Search in sources :

Example 1 with AbstractEndNode

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

the class ConvertDeoptimizeToGuardPhase method processFixedGuardAndMerge.

@SuppressWarnings("try")
private void processFixedGuardAndMerge(FixedGuardNode fixedGuard, PhaseContext context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi, AbstractMergeNode merge) {
    List<EndNode> mergePredecessors = merge.cfgPredecessors().snapshot();
    for (int i = 0; i < mergePredecessors.size(); ++i) {
        AbstractEndNode mergePredecessor = mergePredecessors.get(i);
        if (!mergePredecessor.isAlive()) {
            break;
        }
        Constant xs;
        if (xPhi == null) {
            xs = x.asConstant();
        } else {
            xs = xPhi.valueAt(mergePredecessor).asConstant();
        }
        Constant ys;
        if (yPhi == null) {
            ys = y.asConstant();
        } else {
            ys = yPhi.valueAt(mergePredecessor).asConstant();
        }
        if (xs != null && ys != null && compare.condition().foldCondition(xs, ys, context.getConstantReflection(), compare.unorderedIsTrue()) == fixedGuard.isNegated()) {
            try (DebugCloseable position = fixedGuard.withNodeSourcePosition()) {
                propagateFixed(mergePredecessor, fixedGuard, context.getLowerer());
            }
        }
    }
}
Also used : AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) Constant(jdk.vm.ci.meta.Constant) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) DebugCloseable(org.graalvm.compiler.debug.DebugCloseable)

Example 2 with AbstractEndNode

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

the class DeadCodeEliminationPhase method iterateSuccessorsAndInputs.

private static void iterateSuccessorsAndInputs(NodeFlood flood) {
    Node.EdgeVisitor consumer = new Node.EdgeVisitor() {

        @Override
        public Node apply(Node n, Node succOrInput) {
            assert succOrInput.isAlive() : "dead successor or input " + succOrInput + " in " + n;
            flood.add(succOrInput);
            return succOrInput;
        }
    };
    for (Node current : flood) {
        if (current instanceof AbstractEndNode) {
            AbstractEndNode end = (AbstractEndNode) current;
            flood.add(end.merge());
        } else {
            current.applySuccessors(consumer);
            current.applyInputs(consumer);
        }
    }
}
Also used : GuardNode(org.graalvm.compiler.nodes.GuardNode) Node(org.graalvm.compiler.graph.Node) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode)

Example 3 with AbstractEndNode

use of org.graalvm.compiler.nodes.AbstractEndNode 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 4 with AbstractEndNode

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

the class GraphUtil method fixSurvivingAffectedMerges.

private static void fixSurvivingAffectedMerges(EconomicSet<Node> markedNodes, EconomicMap<AbstractMergeNode, List<AbstractEndNode>> unmarkedMerges) {
    MapCursor<AbstractMergeNode, List<AbstractEndNode>> cursor = unmarkedMerges.getEntries();
    while (cursor.advance()) {
        AbstractMergeNode merge = cursor.getKey();
        for (AbstractEndNode end : cursor.getValue()) {
            merge.removeEnd(end);
        }
        if (merge.phiPredecessorCount() == 1) {
            if (merge instanceof LoopBeginNode) {
                LoopBeginNode loopBegin = (LoopBeginNode) merge;
                assert merge.forwardEndCount() == 1;
                for (LoopExitNode loopExit : loopBegin.loopExits().snapshot()) {
                    if (markedNodes.contains(loopExit)) {
                        /*
                             * disconnect from loop begin so that reduceDegenerateLoopBegin doesn't
                             * transform it into a new beginNode
                             */
                        loopExit.replaceFirstInput(loopBegin, null);
                    }
                }
                merge.graph().reduceDegenerateLoopBegin(loopBegin);
            } else {
                merge.graph().reduceTrivialMerge(merge);
            }
        } else {
            assert merge.phiPredecessorCount() > 1 : merge;
        }
    }
}
Also used : LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) List(java.util.List) ArrayList(java.util.ArrayList) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode)

Example 5 with AbstractEndNode

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

Aggregations

AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)23 FixedNode (org.graalvm.compiler.nodes.FixedNode)17 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)16 Node (org.graalvm.compiler.graph.Node)14 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)13 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)11 ValueNode (org.graalvm.compiler.nodes.ValueNode)11 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)10 EndNode (org.graalvm.compiler.nodes.EndNode)9 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)9 PhiNode (org.graalvm.compiler.nodes.PhiNode)9 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)7 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)6 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)6 ProxyNode (org.graalvm.compiler.nodes.ProxyNode)6 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)6 ArrayList (java.util.ArrayList)5 IfNode (org.graalvm.compiler.nodes.IfNode)5 LogicNode (org.graalvm.compiler.nodes.LogicNode)5 ValuePhiNode (org.graalvm.compiler.nodes.ValuePhiNode)5