use of com.oracle.truffle.dsl.processor.java.model.CodeTree in project graal by oracle.
the class FlatNodeGenFactory method createCallExecuteAndSpecialize.
private CodeTree createCallExecuteAndSpecialize(ExecutableTypeData forType, FrameState frameState) {
TypeMirror returnType = node.getPolymorphicSpecialization().getReturnType().getType();
String frame = null;
if (needsFrameToExecute(reachableSpecializations)) {
frame = FRAME_VALUE;
}
CodeTreeBuilder builder = CodeTreeBuilder.createBuilder();
builder.startCall("executeAndSpecialize");
frameState.addReferencesTo(builder, frame);
builder.end();
CodeTree call = builder.build();
builder = builder.create();
if (isVoid(forType.getReturnType())) {
builder.statement(call);
builder.returnStatement();
} else {
builder.startReturn();
builder.tree(expectOrCast(returnType, forType, call));
builder.end();
}
return builder.build();
}
use of com.oracle.truffle.dsl.processor.java.model.CodeTree in project graal by oracle.
the class FlatNodeGenFactory method createFallbackGuard.
private Element createFallbackGuard() {
boolean frameUsed = false;
FrameState frameState = FrameState.load(this);
List<SpecializationData> specializations = new ArrayList<>(reachableSpecializations);
for (ListIterator<SpecializationData> iterator = specializations.listIterator(); iterator.hasNext(); ) {
SpecializationData specialization = iterator.next();
if (specialization.isFallback()) {
iterator.remove();
} else if (!specialization.isReachesFallback()) {
iterator.remove();
} else {
if (specialization.isFrameUsedByGuard()) {
frameUsed = true;
}
}
}
SpecializationGroup group = SpecializationGroup.create(specializations);
ExecutableTypeData executableType = node.findAnyGenericExecutableType(context, -1);
if (!frameUsed) {
frameState.removeValue(FRAME_VALUE);
}
fallbackNeedsState = false;
fallbackNeedsFrame = frameUsed;
state.createLoad(frameState);
CodeExecutableElement method = frameState.createMethod(modifiers(PRIVATE), getType(boolean.class), METHOD_FALLBACK_GUARD, FRAME_VALUE, STATE_VALUE);
CodeTree result = visitSpecializationGroup(CodeTreeBuilder.createBuilder(), group, executableType, frameState, null, NodeExecutionMode.FALLBACK_GUARD);
if (!fallbackNeedsState) {
VariableElement toRemove = null;
for (VariableElement v : method.getParameters()) {
if (v.getSimpleName().toString().equals(STATE_VALUE)) {
toRemove = v;
break;
}
}
if (toRemove != null) {
method.getParameters().remove(toRemove);
}
}
final CodeTreeBuilder builder = method.createBuilder();
for (SpecializationData implemented : specializations) {
if (implemented.getMaximumNumberOfInstances() > 1) {
method.getAnnotationMirrors().add(createExplodeLoop());
break;
}
}
builder.tree(result);
builder.returnTrue();
if (!accessesCachedState(specializations)) {
method.getModifiers().add(STATIC);
}
return method;
}
use of com.oracle.truffle.dsl.processor.java.model.CodeTree in project graal by oracle.
the class FlatNodeGenFactory method createAssumptionGuard.
private CodeTree createAssumptionGuard(AssumptionExpression assumption, CodeTree assumptionValue) {
CodeTree assumptionGuard = CodeTreeBuilder.createBuilder().startCall("isValid_").tree(assumptionValue).end().build();
isValidSignatures.put(ElementUtils.getQualifiedName(assumption.getExpression().getResolvedType()), assumption.getExpression().getResolvedType());
return assumptionGuard;
}
use of com.oracle.truffle.dsl.processor.java.model.CodeTree in project graal by oracle.
the class FlatNodeGenFactory method createTypeCheckOrCast.
private IfTriple createTypeCheckOrCast(FrameState frameState, SpecializationGroup group, TypeGuard typeGuard, NodeExecutionMode specializationExecution, boolean castOnly, boolean forceImplicitCast) {
CodeTreeBuilder prepareBuilder = CodeTreeBuilder.createBuilder();
CodeTreeBuilder checkBuilder = CodeTreeBuilder.createBuilder();
int signatureIndex = typeGuard.getSignatureIndex();
LocalVariable value = frameState.getValue(signatureIndex);
TypeMirror targetType = typeGuard.getType();
if (!ElementUtils.needsCastTo(value.getTypeMirror(), targetType)) {
boolean foundImplicitSubType = false;
if (forceImplicitCast) {
List<ImplicitCastData> casts = typeSystem.lookupByTargetType(targetType);
for (ImplicitCastData cast : casts) {
if (ElementUtils.isSubtype(cast.getSourceType(), targetType)) {
foundImplicitSubType = true;
break;
}
}
}
if (!foundImplicitSubType) {
return null;
}
}
NodeExecutionData execution = node.getChildExecutions().get(signatureIndex);
CodeTreeBuilder castBuilder = prepareBuilder.create();
List<ImplicitCastData> sourceTypes = typeSystem.lookupByTargetType(targetType);
CodeTree valueReference = value.createReference();
if (sourceTypes.isEmpty()) {
checkBuilder.tree(TypeSystemCodeGenerator.check(typeSystem, targetType, valueReference));
castBuilder.tree(TypeSystemCodeGenerator.cast(typeSystem, targetType, valueReference));
} else {
List<SpecializationData> specializations = group.collectSpecializations();
List<Parameter> parameters = new ArrayList<>();
for (SpecializationData otherSpecialization : specializations) {
parameters.add(otherSpecialization.findParameterOrDie(execution));
}
if (specializationExecution.isFastPath() || specializationExecution.isGuardFallback()) {
CodeTree implicitState;
if (specializationExecution.isGuardFallback()) {
implicitState = CodeTreeBuilder.singleString("0b" + allsetMask(sourceTypes.size() + 1));
} else {
implicitState = state.createExtractInteger(frameState, typeGuard);
}
checkBuilder.tree(TypeSystemCodeGenerator.implicitCheckFlat(typeSystem, targetType, valueReference, implicitState));
castBuilder.tree(TypeSystemCodeGenerator.implicitCastFlat(typeSystem, targetType, valueReference, implicitState));
} else {
Parameter parameter = parameters.get(0);
String implicitStateName = createImplicitTypeStateLocalName(parameter);
CodeTree defaultValue = null;
prepareBuilder.declaration(context.getType(int.class), implicitStateName, defaultValue);
CodeTree specializeCall = TypeSystemCodeGenerator.implicitSpecializeFlat(typeSystem, targetType, valueReference);
checkBuilder.startParantheses();
checkBuilder.string(implicitStateName, " = ").tree(specializeCall);
checkBuilder.end();
checkBuilder.string(" != 0");
castBuilder.tree(TypeSystemCodeGenerator.implicitCastFlat(typeSystem, targetType, valueReference, CodeTreeBuilder.singleString(implicitStateName)));
}
}
if (castOnly) {
LocalVariable currentValue = frameState.getValue(execution);
CodeTreeBuilder localsBuilder = CodeTreeBuilder.createBuilder();
LocalVariable castVariable = currentValue.nextName().newType(typeGuard.getType()).accessWith(null);
frameState.setValue(execution, castVariable);
localsBuilder.tree(castVariable.createDeclaration(castBuilder.build()));
return new IfTriple(localsBuilder.build(), null, null);
} else {
return new IfTriple(prepareBuilder.build(), checkBuilder.build(), null);
}
}
use of com.oracle.truffle.dsl.processor.java.model.CodeTree in project graal by oracle.
the class FlatNodeGenFactory method persistCache.
private Collection<IfTriple> persistCache(FrameState frameState, SpecializationData specialization, CacheExpression cache, CodeTree cacheValue) {
String name = createFieldName(specialization, cache.getParameter());
LocalVariable local = frameState.get(name);
CodeTree value;
if (local != null) {
// already initialized and stored don't use init.
value = local.createReference();
} else if (cacheValue == null) {
return Collections.emptyList();
} else {
value = cacheValue;
}
TypeMirror type = cache.getParameter().getType();
String frameStateInitialized = name + "$initialized";
if (frameState.getBoolean(frameStateInitialized, false)) {
return Collections.emptyList();
} else {
frameState.setBoolean(frameStateInitialized, true);
}
List<IfTriple> triples = new ArrayList<>();
CodeTreeBuilder builder = new CodeTreeBuilder(null);
Parameter parameter = cache.getParameter();
boolean useSpecializationClass = useSpecializationClass(specialization);
if (!useSpecializationClass || frameState.getBoolean(createSpecializationClassPersisted(specialization), false)) {
String insertTarget;
if (useSpecializationClass) {
insertTarget = createSpecializationLocalName(specialization);
} else {
insertTarget = "super";
}
TypeMirror nodeType = context.getType(Node.class);
TypeMirror nodeArrayType = context.getType(Node[].class);
boolean isNode = ElementUtils.isAssignable(parameter.getType(), nodeType);
boolean isNodeInterface = isNode || ElementUtils.isAssignable(type, context.getType(NodeInterface.class));
boolean isNodeArray = ElementUtils.isAssignable(type, nodeArrayType);
boolean isNodeInterfaceArray = isNodeArray || isNodeInterfaceArray(type);
if (isNodeInterface || isNodeInterfaceArray) {
builder = new CodeTreeBuilder(null);
String fieldName = createFieldName(specialization, cache.getParameter()) + "__";
String insertName = useSpecializationClass ? useInsertAccessor(specialization, !isNodeInterface) : "insert";
final TypeMirror castType;
if (isNodeInterface) {
if (isNode) {
castType = null;
} else {
castType = nodeType;
}
} else {
assert isNodeInterfaceArray;
if (isNodeArray) {
castType = null;
} else {
castType = nodeArrayType;
}
}
if (castType == null) {
CodeTreeBuilder noCast = new CodeTreeBuilder(null);
noCast.startCall(insertTarget, insertName);
noCast.tree(value);
noCast.end();
value = noCast.build();
} else {
builder.declaration(cache.getExpression().getResolvedType(), fieldName, value);
builder.startIf().string(fieldName).instanceOf(castType).end().startBlock();
builder.startStatement().startCall(insertTarget, insertName);
builder.startGroup().cast(castType).string(fieldName).end();
builder.end().end();
builder.end();
value = CodeTreeBuilder.singleString(fieldName);
}
}
}
builder.startStatement();
builder.tree(createCacheReference(frameState, specialization, cache.getParameter())).string(" = ").tree(value);
builder.end();
triples.add(new IfTriple(builder.build(), null, null));
return triples;
}
Aggregations