changeset 13610:6537a75007e3

consider register priority in rematerialization decision
author Erik Eckstein <erik.eckstein@oracle.com>
date Mon, 13 Jan 2014 11:28:25 +0100
parents 14db6fb488a0
children 428403544e77
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java
diffstat 3 files changed, 19 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java	Mon Jan 13 10:42:55 2014 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java	Mon Jan 13 11:28:25 2014 +0100
@@ -183,7 +183,7 @@
      * increasing order of priority are are used to optimize spilling when multiple overlapping
      * intervals compete for limited registers.
      */
-    enum RegisterPriority {
+    public enum RegisterPriority {
         /**
          * No special reason for an interval to be allocated a register.
          */
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Mon Jan 13 10:42:55 2014 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Mon Jan 13 11:28:25 2014 +0100
@@ -1036,7 +1036,7 @@
             // detection of method-parameters and roundfp-results
             interval.setSpillState(SpillState.StartInMemory);
         }
-        interval.addMaterializationValue(gen.getMaterializedValue(op, operand));
+        interval.addMaterializationValue(gen.getMaterializedValue(op, operand, interval));
 
         Debug.log("add def: %s defPos %d (%s)", interval, defPos, registerPriority.name());
     }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Mon Jan 13 10:42:55 2014 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Mon Jan 13 11:28:25 2014 +0100
@@ -36,6 +36,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.asm.*;
+import com.oracle.graal.compiler.alloc.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.graph.*;
@@ -192,14 +193,29 @@
      * 
      * @param op An instruction which defines a value
      * @param operand The destination operand of the instruction
+     * @param interval The interval for this defined value.
      * @return Returns the value which is moved to the instruction and which can be reused at all
      *         reload-locations in case the interval of this instruction is spilled. Currently this
      *         can only be a {@link Constant}.
      */
-    public Constant getMaterializedValue(LIRInstruction op, Value operand) {
+    public Constant getMaterializedValue(LIRInstruction op, Value operand, Interval interval) {
         if (op instanceof MoveOp) {
             MoveOp move = (MoveOp) op;
             if (move.getInput() instanceof Constant) {
+                /*
+                 * Check if the interval has any uses which would accept an stack location (priority
+                 * == ShouldHaveRegister). Rematerialization of such intervals can result in a
+                 * degradation, because rematerialization always inserts a constant load, even if
+                 * the value is not needed in a register.
+                 */
+                Interval.UsePosList usePosList = interval.usePosList();
+                int numUsePos = usePosList.size();
+                for (int useIdx = 0; useIdx < numUsePos; useIdx++) {
+                    Interval.RegisterPriority priority = usePosList.registerPriority(useIdx);
+                    if (priority == Interval.RegisterPriority.ShouldHaveRegister) {
+                        return null;
+                    }
+                }
                 return (Constant) move.getInput();
             }
         }