# HG changeset patch # User twisti # Date 1400521501 25200 # Node ID 1c7a75bf04566cfa1e1e5aa173a8def6aca53c17 # Parent 111bf82514ca4c8443f5cb16329974db91df5524 enable some HSAIL virtual call inlining Contributed-by: Tom Deneau diff -r 111bf82514ca -r 1c7a75bf0456 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 May 19 18:59:04 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java Mon May 19 10:45:01 2014 -0700 @@ -131,6 +131,13 @@ } /** + * Determines if the JVM supports the required typeProfileWidth. + */ + public boolean typeProfileWidthAtLeast(int val) { + return (getHSAILBackend().getRuntime().getConfig().typeProfileWidth >= val); + } + + /** * Determines if the runtime supports {@link VirtualObject}s in {@link DebugInfo} associated * with HSAIL code. */ diff -r 111bf82514ca -r 1c7a75bf0456 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VirtualCall3Test.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/lambda/VirtualCall3Test.java Mon May 19 10:45:01 2014 -0700 @@ -0,0 +1,67 @@ +/* + * 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.lambda; + +import org.junit.Test; + +/** + * Tests a true virtual method call with 3 targets. + */ +public class VirtualCall3Test extends VirtualCallBase { + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + inShapeArray[i] = createShape(i % 3, i + 1); + } + } + + // although runTest is the same in each class derived from VirtualCallBase + // we duplicate the logic in each derived test so as to have different lambda call sites + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + Shape shape = inShapeArray[gid]; + outArray[gid] = shape.getArea(); + }); + } + + @Override + protected boolean supportsRequiredCapabilities() { + return typeProfileWidthAtLeast(3); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 111bf82514ca -r 1c7a75bf0456 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VirtualCall4Test.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/lambda/VirtualCall4Test.java Mon May 19 10:45:01 2014 -0700 @@ -0,0 +1,67 @@ +/* + * 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.lambda; + +import org.junit.Test; + +/** + * Tests a true virtual method call with 4 targets. + */ +public class VirtualCall4Test extends VirtualCallBase { + + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + inShapeArray[i] = createShape(i % 4, i + 1); + } + } + + // although runTest is the same in each class derived from VirtualCallBase + // we duplicate the logic in each derived test so as to have different lambda call sites + @Override + public void runTest() { + setupArrays(); + + dispatchLambdaKernel(NUM, (gid) -> { + Shape shape = inShapeArray[gid]; + outArray[gid] = shape.getArea(); + }); + } + + @Override + protected boolean supportsRequiredCapabilities() { + return typeProfileWidthAtLeast(4); + } + + @Test + public void test() { + testGeneratedHsail(); + } + + @Test + public void testUsingLambdaMethod() { + testGeneratedHsailUsingLambdaMethod(); + } + +} diff -r 111bf82514ca -r 1c7a75bf0456 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VirtualCallBase.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/lambda/VirtualCallBase.java Mon May 19 10:45:01 2014 -0700 @@ -0,0 +1,117 @@ +/* + * 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.lambda; + +import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; + +/** + * Base class for testing virtual method calls. + */ +abstract public class VirtualCallBase extends GraalKernelTester { + + static final int NUM = 20000; + + @Result public float[] outArray = new float[NUM]; + public Shape[] inShapeArray = new Shape[NUM]; + + static abstract class Shape { + + abstract public float getArea(); + } + + static class Circle extends Shape { + + private float radius; + + Circle(float r) { + radius = r; + } + + @Override + public float getArea() { + return (float) (Math.PI * radius * radius); + } + } + + static class Square extends Shape { + + private float len; + + Square(float _len) { + len = _len; + } + + @Override + public float getArea() { + return len * len; + } + } + + static class Triangle extends Shape { + + private float base; + private float height; + + Triangle(float base, float height) { + this.base = base; + this.height = height; + } + + @Override + public float getArea() { + return (base * height / 2.0f); + } + } + + static class Rectangle extends Shape { + + private float base; + private float height; + + Rectangle(float base, float height) { + this.base = base; + this.height = height; + } + + @Override + public float getArea() { + return (base * height); + } + } + + Shape createShape(int kind, int size) { + switch (kind) { + case 0: + return new Circle(size); + case 1: + return new Square(size); + case 2: + return new Triangle(size, size + 1); + case 3: + return new Rectangle(size, size + 1); + default: + return null; + } + } +} diff -r 111bf82514ca -r 1c7a75bf0456 graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VirtualCallTest.java --- a/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VirtualCallTest.java Mon May 19 18:59:04 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VirtualCallTest.java Mon May 19 10:45:01 2014 -0700 @@ -23,66 +23,23 @@ package com.oracle.graal.compiler.hsail.test.lambda; -import static com.oracle.graal.debug.Debug.*; - -import com.oracle.graal.compiler.hsail.test.infra.GraalKernelTester; -import com.oracle.graal.debug.*; - import org.junit.Test; /** - * Tests a true virtual method call. + * Tests a true virtual method call with 2 targets. */ -public class VirtualCallTest extends GraalKernelTester { - - static final int NUM = 20; - - static abstract class Shape { - - abstract public float getArea(); - } +public class VirtualCallTest extends VirtualCallBase { - static class Circle extends Shape { - - private float radius; - - Circle(float r) { - radius = r; - } - - @Override - public float getArea() { - return (float) (Math.PI * radius * radius); + void setupArrays() { + for (int i = 0; i < NUM; i++) { + outArray[i] = -i; + int kind = i % 3 == 0 ? 0 : 1; + inShapeArray[i] = createShape(kind, i + 1); } } - static class Square extends Shape { - - private float len; - - Square(float _len) { - len = _len; - } - - @Override - public float getArea() { - return len * len; - } - } - - @Result public float[] outArray = new float[NUM]; - public Shape[] inShapeArray = new Shape[NUM]; - - void setupArrays() { - for (int i = 0; i < NUM; i++) { - if (i % 2 == 0) - inShapeArray[i] = new Circle(i + 1); - else - inShapeArray[i] = new Square(i + 1); - outArray[i] = -i; - } - } - + // although runTest is the same in each class derived from VirtualCallBase + // we duplicate the logic in each derived test so as to have different lambda call sites @Override public void runTest() { setupArrays(); @@ -93,19 +50,19 @@ }); } - // graal says not inlining getArea():float (0 bytes): no type profile exists - @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) - public void test() { - try (DebugConfigScope s = disableIntercept()) { - testGeneratedHsail(); - } + @Override + protected boolean supportsRequiredCapabilities() { + return typeProfileWidthAtLeast(2); } - @Test(expected = com.oracle.graal.compiler.common.GraalInternalError.class) + @Test + public void test() { + testGeneratedHsail(); + } + + @Test public void testUsingLambdaMethod() { - try (DebugConfigScope s = disableIntercept()) { - testGeneratedHsailUsingLambdaMethod(); - } + testGeneratedHsailUsingLambdaMethod(); } } diff -r 111bf82514ca -r 1c7a75bf0456 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 May 19 18:59:04 2014 +0200 +++ b/graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java Mon May 19 10:45:01 2014 -0700 @@ -838,16 +838,6 @@ * series of cascading compare and branch instructions. This is currently the recommended way of * generating performant HSAIL code for switch constructs. * - * In Java bytecode the keys for switch statements are always ints. - * - * The x86 backend also adds support for handling keys of type long or Object but these two - * special cases are for handling the TypeSwitchNode, which is a node that the JVM produces for - * handling operations related to method dispatch. We haven't yet added support for the - * TypeSwitchNode, so for the time being we have added a check to ensure that the keys are of - * type int. This also allows us to flag any test cases/execution paths that may trigger the - * creation of a TypeSwitchNode which we don't support yet. - * - * * @param strategy the strategy used for this switch. * @param keyTargets array of branch targets for each of the cases. * @param defaultTarget the branch target for the default case. @@ -855,12 +845,16 @@ */ @Override public void emitStrategySwitch(SwitchStrategy strategy, Variable key, LabelRef[] keyTargets, LabelRef defaultTarget) { - if ((key.getKind() == Kind.Int) || (key.getKind() == Kind.Long)) { - // Append the LIR instruction for generating compare and branch instructions. - append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key)); - } else { - // Throw an exception if the keys aren't ints. - throw GraalInternalError.unimplemented("Switch statements are only supported for keys of type int or long, not " + key.getKind()); + switch (key.getKind()) { + case Int: + case Long: + case Object: + // Append the LIR instruction for generating compare and branch instructions. + append(new StrategySwitchOp(strategy, keyTargets, defaultTarget, key)); + break; + default: + // Throw an exception if the key kind is anything else. + throw GraalInternalError.unimplemented("Switch statements not supported for keys of type " + key.getKind()); } } diff -r 111bf82514ca -r 1c7a75bf0456 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 May 19 18:59:04 2014 +0200 +++ b/graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java Mon May 19 10:45:01 2014 -0700 @@ -84,11 +84,6 @@ /** * Generates the code for this switch op. * - * The keys for switch statements in Java bytecode for of type int. However, Graal also - * generates a TypeSwitchNode (for method dispatch) which triggers the invocation of these - * routines with keys of type Long or Object. Currently we only support the - * IntegerSwitchNode so we throw an exception if the key isn't of type int. - * * @param crb the CompilationResultBuilder * @param masm the HSAIL assembler */ @@ -100,13 +95,13 @@ switch (key.getKind()) { case Int: case Long: + case Object: // Generate cascading compare and branches for each case. masm.emitCompare(key.getKind(), key, keyConstants[index], HSAILCompare.conditionToString(condition), false, false); masm.cbr(masm.nameOf(target)); break; - case Object: default: - throw new GraalInternalError("switch only supported for int"); + throw new GraalInternalError("switch not supported for kind " + key.getKind()); } } };