Skip to content

Commit

Permalink
loop fragment: do not handle sinks, when running without simplificati…
Browse files Browse the repository at this point in the history
…ons no sinks are duplicated
  • Loading branch information
davleopo committed Aug 3, 2020
1 parent b79f13e commit 32cd9b4
Showing 1 changed file with 2 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@
import org.graalvm.compiler.nodes.AbstractMergeNode;
import org.graalvm.compiler.nodes.BeginNode;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.ControlSinkNode;
import org.graalvm.compiler.nodes.EndNode;
import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
Expand Down Expand Up @@ -306,8 +305,7 @@ private void placeNewSegmentAndCleanup(LoopEx loop, EconomicMap<Node, Node> new2
* proxies to properly proxy all values along the way.
*
* Unrolling loops with multiple exits is special in the way the exits are handled.
* Pre-Main-Post creation will merge them if applicable, or duplicate them if they are control
* sink nodes. Graal IR is a bit implicit about deopt nodes not requiring a proper loop exit.
* Pre-Main-Post creation will merge them.
*/
private void mergeEarlyLoopExits(StructuredGraph graph, LoopBeginNode mainLoopBegin, CountedLoopInfo mainCounted, EconomicMap<Node, Node> new2OldPhis, LoopEx loop) {
if (graph.hasValueProxies()) {
Expand All @@ -321,10 +319,8 @@ private void mergeEarlyLoopExits(StructuredGraph graph, LoopBeginNode mainLoopBe
AbstractBeginNode begin = getDuplicatedNode(exit);
if (next instanceof EndNode) {
mergeRegularEarlyExit(next, begin, exit, mainLoopBegin, graph, new2OldPhis, loop);
} else if (next instanceof ControlSinkNode) {
rewireDataflowDuplicateSinkingExit(next, begin, exit, mainLoopBegin, graph, new2OldPhis);
} else {
GraalError.shouldNotReachHere("Can only unroll loops where the early exits either merge on the same node or sink immediately " + next);
GraalError.shouldNotReachHere("Can only unroll loops where the early exits which merge " + next);
}
}
}
Expand Down Expand Up @@ -368,27 +364,6 @@ public static ValueNode patchProxyAtPhi(PhiNode phi, LoopExitNode lex, ValueNode
}
}

/**
* If we have a control flow sink along the early exit we duplicate the sink and replace all
* values in the original iteration's sink with new values that might need proxy-ing along the
* new loop exit. Thus, we need to find the values of the original iteration in the unrolled
* iteration
*/
private void rewireDataflowDuplicateSinkingExit(FixedNode next, AbstractBeginNode exitBranchBegin, LoopExitNode oldExit, LoopBeginNode mainLoopBegin, StructuredGraph graph,
EconomicMap<Node, Node> new2OldPhis) {
ControlSinkNode sink = (ControlSinkNode) next;
ControlSinkNode sinkCopy = (ControlSinkNode) sink.copyWithInputs(true);
LoopExitNode newLoopExit = graph.add(new LoopExitNode(mainLoopBegin));
for (ProxyNode proxy : oldExit.proxies()) {
assert proxy instanceof ValueProxyNode : "A sink can only consume a value not a guard/memory edge " + proxy;
ValueNode replacement = getNodeInExitPathFromUnrolledSegment(proxy, new2OldPhis);
proxy.replaceAtMatchingUsages(graph.addOrUnique(new ValueProxyNode(replacement, newLoopExit)), x -> x == sinkCopy);
}
createExitStateForNewSegmentEarlyExit(graph, oldExit, newLoopExit, new2OldPhis);
exitBranchBegin.setNext(newLoopExit);
newLoopExit.setNext(sinkCopy);
}

private void createExitStateForNewSegmentEarlyExit(StructuredGraph graph, LoopExitNode exit, LoopExitNode lex, EconomicMap<Node, Node> new2OldPhis) {
assert exit.stateAfter() != null;
FrameState exitState = exit.stateAfter();
Expand Down

0 comments on commit 32cd9b4

Please sign in to comment.