use of org.graalvm.compiler.nodes.ControlSinkNode in project graal by oracle.
the class ControlFlowGraph method identifyBlocks.
/**
* Identify and connect blocks (including loop backward edges). Predecessors need to be in the
* order expected when iterating phi inputs.
*/
private void identifyBlocks() {
// Find all block headers.
int numBlocks = 0;
for (AbstractBeginNode begin : graph.getNodes(AbstractBeginNode.TYPE)) {
Block block = new Block(begin);
identifyBlock(block);
numBlocks++;
}
// Compute reverse post order.
int count = 0;
NodeMap<Block> nodeMap = this.nodeToBlock;
Block[] stack = new Block[numBlocks];
int tos = 0;
Block startBlock = blockFor(graph.start());
stack[0] = startBlock;
startBlock.setPredecessors(Block.EMPTY_ARRAY);
do {
Block block = stack[tos];
int id = block.getId();
if (id == BLOCK_ID_INITIAL) {
// First time we see this block: push all successors.
FixedNode last = block.getEndNode();
if (last instanceof EndNode) {
EndNode endNode = (EndNode) last;
Block suxBlock = nodeMap.get(endNode.merge());
if (suxBlock.getId() == BLOCK_ID_INITIAL) {
stack[++tos] = suxBlock;
}
block.setSuccessors(new Block[] { suxBlock });
} else if (last instanceof IfNode) {
IfNode ifNode = (IfNode) last;
Block trueSucc = nodeMap.get(ifNode.trueSuccessor());
stack[++tos] = trueSucc;
Block falseSucc = nodeMap.get(ifNode.falseSuccessor());
stack[++tos] = falseSucc;
block.setSuccessors(new Block[] { trueSucc, falseSucc });
Block[] ifPred = new Block[] { block };
trueSucc.setPredecessors(ifPred);
falseSucc.setPredecessors(ifPred);
} else if (last instanceof LoopEndNode) {
LoopEndNode loopEndNode = (LoopEndNode) last;
block.setSuccessors(new Block[] { nodeMap.get(loopEndNode.loopBegin()) });
// Nothing to do push onto the stack.
} else if (last instanceof ControlSinkNode) {
block.setSuccessors(Block.EMPTY_ARRAY);
} else {
assert !(last instanceof AbstractEndNode) : "Algorithm only supports EndNode and LoopEndNode.";
int startTos = tos;
Block[] ifPred = new Block[] { block };
for (Node suxNode : last.successors()) {
Block sux = nodeMap.get(suxNode);
stack[++tos] = sux;
sux.setPredecessors(ifPred);
}
int suxCount = tos - startTos;
Block[] successors = new Block[suxCount];
System.arraycopy(stack, startTos + 1, successors, 0, suxCount);
block.setSuccessors(successors);
}
block.setId(BLOCK_ID_VISITED);
AbstractBeginNode beginNode = block.getBeginNode();
if (beginNode instanceof LoopBeginNode) {
computeLoopPredecessors(nodeMap, block, (LoopBeginNode) beginNode);
} else if (beginNode instanceof MergeNode) {
MergeNode mergeNode = (MergeNode) beginNode;
int forwardEndCount = mergeNode.forwardEndCount();
Block[] predecessors = new Block[forwardEndCount];
for (int i = 0; i < forwardEndCount; ++i) {
predecessors[i] = nodeMap.get(mergeNode.forwardEndAt(i));
}
block.setPredecessors(predecessors);
}
} else if (id == BLOCK_ID_VISITED) {
// Second time we see this block: All successors have been processed, so add block
// to result list. Can safely reuse the stack for this.
--tos;
count++;
int index = numBlocks - count;
stack[index] = block;
block.setId(index);
} else {
throw GraalError.shouldNotReachHere();
}
} while (tos >= 0);
// Compute reverse postorder and number blocks.
assert count == numBlocks : "all blocks must be reachable";
this.reversePostOrder = stack;
}
use of org.graalvm.compiler.nodes.ControlSinkNode in project graal by oracle.
the class InliningIterator method apply.
public LinkedList<Invoke> apply() {
LinkedList<Invoke> invokes = new LinkedList<>();
FixedNode current;
forcedQueue(start);
while ((current = nextQueuedNode()) != null) {
assert current.isAlive();
if (current instanceof Invoke && ((Invoke) current).callTarget() instanceof MethodCallTargetNode) {
if (current != start) {
invokes.addLast((Invoke) current);
}
queueSuccessors(current);
} else if (current instanceof LoopBeginNode) {
queueSuccessors(current);
} else if (current instanceof LoopEndNode) {
// nothing to do
} else if (current instanceof AbstractMergeNode) {
queueSuccessors(current);
} else if (current instanceof FixedWithNextNode) {
queueSuccessors(current);
} else if (current instanceof EndNode) {
queueMerge((EndNode) current);
} else if (current instanceof ControlSinkNode) {
// nothing to do
} else if (current instanceof ControlSplitNode) {
queueSuccessors(current);
} else {
assert false : current;
}
}
assert invokes.size() == count(start.graph().getInvokes());
return invokes;
}
use of org.graalvm.compiler.nodes.ControlSinkNode in project graal by oracle.
the class ScopedPostOrderNodeIterator method processScope.
public void processScope() {
FixedNode current;
queue(currentScopeStart);
while ((current = nextQueuedNode()) != null) {
assert current.isAlive();
if (current instanceof Invoke) {
invoke((Invoke) current);
queueSuccessors(current);
} else if (current instanceof LoopBeginNode) {
queueLoopBeginSuccessors((LoopBeginNode) current);
} else if (current instanceof LoopExitNode) {
queueLoopExitSuccessors((LoopExitNode) current);
} else if (current instanceof LoopEndNode) {
// nothing todo
} else if (current instanceof AbstractMergeNode) {
queueSuccessors(current);
} else if (current instanceof FixedWithNextNode) {
queueSuccessors(current);
} else if (current instanceof EndNode) {
queueMerge((EndNode) current);
} else if (current instanceof ControlSinkNode) {
// nothing todo
} else if (current instanceof ControlSplitNode) {
queueSuccessors(current);
} else {
assert false : current;
}
}
}
use of org.graalvm.compiler.nodes.ControlSinkNode in project graal by oracle.
the class SinglePassNodeIterator method apply.
/**
* Performs a single-pass iteration.
*
* <p>
* After this method has been invoked, the {@link SinglePassNodeIterator} instance can't be used
* again. This saves clearing up fields in {@link #finished()}, the assumption being that this
* instance will be garbage-collected soon afterwards.
* </p>
*/
public void apply() {
FixedNode current = start;
do {
if (current instanceof InvokeWithExceptionNode) {
invoke((Invoke) current);
queueSuccessors(current);
current = nextQueuedNode();
} else if (current instanceof LoopBeginNode) {
state.loopBegin((LoopBeginNode) current);
keepForLater(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) {
controlSplit((ControlSplitNode) current);
queueSuccessors(current);
current = nextQueuedNode();
} else {
assert false : current;
}
} while (current != null);
finished();
}
use of org.graalvm.compiler.nodes.ControlSinkNode in project graal by oracle.
the class StatelessPostOrderNodeIterator method apply.
public void apply() {
FixedNode current = start;
do {
if (current instanceof LoopBeginNode) {
loopBegin((LoopBeginNode) current);
current = ((LoopBeginNode) current).next();
assert current != null;
} else if (current instanceof LoopEndNode) {
loopEnd((LoopEndNode) current);
assert !visitedEnds.isMarked(current);
visitedEnds.mark(current);
current = nodeQueue.pollFirst();
} else if (current instanceof AbstractMergeNode) {
merge((AbstractMergeNode) current);
current = ((AbstractMergeNode) current).next();
assert current != null;
} else if (current instanceof FixedWithNextNode) {
node(current);
current = ((FixedWithNextNode) current).next();
} else if (current instanceof EndNode) {
end((EndNode) current);
queueMerge((EndNode) current);
current = nodeQueue.pollFirst();
} else if (current instanceof ControlSinkNode) {
node(current);
current = nodeQueue.pollFirst();
} else if (current instanceof ControlSplitNode) {
controlSplit((ControlSplitNode) current);
for (Node node : current.successors()) {
nodeQueue.addFirst((AbstractBeginNode) node);
}
current = nodeQueue.pollFirst();
} else {
assert false : current;
}
} while (current != null);
finished();
}
Aggregations