blob: 3ccfce4de1d144982b177c8e9215dc20fdbf8b95 [file] [log] [blame]
David Brazdil68427b12015-01-07 19:22:04 +00001/*
Roland Levillain6a92a032015-07-23 12:15:01 +01002 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Alan Leungeaabac92017-08-29 14:05:34 -070016import java.lang.reflect.Method;
David Brazdil68427b12015-01-07 19:22:04 +000017
David Brazdil4846d132015-01-15 19:07:08 +000018public class Main {
David Brazdil9a6f20e2014-12-19 11:17:21 +000019
David Brazdila06d66a2015-05-28 11:14:54 +010020 /// CHECK-START: void Main.InlineVoid() inliner (before)
21 /// CHECK-DAG: <<Const42:i\d+>> IntConstant 42
22 /// CHECK-DAG: InvokeStaticOrDirect
Vladimir Markob554b5a2015-11-06 12:57:55 +000023 /// CHECK-DAG: InvokeStaticOrDirect [<<Const42>>{{(,[ij]\d+)?}}]
David Brazdil9a6f20e2014-12-19 11:17:21 +000024
David Brazdila06d66a2015-05-28 11:14:54 +010025 /// CHECK-START: void Main.InlineVoid() inliner (after)
26 /// CHECK-NOT: InvokeStaticOrDirect
David Brazdil9a6f20e2014-12-19 11:17:21 +000027
28 public static void InlineVoid() {
29 returnVoid();
30 returnVoidWithOneParameter(42);
31 }
32
David Brazdila06d66a2015-05-28 11:14:54 +010033 /// CHECK-START: int Main.InlineParameter(int) inliner (before)
34 /// CHECK-DAG: <<Param:i\d+>> ParameterValue
Vladimir Markob554b5a2015-11-06 12:57:55 +000035 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect [<<Param>>{{(,[ij]\d+)?}}]
David Brazdila06d66a2015-05-28 11:14:54 +010036 /// CHECK-DAG: Return [<<Result>>]
David Brazdil9a6f20e2014-12-19 11:17:21 +000037
David Brazdila06d66a2015-05-28 11:14:54 +010038 /// CHECK-START: int Main.InlineParameter(int) inliner (after)
39 /// CHECK-DAG: <<Param:i\d+>> ParameterValue
40 /// CHECK-DAG: Return [<<Param>>]
David Brazdil9a6f20e2014-12-19 11:17:21 +000041
42 public static int InlineParameter(int a) {
43 return returnParameter(a);
44 }
45
David Brazdila06d66a2015-05-28 11:14:54 +010046 /// CHECK-START: long Main.InlineWideParameter(long) inliner (before)
47 /// CHECK-DAG: <<Param:j\d+>> ParameterValue
Vladimir Markob554b5a2015-11-06 12:57:55 +000048 /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect [<<Param>>{{(,[ij]\d+)?}}]
David Brazdila06d66a2015-05-28 11:14:54 +010049 /// CHECK-DAG: Return [<<Result>>]
David Brazdil9a6f20e2014-12-19 11:17:21 +000050
David Brazdila06d66a2015-05-28 11:14:54 +010051 /// CHECK-START: long Main.InlineWideParameter(long) inliner (after)
52 /// CHECK-DAG: <<Param:j\d+>> ParameterValue
53 /// CHECK-DAG: Return [<<Param>>]
David Brazdil9a6f20e2014-12-19 11:17:21 +000054
55 public static long InlineWideParameter(long a) {
56 return returnWideParameter(a);
57 }
58
David Brazdila06d66a2015-05-28 11:14:54 +010059 /// CHECK-START: java.lang.Object Main.InlineReferenceParameter(java.lang.Object) inliner (before)
60 /// CHECK-DAG: <<Param:l\d+>> ParameterValue
Vladimir Markob554b5a2015-11-06 12:57:55 +000061 /// CHECK-DAG: <<Result:l\d+>> InvokeStaticOrDirect [<<Param>>{{(,[ij]\d+)?}}]
David Brazdila06d66a2015-05-28 11:14:54 +010062 /// CHECK-DAG: Return [<<Result>>]
David Brazdil9a6f20e2014-12-19 11:17:21 +000063
David Brazdila06d66a2015-05-28 11:14:54 +010064 /// CHECK-START: java.lang.Object Main.InlineReferenceParameter(java.lang.Object) inliner (after)
65 /// CHECK-DAG: <<Param:l\d+>> ParameterValue
66 /// CHECK-DAG: Return [<<Param>>]
David Brazdil9a6f20e2014-12-19 11:17:21 +000067
68 public static Object InlineReferenceParameter(Object o) {
69 return returnReferenceParameter(o);
70 }
71
David Brazdila06d66a2015-05-28 11:14:54 +010072 /// CHECK-START: int Main.InlineInt() inliner (before)
73 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect
74 /// CHECK-DAG: Return [<<Result>>]
David Brazdil9a6f20e2014-12-19 11:17:21 +000075
David Brazdila06d66a2015-05-28 11:14:54 +010076 /// CHECK-START: int Main.InlineInt() inliner (after)
77 /// CHECK-DAG: <<Const4:i\d+>> IntConstant 4
78 /// CHECK-DAG: Return [<<Const4>>]
David Brazdil9a6f20e2014-12-19 11:17:21 +000079
80 public static int InlineInt() {
81 return returnInt();
82 }
83
David Brazdila06d66a2015-05-28 11:14:54 +010084 /// CHECK-START: long Main.InlineWide() inliner (before)
85 /// CHECK-DAG: <<Result:j\d+>> InvokeStaticOrDirect
86 /// CHECK-DAG: Return [<<Result>>]
David Brazdil9a6f20e2014-12-19 11:17:21 +000087
David Brazdila06d66a2015-05-28 11:14:54 +010088 /// CHECK-START: long Main.InlineWide() inliner (after)
89 /// CHECK-DAG: <<Const8:j\d+>> LongConstant 8
90 /// CHECK-DAG: Return [<<Const8>>]
David Brazdil9a6f20e2014-12-19 11:17:21 +000091
92 public static long InlineWide() {
93 return returnWide();
94 }
95
David Brazdila06d66a2015-05-28 11:14:54 +010096 /// CHECK-START: int Main.InlineAdd() inliner (before)
97 /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3
98 /// CHECK-DAG: <<Const5:i\d+>> IntConstant 5
99 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect
100 /// CHECK-DAG: Return [<<Result>>]
David Brazdil9a6f20e2014-12-19 11:17:21 +0000101
David Brazdila06d66a2015-05-28 11:14:54 +0100102 /// CHECK-START: int Main.InlineAdd() inliner (after)
Nicolas Geoffraye418dda2015-08-11 20:03:09 -0700103 /// CHECK-DAG: <<Const8:i\d+>> IntConstant 8
104 /// CHECK-DAG: Return [<<Const8>>]
David Brazdil9a6f20e2014-12-19 11:17:21 +0000105
106 public static int InlineAdd() {
107 return returnAdd(3, 5);
108 }
109
David Brazdila06d66a2015-05-28 11:14:54 +0100110 /// CHECK-START: int Main.InlineFieldAccess() inliner (before)
111 /// CHECK-DAG: <<After:i\d+>> InvokeStaticOrDirect
112 /// CHECK-DAG: Return [<<After>>]
David Brazdil9a6f20e2014-12-19 11:17:21 +0000113
David Brazdila06d66a2015-05-28 11:14:54 +0100114 /// CHECK-START: int Main.InlineFieldAccess() inliner (after)
115 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
116 /// CHECK-DAG: <<Before:i\d+>> StaticFieldGet
117 /// CHECK-DAG: <<After:i\d+>> Add [<<Before>>,<<Const1>>]
118 /// CHECK-DAG: StaticFieldSet [{{l\d+}},<<After>>]
119 /// CHECK-DAG: Return [<<After>>]
David Brazdil9a6f20e2014-12-19 11:17:21 +0000120
David Brazdila06d66a2015-05-28 11:14:54 +0100121 /// CHECK-START: int Main.InlineFieldAccess() inliner (after)
122 /// CHECK-NOT: InvokeStaticOrDirect
David Brazdil9a6f20e2014-12-19 11:17:21 +0000123
124 public static int InlineFieldAccess() {
125 return incCounter();
126 }
127
David Brazdil9a6f20e2014-12-19 11:17:21 +0000128 public static int InlineWithControlFlow(boolean cond) {
Alan Leungeaabac92017-08-29 14:05:34 -0700129 try {
130 Class<?> c = Class.forName("Smali");
131 Method m = c.getMethod("InlineWithControlFlow", boolean.class);
132 return (Integer) m.invoke(null, cond);
133 } catch (Throwable t) {
134 throw new RuntimeException(t);
David Brazdil9a6f20e2014-12-19 11:17:21 +0000135 }
David Brazdil9a6f20e2014-12-19 11:17:21 +0000136 }
137
Scott Wakelingd60a1af2015-07-22 14:32:44 +0100138 /// CHECK-START: int Main.returnAbs(int) intrinsics_recognition (before)
139 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect
140 /// CHECK-DAG: Return [<<Result>>]
141
142 /// CHECK-START: int Main.returnAbs(int) intrinsics_recognition (after)
143 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect intrinsic:MathAbsInt
144 /// CHECK-DAG: Return [<<Result>>]
145
146 private static int returnAbs(int i) {
147 return Math.abs(i);
148 }
149
150 /// CHECK-START: int Main.InlinedIntrinsicsAreStillIntrinsic() inliner (before)
151 /// CHECK-DAG: <<ConstMinus1:i\d+>> IntConstant -1
152 /// CHECK-DAG: <<Result:i\d+>> InvokeStaticOrDirect
153 /// CHECK-DAG: Return [<<Result>>]
154
Aart Bik3dad3412018-02-28 12:01:46 -0800155 //
156 // Intrinsic directly simplified into Abs and evaluated!
157 //
Scott Wakelingd60a1af2015-07-22 14:32:44 +0100158 /// CHECK-START: int Main.InlinedIntrinsicsAreStillIntrinsic() inliner (after)
Aart Bik3dad3412018-02-28 12:01:46 -0800159 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
160 /// CHECK-DAG: Return [<<Const1>>]
Scott Wakelingd60a1af2015-07-22 14:32:44 +0100161
162 public static int InlinedIntrinsicsAreStillIntrinsic() {
163 return returnAbs(-1);
164 }
David Brazdil9a6f20e2014-12-19 11:17:21 +0000165
166 private static void returnVoid() {
167 return;
168 }
169
170 private static void returnVoidWithOneParameter(int a) {
171 return;
172 }
173
174 private static int returnParameter(int a) {
175 return a;
176 }
177
178 private static long returnWideParameter(long a) {
179 return a;
180 }
181
182 private static Object returnReferenceParameter(Object o) {
183 return o;
184 }
185
186 private static int returnInt() {
187 return 4;
188 }
189
190 private static long returnWide() {
191 return 8L;
192 }
193
194 private static int returnAdd(int a, int b) {
195 return a + b;
196 }
197
198 private static int returnSub(int a, int b) {
199 return a - b;
200 }
201
202 private static int counter = 42;
203
204 private static int incCounter() {
205 return ++counter;
206 }
David Brazdil4846d132015-01-15 19:07:08 +0000207
208 public static void main(String[] args) {
209 InlineVoid();
210
211 if (InlineInt() != 4) {
212 throw new Error();
213 }
214
215 if (InlineWide() != 8L) {
216 throw new Error();
217 }
218
219 if (InlineParameter(42) != 42) {
220 throw new Error();
221 }
222
223 if (InlineWideParameter(0x100000001L) != 0x100000001L) {
224 throw new Error();
225 }
226
227 if (InlineReferenceParameter(Main.class) != Main.class) {
228 throw new Error();
229 }
230
231 if (InlineAdd() != 8) {
232 throw new Error();
233 }
234
235 if (InlineFieldAccess() != 43 || InlineFieldAccess() != 44) {
236 throw new Error();
237 }
238
239 if (InlineWithControlFlow(true) != 4) {
240 throw new Error();
241 }
242
243 if (InlineWithControlFlow(false) != 2) {
244 throw new Error();
245 }
Scott Wakelingd60a1af2015-07-22 14:32:44 +0100246
247 if (InlinedIntrinsicsAreStillIntrinsic() != 1) {
248 throw new Error();
249 }
250
251 if (returnAbs(-1) != 1) {
252 throw new Error();
253 }
David Brazdil4846d132015-01-15 19:07:08 +0000254 }
David Brazdil9a6f20e2014-12-19 11:17:21 +0000255}