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();
}
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);
}
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);
}
}
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);
}
}
}
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;
}
Aggregations