changeset 19173:396ca3a22ee8

Perform analysis for locals changed in the loop and avoid creating phis for loop invariant locals.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Fri, 06 Feb 2015 04:35:28 +0100
parents 76090119f89c
children c154b12465d2
files graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java
diffstat 3 files changed, 62 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Fri Feb 06 04:33:04 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java	Fri Feb 06 04:35:28 2015 +0100
@@ -837,18 +837,6 @@
             }
         }
         blocks = newBlocks;
-
-        if (consecutiveLoopBlocks && this.nextLoop > 2) {
-            System.out.println();
-            for (int i = 0; i < blocks.length; ++i) {
-                String succ = "";
-                for (BciBlock succBlock : blocks[i].getSuccessors()) {
-                    succ += succBlock.getId() + " ";
-                }
-                System.out.printf("%3s %10s %s succ=[%s]\n", blocks[i].getId(), Long.toBinaryString(blocks[i].loops), blocks[i].isLoopHeader, succ);
-            }
-            System.out.println();
-        }
     }
 
     private int handleLoopHeader(BciBlock[] newBlocks, int nextStart, int i, BciBlock loopHeader) {
@@ -1092,6 +1080,11 @@
         public abstract boolean localIsLiveIn(BciBlock block, int local);
 
         /**
+         * Returns whether the local is set in the given loop.
+         */
+        public abstract boolean localIsChangedInLoop(int loopId, int local);
+
+        /**
          * Returns whether the local is live at the end of the given block.
          */
         public abstract boolean localIsLiveOut(BciBlock block, int local);
@@ -1146,6 +1139,7 @@
                 return;
             }
             int blockID = block.getId();
+            int localIndex;
             stream.setBCI(block.startBci);
             while (stream.currentBCI() <= block.endBci) {
                 switch (stream.currentBC()) {
@@ -1169,8 +1163,12 @@
                     case DLOAD_3:
                         loadTwo(blockID, 3);
                         break;
+                    case IINC:
+                        localIndex = stream.readLocalIndex();
+                        loadOne(blockID, localIndex);
+                        storeOne(blockID, localIndex);
+                        break;
                     case ILOAD:
-                    case IINC:
                     case FLOAD:
                     case ALOAD:
                     case RET:
@@ -1277,6 +1275,7 @@
         private final long[] localsLiveOut;
         private final long[] localsLiveGen;
         private final long[] localsLiveKill;
+        private final long[] localsChangedInLoop;
 
         public SmallLocalLiveness() {
             int blockSize = blocks.length;
@@ -1284,6 +1283,7 @@
             localsLiveOut = new long[blockSize];
             localsLiveGen = new long[blockSize];
             localsLiveKill = new long[blockSize];
+            localsChangedInLoop = new long[BciBlockMapping.this.nextLoop];
         }
 
         private String debugString(long value) {
@@ -1350,6 +1350,17 @@
             if ((localsLiveGen[blockID] & bit) == 0L) {
                 localsLiveKill[blockID] |= bit;
             }
+
+            BciBlock block = blocks[blockID];
+            long tmp = block.loops;
+            int pos = 0;
+            while (tmp != 0) {
+                if ((tmp & 1L) == 1L) {
+                    this.localsChangedInLoop[pos] |= bit;
+                }
+                tmp >>= 1;
+                ++pos;
+            }
         }
 
         @Override
@@ -1363,6 +1374,11 @@
             int blockID = block.getId();
             return blockID >= Integer.MAX_VALUE ? false : (localsLiveOut[blockID] & (1L << local)) != 0L;
         }
+
+        @Override
+        public boolean localIsChangedInLoop(int loopId, int local) {
+            return (localsChangedInLoop[loopId] & (1L << local)) != 0L;
+        }
     }
 
     public final class LargeLocalLiveness extends LocalLiveness {
@@ -1370,6 +1386,7 @@
         private BitSet[] localsLiveOut;
         private BitSet[] localsLiveGen;
         private BitSet[] localsLiveKill;
+        private BitSet[] localsChangedInLoop;
 
         public LargeLocalLiveness() {
             int blocksSize = blocks.length;
@@ -1377,11 +1394,16 @@
             localsLiveOut = new BitSet[blocksSize];
             localsLiveGen = new BitSet[blocksSize];
             localsLiveKill = new BitSet[blocksSize];
+            int maxLocals = method.getMaxLocals();
             for (int i = 0; i < blocksSize; i++) {
-                localsLiveIn[i] = new BitSet(method.getMaxLocals());
-                localsLiveOut[i] = new BitSet(method.getMaxLocals());
-                localsLiveGen[i] = new BitSet(method.getMaxLocals());
-                localsLiveKill[i] = new BitSet(method.getMaxLocals());
+                localsLiveIn[i] = new BitSet(maxLocals);
+                localsLiveOut[i] = new BitSet(maxLocals);
+                localsLiveGen[i] = new BitSet(maxLocals);
+                localsLiveKill[i] = new BitSet(maxLocals);
+            }
+            localsChangedInLoop = new BitSet[nextLoop];
+            for (int i = 0; i < nextLoop; ++i) {
+                localsChangedInLoop[i] = new BitSet(maxLocals);
             }
         }
 
@@ -1436,6 +1458,17 @@
             if (!localsLiveGen[blockID].get(local)) {
                 localsLiveKill[blockID].set(local);
             }
+
+            BciBlock block = blocks[blockID];
+            long tmp = block.loops;
+            int pos = 0;
+            while (tmp != 0) {
+                if ((tmp & 1L) == 1L) {
+                    this.localsChangedInLoop[pos].set(local);
+                }
+                tmp >>= 1;
+                ++pos;
+            }
         }
 
         @Override
@@ -1447,6 +1480,11 @@
         public boolean localIsLiveOut(BciBlock block, int local) {
             return block.getId() >= Integer.MAX_VALUE ? true : localsLiveOut[block.getId()].get(local);
         }
+
+        @Override
+        public boolean localIsChangedInLoop(int loopId, int local) {
+            return localsChangedInLoop[loopId].get(local);
+        }
     }
 
     public BciBlock[] getLoopHeaders() {
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Feb 06 04:33:04 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Feb 06 04:35:28 2015 +0100
@@ -1470,7 +1470,7 @@
                     lastInstr = loopBegin;
 
                     // Create phi functions for all local variables and operand stack slots.
-                    frameState.insertLoopPhis(loopBegin);
+                    frameState.insertLoopPhis(liveness, block.loopId, loopBegin);
                     loopBegin.setStateAfter(frameState.create(block.startBci));
 
                     /*
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Fri Feb 06 04:33:04 2015 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/HIRFrameStateBuilder.java	Fri Feb 06 04:35:28 2015 +0100
@@ -31,6 +31,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.debug.*;
+import com.oracle.graal.java.BciBlockMapping.LocalLiveness;
 import com.oracle.graal.java.GraphBuilderPlugins.ParameterPlugin;
 import com.oracle.graal.nodeinfo.*;
 import com.oracle.graal.nodes.*;
@@ -234,7 +235,7 @@
             return currentValue;
 
         } else if (currentValue != otherValue) {
-            assert !(block instanceof LoopBeginNode) : "Phi functions for loop headers are create eagerly for all locals and stack slots";
+            assert !(block instanceof LoopBeginNode) : "Phi functions for loop headers are create eagerly for changed locals and all stack slots";
             if (otherValue == null || otherValue.isDeleted() || currentValue.getKind() != otherValue.getKind()) {
                 return null;
             }
@@ -271,9 +272,11 @@
         }
     }
 
-    public void insertLoopPhis(LoopBeginNode loopBegin) {
+    public void insertLoopPhis(LocalLiveness liveness, int loopId, LoopBeginNode loopBegin) {
         for (int i = 0; i < localsSize(); i++) {
-            storeLocal(i, createLoopPhi(loopBegin, localAt(i)));
+            if (liveness.localIsChangedInLoop(loopId, i)) {
+                storeLocal(i, createLoopPhi(loopBegin, localAt(i)));
+            }
         }
         for (int i = 0; i < stackSize(); i++) {
             storeStack(i, createLoopPhi(loopBegin, stackAt(i)));