Mercurial > hg > graal-compiler
changeset 22834:7129686d9f18
TraceRA: use data-flow resolver to insert spill moves on block boundaries.
author | Josef Eisl <josef.eisl@jku.at> |
---|---|
date | Tue, 13 Oct 2015 13:48:23 +0200 |
parents | 054a187fc2cb |
children | 1b06a64e784f |
files | graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanResolveDataFlowPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanWalker.java |
diffstat | 2 files changed, 48 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanResolveDataFlowPhase.java Thu Oct 08 15:51:54 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanResolveDataFlowPhase.java Tue Oct 13 13:48:23 2015 +0200 @@ -29,6 +29,7 @@ import static jdk.vm.ci.code.ValueUtil.isStackSlotValue; import static jdk.vm.ci.code.ValueUtil.isVirtualStackSlot; +import java.util.BitSet; import java.util.List; import java.util.ListIterator; @@ -144,16 +145,44 @@ @SuppressWarnings("try") private void resolveCollectMappings(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock, TraceLocalMoveResolver moveResolver) { try (Indent indent0 = Debug.logAndIndent("Edge %s -> %s", fromBlock, toBlock)) { - // collect all intervals that have been split between - // fromBlock and toBlock - SSIUtil.forEachValuePair(allocator.getLIR(), toBlock, fromBlock, new MyPhiValueVisitor(moveResolver, toBlock, fromBlock)); - if (moveResolver.hasMappings()) { - resolveFindInsertPos(fromBlock, toBlock, moveResolver); - moveResolver.resolveAndAppendMoves(); + collectLSRAMappings(fromBlock, toBlock, moveResolver); + collectSSIMappings(fromBlock, toBlock, moveResolver); + } + } + + protected void collectLSRAMappings(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock, TraceLocalMoveResolver moveResolver) { + assert moveResolver.checkEmpty(); + + int toBlockFirstInstructionId = allocator.getFirstLirInstructionId(toBlock); + int fromBlockLastInstructionId = allocator.getLastLirInstructionId(fromBlock) + 1; + int numOperands = allocator.operandSize(); + BitSet liveAtEdge = allocator.getBlockData(toBlock).liveIn; + + // visit all variables for which the liveAtEdge bit is set + for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) { + assert operandNum < numOperands : "live information set for not exisiting interval"; + assert allocator.getBlockData(fromBlock).liveOut.get(operandNum) && allocator.getBlockData(toBlock).liveIn.get(operandNum) : "interval not live at this edge"; + + TraceInterval fromInterval = allocator.splitChildAtOpId(allocator.intervalFor(operandNum), fromBlockLastInstructionId, LIRInstruction.OperandMode.DEF); + TraceInterval toInterval = allocator.splitChildAtOpId(allocator.intervalFor(operandNum), toBlockFirstInstructionId, LIRInstruction.OperandMode.DEF); + + if (fromInterval != toInterval && !fromInterval.location().equals(toInterval.location())) { + // need to insert move instruction + moveResolver.addMapping(fromInterval, toInterval); } } } + protected void collectSSIMappings(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock, TraceLocalMoveResolver moveResolver) { + // collect all intervals that have been split between + // fromBlock and toBlock + SSIUtil.forEachValuePair(allocator.getLIR(), toBlock, fromBlock, new MyPhiValueVisitor(moveResolver, toBlock, fromBlock)); + if (moveResolver.hasMappings()) { + resolveFindInsertPos(fromBlock, toBlock, moveResolver); + moveResolver.resolveAndAppendMoves(); + } + } + private boolean containedInTrace(AbstractBlockBase<?> block) { return currentTrace() == traceBuilderResult.getTraceForBlock(block); }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanWalker.java Thu Oct 08 15:51:54 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanWalker.java Tue Oct 13 13:48:23 2015 +0200 @@ -241,6 +241,7 @@ } } + @SuppressWarnings("unused") private int insertIdAtBasicBlockBoundary(int opId) { assert allocator.isBlockBegin(opId) : "Not a block begin: " + opId; assert allocator.instructionForId(opId) instanceof LabelOp; @@ -518,11 +519,10 @@ assert optimalSplitPos < interval.to() : "cannot split at end of interval"; assert optimalSplitPos >= interval.from() : "cannot split before start of interval"; - if (allocator.isBlockBegin(optimalSplitPos)) { - optimalSplitPos = insertIdAtBasicBlockBoundary(optimalSplitPos); + if (!allocator.isBlockBegin(optimalSplitPos)) { + // move position before actual instruction (odd opId) + optimalSplitPos = (optimalSplitPos - 1) | 1; } - // move position before actual instruction (odd opId) - optimalSplitPos = (optimalSplitPos - 1) | 1; try (Indent indent2 = Debug.logAndIndent("splitting at position %d", optimalSplitPos)) { assert allocator.isBlockBegin(optimalSplitPos) || ((optimalSplitPos & 1) == 1) : "split pos must be odd when not on block boundary"; @@ -533,13 +533,16 @@ handleSpillSlot(spilledPart); changeSpillState(spilledPart, optimalSplitPos); - if (allocator.isBlockBegin(optimalSplitPos)) { - optimalSplitPos = insertIdAtBasicBlockBoundary(optimalSplitPos); + if (!allocator.isBlockBegin(optimalSplitPos)) { + if (Debug.isLogEnabled()) { + Debug.log("inserting move from interval %s to %s", interval, spilledPart); + } + insertMove(optimalSplitPos, interval, spilledPart); + } else { + if (Debug.isLogEnabled()) { + Debug.log("no need to insert move. done by data-flow resolution"); + } } - if (Debug.isLogEnabled()) { - Debug.log("inserting move from interval %s to %s", interval, spilledPart); - } - insertMove(optimalSplitPos, interval, spilledPart); // the currentSplitChild is needed later when moves are inserted for reloading assert spilledPart.currentSplitChild() == interval : "overwriting wrong currentSplitChild";