< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64GraphBuilderPlugins.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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.

@@ -57,10 +57,11 @@
 import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.UnsafeGetPlugin;
 import org.graalvm.compiler.replacements.StandardGraphBuilderPlugins.UnsafePutPlugin;
 import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode;
 import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode.BinaryOperation;
 import org.graalvm.compiler.replacements.nodes.BitCountNode;
+import org.graalvm.compiler.replacements.nodes.FusedMultiplyAddNode;
 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode;
 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation;
 
 import jdk.vm.ci.amd64.AMD64;
 import jdk.vm.ci.amd64.AMD64.CPUFeature;

@@ -68,11 +69,12 @@
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import sun.misc.Unsafe;
 
 public class AMD64GraphBuilderPlugins {
 
-    public static void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, AMD64 arch, boolean explicitUnsafeNullChecks, boolean emitJDK9StringSubstitutions) {
+    public static void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, AMD64 arch, boolean explicitUnsafeNullChecks, boolean emitJDK9StringSubstitutions,
+                    boolean useFMAIntrinsics) {
         InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
         invocationPlugins.defer(new Runnable() {
             @Override
             public void run() {
                 registerThreadPlugins(invocationPlugins, arch);

@@ -84,11 +86,11 @@
                 registerStringPlugins(invocationPlugins, replacementsBytecodeProvider);
                 if (emitJDK9StringSubstitutions) {
                     registerStringLatin1Plugins(invocationPlugins, replacementsBytecodeProvider);
                     registerStringUTF16Plugins(invocationPlugins, replacementsBytecodeProvider);
                 }
-                registerMathPlugins(invocationPlugins, arch, replacementsBytecodeProvider);
+                registerMathPlugins(invocationPlugins, useFMAIntrinsics, arch, replacementsBytecodeProvider);
                 registerArraysEqualsPlugins(invocationPlugins, replacementsBytecodeProvider);
             }
         });
     }
 

@@ -110,11 +112,13 @@
 
     private static void registerIntegerLongPlugins(InvocationPlugins plugins, Class<?> substituteDeclaringClass, JavaKind kind, AMD64 arch, BytecodeProvider bytecodeProvider) {
         Class<?> declaringClass = kind.toBoxedJavaClass();
         Class<?> type = kind.toJavaClass();
         Registration r = new Registration(plugins, declaringClass, bytecodeProvider);
+        r.registerMethodSubstitution(substituteDeclaringClass, "numberOfLeadingZeros", type);
         if (arch.getFeatures().contains(AMD64.CPUFeature.LZCNT) && arch.getFlags().contains(AMD64.Flag.UseCountLeadingZerosInstruction)) {
+            r.setAllowOverwrite(true);
             r.register1("numberOfLeadingZeros", type, new InvocationPlugin() {
                 @Override
                 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
                     ValueNode folded = AMD64CountLeadingZerosNode.tryFold(value);
                     if (folded != null) {

@@ -123,15 +127,17 @@
                         b.addPush(JavaKind.Int, new AMD64CountLeadingZerosNode(value));
                     }
                     return true;
                 }
             });
-        } else {
-            r.registerMethodSubstitution(substituteDeclaringClass, "numberOfLeadingZeros", type);
         }
+
+        r.registerMethodSubstitution(substituteDeclaringClass, "numberOfTrailingZeros", type);
         if (arch.getFeatures().contains(AMD64.CPUFeature.BMI1) && arch.getFlags().contains(AMD64.Flag.UseCountTrailingZerosInstruction)) {
+            r.setAllowOverwrite(true);
             r.register1("numberOfTrailingZeros", type, new InvocationPlugin() {
+
                 @Override
                 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
                     ValueNode folded = AMD64CountTrailingZerosNode.tryFold(value);
                     if (folded != null) {
                         b.addPush(JavaKind.Int, folded);

@@ -139,12 +145,10 @@
                         b.addPush(JavaKind.Int, new AMD64CountTrailingZerosNode(value));
                     }
                     return true;
                 }
             });
-        } else {
-            r.registerMethodSubstitution(substituteDeclaringClass, "numberOfTrailingZeros", type);
         }
 
         if (arch.getFeatures().contains(AMD64.CPUFeature.POPCNT)) {
             r.register1("bitCount", type, new InvocationPlugin() {
                 @Override

@@ -152,13 +156,14 @@
                     b.push(JavaKind.Int, b.append(new BitCountNode(value).canonical(null)));
                     return true;
                 }
             });
         }
+
     }
 
-    private static void registerMathPlugins(InvocationPlugins plugins, AMD64 arch, BytecodeProvider bytecodeProvider) {
+    private static void registerMathPlugins(InvocationPlugins plugins, boolean useFMAIntrinsics, AMD64 arch, BytecodeProvider bytecodeProvider) {
         Registration r = new Registration(plugins, Math.class, bytecodeProvider);
         registerUnaryMath(r, "log", LOG);
         registerUnaryMath(r, "log10", LOG10);
         registerUnaryMath(r, "exp", EXP);
         registerBinaryMath(r, "pow", POW);

@@ -169,10 +174,49 @@
         if (arch.getFeatures().contains(CPUFeature.SSE4_1)) {
             registerRound(r, "rint", RoundingMode.NEAREST);
             registerRound(r, "ceil", RoundingMode.UP);
             registerRound(r, "floor", RoundingMode.DOWN);
         }
+
+        if (useFMAIntrinsics && !Java8OrEarlier && arch.getFeatures().contains(CPUFeature.FMA)) {
+            registerFMA(r);
+        }
+    }
+
+    private static void registerFMA(Registration r) {
+        r.register3("fma",
+                        Double.TYPE,
+                        Double.TYPE,
+                        Double.TYPE,
+                        new InvocationPlugin() {
+                            @Override
+                            public boolean apply(GraphBuilderContext b,
+                                            ResolvedJavaMethod targetMethod,
+                                            Receiver receiver,
+                                            ValueNode na,
+                                            ValueNode nb,
+                                            ValueNode nc) {
+                                b.push(JavaKind.Double, b.append(new FusedMultiplyAddNode(na, nb, nc)));
+                                return true;
+                            }
+                        });
+        r.register3("fma",
+                        Float.TYPE,
+                        Float.TYPE,
+                        Float.TYPE,
+                        new InvocationPlugin() {
+                            @Override
+                            public boolean apply(GraphBuilderContext b,
+                                            ResolvedJavaMethod targetMethod,
+                                            Receiver receiver,
+                                            ValueNode na,
+                                            ValueNode nb,
+                                            ValueNode nc) {
+                                b.push(JavaKind.Float, b.append(new FusedMultiplyAddNode(na, nb, nc)));
+                                return true;
+                            }
+                        });
     }
 
     private static void registerUnaryMath(Registration r, String name, UnaryOperation operation) {
         r.register1(name, Double.TYPE, new InvocationPlugin() {
             @Override
< prev index next >