blob: d647683869d12349ab1f7eab85c20f0c8b161e98 [file] [log] [blame]
Mingyao Yang8df69d42015-10-22 15:40:58 -07001/*
2 * Copyright (C) 2015 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 */
16
17class Circle {
18 Circle(double radius) {
19 this.radius = radius;
20 }
21 public double getArea() {
22 return radius * radius * Math.PI;
23 }
24 private double radius;
Mingyao Yangfb8464a2015-11-02 10:56:59 -080025}
Mingyao Yang8df69d42015-10-22 15:40:58 -070026
27class TestClass {
Mingyao Yang8ab1d642015-12-03 14:11:15 -080028 static {
29 sTestClassObj = new TestClass(-1, -2);
30 }
Mingyao Yang8df69d42015-10-22 15:40:58 -070031 TestClass() {
32 }
33 TestClass(int i, int j) {
34 this.i = i;
35 this.j = j;
36 }
37 int i;
38 int j;
39 volatile int k;
40 TestClass next;
Mingyao Yangfb8464a2015-11-02 10:56:59 -080041 String str;
Mingyao Yang8df69d42015-10-22 15:40:58 -070042 static int si;
Mingyao Yang8ab1d642015-12-03 14:11:15 -080043 static TestClass sTestClassObj;
Mingyao Yangfb8464a2015-11-02 10:56:59 -080044}
Mingyao Yang8df69d42015-10-22 15:40:58 -070045
46class SubTestClass extends TestClass {
47 int k;
Mingyao Yangfb8464a2015-11-02 10:56:59 -080048}
Mingyao Yang8df69d42015-10-22 15:40:58 -070049
50class TestClass2 {
51 int i;
52 int j;
Mingyao Yangfb8464a2015-11-02 10:56:59 -080053}
54
David Brazdilecf52df2015-12-14 16:58:08 +000055class TestClass3 {
56 float floatField = 8.0f;
57 boolean test1 = true;
58}
59
Mingyao Yangfb8464a2015-11-02 10:56:59 -080060class Finalizable {
61 static boolean sVisited = false;
62 static final int VALUE = 0xbeef;
63 int i;
64
65 protected void finalize() {
66 if (i != VALUE) {
67 System.out.println("Where is the beef?");
68 }
69 sVisited = true;
70 }
71}
Mingyao Yang8df69d42015-10-22 15:40:58 -070072
73public class Main {
74
75 /// CHECK-START: double Main.calcCircleArea(double) load_store_elimination (before)
76 /// CHECK: NewInstance
77 /// CHECK: InstanceFieldSet
78 /// CHECK: InstanceFieldGet
79
80 /// CHECK-START: double Main.calcCircleArea(double) load_store_elimination (after)
81 /// CHECK: NewInstance
Mingyao Yangfb8464a2015-11-02 10:56:59 -080082 /// CHECK-NOT: InstanceFieldSet
Mingyao Yang8df69d42015-10-22 15:40:58 -070083 /// CHECK-NOT: InstanceFieldGet
84
85 static double calcCircleArea(double radius) {
86 return new Circle(radius).getArea();
87 }
88
89 /// CHECK-START: int Main.test1(TestClass, TestClass) load_store_elimination (before)
90 /// CHECK: InstanceFieldSet
91 /// CHECK: InstanceFieldSet
92 /// CHECK: InstanceFieldGet
93 /// CHECK: InstanceFieldGet
94
95 /// CHECK-START: int Main.test1(TestClass, TestClass) load_store_elimination (after)
96 /// CHECK: InstanceFieldSet
97 /// CHECK: InstanceFieldSet
98 /// CHECK-NOT: NullCheck
99 /// CHECK-NOT: InstanceFieldGet
100
101 // Different fields shouldn't alias.
102 static int test1(TestClass obj1, TestClass obj2) {
103 obj1.i = 1;
104 obj2.j = 2;
105 return obj1.i + obj2.j;
106 }
107
108 /// CHECK-START: int Main.test2(TestClass) load_store_elimination (before)
109 /// CHECK: InstanceFieldSet
110 /// CHECK: InstanceFieldSet
111 /// CHECK: InstanceFieldGet
112
113 /// CHECK-START: int Main.test2(TestClass) load_store_elimination (after)
114 /// CHECK: InstanceFieldSet
115 /// CHECK-NOT: NullCheck
116 /// CHECK-NOT: InstanceFieldSet
117 /// CHECK-NOT: InstanceFieldGet
118
119 // Redundant store of the same value.
120 static int test2(TestClass obj) {
121 obj.j = 1;
122 obj.j = 1;
123 return obj.j;
124 }
125
126 /// CHECK-START: int Main.test3(TestClass) load_store_elimination (before)
Mingyao Yang8df69d42015-10-22 15:40:58 -0700127 /// CHECK: NewInstance
Mingyao Yang8ab1d642015-12-03 14:11:15 -0800128 /// CHECK: StaticFieldGet
129 /// CHECK: NewInstance
130 /// CHECK: InstanceFieldSet
131 /// CHECK: InstanceFieldSet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700132 /// CHECK: InstanceFieldSet
133 /// CHECK: InstanceFieldSet
134 /// CHECK: InstanceFieldGet
135 /// CHECK: InstanceFieldGet
136 /// CHECK: InstanceFieldGet
137 /// CHECK: InstanceFieldGet
138
139 /// CHECK-START: int Main.test3(TestClass) load_store_elimination (after)
Mingyao Yang8df69d42015-10-22 15:40:58 -0700140 /// CHECK: NewInstance
Mingyao Yang8ab1d642015-12-03 14:11:15 -0800141 /// CHECK: StaticFieldGet
142 /// CHECK: NewInstance
143 /// CHECK: InstanceFieldSet
144 /// CHECK: InstanceFieldSet
145 /// CHECK: InstanceFieldSet
146 /// CHECK: InstanceFieldSet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700147 /// CHECK-NOT: InstanceFieldGet
Mingyao Yang8ab1d642015-12-03 14:11:15 -0800148 /// CHECK-NOT: StaticFieldGet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700149
Mingyao Yang8ab1d642015-12-03 14:11:15 -0800150 // A new allocation (even non-singleton) shouldn't alias with pre-existing values.
Mingyao Yang8df69d42015-10-22 15:40:58 -0700151 static int test3(TestClass obj) {
Nicolas Geoffray729645a2015-11-19 13:29:02 +0000152 // Do an allocation here to avoid the HLoadClass and HClinitCheck
153 // at the second allocation.
154 new TestClass();
Mingyao Yang8ab1d642015-12-03 14:11:15 -0800155 TestClass obj1 = TestClass.sTestClassObj;
156 TestClass obj2 = new TestClass(); // Cannot alias with obj or obj1 which pre-exist.
157 obj.next = obj2; // Make obj2 a non-singleton.
158 // All stores below need to stay since obj/obj1/obj2 are not singletons.
Mingyao Yang8df69d42015-10-22 15:40:58 -0700159 obj.i = 1;
Mingyao Yang8ab1d642015-12-03 14:11:15 -0800160 obj1.j = 2;
161 // Following stores won't kill values of obj.i and obj1.j.
Mingyao Yang8df69d42015-10-22 15:40:58 -0700162 obj2.i = 3;
163 obj2.j = 4;
Mingyao Yang8ab1d642015-12-03 14:11:15 -0800164 return obj.i + obj1.j + obj2.i + obj2.j;
Mingyao Yang8df69d42015-10-22 15:40:58 -0700165 }
166
167 /// CHECK-START: int Main.test4(TestClass, boolean) load_store_elimination (before)
168 /// CHECK: InstanceFieldSet
169 /// CHECK: InstanceFieldGet
170 /// CHECK: Return
171 /// CHECK: InstanceFieldSet
172
173 /// CHECK-START: int Main.test4(TestClass, boolean) load_store_elimination (after)
174 /// CHECK: InstanceFieldSet
175 /// CHECK-NOT: NullCheck
176 /// CHECK-NOT: InstanceFieldGet
177 /// CHECK: Return
178 /// CHECK: InstanceFieldSet
179
180 // Set and merge the same value in two branches.
181 static int test4(TestClass obj, boolean b) {
182 if (b) {
183 obj.i = 1;
184 } else {
185 obj.i = 1;
186 }
187 return obj.i;
188 }
189
190 /// CHECK-START: int Main.test5(TestClass, boolean) load_store_elimination (before)
191 /// CHECK: InstanceFieldSet
192 /// CHECK: InstanceFieldGet
193 /// CHECK: Return
194 /// CHECK: InstanceFieldSet
195
196 /// CHECK-START: int Main.test5(TestClass, boolean) load_store_elimination (after)
197 /// CHECK: InstanceFieldSet
198 /// CHECK: InstanceFieldGet
199 /// CHECK: Return
200 /// CHECK: InstanceFieldSet
201
202 // Set and merge different values in two branches.
203 static int test5(TestClass obj, boolean b) {
204 if (b) {
205 obj.i = 1;
206 } else {
207 obj.i = 2;
208 }
209 return obj.i;
210 }
211
212 /// CHECK-START: int Main.test6(TestClass, TestClass, boolean) load_store_elimination (before)
213 /// CHECK: InstanceFieldSet
214 /// CHECK: InstanceFieldSet
215 /// CHECK: InstanceFieldSet
216 /// CHECK: InstanceFieldGet
217 /// CHECK: InstanceFieldGet
218
219 /// CHECK-START: int Main.test6(TestClass, TestClass, boolean) load_store_elimination (after)
220 /// CHECK: InstanceFieldSet
221 /// CHECK: InstanceFieldSet
222 /// CHECK: InstanceFieldSet
223 /// CHECK: InstanceFieldGet
224 /// CHECK-NOT: NullCheck
225 /// CHECK-NOT: InstanceFieldGet
226
227 // Setting the same value doesn't clear the value for aliased locations.
228 static int test6(TestClass obj1, TestClass obj2, boolean b) {
229 obj1.i = 1;
230 obj1.j = 2;
231 if (b) {
232 obj2.j = 2;
233 }
234 return obj1.j + obj2.j;
235 }
236
237 /// CHECK-START: int Main.test7(TestClass) load_store_elimination (before)
238 /// CHECK: InstanceFieldSet
239 /// CHECK: InstanceFieldGet
240
241 /// CHECK-START: int Main.test7(TestClass) load_store_elimination (after)
242 /// CHECK: InstanceFieldSet
243 /// CHECK: InstanceFieldGet
244
245 // Invocation should kill values in non-singleton heap locations.
246 static int test7(TestClass obj) {
247 obj.i = 1;
248 System.out.print("");
249 return obj.i;
250 }
251
252 /// CHECK-START: int Main.test8() load_store_elimination (before)
253 /// CHECK: NewInstance
254 /// CHECK: InstanceFieldSet
255 /// CHECK: InvokeVirtual
256 /// CHECK: InstanceFieldGet
257
258 /// CHECK-START: int Main.test8() load_store_elimination (after)
259 /// CHECK: NewInstance
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800260 /// CHECK-NOT: InstanceFieldSet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700261 /// CHECK: InvokeVirtual
262 /// CHECK-NOT: NullCheck
263 /// CHECK-NOT: InstanceFieldGet
264
265 // Invocation should not kill values in singleton heap locations.
266 static int test8() {
267 TestClass obj = new TestClass();
268 obj.i = 1;
269 System.out.print("");
270 return obj.i;
271 }
272
273 /// CHECK-START: int Main.test9(TestClass) load_store_elimination (before)
274 /// CHECK: NewInstance
275 /// CHECK: InstanceFieldSet
276 /// CHECK: InstanceFieldSet
277 /// CHECK: InstanceFieldGet
278
279 /// CHECK-START: int Main.test9(TestClass) load_store_elimination (after)
280 /// CHECK: NewInstance
281 /// CHECK: InstanceFieldSet
282 /// CHECK: InstanceFieldSet
283 /// CHECK: InstanceFieldGet
284
285 // Invocation should kill values in non-singleton heap locations.
286 static int test9(TestClass obj) {
287 TestClass obj2 = new TestClass();
288 obj2.i = 1;
289 obj.next = obj2;
290 System.out.print("");
291 return obj2.i;
292 }
293
294 /// CHECK-START: int Main.test10(TestClass) load_store_elimination (before)
295 /// CHECK: StaticFieldGet
296 /// CHECK: InstanceFieldGet
297 /// CHECK: StaticFieldSet
298 /// CHECK: InstanceFieldGet
299
300 /// CHECK-START: int Main.test10(TestClass) load_store_elimination (after)
301 /// CHECK: StaticFieldGet
302 /// CHECK: InstanceFieldGet
303 /// CHECK: StaticFieldSet
304 /// CHECK-NOT: NullCheck
305 /// CHECK-NOT: InstanceFieldGet
306
307 // Static fields shouldn't alias with instance fields.
308 static int test10(TestClass obj) {
309 TestClass.si += obj.i;
310 return obj.i;
311 }
312
313 /// CHECK-START: int Main.test11(TestClass) load_store_elimination (before)
314 /// CHECK: InstanceFieldSet
315 /// CHECK: InstanceFieldGet
316
317 /// CHECK-START: int Main.test11(TestClass) load_store_elimination (after)
318 /// CHECK: InstanceFieldSet
319 /// CHECK-NOT: NullCheck
320 /// CHECK-NOT: InstanceFieldGet
321
322 // Loop without heap writes.
323 // obj.i is actually hoisted to the loop pre-header by licm already.
324 static int test11(TestClass obj) {
325 obj.i = 1;
326 int sum = 0;
327 for (int i = 0; i < 10; i++) {
328 sum += obj.i;
329 }
330 return sum;
331 }
332
333 /// CHECK-START: int Main.test12(TestClass, TestClass) load_store_elimination (before)
334 /// CHECK: InstanceFieldSet
335 /// CHECK: InstanceFieldGet
336 /// CHECK: InstanceFieldSet
337
338 /// CHECK-START: int Main.test12(TestClass, TestClass) load_store_elimination (after)
339 /// CHECK: InstanceFieldSet
340 /// CHECK: InstanceFieldGet
341 /// CHECK: InstanceFieldSet
342
343 // Loop with heap writes.
344 static int test12(TestClass obj1, TestClass obj2) {
345 obj1.i = 1;
346 int sum = 0;
347 for (int i = 0; i < 10; i++) {
348 sum += obj1.i;
349 obj2.i = sum;
350 }
351 return sum;
352 }
353
354 /// CHECK-START: int Main.test13(TestClass, TestClass2) load_store_elimination (before)
355 /// CHECK: InstanceFieldSet
356 /// CHECK: InstanceFieldSet
357 /// CHECK: InstanceFieldGet
358 /// CHECK: InstanceFieldGet
359
360 /// CHECK-START: int Main.test13(TestClass, TestClass2) load_store_elimination (after)
361 /// CHECK: InstanceFieldSet
362 /// CHECK: InstanceFieldSet
363 /// CHECK-NOT: NullCheck
364 /// CHECK-NOT: InstanceFieldGet
365
366 // Different classes shouldn't alias.
367 static int test13(TestClass obj1, TestClass2 obj2) {
368 obj1.i = 1;
369 obj2.i = 2;
370 return obj1.i + obj2.i;
371 }
372
373 /// CHECK-START: int Main.test14(TestClass, SubTestClass) load_store_elimination (before)
374 /// CHECK: InstanceFieldSet
375 /// CHECK: InstanceFieldSet
376 /// CHECK: InstanceFieldGet
377
378 /// CHECK-START: int Main.test14(TestClass, SubTestClass) load_store_elimination (after)
379 /// CHECK: InstanceFieldSet
380 /// CHECK: InstanceFieldSet
381 /// CHECK: InstanceFieldGet
382
383 // Subclass may alias with super class.
384 static int test14(TestClass obj1, SubTestClass obj2) {
385 obj1.i = 1;
386 obj2.i = 2;
387 return obj1.i;
388 }
389
390 /// CHECK-START: int Main.test15() load_store_elimination (before)
391 /// CHECK: StaticFieldSet
392 /// CHECK: StaticFieldSet
393 /// CHECK: StaticFieldGet
394
395 /// CHECK-START: int Main.test15() load_store_elimination (after)
396 /// CHECK: <<Const2:i\d+>> IntConstant 2
397 /// CHECK: StaticFieldSet
398 /// CHECK: StaticFieldSet
399 /// CHECK-NOT: StaticFieldGet
400 /// CHECK: Return [<<Const2>>]
401
402 // Static field access from subclass's name.
403 static int test15() {
404 TestClass.si = 1;
405 SubTestClass.si = 2;
406 return TestClass.si;
407 }
408
409 /// CHECK-START: int Main.test16() load_store_elimination (before)
410 /// CHECK: NewInstance
411 /// CHECK: InstanceFieldSet
412 /// CHECK: InstanceFieldSet
413 /// CHECK: InstanceFieldGet
414 /// CHECK: InstanceFieldGet
415
416 /// CHECK-START: int Main.test16() load_store_elimination (after)
417 /// CHECK: NewInstance
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800418 /// CHECK-NOT: InstanceFieldSet
419 /// CHECK-NOT: InstanceFieldGet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700420
421 // Test inlined constructor.
422 static int test16() {
423 TestClass obj = new TestClass(1, 2);
424 return obj.i + obj.j;
425 }
426
427 /// CHECK-START: int Main.test17() load_store_elimination (before)
428 /// CHECK: NewInstance
429 /// CHECK: InstanceFieldSet
430 /// CHECK: InstanceFieldGet
431
432 /// CHECK-START: int Main.test17() load_store_elimination (after)
433 /// CHECK: <<Const0:i\d+>> IntConstant 0
434 /// CHECK: NewInstance
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800435 /// CHECK-NOT: InstanceFieldSet
436 /// CHECK-NOT: InstanceFieldGet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700437 /// CHECK: Return [<<Const0>>]
438
439 // Test getting default value.
440 static int test17() {
441 TestClass obj = new TestClass();
442 obj.j = 1;
443 return obj.i;
444 }
445
446 /// CHECK-START: int Main.test18(TestClass) load_store_elimination (before)
447 /// CHECK: InstanceFieldSet
448 /// CHECK: InstanceFieldGet
449
450 /// CHECK-START: int Main.test18(TestClass) load_store_elimination (after)
451 /// CHECK: InstanceFieldSet
452 /// CHECK: InstanceFieldGet
453
454 // Volatile field load/store shouldn't be eliminated.
455 static int test18(TestClass obj) {
456 obj.k = 1;
457 return obj.k;
458 }
459
460 /// CHECK-START: float Main.test19(float[], float[]) load_store_elimination (before)
David Brazdil4833f5a2015-12-16 10:37:39 +0000461 /// CHECK: {{f\d+}} ArrayGet
462 /// CHECK: {{f\d+}} ArrayGet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700463
464 /// CHECK-START: float Main.test19(float[], float[]) load_store_elimination (after)
David Brazdil4833f5a2015-12-16 10:37:39 +0000465 /// CHECK: {{f\d+}} ArrayGet
466 /// CHECK-NOT: {{f\d+}} ArrayGet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700467
David Brazdil4833f5a2015-12-16 10:37:39 +0000468 // I/F, J/D aliasing should not happen any more and LSE should eliminate the load.
Mingyao Yang8df69d42015-10-22 15:40:58 -0700469 static float test19(float[] fa1, float[] fa2) {
470 fa1[0] = fa2[0];
471 return fa1[0];
472 }
473
474 /// CHECK-START: TestClass Main.test20() load_store_elimination (before)
475 /// CHECK: NewInstance
476 /// CHECK: InstanceFieldSet
477
478 /// CHECK-START: TestClass Main.test20() load_store_elimination (after)
479 /// CHECK: NewInstance
480 /// CHECK-NOT: InstanceFieldSet
481
482 // Storing default heap value is redundant if the heap location has the
483 // default heap value.
484 static TestClass test20() {
485 TestClass obj = new TestClass();
486 obj.i = 0;
487 return obj;
488 }
489
Mingyao Yang803cbb92015-12-01 12:24:36 -0800490 /// CHECK-START: void Main.test21(TestClass) load_store_elimination (before)
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800491 /// CHECK: NewInstance
492 /// CHECK: InstanceFieldSet
Mingyao Yang803cbb92015-12-01 12:24:36 -0800493 /// CHECK: InstanceFieldSet
494 /// CHECK: InstanceFieldSet
495 /// CHECK: InstanceFieldGet
496 /// CHECK: InstanceFieldGet
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800497
Mingyao Yang803cbb92015-12-01 12:24:36 -0800498 /// CHECK-START: void Main.test21(TestClass) load_store_elimination (after)
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800499 /// CHECK: NewInstance
500 /// CHECK: InstanceFieldSet
Mingyao Yang803cbb92015-12-01 12:24:36 -0800501 /// CHECK: InstanceFieldSet
502 /// CHECK: InstanceFieldSet
503 /// CHECK: InstanceFieldGet
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800504 /// CHECK: InstanceFieldGet
505
506 // Loop side effects can kill heap values, stores need to be kept in that case.
Mingyao Yang803cbb92015-12-01 12:24:36 -0800507 static void test21(TestClass obj0) {
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800508 TestClass obj = new TestClass();
Mingyao Yang803cbb92015-12-01 12:24:36 -0800509 obj0.str = "abc";
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800510 obj.str = "abc";
511 for (int i = 0; i < 2; i++) {
Mingyao Yang803cbb92015-12-01 12:24:36 -0800512 // Generate some loop side effect that writes into obj.
513 obj.str = "def";
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800514 }
Mingyao Yang803cbb92015-12-01 12:24:36 -0800515 System.out.print(obj0.str.substring(0, 0) + obj.str.substring(0, 0));
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800516 }
517
518 /// CHECK-START: int Main.test22() load_store_elimination (before)
519 /// CHECK: NewInstance
520 /// CHECK: InstanceFieldSet
521 /// CHECK: NewInstance
522 /// CHECK: InstanceFieldSet
523 /// CHECK: InstanceFieldGet
524 /// CHECK: NewInstance
525 /// CHECK: InstanceFieldSet
526 /// CHECK: InstanceFieldGet
527 /// CHECK: InstanceFieldGet
528
529 /// CHECK-START: int Main.test22() load_store_elimination (after)
530 /// CHECK: NewInstance
Mingyao Yang803cbb92015-12-01 12:24:36 -0800531 /// CHECK-NOT: InstanceFieldSet
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800532 /// CHECK: NewInstance
533 /// CHECK-NOT: InstanceFieldSet
534 /// CHECK-NOT: InstanceFieldGet
535 /// CHECK: NewInstance
536 /// CHECK-NOT: InstanceFieldSet
Mingyao Yang803cbb92015-12-01 12:24:36 -0800537 /// CHECK-NOT: InstanceFieldGet
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800538 /// CHECK-NOT: InstanceFieldGet
539
Mingyao Yang803cbb92015-12-01 12:24:36 -0800540 // For a singleton, loop side effects can kill its field values only if:
541 // (1) it dominiates the loop header, and
542 // (2) its fields are stored into inside a loop.
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800543 static int test22() {
544 int sum = 0;
545 TestClass obj1 = new TestClass();
Mingyao Yang803cbb92015-12-01 12:24:36 -0800546 obj1.i = 2; // This store can be eliminated since obj1 is never stored into inside a loop.
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800547 for (int i = 0; i < 2; i++) {
548 TestClass obj2 = new TestClass();
Mingyao Yang803cbb92015-12-01 12:24:36 -0800549 obj2.i = 3; // This store can be eliminated since the singleton is inside the loop.
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800550 sum += obj2.i;
551 }
552 TestClass obj3 = new TestClass();
Mingyao Yang803cbb92015-12-01 12:24:36 -0800553 obj3.i = 5; // This store can be eliminated since the singleton is created after the loop.
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800554 sum += obj1.i + obj3.i;
555 return sum;
556 }
557
558 /// CHECK-START: int Main.test23(boolean) load_store_elimination (before)
559 /// CHECK: NewInstance
560 /// CHECK: InstanceFieldSet
561 /// CHECK: InstanceFieldGet
562 /// CHECK: InstanceFieldSet
563 /// CHECK: InstanceFieldGet
564 /// CHECK: Return
565 /// CHECK: InstanceFieldGet
566 /// CHECK: InstanceFieldSet
567
568 /// CHECK-START: int Main.test23(boolean) load_store_elimination (after)
569 /// CHECK: NewInstance
570 /// CHECK-NOT: InstanceFieldSet
571 /// CHECK-NOT: InstanceFieldGet
572 /// CHECK: InstanceFieldSet
573 /// CHECK: InstanceFieldGet
574 /// CHECK: Return
575 /// CHECK-NOT: InstanceFieldGet
576 /// CHECK: InstanceFieldSet
577
578 // Test store elimination on merging.
579 static int test23(boolean b) {
580 TestClass obj = new TestClass();
581 obj.i = 3; // This store can be eliminated since the value flows into each branch.
582 if (b) {
583 obj.i += 1; // This store cannot be eliminated due to the merge later.
584 } else {
585 obj.i += 2; // This store cannot be eliminated due to the merge later.
586 }
587 return obj.i;
588 }
589
David Brazdilecf52df2015-12-14 16:58:08 +0000590 /// CHECK-START: float Main.test24() load_store_elimination (before)
591 /// CHECK-DAG: <<True:i\d+>> IntConstant 1
592 /// CHECK-DAG: <<Float8:f\d+>> FloatConstant 8
593 /// CHECK-DAG: <<Float42:f\d+>> FloatConstant 42
594 /// CHECK-DAG: <<Obj:l\d+>> NewInstance
595 /// CHECK-DAG: InstanceFieldSet [<<Obj>>,<<True>>]
596 /// CHECK-DAG: InstanceFieldSet [<<Obj>>,<<Float8>>]
597 /// CHECK-DAG: <<GetTest:z\d+>> InstanceFieldGet [<<Obj>>]
David Brazdilecf52df2015-12-14 16:58:08 +0000598 /// CHECK-DAG: <<GetField:f\d+>> InstanceFieldGet [<<Obj>>]
David Brazdil74eb1b22015-12-14 11:44:01 +0000599 /// CHECK-DAG: <<Select:f\d+>> Select [<<Float42>>,<<GetField>>,<<GetTest>>]
600 /// CHECK-DAG: Return [<<Select>>]
David Brazdilecf52df2015-12-14 16:58:08 +0000601
602 /// CHECK-START: float Main.test24() load_store_elimination (after)
603 /// CHECK-DAG: <<True:i\d+>> IntConstant 1
604 /// CHECK-DAG: <<Float8:f\d+>> FloatConstant 8
605 /// CHECK-DAG: <<Float42:f\d+>> FloatConstant 42
David Brazdil74eb1b22015-12-14 11:44:01 +0000606 /// CHECK-DAG: <<Select:f\d+>> Select [<<Float42>>,<<Float8>>,<<True>>]
607 /// CHECK-DAG: Return [<<Select>>]
David Brazdilecf52df2015-12-14 16:58:08 +0000608
609 static float test24() {
610 float a = 42.0f;
611 TestClass3 obj = new TestClass3();
612 if (obj.test1) {
613 a = obj.floatField;
614 }
615 return a;
616 }
617
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800618 /// CHECK-START: void Main.testFinalizable() load_store_elimination (before)
619 /// CHECK: NewInstance
620 /// CHECK: InstanceFieldSet
621
622 /// CHECK-START: void Main.testFinalizable() load_store_elimination (after)
623 /// CHECK: NewInstance
624 /// CHECK: InstanceFieldSet
625
626 // Allocations and stores into finalizable objects cannot be eliminated.
627 static void testFinalizable() {
628 Finalizable finalizable = new Finalizable();
629 finalizable.i = Finalizable.VALUE;
630 }
631
632 static java.lang.ref.WeakReference<Object> getWeakReference() {
633 return new java.lang.ref.WeakReference<>(new Object());
634 }
635
636 static void testFinalizableByForcingGc() {
637 testFinalizable();
638 java.lang.ref.WeakReference<Object> reference = getWeakReference();
639
640 Runtime runtime = Runtime.getRuntime();
641 for (int i = 0; i < 20; ++i) {
642 runtime.gc();
643 System.runFinalization();
644 try {
645 Thread.sleep(1);
646 } catch (InterruptedException e) {
647 throw new AssertionError(e);
648 }
649
650 // Check to see if the weak reference has been garbage collected.
651 if (reference.get() == null) {
652 // A little bit more sleep time to make sure.
653 try {
654 Thread.sleep(100);
655 } catch (InterruptedException e) {
656 throw new AssertionError(e);
657 }
658 if (!Finalizable.sVisited) {
659 System.out.println("finalize() not called.");
660 }
661 return;
662 }
663 }
664 System.out.println("testFinalizableByForcingGc() failed to force gc.");
665 }
666
Mingyao Yange5c71f92016-02-02 20:10:32 -0800667 /// CHECK-START: int Main.testHSelect(boolean) load_store_elimination (before)
668 /// CHECK: InstanceFieldSet
669 /// CHECK: Select
670
671 /// CHECK-START: int Main.testHSelect(boolean) load_store_elimination (after)
672 /// CHECK: InstanceFieldSet
673 /// CHECK: Select
674
675 // Test that HSelect creates alias.
676 public static int testHSelect(boolean b) {
677 // Disable inlining.
678 System.out.print("");
679 System.out.print("");
680 System.out.print("");
681 System.out.print("");
682 System.out.print("");
683 System.out.print("");
684 System.out.print("");
685 System.out.print("");
686 System.out.print("");
687 System.out.print("");
688
689 TestClass obj = new TestClass();
690 TestClass obj2 = null;
691 obj.i = 0xdead;
692 if (b) {
693 obj2 = obj;
694 }
695 return obj2.i;
696 }
697
698 public static void assertIntEquals(int result, int expected) {
Mingyao Yang8df69d42015-10-22 15:40:58 -0700699 if (expected != result) {
700 throw new Error("Expected: " + expected + ", found: " + result);
701 }
702 }
703
Mingyao Yange5c71f92016-02-02 20:10:32 -0800704 public static void assertFloatEquals(float result, float expected) {
Mingyao Yang8df69d42015-10-22 15:40:58 -0700705 if (expected != result) {
706 throw new Error("Expected: " + expected + ", found: " + result);
707 }
708 }
709
Mingyao Yange5c71f92016-02-02 20:10:32 -0800710 public static void assertDoubleEquals(double result, double expected) {
Mingyao Yang8df69d42015-10-22 15:40:58 -0700711 if (expected != result) {
712 throw new Error("Expected: " + expected + ", found: " + result);
713 }
714 }
715
716 public static void main(String[] args) {
717 assertDoubleEquals(Math.PI * Math.PI * Math.PI, calcCircleArea(Math.PI));
718 assertIntEquals(test1(new TestClass(), new TestClass()), 3);
719 assertIntEquals(test2(new TestClass()), 1);
720 TestClass obj1 = new TestClass();
721 TestClass obj2 = new TestClass();
722 obj1.next = obj2;
723 assertIntEquals(test3(obj1), 10);
724 assertIntEquals(test4(new TestClass(), true), 1);
725 assertIntEquals(test4(new TestClass(), false), 1);
726 assertIntEquals(test5(new TestClass(), true), 1);
727 assertIntEquals(test5(new TestClass(), false), 2);
728 assertIntEquals(test6(new TestClass(), new TestClass(), true), 4);
729 assertIntEquals(test6(new TestClass(), new TestClass(), false), 2);
730 assertIntEquals(test7(new TestClass()), 1);
731 assertIntEquals(test8(), 1);
732 obj1 = new TestClass();
733 obj2 = new TestClass();
734 obj1.next = obj2;
735 assertIntEquals(test9(new TestClass()), 1);
736 assertIntEquals(test10(new TestClass(3, 4)), 3);
737 assertIntEquals(TestClass.si, 3);
738 assertIntEquals(test11(new TestClass()), 10);
739 assertIntEquals(test12(new TestClass(), new TestClass()), 10);
740 assertIntEquals(test13(new TestClass(), new TestClass2()), 3);
741 SubTestClass obj3 = new SubTestClass();
742 assertIntEquals(test14(obj3, obj3), 2);
743 assertIntEquals(test15(), 2);
744 assertIntEquals(test16(), 3);
745 assertIntEquals(test17(), 0);
746 assertIntEquals(test18(new TestClass()), 1);
747 float[] fa1 = { 0.8f };
748 float[] fa2 = { 1.8f };
749 assertFloatEquals(test19(fa1, fa2), 1.8f);
750 assertFloatEquals(test20().i, 0);
Mingyao Yang803cbb92015-12-01 12:24:36 -0800751 test21(new TestClass());
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800752 assertIntEquals(test22(), 13);
753 assertIntEquals(test23(true), 4);
754 assertIntEquals(test23(false), 5);
David Brazdilecf52df2015-12-14 16:58:08 +0000755 assertFloatEquals(test24(), 8.0f);
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800756 testFinalizableByForcingGc();
Mingyao Yange5c71f92016-02-02 20:10:32 -0800757 assertIntEquals(testHSelect(true), 0xdead);
Mingyao Yang8df69d42015-10-22 15:40:58 -0700758 }
759}