changeset 3212:1e5ca59c8769

Fix broken code in exemples, Fix regression and bug in peeling/inverting
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Tue, 12 Jul 2011 17:54:32 +0200
parents 27ae76ed33ca
children 1ba9612f6d6e
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java
diffstat 4 files changed, 68 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Tue Jul 12 13:10:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java	Tue Jul 12 17:54:32 2011 +0200
@@ -36,7 +36,6 @@
     private static final boolean ____ = false;
     // Checkstyle: resume
 
-
     public static boolean Lower                              = true;
 
     // inlining settings
@@ -163,4 +162,5 @@
     public static boolean OptOptimisticSchedule              = ____;
     public static boolean OptReorderLoops                    = ____;
     public static boolean LoopPeeling                        = ____;
+    public static boolean LoopInversion                      = ____;
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java	Tue Jul 12 13:10:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoopPhase.java	Tue Jul 12 17:54:32 2011 +0200
@@ -41,28 +41,21 @@
     protected void run(Graph graph) {
         List<Loop> loops = LoopUtil.computeLoops(graph);
 
-        // TODO (gd) currently counter detection is disabled when loop peeling is active
-        if (GraalOptions.LoopPeeling) {
-peeling:
+        if (GraalOptions.LoopPeeling || GraalOptions.LoopInversion) {
             for (Loop loop : loops) {
-                GraalCompilation compilation = GraalCompilation.compilation();
-                if (compilation.compiler.isObserved()) {
-                    Map<String, Object> debug = new HashMap<String, Object>();
-                    debug.put("loopExits", loop.exits());
-                    debug.put("inOrBefore", loop.inOrBefore());
-                    debug.put("inOrAfter", loop.inOrAfter());
-                    debug.put("nodes", loop.nodes());
-                    compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "Loop #" + loop.loopBegin().id(), graph, true, false, debug));
-                }
-                //System.out.println("Peel loop : " + loop.loopBegin());
+                boolean hasBadExit = false;
                 for (Node exit : loop.exits()) {
                     if (!(exit instanceof StateSplit) || ((StateSplit) exit).stateAfter() == null) {
                         // TODO (gd) can not do loop peeling if an exit has no state. see LoopUtil.findNearestMergableExitPoint
-                        continue peeling;
+                        hasBadExit = true;
+                        break;
                     }
                 }
+                if (hasBadExit) {
+                    continue;
+                }
                 boolean canInvert = false;
-                if (loop.loopBegin().next() instanceof If) {
+                if (GraalOptions.LoopInversion  && loop.loopBegin().next() instanceof If) {
                     If ifNode = (If) loop.loopBegin().next();
                     if (loop.exits().isMarked(ifNode.trueSuccessor()) || loop.exits().isMarked(ifNode.falseSuccessor())) {
                         canInvert = true;
@@ -70,16 +63,25 @@
                 }
                 if (canInvert) {
                     LoopUtil.inverseLoop(loop, (If) loop.loopBegin().next());
-                } else {
+                } else if (GraalOptions.LoopPeeling) {
+                    GraalCompilation compilation = GraalCompilation.compilation();
+                    if (compilation.compiler.isObserved()) {
+                        Map<String, Object> debug = new HashMap<String, Object>();
+                        debug.put("loopExits", loop.exits());
+                        debug.put("inOrBefore", loop.inOrBefore());
+                        debug.put("inOrAfter", loop.inOrAfter());
+                        debug.put("nodes", loop.nodes());
+                        compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "Loop #" + loop.loopBegin().id(), graph, true, false, debug));
+                    }
                     LoopUtil.peelLoop(loop);
                 }
             }
-        } else {
-//            loops = LoopUtil.computeLoops(graph); // TODO (gd) avoid recomputing loops
-            for (Loop loop : loops) {
-                doLoopCounters(loop);
-            }
         }
+
+        /*
+        for (Loop loop : loops) {
+            doLoopCounters(loop);
+        }*/
     }
 
     private void doLoopCounters(Loop loop) {
@@ -172,7 +174,7 @@
                             useCounterAfterAdd = true;
                         }
                     }
-                    if (stride != null && !loopNodes.isNotNewNotMarked(stride)) {
+                    if (stride != null && loopNodes.isNotNewNotMarked(stride)) {
                         Graph graph = loopBegin.graph();
                         LoopCounter counter = new LoopCounter(init.kind, init, stride, loopBegin, graph);
                         counters.add(counter);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java	Tue Jul 12 13:10:33 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/util/LoopUtil.java	Tue Jul 12 17:54:32 2011 +0200
@@ -176,7 +176,7 @@
         loopNodes.mark(loopBegin);
         NodeBitMap inOrAfter = inOrAfter(loop, loopNodes, false);
         NodeBitMap inOrBefore = inOrBefore(loop, inOrAfter, loopNodes, false);
-        /*if (!recurse) {
+        if (!recurse) {
             recurse = true;
             GraalCompilation compilation = GraalCompilation.compilation();
             if (compilation.compiler.isObserved()) {
@@ -187,7 +187,7 @@
                 compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "Compute loop nodes loop#" + loopBegin.id(), loopBegin.graph(), true, false, debug));
             }
             recurse = false;
-        }*/
+        }
         inOrAfter.setIntersect(inOrBefore);
         loopNodes.setUnion(inOrAfter);
         if (from == loopBegin.loopEnd()) { // fill the Loop cache value for loop nodes this is correct even if after/before were partial
@@ -196,7 +196,11 @@
         return loopNodes;
     }
 
-    private static NodeBitMap markUpCFG(LoopBegin loopBegin, FixedNode from) {
+    public static NodeBitMap markUpCFG(LoopBegin loopBegin) {
+        return markUpCFG(loopBegin, loopBegin.loopEnd());
+    }
+
+    public static NodeBitMap markUpCFG(LoopBegin loopBegin, FixedNode from) {
         NodeFlood workCFG = loopBegin.graph().createNodeFlood();
         workCFG.add(from);
         NodeBitMap loopNodes = loopBegin.graph().createNodeBitMap();
@@ -285,6 +289,17 @@
             }
         }
 
+        loop.invalidateCached();
+
+        // update parents
+        Loop parent = loop.parent();
+        while (parent != null) {
+            parent.cfgNodes = markUpCFG(parent.loopBegin, parent.loopBegin.loopEnd());
+            parent.invalidateCached();
+            parent.exits = computeLoopExits(parent.loopBegin, parent.cfgNodes);
+            parent = parent.parent;
+        }
+
         GraalMetrics.LoopsInverted++;
     }
 
@@ -318,6 +333,7 @@
         /*if (compilation.compiler.isObserved()) {
             compilation.compiler.fireCompilationEvent(new CompilationEvent(compilation, "After rewirePeeling", loopEnd.graph(), true, false));
         }*/
+        loop.invalidateCached();
         // update parents
         Loop parent = loop.parent();
         while (parent != null) {
@@ -417,7 +433,7 @@
                 Value backValue = null;
                 if (inversion && originalValue instanceof Phi && ((Phi) originalValue).merge() == loopBegin) {
                     backValue = ((Phi) originalValue).valueAt(phiBackIndex);
-                    if (!loop.nodes().isMarked(backValue) || peeling.peeledNodes.isNotNewMarked(backValue)) {
+                    if (peeling.peeledNodes.isNotNewMarked(backValue)) {
                         backValue = null;
                     }
                 }
@@ -732,9 +748,13 @@
             Value backValue = phi.valueAt(backIndex);
             if (marked.isMarked(backValue)) {
                 phiInits.set(phi, duplicates.get(backValue));
-            } else if (from == loopBegin.loopEnd() && backValue instanceof Phi && ((Phi) backValue).merge() == loopBegin) {
-                Phi backPhi = (Phi) backValue;
-                phiInits.set(phi, backPhi.valueAt(fowardIndex));
+            } else if (from == loopBegin.loopEnd()) {
+                if (backValue instanceof Phi && ((Phi) backValue).merge() == loopBegin) {
+                    Phi backPhi = (Phi) backValue;
+                    phiInits.set(phi, backPhi.valueAt(fowardIndex));
+                } else {
+                    phiInits.set(phi, backValue);
+                }
             }
         }
 
@@ -867,6 +887,21 @@
                         }
                     }
                 }
+                if (cfgNodes.isNotNewMarked(n)) { //add all values from the exits framestates
+                    for (Node sux : n.cfgSuccessors()) {
+                        if (loop.exits().isNotNewMarked(sux) && sux instanceof StateSplit) {
+                            FrameState stateAfter = ((StateSplit) sux).stateAfter();
+                            while (stateAfter != null) {
+                                for (Node in : stateAfter.inputs()) {
+                                    if (!(in instanceof FrameState)) {
+                                        work.add(in);
+                                    }
+                                }
+                                stateAfter = stateAfter.outerFrameState();
+                            }
+                        }
+                    }
+                }
                 if (n instanceof Merge) { //add phis & counters
                     for (Node usage : n.dataUsages()) {
                         if (!(usage instanceof LoopEnd)) {
--- a/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java	Tue Jul 12 13:10:33 2011 +0200
+++ b/graal/com.oracle.max.graal.examples/src/com/oracle/max/graal/examples/opt/OptimizerImpl.java	Tue Jul 12 17:54:32 2011 +0200
@@ -59,7 +59,7 @@
 
     private boolean canOverflow(Phi phi, LoopBegin loopBegin) {
 
-        NodeBitMap nodes = LoopUtil.computeLoopNodes(loopBegin);
+        NodeBitMap nodes = LoopUtil.markUpCFG(loopBegin);
         NodeBitMap exits = LoopUtil.computeLoopExits(loopBegin, nodes);
         for (Node exit : exits) {
             TTY.println("exit: " + exit);