# HG changeset patch # User Thomas Wuerthinger # Date 1433105330 -7200 # Node ID b14a218c547142be6c50d8d8691526198e72f989 # Parent 316f85995e6bd804fa2d3ad97d64dc52aacda4a8 Fix in the dominator based conditional elimination for the corner case of a loop exit merge. diff -r 316f85995e6b -r b14a218c5471 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java Sun May 31 13:27:50 2015 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java Sun May 31 22:48:50 2015 +0200 @@ -113,7 +113,7 @@ nodeToBlock = n -> schedule.getNodeToBlockMap().get(n); startBlock = cfg.getStartBlock(); } else { - ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, false, true, true); + ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true); cfg.computePostdominators(); BlockMap> nodes = new BlockMap<>(cfg); for (Block b : cfg.getBlocks()) { @@ -136,8 +136,8 @@ private static class Instance { - private final NodeMap map; - private final Deque loopExits; + private NodeMap map; + private Deque loopExits; private final Function> blockToNodes; private final Function nodeToBlock; @@ -187,6 +187,18 @@ LoopExitNode loopExitNode = (LoopExitNode) beginNode; this.loopExits.push(loopExitNode); undoOperations.add(() -> loopExits.pop()); + } else if (block.getDominator() != null && + (block.getDominator().getLoopDepth() > block.getLoopDepth() || (block.getDominator().getLoopDepth() == block.getLoopDepth() && block.getDominator().getLoop() != block.getLoop()))) { + // We are exiting the loop, but there is not a single loop exit block along our + // dominator tree (e.g., we are a merge of two loop exits). + final NodeMap oldMap = map; + final Deque oldLoopExits = loopExits; + map = map.graph().createNodeMap(); + loopExits = new ArrayDeque<>(); + undoOperations.add(() -> { + map = oldMap; + loopExits = oldLoopExits; + }); } for (Node n : blockToNodes.apply(block)) { if (n.isAlive()) { diff -r 316f85995e6b -r b14a218c5471 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Sun May 31 13:27:50 2015 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Sun May 31 22:48:50 2015 +0200 @@ -202,8 +202,8 @@ } private static boolean checkLatestEarliestRelation(Node currentNode, Block earliestBlock, Block latestBlock) { - assert AbstractControlFlowGraph.dominates(earliestBlock, latestBlock) || (currentNode instanceof VirtualState && latestBlock == earliestBlock.getDominator()) : String.format("%s %s %s", - currentNode, earliestBlock, latestBlock); + assert AbstractControlFlowGraph.dominates(earliestBlock, latestBlock) || (currentNode instanceof VirtualState && latestBlock == earliestBlock.getDominator()) : String.format( + "%s %s (%s) %s (%s)", currentNode, earliestBlock, earliestBlock.getBeginNode(), latestBlock, latestBlock.getBeginNode()); return true; }