Mercurial > hg > truffle
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)));