changeset 3215:0ab38d143795

Fix for loop inversion now runs tests, fop, lusearch, eclipse, avrora and scimark
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Wed, 13 Jul 2011 15:08:49 +0200
parents 0ca900bab9d0
children 93b74afbd379 034a4db85c59
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java
diffstat 1 files changed, 48 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java	Wed Jul 13 15:05:04 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java	Wed Jul 13 15:08:49 2011 +0200
@@ -232,49 +232,18 @@
         assert loop.cfgNodes().isMarked(noExit);
 
         PeelingResult peeling = preparePeeling(loop, split);
-        rewirePeeling(peeling, loop, split, true);
+        rewireInversion(peeling, loop, split);
 
         // move peeled part to the end
         LoopBegin loopBegin = loop.loopBegin();
         LoopEnd loopEnd = loopBegin.loopEnd();
         FixedNode lastNode = (FixedNode) loopEnd.singlePredecessor();
-        Graph graph = loopBegin.graph();
         if (loopBegin.next() != lastNode) {
             lastNode.successors().replace(loopEnd, loopBegin.next());
             loopBegin.setNext(noExit);
             split.successors().replace(noExit, loopEnd);
         }
 
-        // rewire dataOut
-        NodeBitMap exitMergesPhis = graph.createNodeBitMap();
-        for (Entry<Node, StateSplit> entry : peeling.exits.entries()) {
-            StateSplit newExit = entry.getValue();
-            Merge merge = ((EndNode) newExit.next()).merge();
-            exitMergesPhis.markAll(merge.phis());
-        }
-        for (Entry<Node, Node> entry : peeling.dataOut.entries()) {
-            Value originalValue = (Value) entry.getKey();
-            if (originalValue instanceof Phi && ((Phi) originalValue).merge() == loopBegin) {
-                continue;
-            }
-            Value newValue = (Value) entry.getValue();
-            Phi phi = null;
-            List<Node> usages = new ArrayList<Node>(originalValue.usages());
-            for (Node usage : usages) {
-                if (exitMergesPhis.isMarked(usage) || (
-                                loop.nodes().isNotNewMarked(usage)
-                                && peeling.peeledNodes.isNotNewNotMarked(usage)
-                                && !(usage instanceof Phi && ((Phi) usage).merge() == loopBegin))
-                                && !(usage instanceof FrameState && ((FrameState) usage).block() == loopBegin)) {
-                    if (phi == null) {
-                        phi = new Phi(originalValue.kind, loopBegin, PhiType.Value, graph);
-                        phi.addInput(newValue);
-                        phi.addInput(originalValue);
-                    }
-                    usage.inputs().replace(originalValue, phi);
-                }
-            }
-        }
         //rewire phi usage in peeled part
         int backIndex = loopBegin.phiPredecessorIndex(loopBegin.loopEnd());
         for (Phi phi : loopBegin.phis()) {
@@ -329,7 +298,7 @@
         for (Entry<Node, Node> entry : peeling.dataOut.entries()) {
             System.out.println("  - " + entry.getKey() + " -> " + entry.getValue());
         }*/
-        rewirePeeling(peeling, loop, loopEnd, false);
+        rewirePeeling(peeling, loop);
         /*if (compilation.compiler.isObserved()) {
             compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After rewirePeeling", loopEnd.graph(), true, false));
         }*/
@@ -345,6 +314,14 @@
         GraalMetrics.LoopsPeeled++;
     }
 
+    private static void rewireInversion(PeelingResult peeling, Loop loop, FixedNode from) {
+        rewirePeeling(peeling, loop, from, true);
+    }
+
+    private static void rewirePeeling(PeelingResult peeling, Loop loop) {
+        rewirePeeling(peeling, loop, loop.loopBegin().loopEnd(), false);
+    }
+
     private static void rewirePeeling(PeelingResult peeling, Loop loop, FixedNode from, boolean inversion) {
         LoopBegin loopBegin = loop.loopBegin();
         Graph graph = loopBegin.graph();
@@ -398,6 +375,7 @@
         for (Node exit : peeling.unaffectedExits) {
             exitPoints.add(exit);
         }
+
         for (Entry<Node, StateSplit> entry : peeling.exits.entries()) {
             StateSplit original = (StateSplit) entry.getKey();
             StateSplit newExit = entry.getValue();
@@ -446,6 +424,43 @@
             }
         }
 
+        if (inversion) {
+            // rewire dataOut in non-peeled body
+            NodeBitMap exitMergesPhis = graph.createNodeBitMap();
+            for (Entry<Node, StateSplit> entry : peeling.exits.entries()) {
+                StateSplit newExit = entry.getValue();
+                Merge merge = ((EndNode) newExit.next()).merge();
+                exitMergesPhis.markAll(merge.phis());
+            }
+            for (Entry<Node, Node> entry : peeling.dataOut.entries()) {
+                Value originalValue = (Value) entry.getKey();
+                if (originalValue instanceof Phi && ((Phi) originalValue).merge() == loopBegin) {
+                    continue;
+                }
+                Value newValue = (Value) entry.getValue();
+                Phi phi = null;
+                List<Node> usages = new ArrayList<Node>(originalValue.usages());
+                for (Node usage : usages) {
+                    if (exitMergesPhis.isMarked(usage) || (
+                                    loop.nodes().isNotNewMarked(usage)
+                                    && peeling.peeledNodes.isNotNewNotMarked(usage)
+                                    && !(usage instanceof Phi && ((Phi) usage).merge() == loopBegin))
+                                    && !(usage instanceof FrameState && ((FrameState) usage).block() == loopBegin)) {
+                        if (phi == null) {
+                            phi = new Phi(originalValue.kind, loopBegin, PhiType.Value, graph);
+                            phi.addInput(newValue);
+                            phi.addInput(originalValue);
+                            NodeMap<Value> exitMap = newExitValues.get(originalValue);
+                            for (Node exit : peeling.unaffectedExits) {
+                                exitMap.set(exit, phi);
+                            }
+                        }
+                        usage.inputs().replace(originalValue, phi);
+                    }
+                }
+            }
+        }
+
         for (Entry<Node, NodeMap<Value>> entry : newExitValues.entries()) {
             Value original = (Value) entry.getKey();
             NodeMap<Value> pointToValue = entry.getValue();