# HG changeset patch # User Doug Simon # Date 1373905345 -7200 # Node ID 395d34c10e26faff92adcacd13a868b86806c2a7 # Parent 058abc2b59a5fa02000b5aa3923a1575d19bce6b HSAIL backend changes Contributed-by: Tom Deneau * stackslot mapping was incorrect when combinations of 32-bit and 64-bit stores were generated. StackSlot alignment in HSAILTargetDescription set to 8. * compressedOops support in various heap size configurations (with or without either of shift or heap base). So we don't need XX:-UseCompressedOops anymore. * some support for unsigned shifts, long shifts, logical ops for long datatype. * a new GraalOption, InlineEverything. Some HSAIL targets are not able to handle HSAIL function calls yet, plus we are still working on emitting HSAIL function calls in the compiler. * hack for emitForeignCall special cases of createOutOfBoundsException or createNullPointerException. (We just emit a comment. Real exception handling still pending). These nodes came about when we more aggressively inlined, although this has not been explained yet. * support HSAILAddressValues as operands for arithmetic ops. Use HSAIL lda instruction to get address into a register. Used in particular for USHR for card-marking. * Added some new junit tests. (some ported from their lambda versions) * StaticNBodyCallTest which would fail with default inlining (since we don't yet generate HSAIL calls). It uses junit.assumeTrue and tests whether InlineEverything is set. It (and also some lambda-based junit tests not part of this webrev) do pass nicely when InlineEverything is set true. * tests for storing an object, which test being able to handle the card-marking logic, as well as the encoding and decoding of a compressed oop. * some 2D matrix tests that showed a problem before the stackslot change above. (have a mixture of 32-bit and 64-bit stackslot spills) diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java --- a/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java Mon Jul 15 17:54:00 2013 +0200 +++ b/graal/com.oracle.graal.asm.hsail/src/com/oracle/graal/asm/hsail/HSAILAssembler.java Mon Jul 15 18:22:25 2013 +0200 @@ -79,13 +79,15 @@ * created by JNI since these JNI global references do not move. */ public final void mov(Register a, Object obj) { + String regName = "$d" + a.encoding(); if (obj instanceof Class) { Class clazz = (Class) obj; long refHandle = OkraUtil.getRefHandle(clazz); String className = clazz.getName(); - String regName = "$d" + a.encoding(); emitString("mov_b64 " + regName + ", 0x" + Long.toHexString(refHandle) + "; // handle for " + className); emitString("ld_global_u64 " + regName + ", [" + regName + "];"); + } else if (obj == null) { + emitString("mov_b64 " + regName + ", 0x0; // null object"); } else { throw GraalInternalError.shouldNotReachHere("mov from object not a class"); } @@ -101,16 +103,32 @@ } } + private void emitAddrOp(String instr, Value reg, HSAILAddress addr) { + emitString(instr + " " + HSAIL.mapRegister(reg) + ", " + mapAddress(addr) + ";"); + } + public final void emitLoad(Value dest, HSAILAddress addr) { - emitString("ld_global_" + getArgType(dest) + " " + HSAIL.mapRegister(dest) + ", " + mapAddress(addr) + ";"); + emitLoad(dest, addr, getArgType(dest)); + } + + public final void emitLoad(Value dest, HSAILAddress addr, String argTypeStr) { + emitAddrOp("ld_global_" + argTypeStr, dest, addr); + } + + public final void emitLda(Value dest, HSAILAddress addr) { + emitAddrOp("lda_global_u64", dest, addr); + } + + public final void emitStore(Value src, HSAILAddress addr) { + emitStore(src, addr, getArgType(src)); + } + + public final void emitStore(Value dest, HSAILAddress addr, String argTypeStr) { + emitAddrOp("st_global_" + argTypeStr, dest, addr); } public final void emitSpillLoad(Value dest, Value src) { - emitString("ld_spill_" + getArgType(dest) + " " + HSAIL.mapRegister(dest) + ", " + HSAIL.mapStackSlot(src) + ";"); - } - - public final void emitStore(Value src, HSAILAddress addr) { - emitString("st_global_" + getArgType(src) + " " + HSAIL.mapRegister(src) + ", " + mapAddress(addr) + ";"); + emitString("ld_spill_" + getArgType(dest) + " " + HSAIL.mapRegister(dest) + ", " + mapStackSlot(src, getArgSize(dest)) + ";"); } public final void emitSpillStore(Value src, Value dest) { @@ -122,7 +140,21 @@ if (maxStackOffset < stackoffset) { maxStackOffset = stackoffset; } - emitString("st_spill_" + getArgType(src) + " " + HSAIL.mapRegister(src) + ", " + HSAIL.mapStackSlot(dest) + ";"); + emitString("st_spill_" + getArgType(src) + " " + HSAIL.mapRegister(src) + ", " + mapStackSlot(dest, getArgSize(src)) + ";"); + } + + /** + * The mapping to stack slots is always relative to the beginning + * of the spillseg. HSAIL.getStackOffset returns the positive + * version of the originally negative offset. Then we back up + * from that by the argSize in bytes. This ensures that slots of + * different size do not overlap, even though we have converted + * from negative to positive offsets. + */ + public static String mapStackSlot(Value reg, int argSize) { + long offset = HSAIL.getStackOffset(reg); + int argSizeBytes = argSize / 8; + return "[%spillseg]" + "[" + (offset - argSizeBytes) + "]"; } public void cbr(String target1) { @@ -181,7 +213,9 @@ public void emitCompare(Value src0, Value src1, String condition, boolean unordered, boolean isUnsignedCompare) { String prefix = "cmp_" + condition + (unordered ? "u" : "") + "_b1_" + (isUnsignedCompare ? getArgTypeForceUnsigned(src1) : getArgType(src1)); - emitString(prefix + " $c0, " + mapRegOrConstToString(src0) + ", " + mapRegOrConstToString(src1) + ";"); + String comment = (isConstant(src1) && (src1.getKind() == Kind.Object) + && (asConstant(src1).asObject() == null) ? " // null test " : ""); + emitString(prefix + " $c0, " + mapRegOrConstToString(src0) + ", " + mapRegOrConstToString(src1) + ";" + comment); } public void emitConvert(Value dest, Value src) { @@ -210,7 +244,14 @@ case Double: return Double.toString(consrc.asDouble()); case Long: - return Long.toString(consrc.asLong()); + return "0x" + Long.toHexString(consrc.asLong()); + case Object: + Object obj = consrc.asObject(); + if (obj == null) { + return "0"; + } else { + throw GraalInternalError.shouldNotReachHere("unknown type: " + src); + } default: throw GraalInternalError.shouldNotReachHere("unknown type: " + src); } @@ -223,14 +264,68 @@ emit(mnemonic + "_" + prefix, dest, "", src0, src1); } + public final void emitForceUnsigned(String mnemonic, Value dest, Value src0, Value src1) { + String prefix = getArgTypeForceUnsigned(dest); + emit(mnemonic + "_" + prefix, dest, "", src0, src1); + } + + private void emit(String instr, Value dest, String controlRegString, Value src0, Value src1) { assert (!isConstant(dest)); emitString(String.format("%s %s, %s%s, %s;", instr, HSAIL.mapRegister(dest), controlRegString, mapRegOrConstToString(src0), mapRegOrConstToString(src1))); } + private void emit(String instr, Value dest, Value src0, Value src1, Value src2) { + assert (!isConstant(dest)); + emitString(String.format("%s %s, %s, %s, %s;", instr, HSAIL.mapRegister(dest), mapRegOrConstToString(src0), + mapRegOrConstToString(src1), mapRegOrConstToString(src2))); + } + + public final void cmovCommon(Value dest, Value trueReg, Value falseReg, int width) { String instr = (width == 32 ? "cmov_b32" : "cmov_b64"); emit(instr, dest, "$c0, ", trueReg, falseReg); } + + /** + * Emit code to build a 64-bit pointer from a compressed-oop and the associated base and shift. + * We only emit this if base and shift are not both zero. + */ + public void emitCompressedOopDecode(Value result, long narrowOopBase, int narrowOopShift) { + if (narrowOopBase == 0) { + emit("shl", result, result, Constant.forInt(narrowOopShift)); + } else if (narrowOopShift == 0) { + // only use add if result is not starting as null (unsigned compare) + emitCompare(result, Constant.forLong(0), "eq", false, true); + emit("add", result, result, Constant.forLong(narrowOopBase)); + cmovCommon(result, Constant.forLong(0), result, 64); + } else { + // only use mad if result is not starting as null (unsigned compare) + emitCompare(result, Constant.forLong(0), "eq", false, true); + emit("mad_u64 ", result, result, Constant.forInt(1 << narrowOopShift), Constant.forLong(narrowOopBase)); + cmovCommon(result, Constant.forLong(0), result, 64); + } + } + + /** + * Emit code to build a 32-bit compressed pointer from a full + * 64-bit pointer using the associated base and shift. We only + * emit this if base and shift are not both zero. + */ + public void emitCompressedOopEncode(Value result, long narrowOopBase, int narrowOopShift) { + if (narrowOopBase != 0) { + // only use sub if result is not starting as null (unsigned compare) + emitCompare(result, Constant.forLong(0), "eq", false, true); + emit("sub", result, result, Constant.forLong(narrowOopBase)); + cmovCommon(result, Constant.forLong(0), result, 64); + } + if (narrowOopShift != 0) { + emit("shr", result, result, Constant.forInt(narrowOopShift)); + } + } + + public void emitComment(String comment) { + emitString(comment); + } } diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java --- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java Mon Jul 15 17:54:00 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java Mon Jul 15 18:22:25 2013 +0200 @@ -30,6 +30,7 @@ import com.oracle.graal.compiler.hsail.HSAILCompilationResult; import java.lang.reflect.Method; import java.io.*; +import static com.oracle.graal.phases.GraalOptions.*; public abstract class GraalKernelTester extends KernelTester { @@ -61,4 +62,15 @@ return hsailSource; } + public boolean aggressiveInliningEnabled() { + return (InlineEverything.getValue()); + } + + public boolean canHandleHSAILMethodCalls() { + // needs 2 things, backend needs to be able to generate such calls, and target needs to be + // able to run them + boolean canGenerateCalls = false; // not implemented yet + boolean canExecuteCalls = runningOnSimulator(); + return (canGenerateCalls && canExecuteCalls); + } } diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java --- a/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java Mon Jul 15 17:54:00 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/KernelTester.java Mon Jul 15 18:22:25 2013 +0200 @@ -150,6 +150,12 @@ } private boolean compareObjects(Object first, Object second) { + if (first == null) { + return (second == null); + } + if (second == null) { + return (first == null); + } Class clazz = first.getClass(); if (clazz != second.getClass()) { return false; @@ -265,6 +271,11 @@ Object getElement(Object ary, int index) { return Array.get(ary, index); } + + @Override + boolean isEquals(Object firstElement, Object secondElement) { + return compareObjects(firstElement, secondElement); + } } /** @@ -496,7 +507,7 @@ String hsailSource = getHSAILSource(testMethod); if (!okraLibExists) { if (!gaveNoOkraWarning) { - logger.fine("No Okra library detected, skipping all KernelTester tests in " + this.getClass().getPackage().getName()); + logger.severe("No Okra library detected, skipping all KernelTester tests in " + this.getClass().getPackage().getName()); gaveNoOkraWarning = true; } } diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Float2DMatrixBase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Float2DMatrixBase.java Mon Jul 15 18:22:25 2013 +0200 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.graal.compiler.hsail.test; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; + +/** + * Base class used by other Float2DMatrix tests. + */ +public abstract class Float2DMatrixBase extends GraalKernelTester { + + float[][] matrixA; + float[][] matrixB; + @Result float[][] outMatrix; + + public void setupArrays(int range) { + matrixA = new float[range][]; + matrixB = new float[range][]; + outMatrix = new float[range][]; + for (int j = 0; j < range; j++) { + matrixA[j] = new float[range]; + matrixB[j] = new float[range]; + outMatrix[j] = new float[range]; + for (int k = 0; k < range; k++) { + matrixA[j][k] = (j + k) % 7; + matrixB[j][k] = (j + k + 1) % 8; + } + } + } +} diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Float2DMatrixMultiplyRangeFinalTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Float2DMatrixMultiplyRangeFinalTest.java Mon Jul 15 18:22:25 2013 +0200 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.graal.compiler.hsail.test; + +import org.junit.*; + +/** + * Tests the mixing of 32-bit and 64-bit spills caused by loop unrolling. + */ +public class Float2DMatrixMultiplyRangeFinalTest extends Float2DMatrixBase { + + static final int range = 6; + + public void run(int gid) { + for (int j = 0; j < range; j++) { + float sum = 0; + for (int k = 0; k < range; k++) { + sum += (matrixA[gid][k] * matrixB[k][j]); + } + outMatrix[gid][j] = sum; + } + } + + @Override + public void runTest() { + setupArrays(range); + dispatchMethodKernel(range); + } + + @Test + public void test() { + testGeneratedHsail(); + } +} diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Float2DMatrixMultiplyTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/Float2DMatrixMultiplyTest.java Mon Jul 15 18:22:25 2013 +0200 @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.graal.compiler.hsail.test; + +import org.junit.Test; + +/** + * Tests 2D array access for Matrix Multiplication. + */ +public class Float2DMatrixMultiplyTest extends Float2DMatrixBase { + int range = 20; + + public void run(int gid) { + for (int j = 0; j < range; j++) { + float sum = 0; + for (int k = 0; k < range; k++) { + sum += (matrixA[gid][k] * matrixB[k][j]); + } + outMatrix[gid][j] = sum; + } + } + @Override + public void runTest() { + setupArrays(range); + dispatchMethodKernel(range); + } + + @Test + public void test() { + testGeneratedHsail(); + } +} diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/ObjectStoreNullTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/ObjectStoreNullTest.java Mon Jul 15 18:22:25 2013 +0200 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.graal.compiler.hsail.test; + +import org.junit.*; + +/** + * Tests the storing of null in an Object array. + */ +public class ObjectStoreNullTest extends ObjectStoreTest { + + @Override + public void run(int gid) { + outIntegerArray[gid] = (gid % 3 == 1 ? null : inIntegerArray[gid]); + } + + @Test + @Override + public void test() { + testGeneratedHsail(); + } + +} diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/ObjectStoreTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/ObjectStoreTest.java Mon Jul 15 18:22:25 2013 +0200 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.graal.compiler.hsail.test; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; +import org.junit.Test; + +/** + * Tests the storing of objects into an array. + */ +public class ObjectStoreTest extends GraalKernelTester { + + static final int NUM = 20; + + @Result public Integer[] outIntegerArray = new Integer[NUM]; + public Integer[] inIntegerArray = new Integer[NUM]; + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + inIntegerArray[i] = new Integer(i); + outIntegerArray[i] = null; + } + } + + public void run(int gid) { + outIntegerArray[gid] = inIntegerArray[gid]; + } + + @Override + public void runTest() { + setupArrays(); + + dispatchMethodKernel(NUM); + } + + @Test + public void test() { + testGeneratedHsail(); + } + +} diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMandelTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMandelTest.java Mon Jul 15 17:54:00 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticMandelTest.java Mon Jul 15 18:22:25 2013 +0200 @@ -25,6 +25,7 @@ import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; import org.junit.Test; +import static org.junit.Assume.*; /** * Unit test that simulates the Mandelbrot application. The run method here is a static method @@ -79,6 +80,7 @@ @Test public void test() { + assumeTrue(runningOnSimulator()); testGeneratedHsail(); } } diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyCallTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/StaticNBodyCallTest.java Mon Jul 15 18:22:25 2013 +0200 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.oracle.graal.compiler.hsail.test; + +import static org.junit.Assume.*; + +import org.junit.*; + +/** + * Unit test of NBody demo app. This version uses a call to the main routine which would normally be + * too large to inline. + */ +public class StaticNBodyCallTest extends StaticNBodyTest { + + public static void run(float[] inxyz, float[] outxyz, float[] invxyz, float[] outvxyz, int gid) { + StaticNBodyTest.run(inxyz, outxyz, invxyz, outvxyz, gid); + } + + @Test + @Override + public void test() { + assumeTrue(aggressiveInliningEnabled() || canHandleHSAILMethodCalls()); + testGeneratedHsail(); + } +} diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java Mon Jul 15 17:54:00 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILCompilationResult.java Mon Jul 15 18:22:25 2013 +0200 @@ -98,7 +98,7 @@ public static HSAILCompilationResult getHSAILCompilationResult(StructuredGraph graph) { Debug.dump(graph, "Graph"); - TargetDescription target = new TargetDescription(new HSAIL(), true, 1, 0, true); + TargetDescription target = new TargetDescription(new HSAIL(), true, 8, 0, true); HSAILBackend hsailBackend = new HSAILBackend(Graal.getRequiredCapability(GraalCodeCacheProvider.class), target); PhasePlan phasePlan = new PhasePlan(); GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.NONE); diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java --- a/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Mon Jul 15 17:54:00 2013 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Mon Jul 15 18:22:25 2013 +0200 @@ -47,20 +47,29 @@ import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCompareBranchOp; import com.oracle.graal.lir.hsail.HSAILControlFlow.FloatCondMoveOp; import com.oracle.graal.lir.hsail.HSAILControlFlow.ReturnOp; +import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCallNoArgOp; +import com.oracle.graal.lir.hsail.HSAILControlFlow.ForeignCall1ArgOp; import com.oracle.graal.lir.hsail.HSAILMove.LeaOp; import com.oracle.graal.lir.hsail.HSAILMove.LoadOp; import com.oracle.graal.lir.hsail.HSAILMove.MoveFromRegOp; import com.oracle.graal.lir.hsail.HSAILMove.MoveToRegOp; import com.oracle.graal.lir.hsail.HSAILMove.StoreOp; +import com.oracle.graal.lir.hsail.HSAILMove.LoadCompressedPointer; +import com.oracle.graal.lir.hsail.HSAILMove.StoreCompressedPointer; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.hotspot.meta.*; /** * This class implements the HSAIL specific portion of the LIR generator. */ public class HSAILLIRGenerator extends LIRGenerator { + private HotSpotRuntime runtime() { + return (HotSpotRuntime) runtime; + } + public static class HSAILSpillMoveFactory implements LIR.SpillMoveFactory { @Override @@ -123,6 +132,14 @@ } } + protected HSAILAddressValue asAddressValue(Value address) { + if (address instanceof HSAILAddressValue) { + return (HSAILAddressValue) address; + } else { + return emitAddress(address, 0, Value.ILLEGAL, 0); + } + } + public HSAILAddressValue emitAddress(Value base, long displacement, Value index, int scale) { AllocatableValue baseRegister; long finalDisp = displacement; @@ -163,27 +180,36 @@ return new HSAILAddressValue(target().wordKind, baseRegister, finalDisp); } - private HSAILAddressValue asAddress(Value address) { - if (address instanceof HSAILAddressValue) { - return (HSAILAddressValue) address; - } else { - return emitAddress(address, 0, Value.ILLEGAL, 0); - } + private static boolean isCompressCandidate(DeoptimizingNode access) { + return access != null && ((HeapAccess) access).compress(); } @Override - public Variable emitLoad(Kind kind, Value address, DeoptimizingNode deopting) { - HSAILAddressValue loadAddress = asAddress(address); + public Variable emitLoad(Kind kind, Value address, DeoptimizingNode access) { + HSAILAddressValue loadAddress = asAddressValue(address); Variable result = newVariable(kind); - append(new LoadOp(kind, result, loadAddress, deopting != null ? state(deopting) : null)); + LIRFrameState state = access != null ? state(access) : null; + assert access == null || access instanceof HeapAccess; + if (runtime().config.useCompressedOops && isCompressCandidate(access)) { + Variable scratch = newVariable(Kind.Long); + append(new LoadCompressedPointer(kind, result, scratch, loadAddress, state, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment)); + } else { + append(new LoadOp(kind, result, loadAddress, state)); + } return result; } @Override - public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode deopting) { - HSAILAddressValue storeAddress = asAddress(address); + public void emitStore(Kind kind, Value address, Value inputVal, DeoptimizingNode access) { + HSAILAddressValue storeAddress = asAddressValue(address); + LIRFrameState state = access != null ? state(access) : null; Variable input = load(inputVal); - append(new StoreOp(kind, storeAddress, input, deopting != null ? state(deopting) : null)); + if (runtime().config.useCompressedOops && isCompressCandidate(access)) { + Variable scratch = newVariable(Kind.Long); + append(new StoreCompressedPointer(kind, storeAddress, input, scratch, state, runtime().config.narrowOopBase, runtime().config.narrowOopShift, runtime().config.logMinObjAlignment)); + } else { + append(new StoreOp(kind, storeAddress, input, state)); + } } @Override @@ -460,6 +486,9 @@ case Int: append(new Op2Stack(IAND, result, a, loadNonConst(b))); break; + case Long: + append(new Op2Stack(LAND, result, a, loadNonConst(b))); + break; default: throw GraalInternalError.shouldNotReachHere(); } @@ -483,6 +512,9 @@ case Int: append(new ShiftOp(ISHL, result, a, b)); break; + case Long: + append(new ShiftOp(LSHL, result, a, b)); + break; default: GraalInternalError.shouldNotReachHere(); } @@ -501,6 +533,9 @@ case Int: append(new ShiftOp(IUSHR, result, a, b)); break; + case Long: + append(new ShiftOp(LUSHR, result, a, b)); + break; default: GraalInternalError.shouldNotReachHere(); } @@ -561,7 +596,23 @@ @Override protected void emitForeignCall(ForeignCallLinkage linkage, Value result, Value[] arguments, Value[] temps, LIRFrameState info) { - throw new InternalError("NYI emitForeignCall"); + String callName = linkage.getDescriptor().getName(); + if (callName.equals("createOutOfBoundsException") || callName.equals("createNullPointerException")) { + // hack Alert !! + switch (arguments.length) { + case 0: + append(new ForeignCallNoArgOp(callName, result)); + break; + case 1: + append(new ForeignCall1ArgOp(callName, result, arguments[0])); + break; + default: + throw new InternalError("NYI emitForeignCall"); + } + + } else { + throw new InternalError("NYI emitForeignCall"); + } } @Override diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java Mon Jul 15 17:54:00 2013 +0200 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILArithmetic.java Mon Jul 15 18:22:25 2013 +0200 @@ -44,10 +44,11 @@ IMIN, LMIN, IUMIN, LUMIN, IREM, LREM, FREM, DREM, IUREM, LUREM, ICARRY, LCARRY, IUCARRY, LUCARRY, - IAND, INEG, IUSHR, I2B, I2S, I2L, + IAND, LAND, INEG, I2B, I2S, I2L, F2D, F2I, F2L, D2F, I2F, I2D, D2I, L2F, D2L, MOV_F2I, MOV_D2L, L2D, MOV_I2F, - MOV_L2D, ISHL, SQRT, UNDEF, CALL, L2I; + MOV_L2D, ISHL, LSHL, ISHR, LSHR, IUSHR, LUSHR, + SQRT, UNDEF, CALL, L2I; public static class Op1Stack extends HSAILLIRInstruction { @Opcode private final HSAILArithmetic opcode; @@ -245,6 +246,22 @@ } public static void emit(TargetMethodAssembler tasm, HSAILAssembler masm, HSAILArithmetic opcode, Value dst, Value src1, Value src2, LIRFrameState info) { + /** + * First check if one of src1 or src2 is an AddressValue. If it is, + * convert the address to a register using an lda instruction. We can + * just reuse the eventual dst register for this. + */ + if (src1 instanceof HSAILAddressValue) { + assert (!(src2 instanceof HSAILAddressValue)); + masm.emitLda(dst, ((HSAILAddressValue) src1).toAddress()); + emit(tasm, masm, opcode, dst, dst, src2, info); + return; + } else if (src2 instanceof HSAILAddressValue) { + assert (!(src1 instanceof HSAILAddressValue)); + masm.emitLda(dst, ((HSAILAddressValue) src2).toAddress()); + emit(tasm, masm, opcode, dst, src1, dst, info); + return; + } int exceptionOffset = -1; switch (opcode) { case IADD: @@ -276,7 +293,14 @@ case LMIN: masm.emit("min", dst, src1, src2); break; case ISHL: + case LSHL: masm.emit("shl", dst, src1, src2); break; + case ISHR: + case LSHR: + masm.emit("shr", dst, src1, src2); break; + case IUSHR: + case LUSHR: + masm.emitForceUnsigned("shr", dst, src1, src2); break; case IREM: masm.emit("rem", dst, src1, src2); break; default: throw GraalInternalError.shouldNotReachHere(); diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java Mon Jul 15 17:54:00 2013 +0200 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java Mon Jul 15 18:22:25 2013 +0200 @@ -53,6 +53,34 @@ } } + + public static class ForeignCallNoArgOp extends HSAILLIRInstruction { + + @Def({REG}) protected Value out; + String callName; + + public ForeignCallNoArgOp(String callName, Value out) { + this.out = out; + this.callName = callName; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) { + masm.emitComment("//ForeignCall to " + callName + " would have gone here"); + } + } + + public static class ForeignCall1ArgOp extends ForeignCallNoArgOp { + + @Use({REG, ILLEGAL}) protected Value arg1; + + public ForeignCall1ArgOp(String callName, Value out, Value arg1) { + super(callName, out); + this.arg1 = arg1; + } + } + + public static class CompareBranchOp extends HSAILLIRInstruction implements StandardOp.BranchOp { @Opcode protected final HSAILCompare opcode; diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java --- a/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java Mon Jul 15 17:54:00 2013 +0200 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILMove.java Mon Jul 15 18:22:25 2013 +0200 @@ -129,49 +129,147 @@ } } - public static class LoadOp extends HSAILLIRInstruction { - @SuppressWarnings("unused") private final Kind kind; - @Def({REG}) protected AllocatableValue result; + public abstract static class MemOp extends HSAILLIRInstruction { + + protected final Kind kind; @Use({COMPOSITE}) protected HSAILAddressValue address; @State protected LIRFrameState state; - public LoadOp(Kind kind, AllocatableValue result, HSAILAddressValue address, LIRFrameState state) { + public MemOp(Kind kind, HSAILAddressValue address, LIRFrameState state) { this.kind = kind; - this.result = result; this.address = address; this.state = state; } + protected abstract void emitMemAccess(HSAILAssembler masm); + @Override public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) { + if (state != null) { + // tasm.recordImplicitException(masm.codeBuffer.position(), state); + throw new InternalError("NYI"); + } + emitMemAccess(masm); + } + } + + public static class LoadOp extends MemOp { + + @Def({REG}) protected AllocatableValue result; + + public LoadOp(Kind kind, AllocatableValue result, HSAILAddressValue address, LIRFrameState state) { + super(kind, address, state); + this.result = result; + } + + @Override + public void emitMemAccess(HSAILAssembler masm) { HSAILAddress addr = address.toAddress(); masm.emitLoad(result, addr); } } - public static class StoreOp extends HSAILLIRInstruction { + public static class StoreOp extends MemOp { - @SuppressWarnings("unused") private final Kind kind; - @Use({COMPOSITE}) protected HSAILAddressValue address; @Use({REG}) protected AllocatableValue input; - @State protected LIRFrameState state; public StoreOp(Kind kind, HSAILAddressValue address, AllocatableValue input, LIRFrameState state) { - this.kind = kind; - this.address = address; + super(kind, address, state); this.input = input; - this.state = state; } @Override - public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) { + public void emitMemAccess(HSAILAssembler masm) { assert isRegister(input); HSAILAddress addr = address.toAddress(); masm.emitStore(input, addr); } } + public static class LoadCompressedPointer extends LoadOp { + + private long narrowOopBase; + private int narrowOopShift; + private int logMinObjAlignment; + @Temp({REG}) private AllocatableValue scratch; + + public LoadCompressedPointer(Kind kind, AllocatableValue result, AllocatableValue scratch, HSAILAddressValue address, LIRFrameState state, long narrowOopBase, int narrowOopShift, + int logMinObjAlignment) { + super(kind, result, address, state); + this.narrowOopBase = narrowOopBase; + this.narrowOopShift = narrowOopShift; + this.logMinObjAlignment = logMinObjAlignment; + this.scratch = scratch; + assert kind == Kind.Object; + } + + @Override + public void emitMemAccess(HSAILAssembler masm) { + // we will do a 32 bit load, zero extending into a 64 bit register + masm.emitLoad(result, address.toAddress(), "u32"); + decodePointer(masm, result, narrowOopBase, narrowOopShift, logMinObjAlignment); + } + } + + public static class StoreCompressedPointer extends HSAILLIRInstruction { + + protected final Kind kind; + private long narrowOopBase; + private int narrowOopShift; + private int logMinObjAlignment; + @Temp({REG}) private AllocatableValue scratch; + @Alive({REG}) protected AllocatableValue input; + @Alive({COMPOSITE}) protected HSAILAddressValue address; + @State protected LIRFrameState state; + + public StoreCompressedPointer(Kind kind, HSAILAddressValue address, AllocatableValue input, AllocatableValue scratch, LIRFrameState state, long narrowOopBase, int narrowOopShift, + int logMinObjAlignment) { + this.narrowOopBase = narrowOopBase; + this.narrowOopShift = narrowOopShift; + this.logMinObjAlignment = logMinObjAlignment; + this.scratch = scratch; + this.kind = kind; + this.address = address; + this.state = state; + this.input = input; + assert kind == Kind.Object; + } + + @Override + public void emitCode(TargetMethodAssembler tasm, HSAILAssembler masm) { + masm.emitMov(scratch, input); + encodePointer(masm, scratch, narrowOopBase, narrowOopShift, logMinObjAlignment); + if (state != null) { + throw new InternalError("NYI"); + // tasm.recordImplicitException(masm.codeBuffer.position(), state); + } + masm.emitStore(scratch, address.toAddress(), "u32"); + } + } + + private static void encodePointer(HSAILAssembler masm, Value scratch, long narrowOopBase, int narrowOopShift, int logMinObjAlignment) { + if (narrowOopBase == 0 && narrowOopShift == 0) { + return; + } + if (narrowOopShift != 0) { + assert logMinObjAlignment == narrowOopShift : "Encode algorithm is wrong"; + } + masm.emitCompressedOopEncode(scratch, narrowOopBase, narrowOopShift); + } + + private static void decodePointer(HSAILAssembler masm, Value result, long narrowOopBase, int narrowOopShift, int logMinObjAlignment) { + if (narrowOopBase == 0 && narrowOopShift == 0) { + return; + } + if (narrowOopShift != 0) { + assert logMinObjAlignment == narrowOopShift : "Decode algorithm is wrong"; + } + masm.emitCompressedOopDecode(result, narrowOopBase, narrowOopShift); + } + + + public static class LeaOp extends HSAILLIRInstruction { @Def({REG}) protected AllocatableValue result; diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Mon Jul 15 17:54:00 2013 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/InliningPhase.java Mon Jul 15 18:22:25 2013 +0200 @@ -448,6 +448,10 @@ @Override public boolean isWorthInlining(InlineInfo info, int inliningDepth, double probability, double relevance, boolean fullyProcessed) { + if (InlineEverything.getValue()) { + return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "inline everything"); + } + if (isIntrinsic(info)) { return InliningUtil.logInlinedMethod(info, inliningDepth, fullyProcessed, "intrinsic"); } diff -r 058abc2b59a5 -r 395d34c10e26 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Mon Jul 15 17:54:00 2013 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Mon Jul 15 18:22:25 2013 +0200 @@ -63,6 +63,8 @@ public static final OptionValue SmallCompiledLowLevelGraphSize = new OptionValue<>(300); @Option(help = "") public static final OptionValue LimitInlinedInvokes = new OptionValue<>(5.0); + @Option(help = "") + public static final OptionValue InlineEverything = new OptionValue<>(false); // escape analysis settings @Option(help = "")