changeset 11537:7ce08e264abf

Fixed registers that flow into a block need to be inputs of the LabelOp, otherwise the register allocator can insert spill moves before the definition of a fixed register.
author Christian Wimmer <christian.wimmer@oracle.com>
date Thu, 05 Sep 2013 16:36:13 -0700
parents 9021f7761457
children 6317ef27930d
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 graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java
diffstat 5 files changed, 25 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Thu Sep 05 16:34:37 2013 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Thu Sep 05 16:36:13 2013 -0700
@@ -686,9 +686,8 @@
             List<LIRInstruction> instructions = ir.lir(block);
             int numInst = instructions.size();
 
-            // iterate all instructions of the block. skip the first because it is always a label
-            assert !instructions.get(0).hasOperands() : "first operation must always be a label";
-            for (int j = 1; j < numInst; j++) {
+            // iterate all instructions of the block
+            for (int j = 0; j < numInst; j++) {
                 final LIRInstruction op = instructions.get(j);
 
                 ValueProcedure useProc = new ValueProcedure() {
@@ -1174,10 +1173,8 @@
             }
 
             // iterate all instructions of the block in reverse order.
-            // skip the first instruction because it is always a label
             // definitions of intervals are processed before uses
-            assert !instructions.get(0).hasOperands() : "first operation must always be a label";
-            for (int j = instructions.size() - 1; j >= 1; j--) {
+            for (int j = instructions.size() - 1; j >= 0; j--) {
                 final LIRInstruction op = instructions.get(j);
                 final int opId = op.id();
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Thu Sep 05 16:34:37 2013 -0700
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Thu Sep 05 16:36:13 2013 -0700
@@ -40,7 +40,6 @@
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.StandardOp.JumpOp;
 import com.oracle.graal.lir.StandardOp.LabelOp;
-import com.oracle.graal.lir.StandardOp.ParametersOp;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.PhiNode.PhiType;
 import com.oracle.graal.nodes.calc.*;
@@ -405,7 +404,7 @@
     }
 
     public void emitIncomingValues(Value[] params) {
-        append(new ParametersOp(params));
+        ((LabelOp) lir.lir(currentBlock).get(0)).setIncomingValues(params);
     }
 
     @Override
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Thu Sep 05 16:34:37 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java	Thu Sep 05 16:36:13 2013 -0700
@@ -45,7 +45,7 @@
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.LIRInstruction.ValueProcedure;
-import com.oracle.graal.lir.StandardOp.ParametersOp;
+import com.oracle.graal.lir.StandardOp.LabelOp;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.asm.*;
 import com.oracle.graal.nodes.*;
@@ -214,7 +214,7 @@
         };
         for (Block block : lir.codeEmittingOrder()) {
             for (LIRInstruction op : lir.lir(block)) {
-                if (op instanceof ParametersOp) {
+                if (op instanceof LabelOp) {
                     // Don't consider this as a definition
                 } else {
                     op.forEachTemp(defProc);
--- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Thu Sep 05 16:34:37 2013 -0700
+++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java	Thu Sep 05 16:36:13 2013 -0700
@@ -46,7 +46,6 @@
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.hotspot.stubs.*;
 import com.oracle.graal.lir.*;
-import com.oracle.graal.lir.StandardOp.ParametersOp;
 import com.oracle.graal.lir.StandardOp.PlaceholderOp;
 import com.oracle.graal.lir.amd64.*;
 import com.oracle.graal.lir.amd64.AMD64ControlFlow.CondMoveOp;
@@ -162,9 +161,8 @@
             }
         }
         params[params.length - 1] = rbpParam;
-        ParametersOp paramsOp = new ParametersOp(params);
 
-        append(paramsOp);
+        emitIncomingValues(params);
 
         saveRbp = new SaveRbp(new PlaceholderOp(currentBlock, lir.lir(currentBlock).size()));
         append(saveRbp.placeholder);
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Thu Sep 05 16:34:37 2013 -0700
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java	Thu Sep 05 16:36:13 2013 -0700
@@ -54,12 +54,30 @@
      */
     public static class LabelOp extends LIRInstruction {
 
+        private static final Value[] NO_VALUES = new Value[0];
+
+        /**
+         * In the LIR, every register and variable must be defined before it is used. For method
+         * parameters that are passed in fixed registers, exception objects passed to the exception
+         * handler in a fixed register, or any other use of a fixed register not defined in this
+         * method, an artificial definition is necessary. To avoid spill moves to be inserted
+         * between the label at the beginning of a block an an actual definition in the second
+         * instruction of a block, the registers are defined here in the label.
+         */
+        @Def({REG, STACK}) private Value[] incomingValues;
+
         private final Label label;
         private final boolean align;
 
         public LabelOp(Label label, boolean align) {
             this.label = label;
             this.align = align;
+            this.incomingValues = NO_VALUES;
+        }
+
+        public void setIncomingValues(Value[] values) {
+            assert incomingValues.length == 0;
+            incomingValues = values;
         }
 
         @Override
@@ -121,25 +139,6 @@
     }
 
     /**
-     * Meta-operation that defines the incoming method parameters. In the LIR, every register and
-     * variable must be defined before it is used. This operation is the definition point of method
-     * parameters, but is otherwise a no-op. In particular, it is not the actual method prologue.
-     */
-    public static final class ParametersOp extends LIRInstruction {
-
-        @Def({REG, STACK}) protected Value[] params;
-
-        public ParametersOp(Value[] params) {
-            this.params = params;
-        }
-
-        @Override
-        public void emitCode(TargetMethodAssembler tasm) {
-            // No code to emit.
-        }
-    }
-
-    /**
      * Placeholder for a LIR instruction that will be subsequently replaced.
      */
     public static class PlaceholderOp extends LIRInstruction {