Mercurial > hg > truffle
changeset 13462:5f54b8a68346
limit complexity of redundant move elimination
author | Erik Eckstein <erik.eckstein@oracle.com> |
---|---|
date | Thu, 19 Dec 2013 08:35:37 +0100 |
parents | 52eb34dd84d7 |
children | 424e2bfecb72 |
files | graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java |
diffstat | 1 files changed, 34 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java Wed Dec 18 17:33:00 2013 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java Thu Dec 19 08:35:37 2013 +0100 @@ -103,17 +103,27 @@ initBlockData(lir); - solveDataFlow(lir); + if (!solveDataFlow(lir)) { + return; + } eliminateMoves(lir); } } + /** + * The maximum number of locations * blocks. This is a complexity limit for the inner loop in + * {@link #mergeState} (assuming a small number of iterations in {@link #solveDataFlow}. + */ + private static final int COMPLEXITY_LIMIT = 30000; + private void initBlockData(LIR lir) { List<Block> blocks = lir.linearScanOrder(); numRegs = 0; + int maxStackLocations = COMPLEXITY_LIMIT / blocks.size(); + /* * Search for relevant locations which can be optimized. These are register or stack slots * which occur as destinations of move instructions. @@ -130,7 +140,7 @@ } } else if (isStackSlot(dest)) { StackSlot stackSlot = (StackSlot) dest; - if (!stackIndices.containsKey(stackSlot)) { + if (!stackIndices.containsKey(stackSlot) && stackIndices.size() < maxStackLocations) { stackIndices.put(stackSlot, stackIndices.size()); } } @@ -151,13 +161,17 @@ /** * Calculates the entry and exit states for all basic blocks. + * + * @return Returns true on success and false if the the control flow is too complex. */ - private void solveDataFlow(LIR lir) { + private boolean solveDataFlow(LIR lir) { Indent indent = Debug.logAndIndent("solve data flow"); List<Block> blocks = lir.linearScanOrder(); + int numIter = 0; + /* * Iterate until there are no more changes. */ @@ -229,10 +243,20 @@ } firstRound = false; indent2.outdent(); + numIter++; + + if (numIter > 5) { + /* + * This is _very_ seldom. + */ + return false; + } } while (changed); indent.outdent(); + + return true; } /** @@ -378,12 +402,15 @@ boolean changed = false; for (int idx = 0; idx < source.length; idx++) { int phiNum = defNum + idx; - if (dest[idx] != source[idx] && source[idx] != INIT_VALUE && dest[idx] != encodeValueNum(phiNum, isObjectValue(dest[idx]))) { - if (dest[idx] != INIT_VALUE) { - dest[idx] = encodeValueNum(phiNum, isObjectValue(dest[idx]) || isObjectValue(source[idx])); + int dst = dest[idx]; + int src = source[idx]; + if (dst != src && src != INIT_VALUE && dst != encodeValueNum(phiNum, isObjectValue(dst))) { + if (dst != INIT_VALUE) { + dst = encodeValueNum(phiNum, isObjectValue(dst) || isObjectValue(src)); } else { - dest[idx] = source[idx]; + dst = src; } + dest[idx] = dst; changed = true; } }