Search in sources :

Example 1 with Simplifiable

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

the class ConvertDeoptimizeToGuardPhase method propagateFixed.

@SuppressWarnings("try")
private static void propagateFixed(FixedNode from, StaticDeoptimizingNode deopt, CoreProviders providers, LazyValue<LoopsData> lazyLoops) {
    Node current = from;
    while (current != null) {
        if (GraalOptions.GuardPriorities.getValue(from.getOptions()) && current instanceof FixedGuardNode) {
            FixedGuardNode otherGuard = (FixedGuardNode) current;
            if (otherGuard.computePriority().isHigherPriorityThan(deopt.computePriority())) {
                moveAsDeoptAfter(otherGuard, deopt);
                return;
            }
        } else if (current instanceof AbstractBeginNode) {
            if (current instanceof AbstractMergeNode) {
                AbstractMergeNode mergeNode = (AbstractMergeNode) current;
                FixedNode next = mergeNode.next();
                while (mergeNode.isAlive()) {
                    AbstractEndNode end = mergeNode.forwardEnds().first();
                    propagateFixed(end, deopt, providers, lazyLoops);
                }
                if (next.isAlive()) {
                    propagateFixed(next, deopt, providers, lazyLoops);
                }
                return;
            } else if (current.predecessor() instanceof IfNode) {
                AbstractBeginNode begin = (AbstractBeginNode) current;
                IfNode ifNode = (IfNode) current.predecessor();
                if (isOsrLoopExit(begin) || isCountedLoopExit(ifNode, lazyLoops)) {
                    moveAsDeoptAfter(begin, deopt);
                } else {
                    // Prioritize the source position of the IfNode
                    try (DebugCloseable closable = ifNode.withNodeSourcePosition()) {
                        StructuredGraph graph = ifNode.graph();
                        LogicNode conditionNode = ifNode.condition();
                        boolean negateGuardCondition = current == ifNode.trueSuccessor();
                        NodeSourcePosition survivingSuccessorPosition = negateGuardCondition ? ifNode.falseSuccessor().getNodeSourcePosition() : ifNode.trueSuccessor().getNodeSourcePosition();
                        FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deopt.getReason(), deopt.getAction(), deopt.getSpeculation(), negateGuardCondition, survivingSuccessorPosition));
                        FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
                        AbstractBeginNode survivingSuccessor;
                        if (negateGuardCondition) {
                            survivingSuccessor = ifNode.falseSuccessor();
                        } else {
                            survivingSuccessor = ifNode.trueSuccessor();
                        }
                        graph.removeSplitPropagate(ifNode, survivingSuccessor);
                        Node newGuard = guard;
                        if (survivingSuccessor instanceof LoopExitNode) {
                            newGuard = ProxyNode.forGuard(guard, (LoopExitNode) survivingSuccessor);
                        }
                        survivingSuccessor.replaceAtUsages(newGuard, InputType.Guard);
                        graph.getDebug().log("Converting deopt on %-5s branch of %s to guard for remaining branch %s.", negateGuardCondition, ifNode, survivingSuccessor);
                        FixedNode next = pred.next();
                        pred.setNext(guard);
                        guard.setNext(next);
                        assert providers != null;
                        SimplifierTool simplifierTool = GraphUtil.getDefaultSimplifier(providers, false, graph.getAssumptions(), graph.getOptions());
                        ((Simplifiable) survivingSuccessor).simplify(simplifierTool);
                    }
                }
                return;
            } else if (current.predecessor() == null || current.predecessor() instanceof ControlSplitNode) {
                assert current.predecessor() != null || (current instanceof StartNode && current == ((AbstractBeginNode) current).graph().start());
                moveAsDeoptAfter((AbstractBeginNode) current, deopt);
                return;
            }
        }
        current = current.predecessor();
    }
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) StartNode(org.graalvm.compiler.nodes.StartNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) GuardNode(org.graalvm.compiler.nodes.GuardNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) StartNode(org.graalvm.compiler.nodes.StartNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) StaticDeoptimizingNode(org.graalvm.compiler.nodes.StaticDeoptimizingNode) DeoptimizeNode(org.graalvm.compiler.nodes.DeoptimizeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode) SimplifierTool(org.graalvm.compiler.nodes.spi.SimplifierTool) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) DebugCloseable(org.graalvm.compiler.debug.DebugCloseable) NodeSourcePosition(org.graalvm.compiler.graph.NodeSourcePosition) Simplifiable(org.graalvm.compiler.nodes.spi.Simplifiable)

Example 2 with Simplifiable

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

the class LoopTransformations method fullUnroll.

@SuppressWarnings("try")
public static void fullUnroll(LoopEx loop, CoreProviders context, CanonicalizerPhase canonicalizer) {
    // assert loop.isCounted(); //TODO (gd) strengthen : counted with known trip count
    LoopBeginNode loopBegin = loop.loopBegin();
    StructuredGraph graph = loopBegin.graph();
    int initialNodeCount = graph.getNodeCount();
    SimplifierTool defaultSimplifier = GraphUtil.getDefaultSimplifier(context, canonicalizer.getCanonicalizeReads(), graph.getAssumptions(), graph.getOptions());
    /*
         * IMPORTANT: Canonicalizations inside the body of the remaining loop can introduce new
         * control flow that is not automatically picked up by the control flow graph computation of
         * the original LoopEx data structure, thus we disable simplification and manually simplify
         * conditions in the peeled iteration to simplify the exit path.
         */
    CanonicalizerPhase c = canonicalizer.copyWithoutSimplification();
    EconomicSetNodeEventListener l = new EconomicSetNodeEventListener();
    int peelings = 0;
    try (NodeEventScope ev = graph.trackNodeEvents(l)) {
        while (!loopBegin.isDeleted()) {
            Mark newNodes = graph.getMark();
            /*
                 * Mark is not enough for the canonicalization of the floating nodes in the unrolled
                 * code since pre-existing constants are not new nodes. Therefore, we canonicalize
                 * (without simplification) all floating nodes changed during peeling but only
                 * simplify new (in the peeled iteration) ones.
                 */
            EconomicSetNodeEventListener peeledListener = new EconomicSetNodeEventListener();
            try (NodeEventScope peeledScope = graph.trackNodeEvents(peeledListener)) {
                LoopTransformations.peel(loop);
            }
            graph.getDebug().dump(DebugContext.VERY_DETAILED_LEVEL, graph, "After peeling loop %s", loop);
            c.applyIncremental(graph, context, peeledListener.getNodes());
            loop.invalidateFragmentsAndIVs();
            for (Node n : graph.getNewNodes(newNodes)) {
                if (n.isAlive() && (n instanceof IfNode || n instanceof SwitchNode || n instanceof FixedGuardNode || n instanceof BeginNode)) {
                    Simplifiable s = (Simplifiable) n;
                    s.simplify(defaultSimplifier);
                    graph.getDebug().dump(DebugContext.VERY_DETAILED_LEVEL, graph, "After simplifying if %s", s);
                }
            }
            if (graph.getNodeCount() > initialNodeCount + MaximumDesiredSize.getValue(graph.getOptions()) * 2 || peelings > DefaultLoopPolicies.Options.FullUnrollMaxIterations.getValue(graph.getOptions())) {
                throw new RetryableBailoutException("FullUnroll : Graph seems to grow out of proportion");
            }
            peelings++;
        }
    }
    // Canonicalize with the original canonicalizer to capture all simplifications
    canonicalizer.applyIncremental(graph, context, l.getNodes());
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) OpaqueNode(org.graalvm.compiler.nodes.extended.OpaqueNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) IfNode(org.graalvm.compiler.nodes.IfNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) AddNode(org.graalvm.compiler.nodes.calc.AddNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) SwitchNode(org.graalvm.compiler.nodes.extended.SwitchNode) ConditionalNode(org.graalvm.compiler.nodes.calc.ConditionalNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) SafepointNode(org.graalvm.compiler.nodes.SafepointNode) ValueProxyNode(org.graalvm.compiler.nodes.ValueProxyNode) GuardPhiNode(org.graalvm.compiler.nodes.GuardPhiNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) Mark(org.graalvm.compiler.graph.Graph.Mark) IfNode(org.graalvm.compiler.nodes.IfNode) SimplifierTool(org.graalvm.compiler.nodes.spi.SimplifierTool) SwitchNode(org.graalvm.compiler.nodes.extended.SwitchNode) EconomicSetNodeEventListener(org.graalvm.compiler.phases.common.util.EconomicSetNodeEventListener) FixedGuardNode(org.graalvm.compiler.nodes.FixedGuardNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) NodeEventScope(org.graalvm.compiler.graph.Graph.NodeEventScope) RetryableBailoutException(org.graalvm.compiler.core.common.RetryableBailoutException) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) BeginNode(org.graalvm.compiler.nodes.BeginNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) CanonicalizerPhase(org.graalvm.compiler.phases.common.CanonicalizerPhase) Simplifiable(org.graalvm.compiler.nodes.spi.Simplifiable)

Aggregations

Node (org.graalvm.compiler.graph.Node)2 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)2 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)2 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)2 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)2 EndNode (org.graalvm.compiler.nodes.EndNode)2 FixedGuardNode (org.graalvm.compiler.nodes.FixedGuardNode)2 FixedNode (org.graalvm.compiler.nodes.FixedNode)2 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)2 IfNode (org.graalvm.compiler.nodes.IfNode)2 LogicNode (org.graalvm.compiler.nodes.LogicNode)2 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)2 ProxyNode (org.graalvm.compiler.nodes.ProxyNode)2 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)2 ValueNode (org.graalvm.compiler.nodes.ValueNode)2 CompareNode (org.graalvm.compiler.nodes.calc.CompareNode)2 Simplifiable (org.graalvm.compiler.nodes.spi.Simplifiable)2 SimplifierTool (org.graalvm.compiler.nodes.spi.SimplifierTool)2 RetryableBailoutException (org.graalvm.compiler.core.common.RetryableBailoutException)1 DebugCloseable (org.graalvm.compiler.debug.DebugCloseable)1