< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/cfg/ControlFlowGraph.java
Print this page
*** 22,31 ****
--- 22,33 ----
*/
package org.graalvm.compiler.nodes.cfg;
+ import static org.graalvm.compiler.core.common.cfg.AbstractBlockBase.BLOCK_ID_COMPARATOR;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.List;
*** 47,57 ****
import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.LoopEndNode;
import org.graalvm.compiler.nodes.LoopExitNode;
import org.graalvm.compiler.nodes.MergeNode;
import org.graalvm.compiler.nodes.StructuredGraph;
- import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
public final class ControlFlowGraph implements AbstractControlFlowGraph<Block> {
/**
* Don't allow relative frequency values to be become too small or too high as this makes
* frequency calculations over- or underflow the range of a double. This commonly happens with
--- 49,58 ----
*** 612,696 ****
for (LoopEndNode end : loopBegin.loopEnds()) {
Block endBlock = nodeToBlock.get(end);
computeLoopBlocks(endBlock, loop, stack, true);
}
! if (graph.getGuardsStage() != GuardsStage.AFTER_FSA) {
for (LoopExitNode exit : loopBegin.loopExits()) {
Block exitBlock = nodeToBlock.get(exit);
assert exitBlock.getPredecessorCount() == 1;
computeLoopBlocks(exitBlock.getFirstPredecessor(), loop, stack, true);
! loop.addExit(exitBlock);
}
// The following loop can add new blocks to the end of the loop's block
// list.
int size = loop.getBlocks().size();
for (int i = 0; i < size; ++i) {
Block b = loop.getBlocks().get(i);
for (Block sux : b.getSuccessors()) {
if (sux.getLoop() != loop) {
AbstractBeginNode begin = sux.getBeginNode();
! if (!(begin instanceof LoopExitNode && ((LoopExitNode) begin).loopBegin() == loopBegin)) {
graph.getDebug().log(DebugContext.VERBOSE_LEVEL, "Unexpected loop exit with %s, including whole branch in the loop", sux);
computeLoopBlocks(sux, loop, stack, false);
}
}
}
}
}
}
}
}
-
- /*
- * Compute the loop exit blocks after FSA.
- */
- if (graph.getGuardsStage() == GuardsStage.AFTER_FSA) {
- for (Block b : reversePostOrder) {
- if (b.getLoop() != null) {
- for (Block succ : b.getSuccessors()) {
- // if the loop of the succ is a different one (or none)
- if (b.getLoop() != succ.getLoop()) {
- // and the succ loop is not a child loop of the curr one
- if (succ.getLoop() == null) {
- // we might exit multiple loops if b.loops is not a loop at depth 0
- Loop<Block> curr = b.getLoop();
- while (curr != null) {
- curr.addExit(succ);
- curr = curr.getParent();
- }
- } else {
- /*
- * succ also has a loop, might be a child loop
- *
- * if it is a child loop we do not exit a loop. if it is a loop
- * different than b.loop and not a child loop it must be a parent
- * loop, thus we exit all loops between b.loop and succ.loop
- *
- * if we exit multiple loops immediately after each other the
- * bytecode parser might generate loop exit nodes after another and
- * the CFG will identify them as separate blocks, we just take the
- * first one and exit all loops at this one
- */
- if (succ.getLoop().getParent() != b.getLoop()) {
- assert succ.getLoop().getDepth() < b.getLoop().getDepth();
- // b.loop must not be a transitive parent of succ.loop
- assert !Loop.transitiveParentLoop(succ.getLoop(), b.getLoop());
- Loop<Block> curr = b.getLoop();
- while (curr != null && curr != succ.getLoop()) {
- curr.addExit(succ);
- curr = curr.getParent();
- }
- }
- }
- }
- }
- }
- }
- }
-
}
private static void computeLoopBlocks(Block start, Loop<Block> loop, Block[] stack, boolean usePred) {
if (start.getLoop() != loop) {
start.setLoop(loop);
--- 613,666 ----
for (LoopEndNode end : loopBegin.loopEnds()) {
Block endBlock = nodeToBlock.get(end);
computeLoopBlocks(endBlock, loop, stack, true);
}
! // Note that at this point, due to traversal order, child loops of `loop` have
! // not been discovered yet.
! for (Block b : loop.getBlocks()) {
! for (Block sux : b.getSuccessors()) {
! if (sux.getLoop() != loop) {
! assert sux.getLoopDepth() < loop.getDepth();
! loop.getNaturalExits().add(sux);
! }
! }
! }
! loop.getNaturalExits().sort(BLOCK_ID_COMPARATOR);
!
! if (!graph.getGuardsStage().areFrameStatesAtDeopts()) {
for (LoopExitNode exit : loopBegin.loopExits()) {
Block exitBlock = nodeToBlock.get(exit);
assert exitBlock.getPredecessorCount() == 1;
computeLoopBlocks(exitBlock.getFirstPredecessor(), loop, stack, true);
! loop.getLoopExits().add(exitBlock);
}
+ loop.getLoopExits().sort(BLOCK_ID_COMPARATOR);
// The following loop can add new blocks to the end of the loop's block
// list.
int size = loop.getBlocks().size();
for (int i = 0; i < size; ++i) {
Block b = loop.getBlocks().get(i);
for (Block sux : b.getSuccessors()) {
if (sux.getLoop() != loop) {
AbstractBeginNode begin = sux.getBeginNode();
! if (!loopBegin.isLoopExit(begin)) {
! assert !(begin instanceof LoopBeginNode);
! assert sux.getLoopDepth() < loop.getDepth();
graph.getDebug().log(DebugContext.VERBOSE_LEVEL, "Unexpected loop exit with %s, including whole branch in the loop", sux);
computeLoopBlocks(sux, loop, stack, false);
}
}
}
}
+ } else {
+ loop.getLoopExits().addAll(loop.getNaturalExits());
}
}
}
}
}
private static void computeLoopBlocks(Block start, Loop<Block> loop, Block[] stack, boolean usePred) {
if (start.getLoop() != loop) {
start.setLoop(loop);
< prev index next >