Search in sources :

Example 31 with FrameState

use of org.graalvm.compiler.nodes.FrameState in project graal by oracle.

the class CInterfaceEnumTool method invokeEnumValue.

private InvokeNode invokeEnumValue(GraphBuilderTool b, CallTargetFactory callTargetFactory, FrameStateBuilder frameState, int bci, EnumInfo enumInfo, ResolvedJavaMethod valueMethod, ValueNode arg) {
    ResolvedJavaType returnType = (ResolvedJavaType) valueMethod.getSignature().getReturnType(null);
    ValueNode[] args = new ValueNode[2];
    args[0] = ConstantNode.forConstant(snippetReflection.forObject(enumInfo.getRuntimeData()), b.getMetaAccess(), b.getGraph());
    args[1] = arg;
    StampPair returnStamp = StampFactory.forDeclaredType(null, returnType, false);
    MethodCallTargetNode callTargetNode = b.append(callTargetFactory.createMethodCallTarget(InvokeKind.Virtual, valueMethod, args, returnStamp, bci));
    Stamp invokeStamp = StampFactory.forKind(returnType.getJavaKind());
    InvokeNode invoke = b.append(new InvokeNode(callTargetNode, bci, invokeStamp));
    frameState.push(returnType.getJavaKind(), invoke);
    FrameState stateWithInvoke = frameState.create(bci, invoke);
    frameState.pop(returnType.getJavaKind());
    invoke.setStateAfter(stateWithInvoke);
    return invoke;
}
Also used : MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) Stamp(org.graalvm.compiler.core.common.type.Stamp) ValueNode(org.graalvm.compiler.nodes.ValueNode) StampPair(org.graalvm.compiler.core.common.type.StampPair) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) FrameState(org.graalvm.compiler.nodes.FrameState) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType)

Example 32 with FrameState

use of org.graalvm.compiler.nodes.FrameState in project graal by oracle.

the class HostedBytecodeParser method parseAndInlineCallee.

@Override
protected void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, IntrinsicContext calleeIntrinsicContext) {
    assert calleeIntrinsicContext != null : "only inlining replacements";
    if (getMethod().compilationInfo.isDeoptEntry(bci(), false, false)) {
        /*
             * Replacements use the frame state before the invoke for all nodes that need a state,
             * i.e., we want to re-execute the whole replacement in case of deoptimization.
             * Therefore, we need to register a DeoptEntryNode before inlining the replacement. The
             * frame state used for the DeoptEntryNode needs to be the same state that will be used
             * later on in the intrinsic.
             */
        FrameState stateAfter = frameState.create(bci(), getNonIntrinsicAncestor(), false, targetMethod.getSignature().toParameterKinds(!targetMethod.isStatic()), args);
        long encodedBci = FrameInfoEncoder.encodeBci(stateAfter.bci, stateAfter.duringCall(), stateAfter.rethrowException());
        if (!deoptEntries.containsKey(encodedBci)) {
            DeoptEntryNode deoptEntry = graph.add(new DeoptEntryNode());
            deoptEntry.setStateAfter(stateAfter);
            insertProxies(deoptEntry, frameState);
            lastInstr.setNext(deoptEntry);
            lastInstr = deoptEntry;
            for (int i = 0; i < args.length; i++) {
                args[i] = createProxyNode(args[i], deoptEntry);
            }
        }
        /*
             * Ensure that no one registers a later state (after the replacement) with the same
             * frame state.
             */
        deoptEntries.put(encodedBci, STICKY_DEOPT_ENTRY);
    }
    super.parseAndInlineCallee(targetMethod, args, calleeIntrinsicContext);
}
Also used : DeoptEntryNode(com.oracle.svm.core.graal.nodes.DeoptEntryNode) FrameState(org.graalvm.compiler.nodes.FrameState)

Example 33 with FrameState

use of org.graalvm.compiler.nodes.FrameState in project graal by oracle.

the class AssertValueNode method insert.

protected static void insert(ValueNode input, AssertValueNode assertionNode) {
    StructuredGraph graph = input.graph();
    /* Find the insertion point where we want to add the assertion node. */
    FixedWithNextNode insertionPoint;
    if (input instanceof ParameterNode) {
        insertionPoint = graph.start();
    } else if (input instanceof InvokeWithExceptionNode) {
        insertionPoint = ((InvokeWithExceptionNode) input).next();
    } else if (input instanceof FixedWithNextNode) {
        insertionPoint = (FixedWithNextNode) input;
    } else {
        throw shouldNotReachHere("Node is not fixed: " + input);
    }
    /*
         * When inserting after an invoke that is also a loop exit, a proxy node is inserted between
         * the invoke and every usage. We need to be after this proxy node to avoid unschedulable
         * graphs.
         */
    ProxyNode proxyUsage = null;
    boolean otherUsages = false;
    for (Node usage : input.usages()) {
        if (usage instanceof ProxyNode && ((ProxyNode) usage).proxyPoint() == insertionPoint) {
            assert proxyUsage == null : "can have only one proxy";
            proxyUsage = (ProxyNode) usage;
        } else if (!(usage instanceof FrameState)) {
            otherUsages = true;
        }
    }
    assert proxyUsage == null || otherUsages == false : "cannot have other usages when having a proxy usage";
    ValueNode assertInput = proxyUsage != null ? proxyUsage : input;
    /*
         * Replace the object at usages. We do not process usages at the frame state because it
         * could be the stateAfter() of the insertion point. Since frame states are not doing
         * anything in code, this is not a loss of assertion precision.
         */
    for (Node usage : assertInput.usages().snapshot()) {
        if (!(usage instanceof FrameState)) {
            usage.replaceFirstInput(assertInput, assertionNode);
        }
    }
    /*
         * Set the input object of the assertion node, now that all other usages have been replaced.
         */
    assertionNode.updateUsages(assertionNode.input, assertInput);
    assertionNode.input = assertInput;
    /* Insert assertion node in graph. */
    graph.addAfterFixed(insertionPoint, assertionNode);
}
Also used : ProxyNode(org.graalvm.compiler.nodes.ProxyNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Node(org.graalvm.compiler.graph.Node) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) FrameState(org.graalvm.compiler.nodes.FrameState)

Example 34 with FrameState

use of org.graalvm.compiler.nodes.FrameState in project graal by oracle.

the class PartialEvaluationTest method removeFrameStates.

protected void removeFrameStates(StructuredGraph graph) {
    for (FrameState frameState : graph.getNodes(FrameState.TYPE)) {
        frameState.replaceAtUsages(null);
        frameState.safeDelete();
    }
    new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
    new DeadCodeEliminationPhase().apply(graph);
}
Also used : PhaseContext(org.graalvm.compiler.phases.tiers.PhaseContext) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase) FrameState(org.graalvm.compiler.nodes.FrameState) DeadCodeEliminationPhase(org.graalvm.compiler.phases.common.DeadCodeEliminationPhase)

Example 35 with FrameState

use of org.graalvm.compiler.nodes.FrameState in project graal by oracle.

the class IntrinsifyMethodHandlesInvocationPlugin method processInvokeWithMethodHandle.

@SuppressWarnings("try")
private void processInvokeWithMethodHandle(GraphBuilderContext b, BytecodeProvider bytecodeProvider, ResolvedJavaMethod methodHandleMethod, ValueNode[] methodHandleArguments) {
    Plugins graphBuilderPlugins = new Plugins(((ReplacementsImpl) originalProviders.getReplacements()).getGraphBuilderPlugins());
    registerInvocationPlugins(graphBuilderPlugins.getInvocationPlugins(), bytecodeProvider);
    graphBuilderPlugins.prependParameterPlugin(new MethodHandlesParameterPlugin(methodHandleArguments));
    graphBuilderPlugins.clearInlineInvokePlugins();
    graphBuilderPlugins.prependInlineInvokePlugin(new MethodHandlesInlineInvokePlugin());
    graphBuilderPlugins.prependNodePlugin(new MethodHandlePlugin(originalProviders.getConstantReflection().getMethodHandleAccess(), false));
    /* We do all the word type rewriting because parameters to the lambda can be word types. */
    SnippetReflectionProvider originalSnippetReflection = GraalAccess.getOriginalSnippetReflection();
    WordOperationPlugin wordOperationPlugin = new WordOperationPlugin(originalSnippetReflection, new WordTypes(originalProviders.getMetaAccess(), FrameAccess.getWordKind()));
    graphBuilderPlugins.appendInlineInvokePlugin(wordOperationPlugin);
    graphBuilderPlugins.appendTypePlugin(wordOperationPlugin);
    graphBuilderPlugins.appendTypePlugin(new TrustedInterfaceTypePlugin());
    graphBuilderPlugins.appendNodePlugin(wordOperationPlugin);
    GraphBuilderConfiguration graphBuilderConfig = GraphBuilderConfiguration.getSnippetDefault(graphBuilderPlugins);
    GraphBuilderPhase.Instance graphBuilder = new GraphBuilderPhase.Instance(originalProviders.getMetaAccess(), originalProviders.getStampProvider(), originalProviders.getConstantReflection(), originalProviders.getConstantFieldProvider(), graphBuilderConfig, OptimisticOptimizations.NONE, null);
    DebugContext debug = b.getDebug();
    StructuredGraph graph = new StructuredGraph.Builder(b.getOptions(), debug).method(toOriginal(methodHandleMethod)).build();
    try (DebugContext.Scope s = debug.scope("IntrinsifyMethodHandles", graph)) {
        graphBuilder.apply(graph);
        /*
             * We do not care about the improved type information from Pi nodes, so we just delete
             * them to simplify our graph.
             */
        for (PiNode pi : graph.getNodes(PiNode.TYPE)) {
            pi.replaceAndDelete(pi.object());
        }
        /*
             * Support for MethodHandle that adapt the input type to a more generic type, i.e., a
             * MethodHandle that does a dynamic type check on a parameter.
             */
        for (UnaryOpLogicNode node : graph.getNodes().filter(UnaryOpLogicNode.class).filter(v -> v instanceof IsNullNode || v instanceof InstanceOfNode)) {
            ValueNode value = node.getValue();
            if (value instanceof ParameterNode) {
                /*
                     * We just assume that the InstanceOfNode or IsNullNode are used in an If and
                     * the true-successor is actually the branch we want. If that assumption is
                     * wrong, nothing bad happens - we will just continue to report the invocation
                     * as unsupported because the updated stamp for the parameter will not simplify
                     * the graph.
                     */
                if (node instanceof InstanceOfNode) {
                    InstanceOfNode inst = (InstanceOfNode) node;
                    TypeReference typeRef = inst.type();
                    value.setStamp(new ObjectStamp(typeRef.getType(), typeRef.isExact(), !inst.allowsNull(), false));
                } else {
                    assert node instanceof IsNullNode;
                    ResolvedJavaType type = value.stamp(NodeView.DEFAULT).javaType(originalProviders.getMetaAccess());
                    value.setStamp(new ObjectStamp(type, false, /* non-null */
                    true, false));
                }
            }
        }
        /*
             * The canonicalizer converts unsafe field accesses for get/set method handles back to
             * high-level field load and store nodes.
             */
        new CanonicalizerPhase().apply(graph, new PhaseContext(originalProviders));
        for (FixedGuardNode guard : graph.getNodes(FixedGuardNode.TYPE)) {
            if (guard.next() instanceof AccessFieldNode && guard.condition() instanceof IsNullNode && guard.isNegated() && ((IsNullNode) guard.condition()).getValue() == ((AccessFieldNode) guard.next()).object()) {
                /*
                     * Method handles to load and stores fields have null checks. Remove them, since
                     * the null check is implicitly done by the field access.
                     */
                GraphUtil.removeFixedWithUnusedInputs(guard);
            }
        }
        debug.dump(DebugContext.VERY_DETAILED_LEVEL, graph, "Final intrinisfication graph");
        /*
             * After parsing (and recursive inlining during parsing), the graph must contain only
             * one invocation (and therefore only one MethodCallTargetNode), plus the parameters,
             * constants, start, and return nodes.
             */
        Node singleFunctionality = null;
        ReturnNode singleReturn = null;
        for (Node node : graph.getNodes()) {
            if (node == graph.start() || node instanceof ParameterNode || node instanceof ConstantNode || node instanceof FrameState) {
                /* Ignore the allowed framework around the nodes we care about. */
                continue;
            } else if (node instanceof Invoke) {
                /* We check the MethodCallTargetNode, so we can ignore the invoke. */
                continue;
            } else if ((node instanceof MethodCallTargetNode || node instanceof LoadFieldNode || node instanceof StoreFieldNode) && singleFunctionality == null) {
                singleFunctionality = node;
                continue;
            } else if (node instanceof ReturnNode && singleReturn == null) {
                singleReturn = (ReturnNode) node;
                continue;
            }
            throw new UnsupportedFeatureException("Invoke with MethodHandle argument could not be reduced to at most a single call: " + methodHandleMethod.format("%H.%n(%p)"));
        }
        if (singleFunctionality instanceof MethodCallTargetNode) {
            MethodCallTargetNode singleCallTarget = (MethodCallTargetNode) singleFunctionality;
            assert singleReturn.result() == null || singleReturn.result() == singleCallTarget.invoke();
            /*
                 * Replace the originalTarget with the replacementTarget. Note that the
                 * replacementTarget node belongs to a different graph than originalTarget, so we
                 * need to match parameter back to the original graph and allocate a new
                 * MethodCallTargetNode for the original graph.
                 */
            ValueNode[] replacedArguments = new ValueNode[singleCallTarget.arguments().size()];
            for (int i = 0; i < replacedArguments.length; i++) {
                replacedArguments[i] = lookup(b, methodHandleArguments, singleCallTarget.arguments().get(i));
            }
            b.handleReplacedInvoke(singleCallTarget.invokeKind(), lookup(singleCallTarget.targetMethod()), replacedArguments, false);
        } else if (singleFunctionality instanceof LoadFieldNode) {
            LoadFieldNode fieldLoad = (LoadFieldNode) singleFunctionality;
            b.addPush(b.getInvokeReturnType().getJavaKind(), LoadFieldNode.create(null, lookup(b, methodHandleArguments, fieldLoad.object()), lookup(fieldLoad.field())));
        } else if (singleFunctionality instanceof StoreFieldNode) {
            StoreFieldNode fieldStore = (StoreFieldNode) singleFunctionality;
            b.add(new StoreFieldNode(lookup(b, methodHandleArguments, fieldStore.object()), lookup(fieldStore.field()), lookup(b, methodHandleArguments, fieldStore.value())));
        } else if (singleReturn.result() != null) {
            /* Replace the invocation with he constant result. */
            JavaConstant constantResult = singleReturn.result().asJavaConstant();
            assert b.getInvokeReturnType().getJavaKind() == constantResult.getJavaKind();
            b.addPush(constantResult.getJavaKind(), ConstantNode.forConstant(lookup(constantResult), universeProviders.getMetaAccess()));
        } else {
            /* No invoke and no return value, so nothing to do. */
            assert b.getInvokeReturnType().getJavaKind() == JavaKind.Void;
        }
    } catch (Throwable ex) {
        throw debug.handle(ex);
    }
}
Also used : ObjectStamp(org.graalvm.compiler.core.common.type.ObjectStamp) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) AccessFieldNode(org.graalvm.compiler.nodes.java.AccessFieldNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) PiNode(org.graalvm.compiler.nodes.PiNode) UnaryOpLogicNode(org.graalvm.compiler.nodes.UnaryOpLogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) Node(org.graalvm.compiler.graph.Node) WordTypes(org.graalvm.compiler.word.WordTypes) JavaConstant(jdk.vm.ci.meta.JavaConstant) PiNode(org.graalvm.compiler.nodes.PiNode) FrameState(org.graalvm.compiler.nodes.FrameState) UnaryOpLogicNode(org.graalvm.compiler.nodes.UnaryOpLogicNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) Invoke(org.graalvm.compiler.nodes.Invoke) PhaseContext(org.graalvm.compiler.phases.tiers.PhaseContext) SnippetReflectionProvider(org.graalvm.compiler.api.replacements.SnippetReflectionProvider) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) TypeReference(org.graalvm.compiler.core.common.type.TypeReference) GraphBuilderPhase(org.graalvm.compiler.java.GraphBuilderPhase) InvocationPlugins(org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins) Plugins(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins) StoreFieldNode(org.graalvm.compiler.nodes.java.StoreFieldNode) UnsupportedFeatureException(com.oracle.graal.pointsto.constraints.UnsupportedFeatureException) GraphBuilderConfiguration(org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration) DebugContext(org.graalvm.compiler.debug.DebugContext) LoadFieldNode(org.graalvm.compiler.nodes.java.LoadFieldNode) TrustedInterfaceTypePlugin(com.oracle.svm.core.graal.phases.TrustedInterfaceTypePlugin) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) AccessFieldNode(org.graalvm.compiler.nodes.java.AccessFieldNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase) InstanceOfNode(org.graalvm.compiler.nodes.java.InstanceOfNode) MethodHandlePlugin(org.graalvm.compiler.replacements.MethodHandlePlugin) WordOperationPlugin(org.graalvm.compiler.word.WordOperationPlugin)

Aggregations

FrameState (org.graalvm.compiler.nodes.FrameState)73 ValueNode (org.graalvm.compiler.nodes.ValueNode)38 Node (org.graalvm.compiler.graph.Node)27 FixedNode (org.graalvm.compiler.nodes.FixedNode)21 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)19 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)19 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)16 ParameterNode (org.graalvm.compiler.nodes.ParameterNode)16 PhiNode (org.graalvm.compiler.nodes.PhiNode)16 EndNode (org.graalvm.compiler.nodes.EndNode)15 MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)15 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)14 MergeNode (org.graalvm.compiler.nodes.MergeNode)14 ReturnNode (org.graalvm.compiler.nodes.ReturnNode)13 InvokeWithExceptionNode (org.graalvm.compiler.nodes.InvokeWithExceptionNode)12 StateSplit (org.graalvm.compiler.nodes.StateSplit)12 MonitorIdNode (org.graalvm.compiler.nodes.java.MonitorIdNode)12 DebugContext (org.graalvm.compiler.debug.DebugContext)11 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)11 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)11