< 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 >