changeset 22831:442985bada8c

TraceRA: TraceLinearScanWalker: clean up splitBeforeUsage and implement findOptimalSplitPos.
author Josef Eisl <josef.eisl@jku.at>
date Thu, 08 Oct 2015 15:17:14 +0200
parents fa48dd0537cd
children 44ebaa4e1ac1
files graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanWalker.java
diffstat 1 files changed, 72 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanWalker.java	Thu Oct 08 15:18:56 2015 +0200
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanWalker.java	Thu Oct 08 15:17:14 2015 +0200
@@ -287,7 +287,6 @@
         moveResolver.addMapping(srcIt, dstIt);
     }
 
-    @SuppressWarnings("unused")
     private int findOptimalSplitPos(AbstractBlockBase<?> minBlock, AbstractBlockBase<?> maxBlock, int maxSplitPos) {
         int fromBlockNr = minBlock.getLinearScanNumber();
         int toBlockNr = maxBlock.getLinearScanNumber();
@@ -303,13 +302,14 @@
             optimalSplitPos = allocator.getFirstLirInstructionId(maxBlock);
         }
 
-        int minLoopDepth = maxBlock.getLoopDepth();
+        // minimal block probability
+        double minProbability = maxBlock.probability();
         for (int i = toBlockNr - 1; i >= fromBlockNr; i--) {
             AbstractBlockBase<?> cur = blockAt(i);
 
-            if (cur.getLoopDepth() < minLoopDepth) {
-                // block with lower loop-depth found . split at the end of this block
-                minLoopDepth = cur.getLoopDepth();
+            if (cur.probability() < minProbability) {
+                // Block with lower probability found. Split at the end of this block.
+                minProbability = cur.probability();
                 optimalSplitPos = allocator.getLastLirInstructionId(cur) + 2;
             }
         }
@@ -318,16 +318,57 @@
         return optimalSplitPos;
     }
 
-    @SuppressWarnings({"static-method", "unused"})
     private int findOptimalSplitPos(TraceInterval interval, int minSplitPos, int maxSplitPos, boolean doLoopOptimization) {
-        // TODO (je) implement
-        int optimalSplitPos = maxSplitPos;
+        int optimalSplitPos = findOptimalSplitPos0(interval, minSplitPos, maxSplitPos, doLoopOptimization);
         if (Debug.isLogEnabled()) {
             Debug.log("optimal split position: %d", optimalSplitPos);
         }
         return optimalSplitPos;
     }
 
+    @SuppressWarnings({"unused"})
+    private int findOptimalSplitPos0(TraceInterval interval, int minSplitPos, int maxSplitPos, boolean doLoopOptimization) {
+        // TODO (je) implement
+        if (minSplitPos == maxSplitPos) {
+            // trivial case, no optimization of split position possible
+            if (Debug.isLogEnabled()) {
+                Debug.log("min-pos and max-pos are equal, no optimization possible");
+            }
+            return minSplitPos;
+
+        }
+        assert minSplitPos < maxSplitPos : "must be true then";
+        assert minSplitPos > 0 : "cannot access minSplitPos - 1 otherwise";
+
+        // reason for using minSplitPos - 1: when the minimal split pos is exactly at the
+        // beginning of a block, then minSplitPos is also a possible split position.
+        // Use the block before as minBlock, because then minBlock.lastLirInstructionId() + 2 ==
+        // minSplitPos
+        AbstractBlockBase<?> minBlock = allocator.blockForId(minSplitPos - 1);
+
+        // reason for using maxSplitPos - 1: otherwise there would be an assert on failure
+        // when an interval ends at the end of the last block of the method
+        // (in this case, maxSplitPos == allocator().maxLirOpId() + 2, and there is no
+        // block at this opId)
+        AbstractBlockBase<?> maxBlock = allocator.blockForId(maxSplitPos - 1);
+
+        assert minBlock.getLinearScanNumber() <= maxBlock.getLinearScanNumber() : "invalid order";
+        if (minBlock == maxBlock) {
+            // split position cannot be moved to block boundary : so split as late as possible
+            if (Debug.isLogEnabled()) {
+                Debug.log("cannot move split pos to block boundary because minPos and maxPos are in same block");
+            }
+            return maxSplitPos;
+
+        }
+        // seach optimal block boundary between minSplitPos and maxSplitPos
+        if (Debug.isLogEnabled()) {
+            Debug.log("moving split pos to optimal block boundary between block B%d and B%d", minBlock.getId(), maxBlock.getId());
+        }
+
+        return findOptimalSplitPos(minBlock, maxBlock, maxSplitPos);
+    }
+
     // split an interval at the optimal position between minSplitPos and
     // maxSplitPos in two parts:
     // 1) the left part has already a location assigned
@@ -342,11 +383,7 @@
             assert minSplitPos <= maxSplitPos : "invalid order";
             assert maxSplitPos <= interval.to() : "cannot split after end of interval";
 
-            int optimalSplitPos = findOptimalSplitPos(interval, minSplitPos, maxSplitPos, true);
-
-            assert minSplitPos <= optimalSplitPos && optimalSplitPos <= maxSplitPos : "out of range";
-            assert optimalSplitPos <= interval.to() : "cannot split after end of interval";
-            assert optimalSplitPos > interval.from() : "cannot split at start of interval";
+            final int optimalSplitPos = findOptimalSplitPos(interval, minSplitPos, maxSplitPos, true);
 
             if (optimalSplitPos == interval.to() && interval.nextUsage(RegisterPriority.MustHaveRegister, minSplitPos) == Integer.MAX_VALUE) {
                 // the split position would be just before the end of the interval
@@ -356,27 +393,37 @@
                 }
                 return;
             }
-
             // must calculate this before the actual split is performed and before split position is
             // moved to odd opId
-            boolean isBlockBegin = allocator.isBlockBegin(optimalSplitPos);
-            boolean moveNecessary = true;
+            final int optimalSplitPosFinal;
+            if (allocator.isBlockBegin(optimalSplitPos)) {
+                assert (optimalSplitPos & 1) == 0 : "Block begins must be even: " + optimalSplitPos;
+                // move position after the label (odd optId)
+                optimalSplitPosFinal = optimalSplitPos + 1;
+            } else {
+                // move position before actual instruction (odd opId)
+                optimalSplitPosFinal = (optimalSplitPos - 1) | 1;
+            }
 
-            if (isBlockBegin) {
-                optimalSplitPos = insertIdAtBasicBlockBoundary(optimalSplitPos);
-            }
-            // move position before actual instruction (odd opId)
-            optimalSplitPos = (optimalSplitPos - 1) | 1;
+            assert minSplitPos <= optimalSplitPosFinal && optimalSplitPosFinal <= maxSplitPos : "out of range";
+            assert optimalSplitPosFinal <= interval.to() : "cannot split after end of interval";
+            assert optimalSplitPosFinal > interval.from() : "cannot split at start of interval";
 
             if (Debug.isLogEnabled()) {
-                Debug.log("splitting at position %d", optimalSplitPos);
+                Debug.log("splitting at position %d", optimalSplitPosFinal);
             }
+            assert optimalSplitPosFinal > currentPosition : "Can not split interval " + interval + " at current position: " + currentPosition;
 
-            assert isBlockBegin || ((optimalSplitPos & 1) == 1) : "split pos must be odd when not on block boundary";
-            assert !isBlockBegin || ((optimalSplitPos & 1) == 0) : "split pos must be even on block boundary";
+            // was:
+            // assert isBlockBegin || ((optimalSplitPos1 & 1) == 1) :
+            // "split pos must be odd when not on block boundary";
+            // assert !isBlockBegin || ((optimalSplitPos1 & 1) == 0) :
+            // "split pos must be even on block boundary";
+            assert (optimalSplitPosFinal & 1) == 1 : "split pos must be odd";
 
-            TraceInterval splitPart = interval.split(optimalSplitPos, allocator);
+            TraceInterval splitPart = interval.split(optimalSplitPosFinal, allocator);
 
+            boolean moveNecessary = true;
             splitPart.setInsertMoveWhenActivated(moveNecessary);
 
             assert splitPart.from() >= currentPosition : "cannot append new interval before current walk position";