48 import jdk.vm.ci.meta.ResolvedJavaMethod;
49
50 /**
51 * Tests if {@link MethodSubstitution}s are inlined correctly. Most test cases only assert that
52 * there are no remaining invocations in the graph. This is sufficient if the method that is being
53 * substituted is a native method. For Java methods, additional checks are necessary.
54 */
55 public abstract class MethodSubstitutionTest extends GraalCompilerTest {
56
57 protected StructuredGraph testGraph(final String snippet) {
58 return testGraph(snippet, null);
59 }
60
61 @SuppressWarnings("unused")
62 public BasePhase<HighTierContext> createInliningPhase(StructuredGraph graph) {
63 return new InliningPhase(new CanonicalizerPhase());
64 }
65
66 @SuppressWarnings("try")
67 protected StructuredGraph testGraph(final String snippet, String name) {
68 DebugContext debug = getDebugContext();
69 try (DebugContext.Scope s = debug.scope("MethodSubstitutionTest", getResolvedJavaMethod(snippet))) {
70 StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES, debug);
71 HighTierContext context = getDefaultHighTierContext();
72 debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
73 createInliningPhase(graph).apply(graph, context);
74 debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
75 new CanonicalizerPhase().apply(graph, context);
76 new DeadCodeEliminationPhase().apply(graph);
77 // Try to ensure any macro nodes are lowered to expose any resulting invokes
78 if (graph.getNodes().filter(MacroNode.class).isNotEmpty()) {
79 new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
80 }
81 if (graph.getNodes().filter(MacroNode.class).isNotEmpty()) {
82 new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context);
83 }
84 assertNotInGraph(graph, MacroNode.class);
85 if (name != null) {
86 for (Node node : graph.getNodes()) {
87 if (node instanceof Invoke) {
88 Invoke invoke = (Invoke) node;
89 if (invoke.callTarget() instanceof MethodCallTargetNode) {
90 MethodCallTargetNode call = (MethodCallTargetNode) invoke.callTarget();
94
95 }
96 } else {
97 assertNotInGraph(graph, Invoke.class);
98 }
99 return graph;
100 } catch (Throwable e) {
101 throw debug.handle(e);
102 }
103 }
104
105 protected static StructuredGraph assertNotInGraph(StructuredGraph graph, Class<?> clazz) {
106 for (Node node : graph.getNodes()) {
107 if (clazz.isInstance(node)) {
108 fail(node.toString());
109 }
110 }
111 return graph;
112 }
113
114 protected void testSubstitution(String testMethodName, Class<?> intrinsicClass, Class<?> holder, String methodName, Class<?>[] parameterTypes, boolean optional, Object[] args1, Object[] args2) {
115 ResolvedJavaMethod realMethod = getResolvedJavaMethod(holder, methodName, parameterTypes);
116 ResolvedJavaMethod testMethod = getResolvedJavaMethod(testMethodName);
117 StructuredGraph graph = testGraph(testMethodName);
118
119 // Check to see if the resulting graph contains the expected node
120 StructuredGraph replacement = getReplacements().getSubstitution(realMethod, -1, false, null);
121 if (replacement == null && !optional) {
122 assertInGraph(graph, intrinsicClass);
123 }
124
125 // Force compilation
126 InstalledCode code = getCode(testMethod);
127 assert optional || code != null;
128
129 for (int i = 0; i < args1.length; i++) {
130 Object arg1 = args1[i];
131 Object arg2 = args2[i];
132 Object expected = invokeSafe(realMethod, null, arg1, arg2);
133 // Verify that the original method and the substitution produce the same value
134 assertDeepEquals(expected, invokeSafe(testMethod, null, arg1, arg2));
135 // Verify that the generated code and the original produce the same value
136 assertDeepEquals(expected, executeVarargsSafe(code, arg1, arg2));
137 }
138 }
139
140 protected static StructuredGraph assertInGraph(StructuredGraph graph, Class<?> clazz) {
141 for (Node node : graph.getNodes()) {
142 if (clazz.isInstance(node)) {
143 return graph;
144 }
145 }
146 fail("Graph does not contain a node of class " + clazz.getName());
|
48 import jdk.vm.ci.meta.ResolvedJavaMethod;
49
50 /**
51 * Tests if {@link MethodSubstitution}s are inlined correctly. Most test cases only assert that
52 * there are no remaining invocations in the graph. This is sufficient if the method that is being
53 * substituted is a native method. For Java methods, additional checks are necessary.
54 */
55 public abstract class MethodSubstitutionTest extends GraalCompilerTest {
56
57 protected StructuredGraph testGraph(final String snippet) {
58 return testGraph(snippet, null);
59 }
60
61 @SuppressWarnings("unused")
62 public BasePhase<HighTierContext> createInliningPhase(StructuredGraph graph) {
63 return new InliningPhase(new CanonicalizerPhase());
64 }
65
66 @SuppressWarnings("try")
67 protected StructuredGraph testGraph(final String snippet, String name) {
68 return testGraph(getResolvedJavaMethod(snippet), name);
69 }
70
71 @SuppressWarnings("try")
72 protected StructuredGraph testGraph(final ResolvedJavaMethod method, String name) {
73 DebugContext debug = getDebugContext();
74 try (DebugContext.Scope s = debug.scope("MethodSubstitutionTest", method)) {
75 StructuredGraph graph = parseEager(method, AllowAssumptions.YES, debug);
76 HighTierContext context = getDefaultHighTierContext();
77 debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
78 createInliningPhase(graph).apply(graph, context);
79 debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
80 new CanonicalizerPhase().apply(graph, context);
81 new DeadCodeEliminationPhase().apply(graph);
82 // Try to ensure any macro nodes are lowered to expose any resulting invokes
83 if (graph.getNodes().filter(MacroNode.class).isNotEmpty()) {
84 new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
85 }
86 if (graph.getNodes().filter(MacroNode.class).isNotEmpty()) {
87 new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, context);
88 }
89 assertNotInGraph(graph, MacroNode.class);
90 if (name != null) {
91 for (Node node : graph.getNodes()) {
92 if (node instanceof Invoke) {
93 Invoke invoke = (Invoke) node;
94 if (invoke.callTarget() instanceof MethodCallTargetNode) {
95 MethodCallTargetNode call = (MethodCallTargetNode) invoke.callTarget();
99
100 }
101 } else {
102 assertNotInGraph(graph, Invoke.class);
103 }
104 return graph;
105 } catch (Throwable e) {
106 throw debug.handle(e);
107 }
108 }
109
110 protected static StructuredGraph assertNotInGraph(StructuredGraph graph, Class<?> clazz) {
111 for (Node node : graph.getNodes()) {
112 if (clazz.isInstance(node)) {
113 fail(node.toString());
114 }
115 }
116 return graph;
117 }
118
119 protected void testSubstitution(String testMethodName, Class<?> intrinsicClass, Class<?> holder, String methodName, Class<?>[] parameterTypes, boolean optional, boolean forceCompilation,
120 Object[] args1, Object[] args2) {
121 ResolvedJavaMethod realMethod = getResolvedJavaMethod(holder, methodName, parameterTypes);
122 ResolvedJavaMethod testMethod = getResolvedJavaMethod(testMethodName);
123 StructuredGraph graph = testGraph(testMethodName);
124
125 // Check to see if the resulting graph contains the expected node
126 StructuredGraph replacement = getReplacements().getSubstitution(realMethod, -1, false, null);
127 if (replacement == null && !optional) {
128 assertInGraph(graph, intrinsicClass);
129 }
130
131 // Force compilation
132 InstalledCode code = getCode(testMethod, null, forceCompilation);
133 assert optional || code != null;
134
135 for (int i = 0; i < args1.length; i++) {
136 Object arg1 = args1[i];
137 Object arg2 = args2[i];
138 Object expected = invokeSafe(realMethod, null, arg1, arg2);
139 // Verify that the original method and the substitution produce the same value
140 assertDeepEquals(expected, invokeSafe(testMethod, null, arg1, arg2));
141 // Verify that the generated code and the original produce the same value
142 assertDeepEquals(expected, executeVarargsSafe(code, arg1, arg2));
143 }
144 }
145
146 protected static StructuredGraph assertInGraph(StructuredGraph graph, Class<?> clazz) {
147 for (Node node : graph.getNodes()) {
148 if (clazz.isInstance(node)) {
149 return graph;
150 }
151 }
152 fail("Graph does not contain a node of class " + clazz.getName());
|