Mercurial > hg > truffle
changeset 16364:a54a64af1e82
LSRA spill optimization: take all blocks (with usepos) of a spill interval into account.
author | Josef Eisl <josef.eisl@jku.at> |
---|---|
date | Thu, 05 Jun 2014 16:38:24 +0200 |
parents | a7d11e1c7387 |
children | d2fc1c153655 |
files | graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java |
diffstat | 1 files changed, 52 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Thu Jun 05 13:25:51 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Thu Jun 05 16:38:24 2014 +0200 @@ -1915,14 +1915,15 @@ try (Indent indent = Debug.logAndIndent("interval %s (%s)", interval, defBlock)) { for (Interval splitChild : interval.getSplitChildren()) { if (isStackSlot(splitChild.location())) { - AbstractBlock<?> splitBlock = blockForId(splitChild.from()); - assert dominates(defBlock, splitBlock) : "Definition does not dominate the spill interval"; - Debug.log("Split interval %s", splitChild, splitBlock); - if (spillBlock == null) { - spillBlock = splitBlock; - } else { - spillBlock = nearestCommonDominator(spillBlock, splitBlock); - assert spillBlock != null; + for (AbstractBlock<?> splitBlock : blocksForSplitChild(splitChild)) { + assert dominates(defBlock, splitBlock) : String.format("Definition does not dominate the spill block %s !dom %s (interval %s)", defBlock, splitBlock, interval); + Debug.log("Split interval %s, block %s", splitChild, splitBlock); + if (spillBlock == null) { + spillBlock = splitBlock; + } else { + spillBlock = nearestCommonDominator(spillBlock, splitBlock); + assert spillBlock != null; + } } } } @@ -1958,6 +1959,49 @@ } } + /** + * Iterate over all {@link AbstractBlock blocks} of an interval with an use position. + */ + private class UseBlockIterator implements Iterator<AbstractBlock<?>> { + + int nextOpId; + Interval interval; + + public UseBlockIterator(Interval interval) { + nextOpId = interval.nextUsage(RegisterPriority.None, 0); + this.interval = interval; + } + + public AbstractBlock<?> next() { + AbstractBlock<?> block = blockForId(nextOpId); + + int nextBlockIndex = block.getLinearScanNumber() + 1; + if (nextBlockIndex < sortedBlocks.size()) { + int from = getFirstLirInstructionId(sortedBlocks.get(nextBlockIndex)); + assert from > nextOpId : "cannot go backwards"; + assert from > maxOpId() || isBlockBegin(from) : "nextOpId is not a block begin"; + assert from > maxOpId() || blockForId(from).getLinearScanNumber() == block.getLinearScanNumber() + 1 : "nextOpId is not the beginning of the next block"; + nextOpId = interval.nextUsage(RegisterPriority.None, from); + } else { + // already at last the last block + nextOpId = Integer.MAX_VALUE; + } + return block; + } + + public boolean hasNext() { + return nextOpId < interval.to(); + } + } + + private Iterable<AbstractBlock<?>> blocksForSplitChild(Interval interval) { + return new Iterable<AbstractBlock<?>>() { + public Iterator<AbstractBlock<?>> iterator() { + return new UseBlockIterator(interval); + } + }; + } + private static AbstractBlock<?> moveSpillOutOfLoop(AbstractBlock<?> defBlock, AbstractBlock<?> spillBlock) { int defLoopDepth = defBlock.getLoopDepth(); for (AbstractBlock<?> block = spillBlock.getDominator(); !defBlock.equals(block); block = block.getDominator()) {