Search in sources :

Example 6 with LoopEndNode

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

the class PostOrderNodeIterator method apply.

public void apply() {
    FixedNode current = start;
    do {
        if (current instanceof InvokeWithExceptionNode) {
            invoke((Invoke) current);
            queueSuccessors(current, null);
            current = nextQueuedNode();
        } else if (current instanceof LoopBeginNode) {
            state.loopBegin((LoopBeginNode) current);
            nodeStates.put(current, state);
            state = state.clone();
            loopBegin((LoopBeginNode) current);
            current = ((LoopBeginNode) current).next();
            assert current != null;
        } else if (current instanceof LoopEndNode) {
            loopEnd((LoopEndNode) current);
            finishLoopEnds((LoopEndNode) current);
            current = nextQueuedNode();
        } else if (current instanceof AbstractMergeNode) {
            merge((AbstractMergeNode) current);
            current = ((AbstractMergeNode) current).next();
            assert current != null;
        } else if (current instanceof FixedWithNextNode) {
            FixedNode next = ((FixedWithNextNode) current).next();
            assert next != null : current;
            node(current);
            current = next;
        } else if (current instanceof EndNode) {
            end((EndNode) current);
            queueMerge((EndNode) current);
            current = nextQueuedNode();
        } else if (current instanceof ControlSinkNode) {
            node(current);
            current = nextQueuedNode();
        } else if (current instanceof ControlSplitNode) {
            Set<Node> successors = controlSplit((ControlSplitNode) current);
            queueSuccessors(current, successors);
            current = nextQueuedNode();
        } else {
            assert false : current;
        }
    } while (current != null);
    finished();
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) Set(java.util.Set) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) InvokeWithExceptionNode(org.graalvm.compiler.nodes.InvokeWithExceptionNode) ControlSplitNode(org.graalvm.compiler.nodes.ControlSplitNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) ControlSinkNode(org.graalvm.compiler.nodes.ControlSinkNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode)

Example 7 with LoopEndNode

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

the class ReentrantNodeIterator method apply.

private static <StateT> EconomicMap<FixedNode, StateT> apply(NodeIteratorClosure<StateT> closure, FixedNode start, StateT initialState, LoopBeginNode boundary) {
    assert start != null;
    Deque<AbstractBeginNode> nodeQueue = new ArrayDeque<>();
    EconomicMap<FixedNode, StateT> blockEndStates = EconomicMap.create(Equivalence.IDENTITY);
    StateT state = initialState;
    FixedNode current = start;
    do {
        while (current instanceof FixedWithNextNode) {
            if (boundary != null && current instanceof LoopExitNode && ((LoopExitNode) current).loopBegin() == boundary) {
                blockEndStates.put(current, state);
                current = null;
            } else {
                FixedNode next = ((FixedWithNextNode) current).next();
                state = closure.processNode(current, state);
                current = closure.continueIteration(state) ? next : null;
            }
        }
        if (current != null) {
            state = closure.processNode(current, state);
            if (closure.continueIteration(state)) {
                Iterator<Node> successors = current.successors().iterator();
                if (!successors.hasNext()) {
                    if (current instanceof LoopEndNode) {
                        blockEndStates.put(current, state);
                    } else if (current instanceof EndNode) {
                        // add the end node and see if the merge is ready for processing
                        AbstractMergeNode merge = ((EndNode) current).merge();
                        if (merge instanceof LoopBeginNode) {
                            EconomicMap<LoopExitNode, StateT> loopExitState = closure.processLoop((LoopBeginNode) merge, state);
                            MapCursor<LoopExitNode, StateT> entry = loopExitState.getEntries();
                            while (entry.advance()) {
                                blockEndStates.put(entry.getKey(), entry.getValue());
                                nodeQueue.add(entry.getKey());
                            }
                        } else {
                            boolean endsVisited = true;
                            for (AbstractEndNode forwardEnd : merge.forwardEnds()) {
                                if (forwardEnd != current && !blockEndStates.containsKey(forwardEnd)) {
                                    endsVisited = false;
                                    break;
                                }
                            }
                            if (endsVisited) {
                                ArrayList<StateT> states = new ArrayList<>(merge.forwardEndCount());
                                for (int i = 0; i < merge.forwardEndCount(); i++) {
                                    AbstractEndNode forwardEnd = merge.forwardEndAt(i);
                                    assert forwardEnd == current || blockEndStates.containsKey(forwardEnd);
                                    StateT other = forwardEnd == current ? state : blockEndStates.removeKey(forwardEnd);
                                    states.add(other);
                                }
                                state = closure.merge(merge, states);
                                current = closure.continueIteration(state) ? merge : null;
                                continue;
                            } else {
                                assert !blockEndStates.containsKey(current);
                                blockEndStates.put(current, state);
                            }
                        }
                    }
                } else {
                    FixedNode firstSuccessor = (FixedNode) successors.next();
                    if (!successors.hasNext()) {
                        current = firstSuccessor;
                        continue;
                    } else {
                        do {
                            AbstractBeginNode successor = (AbstractBeginNode) successors.next();
                            StateT successorState = closure.afterSplit(successor, state);
                            if (closure.continueIteration(successorState)) {
                                blockEndStates.put(successor, successorState);
                                nodeQueue.add(successor);
                            }
                        } while (successors.hasNext());
                        state = closure.afterSplit((AbstractBeginNode) firstSuccessor, state);
                        current = closure.continueIteration(state) ? firstSuccessor : null;
                        continue;
                    }
                }
            }
        }
        // get next queued block
        if (nodeQueue.isEmpty()) {
            return blockEndStates;
        } else {
            current = nodeQueue.removeFirst();
            assert blockEndStates.containsKey(current);
            state = blockEndStates.removeKey(current);
            assert !(current instanceof AbstractMergeNode) && current instanceof AbstractBeginNode;
        }
    } while (true);
}
Also used : FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) EconomicMap(org.graalvm.collections.EconomicMap) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) LoopExitNode(org.graalvm.compiler.nodes.LoopExitNode) Node(org.graalvm.compiler.graph.Node) EndNode(org.graalvm.compiler.nodes.EndNode) FixedWithNextNode(org.graalvm.compiler.nodes.FixedWithNextNode) ArrayList(java.util.ArrayList) FixedNode(org.graalvm.compiler.nodes.FixedNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) ArrayDeque(java.util.ArrayDeque) MapCursor(org.graalvm.collections.MapCursor) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode)

Example 8 with LoopEndNode

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

the class SinglePassNodeIterator method finishLoopEnds.

/**
 * Once all loop-end-nodes for a given loop-node have been visited.
 * <ul>
 * <li>the state for that loop-node is updated based on the states of the loop-end-nodes</li>
 * <li>entries in {@link #nodeStates} are pruned for the loop (they aren't going to be looked up
 * again, anyway)</li>
 * </ul>
 *
 * <p>
 * The entries removed by this method were inserted:
 * <ul>
 * <li>for the loop-begin, by {@link #apply()}</li>
 * <li>for loop-ends, by (previous) invocations of this method</li>
 * </ul>
 * </p>
 */
private void finishLoopEnds(LoopEndNode end) {
    assert !visitedEnds.isMarked(end);
    visitedEnds.mark(end);
    keepForLater(end, state);
    LoopBeginNode begin = end.loopBegin();
    boolean endsVisited = true;
    for (LoopEndNode le : begin.loopEnds()) {
        if (!visitedEnds.isMarked(le)) {
            endsVisited = false;
            break;
        }
    }
    if (endsVisited) {
        ArrayList<T> states = new ArrayList<>(begin.loopEnds().count());
        for (LoopEndNode le : begin.orderedLoopEnds()) {
            T leState = pruneEntry(le);
            states.add(leState);
        }
        T loopBeginState = pruneEntry(begin);
        loopBeginState.loopEnds(begin, states);
    }
}
Also used : LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) ArrayList(java.util.ArrayList) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode)

Example 9 with LoopEndNode

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

the class PostOrderNodeIterator method finishLoopEnds.

private void finishLoopEnds(LoopEndNode end) {
    assert !visitedEnds.isMarked(end);
    assert !nodeStates.containsKey(end);
    nodeStates.put(end, state);
    visitedEnds.mark(end);
    LoopBeginNode begin = end.loopBegin();
    boolean endsVisited = true;
    for (LoopEndNode le : begin.loopEnds()) {
        if (!visitedEnds.isMarked(le)) {
            endsVisited = false;
            break;
        }
    }
    if (endsVisited) {
        ArrayList<T> states = new ArrayList<>(begin.loopEnds().count());
        for (LoopEndNode le : begin.orderedLoopEnds()) {
            states.add(nodeStates.get(le));
        }
        T loopBeginState = nodeStates.get(begin);
        if (loopBeginState != null) {
            loopBeginState.loopEnds(begin, states);
        }
    }
}
Also used : LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) ArrayList(java.util.ArrayList) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode)

Example 10 with LoopEndNode

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

the class LoopFragmentInside method mergeEnds.

private AbstractBeginNode mergeEnds() {
    assert isDuplicate();
    List<EndNode> endsToMerge = new LinkedList<>();
    // map peel exits to the corresponding loop exits
    EconomicMap<AbstractEndNode, LoopEndNode> reverseEnds = EconomicMap.create(Equivalence.IDENTITY);
    LoopBeginNode loopBegin = original().loop().loopBegin();
    for (LoopEndNode le : loopBegin.loopEnds()) {
        AbstractEndNode duplicate = getDuplicatedNode(le);
        if (duplicate != null) {
            endsToMerge.add((EndNode) duplicate);
            reverseEnds.put(duplicate, le);
        }
    }
    mergedInitializers = EconomicMap.create(Equivalence.IDENTITY);
    AbstractBeginNode newExit;
    StructuredGraph graph = graph();
    if (endsToMerge.size() == 1) {
        AbstractEndNode end = endsToMerge.get(0);
        assert end.hasNoUsages();
        newExit = graph.add(new BeginNode());
        end.replaceAtPredecessor(newExit);
        end.safeDelete();
    } else {
        assert endsToMerge.size() > 1;
        AbstractMergeNode newExitMerge = graph.add(new MergeNode());
        newExit = newExitMerge;
        FrameState state = loopBegin.stateAfter();
        FrameState duplicateState = null;
        if (state != null) {
            duplicateState = state.duplicateWithVirtualState();
            newExitMerge.setStateAfter(duplicateState);
        }
        for (EndNode end : endsToMerge) {
            newExitMerge.addForwardEnd(end);
        }
        for (final PhiNode phi : loopBegin.phis().snapshot()) {
            if (phi.hasNoUsages()) {
                continue;
            }
            final PhiNode firstPhi = patchPhi(graph, phi, newExitMerge);
            for (AbstractEndNode end : newExitMerge.forwardEnds()) {
                LoopEndNode loopEnd = reverseEnds.get(end);
                ValueNode prim = prim(phi.valueAt(loopEnd));
                assert prim != null;
                firstPhi.addInput(prim);
            }
            ValueNode initializer = firstPhi;
            if (duplicateState != null) {
                // fix the merge's state after
                duplicateState.applyToNonVirtual(new NodeClosure<ValueNode>() {

                    @Override
                    public void apply(Node from, ValueNode node) {
                        if (node == phi) {
                            from.replaceFirstInput(phi, firstPhi);
                        }
                    }
                });
            }
            mergedInitializers.put(phi, initializer);
        }
    }
    return newExit;
}
Also used : ValuePhiNode(org.graalvm.compiler.nodes.ValuePhiNode) MemoryPhiNode(org.graalvm.compiler.nodes.memory.MemoryPhiNode) GuardPhiNode(org.graalvm.compiler.nodes.GuardPhiNode) PhiNode(org.graalvm.compiler.nodes.PhiNode) 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) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) FrameState(org.graalvm.compiler.nodes.FrameState) LinkedList(java.util.LinkedList) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractMergeNode(org.graalvm.compiler.nodes.AbstractMergeNode) MergeNode(org.graalvm.compiler.nodes.MergeNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) LoopEndNode(org.graalvm.compiler.nodes.LoopEndNode) EndNode(org.graalvm.compiler.nodes.EndNode) StructuredGraph(org.graalvm.compiler.nodes.StructuredGraph) BeginNode(org.graalvm.compiler.nodes.BeginNode) LoopBeginNode(org.graalvm.compiler.nodes.LoopBeginNode) AbstractBeginNode(org.graalvm.compiler.nodes.AbstractBeginNode) AbstractEndNode(org.graalvm.compiler.nodes.AbstractEndNode) ValueNode(org.graalvm.compiler.nodes.ValueNode)

Aggregations

LoopEndNode (org.graalvm.compiler.nodes.LoopEndNode)20 LoopBeginNode (org.graalvm.compiler.nodes.LoopBeginNode)17 FixedNode (org.graalvm.compiler.nodes.FixedNode)15 AbstractMergeNode (org.graalvm.compiler.nodes.AbstractMergeNode)13 EndNode (org.graalvm.compiler.nodes.EndNode)12 FixedWithNextNode (org.graalvm.compiler.nodes.FixedWithNextNode)12 AbstractBeginNode (org.graalvm.compiler.nodes.AbstractBeginNode)10 AbstractEndNode (org.graalvm.compiler.nodes.AbstractEndNode)10 LoopExitNode (org.graalvm.compiler.nodes.LoopExitNode)10 Node (org.graalvm.compiler.graph.Node)8 ControlSplitNode (org.graalvm.compiler.nodes.ControlSplitNode)8 ControlSinkNode (org.graalvm.compiler.nodes.ControlSinkNode)6 MergeNode (org.graalvm.compiler.nodes.MergeNode)6 BeginNode (org.graalvm.compiler.nodes.BeginNode)5 ConstantNode (org.graalvm.compiler.nodes.ConstantNode)5 IfNode (org.graalvm.compiler.nodes.IfNode)5 PhiNode (org.graalvm.compiler.nodes.PhiNode)5 ProxyNode (org.graalvm.compiler.nodes.ProxyNode)5 SafepointNode (org.graalvm.compiler.nodes.SafepointNode)5 ValueNode (org.graalvm.compiler.nodes.ValueNode)5