changeset 15777:1c7a75bf0456

enable some HSAIL virtual call inlining Contributed-by: Tom Deneau <tom.deneau@amd.com>
author twisti
date Mon, 19 May 2014 10:45:01 -0700
parents 111bf82514ca
children 9ae1d2f3bda6
files graal/com.oracle.graal.compiler.hsail.test.infra/src/com/oracle/graal/compiler/hsail/test/infra/GraalKernelTester.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VirtualCall3Test.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VirtualCall4Test.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VirtualCallBase.java graal/com.oracle.graal.compiler.hsail.test/src/com/oracle/graal/compiler/hsail/test/lambda/VirtualCallTest.java graal/com.oracle.graal.compiler.hsail/src/com/oracle/graal/compiler/hsail/HSAILLIRGenerator.java graal/com.oracle.graal.lir.hsail/src/com/oracle/graal/lir/hsail/HSAILControlFlow.java
diffstat 7 files changed, 289 insertions(+), 85 deletions(-) [+]
line wrap: on
line diff
--- 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.
      */
--- /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();
+    }
+
+}
--- /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();
+    }
+
+}
--- /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;
+        }
+    }
+}
--- 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();
     }
 
 }
--- 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());
         }
     }
 
--- 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());
                     }
                 }
             };