Search in sources :

Example 1 with UnreachableBeginNode

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

the class PlaceholderLogicNode method verifyWithExceptionNode.

/**
 * Verifies that a {@link WithExceptionNode} has only memory usages via the
 * {@link WithExceptionNode#next()} edge. On the {@link WithExceptionNode#exceptionEdge()} there
 * must be a {@link MemoryKill} (or an {@link UnreachableBeginNode}), otherwise we would not
 * know from which edge a memory usage is coming from.
 */
private static void verifyWithExceptionNode(ValueNode node) {
    if (node instanceof WithExceptionNode && node instanceof MemoryKill) {
        WithExceptionNode withExceptionNode = (WithExceptionNode) node;
        AbstractBeginNode exceptionEdge = withExceptionNode.exceptionEdge();
        if (exceptionEdge instanceof UnreachableBeginNode) {
            // exception edge is unreachable - we are good
            return;
        }
        GraalError.guarantee(exceptionEdge instanceof MemoryKill, "The exception edge of %s is not a memory kill %s", node, exceptionEdge);
        if (exceptionEdge instanceof SingleMemoryKill) {
            SingleMemoryKill exceptionEdgeKill = (SingleMemoryKill) exceptionEdge;
            if (exceptionEdgeKill.getKilledLocationIdentity().isAny()) {
                // exception edge kills any - we are good
                return;
            }
            // if the exception edge does not kill any, it must kill the same location
            GraalError.guarantee(withExceptionNode instanceof SingleMemoryKill, "Not a single memory kill: %s", withExceptionNode);
            SingleMemoryKill withExceptionKill = (SingleMemoryKill) withExceptionNode;
            GraalError.guarantee(withExceptionKill.getKilledLocationIdentity().equals(exceptionEdgeKill.getKilledLocationIdentity()), "Kill locations do not match: %s (%s) vs %s (%s)", withExceptionKill, withExceptionKill.getKilledLocationIdentity(), exceptionEdgeKill, exceptionEdgeKill.getKilledLocationIdentity());
        } else if (exceptionEdge instanceof MultiMemoryKill) {
            // for multi memory kills the locations must match
            MultiMemoryKill exceptionEdgeKill = (MultiMemoryKill) exceptionEdge;
            GraalError.guarantee(withExceptionNode instanceof MultiMemoryKill, "Not a single memory kill: %s", withExceptionNode);
            MultiMemoryKill withExceptionKill = (MultiMemoryKill) withExceptionNode;
            GraalError.guarantee(Arrays.equals(withExceptionKill.getKilledLocationIdentities(), exceptionEdgeKill.getKilledLocationIdentities()), "Kill locations do not match: %s (%s) vs %s (%s)", withExceptionKill, withExceptionKill.getKilledLocationIdentities(), exceptionEdgeKill, exceptionEdgeKill.getKilledLocationIdentities());
        } else {
            GraalError.shouldNotReachHere("Unexpected exception edge: " + exceptionEdge);
        }
    }
}
Also used : SingleMemoryKill(org.graalvm.compiler.nodes.memory.SingleMemoryKill) MultiMemoryKill(org.graalvm.compiler.nodes.memory.MultiMemoryKill) MemoryKill(org.graalvm.compiler.nodes.memory.MemoryKill) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) FallbackInvokeWithExceptionNode(org.graalvm.compiler.replacements.nodes.FallbackInvokeWithExceptionNode) MacroWithExceptionNode(org.graalvm.compiler.replacements.nodes.MacroWithExceptionNode) WithExceptionNode(org.graalvm.compiler.nodes.WithExceptionNode) MultiMemoryKill(org.graalvm.compiler.nodes.memory.MultiMemoryKill) UnreachableBeginNode(org.graalvm.compiler.nodes.UnreachableBeginNode) SingleMemoryKill(org.graalvm.compiler.nodes.memory.SingleMemoryKill) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 2 with UnreachableBeginNode

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

the class DeoptEntryNode method generate.

@Override
public void generate(NodeLIRBuilderTool gen) {
    LabelRef exceptionRef;
    AbstractBeginNode exceptionNode = exceptionEdge();
    if (exceptionNode instanceof UnreachableBeginNode) {
        exceptionRef = null;
    } else {
        /* Only register exception handler if it is meaningful. */
        exceptionRef = ((NodeLIRBuilder) gen).getLIRBlock(exceptionNode);
    }
    gen.getLIRGeneratorTool().append(new DeoptEntryOp(((NodeLIRBuilder) gen).stateForWithExceptionEdge(this, stateAfter(), exceptionRef)));
    /* Link to next() instruction. */
    gen.getLIRGeneratorTool().emitJump(((NodeLIRBuilder) gen).getLIRBlock(next()));
}
Also used : DeoptEntryOp(com.oracle.svm.core.graal.lir.DeoptEntryOp) UnreachableBeginNode(org.graalvm.compiler.nodes.UnreachableBeginNode) NodeLIRBuilder(org.graalvm.compiler.core.gen.NodeLIRBuilder) LabelRef(org.graalvm.compiler.lir.LabelRef) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 3 with UnreachableBeginNode

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

the class HostedBciBlockMapping method insertDeoptNode.

/**
 * Inserts either a DeoptEntryNode or DeoptProxyAnchorNode into the graph.
 */
private void insertDeoptNode(HostedBciBlockMapping.DeoptEntryInsertionPoint deopt) {
    /* Ensuring current frameState matches the expectations of the DeoptEntryInsertionPoint. */
    if (deopt instanceof HostedBciBlockMapping.DeoptBciBlock) {
        assert !frameState.rethrowException();
    } else {
        assert deopt instanceof HostedBciBlockMapping.DeoptExceptionDispatchBlock;
        assert frameState.rethrowException();
    }
    DeoptEntrySupport deoptNode = graph.add(deopt.isProxy() ? new DeoptProxyAnchorNode() : new DeoptEntryNode());
    FrameState stateAfter = frameState.create(deopt.frameStateBci(), deoptNode);
    deoptNode.setStateAfter(stateAfter);
    if (lastInstr != null) {
        lastInstr.setNext(deoptNode.asFixedNode());
    }
    if (deopt.isProxy()) {
        lastInstr = (DeoptProxyAnchorNode) deoptNode;
    } else {
        assert !deopt.duringCall() : "Implicit deopt entries from invokes cannot have explicit deopt entries.";
        DeoptEntryNode deoptEntryNode = (DeoptEntryNode) deoptNode;
        deoptEntryNode.setNext(graph.add(new DeoptEntryBeginNode()));
        /*
             * DeoptEntries for positions not during an exception dispatch (rethrowException) also
             * must be linked to their exception target.
             */
        if (!deopt.rethrowException()) {
            /*
                 * Saving frameState so that different modifications can be made for next() and
                 * exceptionEdge().
                 */
            FrameStateBuilder originalFrameState = frameState.copy();
            /* Creating exception object and its state after. */
            ExceptionObjectNode newExceptionObject = graph.add(new ExceptionObjectNode(getMetaAccess()));
            frameState.clearStack();
            frameState.push(JavaKind.Object, newExceptionObject);
            frameState.setRethrowException(true);
            int bci = ((HostedBciBlockMapping.DeoptBciBlock) deopt).getStartBci();
            newExceptionObject.setStateAfter(frameState.create(bci, newExceptionObject));
            deoptEntryNode.setExceptionEdge(newExceptionObject);
            /* Inserting proxies for the exception edge. */
            insertProxies(newExceptionObject, frameState);
            /* Linking exception object to exception target. */
            newExceptionObject.setNext(handleException(newExceptionObject, bci, false));
            /* Now restoring FrameState so proxies can be inserted for the next() edge. */
            frameState = originalFrameState;
        } else {
            /* Otherwise, indicate that the exception edge is not reachable. */
            AbstractBeginNode newExceptionEdge = graph.add(new UnreachableBeginNode());
            newExceptionEdge.setNext(graph.add(new LoweredDeadEndNode()));
            deoptEntryNode.setExceptionEdge(newExceptionEdge);
        }
        /* Correctly setting last instruction. */
        lastInstr = deoptEntryNode.next();
    }
    insertProxies(deoptNode.asFixedNode(), frameState);
}
Also used : ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) UnreachableBeginNode(org.graalvm.compiler.nodes.UnreachableBeginNode) FrameState(org.graalvm.compiler.nodes.FrameState) LoweredDeadEndNode(com.oracle.svm.core.graal.nodes.LoweredDeadEndNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) DeoptProxyAnchorNode(com.oracle.svm.core.graal.nodes.DeoptProxyAnchorNode) DeoptEntryNode(com.oracle.svm.core.graal.nodes.DeoptEntryNode) DeoptEntryBeginNode(com.oracle.svm.core.graal.nodes.DeoptEntryBeginNode) DeoptEntrySupport(com.oracle.svm.core.graal.nodes.DeoptEntrySupport) FrameStateBuilder(org.graalvm.compiler.java.FrameStateBuilder)

Example 4 with UnreachableBeginNode

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

the class ForeignCallWithExceptionNode method simplify.

@Override
public void simplify(SimplifierTool tool) {
    if (exceptionEdge instanceof UnreachableBeginNode) {
        FixedNode replacement = replaceWithNonThrowing();
        tool.addToWorkList(replacement);
    }
}
Also used : UnreachableBeginNode(org.graalvm.compiler.nodes.UnreachableBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode)

Example 5 with UnreachableBeginNode

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

the class PlaceholderLogicNode method rewireFrameStatesAfterFSA.

private void rewireFrameStatesAfterFSA(ValueNode replacee, UnmodifiableEconomicMap<Node, Node> duplicates) {
    DeoptimizingNode replaceeDeopt = (DeoptimizingNode) replacee;
    GraalError.guarantee(replaceeDeopt.canDeoptimize(), "Method expects the replacee to have deopt state");
    FrameState stateBefore = null;
    FrameState stateDuring = null;
    FrameState stateAfter = null;
    if (replaceeDeopt instanceof DeoptimizingNode.DeoptBefore) {
        stateBefore = ((DeoptimizingNode.DeoptBefore) replaceeDeopt).stateBefore();
    }
    if (replaceeDeopt instanceof DeoptimizingNode.DeoptDuring) {
        stateDuring = ((DeoptimizingNode.DeoptDuring) replaceeDeopt).stateDuring();
    }
    if (replaceeDeopt instanceof DeoptimizingNode.DeoptAfter) {
        stateAfter = ((DeoptimizingNode.DeoptAfter) replaceeDeopt).stateAfter();
    }
    if (stateAfter == null && stateDuring == null && stateBefore == null) {
        /*
             * There should only be no state available to transfer during testing or if the
             * replacee's graph itself is a substitution.
             */
        StructuredGraph graph = replacee.graph();
        boolean condition = graph.isStateAfterClearedForTesting() || graph.isSubstitution();
        GraalError.guarantee(condition, "No state available to transfer");
        return;
    }
    final ExceptionObjectNode exceptionObject;
    if (replacee instanceof WithExceptionNode) {
        WithExceptionNode withExceptionNode = (WithExceptionNode) replacee;
        if (withExceptionNode.exceptionEdge() instanceof ExceptionObjectNode) {
            exceptionObject = (ExceptionObjectNode) withExceptionNode.exceptionEdge();
        } else {
            GraalError.guarantee(withExceptionNode.exceptionEdge() instanceof UnreachableBeginNode, "Unexpected exception edge %s", withExceptionNode.exceptionEdge());
            exceptionObject = null;
        }
    } else {
        exceptionObject = null;
    }
    for (DeoptimizingNode deoptNode : deoptNodes) {
        DeoptimizingNode deoptDup = (DeoptimizingNode) duplicates.get(deoptNode.asNode());
        if (deoptDup.canDeoptimize()) {
            if (deoptDup instanceof ExceptionObjectNode) {
                ExceptionObjectNode newExceptionObject = (ExceptionObjectNode) deoptDup;
                rewireExceptionFrameState(exceptionObject, newExceptionObject, newExceptionObject);
                continue;
            }
            if (deoptDup instanceof DeoptimizingNode.DeoptBefore) {
                GraalError.guarantee(stateBefore != null, "Invalid stateBefore being transferred.");
                ((DeoptimizingNode.DeoptBefore) deoptDup).setStateBefore(stateBefore);
            }
            if (deoptDup instanceof DeoptimizingNode.DeoptDuring) {
                // compute a state "during" for a DeoptDuring inside the snippet depending
                // on what kind of states we had on the node we are replacing.
                // If the original node had a state "during" already, we just use that,
                // otherwise we need to find a strategy to compute a state during based on
                // some other state (before or after).
                DeoptimizingNode.DeoptDuring deoptDupDuring = (DeoptimizingNode.DeoptDuring) deoptDup;
                if (stateDuring != null) {
                    deoptDupDuring.setStateDuring(stateDuring);
                } else if (stateAfter != null) {
                    deoptDupDuring.computeStateDuring(stateAfter);
                } else if (stateBefore != null) {
                    boolean guarantee = ((DeoptBefore) replaceeDeopt).canUseAsStateDuring() || !deoptDupDuring.hasSideEffect();
                    GraalError.guarantee(guarantee, "Can't use stateBefore as stateDuring for state split %s", deoptDupDuring);
                    deoptDupDuring.setStateDuring(stateBefore);
                } else {
                    throw GraalError.shouldNotReachHere("No stateDuring assigned.");
                }
            }
            if (deoptDup instanceof DeoptimizingNode.DeoptAfter) {
                DeoptimizingNode.DeoptAfter deoptDupAfter = (DeoptimizingNode.DeoptAfter) deoptDup;
                if (stateAfter != null) {
                    deoptDupAfter.setStateAfter(stateAfter);
                } else {
                    boolean guarantee = stateBefore != null && !deoptDupAfter.hasSideEffect();
                    GraalError.guarantee(guarantee, "Can't use stateBefore as stateAfter for state split %s", deoptDupAfter);
                    deoptDupAfter.setStateAfter(stateBefore);
                }
            }
        }
    }
}
Also used : InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) FallbackInvokeWithExceptionNode(org.graalvm.compiler.replacements.nodes.FallbackInvokeWithExceptionNode) MacroWithExceptionNode(org.graalvm.compiler.replacements.nodes.MacroWithExceptionNode) WithExceptionNode(org.graalvm.compiler.nodes.WithExceptionNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) UnreachableBeginNode(org.graalvm.compiler.nodes.UnreachableBeginNode) DeoptBefore(org.graalvm.compiler.nodes.DeoptimizingNode.DeoptBefore) FrameState(org.graalvm.compiler.nodes.FrameState) DeoptimizingNode(org.graalvm.compiler.nodes.DeoptimizingNode)

Aggregations

UnreachableBeginNode (org.graalvm.compiler.nodes.UnreachableBeginNode)7 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)5 FrameState (org.graalvm.compiler.nodes.FrameState)4 InvokeWithExceptionNode (org.graalvm.compiler.nodes.InvokeWithExceptionNode)4 WithExceptionNode (org.graalvm.compiler.nodes.WithExceptionNode)4 ExceptionObjectNode (org.graalvm.compiler.nodes.java.ExceptionObjectNode)4 FallbackInvokeWithExceptionNode (org.graalvm.compiler.replacements.nodes.FallbackInvokeWithExceptionNode)4 MacroWithExceptionNode (org.graalvm.compiler.replacements.nodes.MacroWithExceptionNode)4 DeoptimizingNode (org.graalvm.compiler.nodes.DeoptimizingNode)3 FixedNode (org.graalvm.compiler.nodes.FixedNode)3 Node (org.graalvm.compiler.graph.Node)2 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)2 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)2 ControlSinkNode (org.graalvm.compiler.nodes.ControlSinkNode)2 DeoptBciSupplier (org.graalvm.compiler.nodes.DeoptBciSupplier)2 DeoptBefore (org.graalvm.compiler.nodes.DeoptimizingNode.DeoptBefore)2 EndNode (org.graalvm.compiler.nodes.EndNode)2 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)2 IfNode (org.graalvm.compiler.nodes.IfNode)2 LogicConstantNode (org.graalvm.compiler.nodes.LogicConstantNode)2