Search in sources :

Example 1 with NodeStack

use of org.graalvm.compiler.graph.NodeStack 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)

Example 2 with NodeStack

use of org.graalvm.compiler.graph.NodeStack in project graal by oracle.

the class GraphUtil method markFixedNodes.

private static void markFixedNodes(FixedNode node, EconomicSet<Node> markedNodes, EconomicMap<AbstractMergeNode, List<AbstractEndNode>> unmarkedMerges) {
    NodeStack workStack = new NodeStack();
    workStack.push(node);
    while (!workStack.isEmpty()) {
        Node fixedNode = workStack.pop();
        markedNodes.add(fixedNode);
        if (fixedNode instanceof AbstractMergeNode) {
            unmarkedMerges.removeKey((AbstractMergeNode) fixedNode);
        }
        while (fixedNode instanceof FixedWithNextNode) {
            fixedNode = ((FixedWithNextNode) fixedNode).next();
            if (fixedNode != null) {
                markedNodes.add(fixedNode);
            }
        }
        if (fixedNode instanceof ControlSplitNode) {
            for (Node successor : fixedNode.successors()) {
                workStack.push(successor);
            }
        } else if (fixedNode instanceof AbstractEndNode) {
            AbstractEndNode end = (AbstractEndNode) fixedNode;
            AbstractMergeNode merge = end.merge();
            if (merge != null) {
                assert !markedNodes.contains(merge) || (merge instanceof LoopBeginNode && end instanceof LoopEndNode) : merge;
                if (merge instanceof LoopBeginNode) {
                    if (end == ((LoopBeginNode) merge).forwardEnd()) {
                        workStack.push(merge);
                        continue;
                    }
                    if (markedNodes.contains(merge)) {
                        continue;
                    }
                }
                List<AbstractEndNode> endsSeen = unmarkedMerges.get(merge);
                if (endsSeen == null) {
                    endsSeen = new ArrayList<>(merge.forwardEndCount());
                    unmarkedMerges.put(merge, endsSeen);
                }
                endsSeen.add(end);
                if (!(end instanceof LoopEndNode) && endsSeen.size() == merge.forwardEndCount()) {
                    assert merge.forwardEnds().filter(n -> !markedNodes.contains(n)).isEmpty();
                    // all this merge's forward ends are marked: it needs to be killed
                    workStack.push(merge);
                }
            }
        }
    }
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) 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) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ArrayList(java.util.ArrayList) NodeStack(org.graalvm.compiler.graph.NodeStack) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) List(java.util.List) ArrayList(java.util.ArrayList) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode)

Example 3 with NodeStack

use of org.graalvm.compiler.graph.NodeStack in project graal by oracle.

the class GraphUtil method markUsages.

private static void markUsages(EconomicSet<Node> markedNodes) {
    NodeStack workStack = new NodeStack(markedNodes.size() + 4);
    for (Node marked : markedNodes) {
        workStack.push(marked);
    }
    while (!workStack.isEmpty()) {
        Node marked = workStack.pop();
        for (Node usage : marked.usages()) {
            if (!markedNodes.contains(usage)) {
                workStack.push(usage);
                markedNodes.add(usage);
            }
        }
    }
}
Also used : 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) NodeStack(org.graalvm.compiler.graph.NodeStack)

Aggregations

NodeStack (org.graalvm.compiler.graph.NodeStack)3 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)3 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)3 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)3 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)3 FixedNode (org.graalvm.compiler.nodes.FixedNode)3 Node (org.graalvm.compiler.graph.Node)2 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)2 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)2 GuardNode (org.graalvm.compiler.nodes.GuardNode)2 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)2 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)2 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)2 PhiNode (org.graalvm.compiler.nodes.PhiNode)2 PiNode (org.graalvm.compiler.nodes.PiNode)2 ProxyNode (org.graalvm.compiler.nodes.ProxyNode)2 ValueNode (org.graalvm.compiler.nodes.ValueNode)2 LoadIndexedNode (org.graalvm.compiler.nodes.java.LoadIndexedNode)2 MethodCallTargetNode (org.graalvm.compiler.nodes.java.MethodCallTargetNode)2 MonitorIdNode (org.graalvm.compiler.nodes.java.MonitorIdNode)2