blob: 71f2a66869d6476c15e430df3e7c13850ed95a02 [file] [log] [blame]
Mads Ager418d1ca2017-05-22 09:35:49 +02001// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
2// for details. All rights reserved. Use of this source code is governed by a
3// BSD-style license that can be found in the LICENSE file.
4
5public class Locals {
6
7 private static void noLocals() {
8 System.out.println("There's no local here");
9 }
10
11 private static void unusedLocals() {
12 int i = Integer.MAX_VALUE;
13 System.out.println("Not using local variable");
14 }
15
16 private static void constantLocals(int p) {
17 int c = 5;
18 int v = c + p;
19 System.out.println("c=" + c + ", v=" + v);
20 }
21
22 private static void zeroLocals() {
23 int i = 0;
24 float f = 0.0f;
25 System.out.println("zeroLocals");
26 }
27
28 private static void noFlowOptimization() {
29 int i = 0;
30 if (i == 0) {
31 System.out.println("i == 0");
32 } else {
33 System.out.println("i != 0");
34 }
35 }
36
Sebastien Hertz269d1372017-06-29 14:48:14 +020037 private static void manyLocals() {
38 int i1 = 1;
39 int i2 = 2;
40 int i3 = 3;
41 int i4 = 4;
42 int i5 = 5;
43 int i6 = 6;
44 int i7 = 7;
45 int i8 = 8;
46 int i9 = 9;
47 int i10 = 10;
48 int i11 = 11;
49 int i12 = 12;
50 invokeRange(i6, i5, i4, i3, i2, i1, invokeRange(i12, i11, i10, i9, i8, i7, 0));
51 }
52
53 private static int reverseRange(int a, int b, int c, int d, int e, int f, int g) {
54 return invokeRange(g, f, e, d, c, b, a);
55 }
56
57 private static int invokeRange(int a, int b, int c, int d, int e, int f, int g) {
58 System.out.println(a + b + c + d + e + f + g);
59 return a + b + c + d + e + f + g;
60 }
61
62 private void lotsOfArrayLength() {
63 int lengthOfArray1 = 0;
64 int lengthOfArray2 = 0;
65 int lengthOfArray3 = 0;
66 int lengthOfArray4 = 0;
67 int lengthOfArray5 = 0;
68 int lengthOfArray6 = 0;
69 int lengthOfArray7 = 0;
70 int lengthOfArray8 = 0;
71 int lengthOfArray9 = 0;
72 int lengthOfArray10 = 0;
73 int lengthOfArray11 = 0;
74 int lengthOfArray12 = 0;
75 int lengthOfArray13 = 0;
76 int lengthOfArray14 = 0;
77 int lengthOfArray15 = 0;
78 int lengthOfArray16 = 0;
79
80 // These statements are compiled into new-array in DEX which stores the result in a 4bit
81 // register (0..15).
82 boolean[] array1 = new boolean[1];
83 byte[] array2 = new byte[1];
84 char[] array3 = new char[1];
85 short[] array4 = new short[1];
86 int[] array5 = new int[1];
87 long[] array6 = new long[1];
88 float[] array7 = new float[1];
89 double[] array8 = new double[1];
90 Object[] array9 = new Object[1];
91 String[] array10 = new String[1];
92 String[] array11 = new String[1];
93 String[] array12 = new String[1];
94 String[] array13 = new String[1];
95 String[] array14 = new String[1];
96 String[] array15 = new String[1];
97 String[] array16 = new String[1];
98
99 // 1st breakpoint to capture the IDs of each array.
100 breakpoint();
101
102 // Breakpoint at line below. In DEX, the array-length instruction expects a 4bit register
103 // (0..15). By creating >16 locals, we should cause an intermediate move instruction to
104 // copy/move a high register (>= 16) into a lower register (< 16).
105 // A test should step instruction by instruction and make sure all locals have the correct
106 // value.
107 lengthOfArray1 = array1.length;
108 lengthOfArray2 = array2.length;
109 lengthOfArray3 = array3.length;
110 lengthOfArray4 = array4.length;
111 lengthOfArray5 = array5.length;
112 lengthOfArray6 = array6.length;
113 lengthOfArray7 = array7.length;
114 lengthOfArray8 = array8.length;
115 lengthOfArray9 = array9.length;
116 lengthOfArray10 = array10.length;
117 lengthOfArray11 = array11.length;
118 lengthOfArray12 = array12.length;
119 lengthOfArray13 = array13.length;
120 lengthOfArray14 = array14.length;
121 lengthOfArray15 = array15.length;
122 lengthOfArray16 = array16.length;
123
124 // Use all locals
125 System.out.println(array1);
126 System.out.println(array2);
127 System.out.println(array3);
128 System.out.println(array4);
129 System.out.println(array5);
130 System.out.println(array6);
131 System.out.println(array7);
132 System.out.println(array8);
133 System.out.println(array9);
134 System.out.println(array10);
135 System.out.println(array11);
136 System.out.println(array12);
137 System.out.println(array13);
138 System.out.println(array14);
139 System.out.println(array15);
140 System.out.println(array16);
141
142 System.out.println(lengthOfArray1);
143 System.out.println(lengthOfArray2);
144 System.out.println(lengthOfArray3);
145 System.out.println(lengthOfArray4);
146 System.out.println(lengthOfArray5);
147 System.out.println(lengthOfArray6);
148 System.out.println(lengthOfArray7);
149 System.out.println(lengthOfArray8);
150 System.out.println(lengthOfArray9);
151 System.out.println(lengthOfArray10);
152 System.out.println(lengthOfArray11);
153 System.out.println(lengthOfArray12);
154 System.out.println(lengthOfArray13);
155 System.out.println(lengthOfArray14);
156 System.out.println(lengthOfArray15);
157 System.out.println(lengthOfArray16);
158 }
159
160 // Utility method to set a breakpoint and inspect the stack.
161 private static void breakpoint() {
162 }
163
164 public void foo(int x) {
165 Integer obj = new Integer(x + x);
166 long l = obj.longValue();
167 try {
168 l = obj.longValue();
169 x = (int) l / x;
170 invokerangeLong(l, l, l, l, l, l);
171 sout(x);
172 } catch (ArithmeticException e) {
173 sout(l);
174 } catch (RuntimeException e) {
175 sout(l); // We should not attempt to read the previous definition of 'e' here or below.
176 } catch (Throwable e) {
177 sout(l);
178 }
179 }
180
181 private void sout(long l) {
182 System.out.print(l);
183 }
184
185 private void invokerangeLong(long a, long b, long c, long d, long e, long f) {
186 if (a != d) {
187 throw new RuntimeException("unexpected");
188 }
189 }
190
Ian Zerny1b8279d2017-08-09 13:08:33 +0200191 public static int stepEmptyForLoopBody1(int n) {
192 int i;
193 for (i = 0; i < n; i++) ;
194 return i;
195 }
196
197 public static int stepEmptyForLoopBody2(int n) {
198 int i;
199 for (i = 0; i < n; i++) {
200 // has a line but still empty...
201 }
202 return i;
203 }
204
205 public static int stepNonEmptyForLoopBody(int n) {
206 int i;
207 for (i = 0; i < n; i++)
208 nop();
209 return i;
210 }
211
212 public static void nop() {}
213
Ian Zerny35049302017-08-15 08:05:45 +0200214 public static int tempInCase(int x) {
215 int res = 0;
216 for (int i = 0; i < x; ++i) {
217 int rem = x - i;
218 switch (rem) {
219 case 1:
220 return res;
221 case 5:
222 int tmp = res + x + i;
223 res += tmp;
224 break;
225 case 10:
226 i++;
227 break;
228 default:
229 res += rem;
230 }
231 res += rem % 2;
232 }
233 res *= x;
234 return res;
235 }
236
237 public static int localSwap(int x, int y) {
238 int sum = x + y;
239 {
240 int t = x;
241 x = y;
242 y = t;
243 }
244 return sum + x + y;
245 }
246
Søren Gjesse5d47c7e2017-08-25 10:36:04 +0200247 public static int argumentLiveAtReturn(int x) {
248 switch (x) {
249 case 0:
250 return 0;
251 case 1:
252 return 0;
253 case 2:
254 return 0;
255 case 100:
256 return 1;
257 case 101:
258 return 1;
259 case 102:
260 return 1;
261 }
262 return -1;
263 }
264
Søren Gjessec52bb3d2017-08-25 12:17:44 +0200265 public static int switchRewriteToIfs(int x) {
266 {
267 int t = x + 1;
268 x = t;
269 x = x + x;
270 }
271 switch (x) {
272 case 0:
273 return 0;
274 case 100:
275 return 1;
276 }
277 return -1;
278 }
279
280 public static int switchRewriteToSwitches(int x) {
281 {
282 int t = x + 1;
283 x = t;
284 x = x + x;
285 }
286 switch (x) {
287 case 0:
288 return 0;
289 case 1:
290 return 0;
291 case 2:
292 return 0;
293 case 100:
294 return 1;
295 case 101:
296 return 1;
297 case 102:
298 return 1;
299 }
300 return -1;
301 }
302
Ian Zernycdf81bf2017-08-25 13:18:49 +0200303 public static String regression65039701(boolean createIntNotLong) {
304 Object a = createIntNotLong ? new int[1] : new long[1];
305 if (a instanceof int []) {
306 ((int [])a)[0] = 0;
307 }
308 return "OK";
309 }
310
Ian Zerny73975932017-08-29 07:37:47 +0200311 public static void regression65066975(boolean bit) {
312 nop();
313 if (bit) {
314 nop();
315 } else {
316 nop();
317 }
318 nop();
319 }
320
Mikaël Peltier5d26c9b2017-09-06 17:42:14 +0200321 public static int localConstant(boolean b) {
322 if (b) {
323 int result1 = 1;
324 return result1;
325 } else {
326 int result2 = 2;
327 return result2;
328 }
329 }
330
331 public static int localConstantBis(boolean b) {
332 int result = 0;
333 if (b) {
334 result = 1;
335 } else {
336 result = 2;
337 }
338 return result;
339 }
340
Mikaël Peltier7eb23532017-09-22 14:24:29 +0200341 public static int localTriggeringCSE() {
342 int a = 1;
343 int b = 3;
344 int c = a + b;
345 int d = a + b;
346 return c + d;
347 }
348
Mikaël Peltier8b0b8352017-09-22 14:36:00 +0200349 public static int intAddition(int a, int b, int c) {
350 a += b;
351 b += c;
352 c = a + b;
353 return c;
354 }
355
Mads Ager418d1ca2017-05-22 09:35:49 +0200356 public static void main(String[] args) {
357 noLocals();
358 unusedLocals();
359 constantLocals(10);
360 zeroLocals();
361 noFlowOptimization();
Sebastien Hertz269d1372017-06-29 14:48:14 +0200362 manyLocals();
363 reverseRange(1,2,3,4,5,6,7);
364 new Locals().lotsOfArrayLength();
365 new Locals().foo(21);
Ian Zerny1b8279d2017-08-09 13:08:33 +0200366 stepEmptyForLoopBody1(3);
367 stepEmptyForLoopBody2(3);
368 stepNonEmptyForLoopBody(3);
Ian Zerny35049302017-08-15 08:05:45 +0200369 tempInCase(42);
370 localSwap(1, 2);
Søren Gjesse5d47c7e2017-08-25 10:36:04 +0200371 argumentLiveAtReturn(-1);
Søren Gjessec52bb3d2017-08-25 12:17:44 +0200372 switchRewriteToIfs(1);
373 switchRewriteToSwitches(1);
Ian Zernycdf81bf2017-08-25 13:18:49 +0200374 regression65039701(true);
Ian Zerny73975932017-08-29 07:37:47 +0200375 regression65066975(false);
Mikaël Peltier5d26c9b2017-09-06 17:42:14 +0200376 System.out.println(localConstant(true));
377 System.out.println(localConstantBis(true));
Mikaël Peltier7eb23532017-09-22 14:24:29 +0200378 System.out.println(localTriggeringCSE());
Mikaël Peltier8b0b8352017-09-22 14:36:00 +0200379 System.out.println(intAddition(1, 2, 6));
Mads Ager418d1ca2017-05-22 09:35:49 +0200380 }
Mads Ager418d1ca2017-05-22 09:35:49 +0200381}