1 /*
2 * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 import jdk.incubator.code.Reflect;
25 import jdk.incubator.code.Op;
26 import jdk.incubator.code.CodeTransformer;
27 import jdk.incubator.code.analysis.SSA;
28 import jdk.incubator.code.dialect.core.CoreOp;
29 import jdk.incubator.code.dialect.java.FieldRef;
30 import jdk.incubator.code.dialect.java.JavaOp;
31 import jdk.incubator.code.extern.DialectFactory;
32 import jdk.incubator.code.internal.OpBuilder;
33 import jdk.incubator.code.interpreter.Interpreter;
34 import org.junit.jupiter.api.Assertions;
35 import org.junit.jupiter.api.Test;
36
37 import java.lang.invoke.MethodHandles;
38 import java.lang.reflect.Method;
39 import java.util.LinkedHashMap;
40 import java.util.Map;
41 import java.util.Optional;
42 import java.util.stream.Stream;
43
44 /*
45 * @test
46 * @modules jdk.incubator.code
47 * @modules jdk.incubator.code/jdk.incubator.code.internal
48 * @run junit TestCodeBuilder
49 */
50
51 public class TestCodeBuilder {
52
53 @Reflect
54 static void constants() {
55 boolean bool = false;
56 byte b = 1;
57 char c = 'a';
58 short s = 1;
59 int i = 1;
60 long l = 1L;
61 float f = 1.0f;
62 double d = 1.0;
63 String str = "1";
64 Object obj = null;
65 Class<?> klass = Object.class;
66 }
67
68 @Test
69 public void testConstants() {
70 testWithTransforms(getFuncOp("constants"));
71 }
72
73 static record X(int f) {
74 void m() {}
75 }
76
77 @Reflect
78 static void reflect() {
79 X x = new X(1);
80 int i = x.f;
81 x.m();
82 X[] ax = new X[1];
83 int l = ax.length;
84 x = ax[0];
85
86 Object o = x;
87 x = (X) o;
88 if (o instanceof X) {
89 return;
90 }
91 if (o instanceof X(var a)) {
92 return;
93 }
94 }
95
96 @Test
97 public void testReflect() {
98 testWithTransforms(getFuncOp("reflect"));
99 }
100
101 @Reflect
102 static int bodies(int m, int n) {
103 int sum = 0;
104 for (int i = 0; i < m; i++) {
105 for (int j = 0; j < n; j++) {
106 sum += i + j;
107 }
108 }
109 return m > 10 ? sum : 0;
110 }
111
112 @Test
113 public void testBodies() {
114 testWithTransforms(getFuncOp("bodies"));
115 }
116
117 public void testWithTransforms(CoreOp.FuncOp f) {
118 test(f);
119
120 f = f.transform(CodeTransformer.LOWERING_TRANSFORMER);
121 test(f);
122
123 f = SSA.transform(f);
124 test(f);
125 }
126
127 static void test(CoreOp.FuncOp fExpected) {
128 CoreOp.ModuleOp module = OpBuilder.createBuilderFunctions(new LinkedHashMap<>(Map.of(fExpected.funcName(), fExpected)),
129 b -> b.op(JavaOp.fieldLoad(
130 FieldRef.field(JavaOp.class, "JAVA_DIALECT_FACTORY", DialectFactory.class))));
131 CoreOp.FuncOp fActual = (CoreOp.FuncOp) Interpreter.invoke(MethodHandles.lookup(),
132 module.transform(CodeTransformer.LOWERING_TRANSFORMER).functionTable().get(fExpected.funcName()));
133 Assertions.assertEquals(fExpected.toText(), fActual.toText());
134 }
135
136 static CoreOp.FuncOp getFuncOp(String name) {
137 Optional<Method> om = Stream.of(TestCodeBuilder.class.getDeclaredMethods())
138 .filter(m -> m.getName().equals(name))
139 .findFirst();
140
141 Method m = om.get();
142 return Op.ofMethod(m).get();
143 }
144 }