Search in sources :

Example 11 with NodeExecutionData

use of com.oracle.truffle.dsl.processor.model.NodeExecutionData 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);
    }
}
Also used : ImplicitCastData(com.oracle.truffle.dsl.processor.model.ImplicitCastData) NodeExecutionData(com.oracle.truffle.dsl.processor.model.NodeExecutionData) SpecializationData(com.oracle.truffle.dsl.processor.model.SpecializationData) ArrayList(java.util.ArrayList) 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) Parameter(com.oracle.truffle.dsl.processor.model.Parameter) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)

Example 12 with NodeExecutionData

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

the class FlatNodeGenFactory method executeFastPathGroup.

private CodeTree executeFastPathGroup(final CodeTreeBuilder parent, FrameState frameState, final ExecutableTypeData currentType, SpecializationGroup group, int sharedExecutes, List<SpecializationData> allowedSpecializations) {
    CodeTreeBuilder builder = parent.create();
    FrameState originalFrameState = frameState.copy();
    for (NodeExecutionData execution : node.getChildExecutions()) {
        if (execution.getIndex() < sharedExecutes) {
            // skip shared executes
            continue;
        }
        builder.tree(createFastPathExecuteChild(builder, originalFrameState, frameState, currentType, group, execution));
    }
    builder.tree(visitSpecializationGroup(builder, group, currentType, frameState, allowedSpecializations, NodeExecutionMode.FAST_PATH));
    if (group.hasFallthrough()) {
        builder.tree(createTransferToInterpreterAndInvalidate());
        builder.tree(createCallExecuteAndSpecialize(currentType, originalFrameState));
    }
    return builder.build();
}
Also used : NodeExecutionData(com.oracle.truffle.dsl.processor.model.NodeExecutionData) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)

Example 13 with NodeExecutionData

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

the class FlatNodeGenFactory method renameOriginalParameters.

private void renameOriginalParameters(ExecutableTypeData executedType, CodeExecutableElement executable, FrameState frameState) {
    // rename varargs parameter
    int evaluatedIndex = 0;
    for (int executionIndex = 0; executionIndex < node.getExecutionCount(); executionIndex++) {
        NodeExecutionData execution = node.getChildExecutions().get(executionIndex);
        if (evaluatedIndex < executedType.getEvaluatedCount()) {
            TypeMirror evaluatedType = executedType.getEvaluatedParameters().get(evaluatedIndex);
            LocalVariable value = frameState.getValue(execution);
            if (value != null) {
                frameState.setValue(execution, renameExecutableTypeParameter(executable, executedType, evaluatedIndex, evaluatedType, value));
            }
            evaluatedIndex++;
        }
    }
}
Also used : NodeExecutionData(com.oracle.truffle.dsl.processor.model.NodeExecutionData) 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)

Example 14 with NodeExecutionData

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

the class FlatNodeGenFactory method initializeCasts.

private List<IfTriple> initializeCasts(FrameState frameState, SpecializationGroup group, DSLExpression expression, NodeExecutionMode specializationExecution) {
    Set<VariableElement> boundElements = expression.findBoundVariableElements();
    if (boundElements.isEmpty()) {
        return Collections.emptyList();
    }
    List<IfTriple> triples = new ArrayList<>();
    for (VariableElement variable : boundElements) {
        Parameter p = group.getSpecialization().findByVariable(variable);
        if (p != null) {
            NodeExecutionData execution = p.getSpecification().getExecution();
            if (execution != null) {
                LocalVariable var = frameState.getValue(execution);
                if (var == null) {
                    throw new AssertionError();
                }
                IfTriple triple = createTypeCheckOrCast(frameState, group, new TypeGuard(p.getType(), execution.getIndex()), specializationExecution, true, false);
                if (triple != null) {
                    triples.add(triple);
                }
            }
        }
    }
    return triples;
}
Also used : NodeExecutionData(com.oracle.truffle.dsl.processor.model.NodeExecutionData) ArrayList(java.util.ArrayList) Parameter(com.oracle.truffle.dsl.processor.model.Parameter) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) VariableElement(javax.lang.model.element.VariableElement) TypeGuard(com.oracle.truffle.dsl.processor.parser.SpecializationGroup.TypeGuard)

Example 15 with NodeExecutionData

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

the class FlatNodeGenFactory method create.

public CodeTypeElement create(CodeTypeElement clazz) {
    for (NodeChildData child : node.getChildren()) {
        clazz.addOptional(createAccessChildMethod(child));
    }
    for (NodeFieldData field : node.getFields()) {
        if (!field.isGenerated()) {
            continue;
        }
        clazz.add(new CodeVariableElement(modifiers(PRIVATE, FINAL), field.getType(), field.getName()));
        if (field.getGetter() != null && field.getGetter().getModifiers().contains(Modifier.ABSTRACT)) {
            CodeExecutableElement method = CodeExecutableElement.clone(context.getEnvironment(), field.getGetter());
            method.getModifiers().remove(Modifier.ABSTRACT);
            method.createBuilder().startReturn().string("this.").string(field.getName()).end();
            clazz.add(method);
        }
    }
    for (ExecutableElement superConstructor : GeneratorUtils.findUserConstructors(node.getTemplateType().asType())) {
        clazz.add(createNodeConstructor(clazz, superConstructor));
    }
    for (NodeExecutionData execution : node.getChildExecutions()) {
        if (execution.getChild() != null && execution.getChild().needsGeneratedField()) {
            clazz.add(createNodeField(PRIVATE, execution.getNodeType(), nodeFieldName(execution), Child.class));
        }
    }
    createFields(clazz);
    TypeMirror genericReturnType = node.getPolymorphicSpecialization().getReturnType().getType();
    List<ExecutableTypeData> executableTypes = filterExecutableTypes(node.getExecutableTypes(), reachableSpecializations);
    List<ExecutableTypeData> genericExecutableTypes = new ArrayList<>();
    List<ExecutableTypeData> specializedExecutableTypes = new ArrayList<>();
    List<ExecutableTypeData> voidExecutableTypes = new ArrayList<>();
    for (ExecutableTypeData type : executableTypes) {
        if (ElementUtils.isVoid(type.getReturnType())) {
            voidExecutableTypes.add(type);
        } else if (type.hasUnexpectedValue(context) && !ElementUtils.typeEquals(genericReturnType, type.getReturnType())) {
            specializedExecutableTypes.add(type);
        } else {
            genericExecutableTypes.add(type);
        }
    }
    if (genericExecutableTypes.size() > 1) {
        boolean hasGenericTypeMatch = false;
        for (ExecutableTypeData genericExecutable : genericExecutableTypes) {
            if (ElementUtils.typeEquals(genericExecutable.getReturnType(), genericReturnType)) {
                hasGenericTypeMatch = true;
                break;
            }
        }
        if (hasGenericTypeMatch) {
            for (ListIterator<ExecutableTypeData> iterator = genericExecutableTypes.listIterator(); iterator.hasNext(); ) {
                ExecutableTypeData executableTypeData = iterator.next();
                if (!ElementUtils.typeEquals(genericReturnType, executableTypeData.getReturnType())) {
                    iterator.remove();
                    specializedExecutableTypes.add(executableTypeData);
                }
            }
        }
    }
    SpecializationData fallback = node.getGenericSpecialization();
    if (fallback.getMethod() != null && fallback.isReachable()) {
        clazz.add(createFallbackGuard());
    }
    for (ExecutableTypeData type : genericExecutableTypes) {
        createExecute(clazz, type, Collections.<ExecutableTypeData>emptyList());
    }
    for (ExecutableTypeData type : specializedExecutableTypes) {
        createExecute(clazz, type, genericExecutableTypes);
    }
    for (ExecutableTypeData type : voidExecutableTypes) {
        List<ExecutableTypeData> genericAndSpecialized = new ArrayList<>();
        genericAndSpecialized.addAll(genericExecutableTypes);
        genericAndSpecialized.addAll(specializedExecutableTypes);
        createExecute(clazz, type, genericAndSpecialized);
    }
    clazz.addOptional(createExecuteAndSpecialize());
    if (shouldReportPolymorphism(node, reachableSpecializations)) {
        clazz.addOptional(createCheckForPolymorphicSpecialize());
        if (requiresCacheCheck()) {
            clazz.addOptional(createCountCaches());
        }
    }
    NodeInfo nodeInfo = node.getTemplateType().getAnnotation(NodeInfo.class);
    if (nodeInfo == null || nodeInfo.cost() == NodeCost.MONOMORPHIC) /* the default */
    {
        clazz.add(createGetCostMethod());
    }
    for (TypeMirror type : ElementUtils.uniqueSortedTypes(expectedTypes, false)) {
        if (!typeSystem.hasType(type)) {
            clazz.addOptional(TypeSystemCodeGenerator.createExpectMethod(PRIVATE, typeSystem, context.getType(Object.class), type));
        }
    }
    for (TypeMirror assumptionType : isValidSignatures.values()) {
        clazz.add(createIsValid(assumptionType));
    }
    clazz.getEnclosedElements().addAll(removeThisMethods.values());
    for (SpecializationData specialization : specializationClasses.keySet()) {
        CodeTypeElement type = specializationClasses.get(specialization);
        if (getInsertAccessorSet(true).contains(specialization)) {
            type.add(createInsertAccessor(true));
        } else if (getInsertAccessorSet(false).contains(specialization)) {
            type.add(createInsertAccessor(false));
        }
    }
    if (node.isReflectable()) {
        generateReflectionInfo(clazz);
    }
    return clazz;
}
Also used : ExecutableTypeData(com.oracle.truffle.dsl.processor.model.ExecutableTypeData) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) NodeChildData(com.oracle.truffle.dsl.processor.model.NodeChildData) NodeExecutionData(com.oracle.truffle.dsl.processor.model.NodeExecutionData) CodeExecutableElement(com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement) ExecutableElement(javax.lang.model.element.ExecutableElement) ArrayList(java.util.ArrayList) SpecializationData(com.oracle.truffle.dsl.processor.model.SpecializationData) NodeFieldData(com.oracle.truffle.dsl.processor.model.NodeFieldData) 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) NodeInfo(com.oracle.truffle.api.nodes.NodeInfo) CodeVariableElement(com.oracle.truffle.dsl.processor.java.model.CodeVariableElement) Child(com.oracle.truffle.api.nodes.Node.Child)

Aggregations

NodeExecutionData (com.oracle.truffle.dsl.processor.model.NodeExecutionData)18 ArrayList (java.util.ArrayList)11 ArrayCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror)10 TypeMirror (javax.lang.model.type.TypeMirror)10 CodeTreeBuilder (com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)8 NodeChildData (com.oracle.truffle.dsl.processor.model.NodeChildData)6 CodeExecutableElement (com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement)5 CodeTree (com.oracle.truffle.dsl.processor.java.model.CodeTree)5 CodeVariableElement (com.oracle.truffle.dsl.processor.java.model.CodeVariableElement)5 DeclaredCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror)4 GeneratedTypeMirror (com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror)4 ExecutableTypeData (com.oracle.truffle.dsl.processor.model.ExecutableTypeData)4 Parameter (com.oracle.truffle.dsl.processor.model.Parameter)4 SpecializationData (com.oracle.truffle.dsl.processor.model.SpecializationData)4 ExecutableElement (javax.lang.model.element.ExecutableElement)3 VariableElement (javax.lang.model.element.VariableElement)3 NodeFieldData (com.oracle.truffle.dsl.processor.model.NodeFieldData)2 TypeGuard (com.oracle.truffle.dsl.processor.parser.SpecializationGroup.TypeGuard)2 HashSet (java.util.HashSet)2 UnsupportedSpecializationException (com.oracle.truffle.api.dsl.UnsupportedSpecializationException)1