1 /*
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 
17 import java.lang.reflect.Method;
18 
19 class Circle {
Circle(double radius)20   Circle(double radius) {
21     this.radius = radius;
22   }
getRadius()23   public double getRadius() {
24     return radius;
25   }
getArea()26   public double getArea() {
27     return radius * radius * Math.PI;
28   }
29   private double radius;
30 }
31 
32 class TestClass {
33   static {
34     sTestClassObj = new TestClass(-1, -2);
35   }
TestClass()36   TestClass() {
37   }
TestClass(int i, int j)38   TestClass(int i, int j) {
39     this.i = i;
40     this.j = j;
41   }
42   int i;
43   int j;
44   volatile int k;
45   TestClass next;
46   String str;
47   static int si;
48   static TestClass sTestClassObj;
49 }
50 
51 class SubTestClass extends TestClass {
52   int k;
53 }
54 
55 class TestClass2 {
56   int i;
57   int j;
58 }
59 
60 class TestClass3 {
61   float floatField = 8.0f;
62   boolean test1 = true;
63 }
64 
65 class Finalizable {
66   static boolean sVisited = false;
67   static final int VALUE1 = 0xbeef;
68   static final int VALUE2 = 0xcafe;
69   int i;
70 
finalize()71   protected void finalize() {
72     if (i != VALUE1) {
73       System.out.println("Where is the beef?");
74     }
75     sVisited = true;
76   }
77 }
78 
79 interface Filter {
isValid(int i)80   public boolean isValid(int i);
81 }
82 
83 public class Main {
84 
85   /// CHECK-START: double Main.calcCircleArea(double) load_store_elimination (before)
86   /// CHECK: NewInstance
87   /// CHECK: InstanceFieldSet
88   /// CHECK: InstanceFieldGet
89 
90   /// CHECK-START: double Main.calcCircleArea(double) load_store_elimination (after)
91   /// CHECK-NOT: NewInstance
92   /// CHECK-NOT: InstanceFieldSet
93   /// CHECK-NOT: InstanceFieldGet
94 
calcCircleArea(double radius)95   static double calcCircleArea(double radius) {
96     return new Circle(radius).getArea();
97   }
98 
99   /// CHECK-START: int Main.test1(TestClass, TestClass) load_store_elimination (before)
100   /// CHECK: InstanceFieldSet
101   /// CHECK: InstanceFieldSet
102   /// CHECK: InstanceFieldGet
103   /// CHECK: InstanceFieldGet
104 
105   /// CHECK-START: int Main.test1(TestClass, TestClass) load_store_elimination (after)
106   /// CHECK: InstanceFieldSet
107   /// CHECK: InstanceFieldSet
108   /// CHECK-NOT: NullCheck
109   /// CHECK-NOT: InstanceFieldGet
110 
111   // Different fields shouldn't alias.
test1(TestClass obj1, TestClass obj2)112   static int test1(TestClass obj1, TestClass obj2) {
113     obj1.i = 1;
114     obj2.j = 2;
115     return obj1.i + obj2.j;
116   }
117 
118   /// CHECK-START: int Main.test2(TestClass) load_store_elimination (before)
119   /// CHECK: InstanceFieldSet
120   /// CHECK: InstanceFieldSet
121   /// CHECK: InstanceFieldGet
122 
123   /// CHECK-START: int Main.test2(TestClass) load_store_elimination (after)
124   /// CHECK: InstanceFieldSet
125   /// CHECK-NOT: NullCheck
126   /// CHECK-NOT: InstanceFieldSet
127   /// CHECK-NOT: InstanceFieldGet
128 
129   // Redundant store of the same value.
test2(TestClass obj)130   static int test2(TestClass obj) {
131     obj.j = 1;
132     obj.j = 1;
133     return obj.j;
134   }
135 
136   /// CHECK-START: int Main.test3(TestClass) load_store_elimination (before)
137   /// CHECK: StaticFieldGet
138   /// CHECK: NewInstance
139   /// CHECK: InstanceFieldSet
140   /// CHECK: InstanceFieldSet
141   /// CHECK: InstanceFieldSet
142   /// CHECK: InstanceFieldSet
143   /// CHECK: InstanceFieldGet
144   /// CHECK: InstanceFieldGet
145   /// CHECK: InstanceFieldGet
146   /// CHECK: InstanceFieldGet
147 
148   /// CHECK-START: int Main.test3(TestClass) load_store_elimination (after)
149   /// CHECK: StaticFieldGet
150   /// CHECK: NewInstance
151   /// CHECK: InstanceFieldSet
152   /// CHECK: InstanceFieldSet
153   /// CHECK: InstanceFieldSet
154   /// CHECK: InstanceFieldSet
155   /// CHECK-NOT: InstanceFieldGet
156   /// CHECK-NOT: StaticFieldGet
157 
158   // A new allocation (even non-singleton) shouldn't alias with pre-existing values.
test3(TestClass obj)159   static int test3(TestClass obj) {
160     TestClass obj1 = TestClass.sTestClassObj;
161     TestClass obj2 = new TestClass();  // Cannot alias with obj or obj1 which pre-exist.
162     obj.next = obj2;  // Make obj2 a non-singleton.
163     // All stores below need to stay since obj/obj1/obj2 are not singletons.
164     obj.i = 1;
165     obj1.j = 2;
166     // Following stores won't kill values of obj.i and obj1.j.
167     obj2.i = 3;
168     obj2.j = 4;
169     return obj.i + obj1.j + obj2.i + obj2.j;
170   }
171 
172   /// CHECK-START: int Main.test6(TestClass, TestClass, boolean) load_store_elimination (before)
173   /// CHECK: InstanceFieldSet
174   /// CHECK: InstanceFieldSet
175   /// CHECK: InstanceFieldSet
176   /// CHECK: InstanceFieldGet
177   /// CHECK: InstanceFieldGet
178 
179   /// CHECK-START: int Main.test6(TestClass, TestClass, boolean) load_store_elimination (after)
180   /// CHECK: InstanceFieldSet
181   /// CHECK: InstanceFieldSet
182   /// CHECK: InstanceFieldSet
183   /// CHECK: InstanceFieldGet
184   /// CHECK-NOT: NullCheck
185   /// CHECK-NOT: InstanceFieldGet
186 
187   // Setting the same value doesn't clear the value for aliased locations.
test6(TestClass obj1, TestClass obj2, boolean b)188   static int test6(TestClass obj1, TestClass obj2, boolean b) {
189     obj1.i = 1;
190     obj1.j = 2;
191     if (b) {
192       obj2.j = 2;
193     }
194     return obj1.j + obj2.j;
195   }
196 
197   /// CHECK-START: int Main.test7(TestClass) load_store_elimination (before)
198   /// CHECK: InstanceFieldSet
199   /// CHECK: InstanceFieldGet
200 
201   /// CHECK-START: int Main.test7(TestClass) load_store_elimination (after)
202   /// CHECK: InstanceFieldSet
203   /// CHECK: InstanceFieldGet
204 
205   // Invocation should kill values in non-singleton heap locations.
test7(TestClass obj)206   static int test7(TestClass obj) {
207     obj.i = 1;
208     System.out.print("");
209     return obj.i;
210   }
211 
212   /// CHECK-START: int Main.test8() load_store_elimination (before)
213   /// CHECK: NewInstance
214   /// CHECK: InstanceFieldSet
215   /// CHECK: InvokeVirtual
216   /// CHECK: InstanceFieldGet
217 
218   /// CHECK-START: int Main.test8() load_store_elimination (after)
219   /// CHECK-NOT: NewInstance
220   /// CHECK-NOT: InstanceFieldSet
221   /// CHECK: InvokeVirtual
222   /// CHECK-NOT: NullCheck
223   /// CHECK-NOT: InstanceFieldGet
224 
225   // Invocation should not kill values in singleton heap locations.
test8()226   static int test8() {
227     TestClass obj = new TestClass();
228     obj.i = 1;
229     System.out.print("");
230     return obj.i;
231   }
232 
233   /// CHECK-START: int Main.test9(TestClass) load_store_elimination (before)
234   /// CHECK: NewInstance
235   /// CHECK: InstanceFieldSet
236   /// CHECK: InstanceFieldSet
237   /// CHECK: InstanceFieldGet
238 
239   /// CHECK-START: int Main.test9(TestClass) load_store_elimination (after)
240   /// CHECK: NewInstance
241   /// CHECK: InstanceFieldSet
242   /// CHECK: InstanceFieldSet
243   /// CHECK: InstanceFieldGet
244 
245   // Invocation should kill values in non-singleton heap locations.
test9(TestClass obj)246   static int test9(TestClass obj) {
247     TestClass obj2 = new TestClass();
248     obj2.i = 1;
249     obj.next = obj2;
250     System.out.print("");
251     return obj2.i;
252   }
253 
254   /// CHECK-START: int Main.test11(TestClass) load_store_elimination (before)
255   /// CHECK: InstanceFieldSet
256   /// CHECK: InstanceFieldGet
257 
258   /// CHECK-START: int Main.test11(TestClass) load_store_elimination (after)
259   /// CHECK: InstanceFieldSet
260   /// CHECK-NOT: NullCheck
261   /// CHECK-NOT: InstanceFieldGet
262 
263   // Loop without heap writes.
264   // obj.i is actually hoisted to the loop pre-header by licm already.
test11(TestClass obj)265   static int test11(TestClass obj) {
266     obj.i = 1;
267     int sum = 0;
268     for (int i = 0; i < 10; i++) {
269       sum += obj.i;
270     }
271     return sum;
272   }
273 
274   /// CHECK-START: int Main.test12(TestClass, TestClass) load_store_elimination (before)
275   /// CHECK: InstanceFieldSet
276   /// CHECK: InstanceFieldGet
277   /// CHECK: InstanceFieldSet
278 
279   /// CHECK-START: int Main.test12(TestClass, TestClass) load_store_elimination (after)
280   /// CHECK: InstanceFieldSet
281   /// CHECK: InstanceFieldGet
282   /// CHECK: InstanceFieldSet
283 
284   // Loop with heap writes.
test12(TestClass obj1, TestClass obj2)285   static int test12(TestClass obj1, TestClass obj2) {
286     obj1.i = 1;
287     int sum = 0;
288     for (int i = 0; i < 10; i++) {
289       sum += obj1.i;
290       obj2.i = sum;
291     }
292     return sum;
293   }
294 
295   /// CHECK-START: int Main.test13(TestClass, TestClass2) load_store_elimination (before)
296   /// CHECK: InstanceFieldSet
297   /// CHECK: InstanceFieldSet
298   /// CHECK: InstanceFieldGet
299   /// CHECK: InstanceFieldGet
300 
301   /// CHECK-START: int Main.test13(TestClass, TestClass2) load_store_elimination (after)
302   /// CHECK: InstanceFieldSet
303   /// CHECK: InstanceFieldSet
304   /// CHECK-NOT: NullCheck
305   /// CHECK-NOT: InstanceFieldGet
306 
307   // Different classes shouldn't alias.
test13(TestClass obj1, TestClass2 obj2)308   static int test13(TestClass obj1, TestClass2 obj2) {
309     obj1.i = 1;
310     obj2.i = 2;
311     return obj1.i + obj2.i;
312   }
313 
314   /// CHECK-START: int Main.test14(TestClass, SubTestClass) load_store_elimination (before)
315   /// CHECK: InstanceFieldSet
316   /// CHECK: InstanceFieldSet
317   /// CHECK: InstanceFieldGet
318 
319   /// CHECK-START: int Main.test14(TestClass, SubTestClass) load_store_elimination (after)
320   /// CHECK: InstanceFieldSet
321   /// CHECK: InstanceFieldSet
322   /// CHECK: InstanceFieldGet
323 
324   // Subclass may alias with super class.
test14(TestClass obj1, SubTestClass obj2)325   static int test14(TestClass obj1, SubTestClass obj2) {
326     obj1.i = 1;
327     obj2.i = 2;
328     return obj1.i;
329   }
330 
331   /// CHECK-START: int Main.test15() load_store_elimination (before)
332   /// CHECK: StaticFieldSet
333   /// CHECK: StaticFieldSet
334   /// CHECK: StaticFieldGet
335 
336   /// CHECK-START: int Main.test15() load_store_elimination (after)
337   /// CHECK: <<Const2:i\d+>> IntConstant 2
338   /// CHECK: StaticFieldSet
339   /// CHECK-NOT: StaticFieldGet
340   /// CHECK: Return [<<Const2>>]
341 
342   // Static field access from subclass's name.
test15()343   static int test15() {
344     TestClass.si = 1;
345     SubTestClass.si = 2;
346     return TestClass.si;
347   }
348 
349   /// CHECK-START: int Main.test16() load_store_elimination (before)
350   /// CHECK: NewInstance
351   /// CHECK: InstanceFieldSet
352   /// CHECK: InstanceFieldSet
353   /// CHECK: InstanceFieldGet
354   /// CHECK: InstanceFieldGet
355 
356   /// CHECK-START: int Main.test16() load_store_elimination (after)
357   /// CHECK-NOT: NewInstance
358   /// CHECK-NOT: InstanceFieldSet
359   /// CHECK-NOT: InstanceFieldGet
360 
361   // Test inlined constructor.
test16()362   static int test16() {
363     TestClass obj = new TestClass(1, 2);
364     return obj.i + obj.j;
365   }
366 
367   /// CHECK-START: int Main.test17() load_store_elimination (before)
368   /// CHECK: NewInstance
369   /// CHECK: InstanceFieldSet
370   /// CHECK: InstanceFieldGet
371 
372   /// CHECK-START: int Main.test17() load_store_elimination (after)
373   /// CHECK: <<Const0:i\d+>> IntConstant 0
374   /// CHECK-NOT: NewInstance
375   /// CHECK-NOT: InstanceFieldSet
376   /// CHECK-NOT: InstanceFieldGet
377   /// CHECK: Return [<<Const0>>]
378 
379   // Test getting default value.
test17()380   static int test17() {
381     TestClass obj = new TestClass();
382     obj.j = 1;
383     return obj.i;
384   }
385 
386   /// CHECK-START: int Main.test18(TestClass) load_store_elimination (before)
387   /// CHECK: InstanceFieldSet
388   /// CHECK: InstanceFieldGet
389 
390   /// CHECK-START: int Main.test18(TestClass) load_store_elimination (after)
391   /// CHECK: InstanceFieldSet
392   /// CHECK: InstanceFieldGet
393 
394   // Volatile field load/store shouldn't be eliminated.
test18(TestClass obj)395   static int test18(TestClass obj) {
396     obj.k = 1;
397     return obj.k;
398   }
399 
400   /// CHECK-START: float Main.test19(float[], float[]) load_store_elimination (before)
401   /// CHECK:     {{f\d+}} ArrayGet
402   /// CHECK:     {{f\d+}} ArrayGet
403 
404   /// CHECK-START: float Main.test19(float[], float[]) load_store_elimination (after)
405   /// CHECK:     {{f\d+}} ArrayGet
406   /// CHECK-NOT: {{f\d+}} ArrayGet
407 
408   // I/F, J/D aliasing should not happen any more and LSE should eliminate the load.
test19(float[] fa1, float[] fa2)409   static float test19(float[] fa1, float[] fa2) {
410     fa1[0] = fa2[0];
411     return fa1[0];
412   }
413 
414   /// CHECK-START: TestClass Main.test20() load_store_elimination (before)
415   /// CHECK: NewInstance
416   /// CHECK: InstanceFieldSet
417 
418   /// CHECK-START: TestClass Main.test20() load_store_elimination (after)
419   /// CHECK: NewInstance
420   /// CHECK-NOT: InstanceFieldSet
421 
422   // Storing default heap value is redundant if the heap location has the
423   // default heap value.
test20()424   static TestClass test20() {
425     TestClass obj = new TestClass();
426     obj.i = 0;
427     return obj;
428   }
429 
430   /// CHECK-START: void Main.test21(TestClass) load_store_elimination (before)
431   /// CHECK: NewInstance
432   /// CHECK: InstanceFieldSet
433   /// CHECK: InstanceFieldSet
434   /// CHECK: InstanceFieldSet
435   /// CHECK: InstanceFieldGet
436   /// CHECK: InstanceFieldGet
437 
438   /// CHECK-START: void Main.test21(TestClass) load_store_elimination (after)
439   /// CHECK: NewInstance
440   /// CHECK: InstanceFieldSet
441   /// CHECK: InstanceFieldSet
442   /// CHECK: InstanceFieldSet
443   /// CHECK: InstanceFieldGet
444   /// CHECK: InstanceFieldGet
445 
446   // Loop side effects can kill heap values, stores need to be kept in that case.
test21(TestClass obj0)447   static void test21(TestClass obj0) {
448     TestClass obj = new TestClass();
449     obj0.str = "abc";
450     obj.str = "abc";
451     for (int i = 0; i < 2; i++) {
452       // Generate some loop side effect that writes into obj.
453       obj.str = "def";
454     }
455     System.out.print(obj0.str.substring(0, 0) + obj.str.substring(0, 0));
456   }
457 
458   /// CHECK-START: int Main.test22() load_store_elimination (before)
459   /// CHECK: NewInstance
460   /// CHECK: InstanceFieldSet
461   /// CHECK: NewInstance
462   /// CHECK: InstanceFieldSet
463   /// CHECK: InstanceFieldGet
464   /// CHECK: NewInstance
465   /// CHECK: InstanceFieldSet
466   /// CHECK: InstanceFieldGet
467   /// CHECK: InstanceFieldGet
468 
469   /// CHECK-START: int Main.test22() load_store_elimination (after)
470   /// CHECK-NOT: NewInstance
471   /// CHECK-NOT: InstanceFieldSet
472   /// CHECK-NOT: NewInstance
473   /// CHECK-NOT: InstanceFieldSet
474   /// CHECK-NOT: InstanceFieldGet
475   /// CHECK-NOT: NewInstance
476   /// CHECK-NOT: InstanceFieldSet
477   /// CHECK-NOT: InstanceFieldGet
478   /// CHECK-NOT: InstanceFieldGet
479 
480   // For a singleton, loop side effects can kill its field values only if:
481   // (1) it dominiates the loop header, and
482   // (2) its fields are stored into inside a loop.
test22()483   static int test22() {
484     int sum = 0;
485     TestClass obj1 = new TestClass();
486     obj1.i = 2;    // This store can be eliminated since obj1 is never stored into inside a loop.
487     for (int i = 0; i < 2; i++) {
488       TestClass obj2 = new TestClass();
489       obj2.i = 3;  // This store can be eliminated since the singleton is inside the loop.
490       sum += obj2.i;
491     }
492     TestClass obj3 = new TestClass();
493     obj3.i = 5;    // This store can be eliminated since the singleton is created after the loop.
494     sum += obj1.i + obj3.i;
495     return sum;
496   }
497 
498   /// CHECK-START: void Main.testFinalizable() load_store_elimination (before)
499   /// CHECK: NewInstance
500   /// CHECK: InstanceFieldSet
501   /// CHECK: InstanceFieldSet
502 
503   /// CHECK-START: void Main.testFinalizable() load_store_elimination (after)
504   /// CHECK: NewInstance
505   /// CHECK: InstanceFieldSet
506   /// CHECK-NOT: InstanceFieldSet
507 
508   // Allocations of finalizable objects cannot be eliminated.
testFinalizable()509   static void testFinalizable() {
510     Finalizable finalizable = new Finalizable();
511     finalizable.i = Finalizable.VALUE2;
512     finalizable.i = Finalizable.VALUE1;
513   }
514 
getWeakReference()515   static java.lang.ref.WeakReference<Object> getWeakReference() {
516     return new java.lang.ref.WeakReference<>(new Object());
517   }
518 
testFinalizableByForcingGc()519   static void testFinalizableByForcingGc() {
520     testFinalizable();
521     java.lang.ref.WeakReference<Object> reference = getWeakReference();
522 
523     Runtime runtime = Runtime.getRuntime();
524     for (int i = 0; i < 20; ++i) {
525       runtime.gc();
526       System.runFinalization();
527       try {
528         Thread.sleep(1);
529       } catch (InterruptedException e) {
530         throw new AssertionError(e);
531       }
532 
533       // Check to see if the weak reference has been garbage collected.
534       if (reference.get() == null) {
535         // A little bit more sleep time to make sure.
536         try {
537           Thread.sleep(100);
538         } catch (InterruptedException e) {
539           throw new AssertionError(e);
540         }
541         if (!Finalizable.sVisited) {
542           System.out.println("finalize() not called.");
543         }
544         return;
545       }
546     }
547     System.out.println("testFinalizableByForcingGc() failed to force gc.");
548   }
549 
550   /// CHECK-START: int Main.$noinline$testHSelect(boolean) load_store_elimination (before)
551   /// CHECK: InstanceFieldSet
552   /// CHECK: Select
553 
554   /// CHECK-START: int Main.$noinline$testHSelect(boolean) load_store_elimination (after)
555   /// CHECK: InstanceFieldSet
556   /// CHECK: Select
557 
558   // Test that HSelect creates alias.
$noinline$testHSelect(boolean b)559   static int $noinline$testHSelect(boolean b) {
560     if (sFlag) {
561       throw new Error();
562     }
563     TestClass obj = new TestClass();
564     TestClass obj2 = null;
565     obj.i = 0xdead;
566     if (b) {
567       obj2 = obj;
568     }
569     return obj2.i;
570   }
571 
sumWithFilter(int[] array, Filter f)572   static int sumWithFilter(int[] array, Filter f) {
573     int sum = 0;
574     for (int i = 0; i < array.length; i++) {
575       if (f.isValid(array[i])) {
576         sum += array[i];
577       }
578     }
579     return sum;
580   }
581 
582   /// CHECK-START: int Main.sumWithinRange(int[], int, int) load_store_elimination (before)
583   /// CHECK: NewInstance
584   /// CHECK: InstanceFieldSet
585   /// CHECK: InstanceFieldSet
586   /// CHECK: InstanceFieldGet
587   /// CHECK: InstanceFieldGet
588 
589   /// CHECK-START: int Main.sumWithinRange(int[], int, int) load_store_elimination (after)
590   /// CHECK-NOT: NewInstance
591   /// CHECK-NOT: InstanceFieldSet
592   /// CHECK-NOT: InstanceFieldGet
593 
594   // A lambda-style allocation can be eliminated after inlining.
sumWithinRange(int[] array, final int low, final int high)595   static int sumWithinRange(int[] array, final int low, final int high) {
596     Filter filter = new Filter() {
597       public boolean isValid(int i) {
598         return (i >= low) && (i <= high);
599       }
600     };
601     return sumWithFilter(array, filter);
602   }
603 
604   private static int mI = 0;
605   private static float mF = 0f;
606 
607   /// CHECK-START: float Main.testAllocationEliminationWithLoops() load_store_elimination (before)
608   /// CHECK: NewInstance
609   /// CHECK: NewInstance
610   /// CHECK: NewInstance
611 
612   /// CHECK-START: float Main.testAllocationEliminationWithLoops() load_store_elimination (after)
613   /// CHECK-NOT: NewInstance
614 
testAllocationEliminationWithLoops()615   private static float testAllocationEliminationWithLoops() {
616     for (int i0 = 0; i0 < 5; i0++) {
617       for (int i1 = 0; i1 < 5; i1++) {
618         for (int i2 = 0; i2 < 5; i2++) {
619           int lI0 = ((int) new Integer(((int) new Integer(mI))));
620           if (((boolean) new Boolean(false))) {
621             for (int i3 = 576 - 1; i3 >= 0; i3--) {
622               mF -= 976981405.0f;
623             }
624           }
625         }
626       }
627     }
628     return 1.0f;
629   }
630 
631   /// CHECK-START: TestClass2 Main.testStoreStore() load_store_elimination (before)
632   /// CHECK: NewInstance
633   /// CHECK: InstanceFieldSet
634   /// CHECK: InstanceFieldSet
635   /// CHECK: InstanceFieldSet
636   /// CHECK: InstanceFieldSet
637 
638   /// CHECK-START: TestClass2 Main.testStoreStore() load_store_elimination (after)
639   /// CHECK: NewInstance
640   /// CHECK: InstanceFieldSet
641   /// CHECK: InstanceFieldSet
642   /// CHECK-NOT: InstanceFieldSet
643 
testStoreStore()644   private static TestClass2 testStoreStore() {
645     TestClass2 obj = new TestClass2();
646     obj.i = 41;
647     obj.j = 42;
648     obj.i = 41;
649     obj.j = 43;
650     return obj;
651   }
652 
653   /// CHECK-START: void Main.testStoreStore2(TestClass2) load_store_elimination (before)
654   /// CHECK: InstanceFieldSet
655   /// CHECK: InstanceFieldSet
656   /// CHECK: InstanceFieldSet
657   /// CHECK: InstanceFieldSet
658 
659   /// CHECK-START: void Main.testStoreStore2(TestClass2) load_store_elimination (after)
660   /// CHECK: InstanceFieldSet
661   /// CHECK: InstanceFieldSet
662   /// CHECK-NOT: InstanceFieldSet
663 
testStoreStore2(TestClass2 obj)664   private static void testStoreStore2(TestClass2 obj) {
665     obj.i = 41;
666     obj.j = 42;
667     obj.i = 43;
668     obj.j = 44;
669   }
670 
671   /// CHECK-START: void Main.testStoreStore3(TestClass2, boolean) load_store_elimination (before)
672   /// CHECK: InstanceFieldSet
673   /// CHECK: InstanceFieldSet
674   /// CHECK: InstanceFieldSet
675   /// CHECK: InstanceFieldSet
676 
677   /// CHECK-START: void Main.testStoreStore3(TestClass2, boolean) load_store_elimination (after)
678   /// CHECK: InstanceFieldSet
679   /// CHECK: InstanceFieldSet
680   /// CHECK: InstanceFieldSet
681   /// CHECK-NOT: InstanceFieldSet
682 
testStoreStore3(TestClass2 obj, boolean flag)683   private static void testStoreStore3(TestClass2 obj, boolean flag) {
684     obj.i = 41;
685     obj.j = 42;    // redundant since it's overwritten in both branches below.
686     if (flag) {
687       obj.j = 43;
688     } else {
689       obj.j = 44;
690     }
691   }
692 
693   /// CHECK-START: void Main.testStoreStore4() load_store_elimination (before)
694   /// CHECK: StaticFieldSet
695   /// CHECK: StaticFieldSet
696 
697   /// CHECK-START: void Main.testStoreStore4() load_store_elimination (after)
698   /// CHECK: StaticFieldSet
699   /// CHECK-NOT: StaticFieldSet
700 
testStoreStore4()701   private static void testStoreStore4() {
702     TestClass.si = 61;
703     TestClass.si = 62;
704   }
705 
706   /// CHECK-START: int Main.testStoreStore5(TestClass2, TestClass2) load_store_elimination (before)
707   /// CHECK: InstanceFieldSet
708   /// CHECK: InstanceFieldGet
709   /// CHECK: InstanceFieldSet
710 
711   /// CHECK-START: int Main.testStoreStore5(TestClass2, TestClass2) load_store_elimination (after)
712   /// CHECK: InstanceFieldSet
713   /// CHECK: InstanceFieldGet
714   /// CHECK: InstanceFieldSet
715 
testStoreStore5(TestClass2 obj1, TestClass2 obj2)716   private static int testStoreStore5(TestClass2 obj1, TestClass2 obj2) {
717     obj1.i = 71;      // This store is needed since obj2.i may load from it.
718     int i = obj2.i;
719     obj1.i = 72;
720     return i;
721   }
722 
723   /// CHECK-START: int Main.testStoreStore6(TestClass2, TestClass2) load_store_elimination (before)
724   /// CHECK: InstanceFieldSet
725   /// CHECK: InstanceFieldGet
726   /// CHECK: InstanceFieldSet
727 
728   /// CHECK-START: int Main.testStoreStore6(TestClass2, TestClass2) load_store_elimination (after)
729   /// CHECK-NOT: InstanceFieldSet
730   /// CHECK: InstanceFieldGet
731   /// CHECK: InstanceFieldSet
732 
testStoreStore6(TestClass2 obj1, TestClass2 obj2)733   private static int testStoreStore6(TestClass2 obj1, TestClass2 obj2) {
734     obj1.i = 81;      // This store is not needed since obj2.j cannot load from it.
735     int j = obj2.j;
736     obj1.i = 82;
737     return j;
738   }
739 
740   /// CHECK-START: int Main.testNoSideEffects(int[]) load_store_elimination (before)
741   /// CHECK: ArraySet
742   /// CHECK: ArraySet
743   /// CHECK: ArraySet
744   /// CHECK: ArrayGet
745 
746   /// CHECK-START: int Main.testNoSideEffects(int[]) load_store_elimination (after)
747   /// CHECK: ArraySet
748   /// CHECK: ArraySet
749   /// CHECK-NOT: ArraySet
750   /// CHECK-NOT: ArrayGet
751 
testNoSideEffects(int[] array)752   private static int testNoSideEffects(int[] array) {
753     array[0] = 101;
754     array[1] = 102;
755     int bitCount = Integer.bitCount(0x3456);
756     array[1] = 103;
757     return array[0] + bitCount;
758   }
759 
760   /// CHECK-START: void Main.testThrow(TestClass2, java.lang.Exception) load_store_elimination (before)
761   /// CHECK: InstanceFieldSet
762   /// CHECK: Throw
763 
764   /// CHECK-START: void Main.testThrow(TestClass2, java.lang.Exception) load_store_elimination (after)
765   /// CHECK: InstanceFieldSet
766   /// CHECK: Throw
767 
768   // Make sure throw keeps the store.
testThrow(TestClass2 obj, Exception e)769   private static void testThrow(TestClass2 obj, Exception e) throws Exception {
770     obj.i = 55;
771     throw e;
772   }
773 
774   /// CHECK-START: int Main.testStoreStoreWithDeoptimize(int[]) load_store_elimination (before)
775   /// CHECK: NewInstance
776   /// CHECK: InstanceFieldSet
777   /// CHECK: InstanceFieldSet
778   /// CHECK: InstanceFieldSet
779   /// CHECK: InstanceFieldSet
780   /// CHECK: Deoptimize
781   /// CHECK: ArraySet
782   /// CHECK: ArraySet
783   /// CHECK: ArraySet
784   /// CHECK: ArraySet
785   /// CHECK: ArrayGet
786   /// CHECK: ArrayGet
787   /// CHECK: ArrayGet
788   /// CHECK: ArrayGet
789 
790   /// CHECK-START: int Main.testStoreStoreWithDeoptimize(int[]) load_store_elimination (after)
791   /// CHECK: NewInstance
792   /// CHECK: InstanceFieldSet
793   /// CHECK: InstanceFieldSet
794   /// CHECK-NOT: InstanceFieldSet
795   /// CHECK: Deoptimize
796   /// CHECK: ArraySet
797   /// CHECK: ArraySet
798   /// CHECK: ArraySet
799   /// CHECK: ArraySet
800   /// CHECK-NOT: ArrayGet
801 
testStoreStoreWithDeoptimize(int[] arr)802   private static int testStoreStoreWithDeoptimize(int[] arr) {
803     TestClass2 obj = new TestClass2();
804     obj.i = 41;
805     obj.j = 42;
806     obj.i = 41;
807     obj.j = 43;
808     arr[0] = 1;  // One HDeoptimize here.
809     arr[1] = 1;
810     arr[2] = 1;
811     arr[3] = 1;
812     return arr[0] + arr[1] + arr[2] + arr[3];
813   }
814 
815   /// CHECK-START: double Main.getCircleArea(double, boolean) load_store_elimination (before)
816   /// CHECK: NewInstance
817 
818   /// CHECK-START: double Main.getCircleArea(double, boolean) load_store_elimination (after)
819   /// CHECK-NOT: NewInstance
820 
getCircleArea(double radius, boolean b)821   private static double getCircleArea(double radius, boolean b) {
822     double area = 0d;
823     if (b) {
824       area = new Circle(radius).getArea();
825     }
826     return area;
827   }
828 
829   /// CHECK-START: double Main.testDeoptimize(int[], double[], double) load_store_elimination (before)
830   /// CHECK: Deoptimize
831   /// CHECK: NewInstance
832   /// CHECK: Deoptimize
833   /// CHECK: NewInstance
834 
835   /// CHECK-START: double Main.testDeoptimize(int[], double[], double) load_store_elimination (after)
836   /// CHECK: Deoptimize
837   /// CHECK: NewInstance
838   /// CHECK: Deoptimize
839   /// CHECK-NOT: NewInstance
840 
testDeoptimize(int[] iarr, double[] darr, double radius)841   private static double testDeoptimize(int[] iarr, double[] darr, double radius) {
842     iarr[0] = 1;  // One HDeoptimize here. Not triggered.
843     iarr[1] = 1;
844     Circle circle1 = new Circle(radius);
845     iarr[2] = 1;
846     darr[0] = circle1.getRadius();  // One HDeoptimize here, which holds circle1 live. Triggered.
847     darr[1] = circle1.getRadius();
848     darr[2] = circle1.getRadius();
849     darr[3] = circle1.getRadius();
850     return new Circle(Math.PI).getArea();
851   }
852 
853   /// CHECK-START: int Main.testAllocationEliminationOfArray1() load_store_elimination (before)
854   /// CHECK: NewArray
855   /// CHECK: ArraySet
856   /// CHECK: ArraySet
857   /// CHECK: ArrayGet
858   /// CHECK: ArrayGet
859   /// CHECK: ArrayGet
860   /// CHECK: ArrayGet
861 
862   /// CHECK-START: int Main.testAllocationEliminationOfArray1() load_store_elimination (after)
863   /// CHECK-NOT: NewArray
864   /// CHECK-NOT: ArraySet
865   /// CHECK-NOT: ArrayGet
testAllocationEliminationOfArray1()866   private static int testAllocationEliminationOfArray1() {
867     int[] array = new int[4];
868     array[2] = 4;
869     array[3] = 7;
870     return array[0] + array[1] + array[2] + array[3];
871   }
872 
873   /// CHECK-START: int Main.testAllocationEliminationOfArray2() load_store_elimination (before)
874   /// CHECK: NewArray
875   /// CHECK: ArraySet
876   /// CHECK: ArraySet
877   /// CHECK: ArrayGet
878 
879   /// CHECK-START: int Main.testAllocationEliminationOfArray2() load_store_elimination (after)
880   /// CHECK: NewArray
881   /// CHECK: ArraySet
882   /// CHECK: ArraySet
883   /// CHECK: ArrayGet
testAllocationEliminationOfArray2()884   private static int testAllocationEliminationOfArray2() {
885     // Cannot eliminate array allocation since array is accessed with non-constant
886     // index (only 3 elements to prevent vectorization of the reduction).
887     int[] array = new int[3];
888     array[1] = 4;
889     array[2] = 7;
890     int sum = 0;
891     for (int e : array) {
892       sum += e;
893     }
894     return sum;
895   }
896 
897   /// CHECK-START: int Main.testAllocationEliminationOfArray3(int) load_store_elimination (before)
898   /// CHECK: NewArray
899   /// CHECK: ArraySet
900   /// CHECK: ArrayGet
901 
902   /// CHECK-START: int Main.testAllocationEliminationOfArray3(int) load_store_elimination (after)
903   /// CHECK-NOT: NewArray
904   /// CHECK-NOT: ArraySet
905   /// CHECK-NOT: ArrayGet
testAllocationEliminationOfArray3(int i)906   private static int testAllocationEliminationOfArray3(int i) {
907     int[] array = new int[4];
908     array[i] = 4;
909     return array[i];
910   }
911 
912   /// CHECK-START: int Main.testAllocationEliminationOfArray4(int) load_store_elimination (before)
913   /// CHECK: NewArray
914   /// CHECK: ArraySet
915   /// CHECK: ArraySet
916   /// CHECK: ArrayGet
917   /// CHECK: ArrayGet
918 
919   /// CHECK-START: int Main.testAllocationEliminationOfArray4(int) load_store_elimination (after)
920   /// CHECK: NewArray
921   /// CHECK: ArraySet
922   /// CHECK: ArraySet
923   /// CHECK: ArrayGet
924   /// CHECK-NOT: ArrayGet
testAllocationEliminationOfArray4(int i)925   private static int testAllocationEliminationOfArray4(int i) {
926     // Cannot eliminate array allocation due to index aliasing between 1 and i.
927     int[] array = new int[4];
928     array[1] = 2;
929     array[i] = 4;
930     return array[1] + array[i];
931   }
932 
933   /// CHECK-START: int Main.testAllocationEliminationOfArray5(int) load_store_elimination (before)
934   /// CHECK: NewArray
935   /// CHECK: ArraySet
936   /// CHECK: ArrayGet
937 
938   /// CHECK-START: int Main.testAllocationEliminationOfArray5(int) load_store_elimination (after)
939   /// CHECK: NewArray
940   /// CHECK-NOT: ArraySet
941   /// CHECK-NOT: ArrayGet
testAllocationEliminationOfArray5(int i)942   private static int testAllocationEliminationOfArray5(int i) {
943     // Cannot eliminate array allocation due to unknown i that may
944     // cause NegativeArraySizeException.
945     int[] array = new int[i];
946     array[1] = 12;
947     return array[1];
948   }
949 
950   /// CHECK-START: int Main.testExitMerge(boolean) load_store_elimination (before)
951   /// CHECK: NewInstance
952   /// CHECK: InstanceFieldSet
953   /// CHECK: InstanceFieldGet
954   /// CHECK: Return
955   /// CHECK: InstanceFieldSet
956   /// CHECK: Throw
957 
958   /// CHECK-START: int Main.testExitMerge(boolean) load_store_elimination (after)
959   /// CHECK-NOT: NewInstance
960   /// CHECK-NOT: InstanceFieldSet
961   /// CHECK-NOT: InstanceFieldGet
962   /// CHECK: Return
963   /// CHECK-NOT: InstanceFieldSet
964   /// CHECK: Throw
testExitMerge(boolean cond)965   private static int testExitMerge(boolean cond) {
966     TestClass obj = new TestClass();
967     if (cond) {
968       obj.i = 1;
969       return obj.i + 1;
970     } else {
971       obj.i = 2;
972       throw new Error();
973     }
974   }
975 
976   /// CHECK-START: int Main.testExitMerge2(boolean) load_store_elimination (before)
977   /// CHECK: NewInstance
978   /// CHECK: InstanceFieldSet
979   /// CHECK: InstanceFieldGet
980   /// CHECK: InstanceFieldSet
981   /// CHECK: InstanceFieldGet
982 
983   /// CHECK-START: int Main.testExitMerge2(boolean) load_store_elimination (after)
984   /// CHECK-NOT: NewInstance
985   /// CHECK-NOT: InstanceFieldSet
986   /// CHECK-NOT: InstanceFieldGet
testExitMerge2(boolean cond)987   private static int testExitMerge2(boolean cond) {
988     TestClass obj = new TestClass();
989     int res;
990     if (cond) {
991       obj.i = 1;
992       res = obj.i + 1;
993     } else {
994       obj.i = 2;
995       res = obj.j + 2;
996     }
997     return res;
998   }
999 
1000   /// CHECK-START: void Main.testStoreSameValue() load_store_elimination (before)
1001   /// CHECK: NewArray
1002   /// CHECK: ArrayGet
1003   /// CHECK: ArraySet
1004 
1005   /// CHECK-START: void Main.testStoreSameValue() load_store_elimination (after)
1006   /// CHECK: NewArray
1007   /// CHECK-NOT: ArrayGet
1008   /// CHECK-NOT: ArraySet
testStoreSameValue()1009   private static void testStoreSameValue() {
1010     Object[] array = new Object[2];
1011     sArray = array;
1012     Object obj = array[0];
1013     array[1] = obj;    // store the same value as the defaut value.
1014   }
1015 
1016   static Object[] sArray;
1017 
1018   /// CHECK-START: int Main.testLocalArrayMerge1(boolean) load_store_elimination (before)
1019   /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1020   /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1021   /// CHECK-DAG: <<A:l\d+>>      NewArray
1022   /// CHECK-DAG:                 ArraySet [<<A>>,<<Const0>>,<<Const0>>]
1023   /// CHECK-DAG:                 ArraySet [<<A>>,<<Const0>>,<<Const1>>]
1024   /// CHECK-DAG:                 ArraySet [<<A>>,<<Const0>>,<<Const1>>]
1025   /// CHECK-DAG: <<Get:i\d+>>    ArrayGet [<<A>>,<<Const0>>]
1026   /// CHECK-DAG:                 Return [<<Get>>]
1027   //
1028   /// CHECK-START: int Main.testLocalArrayMerge1(boolean) load_store_elimination (after)
1029   /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1030   /// CHECK-DAG:                 Return [<<Const1>>]
1031   //
1032   /// CHECK-START: int Main.testLocalArrayMerge1(boolean) load_store_elimination (after)
1033   /// CHECK-NOT:                 NewArray
1034   /// CHECK-NOT:                 ArraySet
1035   /// CHECK-NOT:                 ArrayGet
testLocalArrayMerge1(boolean x)1036   private static int testLocalArrayMerge1(boolean x) {
1037     // The explicit store can be removed right away
1038     // since it is equivalent to the default.
1039     int[] a = { 0 };
1040     // The diamond pattern stores/load can be replaced
1041     // by the direct value.
1042     if (x) {
1043       a[0] = 1;
1044     } else {
1045       a[0] = 1;
1046     }
1047     return a[0];
1048   }
1049 
1050   /// CHECK-START: int Main.testLocalArrayMerge2(boolean) load_store_elimination (before)
1051   /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1052   /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1053   /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
1054   /// CHECK-DAG: <<Const3:i\d+>> IntConstant 3
1055   /// CHECK-DAG: <<A:l\d+>>      NewArray
1056   /// CHECK-DAG:                 ArraySet [<<A>>,<<Const0>>,<<Const1>>]
1057   /// CHECK-DAG:                 ArraySet [<<A>>,<<Const0>>,<<Const2>>]
1058   /// CHECK-DAG:                 ArraySet [<<A>>,<<Const0>>,<<Const3>>]
1059   /// CHECK-DAG: <<Get:i\d+>>    ArrayGet [<<A>>,<<Const0>>]
1060   /// CHECK-DAG:                 Return [<<Get>>]
1061   //
1062   /// CHECK-START: int Main.testLocalArrayMerge2(boolean) load_store_elimination (after)
1063   /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1064   /// CHECK-DAG: <<A:l\d+>>      NewArray
1065   /// CHECK-DAG: <<Get:i\d+>>    ArrayGet [<<A>>,<<Const0>>]
1066   /// CHECK-DAG:                 Return [<<Get>>]
1067   //
1068   /// CHECK-START: int Main.testLocalArrayMerge2(boolean) load_store_elimination (after)
1069   /// CHECK-DAG:                 ArraySet
1070   /// CHECK-DAG:                 ArraySet
1071   /// CHECK-NOT:                 ArraySet
testLocalArrayMerge2(boolean x)1072   private static int testLocalArrayMerge2(boolean x) {
1073     // The explicit store can be removed eventually even
1074     // though it is not equivalent to the default.
1075     int[] a = { 1 };
1076     // The diamond pattern stores/load remain.
1077     if (x) {
1078       a[0] = 2;
1079     } else {
1080       a[0] = 3;
1081     }
1082     return a[0];
1083   }
1084 
1085   /// CHECK-START: int Main.testLocalArrayMerge3(boolean) load_store_elimination (after)
1086   /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1087   /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1088   /// CHECK-DAG: <<Const2:i\d+>> IntConstant 2
1089   /// CHECK-DAG: <<A:l\d+>>      NewArray
1090   /// CHECK-DAG:                 ArraySet [<<A>>,<<Const0>>,<<Const1>>]
1091   /// CHECK-DAG:                 ArraySet [<<A>>,<<Const0>>,<<Const2>>]
1092   /// CHECK-DAG: <<Get:i\d+>>    ArrayGet [<<A>>,<<Const0>>]
1093   /// CHECK-DAG:                 Return [<<Get>>]
testLocalArrayMerge3(boolean x)1094   private static int testLocalArrayMerge3(boolean x) {
1095     // All stores/load remain.
1096     int[] a = { 1 };
1097     if (x) {
1098       a[0] = 2;
1099     }
1100     return a[0];
1101   }
1102 
1103   /// CHECK-START: int Main.testLocalArrayMerge4(boolean) load_store_elimination (before)
1104   /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0
1105   /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1106   /// CHECK-DAG: <<A:l\d+>>      NewArray
1107   /// CHECK-DAG:                 ArraySet [<<A>>,<<Const0>>,<<Const0>>]
1108   /// CHECK-DAG:                 ArraySet [<<A>>,<<Const0>>,<<Const1>>]
1109   /// CHECK-DAG:                 ArraySet [<<A>>,<<Const0>>,<<Const1>>]
1110   /// CHECK-DAG: <<Get1:b\d+>>   ArrayGet [<<A>>,<<Const0>>]
1111   /// CHECK-DAG: <<Get2:a\d+>>   ArrayGet [<<A>>,<<Const0>>]
1112   /// CHECK-DAG: <<Add:i\d+>>    Add [<<Get1>>,<<Get2>>]
1113   /// CHECK-DAG:                 Return [<<Add>>]
1114   //
1115   /// CHECK-START: int Main.testLocalArrayMerge4(boolean) load_store_elimination (after)
1116   /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1
1117   /// CHECK-DAG: <<Cnv1:b\d+>>   TypeConversion [<<Const1>>]
1118   /// CHECK-DAG: <<Cnv2:a\d+>>   TypeConversion [<<Const1>>]
1119   /// CHECK-DAG: <<Add:i\d+>>    Add [<<Cnv1>>,<<Cnv2>>]
1120   /// CHECK-DAG:                 Return [<<Add>>]
1121   //
1122   /// CHECK-START: int Main.testLocalArrayMerge4(boolean) load_store_elimination (after)
1123   /// CHECK-NOT:                 NewArray
1124   /// CHECK-NOT:                 ArraySet
1125   /// CHECK-NOT:                 ArrayGet
testLocalArrayMerge4(boolean x)1126   private static int testLocalArrayMerge4(boolean x) {
1127     byte[] a = { 0 };
1128     if (x) {
1129       a[0] = 1;
1130     } else {
1131       a[0] = 1;
1132     }
1133     // Differently typed (signed vs unsigned),
1134     // but same reference.
1135     return a[0] + (a[0] & 0xff);
1136   }
1137 
assertIntEquals(int result, int expected)1138   static void assertIntEquals(int result, int expected) {
1139     if (expected != result) {
1140       throw new Error("Expected: " + expected + ", found: " + result);
1141     }
1142   }
1143 
assertFloatEquals(float result, float expected)1144   static void assertFloatEquals(float result, float expected) {
1145     if (expected != result) {
1146       throw new Error("Expected: " + expected + ", found: " + result);
1147     }
1148   }
1149 
assertDoubleEquals(double result, double expected)1150   static void assertDoubleEquals(double result, double expected) {
1151     if (expected != result) {
1152       throw new Error("Expected: " + expected + ", found: " + result);
1153     }
1154   }
1155 
main(String[] args)1156   public static void main(String[] args) throws Exception {
1157 
1158     Class main2 = Class.forName("Main2");
1159     Method test4 = main2.getMethod("test4", TestClass.class, boolean.class);
1160     Method test5 = main2.getMethod("test5", TestClass.class, boolean.class);
1161     Method test10 = main2.getMethod("test10", TestClass.class);
1162     Method test23 = main2.getMethod("test23", boolean.class);
1163     Method test24 = main2.getMethod("test24");
1164 
1165     assertDoubleEquals(Math.PI * Math.PI * Math.PI, calcCircleArea(Math.PI));
1166     assertIntEquals(test1(new TestClass(), new TestClass()), 3);
1167     assertIntEquals(test2(new TestClass()), 1);
1168     TestClass obj1 = new TestClass();
1169     TestClass obj2 = new TestClass();
1170     obj1.next = obj2;
1171     assertIntEquals(test3(obj1), 10);
1172     assertIntEquals((int)test4.invoke(null, new TestClass(), true), 1);
1173     assertIntEquals((int)test4.invoke(null, new TestClass(), false), 1);
1174     assertIntEquals((int)test5.invoke(null, new TestClass(), true), 1);
1175     assertIntEquals((int)test5.invoke(null, new TestClass(), false), 2);
1176     assertIntEquals(test6(new TestClass(), new TestClass(), true), 4);
1177     assertIntEquals(test6(new TestClass(), new TestClass(), false), 2);
1178     assertIntEquals(test7(new TestClass()), 1);
1179     assertIntEquals(test8(), 1);
1180     obj1 = new TestClass();
1181     obj2 = new TestClass();
1182     obj1.next = obj2;
1183     assertIntEquals(test9(new TestClass()), 1);
1184     assertIntEquals((int)test10.invoke(null, new TestClass(3, 4)), 3);
1185     assertIntEquals(TestClass.si, 3);
1186     assertIntEquals(test11(new TestClass()), 10);
1187     assertIntEquals(test12(new TestClass(), new TestClass()), 10);
1188     assertIntEquals(test13(new TestClass(), new TestClass2()), 3);
1189     SubTestClass obj3 = new SubTestClass();
1190     assertIntEquals(test14(obj3, obj3), 2);
1191     assertIntEquals(test15(), 2);
1192     assertIntEquals(test16(), 3);
1193     assertIntEquals(test17(), 0);
1194     assertIntEquals(test18(new TestClass()), 1);
1195     float[] fa1 = { 0.8f };
1196     float[] fa2 = { 1.8f };
1197     assertFloatEquals(test19(fa1, fa2), 1.8f);
1198     assertFloatEquals(test20().i, 0);
1199     test21(new TestClass());
1200     assertIntEquals(test22(), 13);
1201     assertIntEquals((int)test23.invoke(null, true), 4);
1202     assertIntEquals((int)test23.invoke(null, false), 5);
1203     assertFloatEquals((float)test24.invoke(null), 8.0f);
1204     testFinalizableByForcingGc();
1205     assertIntEquals($noinline$testHSelect(true), 0xdead);
1206     int[] array = {2, 5, 9, -1, -3, 10, 8, 4};
1207     assertIntEquals(sumWithinRange(array, 1, 5), 11);
1208     assertFloatEquals(testAllocationEliminationWithLoops(), 1.0f);
1209     assertFloatEquals(mF, 0f);
1210     assertDoubleEquals(Math.PI * Math.PI * Math.PI, getCircleArea(Math.PI, true));
1211     assertDoubleEquals(0d, getCircleArea(Math.PI, false));
1212 
1213     int[] iarray = {0, 0, 0};
1214     double[] darray = {0d, 0d, 0d};
1215     try {
1216       assertDoubleEquals(Math.PI * Math.PI * Math.PI, testDeoptimize(iarray, darray, Math.PI));
1217     } catch (Exception e) {
1218       System.out.println(e);
1219     }
1220     assertIntEquals(iarray[0], 1);
1221     assertIntEquals(iarray[1], 1);
1222     assertIntEquals(iarray[2], 1);
1223     assertDoubleEquals(darray[0], Math.PI);
1224     assertDoubleEquals(darray[1], Math.PI);
1225     assertDoubleEquals(darray[2], Math.PI);
1226 
1227     assertIntEquals(testAllocationEliminationOfArray1(), 11);
1228     assertIntEquals(testAllocationEliminationOfArray2(), 11);
1229     assertIntEquals(testAllocationEliminationOfArray3(2), 4);
1230     assertIntEquals(testAllocationEliminationOfArray4(2), 6);
1231     assertIntEquals(testAllocationEliminationOfArray5(2), 12);
1232     try {
1233       testAllocationEliminationOfArray5(-2);
1234     } catch (NegativeArraySizeException e) {
1235       System.out.println("Got NegativeArraySizeException.");
1236     }
1237 
1238     assertIntEquals(testStoreStore().i, 41);
1239     assertIntEquals(testStoreStore().j, 43);
1240 
1241     assertIntEquals(testExitMerge(true), 2);
1242     assertIntEquals(testExitMerge2(true), 2);
1243     assertIntEquals(testExitMerge2(false), 2);
1244 
1245     TestClass2 testclass2 = new TestClass2();
1246     testStoreStore2(testclass2);
1247     assertIntEquals(testclass2.i, 43);
1248     assertIntEquals(testclass2.j, 44);
1249 
1250     testStoreStore3(testclass2, true);
1251     assertIntEquals(testclass2.i, 41);
1252     assertIntEquals(testclass2.j, 43);
1253     testStoreStore3(testclass2, false);
1254     assertIntEquals(testclass2.i, 41);
1255     assertIntEquals(testclass2.j, 44);
1256 
1257     testStoreStore4();
1258     assertIntEquals(TestClass.si, 62);
1259 
1260     int ret = testStoreStore5(testclass2, testclass2);
1261     assertIntEquals(testclass2.i, 72);
1262     assertIntEquals(ret, 71);
1263 
1264     testclass2.j = 88;
1265     ret = testStoreStore6(testclass2, testclass2);
1266     assertIntEquals(testclass2.i, 82);
1267     assertIntEquals(ret, 88);
1268 
1269     ret = testNoSideEffects(iarray);
1270     assertIntEquals(iarray[0], 101);
1271     assertIntEquals(iarray[1], 103);
1272     assertIntEquals(ret, 108);
1273 
1274     try {
1275       testThrow(testclass2, new Exception());
1276     } catch (Exception e) {}
1277     assertIntEquals(testclass2.i, 55);
1278 
1279     assertIntEquals(testStoreStoreWithDeoptimize(new int[4]), 4);
1280 
1281     assertIntEquals(testLocalArrayMerge1(true), 1);
1282     assertIntEquals(testLocalArrayMerge1(false), 1);
1283     assertIntEquals(testLocalArrayMerge2(true), 2);
1284     assertIntEquals(testLocalArrayMerge2(false), 3);
1285     assertIntEquals(testLocalArrayMerge3(true), 2);
1286     assertIntEquals(testLocalArrayMerge3(false), 1);
1287     assertIntEquals(testLocalArrayMerge4(true), 2);
1288     assertIntEquals(testLocalArrayMerge4(false), 2);
1289   }
1290 
1291   static boolean sFlag;
1292 }
1293