changeset 13814:b42977294f02

respect useCountLeadingZerosInstruction. improve substitution test
author Tom Rodriguez <tom.rodriguez@oracle.com>
date Tue, 28 Jan 2014 13:20:56 -0800
parents 6c5c17d0f57d
children 9a8e4dfae480
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalTest.java
diffstat 3 files changed, 63 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Tue Jan 28 21:24:24 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Tue Jan 28 13:20:56 2014 -0800
@@ -58,6 +58,11 @@
                 if (!config.usePopCountInstruction) {
                     return null;
                 }
+            } else if (substituteMethod.getName().equals("numberOfLeadingZeros")) {
+                if (config.useCountLeadingZerosInstruction) {
+                    // bsr is lzcnt
+                    return null;
+                }
             }
         } else if (substituteClass == CRC32Substitutions.class) {
             if (!config.useCRC32Intrinsics) {
--- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java	Tue Jan 28 21:24:24 2014 +0100
+++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/StandardMethodSubstitutionsTest.java	Tue Jan 28 13:20:56 2014 -0800
@@ -32,6 +32,7 @@
 
 import sun.misc.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.replacements.*;
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.nodes.calc.*;
@@ -350,19 +351,54 @@
         // Math.pow(value, 13);
     }
 
+    private static Object executeVarargsSafe(InstalledCode code, Object... args) {
+        try {
+            return code.executeVarargs(args);
+        } catch (InvalidInstalledCodeException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static Object invokeSafe(Method method, Object... args) {
+        method.setAccessible(true);
+        try {
+            Object result = method.invoke(null, args);
+            return result;
+        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public void testSubstitution(String testMethodName, Class<?> intrinsicClass, Class<?> holder, String methodName, boolean optional, Object... args) {
+        Method realMethod = getMethod(holder, methodName);
+        Method testMethod = getMethod(testMethodName);
+        StructuredGraph graph = test(testMethodName);
+
+        // Check to see if the resulting graph contains the expected node
+        StructuredGraph replacement = getReplacements().getMethodSubstitution(getMetaAccess().lookupJavaMethod(realMethod));
+        if (replacement == null && !optional) {
+            assertInGraph(graph, intrinsicClass);
+        }
+
+        // Force compilation
+        InstalledCode code = getCode(getMetaAccess().lookupJavaMethod(testMethod), parse(testMethod));
+        assert optional || code != null;
+        for (Object l : args) {
+            // Verify that the original method and the substitution produce the same value
+            assertEquals(invokeSafe(testMethod, l), invokeSafe(realMethod, l));
+            // Verify that the generated code and the original produce the same value
+            assertEquals(executeVarargsSafe(code, l), invokeSafe(realMethod, l));
+        }
+    }
+
     @Test
     public void testIntegerSubstitutions() {
-        assertInGraph(test("integerReverseBytes"), ReverseBytesNode.class);              // Java
-        assertInGraph(test("integerNumberOfLeadingZeros"), BitScanReverseNode.class);    // Java
-        assertInGraph(test("integerNumberOfTrailingZeros"), BitScanForwardNode.class);   // Java
-        assertInGraph(test("integerBitCount"), BitCountNode.class);                      // Java
+        Object[] args = new Object[]{Integer.MIN_VALUE, -1, 0, 1, Integer.MAX_VALUE};
 
-        for (int i : new int[]{Integer.MIN_VALUE, -1, 0, 1, Integer.MAX_VALUE}) {
-            assertEquals(Integer.reverseBytes(i), IntegerSubstitutions.reverseBytes(i));
-            assertEquals(Integer.numberOfLeadingZeros(i), IntegerSubstitutions.numberOfLeadingZeros(i));
-            assertEquals(Integer.numberOfTrailingZeros(i), IntegerSubstitutions.numberOfTrailingZeros(i));
-            assertEquals(Integer.bitCount(i), IntegerSubstitutions.bitCount(i));
-        }
+        testSubstitution("integerReverseBytes", ReverseBytesNode.class, Integer.class, "reverseBytes", false, args);
+        testSubstitution("integerNumberOfLeadingZeros", BitScanReverseNode.class, Integer.class, "numberOfLeadingZeros", true, args);
+        testSubstitution("integerNumberOfTrailingZeros", BitScanForwardNode.class, Integer.class, "numberOfTrailingZeros", false, args);
+        testSubstitution("integerBitCount", BitCountNode.class, Integer.class, "bitCount", true, args);
     }
 
     @SuppressWarnings("all")
@@ -387,17 +423,12 @@
 
     @Test
     public void testLongSubstitutions() {
-        assertInGraph(test("longReverseBytes"), ReverseBytesNode.class);              // Java
-        assertInGraph(test("longNumberOfLeadingZeros"), BitScanReverseNode.class);    // Java
-        assertInGraph(test("longNumberOfTrailingZeros"), BitScanForwardNode.class);   // Java
-        assertInGraph(test("longBitCount"), BitCountNode.class);                      // Java
+        Object[] args = new Object[]{Long.MIN_VALUE, -1L, 0L, 1L, Long.MAX_VALUE};
 
-        for (long l : new long[]{Long.MIN_VALUE, -1L, 0L, 1L, Long.MAX_VALUE}) {
-            assertEquals(Long.reverseBytes(l), LongSubstitutions.reverseBytes(l));
-            assertEquals(Long.numberOfLeadingZeros(l), LongSubstitutions.numberOfLeadingZeros(l));
-            assertEquals(Long.numberOfTrailingZeros(l), LongSubstitutions.numberOfTrailingZeros(l));
-            assertEquals(Long.bitCount(l), LongSubstitutions.bitCount(l));
-        }
+        testSubstitution("longReverseBytes", ReverseBytesNode.class, Long.class, "reverseBytes", false, args);
+        testSubstitution("longNumberOfLeadingZeros", BitScanReverseNode.class, Long.class, "numberOfLeadingZeros", true, args);
+        testSubstitution("longNumberOfTrailingZeros", BitScanForwardNode.class, Long.class, "numberOfTrailingZeros", false, args);
+        testSubstitution("longBitCount", BitCountNode.class, Long.class, "bitCount", true, args);
     }
 
     @SuppressWarnings("all")
@@ -406,12 +437,12 @@
     }
 
     @SuppressWarnings("all")
-    public static long longNumberOfLeadingZeros(long value) {
+    public static int longNumberOfLeadingZeros(long value) {
         return Long.numberOfLeadingZeros(value);
     }
 
     @SuppressWarnings("all")
-    public static long longNumberOfTrailingZeros(long value) {
+    public static int longNumberOfTrailingZeros(long value) {
         return Long.numberOfTrailingZeros(value);
     }
 
--- a/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalTest.java	Tue Jan 28 21:24:24 2014 +0100
+++ b/graal/com.oracle.graal.test/src/com/oracle/graal/test/GraalTest.java	Tue Jan 28 13:20:56 2014 -0800
@@ -36,8 +36,12 @@
 public class GraalTest {
 
     protected Method getMethod(String methodName) {
+        return getMethod(getClass(), methodName);
+    }
+
+    protected Method getMethod(Class<?> clazz, String methodName) {
         Method found = null;
-        for (Method m : this.getClass().getMethods()) {
+        for (Method m : clazz.getMethods()) {
             if (m.getName().equals(methodName)) {
                 Assert.assertNull(found);
                 found = m;