30 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG; |
30 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG; |
31 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG10; |
31 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.LOG10; |
32 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN; |
32 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.SIN; |
33 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN; |
33 import static org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation.TAN; |
34 |
34 |
35 import org.graalvm.compiler.bytecode.BytecodeProvider; |
|
36 import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticLIRGeneratorTool.RoundingMode; |
35 import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticLIRGeneratorTool.RoundingMode; |
37 import org.graalvm.compiler.nodes.ValueNode; |
36 import org.graalvm.compiler.nodes.ValueNode; |
38 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; |
37 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; |
39 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext; |
38 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderContext; |
40 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; |
39 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; |
43 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration; |
42 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration; |
44 import org.graalvm.compiler.nodes.java.AtomicReadAndAddNode; |
43 import org.graalvm.compiler.nodes.java.AtomicReadAndAddNode; |
45 import org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode; |
44 import org.graalvm.compiler.nodes.java.AtomicReadAndWriteNode; |
46 import org.graalvm.compiler.nodes.memory.address.AddressNode; |
45 import org.graalvm.compiler.nodes.memory.address.AddressNode; |
47 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode; |
46 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode; |
|
47 import org.graalvm.compiler.nodes.spi.Replacements; |
48 import org.graalvm.compiler.replacements.TargetGraphBuilderPlugins; |
48 import org.graalvm.compiler.replacements.TargetGraphBuilderPlugins; |
49 import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode; |
49 import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode; |
50 import org.graalvm.compiler.replacements.nodes.FusedMultiplyAddNode; |
50 import org.graalvm.compiler.replacements.nodes.FusedMultiplyAddNode; |
51 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode; |
51 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode; |
52 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation; |
52 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation; |
58 import jdk.vm.ci.meta.ResolvedJavaMethod; |
58 import jdk.vm.ci.meta.ResolvedJavaMethod; |
59 import sun.misc.Unsafe; |
59 import sun.misc.Unsafe; |
60 |
60 |
61 public class AArch64GraphBuilderPlugins implements TargetGraphBuilderPlugins { |
61 public class AArch64GraphBuilderPlugins implements TargetGraphBuilderPlugins { |
62 @Override |
62 @Override |
63 public void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, Architecture arch, boolean explicitUnsafeNullChecks, boolean registerMathPlugins, |
63 public void register(Plugins plugins, Replacements replacements, Architecture arch, boolean explicitUnsafeNullChecks, boolean registerMathPlugins, |
64 boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) { |
64 boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) { |
65 register(plugins, replacementsBytecodeProvider, explicitUnsafeNullChecks, registerMathPlugins, emitJDK9StringSubstitutions, useFMAIntrinsics); |
65 register(plugins, replacements, explicitUnsafeNullChecks, registerMathPlugins, emitJDK9StringSubstitutions, useFMAIntrinsics); |
66 } |
66 } |
67 |
67 |
68 public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks, |
68 public static void register(Plugins plugins, Replacements replacements, boolean explicitUnsafeNullChecks, |
69 boolean registerMathPlugins, boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) { |
69 boolean registerMathPlugins, boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) { |
70 InvocationPlugins invocationPlugins = plugins.getInvocationPlugins(); |
70 InvocationPlugins invocationPlugins = plugins.getInvocationPlugins(); |
71 invocationPlugins.defer(new Runnable() { |
71 invocationPlugins.defer(new Runnable() { |
72 @Override |
72 @Override |
73 public void run() { |
73 public void run() { |
74 registerIntegerLongPlugins(invocationPlugins, JavaKind.Int, bytecodeProvider); |
74 registerIntegerLongPlugins(invocationPlugins, JavaKind.Int, replacements); |
75 registerIntegerLongPlugins(invocationPlugins, JavaKind.Long, bytecodeProvider); |
75 registerIntegerLongPlugins(invocationPlugins, JavaKind.Long, replacements); |
76 if (registerMathPlugins) { |
76 if (registerMathPlugins) { |
77 registerMathPlugins(invocationPlugins, useFMAIntrinsics); |
77 registerMathPlugins(invocationPlugins, useFMAIntrinsics); |
78 } |
78 } |
79 if (emitJDK9StringSubstitutions) { |
79 if (emitJDK9StringSubstitutions) { |
80 registerStringLatin1Plugins(invocationPlugins, bytecodeProvider); |
80 registerStringLatin1Plugins(invocationPlugins, replacements); |
81 registerStringUTF16Plugins(invocationPlugins, bytecodeProvider); |
81 registerStringUTF16Plugins(invocationPlugins, replacements); |
82 } |
82 } |
83 registerUnsafePlugins(invocationPlugins, bytecodeProvider); |
83 registerUnsafePlugins(invocationPlugins, replacements); |
84 // This is temporarily disabled until we implement correct emitting of the CAS |
84 // This is temporarily disabled until we implement correct emitting of the CAS |
85 // instructions of the proper width. |
85 // instructions of the proper width. |
86 registerPlatformSpecificUnsafePlugins(invocationPlugins, bytecodeProvider, explicitUnsafeNullChecks, |
86 registerPlatformSpecificUnsafePlugins(invocationPlugins, replacements, explicitUnsafeNullChecks, |
87 new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object}); |
87 new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object}); |
88 } |
88 } |
89 }); |
89 }); |
90 } |
90 } |
91 |
91 |
92 private static void registerIntegerLongPlugins(InvocationPlugins plugins, JavaKind kind, BytecodeProvider bytecodeProvider) { |
92 private static void registerIntegerLongPlugins(InvocationPlugins plugins, JavaKind kind, Replacements replacements) { |
93 Class<?> declaringClass = kind.toBoxedJavaClass(); |
93 Class<?> declaringClass = kind.toBoxedJavaClass(); |
94 Class<?> type = kind.toJavaClass(); |
94 Class<?> type = kind.toJavaClass(); |
95 Registration r = new Registration(plugins, declaringClass, bytecodeProvider); |
95 Registration r = new Registration(plugins, declaringClass, replacements); |
96 r.register1("numberOfLeadingZeros", type, new InvocationPlugin() { |
96 r.register1("numberOfLeadingZeros", type, new InvocationPlugin() { |
97 @Override |
97 @Override |
98 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { |
98 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) { |
99 ValueNode folded = AArch64CountLeadingZerosNode.tryFold(value); |
99 ValueNode folded = AArch64CountLeadingZerosNode.tryFold(value); |
100 if (folded != null) { |
100 if (folded != null) { |
194 return true; |
194 return true; |
195 } |
195 } |
196 }); |
196 }); |
197 } |
197 } |
198 |
198 |
199 private static void registerStringLatin1Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) { |
199 private static void registerStringLatin1Plugins(InvocationPlugins plugins, Replacements replacements) { |
200 if (JavaVersionUtil.JAVA_SPEC >= 9) { |
200 if (JavaVersionUtil.JAVA_SPEC >= 9) { |
201 Registration r = new Registration(plugins, "java.lang.StringLatin1", replacementsBytecodeProvider); |
201 Registration r = new Registration(plugins, "java.lang.StringLatin1", replacements); |
202 r.setAllowOverwrite(true); |
202 r.setAllowOverwrite(true); |
203 r.registerMethodSubstitution(AArch64StringLatin1Substitutions.class, "compareTo", byte[].class, byte[].class); |
203 r.registerMethodSubstitution(AArch64StringLatin1Substitutions.class, "compareTo", byte[].class, byte[].class); |
204 r.registerMethodSubstitution(AArch64StringLatin1Substitutions.class, "compareToUTF16", byte[].class, byte[].class); |
204 r.registerMethodSubstitution(AArch64StringLatin1Substitutions.class, "compareToUTF16", byte[].class, byte[].class); |
205 } |
205 } |
206 } |
206 } |
207 |
207 |
208 private static void registerStringUTF16Plugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) { |
208 private static void registerStringUTF16Plugins(InvocationPlugins plugins, Replacements replacements) { |
209 if (JavaVersionUtil.JAVA_SPEC >= 9) { |
209 if (JavaVersionUtil.JAVA_SPEC >= 9) { |
210 Registration r = new Registration(plugins, "java.lang.StringUTF16", replacementsBytecodeProvider); |
210 Registration r = new Registration(plugins, "java.lang.StringUTF16", replacements); |
211 r.setAllowOverwrite(true); |
211 r.setAllowOverwrite(true); |
212 r.registerMethodSubstitution(AArch64StringUTF16Substitutions.class, "compareTo", byte[].class, byte[].class); |
212 r.registerMethodSubstitution(AArch64StringUTF16Substitutions.class, "compareTo", byte[].class, byte[].class); |
213 r.registerMethodSubstitution(AArch64StringUTF16Substitutions.class, "compareToLatin1", byte[].class, byte[].class); |
213 r.registerMethodSubstitution(AArch64StringUTF16Substitutions.class, "compareToLatin1", byte[].class, byte[].class); |
214 } |
214 } |
215 } |
215 } |
216 |
216 |
217 private static void registerUnsafePlugins(InvocationPlugins plugins, BytecodeProvider replacementsBytecodeProvider) { |
217 private static void registerUnsafePlugins(InvocationPlugins plugins, Replacements replacements) { |
218 registerUnsafePlugins(new Registration(plugins, Unsafe.class), |
218 registerUnsafePlugins(new Registration(plugins, Unsafe.class), |
219 new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object}, "Object"); |
219 new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object}, "Object"); |
220 if (JavaVersionUtil.JAVA_SPEC > 8) { |
220 if (JavaVersionUtil.JAVA_SPEC > 8) { |
221 registerUnsafePlugins(new Registration(plugins, "jdk.internal.misc.Unsafe", replacementsBytecodeProvider), |
221 registerUnsafePlugins(new Registration(plugins, "jdk.internal.misc.Unsafe", replacements), |
222 new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object}, |
222 new JavaKind[]{JavaKind.Int, JavaKind.Long, JavaKind.Object}, |
223 JavaVersionUtil.JAVA_SPEC <= 11 ? "Object" : "Reference"); |
223 JavaVersionUtil.JAVA_SPEC <= 11 ? "Object" : "Reference"); |
224 } |
224 } |
225 } |
225 } |
226 |
226 |