use of com.oracle.truffle.dsl.processor.model.SpecializationData in project graal by oracle.
the class FlatNodeGenFactory method createGetCostMethod.
private Element createGetCostMethod() {
TypeMirror returnType = getType(NodeCost.class);
CodeExecutableElement executable = new CodeExecutableElement(modifiers(PUBLIC), returnType, "getCost");
executable.getAnnotationMirrors().add(new CodeAnnotationMirror(context.getDeclaredType(Override.class)));
CodeTreeBuilder builder = executable.createBuilder();
FrameState frameState = FrameState.load(this);
builder.tree(state.createLoad(frameState));
if (node.needsRewrites(context)) {
builder.startIf().tree(state.createIs(frameState, new Object[0], reachableSpecializationsArray)).end();
builder.startBlock();
builder.startReturn().staticReference(getType(NodeCost.class), "UNINITIALIZED").end();
builder.end();
if (reachableSpecializations.size() == 1 && !reachableSpecializations.iterator().next().hasMultipleInstances()) {
builder.startElseBlock();
builder.startReturn().staticReference(getType(NodeCost.class), "MONOMORPHIC").end();
builder.end();
} else {
builder.startElseIf();
builder.tree(state.createIsOneBitOf(frameState, reachableSpecializationsArray));
builder.end();
builder.startBlock();
List<CodeTree> additionalChecks = new ArrayList<>();
for (SpecializationData specialization : reachableSpecializations) {
if (useSpecializationClass(specialization) && specialization.getMaximumNumberOfInstances() > 1) {
String typeName = createSpecializationTypeName(specialization);
String fieldName = createSpecializationFieldName(specialization);
String localName = createSpecializationLocalName(specialization);
builder.declaration(typeName, localName, "this." + fieldName);
CodeTree check = builder.create().startParantheses().string(localName, " == null || ", localName, ".next_ == null").end().build();
additionalChecks.add(check);
}
}
if (!additionalChecks.isEmpty()) {
builder.startIf().tree(combineTrees(" && ", additionalChecks.toArray(new CodeTree[0]))).end().startBlock();
}
builder.startReturn().staticReference(getType(NodeCost.class), "MONOMORPHIC").end();
if (!additionalChecks.isEmpty()) {
builder.end();
}
builder.end();
builder.startReturn().staticReference(getType(NodeCost.class), "POLYMORPHIC").end();
}
} else {
builder.startReturn().staticReference(getType(NodeCost.class), "MONOMORPHIC").end();
}
return executable;
}
use of com.oracle.truffle.dsl.processor.model.SpecializationData in project graal by oracle.
the class FlatNodeGenFactory method createCountCaches.
private Element createCountCaches() {
TypeMirror returnType = getType(int.class);
CodeExecutableElement executable = new CodeExecutableElement(modifiers(PRIVATE), returnType, COUNT_CACHES);
CodeTreeBuilder builder = executable.createBuilder();
final String cacheCount = "cache" + COUNT_SUFIX;
builder.declaration(context.getType(int.class), cacheCount, "0");
for (SpecializationData specialization : reachableSpecializations) {
if (useSpecializationClass(specialization) && specialization.getMaximumNumberOfInstances() > 1) {
String typeName = createSpecializationTypeName(specialization);
String fieldName = createSpecializationFieldName(specialization);
String localName = createSpecializationLocalName(specialization);
builder.declaration(typeName, localName, "this." + fieldName);
builder.startWhile().string(localName, " != null");
builder.end();
builder.startBlock().statement(cacheCount + "++").statement(localName + "= " + localName + ".next_");
builder.end();
}
}
builder.startReturn().statement(cacheCount);
return executable;
}
use of com.oracle.truffle.dsl.processor.model.SpecializationData in project graal by oracle.
the class FlatNodeGenFactory method createFastPath.
private CodeTree createFastPath(CodeTreeBuilder parent, List<SpecializationData> allSpecializations, SpecializationGroup originalGroup, final ExecutableTypeData currentType, FrameState frameState) {
final CodeTreeBuilder builder = parent.create();
builder.tree(state.createLoad(frameState));
int sharedExecutes = 0;
for (NodeExecutionData execution : node.getChildExecutions()) {
boolean canExecuteChild = execution.getIndex() < currentType.getEvaluatedCount();
for (TypeGuard checkedGuard : originalGroup.getTypeGuards()) {
if (checkedGuard.getSignatureIndex() == execution.getIndex()) {
canExecuteChild = true;
break;
}
}
if (!canExecuteChild) {
break;
}
for (TypeGuard checkedGuard : originalGroup.getTypeGuards()) {
// we cannot pull out guards that use optimized implicit source types
if (resolveOptimizedImplicitSourceTypes(execution, checkedGuard.getType()).size() > 1) {
canExecuteChild = false;
break;
}
}
if (!canExecuteChild) {
break;
}
builder.tree(createFastPathExecuteChild(builder, frameState.copy(), frameState, currentType, originalGroup, execution));
sharedExecutes++;
}
List<BoxingSplit> boxingSplits = parameterBoxingElimination(originalGroup, sharedExecutes);
if (boxingSplits.isEmpty()) {
builder.tree(executeFastPathGroup(builder, frameState, currentType, originalGroup, sharedExecutes, null));
addExplodeLoop(builder, originalGroup);
} else {
FrameState originalFrameState = frameState.copy();
boolean elseIf = false;
for (BoxingSplit split : boxingSplits) {
elseIf = builder.startIf(elseIf);
List<SpecializationData> specializations = split.group.collectSpecializations();
builder.startGroup();
builder.tree(state.createContainsOnly(frameState, 0, -1, specializations.toArray(), allSpecializations.toArray())).end();
builder.string(" && ");
builder.tree(state.createIsNotAny(frameState, allSpecializations.toArray()));
builder.end();
builder.end().startBlock();
builder.tree(wrapInAMethod(builder, split.group, originalFrameState, split.getName(), executeFastPathGroup(builder, frameState.copy(), currentType, split.group, sharedExecutes, specializations)));
builder.end();
}
builder.startElseBlock();
builder.tree(wrapInAMethod(builder, originalGroup, originalFrameState, "generic", executeFastPathGroup(builder, frameState, currentType, originalGroup, sharedExecutes, null)));
builder.end();
}
return builder.build();
}
use of com.oracle.truffle.dsl.processor.model.SpecializationData in project graal by oracle.
the class FlatNodeGenFactory method createFields.
private void createFields(CodeTypeElement clazz) {
state.declareFields(clazz);
if (requiresExclude()) {
exclude.declareFields(clazz);
}
for (SpecializationData specialization : reachableSpecializations) {
List<CodeVariableElement> fields = new ArrayList<>();
boolean useSpecializationClass = useSpecializationClass(specialization);
for (CacheExpression cache : specialization.getCaches()) {
Parameter parameter = cache.getParameter();
String fieldName = createFieldName(specialization, parameter);
TypeMirror type = parameter.getType();
Modifier visibility = useSpecializationClass ? null : Modifier.PRIVATE;
CodeVariableElement cachedField;
if (ElementUtils.isAssignable(type, context.getType(NodeInterface.class))) {
cachedField = createNodeField(visibility, type, fieldName, Child.class);
} else if (isNodeInterfaceArray(type)) {
cachedField = createNodeField(visibility, type, fieldName, Children.class);
} else {
cachedField = createNodeField(visibility, type, fieldName, null);
setFieldCompilationFinal(cachedField, parameter.getVariableElement().getAnnotation(Cached.class).dimensions());
}
fields.add(cachedField);
}
for (AssumptionExpression assumption : specialization.getAssumptionExpressions()) {
String fieldName = createAssumptionFieldName(specialization, assumption);
TypeMirror type;
int compilationFinalDimensions;
if (assumption.getExpression().getResolvedType().getKind() == TypeKind.ARRAY) {
type = context.getType(Assumption[].class);
compilationFinalDimensions = 1;
} else {
type = context.getType(Assumption.class);
compilationFinalDimensions = -1;
}
CodeVariableElement assumptionField;
if (useSpecializationClass) {
assumptionField = createNodeField(null, type, fieldName, null);
} else {
assumptionField = createNodeField(PRIVATE, type, fieldName, null);
}
setFieldCompilationFinal(assumptionField, compilationFinalDimensions);
fields.add(assumptionField);
}
if (useSpecializationClass) {
TypeMirror baseType;
boolean useNode = specializationClassIsNode(specialization);
if (useNode) {
baseType = context.getType(Node.class);
} else {
baseType = context.getType(Object.class);
}
CodeTypeElement cacheType = GeneratorUtils.createClass(node, null, modifiers(PRIVATE, FINAL, STATIC), createSpecializationTypeName(specialization), baseType);
Class<?> annotationType;
if (useNode) {
annotationType = Child.class;
if (specialization.getMaximumNumberOfInstances() > 1) {
cacheType.add(createNodeField(null, cacheType.asType(), "next_", Child.class));
}
CodeExecutableElement getNodeCost = new CodeExecutableElement(modifiers(PUBLIC), context.getType(NodeCost.class), "getCost");
getNodeCost.createBuilder().startReturn().staticReference(context.getType(NodeCost.class), "NONE").end();
cacheType.add(getNodeCost);
} else {
annotationType = CompilationFinal.class;
if (specialization.getMaximumNumberOfInstances() > 1) {
cacheType.add(createNodeField(null, cacheType.asType(), "next_", annotationType));
}
}
cacheType.add(GeneratorUtils.createConstructorUsingFields(modifiers(), cacheType));
cacheType.getEnclosedElements().addAll(fields);
clazz.add(createNodeField(PRIVATE, cacheType.asType(), createSpecializationFieldName(specialization), annotationType));
clazz.add(cacheType);
specializationClasses.put(specialization, cacheType);
} else {
clazz.getEnclosedElements().addAll(fields);
}
}
}
use of com.oracle.truffle.dsl.processor.model.SpecializationData in project graal by oracle.
the class FlatNodeGenFactory method createDuplicationCheck.
private CodeTree createDuplicationCheck(CodeTreeBuilder parent, FrameState frameState, SpecializationGroup group, List<GuardExpression> guardExpressions, boolean useDuplicate, String countName, String duplicateFoundName, String specializationLocalName) {
SpecializationData specialization = group.getSpecialization();
CodeTreeBuilder builder = parent.create();
if (!useDuplicate) {
builder.declaration("int", countName, CodeTreeBuilder.singleString("0"));
}
if (useSpecializationClass(specialization)) {
builder.tree(loadSpecializationClass(frameState, specialization));
}
if (!specialization.hasMultipleInstances()) {
builder.declaration("boolean", duplicateFoundName, CodeTreeBuilder.singleString("false"));
}
builder.startIf().tree(state.createContains(frameState, new Object[] { specialization })).end().startBlock();
if (specialization.hasMultipleInstances()) {
builder.startWhile().string(specializationLocalName, " != null").end().startBlock();
}
List<IfTriple> duplicationtriples = new ArrayList<>();
duplicationtriples.addAll(createMethodGuardCheck(frameState, group, guardExpressions, NodeExecutionMode.FAST_PATH));
duplicationtriples.addAll(createAssumptionCheckTriples(frameState, specialization));
int duplicationIfCount = IfTriple.materialize(builder, IfTriple.optimize(duplicationtriples), false);
if (useDuplicate) {
builder.startStatement().string(duplicateFoundName, " = true").end();
}
if (specialization.hasMultipleInstances()) {
builder.statement("break");
}
builder.end(duplicationIfCount);
if (useDuplicate) {
// no counting and next traversal necessary for duplication only check
} else {
if (specialization.getMaximumNumberOfInstances() > 1) {
builder.startStatement().string(specializationLocalName, " = ", specializationLocalName, ".next_").end();
} else {
builder.statement(specializationLocalName + " = null");
}
builder.statement(countName + "++");
builder.end();
}
builder.end();
return builder.build();
}
Aggregations