< 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 >