Search in sources :

Example 41 with CodeTreeBuilder

use of com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder 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 42 with CodeTreeBuilder

use of com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder 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 43 with CodeTreeBuilder

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

the class FlatNodeGenFactory method createExcludeThis.

private CodeTree createExcludeThis(CodeTreeBuilder parent, FrameState frameState, ExecutableTypeData forType, SpecializationData specialization, NodeExecutionMode mode) {
    CodeTreeBuilder builder = parent.create();
    // slow path might be already already locked
    if (!mode.isSlowPath()) {
        builder.declaration(context.getType(Lock.class), "lock", "getLock()");
    }
    builder.statement("lock.lock()");
    builder.startTryBlock();
    // pass null frame state to ensure values are reloaded.
    builder.tree(this.exclude.createSet(null, new Object[] { specialization }, true, true));
    builder.tree(this.state.createSet(null, new Object[] { specialization }, false, true));
    if (useSpecializationClass(specialization)) {
        String fieldName = createSpecializationFieldName(specialization);
        builder.statement("this." + fieldName + " = null");
    }
    builder.end().startFinallyBlock();
    builder.statement("lock.unlock()");
    builder.end();
    boolean hasUnexpectedResultRewrite = specialization.hasUnexpectedResultRewrite();
    boolean hasReexecutingRewrite = !hasUnexpectedResultRewrite || specialization.getExceptions().size() > 1;
    if (hasReexecutingRewrite) {
        if (hasUnexpectedResultRewrite) {
            builder.startIf().string("ex").instanceOf(context.getType(UnexpectedResultException.class)).end().startBlock();
            builder.tree(createReturnUnexpectedResult(forType, true));
            builder.end().startElseBlock();
            builder.tree(createCallExecuteAndSpecialize(forType, frameState));
            builder.end();
        } else {
            builder.tree(createCallExecuteAndSpecialize(forType, frameState));
        }
    } else {
        assert hasUnexpectedResultRewrite;
        builder.tree(createReturnUnexpectedResult(forType, false));
    }
    builder.end();
    return builder.build();
}
Also used : UnexpectedResultException(com.oracle.truffle.api.nodes.UnexpectedResultException) ElementUtils.isObject(com.oracle.truffle.dsl.processor.java.ElementUtils.isObject) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder) Lock(java.util.concurrent.locks.Lock)

Example 44 with CodeTreeBuilder

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

Example 45 with CodeTreeBuilder

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

the class FlatNodeGenFactory method createFastPathExecuteChild.

private CodeTree createFastPathExecuteChild(final CodeTreeBuilder parent, FrameState originalFrameState, FrameState frameState, final ExecutableTypeData currentType, SpecializationGroup group, NodeExecutionData execution) {
    CodeTreeBuilder builder = parent.create();
    LocalVariable var = frameState.getValue(execution);
    if (var == null) {
        TypeMirror targetType;
        TypeGuard eliminatedGuard = null;
        if (boxingEliminationEnabled) {
            for (TypeGuard checkedGuard : group.getTypeGuards()) {
                if (!ElementUtils.isPrimitive(checkedGuard.getType())) {
                    // no elimination for non primitive types
                    continue;
                } else if (node.getChildExecutions().get(checkedGuard.getSignatureIndex()).getChild().findExecutableType(checkedGuard.getType()) == null) {
                    // type cannot be executed so it cannot be eliminated
                    continue;
                }
                if (checkedGuard.getSignatureIndex() == execution.getIndex()) {
                    eliminatedGuard = checkedGuard;
                    break;
                }
            }
        }
        if (eliminatedGuard != null) {
            // we can optimize the type guard away by executing it
            group.getTypeGuards().remove(eliminatedGuard);
            targetType = eliminatedGuard.getType();
        } else {
            targetType = execution.getChild().findAnyGenericExecutableType(context).getReturnType();
        }
        var = frameState.createValue(execution, targetType).nextName();
        LocalVariable fallbackVar;
        List<TypeMirror> originalSourceTypes = typeSystem.lookupSourceTypes(targetType);
        List<TypeMirror> sourceTypes = resolveOptimizedImplicitSourceTypes(execution, targetType);
        if (sourceTypes.size() > 1) {
            TypeGuard typeGuard = new TypeGuard(targetType, execution.getIndex());
            TypeMirror generic = node.getPolymorphicSpecialization().findParameterOrDie(execution).getType();
            fallbackVar = originalFrameState.createValue(execution, generic);
            // we want to create the check tree in reverse order
            Collections.reverse(sourceTypes);
            CodeTree access = var.createReference();
            boolean first = true;
            for (TypeMirror sType : sourceTypes) {
                if (ElementUtils.typeEquals(sType, targetType)) {
                    continue;
                }
                String localName = createSourceTypeLocalName(var, sType);
                builder.declaration(sType, localName, CodeTreeBuilder.createBuilder().defaultValue(sType).build());
                CodeTreeBuilder accessBuilder = builder.create();
                accessBuilder.startParantheses();
                accessBuilder.tree(state.createContainsOnly(frameState, originalSourceTypes.indexOf(sType), 1, new Object[] { typeGuard }, new Object[] { typeGuard }));
                accessBuilder.string(" && ");
                accessBuilder.tree(state.createIsNotAny(frameState, reachableSpecializationsArray));
                accessBuilder.string(" ? ");
                if (ElementUtils.isPrimitive(sType)) {
                    accessBuilder.string("(").type(generic).string(") ");
                }
                accessBuilder.string(localName);
                accessBuilder.string(" : ");
                if (first && ElementUtils.isPrimitive(targetType)) {
                    accessBuilder.string("(").type(generic).string(") ");
                }
                accessBuilder.tree(access);
                accessBuilder.end();
                access = accessBuilder.build();
                first = false;
            }
            fallbackVar = fallbackVar.accessWith(access);
        } else {
            fallbackVar = var;
        }
        builder.tree(createAssignExecuteChild(originalFrameState, frameState, builder, execution, currentType, var));
        frameState.setValue(execution, var);
        originalFrameState.setValue(execution, fallbackVar);
    }
    return builder.build();
}
Also used : 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) ElementUtils.isObject(com.oracle.truffle.dsl.processor.java.ElementUtils.isObject) CodeTreeBuilder(com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder) TypeGuard(com.oracle.truffle.dsl.processor.parser.SpecializationGroup.TypeGuard)

Aggregations

CodeTreeBuilder (com.oracle.truffle.dsl.processor.java.model.CodeTreeBuilder)64 CodeExecutableElement (com.oracle.truffle.dsl.processor.java.model.CodeExecutableElement)23 TypeMirror (javax.lang.model.type.TypeMirror)23 CodeTree (com.oracle.truffle.dsl.processor.java.model.CodeTree)21 GeneratedTypeMirror (com.oracle.truffle.dsl.processor.java.model.GeneratedTypeMirror)20 ArrayList (java.util.ArrayList)18 ArrayCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.ArrayCodeTypeMirror)17 DeclaredCodeTypeMirror (com.oracle.truffle.dsl.processor.java.model.CodeTypeMirror.DeclaredCodeTypeMirror)16 CodeVariableElement (com.oracle.truffle.dsl.processor.java.model.CodeVariableElement)13 SpecializationData (com.oracle.truffle.dsl.processor.model.SpecializationData)12 NodeExecutionData (com.oracle.truffle.dsl.processor.model.NodeExecutionData)8 VariableElement (javax.lang.model.element.VariableElement)8 ElementUtils.isObject (com.oracle.truffle.dsl.processor.java.ElementUtils.isObject)7 ExecutableElement (javax.lang.model.element.ExecutableElement)7 CodeTypeElement (com.oracle.truffle.dsl.processor.java.model.CodeTypeElement)5 ExecutableTypeData (com.oracle.truffle.dsl.processor.model.ExecutableTypeData)5 Arrays (java.util.Arrays)5 UnexpectedResultException (com.oracle.truffle.api.nodes.UnexpectedResultException)4 AssumptionExpression (com.oracle.truffle.dsl.processor.model.AssumptionExpression)4 SpecializationGroup (com.oracle.truffle.dsl.processor.parser.SpecializationGroup)4