changeset 5741:c84c75339af1

Work on loop unswitching, things look ok, still disabled until FloatingRead preserves loop-closed form
author Gilles Duboscq <duboscq@ssw.jku.at>
date Mon, 02 Jul 2012 16:53:12 +0200
parents 98325620b7e2
children a8c6104ef526
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragment.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentInside.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentWhole.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopTransformations.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformLowPhase.java src/share/tools/IdealGraphVisualizer/nbproject/project.properties
diffstat 8 files changed, 123 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Mon Jul 02 15:08:05 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java	Mon Jul 02 16:53:12 2012 +0200
@@ -188,18 +188,17 @@
         if (GraalOptions.CheckCastElimination) {
             new CheckCastEliminationPhase().apply(graph);
         }
+        if (GraalOptions.OptCanonicalizer) {
+            new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
+        }
+        if (GraalOptions.OptCanonicalizer) {
+            new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
+        }
 
         if (GraalOptions.OptLoopTransform) {
             new LoopTransformLowPhase().apply(graph);
         }
         new RemoveValueProxyPhase().apply(graph);
-        if (GraalOptions.OptCanonicalizer) {
-            new CanonicalizerPhase(target, runtime, assumptions).apply(graph);
-        }
-        if (GraalOptions.CheckCastElimination) {
-            new CheckCastEliminationPhase().apply(graph);
-        }
-
 
         plan.runPhases(PhasePosition.MID_LEVEL, graph);
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Mon Jul 02 15:08:05 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Mon Jul 02 16:53:12 2012 +0200
@@ -97,11 +97,11 @@
     //rematerialize settings
     public static float   MinimumUsageProbability            = 0.95f;
 
-    //loop transform settings
+    //loop transform settings TODO (gd) tune
     public static float   MinimumPeelProbability             = 0.35f;
     public static boolean ReassociateInvariants              = true;
     public static boolean FullUnroll                         = true;
-    public static int     FullUnrollMaxNodes                 = 150; // TODO (gd) tune
+    public static int     FullUnrollMaxNodes                 = 150;
     public static boolean LoopUnswitch                       = ____;
     public static int     LoopUnswitchMaxIncrease            = 50;
     public static int     LoopUnswitchUncertaintyBoost       = 5;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragment.java	Mon Jul 02 15:08:05 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragment.java	Mon Jul 02 16:53:12 2012 +0200
@@ -89,7 +89,13 @@
     public abstract NodeIterable<Node> nodes();
 
     public StructuredGraph graph() {
-        return (StructuredGraph) loop.loopBegin().graph();
+        LoopEx l;
+        if (isDuplicate()) {
+            l = original().loop();
+        } else {
+            l = loop();
+        }
+        return (StructuredGraph) l.loopBegin().graph();
     }
 
     protected abstract DuplicationReplacement getDuplicationReplacement();
@@ -99,11 +105,13 @@
     protected void patchNodes(final DuplicationReplacement dataFix) {
         if (isDuplicate() && !nodesReady) {
             assert !original.isDuplicate();
-            final DuplicationReplacement cfgFix = getDuplicationReplacement();
+            final DuplicationReplacement cfgFix = original().getDuplicationReplacement();
             DuplicationReplacement dr;
-            if (cfgFix == null) {
+            if (cfgFix == null && dataFix != null) {
                 dr = dataFix;
-            } else {
+            } else if (cfgFix != null && dataFix == null) {
+                dr = cfgFix;
+            } else if (cfgFix != null && dataFix != null) {
                 dr = new DuplicationReplacement() {
                     @Override
                     public Node replacement(Node o) {
@@ -119,8 +127,15 @@
                         return o;
                     }
                 };
+            } else {
+                dr = new DuplicationReplacement() {
+                    @Override
+                    public Node replacement(Node o) {
+                        return o;
+                    }
+                };
             }
-            duplicationMap = graph().addDuplicates(nodes(), dr);
+            duplicationMap = graph().addDuplicates(original().nodes(), dr);
             finishDuplication();
             nodesReady = true;
         } else {
@@ -221,11 +236,13 @@
         StructuredGraph graph = graph();
         for (BeginNode earlyExit : LoopFragment.toHirBlocks(original().loop().lirLoop().exits)) {
             FixedNode next = earlyExit.next();
-            if (earlyExit.isDeleted() || !this.contains(earlyExit)) {
+            if (earlyExit.isDeleted() || !this.original().contains(earlyExit)) {
                 continue;
             }
             BeginNode newEarlyExit = getDuplicatedNode(earlyExit);
-            assert newEarlyExit != null;
+            if (newEarlyExit == null) {
+                continue;
+            }
             MergeNode merge = graph.add(new MergeNode());
             merge.setProbability(next.probability());
             EndNode originalEnd = graph.add(new EndNode());
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentInside.java	Mon Jul 02 15:08:05 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentInside.java	Mon Jul 02 16:53:12 2012 +0200
@@ -41,7 +41,7 @@
      * In the unrolling case they will be used as the value that replace the loop-phis of the duplicated inside fragment
      */
     private Map<PhiNode, ValueNode> mergedInitializers;
-    private final DuplicationReplacement dataFix = new DuplicationReplacement() {
+    private final DuplicationReplacement dataFixBefore = new DuplicationReplacement() {
         @Override
         public Node replacement(Node oriInput) {
             if (!(oriInput instanceof ValueNode)) {
@@ -56,7 +56,7 @@
     }
 
     public LoopFragmentInside(LoopFragmentInside original) {
-        super(original.loop(), original);
+        super(null, original);
     }
 
     @Override
@@ -76,11 +76,16 @@
     }
 
     @Override
+    public LoopEx loop() {
+        assert !this.isDuplicate();
+        return super.loop();
+    }
+
+    @Override
     public void insertBefore(LoopEx loop) {
-        if (this.loop() != loop) {
-            throw new UnsupportedOperationException();
-        }
-        patchNodes(dataFix);
+        assert this.isDuplicate() && this.original().loop() == loop;
+
+        patchNodes(dataFixBefore);
 
         BeginNode end = mergeEnds();
 
@@ -88,7 +93,7 @@
 
         mergeEarlyExits();
 
-        BeginNode entry = getDuplicatedNode(this.loop().loopBegin());
+        BeginNode entry = getDuplicatedNode(loop.loopBegin());
         FrameState state = entry.stateAfter();
         if (state != null) {
             entry.setStateAfter(null);
@@ -137,7 +142,6 @@
     @Override
     protected void finishDuplication() {
         // TODO (gd) ?
-
     }
 
     private void patchPeeling(LoopFragmentInside peel) {
@@ -187,7 +191,8 @@
      * @return corresponding value in the peel
      */
     private ValueNode prim(ValueNode b) {
-        LoopBeginNode loopBegin = loop().loopBegin();
+        assert isDuplicate();
+        LoopBeginNode loopBegin = original().loop().loopBegin();
         if (loopBegin.isPhiAtMerge(b)) {
             PhiNode phi = (PhiNode) b;
             return phi.valueAt(loopBegin.forwardEnd());
@@ -203,9 +208,10 @@
     }
 
     private BeginNode mergeEnds() {
+        assert isDuplicate();
         List<EndNode> endsToMerge = new LinkedList<>();
         Map<EndNode, LoopEndNode> reverseEnds = new HashMap<>(); // map peel's exit to the corresponding loop exits
-        LoopBeginNode loopBegin = loop().loopBegin();
+        LoopBeginNode loopBegin = original().loop().loopBegin();
         for (LoopEndNode le : loopBegin.loopEnds()) {
             EndNode duplicate = getDuplicatedNode(le);
             if (duplicate != null) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentWhole.java	Mon Jul 02 15:08:05 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentWhole.java	Mon Jul 02 16:53:12 2012 +0200
@@ -26,6 +26,7 @@
 import com.oracle.graal.graph.*;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.lir.cfg.*;
+import com.oracle.graal.nodes.*;
 
 
 public class LoopFragmentWhole extends LoopFragment {
@@ -34,10 +35,23 @@
         super(loop);
     }
 
+    public LoopFragmentWhole(LoopFragmentWhole original) {
+        super(null, original);
+    }
+
     @Override
     public LoopFragmentWhole duplicate() {
-        // TODO (gd) do not forget to make a FULL loop : do not forget the forward end which is not part of the original loop stricto sensus
-        return null;
+        LoopFragmentWhole loopFragmentWhole = new LoopFragmentWhole(this);
+        loopFragmentWhole.reify();
+        return loopFragmentWhole;
+    }
+
+    private void reify() {
+        assert this.isDuplicate();
+
+        patchNodes(null);
+
+        mergeEarlyExits();
     }
 
     @Override
@@ -51,13 +65,29 @@
 
     @Override
     protected DuplicationReplacement getDuplicationReplacement() {
-        return null;
+        final FixedNode entry = loop().entryPoint();
+        final Graph graph = this.graph();
+        return new DuplicationReplacement() {
+            @Override
+            public Node replacement(Node o) {
+                if (o == entry) {
+                    return graph.add(new EndNode());
+                }
+                return o;
+            }
+        };
+    }
+
+    public FixedNode entryPoint() {
+        if (isDuplicate()) {
+            return getDuplicatedNode(original().loop().loopBegin()).forwardEnd();
+        }
+        return loop().entryPoint();
     }
 
     @Override
     protected void finishDuplication() {
-        // TODO Auto-generated method stub
-
+        // TODO (gd) ?
     }
 
     @Override
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopTransformations.java	Mon Jul 02 15:08:05 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopTransformations.java	Mon Jul 02 16:53:12 2012 +0200
@@ -23,13 +23,43 @@
 package com.oracle.graal.compiler.loop;
 
 import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.phases.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.graal.nodes.util.*;
 
 
 public abstract class LoopTransformations {
     private static final int UNROLL_LIMIT = GraalOptions.FullUnrollMaxNodes * 2;
+    private static final SimplifierTool simplifier = new SimplifierTool() {
+        @Override
+        public TargetDescription target() {
+            return null;
+        }
+        @Override
+        public CodeCacheProvider runtime() {
+            return null;
+        }
+        @Override
+        public boolean isImmutable(Constant objectConstant) {
+            return false;
+        }
+        @Override
+        public Assumptions assumptions() {
+            return null;
+        }
+        @Override
+        public void deleteBranch(FixedNode branch) {
+            branch.predecessor().replaceFirstSuccessor(branch, null);
+            GraphUtil.killCFG(branch);
+        }
+        @Override
+        public void addToWorkList(Node node) {
+        }
+    };
 
     private LoopTransformations() {
         // does not need to be instantiated
@@ -64,16 +94,19 @@
 
     public static void unswitch(LoopEx loop, IfNode ifNode) {
         // duplicate will be true case, original will be false case
-        LoopFragmentWhole duplicateLoop = loop.whole().duplicate();
+        LoopFragmentWhole originalLoop = loop.whole();
+        LoopFragmentWhole duplicateLoop = originalLoop.duplicate();
         StructuredGraph graph = (StructuredGraph) ifNode.graph();
         BeginNode tempBegin = graph.add(new BeginNode());
-        loop.entryPoint().replaceAtPredecessor(tempBegin);
+        originalLoop.entryPoint().replaceAtPredecessor(tempBegin);
         double takenProbability = ifNode.probability(ifNode.blockSuccessorIndex(ifNode.trueSuccessor()));
-        IfNode newIf = graph.add(new IfNode(ifNode.compare(), duplicateLoop.loop().entryPoint(), loop.entryPoint(), takenProbability, ifNode.leafGraphId()));
+        IfNode newIf = graph.add(new IfNode(ifNode.compare(), duplicateLoop.entryPoint(), originalLoop.entryPoint(), takenProbability, ifNode.leafGraphId()));
         tempBegin.setNext(newIf);
         ifNode.setCompare(graph.unique(ConstantNode.forBoolean(false, graph)));
         IfNode duplicateIf = duplicateLoop.getDuplicatedNode(ifNode);
         duplicateIf.setCompare(graph.unique(ConstantNode.forBoolean(true, graph)));
+        ifNode.simplify(simplifier);
+        duplicateIf.simplify(simplifier);
         // TODO (gd) probabilities need some amount of fixup.. (probably also in other transforms)
     }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformLowPhase.java	Mon Jul 02 15:08:05 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformLowPhase.java	Mon Jul 02 16:53:12 2012 +0200
@@ -25,7 +25,6 @@
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.loop.*;
 import com.oracle.graal.debug.*;
-import com.oracle.graal.graph.*;
 import com.oracle.graal.nodes.*;
 
 public class LoopTransformLowPhase extends Phase {
@@ -46,7 +45,6 @@
                 });
             }
             if (GraalOptions.LoopUnswitch) {
-                NodeBitMap unswitchedDebug = graph.createNodeBitMap();
                 boolean unswitched;
                 do {
                     unswitched = false;
@@ -54,12 +52,11 @@
                     for (LoopEx loop : dataUnswitch.loops()) {
                         if (LoopPolicies.shouldTryUnswitch(loop)) {
                             IfNode ifNode = LoopTransformations.findUnswitchableIf(loop);
-                            if (ifNode != null && !unswitchedDebug.isMarked(ifNode) && LoopPolicies.shouldUnswitch(loop, ifNode)) {
-                                unswitchedDebug.mark(ifNode);
+                            if (ifNode != null && LoopPolicies.shouldUnswitch(loop, ifNode)) {
                                 Debug.log("Unswitching %s at %s [%f - %f]", loop, ifNode, ifNode.probability(0), ifNode.probability(1));
-                                //LoopTransformations.unswitch(loop, ifNode);
+                                LoopTransformations.unswitch(loop, ifNode);
                                 UNSWITCHED.increment();
-                                //Debug.dump(graph, "After unswitch %s", loop);
+                                Debug.dump(graph, "After unswitch %s", loop);
                                 unswitched = true;
                                 break;
                             }
--- a/src/share/tools/IdealGraphVisualizer/nbproject/project.properties	Mon Jul 02 15:08:05 2012 +0200
+++ b/src/share/tools/IdealGraphVisualizer/nbproject/project.properties	Mon Jul 02 16:53:12 2012 +0200
@@ -40,5 +40,5 @@
 
 # Disable assertions for RequestProcessor to prevent annoying messages in case
 # of multiple SceneAnimator update tasks in the default RequestProcessor.
-run.args.extra = -J-server -J-da:org.openide.util.RequestProcessor -J-Xms2g -J-Xmx2g
+run.args.extra = -J-server -J-da:org.openide.util.RequestProcessor -J-Xms2g -J-Xmx4g
 debug.args.extra = -J-server -J-da:org.openide.util.RequestProcessor