# HG changeset patch # User Christian Wimmer # Date 1378424173 25200 # Node ID 7ce08e264abfd1d6dfc8a1794a178f9e0a8873b7 # Parent 9021f7761457b77eff99868dec9162628a2684f9 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. diff -r 9021f7761457 -r 7ce08e264abf graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- 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 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(); diff -r 9021f7761457 -r 7ce08e264abf graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- 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 diff -r 9021f7761457 -r 7ce08e264abf graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotBackend.java --- 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); diff -r 9021f7761457 -r 7ce08e264abf graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- 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); diff -r 9021f7761457 -r 7ce08e264abf graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java --- 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 {