Search in sources :

Example 1 with CacheExpression

use of com.oracle.truffle.dsl.processor.model.CacheExpression in project graal by oracle.

the class FlatNodeGenFactory method generateReflectionInfo.

private void generateReflectionInfo(CodeTypeElement clazz) {
    clazz.getImplements().add(context.getType(Introspection.Provider.class));
    CodeExecutableElement reflection = new CodeExecutableElement(modifiers(PUBLIC), context.getType(Introspection.class), "getIntrospectionData");
    CodeTreeBuilder builder = reflection.createBuilder();
    List<SpecializationData> filteredSpecializations = new ArrayList<>();
    for (SpecializationData s : node.getSpecializations()) {
        if (s.getMethod() == null) {
            continue;
        }
        filteredSpecializations.add(s);
    }
    ArrayCodeTypeMirror objectArray = new ArrayCodeTypeMirror(context.getType(Object.class));
    builder.declaration(objectArray, "data", builder.create().startNewArray(objectArray, CodeTreeBuilder.singleString(String.valueOf(filteredSpecializations.size() + 1))).end().build());
    builder.declaration(objectArray, "s", (CodeTree) null);
    // declare version 0
    builder.statement("data[0] = 0");
    FrameState frameState = FrameState.load(this);
    builder.tree(state.createLoad(frameState));
    if (requiresExclude()) {
        builder.tree(exclude.createLoad(frameState));
    }
    int index = 1;
    for (SpecializationData specialization : filteredSpecializations) {
        builder.startStatement().string("s = ").startNewArray(objectArray, CodeTreeBuilder.singleString("3")).end().end();
        builder.startStatement().string("s[0] = ").doubleQuote(specialization.getMethodName()).end();
        builder.startIf().tree(state.createContains(frameState, new Object[] { specialization })).end().startBlock();
        builder.startStatement().string("s[1] = (byte)0b01 /* active */").end();
        TypeMirror listType = new DeclaredCodeTypeMirror((TypeElement) context.getDeclaredType(ArrayList.class).asElement(), Arrays.asList(context.getType(Object.class)));
        if (!specialization.getCaches().isEmpty()) {
            builder.declaration(listType, "cached", "new ArrayList<>()");
            boolean useSpecializationClass = useSpecializationClass(specialization);
            String name = createSpecializationLocalName(specialization);
            if (useSpecializationClass) {
                builder.tree(loadSpecializationClass(frameState, specialization));
                if (specialization.hasMultipleInstances()) {
                    builder.startWhile();
                } else {
                    builder.startIf();
                }
                builder.string(name, " != null");
                builder.end();
                builder.startBlock();
            }
            builder.startStatement().startCall("cached", "add");
            builder.startStaticCall(context.getType(Arrays.class), "asList");
            for (CacheExpression cache : specialization.getCaches()) {
                builder.startGroup();
                builder.tree(createCacheReference(frameState, specialization, cache.getParameter()));
                builder.end();
            }
            builder.end();
            builder.end().end();
            if (useSpecializationClass) {
                if (specialization.getMaximumNumberOfInstances() > 1) {
                    builder.startStatement().string(name, " = ", name, ".next_").end();
                }
                // cache while or if
                builder.end();
            }
            builder.statement("s[2] = cached");
        }
        builder.end();
        if (mayBeExcluded(specialization)) {
            builder.startElseIf().tree(exclude.createContains(frameState, new Object[] { specialization })).end().startBlock();
            builder.startStatement().string("s[1] = (byte)0b10 /* excluded */").end();
            builder.end();
        }
        builder.startElseBlock();
        builder.startStatement().string("s[1] = (byte)0b00 /* inactive */").end();
        builder.end();
        builder.startStatement().string("data[", String.valueOf(index), "] = s").end();
        index++;
    }
    builder.startReturn().startStaticCall(context.getType(Introspection.Provider.class), "create").string("data").end().end();
    clazz.add(reflection);
}
Also used : CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) SpecializationData(com.oracle.truffle.dsl.processor.model.SpecializationData) ArrayList(java.util.ArrayList) DeclaredCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror) Introspection(com.oracle.truffle.api.dsl.Introspection) CacheExpression(com.oracle.truffle.dsl.processor.model.CacheExpression) 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) ElementUtils.isObject(com.oracle.truffle.dsl.processor.java.ElementUtils.isObject) Arrays(java.util.Arrays) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror)

Example 2 with CacheExpression

use of com.oracle.truffle.dsl.processor.model.CacheExpression 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 3 with CacheExpression

use of com.oracle.truffle.dsl.processor.model.CacheExpression in project graal by oracle.

the class NodeParser method initializeCaches.

private void initializeCaches(SpecializationData specialization, DSLExpressionResolver resolver) {
    TypeMirror cacheMirror = context.getType(Cached.class);
    List<CacheExpression> expressions = new ArrayList<>();
    for (Parameter parameter : specialization.getParameters()) {
        AnnotationMirror annotationMirror = ElementUtils.findAnnotationMirror(parameter.getVariableElement().getAnnotationMirrors(), cacheMirror);
        if (annotationMirror != null) {
            String initializer = ElementUtils.getAnnotationValue(String.class, annotationMirror, "value");
            TypeMirror parameterType = parameter.getType();
            DSLExpressionResolver localResolver = resolver;
            if (parameterType.getKind() == TypeKind.DECLARED) {
                localResolver = localResolver.copy(importPublicStaticMembers(ElementUtils.fromTypeMirror(parameterType), true));
            }
            CacheExpression cacheExpression;
            DSLExpression expression = null;
            try {
                expression = DSLExpression.parse(initializer);
                expression.accept(localResolver);
                cacheExpression = new CacheExpression(parameter, annotationMirror, expression);
                if (!ElementUtils.typeEquals(expression.getResolvedType(), parameter.getType())) {
                    cacheExpression.addError("Incompatible return type %s. The expression type must be equal to the parameter type %s.", ElementUtils.getSimpleName(expression.getResolvedType()), ElementUtils.getSimpleName(parameter.getType()));
                }
            } catch (InvalidExpressionException e) {
                cacheExpression = new CacheExpression(parameter, annotationMirror, null);
                cacheExpression.addError("Error parsing expression '%s': %s", initializer, e.getMessage());
            }
            if (!cacheExpression.hasErrors()) {
                Cached cached = cacheExpression.getParameter().getVariableElement().getAnnotation(Cached.class);
                cacheExpression.setDimensions(cached.dimensions());
                if (parameterType.getKind() == TypeKind.ARRAY && !ElementUtils.isSubtype(((ArrayType) parameterType).getComponentType(), context.getType(NodeInterface.class))) {
                    if (cacheExpression.getDimensions() == -1) {
                        cacheExpression.addWarning("The cached dimensions attribute must be specified for array types.");
                    }
                } else {
                    if (cacheExpression.getDimensions() != -1) {
                        cacheExpression.addError("The dimensions attribute has no affect for the type %s.", ElementUtils.getSimpleName(parameterType));
                    }
                }
            }
            expressions.add(cacheExpression);
        }
    }
    specialization.setCaches(expressions);
    if (specialization.hasErrors()) {
        return;
    }
    // verify that cache expressions are bound in the correct order.
    for (int i = 0; i < expressions.size(); i++) {
        CacheExpression currentExpression = expressions.get(i);
        Set<VariableElement> boundVariables = currentExpression.getExpression().findBoundVariableElements();
        for (int j = i + 1; j < expressions.size(); j++) {
            CacheExpression boundExpression = expressions.get(j);
            if (boundVariables.contains(boundExpression.getParameter().getVariableElement())) {
                currentExpression.addError("The initializer expression of parameter '%s' binds unitialized parameter '%s. Reorder the parameters to resolve the problem.", currentExpression.getParameter().getLocalName(), boundExpression.getParameter().getLocalName());
                break;
            }
        }
    }
}
Also used : ArrayList(java.util.ArrayList) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) VariableElement(javax.lang.model.element.VariableElement) DSLExpression(com.oracle.truffle.dsl.processor.expression.DSLExpression) CacheExpression(com.oracle.truffle.dsl.processor.model.CacheExpression) AnnotationMirror(javax.lang.model.element.AnnotationMirror) ArrayCodeTypeMirror(com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror) TypeMirror(javax.lang.model.type.TypeMirror) InvalidExpressionException(com.oracle.truffle.dsl.processor.expression.InvalidExpressionException) Cached(com.oracle.truffle.api.dsl.Cached) Parameter(com.oracle.truffle.dsl.processor.model.Parameter) DSLExpressionResolver(com.oracle.truffle.dsl.processor.expression.DSLExpressionResolver) NodeInterface(com.oracle.truffle.api.nodes.NodeInterface)

Example 4 with CacheExpression

use of com.oracle.truffle.dsl.processor.model.CacheExpression in project graal by oracle.

the class FlatNodeGenFactory method initializeCaches.

private List<IfTriple> initializeCaches(FrameState frameState, SpecializationGroup group, Collection<CacheExpression> caches, NodeExecutionMode mode, boolean store, boolean forcePersist) {
    if (mode != NodeExecutionMode.SLOW_PATH || group.getSpecialization() == null) {
        return Collections.emptyList();
    }
    List<IfTriple> triples = new ArrayList<>();
    if (!caches.isEmpty()) {
        // preinitialize caches for guards in local variables
        for (CacheExpression cache : caches) {
            triples.addAll(initializeCasts(frameState, group, cache.getExpression(), mode));
            triples.addAll(persistAndInitializeCache(frameState, group.getSpecialization(), cache, store, forcePersist));
        }
    }
    return triples;
}
Also used : ArrayList(java.util.ArrayList) CacheExpression(com.oracle.truffle.dsl.processor.model.CacheExpression)

Aggregations

CacheExpression (com.oracle.truffle.dsl.processor.model.CacheExpression)4 ArrayList (java.util.ArrayList)4 ArrayCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror)3 TypeMirror (javax.lang.model.type.TypeMirror)3 Cached (com.oracle.truffle.api.dsl.Cached)2 NodeInterface (com.oracle.truffle.api.nodes.NodeInterface)2 ElementUtils.isObject (com.oracle.truffle.dsl.processor.java.ElementUtils.isObject)2 CodeExecutableElement (com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement)2 DeclaredCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror)2 CodeVariableElement (com.oracle.truffle.dsl.processor.java.model.CodeVariableElement)2 GeneratedTypeMirror (com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror)2 Parameter (com.oracle.truffle.dsl.processor.model.Parameter)2 SpecializationData (com.oracle.truffle.dsl.processor.model.SpecializationData)2 Assumption (com.oracle.truffle.api.Assumption)1 Introspection (com.oracle.truffle.api.dsl.Introspection)1 Node (com.oracle.truffle.api.nodes.Node)1 Child (com.oracle.truffle.api.nodes.Node.Child)1 NodeCost (com.oracle.truffle.api.nodes.NodeCost)1 DSLExpression (com.oracle.truffle.dsl.processor.expression.DSLExpression)1 DSLExpressionResolver (com.oracle.truffle.dsl.processor.expression.DSLExpressionResolver)1