# HG changeset patch # User Josef Eisl # Date 1433768605 -7200 # Node ID 4005025656eeef8c3d5fe7e5aceb4df62effffc1 # Parent 647459c6013aea53d7b6515a98795244ad290832 SSAMoveResolver: support stack2stack-only mappings. diff -r 647459c6013a -r 4005025656ee graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/MoveResolver.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/MoveResolver.java Mon Jun 08 17:51:58 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/MoveResolver.java Mon Jun 08 15:03:25 2015 +0200 @@ -26,6 +26,7 @@ import com.oracle.jvmci.meta.Value; import com.oracle.jvmci.meta.LIRKind; import com.oracle.jvmci.meta.AllocatableValue; + import static com.oracle.jvmci.code.ValueUtil.*; import static java.lang.String.*; @@ -44,7 +45,7 @@ private int insertIdx; private LIRInsertionBuffer insertionBuffer; // buffer where moves are inserted - private final List mappingFrom; + protected final List mappingFrom; private final List mappingFromOpr; private final List mappingTo; private boolean multipleReadsAllowed; @@ -320,39 +321,7 @@ } if (!processedInterval) { - // no move could be processed because there is a cycle in the move list - // (e.g. r1 . r2, r2 . r1), so one interval must be spilled to memory - assert spillCandidate != -1 : "no interval in register for spilling found"; - - // create a new spill interval and assign a stack slot to it - Interval fromInterval = mappingFrom.get(spillCandidate); - Interval spillInterval = getAllocator().createDerivedInterval(fromInterval); - spillInterval.setKind(fromInterval.kind()); - - // add a dummy range because real position is difficult to calculate - // Note: this range is a special case when the integrity of the allocation is - // checked - spillInterval.addRange(1, 2); - - // do not allocate a new spill slot for temporary interval, but - // use spill slot assigned to fromInterval. Otherwise moves from - // one stack slot to another can happen (not allowed by LIRAssembler - StackSlotValue spillSlot = fromInterval.spillSlot(); - if (spillSlot == null) { - spillSlot = getAllocator().frameMapBuilder.allocateSpillSlot(spillInterval.kind()); - fromInterval.setSpillSlot(spillSlot); - } - spillInterval.assignLocation(spillSlot); - - if (Debug.isLogEnabled()) { - Debug.log("created new Interval for spilling: %s", spillInterval); - } - blockRegisters(spillInterval); - - // insert a move from register to stack and update the mapping - insertMove(fromInterval, spillInterval); - mappingFrom.set(spillCandidate, spillInterval); - unblockRegisters(fromInterval); + breakCycle(spillCandidate); } } } @@ -364,6 +333,47 @@ assert checkEmpty(); } + protected void breakCycle(int spillCandidate) { + // no move could be processed because there is a cycle in the move list + // (e.g. r1 . r2, r2 . r1), so one interval must be spilled to memory + assert spillCandidate != -1 : "no interval in register for spilling found"; + + // create a new spill interval and assign a stack slot to it + Interval fromInterval = mappingFrom.get(spillCandidate); + // do not allocate a new spill slot for temporary interval, but + // use spill slot assigned to fromInterval. Otherwise moves from + // one stack slot to another can happen (not allowed by LIRAssembler + StackSlotValue spillSlot = fromInterval.spillSlot(); + if (spillSlot == null) { + spillSlot = getAllocator().frameMapBuilder.allocateSpillSlot(fromInterval.kind()); + fromInterval.setSpillSlot(spillSlot); + } + spillInterval(spillCandidate, fromInterval, spillSlot); + } + + protected void spillInterval(int spillCandidate, Interval fromInterval, StackSlotValue spillSlot) { + assert mappingFrom.get(spillCandidate).equals(fromInterval); + Interval spillInterval = getAllocator().createDerivedInterval(fromInterval); + spillInterval.setKind(fromInterval.kind()); + + // add a dummy range because real position is difficult to calculate + // Note: this range is a special case when the integrity of the allocation is + // checked + spillInterval.addRange(1, 2); + + spillInterval.assignLocation(spillSlot); + + if (Debug.isLogEnabled()) { + Debug.log("created new Interval for spilling: %s", spillInterval); + } + blockRegisters(spillInterval); + + // insert a move from register to stack and update the mapping + insertMove(fromInterval, spillInterval); + mappingFrom.set(spillCandidate, spillInterval); + unblockRegisters(fromInterval); + } + private void printMapping() { try (Indent indent = Debug.logAndIndent("Mapping")) { for (int i = mappingFrom.size() - 1; i >= 0; i--) { diff -r 647459c6013a -r 4005025656ee graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/SSAMoveResolver.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/SSAMoveResolver.java Mon Jun 08 17:51:58 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/SSAMoveResolver.java Mon Jun 08 15:03:25 2015 +0200 @@ -149,4 +149,20 @@ } return super.createMove(fromOpr, toOpr, fromLocation, toLocation); } + + @Override + protected void breakCycle(int spillCandidate) { + if (spillCandidate != -1) { + super.breakCycle(spillCandidate); + return; + } + assert mappingFrom.size() > 1; + // Arbitrarily select the first entry for spilling. + int stackSpillCandidate = 0; + Interval fromInterval = mappingFrom.get(stackSpillCandidate); + assert isStackSlotValue(fromInterval.location()); + // allocate new stack slot + StackSlotValue spillSlot = getAllocator().frameMapBuilder.allocateSpillSlot(fromInterval.kind()); + spillInterval(stackSpillCandidate, fromInterval, spillSlot); + } }