use of org.graalvm.compiler.nodes.FixedWithNextNode in project graal by oracle.
the class LoopFragmentInside method placeNewSegmentAndCleanup.
private void placeNewSegmentAndCleanup(LoopEx loop) {
CountedLoopInfo mainCounted = loop.counted();
LoopBeginNode mainLoopBegin = loop.loopBegin();
// Discard the segment entry and its flow, after if merging it into the loop
StructuredGraph graph = mainLoopBegin.graph();
IfNode loopTest = mainCounted.getLimitTest();
IfNode newSegmentTest = getDuplicatedNode(loopTest);
AbstractBeginNode trueSuccessor = loopTest.trueSuccessor();
AbstractBeginNode falseSuccessor = loopTest.falseSuccessor();
FixedNode firstNode;
boolean codeInTrueSide = false;
if (trueSuccessor == mainCounted.getBody()) {
firstNode = trueSuccessor.next();
codeInTrueSide = true;
} else {
assert (falseSuccessor == mainCounted.getBody());
firstNode = falseSuccessor.next();
}
trueSuccessor = newSegmentTest.trueSuccessor();
falseSuccessor = newSegmentTest.falseSuccessor();
for (Node usage : falseSuccessor.anchored().snapshot()) {
usage.replaceFirstInput(falseSuccessor, loopTest.falseSuccessor());
}
for (Node usage : trueSuccessor.anchored().snapshot()) {
usage.replaceFirstInput(trueSuccessor, loopTest.trueSuccessor());
}
AbstractBeginNode startBlockNode;
if (codeInTrueSide) {
startBlockNode = trueSuccessor;
} else {
graph.getDebug().dump(DebugContext.VERBOSE_LEVEL, mainLoopBegin.graph(), "before");
startBlockNode = falseSuccessor;
}
FixedNode lastNode = getBlockEnd(startBlockNode);
LoopEndNode loopEndNode = mainLoopBegin.getSingleLoopEnd();
FixedWithNextNode lastCodeNode = (FixedWithNextNode) loopEndNode.predecessor();
FixedNode newSegmentFirstNode = getDuplicatedNode(firstNode);
FixedWithNextNode newSegmentLastNode = getDuplicatedNode(lastCodeNode);
graph.getDebug().dump(DebugContext.DETAILED_LEVEL, loopEndNode.graph(), "Before placing segment");
if (firstNode instanceof LoopEndNode) {
GraphUtil.killCFG(getDuplicatedNode(mainLoopBegin));
} else {
newSegmentLastNode.clearSuccessors();
startBlockNode.setNext(lastNode);
lastCodeNode.replaceFirstSuccessor(loopEndNode, newSegmentFirstNode);
newSegmentLastNode.replaceFirstSuccessor(lastNode, loopEndNode);
lastCodeNode.setNext(newSegmentFirstNode);
newSegmentLastNode.setNext(loopEndNode);
startBlockNode.clearSuccessors();
lastNode.safeDelete();
Node newSegmentTestStart = newSegmentTest.predecessor();
LogicNode newSegmentIfTest = newSegmentTest.condition();
newSegmentTestStart.clearSuccessors();
newSegmentTest.safeDelete();
newSegmentIfTest.safeDelete();
trueSuccessor.safeDelete();
falseSuccessor.safeDelete();
newSegmentTestStart.safeDelete();
}
graph.getDebug().dump(DebugContext.DETAILED_LEVEL, loopEndNode.graph(), "After placing segment");
}
use of org.graalvm.compiler.nodes.FixedWithNextNode in project graal by oracle.
the class PEGraphDecoder method tryInvocationPlugin.
protected boolean tryInvocationPlugin(PEMethodScope methodScope, LoopScope loopScope, InvokeData invokeData, MethodCallTargetNode callTarget) {
if (invocationPlugins == null || invocationPlugins.isEmpty()) {
return false;
}
Invoke invoke = invokeData.invoke;
ResolvedJavaMethod targetMethod = callTarget.targetMethod();
InvocationPlugin invocationPlugin = getInvocationPlugin(targetMethod);
if (invocationPlugin == null) {
return false;
}
ValueNode[] arguments = callTarget.arguments().toArray(new ValueNode[0]);
FixedWithNextNode invokePredecessor = (FixedWithNextNode) invoke.asNode().predecessor();
/*
* Remove invoke from graph so that invocation plugin can append nodes to the predecessor.
*/
invoke.asNode().replaceAtPredecessor(null);
PEMethodScope inlineScope = new PEMethodScope(graph, methodScope, loopScope, null, targetMethod, invokeData, methodScope.inliningDepth + 1, loopExplosionPlugin, arguments);
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(inlineScope, invokePredecessor);
InvocationPluginReceiver invocationPluginReceiver = new InvocationPluginReceiver(graphBuilderContext);
if (invocationPlugin.execute(graphBuilderContext, targetMethod, invocationPluginReceiver.init(targetMethod, arguments), arguments)) {
if (graphBuilderContext.invokeConsumed) {
/* Nothing to do. */
} else if (graphBuilderContext.lastInstr != null) {
registerNode(loopScope, invokeData.invokeOrderId, graphBuilderContext.pushedNode, true, true);
invoke.asNode().replaceAtUsages(graphBuilderContext.pushedNode);
graphBuilderContext.lastInstr.setNext(nodeAfterInvoke(methodScope, loopScope, invokeData, AbstractBeginNode.prevBegin(graphBuilderContext.lastInstr)));
deleteInvoke(invoke);
} else {
assert graphBuilderContext.pushedNode == null : "Why push a node when the invoke does not return anyway?";
invoke.asNode().replaceAtUsages(null);
deleteInvoke(invoke);
}
return true;
} else {
/* Intrinsification failed, restore original state: invoke is in Graph. */
invokePredecessor.setNext(invoke.asNode());
return false;
}
}
use of org.graalvm.compiler.nodes.FixedWithNextNode 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.FixedWithNextNode 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.FixedWithNextNode in project graal by oracle.
the class ScheduledNodeIterator method processNodes.
public void processNodes(Block block, ScheduleResult schedule) {
lastFixed = block.getBeginNode();
assert lastFixed != null;
reconnect = null;
iterator = schedule.nodesFor(block).listIterator();
while (iterator.hasNext()) {
Node node = iterator.next();
if (!node.isAlive()) {
continue;
}
if (reconnect != null && node instanceof FixedNode) {
reconnect.setNext((FixedNode) node);
reconnect = null;
}
if (node instanceof FixedWithNextNode) {
lastFixed = (FixedWithNextNode) node;
}
processNode(node);
}
if (reconnect != null) {
assert block.getSuccessorCount() == 1;
reconnect.setNext(block.getFirstSuccessor().getBeginNode());
}
}
Aggregations