changeset 13212:eb03a7335eb0

Use fixed instead of virtual register for target in far foreign call, since the register allocator does not support virtual registers to be used at call sites.
author Christian Wimmer <christian.wimmer@oracle.com>
date Mon, 02 Dec 2013 14:20:32 -0800
parents d862cb983214
children d49e17387efc
files graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java
diffstat 3 files changed, 44 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java	Mon Dec 02 14:19:20 2013 -0800
+++ b/graal/com.oracle.graal.api.code/src/com/oracle/graal/api/code/ValueUtil.java	Mon Dec 02 14:20:32 2013 -0800
@@ -22,6 +22,8 @@
  */
 package com.oracle.graal.api.code;
 
+import java.util.*;
+
 import com.oracle.graal.api.meta.*;
 
 /**
@@ -127,11 +129,39 @@
         return sameRegister(v1, v2) && sameRegister(v1, v3);
     }
 
-    public static boolean differentRegisters(Value v1, Value v2) {
-        return !isRegister(v1) || !isRegister(v2) || !asRegister(v1).equals(asRegister(v2));
+    /**
+     * Checks if all the provided values are different physical registers. The parameters can be
+     * either {@link Register registers}, {@link Value values} or arrays of them. All values that
+     * are not {@link RegisterValue registers} are ignored.
+     */
+    public static boolean differentRegisters(Object... values) {
+        List<Register> registers = collectRegisters(values, new ArrayList<Register>());
+        for (int i = 1; i < registers.size(); i++) {
+            Register r1 = registers.get(i);
+            for (int j = 0; j < i; j++) {
+                Register r2 = registers.get(j);
+                if (r1.equals(r2)) {
+                    return false;
+                }
+            }
+        }
+        return true;
     }
 
-    public static boolean differentRegisters(Value v1, Value v2, Value v3) {
-        return differentRegisters(v1, v2) && differentRegisters(v1, v3) && differentRegisters(v2, v3);
+    private static List<Register> collectRegisters(Object[] values, List<Register> registers) {
+        for (Object o : values) {
+            if (o instanceof Register) {
+                registers.add((Register) o);
+            } else if (o instanceof Value) {
+                if (isRegister((Value) o)) {
+                    registers.add(asRegister((Value) o));
+                }
+            } else if (o instanceof Object[]) {
+                collectRegisters((Object[]) o, registers);
+            } else {
+                throw new IllegalArgumentException("Not a Register or Value: " + o);
+            }
+        }
+        return registers;
     }
 }
--- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Mon Dec 02 14:19:20 2013 -0800
+++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64LIRGenerator.java	Mon Dec 02 14:20:32 2013 -0800
@@ -885,7 +885,7 @@
     protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) {
         long maxOffset = linkage.getMaxCallTargetOffset();
         if (maxOffset != (int) maxOffset) {
-            append(new AMD64Call.DirectFarForeignCallOp(this, linkage, result, arguments, temps, info));
+            append(new AMD64Call.DirectFarForeignCallOp(linkage, result, arguments, temps, info));
         } else {
             append(new AMD64Call.DirectNearForeignCallOp(linkage, result, arguments, temps, info));
         }
--- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Mon Dec 02 14:19:20 2013 -0800
+++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/AMD64Call.java	Mon Dec 02 14:20:32 2013 -0800
@@ -25,13 +25,13 @@
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRInstruction.OperandFlag.*;
 
+import com.oracle.graal.amd64.*;
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
+import com.oracle.graal.asm.amd64.AMD64Assembler.ConditionFlag;
 import com.oracle.graal.asm.amd64.*;
-import com.oracle.graal.asm.amd64.AMD64Assembler.*;
 import com.oracle.graal.lir.*;
 import com.oracle.graal.lir.asm.*;
-import com.oracle.graal.nodes.spi.*;
 
 public class AMD64Call {
 
@@ -135,9 +135,14 @@
 
         @Temp({REG}) protected AllocatableValue callTemp;
 
-        public DirectFarForeignCallOp(LIRGeneratorTool gen, ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) {
+        public DirectFarForeignCallOp(ForeignCallLinkage callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState state) {
             super(callTarget, result, parameters, temps, state);
-            callTemp = gen.newVariable(Kind.Long);
+            /*
+             * The register allocator does not support virtual registers that are used at the call
+             * site, so use a fixed register.
+             */
+            callTemp = AMD64.rax.asValue(Kind.Long);
+            assert ValueUtil.differentRegisters(parameters, callTemp);
         }
 
         @Override