changeset 16368:ef641ba1fb69

LSRA spill optimization: mark the correct frame locations.
author Josef Eisl <josef.eisl@jku.at>
date Wed, 11 Jun 2014 14:51:27 +0200
parents f0ac7457252a
children f8ba57019a5d
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java
diffstat 1 files changed, 22 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Wed Jun 11 14:49:59 2014 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Wed Jun 11 14:51:27 2014 +0200
@@ -1728,6 +1728,9 @@
         // included in the oop map
         iw.walkBefore(op.id());
 
+        // TODO(je) we could pass this as parameter
+        AbstractBlock<?> block = blockForId(op.id());
+
         // Iterate through active intervals
         for (Interval interval = iw.activeLists.get(RegisterBinding.Fixed); interval != Interval.EndMarker; interval = interval.next) {
             Value operand = interval.operand;
@@ -1750,11 +1753,25 @@
                 // Spill optimization: when the stack value is guaranteed to be always correct,
                 // then it must be added to the oop map even if the interval is currently in a
                 // register
-                if (interval.alwaysInMemory() && op.id() > interval.spillDefinitionPos() && !interval.location().equals(interval.spillSlot())) {
-                    assert interval.spillDefinitionPos() > 0 : "position not set correctly";
-                    assert interval.spillSlot() != null : "no spill slot assigned";
-                    assert !isRegister(interval.operand) : "interval is on stack :  so stack slot is registered twice";
-                    info.markLocation(interval.spillSlot(), frameMap);
+                int spillPos = interval.spillDefinitionPos();
+                if (interval.spillState() != SpillState.SpillInDominator) {
+                    if (interval.alwaysInMemory() && op.id() > interval.spillDefinitionPos() && !interval.location().equals(interval.spillSlot())) {
+                        assert interval.spillDefinitionPos() > 0 : "position not set correctly";
+                        assert spillPos > 0 : "position not set correctly";
+                        assert interval.spillSlot() != null : "no spill slot assigned";
+                        assert !isRegister(interval.operand) : "interval is on stack :  so stack slot is registered twice";
+                        info.markLocation(interval.spillSlot(), frameMap);
+                    }
+                } else {
+                    AbstractBlock<?> spillBlock = blockForId(spillPos);
+                    if (interval.alwaysInMemory() && !interval.location().equals(interval.spillSlot())) {
+                        if ((spillBlock.equals(block) && op.id() > spillPos) || AbstractBlock.dominates(spillBlock, block)) {
+                            assert spillPos > 0 : "position not set correctly";
+                            assert interval.spillSlot() != null : "no spill slot assigned";
+                            assert !isRegister(interval.operand) : "interval is on stack :  so stack slot is registered twice";
+                            info.markLocation(interval.spillSlot(), frameMap);
+                        }
+                    }
                 }
             }
         }