blob: 9f4be6c22799755223d6e179aedc8cd79051b359 [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 }
Mingyao Yange58bdca2016-10-28 11:07:24 -070021 public double getRadius() {
22 return radius;
23 }
Mingyao Yang8df69d42015-10-22 15:40:58 -070024 public double getArea() {
25 return radius * radius * Math.PI;
26 }
27 private double radius;
Mingyao Yangfb8464a2015-11-02 10:56:59 -080028}
Mingyao Yang8df69d42015-10-22 15:40:58 -070029
30class TestClass {
Mingyao Yang8ab1d642015-12-03 14:11:15 -080031 static {
32 sTestClassObj = new TestClass(-1, -2);
33 }
Mingyao Yang8df69d42015-10-22 15:40:58 -070034 TestClass() {
35 }
36 TestClass(int i, int j) {
37 this.i = i;
38 this.j = j;
39 }
40 int i;
41 int j;
42 volatile int k;
43 TestClass next;
Mingyao Yangfb8464a2015-11-02 10:56:59 -080044 String str;
Mingyao Yang8df69d42015-10-22 15:40:58 -070045 static int si;
Mingyao Yang8ab1d642015-12-03 14:11:15 -080046 static TestClass sTestClassObj;
Mingyao Yangfb8464a2015-11-02 10:56:59 -080047}
Mingyao Yang8df69d42015-10-22 15:40:58 -070048
49class SubTestClass extends TestClass {
50 int k;
Mingyao Yangfb8464a2015-11-02 10:56:59 -080051}
Mingyao Yang8df69d42015-10-22 15:40:58 -070052
53class TestClass2 {
54 int i;
55 int j;
Mingyao Yangfb8464a2015-11-02 10:56:59 -080056}
57
David Brazdilecf52df2015-12-14 16:58:08 +000058class TestClass3 {
59 float floatField = 8.0f;
60 boolean test1 = true;
61}
62
Mingyao Yangfb8464a2015-11-02 10:56:59 -080063class Finalizable {
64 static boolean sVisited = false;
65 static final int VALUE = 0xbeef;
66 int i;
67
68 protected void finalize() {
69 if (i != VALUE) {
70 System.out.println("Where is the beef?");
71 }
72 sVisited = true;
73 }
74}
Mingyao Yang8df69d42015-10-22 15:40:58 -070075
Mingyao Yang062157f2016-03-02 10:15:36 -080076interface Filter {
77 public boolean isValid(int i);
78}
79
Mingyao Yang8df69d42015-10-22 15:40:58 -070080public class Main {
81
82 /// CHECK-START: double Main.calcCircleArea(double) load_store_elimination (before)
83 /// CHECK: NewInstance
84 /// CHECK: InstanceFieldSet
85 /// CHECK: InstanceFieldGet
86
87 /// CHECK-START: double Main.calcCircleArea(double) load_store_elimination (after)
Mingyao Yang062157f2016-03-02 10:15:36 -080088 /// CHECK-NOT: NewInstance
Mingyao Yangfb8464a2015-11-02 10:56:59 -080089 /// CHECK-NOT: InstanceFieldSet
Mingyao Yang8df69d42015-10-22 15:40:58 -070090 /// CHECK-NOT: InstanceFieldGet
91
92 static double calcCircleArea(double radius) {
93 return new Circle(radius).getArea();
94 }
95
96 /// CHECK-START: int Main.test1(TestClass, TestClass) load_store_elimination (before)
97 /// CHECK: InstanceFieldSet
98 /// CHECK: InstanceFieldSet
99 /// CHECK: InstanceFieldGet
100 /// CHECK: InstanceFieldGet
101
102 /// CHECK-START: int Main.test1(TestClass, TestClass) load_store_elimination (after)
103 /// CHECK: InstanceFieldSet
104 /// CHECK: InstanceFieldSet
105 /// CHECK-NOT: NullCheck
106 /// CHECK-NOT: InstanceFieldGet
107
108 // Different fields shouldn't alias.
109 static int test1(TestClass obj1, TestClass obj2) {
110 obj1.i = 1;
111 obj2.j = 2;
112 return obj1.i + obj2.j;
113 }
114
115 /// CHECK-START: int Main.test2(TestClass) load_store_elimination (before)
116 /// CHECK: InstanceFieldSet
117 /// CHECK: InstanceFieldSet
118 /// CHECK: InstanceFieldGet
119
120 /// CHECK-START: int Main.test2(TestClass) load_store_elimination (after)
121 /// CHECK: InstanceFieldSet
122 /// CHECK-NOT: NullCheck
123 /// CHECK-NOT: InstanceFieldSet
124 /// CHECK-NOT: InstanceFieldGet
125
126 // Redundant store of the same value.
127 static int test2(TestClass obj) {
128 obj.j = 1;
129 obj.j = 1;
130 return obj.j;
131 }
132
133 /// CHECK-START: int Main.test3(TestClass) load_store_elimination (before)
Mingyao Yang8ab1d642015-12-03 14:11:15 -0800134 /// CHECK: StaticFieldGet
135 /// CHECK: NewInstance
136 /// CHECK: InstanceFieldSet
137 /// CHECK: InstanceFieldSet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700138 /// CHECK: InstanceFieldSet
139 /// CHECK: InstanceFieldSet
140 /// CHECK: InstanceFieldGet
141 /// CHECK: InstanceFieldGet
142 /// CHECK: InstanceFieldGet
143 /// CHECK: InstanceFieldGet
144
145 /// CHECK-START: int Main.test3(TestClass) load_store_elimination (after)
Mingyao Yang8ab1d642015-12-03 14:11:15 -0800146 /// CHECK: StaticFieldGet
147 /// CHECK: NewInstance
148 /// CHECK: InstanceFieldSet
149 /// CHECK: InstanceFieldSet
150 /// CHECK: InstanceFieldSet
151 /// CHECK: InstanceFieldSet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700152 /// CHECK-NOT: InstanceFieldGet
Mingyao Yang8ab1d642015-12-03 14:11:15 -0800153 /// CHECK-NOT: StaticFieldGet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700154
Mingyao Yang8ab1d642015-12-03 14:11:15 -0800155 // A new allocation (even non-singleton) shouldn't alias with pre-existing values.
Mingyao Yang8df69d42015-10-22 15:40:58 -0700156 static int test3(TestClass obj) {
Mingyao Yang8ab1d642015-12-03 14:11:15 -0800157 TestClass obj1 = TestClass.sTestClassObj;
158 TestClass obj2 = new TestClass(); // Cannot alias with obj or obj1 which pre-exist.
159 obj.next = obj2; // Make obj2 a non-singleton.
160 // All stores below need to stay since obj/obj1/obj2 are not singletons.
Mingyao Yang8df69d42015-10-22 15:40:58 -0700161 obj.i = 1;
Mingyao Yang8ab1d642015-12-03 14:11:15 -0800162 obj1.j = 2;
163 // Following stores won't kill values of obj.i and obj1.j.
Mingyao Yang8df69d42015-10-22 15:40:58 -0700164 obj2.i = 3;
165 obj2.j = 4;
Mingyao Yang8ab1d642015-12-03 14:11:15 -0800166 return obj.i + obj1.j + obj2.i + obj2.j;
Mingyao Yang8df69d42015-10-22 15:40:58 -0700167 }
168
169 /// CHECK-START: int Main.test4(TestClass, boolean) load_store_elimination (before)
170 /// CHECK: InstanceFieldSet
171 /// CHECK: InstanceFieldGet
172 /// CHECK: Return
173 /// CHECK: InstanceFieldSet
174
175 /// CHECK-START: int Main.test4(TestClass, boolean) load_store_elimination (after)
176 /// CHECK: InstanceFieldSet
177 /// CHECK-NOT: NullCheck
178 /// CHECK-NOT: InstanceFieldGet
179 /// CHECK: Return
180 /// CHECK: InstanceFieldSet
181
182 // Set and merge the same value in two branches.
183 static int test4(TestClass obj, boolean b) {
184 if (b) {
185 obj.i = 1;
186 } else {
187 obj.i = 1;
188 }
189 return obj.i;
190 }
191
192 /// CHECK-START: int Main.test5(TestClass, boolean) load_store_elimination (before)
193 /// CHECK: InstanceFieldSet
194 /// CHECK: InstanceFieldGet
195 /// CHECK: Return
196 /// CHECK: InstanceFieldSet
197
198 /// CHECK-START: int Main.test5(TestClass, boolean) load_store_elimination (after)
199 /// CHECK: InstanceFieldSet
200 /// CHECK: InstanceFieldGet
201 /// CHECK: Return
202 /// CHECK: InstanceFieldSet
203
204 // Set and merge different values in two branches.
205 static int test5(TestClass obj, boolean b) {
206 if (b) {
207 obj.i = 1;
208 } else {
209 obj.i = 2;
210 }
211 return obj.i;
212 }
213
214 /// CHECK-START: int Main.test6(TestClass, TestClass, boolean) load_store_elimination (before)
215 /// CHECK: InstanceFieldSet
216 /// CHECK: InstanceFieldSet
217 /// CHECK: InstanceFieldSet
218 /// CHECK: InstanceFieldGet
219 /// CHECK: InstanceFieldGet
220
221 /// CHECK-START: int Main.test6(TestClass, TestClass, boolean) load_store_elimination (after)
222 /// CHECK: InstanceFieldSet
223 /// CHECK: InstanceFieldSet
224 /// CHECK: InstanceFieldSet
225 /// CHECK: InstanceFieldGet
226 /// CHECK-NOT: NullCheck
227 /// CHECK-NOT: InstanceFieldGet
228
229 // Setting the same value doesn't clear the value for aliased locations.
230 static int test6(TestClass obj1, TestClass obj2, boolean b) {
231 obj1.i = 1;
232 obj1.j = 2;
233 if (b) {
234 obj2.j = 2;
235 }
236 return obj1.j + obj2.j;
237 }
238
239 /// CHECK-START: int Main.test7(TestClass) load_store_elimination (before)
240 /// CHECK: InstanceFieldSet
241 /// CHECK: InstanceFieldGet
242
243 /// CHECK-START: int Main.test7(TestClass) load_store_elimination (after)
244 /// CHECK: InstanceFieldSet
245 /// CHECK: InstanceFieldGet
246
247 // Invocation should kill values in non-singleton heap locations.
248 static int test7(TestClass obj) {
249 obj.i = 1;
250 System.out.print("");
251 return obj.i;
252 }
253
254 /// CHECK-START: int Main.test8() load_store_elimination (before)
255 /// CHECK: NewInstance
256 /// CHECK: InstanceFieldSet
257 /// CHECK: InvokeVirtual
258 /// CHECK: InstanceFieldGet
259
260 /// CHECK-START: int Main.test8() load_store_elimination (after)
Mingyao Yang062157f2016-03-02 10:15:36 -0800261 /// CHECK-NOT: NewInstance
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800262 /// CHECK-NOT: InstanceFieldSet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700263 /// CHECK: InvokeVirtual
264 /// CHECK-NOT: NullCheck
265 /// CHECK-NOT: InstanceFieldGet
266
267 // Invocation should not kill values in singleton heap locations.
268 static int test8() {
269 TestClass obj = new TestClass();
270 obj.i = 1;
271 System.out.print("");
272 return obj.i;
273 }
274
275 /// CHECK-START: int Main.test9(TestClass) load_store_elimination (before)
276 /// CHECK: NewInstance
277 /// CHECK: InstanceFieldSet
278 /// CHECK: InstanceFieldSet
279 /// CHECK: InstanceFieldGet
280
281 /// CHECK-START: int Main.test9(TestClass) load_store_elimination (after)
282 /// CHECK: NewInstance
283 /// CHECK: InstanceFieldSet
284 /// CHECK: InstanceFieldSet
285 /// CHECK: InstanceFieldGet
286
287 // Invocation should kill values in non-singleton heap locations.
288 static int test9(TestClass obj) {
289 TestClass obj2 = new TestClass();
290 obj2.i = 1;
291 obj.next = obj2;
292 System.out.print("");
293 return obj2.i;
294 }
295
296 /// CHECK-START: int Main.test10(TestClass) load_store_elimination (before)
297 /// CHECK: StaticFieldGet
298 /// CHECK: InstanceFieldGet
299 /// CHECK: StaticFieldSet
300 /// CHECK: InstanceFieldGet
301
302 /// CHECK-START: int Main.test10(TestClass) load_store_elimination (after)
303 /// CHECK: StaticFieldGet
304 /// CHECK: InstanceFieldGet
305 /// CHECK: StaticFieldSet
306 /// CHECK-NOT: NullCheck
307 /// CHECK-NOT: InstanceFieldGet
308
309 // Static fields shouldn't alias with instance fields.
310 static int test10(TestClass obj) {
311 TestClass.si += obj.i;
312 return obj.i;
313 }
314
315 /// CHECK-START: int Main.test11(TestClass) load_store_elimination (before)
316 /// CHECK: InstanceFieldSet
317 /// CHECK: InstanceFieldGet
318
319 /// CHECK-START: int Main.test11(TestClass) load_store_elimination (after)
320 /// CHECK: InstanceFieldSet
321 /// CHECK-NOT: NullCheck
322 /// CHECK-NOT: InstanceFieldGet
323
324 // Loop without heap writes.
325 // obj.i is actually hoisted to the loop pre-header by licm already.
326 static int test11(TestClass obj) {
327 obj.i = 1;
328 int sum = 0;
329 for (int i = 0; i < 10; i++) {
330 sum += obj.i;
331 }
332 return sum;
333 }
334
335 /// CHECK-START: int Main.test12(TestClass, TestClass) load_store_elimination (before)
336 /// CHECK: InstanceFieldSet
337 /// CHECK: InstanceFieldGet
338 /// CHECK: InstanceFieldSet
339
340 /// CHECK-START: int Main.test12(TestClass, TestClass) load_store_elimination (after)
341 /// CHECK: InstanceFieldSet
342 /// CHECK: InstanceFieldGet
343 /// CHECK: InstanceFieldSet
344
345 // Loop with heap writes.
346 static int test12(TestClass obj1, TestClass obj2) {
347 obj1.i = 1;
348 int sum = 0;
349 for (int i = 0; i < 10; i++) {
350 sum += obj1.i;
351 obj2.i = sum;
352 }
353 return sum;
354 }
355
356 /// CHECK-START: int Main.test13(TestClass, TestClass2) load_store_elimination (before)
357 /// CHECK: InstanceFieldSet
358 /// CHECK: InstanceFieldSet
359 /// CHECK: InstanceFieldGet
360 /// CHECK: InstanceFieldGet
361
362 /// CHECK-START: int Main.test13(TestClass, TestClass2) load_store_elimination (after)
363 /// CHECK: InstanceFieldSet
364 /// CHECK: InstanceFieldSet
365 /// CHECK-NOT: NullCheck
366 /// CHECK-NOT: InstanceFieldGet
367
368 // Different classes shouldn't alias.
369 static int test13(TestClass obj1, TestClass2 obj2) {
370 obj1.i = 1;
371 obj2.i = 2;
372 return obj1.i + obj2.i;
373 }
374
375 /// CHECK-START: int Main.test14(TestClass, SubTestClass) load_store_elimination (before)
376 /// CHECK: InstanceFieldSet
377 /// CHECK: InstanceFieldSet
378 /// CHECK: InstanceFieldGet
379
380 /// CHECK-START: int Main.test14(TestClass, SubTestClass) load_store_elimination (after)
381 /// CHECK: InstanceFieldSet
382 /// CHECK: InstanceFieldSet
383 /// CHECK: InstanceFieldGet
384
385 // Subclass may alias with super class.
386 static int test14(TestClass obj1, SubTestClass obj2) {
387 obj1.i = 1;
388 obj2.i = 2;
389 return obj1.i;
390 }
391
392 /// CHECK-START: int Main.test15() load_store_elimination (before)
393 /// CHECK: StaticFieldSet
394 /// CHECK: StaticFieldSet
395 /// CHECK: StaticFieldGet
396
397 /// CHECK-START: int Main.test15() load_store_elimination (after)
398 /// CHECK: <<Const2:i\d+>> IntConstant 2
399 /// CHECK: StaticFieldSet
400 /// CHECK: StaticFieldSet
401 /// CHECK-NOT: StaticFieldGet
402 /// CHECK: Return [<<Const2>>]
403
404 // Static field access from subclass's name.
405 static int test15() {
406 TestClass.si = 1;
407 SubTestClass.si = 2;
408 return TestClass.si;
409 }
410
411 /// CHECK-START: int Main.test16() load_store_elimination (before)
412 /// CHECK: NewInstance
413 /// CHECK: InstanceFieldSet
414 /// CHECK: InstanceFieldSet
415 /// CHECK: InstanceFieldGet
416 /// CHECK: InstanceFieldGet
417
418 /// CHECK-START: int Main.test16() load_store_elimination (after)
Mingyao Yang062157f2016-03-02 10:15:36 -0800419 /// CHECK-NOT: NewInstance
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800420 /// CHECK-NOT: InstanceFieldSet
421 /// CHECK-NOT: InstanceFieldGet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700422
423 // Test inlined constructor.
424 static int test16() {
425 TestClass obj = new TestClass(1, 2);
426 return obj.i + obj.j;
427 }
428
429 /// CHECK-START: int Main.test17() load_store_elimination (before)
430 /// CHECK: NewInstance
431 /// CHECK: InstanceFieldSet
432 /// CHECK: InstanceFieldGet
433
434 /// CHECK-START: int Main.test17() load_store_elimination (after)
435 /// CHECK: <<Const0:i\d+>> IntConstant 0
Mingyao Yang062157f2016-03-02 10:15:36 -0800436 /// CHECK-NOT: NewInstance
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800437 /// CHECK-NOT: InstanceFieldSet
438 /// CHECK-NOT: InstanceFieldGet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700439 /// CHECK: Return [<<Const0>>]
440
441 // Test getting default value.
442 static int test17() {
443 TestClass obj = new TestClass();
444 obj.j = 1;
445 return obj.i;
446 }
447
448 /// CHECK-START: int Main.test18(TestClass) load_store_elimination (before)
449 /// CHECK: InstanceFieldSet
450 /// CHECK: InstanceFieldGet
451
452 /// CHECK-START: int Main.test18(TestClass) load_store_elimination (after)
453 /// CHECK: InstanceFieldSet
454 /// CHECK: InstanceFieldGet
455
456 // Volatile field load/store shouldn't be eliminated.
457 static int test18(TestClass obj) {
458 obj.k = 1;
459 return obj.k;
460 }
461
462 /// CHECK-START: float Main.test19(float[], float[]) load_store_elimination (before)
David Brazdil4833f5a2015-12-16 10:37:39 +0000463 /// CHECK: {{f\d+}} ArrayGet
464 /// CHECK: {{f\d+}} ArrayGet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700465
466 /// CHECK-START: float Main.test19(float[], float[]) load_store_elimination (after)
David Brazdil4833f5a2015-12-16 10:37:39 +0000467 /// CHECK: {{f\d+}} ArrayGet
468 /// CHECK-NOT: {{f\d+}} ArrayGet
Mingyao Yang8df69d42015-10-22 15:40:58 -0700469
David Brazdil4833f5a2015-12-16 10:37:39 +0000470 // I/F, J/D aliasing should not happen any more and LSE should eliminate the load.
Mingyao Yang8df69d42015-10-22 15:40:58 -0700471 static float test19(float[] fa1, float[] fa2) {
472 fa1[0] = fa2[0];
473 return fa1[0];
474 }
475
476 /// CHECK-START: TestClass Main.test20() load_store_elimination (before)
477 /// CHECK: NewInstance
478 /// CHECK: InstanceFieldSet
479
480 /// CHECK-START: TestClass Main.test20() load_store_elimination (after)
481 /// CHECK: NewInstance
482 /// CHECK-NOT: InstanceFieldSet
483
484 // Storing default heap value is redundant if the heap location has the
485 // default heap value.
486 static TestClass test20() {
487 TestClass obj = new TestClass();
488 obj.i = 0;
489 return obj;
490 }
491
Mingyao Yang803cbb92015-12-01 12:24:36 -0800492 /// CHECK-START: void Main.test21(TestClass) load_store_elimination (before)
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800493 /// CHECK: NewInstance
494 /// CHECK: InstanceFieldSet
Mingyao Yang803cbb92015-12-01 12:24:36 -0800495 /// CHECK: InstanceFieldSet
496 /// CHECK: InstanceFieldSet
497 /// CHECK: InstanceFieldGet
498 /// CHECK: InstanceFieldGet
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800499
Mingyao Yang803cbb92015-12-01 12:24:36 -0800500 /// CHECK-START: void Main.test21(TestClass) load_store_elimination (after)
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800501 /// CHECK: NewInstance
502 /// CHECK: InstanceFieldSet
Mingyao Yang803cbb92015-12-01 12:24:36 -0800503 /// CHECK: InstanceFieldSet
504 /// CHECK: InstanceFieldSet
505 /// CHECK: InstanceFieldGet
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800506 /// CHECK: InstanceFieldGet
507
508 // Loop side effects can kill heap values, stores need to be kept in that case.
Mingyao Yang803cbb92015-12-01 12:24:36 -0800509 static void test21(TestClass obj0) {
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800510 TestClass obj = new TestClass();
Mingyao Yang803cbb92015-12-01 12:24:36 -0800511 obj0.str = "abc";
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800512 obj.str = "abc";
513 for (int i = 0; i < 2; i++) {
Mingyao Yang803cbb92015-12-01 12:24:36 -0800514 // Generate some loop side effect that writes into obj.
515 obj.str = "def";
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800516 }
Mingyao Yang803cbb92015-12-01 12:24:36 -0800517 System.out.print(obj0.str.substring(0, 0) + obj.str.substring(0, 0));
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800518 }
519
520 /// CHECK-START: int Main.test22() load_store_elimination (before)
521 /// CHECK: NewInstance
522 /// CHECK: InstanceFieldSet
523 /// CHECK: NewInstance
524 /// CHECK: InstanceFieldSet
525 /// CHECK: InstanceFieldGet
526 /// CHECK: NewInstance
527 /// CHECK: InstanceFieldSet
528 /// CHECK: InstanceFieldGet
529 /// CHECK: InstanceFieldGet
530
531 /// CHECK-START: int Main.test22() load_store_elimination (after)
Mingyao Yang062157f2016-03-02 10:15:36 -0800532 /// CHECK-NOT: NewInstance
Mingyao Yang803cbb92015-12-01 12:24:36 -0800533 /// CHECK-NOT: InstanceFieldSet
Mingyao Yang062157f2016-03-02 10:15:36 -0800534 /// CHECK-NOT: NewInstance
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800535 /// CHECK-NOT: InstanceFieldSet
536 /// CHECK-NOT: InstanceFieldGet
Mingyao Yang062157f2016-03-02 10:15:36 -0800537 /// CHECK-NOT: NewInstance
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800538 /// CHECK-NOT: InstanceFieldSet
Mingyao Yang803cbb92015-12-01 12:24:36 -0800539 /// CHECK-NOT: InstanceFieldGet
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800540 /// CHECK-NOT: InstanceFieldGet
541
Mingyao Yang803cbb92015-12-01 12:24:36 -0800542 // For a singleton, loop side effects can kill its field values only if:
543 // (1) it dominiates the loop header, and
544 // (2) its fields are stored into inside a loop.
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800545 static int test22() {
546 int sum = 0;
547 TestClass obj1 = new TestClass();
Mingyao Yang803cbb92015-12-01 12:24:36 -0800548 obj1.i = 2; // This store can be eliminated since obj1 is never stored into inside a loop.
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800549 for (int i = 0; i < 2; i++) {
550 TestClass obj2 = new TestClass();
Mingyao Yang803cbb92015-12-01 12:24:36 -0800551 obj2.i = 3; // This store can be eliminated since the singleton is inside the loop.
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800552 sum += obj2.i;
553 }
554 TestClass obj3 = new TestClass();
Mingyao Yang803cbb92015-12-01 12:24:36 -0800555 obj3.i = 5; // This store can be eliminated since the singleton is created after the loop.
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800556 sum += obj1.i + obj3.i;
557 return sum;
558 }
559
560 /// CHECK-START: int Main.test23(boolean) load_store_elimination (before)
561 /// CHECK: NewInstance
562 /// CHECK: InstanceFieldSet
563 /// CHECK: InstanceFieldGet
564 /// CHECK: InstanceFieldSet
565 /// CHECK: InstanceFieldGet
566 /// CHECK: Return
567 /// CHECK: InstanceFieldGet
568 /// CHECK: InstanceFieldSet
569
570 /// CHECK-START: int Main.test23(boolean) load_store_elimination (after)
571 /// CHECK: NewInstance
572 /// CHECK-NOT: InstanceFieldSet
573 /// CHECK-NOT: InstanceFieldGet
574 /// CHECK: InstanceFieldSet
575 /// CHECK: InstanceFieldGet
576 /// CHECK: Return
577 /// CHECK-NOT: InstanceFieldGet
578 /// CHECK: InstanceFieldSet
579
580 // Test store elimination on merging.
581 static int test23(boolean b) {
582 TestClass obj = new TestClass();
583 obj.i = 3; // This store can be eliminated since the value flows into each branch.
584 if (b) {
585 obj.i += 1; // This store cannot be eliminated due to the merge later.
586 } else {
587 obj.i += 2; // This store cannot be eliminated due to the merge later.
588 }
589 return obj.i;
590 }
591
David Brazdilecf52df2015-12-14 16:58:08 +0000592 /// CHECK-START: float Main.test24() load_store_elimination (before)
593 /// CHECK-DAG: <<True:i\d+>> IntConstant 1
594 /// CHECK-DAG: <<Float8:f\d+>> FloatConstant 8
595 /// CHECK-DAG: <<Float42:f\d+>> FloatConstant 42
596 /// CHECK-DAG: <<Obj:l\d+>> NewInstance
597 /// CHECK-DAG: InstanceFieldSet [<<Obj>>,<<True>>]
598 /// CHECK-DAG: InstanceFieldSet [<<Obj>>,<<Float8>>]
599 /// CHECK-DAG: <<GetTest:z\d+>> InstanceFieldGet [<<Obj>>]
David Brazdilecf52df2015-12-14 16:58:08 +0000600 /// CHECK-DAG: <<GetField:f\d+>> InstanceFieldGet [<<Obj>>]
David Brazdil74eb1b22015-12-14 11:44:01 +0000601 /// CHECK-DAG: <<Select:f\d+>> Select [<<Float42>>,<<GetField>>,<<GetTest>>]
602 /// CHECK-DAG: Return [<<Select>>]
David Brazdilecf52df2015-12-14 16:58:08 +0000603
604 /// CHECK-START: float Main.test24() load_store_elimination (after)
605 /// CHECK-DAG: <<True:i\d+>> IntConstant 1
606 /// CHECK-DAG: <<Float8:f\d+>> FloatConstant 8
607 /// CHECK-DAG: <<Float42:f\d+>> FloatConstant 42
David Brazdil74eb1b22015-12-14 11:44:01 +0000608 /// CHECK-DAG: <<Select:f\d+>> Select [<<Float42>>,<<Float8>>,<<True>>]
609 /// CHECK-DAG: Return [<<Select>>]
David Brazdilecf52df2015-12-14 16:58:08 +0000610
611 static float test24() {
612 float a = 42.0f;
613 TestClass3 obj = new TestClass3();
614 if (obj.test1) {
615 a = obj.floatField;
616 }
617 return a;
618 }
619
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800620 /// CHECK-START: void Main.testFinalizable() load_store_elimination (before)
621 /// CHECK: NewInstance
622 /// CHECK: InstanceFieldSet
623
624 /// CHECK-START: void Main.testFinalizable() load_store_elimination (after)
625 /// CHECK: NewInstance
626 /// CHECK: InstanceFieldSet
627
628 // Allocations and stores into finalizable objects cannot be eliminated.
629 static void testFinalizable() {
630 Finalizable finalizable = new Finalizable();
631 finalizable.i = Finalizable.VALUE;
632 }
633
634 static java.lang.ref.WeakReference<Object> getWeakReference() {
635 return new java.lang.ref.WeakReference<>(new Object());
636 }
637
638 static void testFinalizableByForcingGc() {
639 testFinalizable();
640 java.lang.ref.WeakReference<Object> reference = getWeakReference();
641
642 Runtime runtime = Runtime.getRuntime();
643 for (int i = 0; i < 20; ++i) {
644 runtime.gc();
645 System.runFinalization();
646 try {
647 Thread.sleep(1);
648 } catch (InterruptedException e) {
649 throw new AssertionError(e);
650 }
651
652 // Check to see if the weak reference has been garbage collected.
653 if (reference.get() == null) {
654 // A little bit more sleep time to make sure.
655 try {
656 Thread.sleep(100);
657 } catch (InterruptedException e) {
658 throw new AssertionError(e);
659 }
660 if (!Finalizable.sVisited) {
661 System.out.println("finalize() not called.");
662 }
663 return;
664 }
665 }
666 System.out.println("testFinalizableByForcingGc() failed to force gc.");
667 }
668
Mingyao Yang40bcb932016-02-03 05:46:57 -0800669 /// CHECK-START: int Main.$noinline$testHSelect(boolean) load_store_elimination (before)
Mingyao Yange5c71f92016-02-02 20:10:32 -0800670 /// CHECK: InstanceFieldSet
671 /// CHECK: Select
672
Mingyao Yang40bcb932016-02-03 05:46:57 -0800673 /// CHECK-START: int Main.$noinline$testHSelect(boolean) load_store_elimination (after)
Mingyao Yange5c71f92016-02-02 20:10:32 -0800674 /// CHECK: InstanceFieldSet
675 /// CHECK: Select
676
677 // Test that HSelect creates alias.
Mingyao Yang062157f2016-03-02 10:15:36 -0800678 static int $noinline$testHSelect(boolean b) {
Mingyao Yang40bcb932016-02-03 05:46:57 -0800679 if (sFlag) {
680 throw new Error();
681 }
Mingyao Yange5c71f92016-02-02 20:10:32 -0800682 TestClass obj = new TestClass();
683 TestClass obj2 = null;
684 obj.i = 0xdead;
685 if (b) {
686 obj2 = obj;
687 }
688 return obj2.i;
689 }
690
Mingyao Yang062157f2016-03-02 10:15:36 -0800691 static int sumWithFilter(int[] array, Filter f) {
692 int sum = 0;
693 for (int i = 0; i < array.length; i++) {
694 if (f.isValid(array[i])) {
695 sum += array[i];
696 }
697 }
698 return sum;
699 }
700
701 /// CHECK-START: int Main.sumWithinRange(int[], int, int) load_store_elimination (before)
702 /// CHECK: NewInstance
703 /// CHECK: InstanceFieldSet
704 /// CHECK: InstanceFieldSet
705 /// CHECK: InstanceFieldGet
706 /// CHECK: InstanceFieldGet
707
708 /// CHECK-START: int Main.sumWithinRange(int[], int, int) load_store_elimination (after)
709 /// CHECK-NOT: NewInstance
710 /// CHECK-NOT: InstanceFieldSet
711 /// CHECK-NOT: InstanceFieldGet
712
713 // A lambda-style allocation can be eliminated after inlining.
714 static int sumWithinRange(int[] array, final int low, final int high) {
715 Filter filter = new Filter() {
716 public boolean isValid(int i) {
717 return (i >= low) && (i <= high);
718 }
719 };
720 return sumWithFilter(array, filter);
721 }
722
Mingyao Yang0a845202016-10-14 16:26:08 -0700723 private static int mI = 0;
724 private static float mF = 0f;
725
726 /// CHECK-START: float Main.testAllocationEliminationWithLoops() load_store_elimination (before)
727 /// CHECK: NewInstance
728 /// CHECK: NewInstance
729 /// CHECK: NewInstance
730
731 /// CHECK-START: float Main.testAllocationEliminationWithLoops() load_store_elimination (after)
732 /// CHECK-NOT: NewInstance
733
734 private static float testAllocationEliminationWithLoops() {
735 for (int i0 = 0; i0 < 5; i0++) {
736 for (int i1 = 0; i1 < 5; i1++) {
737 for (int i2 = 0; i2 < 5; i2++) {
738 int lI0 = ((int) new Integer(((int) new Integer(mI))));
739 if (((boolean) new Boolean(false))) {
740 for (int i3 = 576 - 1; i3 >= 0; i3--) {
741 mF -= 976981405.0f;
742 }
743 }
744 }
745 }
746 }
747 return 1.0f;
748 }
749
Mingyao Yang58d9bfc2016-11-01 13:31:58 -0700750 /// CHECK-START: double Main.getCircleArea(double, boolean) load_store_elimination (before)
751 /// CHECK: NewInstance
752
753 /// CHECK-START: double Main.getCircleArea(double, boolean) load_store_elimination (after)
754 /// CHECK-NOT: NewInstance
755
756 private static double getCircleArea(double radius, boolean b) {
757 double area = 0d;
758 if (b) {
759 area = new Circle(radius).getArea();
760 }
761 return area;
762 }
763
Mingyao Yange58bdca2016-10-28 11:07:24 -0700764 /// CHECK-START: double Main.testDeoptimize(int[], double[], double) load_store_elimination (before)
765 /// CHECK: Deoptimize
766 /// CHECK: NewInstance
767 /// CHECK: Deoptimize
768 /// CHECK: NewInstance
769
770 /// CHECK-START: double Main.testDeoptimize(int[], double[], double) load_store_elimination (after)
771 /// CHECK: Deoptimize
772 /// CHECK: NewInstance
773 /// CHECK: Deoptimize
774 /// CHECK-NOT: NewInstance
775
776 private static double testDeoptimize(int[] iarr, double[] darr, double radius) {
777 iarr[0] = 1; // One HDeoptimize here. Not triggered.
778 iarr[1] = 1;
779 Circle circle1 = new Circle(radius);
780 iarr[2] = 1;
781 darr[0] = circle1.getRadius(); // One HDeoptimize here, which holds circle1 live. Triggered.
782 darr[1] = circle1.getRadius();
783 darr[2] = circle1.getRadius();
784 darr[3] = circle1.getRadius();
785 return new Circle(Math.PI).getArea();
786 }
787
Mingyao Yang062157f2016-03-02 10:15:36 -0800788 static void assertIntEquals(int result, int expected) {
Mingyao Yang8df69d42015-10-22 15:40:58 -0700789 if (expected != result) {
790 throw new Error("Expected: " + expected + ", found: " + result);
791 }
792 }
793
Mingyao Yang062157f2016-03-02 10:15:36 -0800794 static void assertFloatEquals(float result, float expected) {
Mingyao Yang8df69d42015-10-22 15:40:58 -0700795 if (expected != result) {
796 throw new Error("Expected: " + expected + ", found: " + result);
797 }
798 }
799
Mingyao Yang062157f2016-03-02 10:15:36 -0800800 static void assertDoubleEquals(double result, double expected) {
Mingyao Yang8df69d42015-10-22 15:40:58 -0700801 if (expected != result) {
802 throw new Error("Expected: " + expected + ", found: " + result);
803 }
804 }
805
806 public static void main(String[] args) {
807 assertDoubleEquals(Math.PI * Math.PI * Math.PI, calcCircleArea(Math.PI));
808 assertIntEquals(test1(new TestClass(), new TestClass()), 3);
809 assertIntEquals(test2(new TestClass()), 1);
810 TestClass obj1 = new TestClass();
811 TestClass obj2 = new TestClass();
812 obj1.next = obj2;
813 assertIntEquals(test3(obj1), 10);
814 assertIntEquals(test4(new TestClass(), true), 1);
815 assertIntEquals(test4(new TestClass(), false), 1);
816 assertIntEquals(test5(new TestClass(), true), 1);
817 assertIntEquals(test5(new TestClass(), false), 2);
818 assertIntEquals(test6(new TestClass(), new TestClass(), true), 4);
819 assertIntEquals(test6(new TestClass(), new TestClass(), false), 2);
820 assertIntEquals(test7(new TestClass()), 1);
821 assertIntEquals(test8(), 1);
822 obj1 = new TestClass();
823 obj2 = new TestClass();
824 obj1.next = obj2;
825 assertIntEquals(test9(new TestClass()), 1);
826 assertIntEquals(test10(new TestClass(3, 4)), 3);
827 assertIntEquals(TestClass.si, 3);
828 assertIntEquals(test11(new TestClass()), 10);
829 assertIntEquals(test12(new TestClass(), new TestClass()), 10);
830 assertIntEquals(test13(new TestClass(), new TestClass2()), 3);
831 SubTestClass obj3 = new SubTestClass();
832 assertIntEquals(test14(obj3, obj3), 2);
833 assertIntEquals(test15(), 2);
834 assertIntEquals(test16(), 3);
835 assertIntEquals(test17(), 0);
836 assertIntEquals(test18(new TestClass()), 1);
837 float[] fa1 = { 0.8f };
838 float[] fa2 = { 1.8f };
839 assertFloatEquals(test19(fa1, fa2), 1.8f);
840 assertFloatEquals(test20().i, 0);
Mingyao Yang803cbb92015-12-01 12:24:36 -0800841 test21(new TestClass());
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800842 assertIntEquals(test22(), 13);
843 assertIntEquals(test23(true), 4);
844 assertIntEquals(test23(false), 5);
David Brazdilecf52df2015-12-14 16:58:08 +0000845 assertFloatEquals(test24(), 8.0f);
Mingyao Yangfb8464a2015-11-02 10:56:59 -0800846 testFinalizableByForcingGc();
Mingyao Yang40bcb932016-02-03 05:46:57 -0800847 assertIntEquals($noinline$testHSelect(true), 0xdead);
Mingyao Yang062157f2016-03-02 10:15:36 -0800848 int[] array = {2, 5, 9, -1, -3, 10, 8, 4};
849 assertIntEquals(sumWithinRange(array, 1, 5), 11);
Mingyao Yang0a845202016-10-14 16:26:08 -0700850 assertFloatEquals(testAllocationEliminationWithLoops(), 1.0f);
851 assertFloatEquals(mF, 0f);
Mingyao Yang58d9bfc2016-11-01 13:31:58 -0700852 assertDoubleEquals(Math.PI * Math.PI * Math.PI, getCircleArea(Math.PI, true));
853 assertDoubleEquals(0d, getCircleArea(Math.PI, false));
Mingyao Yange58bdca2016-10-28 11:07:24 -0700854
855 int[] iarray = {0, 0, 0};
856 double[] darray = {0d, 0d, 0d};
857 try {
858 assertDoubleEquals(Math.PI * Math.PI * Math.PI, testDeoptimize(iarray, darray, Math.PI));
859 } catch (Exception e) {
860 System.out.println(e);
861 }
862 assertIntEquals(iarray[0], 1);
863 assertIntEquals(iarray[1], 1);
864 assertIntEquals(iarray[2], 1);
865 assertDoubleEquals(darray[0], Math.PI);
866 assertDoubleEquals(darray[1], Math.PI);
867 assertDoubleEquals(darray[2], Math.PI);
Mingyao Yang8df69d42015-10-22 15:40:58 -0700868 }
Mingyao Yang40bcb932016-02-03 05:46:57 -0800869
870 static boolean sFlag;
Mingyao Yang8df69d42015-10-22 15:40:58 -0700871}