changeset 8969:1fa6536416db

Runtime calls that do not destroy the caller's registers need no spilling at the call site.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Tue, 09 Apr 2013 19:29:12 +0200
parents e41c32a4d573
children 50c63b0d858e
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/RuntimeCallTarget.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotRuntimeCallTarget.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/StandardOp.java
diffstat 5 files changed, 33 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- 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();
 }
--- 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;
+    }
 }
--- 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) {
--- 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) {
--- 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.