# HG changeset patch # User Thomas Wuerthinger # Date 1365528552 -7200 # Node ID 1fa6536416dbfed0d8dd3ecf7c8ed306f467ba7d # Parent e41c32a4d573eec905bd20d3c21a6499619b3d89 Runtime calls that do not destroy the caller's registers need no spilling at the call site. diff -r e41c32a4d573 -r 1fa6536416db graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RuntimeCallTarget.java --- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RuntimeCallTarget.java Tue Apr 09 19:28:34 2013 +0200 +++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RuntimeCallTarget.java Tue Apr 09 19:29:12 2013 +0200 @@ -114,4 +114,6 @@ long getMaxCallTargetOffset(); Descriptor getDescriptor(); + + boolean preservesRegisters(); } diff -r e41c32a4d573 -r 1fa6536416db graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java Tue Apr 09 19:28:34 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java Tue Apr 09 19:29:12 2013 +0200 @@ -90,4 +90,9 @@ address = stub.getAddress(backend); } } + + @Override + public boolean preservesRegisters() { + return stub == null; + } } diff -r e41c32a4d573 -r 1fa6536416db graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java Tue Apr 09 19:28:34 2013 +0200 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java Tue Apr 09 19:29:12 2013 +0200 @@ -36,7 +36,7 @@ public class AMD64Call { @Opcode("CALL_DIRECT") - public static class DirectCallOp extends AMD64LIRInstruction implements StandardOp.CallOp { + public static class DirectCallOp extends AMD64LIRInstruction { @Def({REG, ILLEGAL}) protected Value result; @Use({REG, STACK}) protected Value[] parameters; @@ -58,10 +58,15 @@ public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { directCall(tasm, masm, callTarget, null, true, state); } + + @Override + public boolean hasCall() { + return true; + } } @Opcode("CALL_NEAR_RUNTIME") - public static class DirectNearRuntimeCallOp extends AMD64LIRInstruction implements StandardOp.CallOp { + public static class DirectNearRuntimeCallOp extends AMD64LIRInstruction { @Def({REG, ILLEGAL}) protected Value result; @Use({REG, STACK}) protected Value[] parameters; @@ -83,10 +88,15 @@ public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { directCall(tasm, masm, callTarget, null, false, state); } + + @Override + public boolean hasCall() { + return !callTarget.preservesRegisters(); + } } @Opcode("CALL_FAR_RUNTIME") - public static class DirectFarRuntimeCallOp extends AMD64LIRInstruction implements StandardOp.CallOp { + public static class DirectFarRuntimeCallOp extends AMD64LIRInstruction { @Def({REG, ILLEGAL}) protected Value result; @Use({REG, STACK}) protected Value[] parameters; @@ -110,10 +120,15 @@ public void emitCode(TargetMethodAssembler tasm, AMD64MacroAssembler masm) { directCall(tasm, masm, callTarget, ((RegisterValue) callTemp).getRegister(), false, state); } + + @Override + public boolean hasCall() { + return !callTarget.preservesRegisters(); + } } @Opcode("CALL_INDIRECT") - public static class IndirectCallOp extends AMD64LIRInstruction implements StandardOp.CallOp { + public static class IndirectCallOp extends AMD64LIRInstruction { @Def({REG, ILLEGAL}) protected Value result; @Use({REG, STACK}) protected Value[] parameters; @@ -143,6 +158,11 @@ super.verify(); assert isRegister(targetAddress) : "The current register allocator cannot handle variables to be used at call sites, it must be in a fixed register for now"; } + + @Override + public boolean hasCall() { + return true; + } } public static void directCall(TargetMethodAssembler tasm, AMD64MacroAssembler masm, InvokeTarget callTarget, Register scratch, boolean align, LIRFrameState info) { diff -r e41c32a4d573 -r 1fa6536416db graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Tue Apr 09 19:28:34 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Tue Apr 09 19:29:12 2013 +0200 @@ -260,8 +260,8 @@ * Returns true when this instruction is a call instruction that destroys all caller-saved * registers. */ - public final boolean hasCall() { - return this instanceof StandardOp.CallOp; + public boolean hasCall() { + return false; } public final void forEachInput(ValueProcedure proc) { diff -r e41c32a4d573 -r 1fa6536416db 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 Tue Apr 09 19:28:34 2013 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java Tue Apr 09 19:29:12 2013 +0200 @@ -118,13 +118,6 @@ } /** - * Marker interface for a LIR operation that calls a method, i.e., destroys all caller-saved - * registers. - */ - public interface CallOp { - } - - /** * 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.