Mercurial > hg > graal-jvmci-8
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