changeset 5732:e1d5c642d022

Started to draft a loop unswitching policy
author Gilles Duboscq <duboscq@ssw.jku.at>
date Thu, 28 Jun 2012 17:39:06 +0200
parents 3d5e2e330ae3
children 141b15521a39 98325620b7e2
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopEx.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/LoopFragmentWhole.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopPolicies.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopsData.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformLowPhase.java
diffstat 7 files changed, 67 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Thu Jun 28 16:04:37 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java	Thu Jun 28 17:39:06 2012 +0200
@@ -103,6 +103,8 @@
     public static boolean FullUnroll                         = true;
     public static int     FullUnrollMaxNodes                 = 150; // TODO (gd) tune
     public static boolean LoopUnswitch                       = ____;
+    public static int     LoopUnswitchMaxIncrease            = 50;
+    public static int     LoopUnswitchUncertaintyBoost       = 5;
 
     // debugging settings
     public static int     MethodEndBreakpointGuards          = 0;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopEx.java	Thu Jun 28 16:04:37 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopEx.java	Thu Jun 28 17:39:06 2012 +0200
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.compiler.loop;
 
+import java.util.*;
+
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
@@ -137,4 +139,30 @@
     public void setCounted(CountedLoopInfo countedLoopInfo) {
         counted = countedLoopInfo;
     }
+
+    public LoopsData loopsData() {
+        return data;
+    }
+
+    public NodeBitMap nodesInLoopFrom(BeginNode point, BeginNode until) {
+        Collection<BeginNode> blocks = new LinkedList<>();
+        Collection<BeginNode> exits = new LinkedList<>();
+        Queue<Block> work = new LinkedList<>();
+        ControlFlowGraph cfg = loopsData().controlFlowGraph();
+        work.add(cfg.blockFor(point));
+        Block untilBlock = until != null ? cfg.blockFor(until) : null;
+        while (!work.isEmpty()) {
+            Block b = work.remove();
+            if (b == untilBlock) {
+                continue;
+            }
+            if (lirLoop().exits.contains(b)) {
+                exits.add(b.getBeginNode());
+            } else if (lirLoop().blocks.contains(b)) {
+                blocks.add(b.getBeginNode());
+                work.addAll(b.getDominated());
+            }
+        }
+        return LoopFragment.computeNodes(point.graph(), blocks, exits);
+    }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragment.java	Thu Jun 28 16:04:37 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragment.java	Thu Jun 28 17:39:06 2012 +0200
@@ -30,7 +30,8 @@
 import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.PhiNode.PhiType;
-import com.oracle.graal.nodes.VirtualState.*;
+import com.oracle.graal.nodes.VirtualState.NodeClosure;
+import com.oracle.graal.nodes.VirtualState.VirtualClosure;
 
 
 public abstract class LoopFragment {
@@ -127,14 +128,6 @@
         }
     }
 
-    public static Collection<BeginNode> toHirBlocks(Collection<Block> blocks) {
-        List<BeginNode> hir = new ArrayList<>(blocks.size());
-        for (Block b : blocks) {
-            hir.add(b.getBeginNode());
-        }
-        return hir;
-    }
-
     protected static NodeBitMap computeNodes(Graph graph, Collection<BeginNode> blocks) {
         return computeNodes(graph, blocks, Collections.<BeginNode>emptyList());
     }
@@ -212,13 +205,21 @@
         return false;
     }
 
+    public static Collection<BeginNode> toHirBlocks(Collection<Block> blocks) {
+        List<BeginNode> hir = new ArrayList<>(blocks.size());
+        for (Block b : blocks) {
+            hir.add(b.getBeginNode());
+        }
+        return hir;
+    }
+
     /**
      * Merges the early exits (i.e. loop exits) that were duplicated as part of this fragment, with the original fragment's exits.
      */
     protected void mergeEarlyExits() {
         assert isDuplicate();
         StructuredGraph graph = graph();
-        for (BeginNode earlyExit : toHirBlocks(original().loop().lirLoop().exits)) {
+        for (BeginNode earlyExit : LoopFragment.toHirBlocks(original().loop().lirLoop().exits)) {
             FixedNode next = earlyExit.next();
             if (earlyExit.isDeleted() || !this.contains(earlyExit)) {
                 continue;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentWhole.java	Thu Jun 28 16:04:37 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopFragmentWhole.java	Thu Jun 28 17:39:06 2012 +0200
@@ -22,8 +22,8 @@
  */
 package com.oracle.graal.compiler.loop;
 
+import com.oracle.graal.graph.Graph.DuplicationReplacement;
 import com.oracle.graal.graph.*;
-import com.oracle.graal.graph.Graph.DuplicationReplacement;
 import com.oracle.graal.graph.iterators.*;
 import com.oracle.graal.lir.cfg.*;
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopPolicies.java	Thu Jun 28 16:04:37 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopPolicies.java	Thu Jun 28 17:39:06 2012 +0200
@@ -23,6 +23,8 @@
 package com.oracle.graal.compiler.loop;
 
 import com.oracle.graal.compiler.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.lir.cfg.*;
 import com.oracle.graal.nodes.*;
 
 
@@ -52,4 +54,19 @@
         // TODO (gd) maybe there should be a may number of unswitching per loop
         return true;
     }
+
+    public static boolean shouldUnswitch(LoopEx loop, IfNode ifNode) {
+        Block postDomBlock = loop.loopsData().controlFlowGraph().blockFor(ifNode).getPostdominator();
+        BeginNode postDom = postDomBlock != null ? postDomBlock.getBeginNode() : null;
+        int inTrueBranch = loop.nodesInLoopFrom(ifNode.trueSuccessor(), postDom).cardinality();
+        int inFalseBranch = loop.nodesInLoopFrom(ifNode.falseSuccessor(), postDom).cardinality();
+        int loopTotal = loop.size();
+        int netDiff = loopTotal - (inTrueBranch + inFalseBranch);
+        double uncertainty = (0.5 - Math.abs(ifNode.probability(IfNode.TRUE_EDGE) - 0.5)) * 2;
+        int maxDiff = GraalOptions.LoopUnswitchMaxIncrease + (int) (GraalOptions.LoopUnswitchUncertaintyBoost * loop.loopBegin().loopFrequency() * uncertainty);
+        Debug.log("shouldUnswitch(%s, %s) : delta=%d, max=%d, %.2f%% inside of if", loop, ifNode, netDiff, maxDiff, (double) (inTrueBranch + inFalseBranch) / loopTotal * 100);
+        return netDiff <= maxDiff;
+    }
+
+
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopsData.java	Thu Jun 28 16:04:37 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/loop/LoopsData.java	Thu Jun 28 17:39:06 2012 +0200
@@ -35,13 +35,14 @@
 public class LoopsData {
     private Map<Loop, LoopEx> lirLoopToEx = new IdentityHashMap<>();
     private Map<LoopBeginNode, LoopEx> loopBeginToEx = new IdentityHashMap<>();
+    private ControlFlowGraph cfg;
 
     public LoopsData(final StructuredGraph graph) {
 
-        ControlFlowGraph cfg = Debug.scope("ControlFlowGraph", new Callable<ControlFlowGraph>() {
+        cfg = Debug.scope("ControlFlowGraph", new Callable<ControlFlowGraph>() {
             @Override
             public ControlFlowGraph call() throws Exception {
-                return ControlFlowGraph.compute(graph, true, true, true, false);
+                return ControlFlowGraph.compute(graph, true, true, true, true);
             }
         });
         for (Loop lirLoop : cfg.getLoops()) {
@@ -150,4 +151,8 @@
             }
         }
     }
+
+    public ControlFlowGraph controlFlowGraph() {
+        return cfg;
+    }
 }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformLowPhase.java	Thu Jun 28 16:04:37 2012 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoopTransformLowPhase.java	Thu Jun 28 17:39:06 2012 +0200
@@ -54,7 +54,7 @@
                     for (LoopEx loop : dataUnswitch.loops()) {
                         if (LoopPolicies.shouldTryUnswitch(loop)) {
                             IfNode ifNode = LoopTransformations.findUnswitchableIf(loop);
-                            if (ifNode != null && !unswitchedDebug.isMarked(ifNode)) {
+                            if (ifNode != null && !unswitchedDebug.isMarked(ifNode) && LoopPolicies.shouldUnswitch(loop, ifNode)) {
                                 unswitchedDebug.mark(ifNode);
                                 Debug.log("Unswitching %s at %s [%f - %f]", loop, ifNode, ifNode.probability(0), ifNode.probability(1));
                                 //LoopTransformations.unswitch(loop, ifNode);