changeset 19046:2358c0e65b9e

Unit tests for GraalDirectives API.
author Roland Schatz <roland.schatz@oracle.com>
date Thu, 29 Jan 2015 16:49:03 +0100
parents 862997951c0a
children 173bdcc85ab8
files graal/com.oracle.graal.api.directives.test/src/com/oracle/graal/api/directives/test/BlackholeDirectiveTest.java graal/com.oracle.graal.api.directives.test/src/com/oracle/graal/api/directives/test/DeoptimizeDirectiveTest.java graal/com.oracle.graal.api.directives.test/src/com/oracle/graal/api/directives/test/IterationDirectiveTest.java graal/com.oracle.graal.api.directives.test/src/com/oracle/graal/api/directives/test/OpaqueDirectiveTest.java graal/com.oracle.graal.api.directives.test/src/com/oracle/graal/api/directives/test/ProbabilityDirectiveTest.java mx/suite.py
diffstat 6 files changed, 494 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.directives.test/src/com/oracle/graal/api/directives/test/BlackholeDirectiveTest.java	Thu Jan 29 16:49:03 2015 +0100
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2015, 2015, 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.api.directives.test;
+
+import java.lang.annotation.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.directives.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.nodes.*;
+
+/**
+ * Tests for {@link GraalDirectives#blackhole}.
+ *
+ * There are two snippets for each kind:
+ * <ul>
+ * <li>blackhole&lt;Kind&gt;Snippet verifies that dead code elimination is prevented by the
+ * blackhole directive.
+ * <li>&lt;kind&gt;Snippet verifies that dead code elimination does happen if the blackhole
+ * directive is not there.
+ * </ul>
+ *
+ */
+public class BlackholeDirectiveTest extends GraalCompilerTest {
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.METHOD)
+    private @interface BlackholeSnippet {
+        boolean expectParameterUsage();
+    }
+
+    @BlackholeSnippet(expectParameterUsage = false)
+    public static int booleanSnippet(int arg) {
+        boolean b = arg > 3;
+        if (b) {
+            return 1;
+        } else {
+            return 1;
+        }
+    }
+
+    @BlackholeSnippet(expectParameterUsage = true)
+    public static int blackholeBooleanSnippet(int arg) {
+        boolean b = arg > 3;
+        GraalDirectives.blackhole(b);
+        if (b) {
+            return 1;
+        } else {
+            return 1;
+        }
+    }
+
+    @Test
+    public void testBoolean() {
+        test("booleanSnippet", 5);
+        test("blackholeBooleanSnippet", 5);
+    }
+
+    @BlackholeSnippet(expectParameterUsage = false)
+    public static int intSnippet(int arg) {
+        int x = 42 + arg;
+        return x - arg;
+    }
+
+    @BlackholeSnippet(expectParameterUsage = true)
+    public static int blackholeIntSnippet(int arg) {
+        int x = 42 + arg;
+        GraalDirectives.blackhole(x);
+        return x - arg;
+    }
+
+    @Test
+    public void testInt() {
+        test("intSnippet", 17);
+        test("blackholeIntSnippet", 17);
+    }
+
+    private static class Dummy {
+        private int x = 42;
+    }
+
+    @BlackholeSnippet(expectParameterUsage = false)
+    public static int objectSnippet(int arg) {
+        Dummy obj = new Dummy();
+        int ret = obj.x;
+        obj.x = arg;
+        return ret;
+    }
+
+    @BlackholeSnippet(expectParameterUsage = true)
+    public static int blackholeObjectSnippet(int arg) {
+        Dummy obj = new Dummy();
+        int ret = obj.x;
+        obj.x = arg;
+        GraalDirectives.blackhole(obj);
+        return ret;
+    }
+
+    @Test
+    public void testObject() {
+        test("objectSnippet", 37);
+        test("blackholeObjectSnippet", 37);
+    }
+
+    @Override
+    protected boolean checkLowTierGraph(StructuredGraph graph) {
+        BlackholeSnippet snippet = graph.method().getAnnotation(BlackholeSnippet.class);
+        ParameterNode arg = graph.getParameter(0);
+        if (snippet.expectParameterUsage()) {
+            Assert.assertNotNull("couldn't find ParameterNode(0)", arg);
+            Assert.assertFalse("expected usages of " + arg, arg.hasNoUsages());
+        } else {
+            Assert.assertTrue("expected no usages of ParameterNode", arg == null || arg.hasNoUsages());
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.directives.test/src/com/oracle/graal/api/directives/test/DeoptimizeDirectiveTest.java	Thu Jan 29 16:49:03 2015 +0100
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2015, 2015, 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.api.directives.test;
+
+import org.junit.*;
+
+import com.oracle.graal.api.code.*;
+import com.oracle.graal.api.directives.*;
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.compiler.test.*;
+
+public class DeoptimizeDirectiveTest extends GraalCompilerTest {
+
+    public static boolean inCompiledCode() {
+        return GraalDirectives.inCompiledCode();
+    }
+
+    @Test
+    public void testInCompiledCode() {
+        ResolvedJavaMethod method = getResolvedJavaMethod("inCompiledCode");
+
+        Result interpreted = executeExpected(method, null);
+        assertEquals(new Result(false, null), interpreted);
+
+        Result compiled = executeActual(method, null);
+        assertEquals(new Result(true, null), compiled);
+    }
+
+    public static boolean deoptimizeSnippet() {
+        GraalDirectives.deoptimize();
+        return GraalDirectives.inCompiledCode(); // should always return false
+    }
+
+    public static boolean deoptimizeAndInvalidateSnippet() {
+        GraalDirectives.deoptimizeAndInvalidate();
+        return GraalDirectives.inCompiledCode(); // should always return false
+    }
+
+    @Test
+    public void testDeoptimize() {
+        test("deoptimizeSnippet");
+    }
+
+    private boolean testDeoptimizeCheckValid(ResolvedJavaMethod method) {
+        Result expected = executeExpected(method, null);
+
+        InstalledCode code = getCode(method);
+        Result actual;
+        try {
+            actual = new Result(code.executeVarargs(), null);
+        } catch (Throwable e) {
+            actual = new Result(null, e);
+        }
+
+        assertEquals(expected, actual);
+        return code.isValid();
+    }
+
+    @Test
+    public void testDeoptimizeAndInvalidate() {
+        ResolvedJavaMethod method = getResolvedJavaMethod("deoptimizeAndInvalidateSnippet");
+        boolean valid = testDeoptimizeCheckValid(method);
+        Assert.assertFalse("code should be invalidated", valid);
+    }
+
+    @Test
+    public void testDeoptimizeDontInvalidate() {
+        ResolvedJavaMethod method = getResolvedJavaMethod("deoptimizeSnippet");
+        boolean valid = testDeoptimizeCheckValid(method);
+        Assert.assertTrue("code should still be valid", valid);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.directives.test/src/com/oracle/graal/api/directives/test/IterationDirectiveTest.java	Thu Jan 29 16:49:03 2015 +0100
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, 2015, 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.api.directives.test;
+
+import org.junit.*;
+
+import com.oracle.graal.api.directives.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.nodes.*;
+
+public class IterationDirectiveTest extends GraalCompilerTest {
+
+    public static int loopFrequencySnippet(int arg) {
+        int x = arg;
+        while (GraalDirectives.injectIterationCount(128, x > 1)) {
+            GraalDirectives.controlFlowAnchor(); // prevent loop peeling or unrolling
+            if (x % 2 == 0) {
+                x /= 2;
+            } else {
+                x = 3 * x + 1;
+            }
+        }
+        return x;
+    }
+
+    @Test
+    public void testLoopFrequency() {
+        test("loopFrequencySnippet", 7);
+    }
+
+    @Override
+    protected boolean checkLowTierGraph(StructuredGraph graph) {
+        NodeIterable<LoopBeginNode> loopBeginNodes = graph.getNodes(LoopBeginNode.class);
+        Assert.assertEquals("LoopBeginNode count", 1, loopBeginNodes.count());
+
+        LoopBeginNode loopBeginNode = loopBeginNodes.first();
+        Assert.assertEquals("loop frequency of " + loopBeginNode, 128, loopBeginNode.loopFrequency(), 0);
+
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.directives.test/src/com/oracle/graal/api/directives/test/OpaqueDirectiveTest.java	Thu Jan 29 16:49:03 2015 +0100
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2015, 2015, 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.api.directives.test;
+
+import java.lang.annotation.*;
+
+import org.junit.*;
+
+import com.oracle.graal.api.directives.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.calc.*;
+
+/**
+ * Tests for {@link GraalDirectives#opaque}.
+ *
+ * There are two snippets for each kind:
+ * <ul>
+ * <li>opaque&lt;Kind&gt;Snippet verifies that constant folding is prevented by the opaque
+ * directive.
+ * <li>&lt;kind&gt;Snippet verifies that constant folding does happen if the opaque directive is not
+ * there.
+ * </ul>
+ *
+ */
+public class OpaqueDirectiveTest extends GraalCompilerTest {
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.METHOD)
+    private @interface OpaqueSnippet {
+        Class<?> expectedReturnNode();
+    }
+
+    @OpaqueSnippet(expectedReturnNode = ConstantNode.class)
+    public static boolean booleanSnippet() {
+        return 5 > 3;
+    }
+
+    @OpaqueSnippet(expectedReturnNode = ConditionalNode.class)
+    public static boolean opaqueBooleanSnippet() {
+        return 5 > GraalDirectives.opaque(3);
+    }
+
+    @Test
+    public void testBoolean() {
+        test("booleanSnippet");
+        test("opaqueBooleanSnippet");
+    }
+
+    @OpaqueSnippet(expectedReturnNode = ConstantNode.class)
+    public static int intSnippet() {
+        return 5 + 3;
+    }
+
+    @OpaqueSnippet(expectedReturnNode = AddNode.class)
+    public static int opaqueIntSnippet() {
+        return 5 + GraalDirectives.opaque(3);
+    }
+
+    @Test
+    public void testInt() {
+        test("intSnippet");
+        test("opaqueIntSnippet");
+    }
+
+    @OpaqueSnippet(expectedReturnNode = ConstantNode.class)
+    public static double doubleSnippet() {
+        return 5. + 3.;
+    }
+
+    @OpaqueSnippet(expectedReturnNode = AddNode.class)
+    public static double opaqueDoubleSnippet() {
+        return 5. + GraalDirectives.opaque(3.);
+    }
+
+    @Test
+    public void testDouble() {
+        test("doubleSnippet");
+        test("opaqueDoubleSnippet");
+    }
+
+    private static class Dummy {
+    }
+
+    @OpaqueSnippet(expectedReturnNode = ConstantNode.class)
+    public static boolean objectSnippet() {
+        Object obj = new Dummy();
+        return obj == null;
+    }
+
+    @OpaqueSnippet(expectedReturnNode = ConditionalNode.class)
+    public static boolean opaqueObjectSnippet() {
+        Object obj = new Dummy();
+        return GraalDirectives.opaque(obj) == null;
+    }
+
+    @Test
+    public void testObject() {
+        test("objectSnippet");
+        test("opaqueObjectSnippet");
+    }
+
+    @Override
+    protected boolean checkLowTierGraph(StructuredGraph graph) {
+        OpaqueSnippet snippet = graph.method().getAnnotation(OpaqueSnippet.class);
+        for (ReturnNode returnNode : graph.getNodes(ReturnNode.class)) {
+            Assert.assertEquals(snippet.expectedReturnNode(), returnNode.result().getClass());
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.directives.test/src/com/oracle/graal/api/directives/test/ProbabilityDirectiveTest.java	Thu Jan 29 16:49:03 2015 +0100
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015, 2015, 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.api.directives.test;
+
+import org.junit.*;
+
+import com.oracle.graal.api.directives.*;
+import com.oracle.graal.compiler.test.*;
+import com.oracle.graal.graph.iterators.*;
+import com.oracle.graal.nodes.*;
+
+public class ProbabilityDirectiveTest extends GraalCompilerTest {
+
+    public static int branchProbabilitySnippet(int arg) {
+        if (GraalDirectives.injectBranchProbability(0.125, arg > 0)) {
+            GraalDirectives.controlFlowAnchor(); // prevent removal of the if
+            return 1;
+        } else {
+            GraalDirectives.controlFlowAnchor(); // prevent removal of the if
+            return 2;
+        }
+    }
+
+    @Test
+    public void testBranchProbability() {
+        test("branchProbabilitySnippet", 5);
+    }
+
+    @Override
+    protected boolean checkLowTierGraph(StructuredGraph graph) {
+        NodeIterable<IfNode> ifNodes = graph.getNodes(IfNode.class);
+        Assert.assertEquals("IfNode count", 1, ifNodes.count());
+
+        IfNode ifNode = ifNodes.first();
+        AbstractBeginNode trueSuccessor = ifNode.trueSuccessor();
+        Assert.assertEquals("branch probability of " + ifNode, 0.125, ifNode.probability(trueSuccessor), 0);
+
+        return true;
+    }
+}
--- a/mx/suite.py	Thu Jan 29 16:45:09 2015 +0100
+++ b/mx/suite.py	Thu Jan 29 16:49:03 2015 +0100
@@ -228,6 +228,17 @@
       "workingSets" : "API,Graal",
     },
 
+    "com.oracle.graal.api.directives.test" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "checkstyle" : "com.oracle.graal.graph",
+      "dependencies" : [
+        "com.oracle.graal.compiler.test",
+      ],
+      "javaCompliance" : "1.8",
+      "workingSets" : "API,Graal",
+    },
+
     "com.oracle.graal.api.runtime" : {
       "subDir" : "graal",
       "sourceDirs" : ["src"],