Search in sources :

Example 6 with SpecializationData

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;
}
Also used : CodeAnnotationMirror(com.oracle.truffle.dsl.processor.java.model.CodeAnnotationMirror) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) DeclaredCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) GeneratedTypeMirror(com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) CodeTree(com.oracle.truffle.dsl.processor.java.model.CodeTree) ArrayList(java.util.ArrayList) SpecializationData(com.oracle.truffle.dsl.processor.model.SpecializationData) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)

Example 7 with SpecializationData

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;
}
Also used : CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) DeclaredCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) GeneratedTypeMirror(com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) SpecializationData(com.oracle.truffle.dsl.processor.model.SpecializationData) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)

Example 8 with SpecializationData

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();
}
Also used : NodeExecutionData(com.oracle.truffle.dsl.processor.model.NodeExecutionData) SpecializationData(com.oracle.truffle.dsl.processor.model.SpecializationData) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder) TypeGuard(com.oracle.truffle.dsl.processor.parser.SpecializationGroup.TypeGuard)

Example 9 with SpecializationData

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);
        }
    }
}
Also used : CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) Node(com.oracle.truffle.api.nodes.Node) SpecializationData(com.oracle.truffle.dsl.processor.model.SpecializationData) ArrayList(java.util.ArrayList) NodeCost(com.oracle.truffle.api.nodes.NodeCost) CacheExpression(com.oracle.truffle.dsl.processor.model.CacheExpression) Assumption(com.oracle.truffle.api.Assumption) DeclaredCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) GeneratedTypeMirror(com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) CodeTypeElement(com.oracle.truffle.dsl.processor.java.model.CodeTypeElement) Cached(com.oracle.truffle.api.dsl.Cached) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) Parameter(com.oracle.truffle.dsl.processor.model.Parameter) ElementUtils.isObject(com.oracle.truffle.dsl.processor.java.ElementUtils.isObject) Modifier(javax.lang.model.element.Modifier) Child(com.oracle.truffle.api.nodes.Node.Child) NodeInterface(com.oracle.truffle.api.nodes.NodeInterface) AssumptionExpression(com.oracle.truffle.dsl.processor.model.AssumptionExpression)

Example 10 with SpecializationData

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();
}
Also used : SpecializationData(com.oracle.truffle.dsl.processor.model.SpecializationData) ArrayList(java.util.ArrayList) ElementUtils.isObject(com.oracle.truffle.dsl.processor.java.ElementUtils.isObject) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)

Aggregations

SpecializationData (com.oracle.truffle.dsl.processor.model.SpecializationData)35 ArrayList (java.util.ArrayList)22 TypeMirror (javax.lang.model.type.TypeMirror)17 ArrayCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror)16 CodeTreeBuilder (com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)12 CodeExecutableElement (com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement)11 DeclaredCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror)11 GeneratedTypeMirror (com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror)11 Parameter (com.oracle.truffle.dsl.processor.model.Parameter)9 CodeVariableElement (com.oracle.truffle.dsl.processor.java.model.CodeVariableElement)8 ExecutableTypeData (com.oracle.truffle.dsl.processor.model.ExecutableTypeData)7 CodeTree (com.oracle.truffle.dsl.processor.java.model.CodeTree)6 HashSet (java.util.HashSet)6 NodeExecutionData (com.oracle.truffle.dsl.processor.model.NodeExecutionData)5 VariableElement (javax.lang.model.element.VariableElement)5 AnnotationValue (javax.lang.model.element.AnnotationValue)4 ExecutableElement (javax.lang.model.element.ExecutableElement)4 Child (com.oracle.truffle.api.nodes.Node.Child)3 DSLExpression (com.oracle.truffle.dsl.processor.expression.DSLExpression)3 ElementUtils.isObject (com.oracle.truffle.dsl.processor.java.ElementUtils.isObject)3