# HG changeset patch # User Josef Eisl # Date 1404301621 -7200 # Node ID d075b97fbd31c79b450fe90a571f8ef1df5ad7c5 # Parent 62dd783630c4453fca2009bead15c079e8b294df LSRA spill optimization: insert spill moves eagerly. diff -r 62dd783630c4 -r d075b97fbd31 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Tue Jul 01 20:35:53 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Wed Jul 02 13:47:01 2014 +0200 @@ -2028,6 +2028,7 @@ private DebugMetric betterSpillPosWithLowerProbability = Debug.metric("BetterSpillPositionWithLowerProbability"); private void optimizeSpillPosition() { + LIRInsertionBuffer[] insertionBuffers = new LIRInsertionBuffer[ir.linearScanOrder().size()]; for (Interval interval : intervals) { if (interval != null && interval.isSplitParent() && interval.spillState() == SpillState.SpillInDominator) { AbstractBlock defBlock = blockForId(interval.spillDefinitionPos()); @@ -2084,8 +2085,26 @@ // better spill block has the same probability -> do nothing interval.setSpillState(SpillState.StoreAtDefinition); } else { + LIRInsertionBuffer insertionBuffer = insertionBuffers[spillBlock.getId()]; + if (insertionBuffer == null) { + insertionBuffer = new LIRInsertionBuffer(); + insertionBuffers[spillBlock.getId()] = insertionBuffer; + insertionBuffer.init(ir.getLIRforBlock(spillBlock)); + } + int spillOpId = getFirstLirInstructionId(spillBlock); + // insert spill move + AllocatableValue fromLocation = interval.getSplitChildAtOpId(spillOpId, OperandMode.DEF, this).location(); + AllocatableValue toLocation = canonicalSpillOpr(interval); + LIRInstruction move = ir.getSpillMoveFactory().createMove(toLocation, fromLocation); + move.setId(-2); + /* + * We can use the insertion buffer directly because we always insert + * at position 1. + */ + insertionBuffer.append(1, move); + betterSpillPosWithLowerProbability.increment(); - interval.setSpillDefinitionPos(getFirstLirInstructionId(spillBlock)); + interval.setSpillDefinitionPos(spillOpId); } } else { // definition is the best choice @@ -2095,6 +2114,12 @@ } } } + for (LIRInsertionBuffer insertionBuffer : insertionBuffers) { + if (insertionBuffer != null) { + assert insertionBuffer.initialized() : "Insertion buffer is nonnull but not initialized!"; + insertionBuffer.finish(); + } + } } /** diff -r 62dd783630c4 -r d075b97fbd31 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java Tue Jul 01 20:35:53 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java Wed Jul 02 13:47:01 2014 +0200 @@ -191,7 +191,8 @@ @Override public Value doValue(LIRInstruction op, Value operand, OperandMode mode, EnumSet flags) { - if (LinearScan.isVariableOrRegister(operand) && allocator.isProcessed(operand)) { + // op.id() == -2 are spill moves inserted by the spill position optimization + if (LinearScan.isVariableOrRegister(operand) && allocator.isProcessed(operand) && op.id() != -2) { Interval interval = intervalAt(operand); if (op.id() != -1) { interval = interval.getSplitChildAtOpId(op.id(), mode, allocator);