Mercurial > hg > graal-compiler
changeset 23029:ccfa6d4d989b
TraceRA: replace TraceInterval.alwaysInMemory() with inMemoryAt(opId).
author | Josef Eisl <josef.eisl@jku.at> |
---|---|
date | Thu, 19 Nov 2015 16:51:23 +0100 |
parents | f81a81808795 |
children | 183221119491 |
files | graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceInterval.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanAssignLocationsPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanEliminateSpillMovePhase.java |
diffstat | 3 files changed, 16 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceInterval.java Thu Nov 19 16:36:45 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceInterval.java Thu Nov 19 16:51:23 2015 +0100 @@ -530,9 +530,12 @@ splitParent().spillDefinitionPos = pos; } - // returns true if this interval has a shadow copy on the stack that is always correct - public boolean alwaysInMemory() { - return SpillState.ALWAYS_IN_MEMORY.contains(spillState()) && !canMaterialize(); + /** + * Returns true if this interval has a shadow copy on the stack that is correct after + * {@code opId}. + */ + public boolean inMemoryAt(int opId) { + return SpillState.ALWAYS_IN_MEMORY.contains(spillState()) && !canMaterialize() && opId > spillDefinitionPos(); } void removeFirstUsePos() {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanAssignLocationsPhase.java Thu Nov 19 16:36:45 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanAssignLocationsPhase.java Thu Nov 19 16:51:23 2015 +0100 @@ -148,7 +148,7 @@ * instruction is a branch, spill moves are inserted before this branch and so the * wrong operand would be returned (spill moves at block boundaries are not * considered in the live ranges of intervals). - * + * * Solution: use the first opId of the branch target block instead. */ final LIRInstruction instr = allocator.getLIR().getLIRforBlock(block).get(allocator.getLIR().getLIRforBlock(block).size() - 1); @@ -264,7 +264,7 @@ assert interval != null : "interval must exist"; interval = allocator.splitChildAtOpId(interval, instruction.id(), mode); - if (interval.alwaysInMemory() && isRegister(interval.location())) { + if (interval.inMemoryAt(instruction.id()) && isRegister(interval.location())) { return new ShadowedRegisterValue((RegisterValue) interval.location(), interval.spillSlot()); } }
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanEliminateSpillMovePhase.java Thu Nov 19 16:36:45 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanEliminateSpillMovePhase.java Thu Nov 19 16:51:23 2015 +0100 @@ -88,6 +88,7 @@ List<LIRInstruction> instructions = allocator.getLIR().getLIRforBlock(block); int numInst = instructions.size(); + int lastOpId = -1; // iterate all instructions of the block. for (int j = 0; j < numInst; j++) { LIRInstruction op = instructions.get(j); @@ -100,7 +101,7 @@ * be correct. Only moves that have been inserted by LinearScan can be * removed. */ - if (shouldEliminateSpillMoves && canEliminateSpillMove(allocator, block, move)) { + if (shouldEliminateSpillMoves && canEliminateSpillMove(allocator, block, move, lastOpId)) { /* * Move target is a stack slot that is always correct, so eliminate * instruction. @@ -121,6 +122,7 @@ } } else { + lastOpId = opId; /* * Insert move from register to stack just after the beginning of the * interval. @@ -173,13 +175,16 @@ * @param allocator * @param block The block {@code move} is located in. * @param move Spill move. + * @param lastOpId The id of last "normal" instruction before the spill move. (Spill moves have + * no valid opId but -1.) */ - private static boolean canEliminateSpillMove(TraceLinearScan allocator, AbstractBlockBase<?> block, MoveOp move) { + private static boolean canEliminateSpillMove(TraceLinearScan allocator, AbstractBlockBase<?> block, MoveOp move, int lastOpId) { assert isVariable(move.getResult()) : "LinearScan inserts only moves to variables: " + move; + assert lastOpId >= 0 : "Invalid lastOpId: " + lastOpId; TraceInterval curInterval = allocator.intervalFor(move.getResult()); - if (!isRegister(curInterval.location()) && curInterval.alwaysInMemory() && isPhiResolutionMove(allocator, move)) { + if (!isRegister(curInterval.location()) && curInterval.inMemoryAt(lastOpId) && isPhiResolutionMove(allocator, move)) { assert isStackSlotValue(curInterval.location()) : "Not a stack slot: " + curInterval.location(); return true; }