Search in sources :

Example 6 with EndNode

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

the class BytecodeParser method afterInvocationPluginExecution.

/**
 * Performs any action required after execution of an invocation plugin. This includes
 * {@linkplain InvocationPluginAssertions#check checking} invocation plugin invariants as well
 * as weaving the {@code else} branch of the code woven by {@link #guardIntrinsic} if
 * {@code guard != null}.
 */
protected void afterInvocationPluginExecution(boolean pluginHandledInvoke, InvocationPluginAssertions assertions, IntrinsicGuard intrinsicGuard, InvokeKind invokeKind, ValueNode[] args, ResolvedJavaMethod targetMethod, JavaKind resultType, JavaType returnType) {
    assert assertions.check(pluginHandledInvoke);
    if (intrinsicGuard != null) {
        if (pluginHandledInvoke) {
            if (intrinsicGuard.nonIntrinsicBranch != null) {
                // Intrinsic emitted: emit a virtual call to the target method and
                // merge it with the intrinsic branch
                EndNode intrinsicEnd = append(new EndNode());
                FrameStateBuilder intrinsicState = null;
                FrameStateBuilder nonIntrinisicState = null;
                if (resultType != JavaKind.Void) {
                    intrinsicState = frameState.copy();
                    frameState.pop(resultType);
                    nonIntrinisicState = frameState;
                }
                lastInstr = intrinsicGuard.nonIntrinsicBranch;
                createNonInlinedInvoke(getActionForInvokeExceptionEdge(null), bci(), args, targetMethod, invokeKind, resultType, returnType, intrinsicGuard.profile);
                EndNode nonIntrinsicEnd = append(new EndNode());
                AbstractMergeNode mergeNode = graph.add(new MergeNode());
                mergeNode.addForwardEnd(intrinsicEnd);
                if (intrinsicState != null) {
                    intrinsicState.merge(mergeNode, nonIntrinisicState);
                    frameState = intrinsicState;
                }
                mergeNode.addForwardEnd(nonIntrinsicEnd);
                mergeNode.setStateAfter(frameState.create(stream.nextBCI(), mergeNode));
                lastInstr = mergeNode;
            }
        } else {
            // Intrinsic was not applied: remove intrinsic guard
            // and restore the original receiver node in the arguments array
            intrinsicGuard.lastInstr.setNext(null);
            GraphUtil.removeNewNodes(graph, intrinsicGuard.mark);
            lastInstr = intrinsicGuard.lastInstr;
            args[0] = intrinsicGuard.receiver;
        }
    }
}
Also used : AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode)

Example 7 with EndNode

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

the class LoopTransformations method insertPrePostLoops.

// This function splits candidate loops into pre, main and post loops,
// dividing the iteration space to facilitate the majority of iterations
// being executed in a main loop, which will have RCE implemented upon it.
// The initial loop form is constrained to single entry/exit, but can have
// flow. The translation looks like:
// 
// @formatter:off
// 
// (Simple Loop entry)                   (Pre Loop Entry)
// |                                  |
// (LoopBeginNode)                    (LoopBeginNode)
// |                                  |
// (Loop Control Test)<------   ==>  (Loop control Test)<------
// /               \       \         /               \       \
// (Loop Exit)      (Loop Body) |    (Loop Exit)      (Loop Body) |
// |                |       |        |                |       |
// (continue code)     (Loop End)  |  if (M < length)*   (Loop End)  |
// \       /       /      \           \      /
// ----->        /       |            ----->
// /  if ( ... )*
// /     /       \
// /     /         \
// /     /           \
// |     /     (Main Loop Entry)
// |    |             |
// |    |      (LoopBeginNode)
// |    |             |
// |    |     (Loop Control Test)<------
// |    |      /               \        \
// |    |  (Loop Exit)      (Loop Body) |
// \   \      |                |       |
// \   \     |            (Loop End)  |
// \   \    |                \       /
// \   \   |                 ------>
// \   \  |
// (Main Loop Merge)*
// |
// (Post Loop Entry)
// |
// (LoopBeginNode)
// |
// (Loop Control Test)<-----
// /               \       \
// (Loop Exit)     (Loop Body) |
// |               |       |
// (continue code)    (Loop End)  |
// \      /
// ----->
// 
// Key: "*" = optional.
// @formatter:on
// 
// The value "M" is the maximal value of the loop trip for the original
// loop. The value of "length" is applicable to the number of arrays found
// in the loop but is reduced if some or all of the arrays are known to be
// the same length as "M". The maximum number of tests can be equal to the
// number of arrays in the loop, where multiple instances of an array are
// subsumed into a single test for that arrays length.
// 
// If the optional main loop entry tests are absent, the Pre Loop exit
// connects to the Main loops entry and there is no merge hanging off the
// main loops exit to converge flow from said tests. All split use data
// flow is mitigated through phi(s) in the main merge if present and
// passed through the main and post loop phi(s) from the originating pre
// loop with final phi(s) and data flow patched to the "continue code".
// The pre loop is constrained to one iteration for now and will likely
// be updated to produce vector alignment if applicable.
public static LoopBeginNode insertPrePostLoops(LoopEx loop) {
    StructuredGraph graph = loop.loopBegin().graph();
    graph.getDebug().log("LoopTransformations.insertPrePostLoops %s", loop);
    LoopFragmentWhole preLoop = loop.whole();
    CountedLoopInfo preCounted = loop.counted();
    IfNode preLimit = preCounted.getLimitTest();
    assert preLimit != null;
    LoopBeginNode preLoopBegin = loop.loopBegin();
    InductionVariable preIv = preCounted.getCounter();
    LoopExitNode preLoopExitNode = preLoopBegin.getSingleLoopExit();
    FixedNode continuationNode = preLoopExitNode.next();
    // Each duplication is inserted after the original, ergo create the post loop first
    LoopFragmentWhole mainLoop = preLoop.duplicate();
    LoopFragmentWhole postLoop = preLoop.duplicate();
    preLoopBegin.incrementSplits();
    preLoopBegin.incrementSplits();
    preLoopBegin.setPreLoop();
    graph.getDebug().dump(DebugContext.VERBOSE_LEVEL, graph, "After duplication");
    LoopBeginNode mainLoopBegin = mainLoop.getDuplicatedNode(preLoopBegin);
    mainLoopBegin.setMainLoop();
    LoopBeginNode postLoopBegin = postLoop.getDuplicatedNode(preLoopBegin);
    postLoopBegin.setPostLoop();
    EndNode postEndNode = getBlockEndAfterLoopExit(postLoopBegin);
    AbstractMergeNode postMergeNode = postEndNode.merge();
    LoopExitNode postLoopExitNode = postLoopBegin.getSingleLoopExit();
    // Update the main loop phi initialization to carry from the pre loop
    for (PhiNode prePhiNode : preLoopBegin.phis()) {
        PhiNode mainPhiNode = mainLoop.getDuplicatedNode(prePhiNode);
        mainPhiNode.setValueAt(0, prePhiNode);
    }
    EndNode mainEndNode = getBlockEndAfterLoopExit(mainLoopBegin);
    AbstractMergeNode mainMergeNode = mainEndNode.merge();
    AbstractEndNode postEntryNode = postLoopBegin.forwardEnd();
    // In the case of no Bounds tests, we just flow right into the main loop
    AbstractBeginNode mainLandingNode = BeginNode.begin(postEntryNode);
    LoopExitNode mainLoopExitNode = mainLoopBegin.getSingleLoopExit();
    mainLoopExitNode.setNext(mainLandingNode);
    preLoopExitNode.setNext(mainLoopBegin.forwardEnd());
    // Add and update any phi edges as per merge usage as needed and update usages
    processPreLoopPhis(loop, mainLoop, postLoop);
    continuationNode.predecessor().clearSuccessors();
    postLoopExitNode.setNext(continuationNode);
    cleanupMerge(postMergeNode, postLoopExitNode);
    cleanupMerge(mainMergeNode, mainLandingNode);
    // Change the preLoop to execute one iteration for now
    updateMainLoopLimit(preLimit, preIv, mainLoop);
    updatePreLoopLimit(preLimit, preIv, preCounted);
    preLoopBegin.setLoopFrequency(1);
    mainLoopBegin.setLoopFrequency(Math.max(0.0, mainLoopBegin.loopFrequency() - 2));
    postLoopBegin.setLoopFrequency(Math.max(0.0, postLoopBegin.loopFrequency() - 1));
    // The pre and post loops don't require safepoints at all
    for (SafepointNode safepoint : preLoop.nodes().filter(SafepointNode.class)) {
        graph.removeFixed(safepoint);
    }
    for (SafepointNode safepoint : postLoop.nodes().filter(SafepointNode.class)) {
        graph.removeFixed(safepoint);
    }
    graph.getDebug().dump(DebugContext.DETAILED_LEVEL, graph, "InsertPrePostLoops %s", loop);
    return mainLoopBegin;
}
Also used : LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) SafepointNode(org.graalvm.compiler.nodes.SafepointNode) CountedLoopInfo(org.graalvm.compiler.loop.CountedLoopInfo) IfNode(org.graalvm.compiler.nodes.IfNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) LoopFragmentWhole(org.graalvm.compiler.loop.LoopFragmentWhole) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) InductionVariable(org.graalvm.compiler.loop.InductionVariable)

Example 8 with EndNode

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

the class LoopFragmentInside method getDuplicationReplacement.

@Override
@SuppressWarnings("try")
protected DuplicationReplacement getDuplicationReplacement() {
    final LoopBeginNode loopBegin = loop().loopBegin();
    final StructuredGraph graph = graph();
    return new DuplicationReplacement() {

        private EconomicMap<Node, Node> seenNode = EconomicMap.create(Equivalence.IDENTITY);

        @Override
        public Node replacement(Node original) {
            try (DebugCloseable position = original.withNodeSourcePosition()) {
                if (original == loopBegin) {
                    Node value = seenNode.get(original);
                    if (value != null) {
                        return value;
                    }
                    AbstractBeginNode newValue = graph.add(new BeginNode());
                    seenNode.put(original, newValue);
                    return newValue;
                }
                if (original instanceof LoopExitNode && ((LoopExitNode) original).loopBegin() == loopBegin) {
                    Node value = seenNode.get(original);
                    if (value != null) {
                        return value;
                    }
                    AbstractBeginNode newValue = graph.add(new BeginNode());
                    seenNode.put(original, newValue);
                    return newValue;
                }
                if (original instanceof LoopEndNode && ((LoopEndNode) original).loopBegin() == loopBegin) {
                    Node value = seenNode.get(original);
                    if (value != null) {
                        return value;
                    }
                    EndNode newValue = graph.add(new EndNode());
                    seenNode.put(original, newValue);
                    return newValue;
                }
                return original;
            }
        }
    };
}
Also used : LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) EconomicMap(org.graalvm.collections.EconomicMap) BeginNode(org.graalvm.compiler.nodes.BeginNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) CompareNode(org.graalvm.compiler.nodes.calc.CompareNode) ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) MemoryPhiNode(org.graalvm.compiler.nodes.memory.MemoryPhiNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) AddNode(org.graalvm.compiler.nodes.calc.AddNode) BeginNode(org.graalvm.compiler.nodes.BeginNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) IfNode(org.graalvm.compiler.nodes.IfNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) SubNode(org.graalvm.compiler.nodes.calc.SubNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) LogicNode(org.graalvm.compiler.nodes.LogicNode) SafepointNode(org.graalvm.compiler.nodes.SafepointNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) 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) DebugCloseable(org.graalvm.compiler.debug.DebugCloseable) DuplicationReplacement(org.graalvm.compiler.graph.Graph.DuplicationReplacement) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode)

Example 9 with EndNode

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

the class LoopFragmentWhole method getDuplicationReplacement.

@Override
protected DuplicationReplacement getDuplicationReplacement() {
    final FixedNode entry = loop().entryPoint();
    final Graph graph = this.graph();
    return new DuplicationReplacement() {

        private EndNode endNode;

        @Override
        public Node replacement(Node o) {
            if (o == entry) {
                if (endNode == null) {
                    endNode = graph.add(new EndNode());
                }
                return endNode;
            }
            return o;
        }
    };
}
Also used : Graph(org.graalvm.compiler.graph.Graph) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) EndNode(org.graalvm.compiler.nodes.EndNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) DuplicationReplacement(org.graalvm.compiler.graph.Graph.DuplicationReplacement)

Example 10 with EndNode

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

the class GraphOrder method visitForward.

private static void visitForward(ArrayList<Node> nodes, NodeBitMap visited, Node node, boolean floatingOnly) {
    try {
        assert node == null || node.isAlive() : node + " not alive";
        if (node != null && !visited.isMarked(node)) {
            if (floatingOnly && node instanceof FixedNode) {
                throw new GraalError("unexpected reference to fixed node: %s (this indicates an unexpected cycle)", node);
            }
            visited.mark(node);
            FrameState stateAfter = null;
            if (node instanceof StateSplit) {
                stateAfter = ((StateSplit) node).stateAfter();
            }
            for (Node input : node.inputs()) {
                if (input != stateAfter) {
                    visitForward(nodes, visited, input, true);
                }
            }
            if (node instanceof EndNode) {
                EndNode end = (EndNode) node;
                for (PhiNode phi : end.merge().phis()) {
                    visitForward(nodes, visited, phi.valueAt(end), true);
                }
            }
            nodes.add(node);
            if (node instanceof AbstractMergeNode) {
                for (PhiNode phi : ((AbstractMergeNode) node).phis()) {
                    visited.mark(phi);
                    nodes.add(phi);
                }
            }
            if (stateAfter != null) {
                visitForward(nodes, visited, stateAfter, true);
            }
        }
    } catch (GraalError e) {
        throw GraalGraphError.transformAndAddContext(e, node);
    }
}
Also used : GraalError(org.graalvm.compiler.debug.GraalError) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ConstantNode(org.graalvm.compiler.nodes.ConstantNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) VirtualObjectNode(org.graalvm.compiler.nodes.virtual.VirtualObjectNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ValueNode(org.graalvm.compiler.nodes.ValueNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FullInfopointNode(org.graalvm.compiler.nodes.FullInfopointNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) ProxyNode(org.graalvm.compiler.nodes.ProxyNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FrameState(org.graalvm.compiler.nodes.FrameState) StateSplit(org.graalvm.compiler.nodes.StateSplit)

Aggregations

EndNode (org.graalvm.compiler.nodes.EndNode)30 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)22 FixedNode (org.graalvm.compiler.nodes.FixedNode)18 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)16 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)15 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)14 LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)13 MergeNode (org.graalvm.compiler.nodes.MergeNode)13 Node (org.graalvm.compiler.graph.Node)12 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)12 ValueNode (org.graalvm.compiler.nodes.ValueNode)10 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)9 PhiNode (org.graalvm.compiler.nodes.PhiNode)9 BeginNode (org.graalvm.compiler.nodes.BeginNode)7 ControlSinkNode (org.graalvm.compiler.nodes.ControlSinkNode)7 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)7 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)7 FrameState (org.graalvm.compiler.nodes.FrameState)6 IfNode (org.graalvm.compiler.nodes.IfNode)6 ValuePhiNode (org.graalvm.compiler.nodes.ValuePhiNode)6