Search in sources :

Example 1 with StateSplit

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

the class IntrinsicContext method createFrameState.

public FrameState createFrameState(StructuredGraph graph, SideEffectsState sideEffects, StateSplit forStateSplit, NodeSourcePosition sourcePosition) {
    assert forStateSplit != graph.start();
    if (forStateSplit.hasSideEffect()) {
        if (sideEffects.isAfterSideEffect()) {
            // Only the last side effect on any execution path in a replacement
            // can inherit the stateAfter of the replaced node
            FrameState invalid = graph.add(new FrameState(INVALID_FRAMESTATE_BCI));
            if (graph.trackNodeSourcePosition()) {
                invalid.setNodeSourcePosition(sourcePosition);
            }
            for (StateSplit lastSideEffect : sideEffects.sideEffects()) {
                lastSideEffect.setStateAfter(invalid);
            }
        }
        sideEffects.addSideEffect(forStateSplit);
        FrameState frameState;
        if (forStateSplit instanceof ExceptionObjectNode) {
            frameState = graph.add(new FrameState(AFTER_EXCEPTION_BCI, (ExceptionObjectNode) forStateSplit));
        } else {
            frameState = graph.add(new FrameState(AFTER_BCI));
        }
        if (graph.trackNodeSourcePosition()) {
            frameState.setNodeSourcePosition(sourcePosition);
        }
        return frameState;
    } else {
        if (forStateSplit instanceof AbstractMergeNode) {
            // Merge nodes always need a frame state
            if (sideEffects.isAfterSideEffect()) {
                // A merge after one or more side effects
                FrameState frameState = graph.add(new FrameState(AFTER_BCI));
                if (graph.trackNodeSourcePosition()) {
                    frameState.setNodeSourcePosition(sourcePosition);
                }
                return frameState;
            } else {
                // A merge before any side effects
                FrameState frameState = graph.add(new FrameState(BEFORE_BCI));
                if (graph.trackNodeSourcePosition()) {
                    frameState.setNodeSourcePosition(sourcePosition);
                }
                return frameState;
            }
        } else {
            // Other non-side-effects do not need a state
            return null;
        }
    }
}
Also used : ExceptionObjectNode(org.graalvm.compiler.nodes.java.ExceptionObjectNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FrameState(org.graalvm.compiler.nodes.FrameState) StateSplit(org.graalvm.compiler.nodes.StateSplit)

Example 2 with StateSplit

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

the class InliningUtil method fixFrameStates.

private static void fixFrameStates(StructuredGraph graph, MergeNode originalMerge, PhiNode returnPhi) {
    // It is possible that some of the frame states that came from AFTER_BCI reference a Phi
    // node that was created to merge multiple returns. This can create cycles
    // (see GR-3949 and GR-3957).
    // To detect this, we follow the control paths starting from the merge node,
    // split the Phi node inputs at merges and assign the proper input to each frame state.
    NodeMap<Node> seen = new NodeMap<>(graph);
    ArrayDeque<Node> workList = new ArrayDeque<>();
    ArrayDeque<ValueNode> valueList = new ArrayDeque<>();
    workList.push(originalMerge);
    valueList.push(returnPhi);
    while (!workList.isEmpty()) {
        Node current = workList.pop();
        ValueNode currentValue = valueList.pop();
        if (seen.containsKey(current)) {
            continue;
        }
        seen.put(current, current);
        if (current instanceof StateSplit && current != originalMerge) {
            StateSplit stateSplit = (StateSplit) current;
            FrameState state = stateSplit.stateAfter();
            if (state != null && state.values().contains(returnPhi)) {
                int index = 0;
                FrameState duplicate = state.duplicate();
                for (ValueNode value : state.values()) {
                    if (value == returnPhi) {
                        duplicate.values().set(index, currentValue);
                    }
                    index++;
                }
                stateSplit.setStateAfter(duplicate);
                GraphUtil.tryKillUnused(state);
            }
        }
        if (current instanceof AbstractMergeNode) {
            AbstractMergeNode currentMerge = (AbstractMergeNode) current;
            for (EndNode pred : currentMerge.cfgPredecessors()) {
                ValueNode newValue = currentValue;
                if (currentMerge.isPhiAtMerge(currentValue)) {
                    PhiNode currentPhi = (PhiNode) currentValue;
                    newValue = currentPhi.valueAt(pred);
                }
                workList.push(pred);
                valueList.push(newValue);
            }
        } else if (current.predecessor() != null) {
            workList.push(current.predecessor());
            valueList.push(currentValue);
        }
    }
}
Also used : PhiNode(org.graalvm.compiler.nodes.PhiNode) 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) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FrameState(org.graalvm.compiler.nodes.FrameState) ArrayDeque(java.util.ArrayDeque) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) NodeMap(org.graalvm.compiler.graph.NodeMap) StateSplit(org.graalvm.compiler.nodes.StateSplit)

Example 3 with StateSplit

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

the class GraphUtil method approxSourceStackTraceElement.

/**
 * Gets an approximate source code location for a node if possible.
 *
 * @return the StackTraceElements if an approximate source location is found, null otherwise
 */
public static StackTraceElement[] approxSourceStackTraceElement(Node node) {
    NodeSourcePosition position = node.getNodeSourcePosition();
    if (position != null) {
        // positions.
        return approxSourceStackTraceElement(position);
    }
    ArrayList<StackTraceElement> elements = new ArrayList<>();
    Node n = node;
    while (n != null) {
        if (n instanceof MethodCallTargetNode) {
            elements.add(((MethodCallTargetNode) n).targetMethod().asStackTraceElement(-1));
            n = ((MethodCallTargetNode) n).invoke().asNode();
        }
        if (n instanceof StateSplit) {
            FrameState state = ((StateSplit) n).stateAfter();
            elements.addAll(Arrays.asList(approxSourceStackTraceElement(state)));
            break;
        }
        n = n.predecessor();
    }
    return elements.toArray(new StackTraceElement[elements.size()]);
}
Also used : MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MonitorIdNode(org.graalvm.compiler.nodes.java.MonitorIdNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) PiNode(org.graalvm.compiler.nodes.PiNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) VirtualArrayNode(org.graalvm.compiler.nodes.virtual.VirtualArrayNode) GuardNode(org.graalvm.compiler.nodes.GuardNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) ArrayList(java.util.ArrayList) FrameState(org.graalvm.compiler.nodes.FrameState) NodeSourcePosition(org.graalvm.compiler.graph.NodeSourcePosition) StateSplit(org.graalvm.compiler.nodes.StateSplit)

Example 4 with StateSplit

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

the class SnippetTemplate method rewireFrameStates.

protected void rewireFrameStates(ValueNode replacee, UnmodifiableEconomicMap<Node, Node> duplicates) {
    if (replacee instanceof StateSplit) {
        for (StateSplit sideEffectNode : sideEffectNodes) {
            assert ((StateSplit) replacee).hasSideEffect();
            Node sideEffectDup = duplicates.get(sideEffectNode.asNode());
            ((StateSplit) sideEffectDup).setStateAfter(((StateSplit) replacee).stateAfter());
        }
    }
}
Also used : MemoryNode(org.graalvm.compiler.nodes.memory.MemoryNode) MemoryAnchorNode(org.graalvm.compiler.nodes.memory.MemoryAnchorNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) ControlSinkNode(org.graalvm.compiler.nodes.ControlSinkNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) ExplodeLoopNode(org.graalvm.compiler.replacements.nodes.ExplodeLoopNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) LoadSnippetVarargParameterNode(org.graalvm.compiler.replacements.nodes.LoadSnippetVarargParameterNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoadIndexedNode(org.graalvm.compiler.nodes.java.LoadIndexedNode) ReturnNode(org.graalvm.compiler.nodes.ReturnNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) DeoptimizingNode(org.graalvm.compiler.nodes.DeoptimizingNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) FloatingNode(org.graalvm.compiler.nodes.calc.FloatingNode) MemoryPhiNode(org.graalvm.compiler.nodes.memory.MemoryPhiNode) StartNode(org.graalvm.compiler.nodes.StartNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) StoreIndexedNode(org.graalvm.compiler.nodes.java.StoreIndexedNode) MemoryMapNode(org.graalvm.compiler.nodes.memory.MemoryMapNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) StateSplit(org.graalvm.compiler.nodes.StateSplit)

Example 5 with StateSplit

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

the class CompileQueue method insertDeoptTests.

/**
 * Inserts a call to {@link DeoptTester#deoptTest} right after FixedWithNextNode StateSplits.
 *
 * @param method method that is being augmented with deopt test calls
 * @param graph The graph of a deoptimizable method or the corresponding deopt target method.
 */
private static void insertDeoptTests(HostedMethod method, StructuredGraph graph) {
    for (Node node : graph.getNodes()) {
        if (node instanceof FixedWithNextNode && node instanceof StateSplit && !(node instanceof InvokeNode) && !(node instanceof ForeignCallNode) && !(node instanceof DeoptTestNode) && !(method.isSynchronized() && node instanceof StartNode)) {
            FixedWithNextNode fixedWithNext = (FixedWithNextNode) node;
            FixedNode next = fixedWithNext.next();
            DeoptTestNode testNode = graph.add(new DeoptTestNode());
            fixedWithNext.setNext(null);
            testNode.setNext(next);
            fixedWithNext.setNext(testNode);
        }
    }
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) StartNode(org.graalvm.compiler.nodes.StartNode) ForeignCallNode(org.graalvm.compiler.nodes.extended.ForeignCallNode) StackValueNode(com.oracle.svm.core.graal.stackvalue.StackValueNode) MethodCallTargetNode(org.graalvm.compiler.nodes.java.MethodCallTargetNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) DeoptTestNode(com.oracle.svm.core.graal.nodes.DeoptTestNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) ForeignCallNode(org.graalvm.compiler.nodes.extended.ForeignCallNode) DeoptEntryNode(com.oracle.svm.core.graal.nodes.DeoptEntryNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) StartNode(org.graalvm.compiler.nodes.StartNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) ParameterNode(org.graalvm.compiler.nodes.ParameterNode) Node(org.graalvm.compiler.graph.Node) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) InvokeNode(org.graalvm.compiler.nodes.InvokeNode) DeoptTestNode(com.oracle.svm.core.graal.nodes.DeoptTestNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) StateSplit(org.graalvm.compiler.nodes.StateSplit)

Aggregations

StateSplit (org.graalvm.compiler.nodes.StateSplit)15 Node (org.graalvm.compiler.graph.Node)11 FrameState (org.graalvm.compiler.nodes.FrameState)11 ValueNode (org.graalvm.compiler.nodes.ValueNode)11 FixedNode (org.graalvm.compiler.nodes.FixedNode)10 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)9 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)8 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)7 PhiNode (org.graalvm.compiler.nodes.PhiNode)7 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)6 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)6 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)6 ReturnNode (org.graalvm.compiler.nodes.ReturnNode)6 MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)6 EndNode (org.graalvm.compiler.nodes.EndNode)5 ParameterNode (org.graalvm.compiler.nodes.ParameterNode)5 ExceptionObjectNode (org.graalvm.compiler.nodes.java.ExceptionObjectNode)5 BeginNode (org.graalvm.compiler.nodes.BeginNode)4 InvokeNode (org.graalvm.compiler.nodes.InvokeNode)4 KillingBeginNode (org.graalvm.compiler.nodes.KillingBeginNode)4