Search in sources :

Example 1 with AbstractMergeNode

use of org.graalvm.compiler.nodes.AbstractMergeNode 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 AbstractMergeNode

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

the class ProfileNode method simplify.

@Override
public void simplify(SimplifierTool tool) {
    for (Node p = predecessor(); p != null; p = p.predecessor()) {
        // Terminate search when we hit a control split or merge.
        if (p instanceof ControlSplitNode || p instanceof AbstractMergeNode) {
            break;
        }
        if (p instanceof ProfileNode) {
            ProfileNode that = (ProfileNode) p;
            if (this.canBeMergedWith(that)) {
                that.setStep(this.getStep() + that.getStep());
                removeFixedWithUnusedInputs(this);
                tool.addToWorkList(that);
                break;
            }
        }
    }
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) DeoptimizingFixedWithNextNode(org.graalvm.compiler.nodes.DeoptimizingFixedWithNextNode) Node(org.graalvm.compiler.graph.Node) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode)

Example 3 with AbstractMergeNode

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

the class ConvertDeoptimizeToGuardPhase method processFixedGuardAndPhis.

private void processFixedGuardAndPhis(FixedGuardNode fixedGuard, PhaseContext context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi) {
    AbstractBeginNode pred = AbstractBeginNode.prevBegin(fixedGuard);
    if (pred instanceof AbstractMergeNode) {
        AbstractMergeNode merge = (AbstractMergeNode) pred;
        if (xPhi != null && xPhi.merge() != merge) {
            return;
        }
        if (yPhi != null && yPhi.merge() != merge) {
            return;
        }
        processFixedGuardAndMerge(fixedGuard, context, compare, x, xPhi, y, yPhi, merge);
    }
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Example 4 with AbstractMergeNode

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

the class DeoptimizationGroupingPhase method run.

@Override
protected void run(StructuredGraph graph, MidTierContext context) {
    ControlFlowGraph cfg = null;
    for (FrameState fs : graph.getNodes(FrameState.TYPE)) {
        FixedNode target = null;
        PhiNode reasonActionPhi = null;
        PhiNode speculationPhi = null;
        List<AbstractDeoptimizeNode> obsoletes = null;
        for (AbstractDeoptimizeNode deopt : fs.usages().filter(AbstractDeoptimizeNode.class)) {
            if (target == null) {
                target = deopt;
            } else {
                if (cfg == null) {
                    cfg = ControlFlowGraph.compute(graph, true, true, false, false);
                }
                AbstractMergeNode merge;
                if (target instanceof AbstractDeoptimizeNode) {
                    merge = graph.add(new MergeNode());
                    EndNode firstEnd = graph.add(new EndNode());
                    ValueNode actionAndReason = ((AbstractDeoptimizeNode) target).getActionAndReason(context.getMetaAccess());
                    ValueNode speculation = ((AbstractDeoptimizeNode) target).getSpeculation(context.getMetaAccess());
                    reasonActionPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(actionAndReason.getStackKind()), merge));
                    speculationPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(speculation.getStackKind()), merge));
                    merge.addForwardEnd(firstEnd);
                    reasonActionPhi.addInput(actionAndReason);
                    speculationPhi.addInput(speculation);
                    target.replaceAtPredecessor(firstEnd);
                    exitLoops((AbstractDeoptimizeNode) target, firstEnd, cfg);
                    merge.setNext(graph.add(new DynamicDeoptimizeNode(reasonActionPhi, speculationPhi)));
                    obsoletes = new LinkedList<>();
                    obsoletes.add((AbstractDeoptimizeNode) target);
                    target = merge;
                } else {
                    merge = (AbstractMergeNode) target;
                }
                EndNode newEnd = graph.add(new EndNode());
                merge.addForwardEnd(newEnd);
                reasonActionPhi.addInput(deopt.getActionAndReason(context.getMetaAccess()));
                speculationPhi.addInput(deopt.getSpeculation(context.getMetaAccess()));
                deopt.replaceAtPredecessor(newEnd);
                exitLoops(deopt, newEnd, cfg);
                obsoletes.add(deopt);
            }
        }
        if (obsoletes != null) {
            ((DynamicDeoptimizeNode) ((AbstractMergeNode) target).next()).setStateBefore(fs);
            for (AbstractDeoptimizeNode obsolete : obsoletes) {
                obsolete.safeDelete();
            }
        }
    }
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) DynamicDeoptimizeNode(org.graalvm.compiler.nodes.DynamicDeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FrameState(org.graalvm.compiler.nodes.FrameState) AbstractDeoptimizeNode(org.graalvm.compiler.nodes.AbstractDeoptimizeNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) EndNode(org.graalvm.compiler.nodes.EndNode) ControlFlowGraph(org.graalvm.compiler.nodes.cfg.ControlFlowGraph) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Example 5 with AbstractMergeNode

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

the class PropagateDeoptimizeProbabilityPhase method run.

@Override
@SuppressWarnings("try")
protected void run(final StructuredGraph graph, PhaseContext context) {
    assert !graph.hasValueProxies() : "ConvertDeoptimizeToGuardPhase always creates proxies";
    if (graph.hasNode(AbstractDeoptimizeNode.TYPE)) {
        NodeStack stack = new NodeStack();
        EconomicMap<ControlSplitNode, EconomicSet<AbstractBeginNode>> reachableSplits = EconomicMap.create();
        // Mark all control flow nodes that are post-dominated by a deoptimization.
        for (AbstractDeoptimizeNode d : graph.getNodes(AbstractDeoptimizeNode.TYPE)) {
            stack.push(AbstractBeginNode.prevBegin(d));
            while (!stack.isEmpty()) {
                AbstractBeginNode beginNode = (AbstractBeginNode) stack.pop();
                FixedNode fixedNode = (FixedNode) beginNode.predecessor();
                if (fixedNode == null) {
                // Can happen for start node.
                } else if (fixedNode instanceof AbstractMergeNode) {
                    AbstractMergeNode mergeNode = (AbstractMergeNode) fixedNode;
                    for (AbstractEndNode end : mergeNode.forwardEnds()) {
                        AbstractBeginNode newBeginNode = AbstractBeginNode.prevBegin(end);
                        stack.push(newBeginNode);
                    }
                } else if (fixedNode instanceof ControlSplitNode) {
                    ControlSplitNode controlSplitNode = (ControlSplitNode) fixedNode;
                    EconomicSet<AbstractBeginNode> reachableSuccessors = reachableSplits.get(controlSplitNode);
                    if (reachableSuccessors == null) {
                        reachableSuccessors = EconomicSet.create();
                        reachableSplits.put(controlSplitNode, reachableSuccessors);
                    }
                    if (controlSplitNode.getSuccessorCount() == reachableSuccessors.size() - 1) {
                        // All successors of this split lead to deopt, propagate reachability
                        // further upwards.
                        reachableSplits.removeKey(controlSplitNode);
                        stack.push(AbstractBeginNode.prevBegin((FixedNode) controlSplitNode.predecessor()));
                    } else {
                        reachableSuccessors.add(beginNode);
                    }
                } else {
                    stack.push(AbstractBeginNode.prevBegin(fixedNode));
                }
            }
        }
        // Make sure the probability on the path towards the deoptimization is 0.0.
        MapCursor<ControlSplitNode, EconomicSet<AbstractBeginNode>> entries = reachableSplits.getEntries();
        while (entries.advance()) {
            ControlSplitNode controlSplitNode = entries.getKey();
            EconomicSet<AbstractBeginNode> value = entries.getValue();
            for (AbstractBeginNode begin : value) {
                double probability = controlSplitNode.probability(begin);
                if (probability != 0.0) {
                    controlSplitNode.setProbability(begin, 0.0);
                }
            }
        }
    }
}
Also used : AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) NodeStack(org.graalvm.compiler.graph.NodeStack) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) EconomicSet(org.graalvm.collections.EconomicSet) AbstractDeoptimizeNode(org.graalvm.compiler.nodes.AbstractDeoptimizeNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode)

Aggregations

AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)59 FixedNode (org.graalvm.compiler.nodes.FixedNode)31 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)28 EndNode (org.graalvm.compiler.nodes.EndNode)24 Node (org.graalvm.compiler.graph.Node)22 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)22 ValueNode (org.graalvm.compiler.nodes.ValueNode)22 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)20 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)19 PhiNode (org.graalvm.compiler.nodes.PhiNode)18 MergeNode (org.graalvm.compiler.nodes.MergeNode)16 ValuePhiNode (org.graalvm.compiler.nodes.ValuePhiNode)14 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)13 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)13 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)13 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)12 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)11 ArrayList (java.util.ArrayList)10 FrameState (org.graalvm.compiler.nodes.FrameState)10 IfNode (org.graalvm.compiler.nodes.IfNode)9