Mercurial > hg > truffle
changeset 16357:a07492ccaf52
LSRA spill optimization: calculate optimized spill position.
author | Josef Eisl <josef.eisl@jku.at> |
---|---|
date | Wed, 04 Jun 2014 14:53:12 +0200 |
parents | 830fd9cd1099 |
children | 9371b9c246ca |
files | graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java |
diffstat | 1 files changed, 69 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Wed Jun 04 12:19:24 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Wed Jun 04 14:53:12 2014 +0200 @@ -25,6 +25,7 @@ import static com.oracle.graal.api.code.CodeUtil.*; import static com.oracle.graal.api.code.ValueUtil.*; import static com.oracle.graal.compiler.GraalDebugConfig.*; +import static com.oracle.graal.compiler.common.cfg.AbstractBlock.*; import static com.oracle.graal.lir.LIRValueUtil.*; import java.util.*; @@ -1844,6 +1845,12 @@ throw Debug.handle(e); } + try (Scope s = Debug.scope("SpillPosition")) { + findSpillPosition(); + } catch (Throwable e) { + throw Debug.handle(e); + } + try (Scope s = Debug.scope("ResolveDataFlow")) { resolveDataFlow(); } catch (Throwable e) { @@ -1876,6 +1883,68 @@ } } + private DebugMetric betterSpillPos = Debug.metric("BetterSpillPosition"); + + private void findSpillPosition() { + for (Interval interval : intervals) { + if (interval != null && interval.isSplitParent() && interval.spillState() == SpillState.StoreAtDefinition) { + AbstractBlock<?> defBlock = blockForId(interval.spillDefinitionPos()); + AbstractBlock<?> spillBlock = null; + 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; + } + } + } + assert spillBlock != null; + assert dominates(defBlock, spillBlock); + if (!defBlock.equals(spillBlock)) { + betterSpillPos.increment(); + int pos = getFirstLirInstructionId(spillBlock); + Debug.log("Better spill position found (Block %s, %d)", spillBlock, pos); + } + } + } + } + } + + private AbstractBlock<?> nearestCommonDominator(AbstractBlock<?> a, AbstractBlock<?> b) { + assert a != null; + assert b != null; + try (Indent indent = Debug.logAndIndent("nearest common dominator of %s and %s", a, b)) { + + if (a.equals(b)) { + return a; + } + + // collect a's dominators + BitSet aDom = new BitSet(sortedBlocks.size()); + + // a != b + for (AbstractBlock<?> x = a; x != null; x = x.getDominator()) { + aDom.set(x.getId()); + } + + // walk b's dominator + for (AbstractBlock<?> x = b; x != null; x = x.getDominator()) { + if (aDom.get(x.getId())) { + Debug.log("found %s", x); + return x; + } + } + } + Debug.log("no common dominator found"); + return null; + } + void printIntervals(String label) { if (Debug.isLogEnabled()) { try (Indent indent = Debug.logAndIndent("intervals %s", label)) {