Search in sources :

Example 1 with InvokeWithExceptionNode

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

the class ExceptionObjectNode method lower.

@Override
public void lower(LoweringTool tool) {
    if (graph().getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
        /*
             * Now the lowering to BeginNode+LoadExceptionNode can be performed, since no more
             * deopts can float in between the begin node and the load exception node.
             */
        LocationIdentity locationsKilledByInvoke = ((InvokeWithExceptionNode) predecessor()).getLocationIdentity();
        AbstractBeginNode entry = graph().add(KillingBeginNode.create(locationsKilledByInvoke));
        LoadExceptionObjectNode loadException = graph().add(new LoadExceptionObjectNode(stamp(NodeView.DEFAULT)));
        loadException.setStateAfter(stateAfter());
        replaceAtUsages(InputType.Value, loadException);
        graph().replaceFixedWithFixed(this, entry);
        entry.graph().addAfterFixed(entry, loadException);
        loadException.lower(tool);
    }
}
Also used : InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) LocationIdentity(org.graalvm.word.LocationIdentity) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 2 with InvokeWithExceptionNode

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

the class InliningUtil method finishInlining.

private static ValueNode finishInlining(Invoke invoke, StructuredGraph graph, FixedNode firstNode, List<ReturnNode> returnNodes, UnwindNode unwindNode, Assumptions inlinedAssumptions, StructuredGraph inlineGraph) {
    FixedNode invokeNode = invoke.asNode();
    FrameState stateAfter = invoke.stateAfter();
    assert stateAfter == null || stateAfter.isAlive();
    invokeNode.replaceAtPredecessor(firstNode);
    if (invoke instanceof InvokeWithExceptionNode) {
        InvokeWithExceptionNode invokeWithException = ((InvokeWithExceptionNode) invoke);
        if (unwindNode != null && unwindNode.isAlive()) {
            assert unwindNode.predecessor() != null;
            assert invokeWithException.exceptionEdge().successors().count() == 1;
            ExceptionObjectNode obj = (ExceptionObjectNode) invokeWithException.exceptionEdge();
            obj.replaceAtUsages(unwindNode.exception());
            Node n = obj.next();
            obj.setNext(null);
            unwindNode.replaceAndDelete(n);
            obj.replaceAtPredecessor(null);
            obj.safeDelete();
        } else {
            invokeWithException.killExceptionEdge();
        }
        // get rid of memory kill
        AbstractBeginNode begin = invokeWithException.next();
        if (begin instanceof KillingBeginNode) {
            AbstractBeginNode newBegin = new BeginNode();
            graph.addAfterFixed(begin, graph.add(newBegin));
            begin.replaceAtUsages(newBegin);
            graph.removeFixed(begin);
        }
    } else {
        if (unwindNode != null && unwindNode.isAlive()) {
            DeoptimizeNode deoptimizeNode = addDeoptimizeNode(graph, DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler);
            unwindNode.replaceAndDelete(deoptimizeNode);
        }
    }
    ValueNode returnValue;
    if (!returnNodes.isEmpty()) {
        FixedNode n = invoke.next();
        invoke.setNext(null);
        if (returnNodes.size() == 1) {
            ReturnNode returnNode = returnNodes.get(0);
            returnValue = returnNode.result();
            invokeNode.replaceAtUsages(returnValue);
            returnNode.replaceAndDelete(n);
        } else {
            MergeNode merge = graph.add(new MergeNode());
            merge.setStateAfter(stateAfter);
            returnValue = mergeReturns(merge, returnNodes);
            invokeNode.replaceAtUsages(returnValue);
            if (merge.isPhiAtMerge(returnValue)) {
                fixFrameStates(graph, merge, (PhiNode) returnValue);
            }
            merge.setNext(n);
        }
    } else {
        returnValue = null;
        invokeNode.replaceAtUsages(null);
        GraphUtil.killCFG(invoke.next());
    }
    // Copy assumptions from inlinee to caller
    Assumptions assumptions = graph.getAssumptions();
    if (assumptions != null) {
        if (inlinedAssumptions != null) {
            assumptions.record(inlinedAssumptions);
        }
    } else {
        assert inlinedAssumptions == null : String.format("cannot inline graph (%s) which makes assumptions into a graph (%s) that doesn't", inlineGraph, graph);
    }
    // Copy inlined methods from inlinee to caller
    graph.updateMethods(inlineGraph);
    // Update the set of accessed fields
    if (GraalOptions.GeneratePIC.getValue(graph.getOptions())) {
        graph.updateFields(inlineGraph);
    }
    if (inlineGraph.hasUnsafeAccess()) {
        graph.markUnsafeAccess();
    }
    assert inlineGraph.getSpeculationLog() == null || inlineGraph.getSpeculationLog() == graph.getSpeculationLog() : "Only the root graph should have a speculation log";
    return returnValue;
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) CallTargetNode(org.graalvm.compiler.nodes.CallTargetNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) PiNode(org.graalvm.compiler.nodes.PiNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) MonitorExitNode(org.graalvm.compiler.nodes.java.MonitorExitNode) IsNullNode(org.graalvm.compiler.nodes.calc.IsNullNode) GuardingNode(org.graalvm.compiler.nodes.extended.GuardingNode) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) StartNode(org.graalvm.compiler.nodes.StartNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) UnwindNode(org.graalvm.compiler.nodes.UnwindNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) ForeignCallNode(org.graalvm.compiler.nodes.extended.ForeignCallNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) FrameState(org.graalvm.compiler.nodes.FrameState) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Assumptions(jdk.vm.ci.meta.Assumptions) KillingBeginNode(org.graalvm.compiler.nodes.KillingBeginNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode)

Example 3 with InvokeWithExceptionNode

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

the class MultiTypeGuardInlineInfo method inlineMultipleMethods.

private EconomicSet<Node> inlineMultipleMethods(StructuredGraph graph, Providers providers) {
    int numberOfMethods = concretes.size();
    FixedNode continuation = invoke.next();
    // setup merge and phi nodes for results and exceptions
    AbstractMergeNode returnMerge = graph.add(new MergeNode());
    returnMerge.setStateAfter(invoke.stateAfter());
    PhiNode returnValuePhi = null;
    if (invoke.asNode().getStackKind() != JavaKind.Void) {
        returnValuePhi = graph.addWithoutUnique(new ValuePhiNode(invoke.asNode().stamp(NodeView.DEFAULT).unrestricted(), returnMerge));
    }
    AbstractMergeNode exceptionMerge = null;
    PhiNode exceptionObjectPhi = null;
    if (invoke instanceof InvokeWithExceptionNode) {
        InvokeWithExceptionNode invokeWithException = (InvokeWithExceptionNode) invoke;
        ExceptionObjectNode exceptionEdge = (ExceptionObjectNode) invokeWithException.exceptionEdge();
        exceptionMerge = graph.add(new MergeNode());
        FixedNode exceptionSux = exceptionEdge.next();
        graph.addBeforeFixed(exceptionSux, exceptionMerge);
        exceptionObjectPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(JavaKind.Object), exceptionMerge));
        exceptionMerge.setStateAfter(exceptionEdge.stateAfter().duplicateModified(invoke.stateAfter().bci, true, JavaKind.Object, new JavaKind[] { JavaKind.Object }, new ValueNode[] { exceptionObjectPhi }));
    }
    // create one separate block for each invoked method
    AbstractBeginNode[] successors = new AbstractBeginNode[numberOfMethods + 1];
    for (int i = 0; i < numberOfMethods; i++) {
        successors[i] = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, true);
    }
    // create the successor for an unknown type
    FixedNode unknownTypeSux;
    if (shouldFallbackToInvoke()) {
        unknownTypeSux = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, false);
    } else {
        unknownTypeSux = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated));
    }
    successors[successors.length - 1] = BeginNode.begin(unknownTypeSux);
    // replace the invoke exception edge
    if (invoke instanceof InvokeWithExceptionNode) {
        InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invoke;
        ExceptionObjectNode exceptionEdge = (ExceptionObjectNode) invokeWithExceptionNode.exceptionEdge();
        exceptionEdge.replaceAtUsages(exceptionObjectPhi);
        exceptionEdge.setNext(null);
        GraphUtil.killCFG(invokeWithExceptionNode.exceptionEdge());
    }
    assert invoke.asNode().isAlive();
    // replace the invoke with a switch on the type of the actual receiver
    boolean methodDispatch = createDispatchOnTypeBeforeInvoke(graph, successors, false, providers.getStampProvider(), providers.getConstantReflection());
    assert invoke.next() == continuation;
    invoke.setNext(null);
    returnMerge.setNext(continuation);
    if (returnValuePhi != null) {
        invoke.asNode().replaceAtUsages(returnValuePhi);
    }
    invoke.asNode().safeDelete();
    ArrayList<PiNode> replacementNodes = new ArrayList<>();
    // prepare the anchors for the invokes
    for (int i = 0; i < numberOfMethods; i++) {
        AbstractBeginNode node = successors[i];
        Invoke invokeForInlining = (Invoke) node.next();
        ResolvedJavaType commonType;
        if (methodDispatch) {
            commonType = concretes.get(i).getDeclaringClass();
        } else {
            commonType = getLeastCommonType(i);
        }
        ValueNode receiver = ((MethodCallTargetNode) invokeForInlining.callTarget()).receiver();
        boolean exact = (getTypeCount(i) == 1 && !methodDispatch);
        PiNode anchoredReceiver = InliningUtil.createAnchoredReceiver(graph, node, commonType, receiver, exact);
        invokeForInlining.callTarget().replaceFirstInput(receiver, anchoredReceiver);
        assert !anchoredReceiver.isDeleted() : anchoredReceiver;
        replacementNodes.add(anchoredReceiver);
    }
    if (shouldFallbackToInvoke()) {
        replacementNodes.add(null);
    }
    EconomicSet<Node> canonicalizeNodes = EconomicSet.create(Equivalence.DEFAULT);
    // do the actual inlining for every invoke
    for (int i = 0; i < numberOfMethods; i++) {
        Invoke invokeForInlining = (Invoke) successors[i].next();
        canonicalizeNodes.addAll(doInline(i, invokeForInlining));
    }
    if (returnValuePhi != null) {
        canonicalizeNodes.add(returnValuePhi);
    }
    return canonicalizeNodes;
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) LoadHubNode(org.graalvm.compiler.nodes.extended.LoadHubNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) PiNode(org.graalvm.compiler.nodes.PiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) TypeSwitchNode(org.graalvm.compiler.nodes.java.TypeSwitchNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) ArrayList(java.util.ArrayList) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) PiNode(org.graalvm.compiler.nodes.PiNode) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) Invoke(org.graalvm.compiler.nodes.Invoke) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) JavaKind(jdk.vm.ci.meta.JavaKind)

Example 4 with InvokeWithExceptionNode

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

the class RemoveUnwindPhase method run.

@Override
protected void run(StructuredGraph graph) {
    SharedMethod method = (SharedMethod) graph.method();
    if (method.isDeoptTarget()) {
        /*
             * Deoptimization targets need need to have an exception entry point for every invoke.
             * This decouples deoptimization from exception handling: the exception handling
             * mechanism can just deliver an exception to a deoptimized method without any checks.
             */
        return;
    }
    List<InvokeWithExceptionNode> invocations = new ArrayList<>();
    for (UnwindNode node : graph.getNodes().filter(UnwindNode.class)) {
        walkBack(node.predecessor(), node, invocations);
    }
    /*
         * Modify graph only after all suitable invocations are found, to avoid problems with
         * deleted nodes during graph traversal.
         */
    for (InvokeWithExceptionNode node : invocations) {
        InvokeNode replacement = node.graph().add(new InvokeNode(node.callTarget(), node.bci(), node.stamp(NodeView.DEFAULT)));
        replacement.setStateAfter(node.stateAfter());
        node.killExceptionEdge();
        node.graph().replaceSplit(node, replacement, node.next());
    }
}
Also used : InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) ArrayList(java.util.ArrayList) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) SharedMethod(com.oracle.svm.core.meta.SharedMethod) UnwindNode(org.graalvm.compiler.nodes.UnwindNode)

Example 5 with InvokeWithExceptionNode

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

the class TruffleBoundaryPhase method run.

@Override
@SuppressWarnings("deprecation")
protected void run(StructuredGraph graph) {
    for (Node n : graph.getNodes()) {
        if (n instanceof InvokeWithExceptionNode) {
            InvokeWithExceptionNode invoke = (InvokeWithExceptionNode) n;
            ExceptionObjectNode exceptionObject = (ExceptionObjectNode) invoke.exceptionEdge();
            FixedNode originalNext = exceptionObject.next();
            if (!(originalNext instanceof DeoptimizeNode)) {
                TruffleBoundary truffleBoundary = invoke.callTarget().targetMethod().getAnnotation(TruffleBoundary.class);
                if (truffleBoundary != null) {
                    if (!truffleBoundary.throwsControlFlowException() && truffleBoundary.transferToInterpreterOnException()) {
                        addDeoptimizeNode(graph, originalNext);
                    }
                }
            }
        }
    }
}
Also used : InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) TruffleBoundary(com.oracle.truffle.api.CompilerDirectives.TruffleBoundary) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) Node(org.graalvm.compiler.graph.Node) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode)

Aggregations

InvokeWithExceptionNode (org.graalvm.compiler.nodes.InvokeWithExceptionNode)25 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)11 ValueNode (org.graalvm.compiler.nodes.ValueNode)11 ExceptionObjectNode (org.graalvm.compiler.nodes.java.ExceptionObjectNode)11 FixedNode (org.graalvm.compiler.nodes.FixedNode)10 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)9 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)9 Node (org.graalvm.compiler.graph.Node)8 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)8 MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)8 DeoptimizeNode (org.graalvm.compiler.nodes.DeoptimizeNode)7 EndNode (org.graalvm.compiler.nodes.EndNode)7 FrameState (org.graalvm.compiler.nodes.FrameState)7 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)6 InvokeNode (org.graalvm.compiler.nodes.InvokeNode)6 MergeNode (org.graalvm.compiler.nodes.MergeNode)6 ParameterNode (org.graalvm.compiler.nodes.ParameterNode)6 UnwindNode (org.graalvm.compiler.nodes.UnwindNode)6 ArrayList (java.util.ArrayList)5 JavaKind (jdk.vm.ci.meta.JavaKind)5