changeset 13377:40530019af02

enable rematerialization of constants in LinearScan, including a bug fix
author Erik Eckstein <erik.eckstein@oracle.com>
date Wed, 18 Dec 2013 09:02:01 +0100
parents 24ae4e7ecf03
children 16d99e9d77ad e3ec81d3e976 f45452c87b52
files 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 2 files changed, 38 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Wed Dec 18 08:57:34 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Wed Dec 18 09:02:01 2013 +0100
@@ -1655,11 +1655,25 @@
         }
 
         if (isIllegal(interval.location()) && interval.canMaterialize()) {
+            assert mode != OperandMode.DEF;
             return interval.getMaterializedValue();
         }
         return interval.location();
     }
 
+    private boolean isMaterialized(AllocatableValue operand, int opId, OperandMode mode) {
+        Interval interval = intervalFor(operand);
+        assert interval != null : "interval must exist";
+
+        if (opId != -1) {
+            // operands are not changed when an interval is split during allocation,
+            // so search the right interval here
+            interval = splitChildAtOpId(interval, opId, mode);
+        }
+
+        return isIllegal(interval.location()) && interval.canMaterialize();
+    }
+
     protected IntervalWalker initIntervalWalker(IntervalPredicate predicate) {
         // setup lists of potential oops for walking
         Interval oopIntervals;
@@ -1776,6 +1790,23 @@
                 continue;
             }
 
+            // remove useless moves
+            MoveOp move = null;
+            if (op instanceof MoveOp) {
+                move = (MoveOp) op;
+                AllocatableValue result = move.getResult();
+                if (isVariable(result) && isMaterialized(result, op.id(), OperandMode.DEF)) {
+                    /*
+                     * This happens if a materializable interval is originally not spilled but then
+                     * kicked out in LinearScanWalker.splitForSpilling(). When kicking out such an
+                     * interval this move operation was already generated.
+                     */
+                    instructions.set(j, null);
+                    hasDead = true;
+                    continue;
+                }
+            }
+
             ValueProcedure assignProc = new ValueProcedure() {
 
                 @Override
@@ -1802,8 +1833,7 @@
             });
 
             // remove useless moves
-            if (op instanceof MoveOp) {
-                MoveOp move = (MoveOp) op;
+            if (move != null) {
                 if (move.getInput().equals(move.getResult())) {
                     instructions.set(j, null);
                     hasDead = true;
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Dec 18 08:57:34 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Wed Dec 18 09:02:01 2013 +0100
@@ -197,6 +197,12 @@
      *         can only be a {@link Constant}.
      */
     public Constant getMaterializedValue(LIRInstruction op, Value operand) {
+        if (op instanceof MoveOp) {
+            MoveOp move = (MoveOp) op;
+            if (move.getInput() instanceof Constant) {
+                return (Constant) move.getInput();
+            }
+        }
         return null;
     }