changeset 21619:b14a218c5471

Fix in the dominator based conditional elimination for the corner case of a loop exit merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sun, 31 May 2015 22:48:50 +0200
parents 316f85995e6b
children d06ff213a181
files graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DominatorConditionalEliminationPhase.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java
diffstat 2 files changed, 17 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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<List<FixedNode>> nodes = new BlockMap<>(cfg);
             for (Block b : cfg.getBlocks()) {
@@ -136,8 +136,8 @@
 
     private static class Instance {
 
-        private final NodeMap<Info> map;
-        private final Deque<LoopExitNode> loopExits;
+        private NodeMap<Info> map;
+        private Deque<LoopExitNode> loopExits;
         private final Function<Block, Iterable<? extends Node>> blockToNodes;
         private final Function<Node, Block> 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<Info> oldMap = map;
+                final Deque<LoopExitNode> oldLoopExits = loopExits;
+                map = map.graph().createNodeMap();
+                loopExits = new ArrayDeque<>();
+                undoOperations.add(() -> {
+                    map = oldMap;
+                    loopExits = oldLoopExits;
+                });
             }
             for (Node n : blockToNodes.apply(block)) {
                 if (n.isAlive()) {
--- 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;
     }