changeset 21966:4005025656ee

SSAMoveResolver: support stack2stack-only mappings.
author Josef Eisl <josef.eisl@jku.at>
date Mon, 08 Jun 2015 15:03:25 +0200
parents 647459c6013a
children f0e4a8342803
files graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/MoveResolver.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/SSAMoveResolver.java
diffstat 2 files changed, 60 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- 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<Interval> mappingFrom;
+    protected final List<Interval> mappingFrom;
     private final List<Value> mappingFromOpr;
     private final List<Interval> 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--) {
--- 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);
+    }
 }