• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 interface SuperInterface {
superInterfaceMethod()18   void superInterfaceMethod();
19 }
20 
21 interface OtherInterface extends SuperInterface {
22 }
23 
24 interface Interface extends SuperInterface {
$noinline$f()25   void $noinline$f();
26 }
27 
28 class Super implements Interface {
superInterfaceMethod()29   public void superInterfaceMethod() {}
$noinline$f()30   public void $noinline$f() {
31     throw new RuntimeException();
32   }
33 }
34 
35 class SubclassA extends Super {
$noinline$f()36   public void $noinline$f() {
37     throw new RuntimeException();
38   }
39 
$noinline$h()40   public String $noinline$h() {
41     throw new RuntimeException();
42   }
43 
$noinline$g()44   void $noinline$g() {
45     throw new RuntimeException();
46   }
47 }
48 
49 class SubclassC extends SubclassA {
50 }
51 
52 class SubclassB extends Super {
$noinline$f()53   public void $noinline$f() {
54     throw new RuntimeException();
55   }
56 
$noinline$g()57   void $noinline$g() {
58     throw new RuntimeException();
59   }
60 }
61 
62 class Generic<A> {
63   private A a = null;
get()64   public A get() {
65     return a;
66   }
67 }
68 
69 final class Final {}
70 
71 final class FinalException extends Exception {}
72 
73 public class Main {
74 
75   /// CHECK-START: void Main.testSimpleRemove() instruction_simplifier (before)
76   /// CHECK:         CheckCast
77 
78   /// CHECK-START: void Main.testSimpleRemove() instruction_simplifier (after)
79   /// CHECK-NOT:     CheckCast
testSimpleRemove()80   public void testSimpleRemove() {
81     Super s = new SubclassA();
82     ((SubclassA)s).$noinline$g();
83   }
84 
85   /// CHECK-START: void Main.testSimpleKeep(Super) instruction_simplifier (before)
86   /// CHECK:         CheckCast
87 
88   /// CHECK-START: void Main.testSimpleKeep(Super) instruction_simplifier (after)
89   /// CHECK:         CheckCast
testSimpleKeep(Super s)90   public void testSimpleKeep(Super s) {
91     ((SubclassA)s).$noinline$f();
92   }
93 
94   /// CHECK-START: java.lang.String Main.testClassRemove() instruction_simplifier (before)
95   /// CHECK:         CheckCast
96 
97   /// CHECK-START: java.lang.String Main.testClassRemove() instruction_simplifier (after)
98   /// CHECK-NOT:     CheckCast
testClassRemove()99   public String testClassRemove() {
100     Object s = SubclassA.class;
101     return ((Class)s).getName();
102   }
103 
104   /// CHECK-START: java.lang.String Main.testClassKeep() instruction_simplifier (before)
105   /// CHECK:         CheckCast
106 
107   /// CHECK-START: java.lang.String Main.testClassKeep() instruction_simplifier (after)
108   /// CHECK:         CheckCast
testClassKeep()109   public String testClassKeep() {
110     Object s = SubclassA.class;
111     return ((SubclassA)s).$noinline$h();
112   }
113 
114   /// CHECK-START: void Main.testIfRemove(int) instruction_simplifier (before)
115   /// CHECK:         CheckCast
116 
117   /// CHECK-START: void Main.testIfRemove(int) instruction_simplifier (after)
118   /// CHECK-NOT:     CheckCast
testIfRemove(int x)119   public void testIfRemove(int x) {
120     Super s;
121     if (x % 2 == 0) {
122       s = new SubclassA();
123     } else {
124       s = new SubclassC();
125     }
126     ((SubclassA)s).$noinline$g();
127   }
128 
129   /// CHECK-START: void Main.testIfKeep(int) instruction_simplifier (before)
130   /// CHECK:         CheckCast
131 
132   /// CHECK-START: void Main.testIfKeep(int) instruction_simplifier (after)
133   /// CHECK:         CheckCast
testIfKeep(int x)134   public void testIfKeep(int x) {
135     Super s;
136     if (x % 2 == 0) {
137       s = new SubclassA();
138     } else {
139       s = new SubclassB();
140     }
141     ((SubclassA)s).$noinline$g();
142   }
143 
144   /// CHECK-START: void Main.testForRemove(int) instruction_simplifier (before)
145   /// CHECK:         CheckCast
146 
147   /// CHECK-START: void Main.testForRemove(int) instruction_simplifier (after)
148   /// CHECK-NOT:     CheckCast
testForRemove(int x)149   public void testForRemove(int x) {
150     Super s = new SubclassA();
151     for (int i = 0 ; i < x; i++) {
152       if (x % 2 == 0) {
153         s = new SubclassC();
154       }
155     }
156     ((SubclassA)s).$noinline$g();
157   }
158 
159   /// CHECK-START: void Main.testForKeep(int) instruction_simplifier (before)
160   /// CHECK:         CheckCast
161 
162   /// CHECK-START: void Main.testForKeep(int) instruction_simplifier (after)
163   /// CHECK:         CheckCast
testForKeep(int x)164   public void testForKeep(int x) {
165     Super s = new SubclassA();
166     for (int i = 0 ; i < x; i++) {
167       if (x % 2 == 0) {
168         s = new SubclassC();
169       }
170     }
171     ((SubclassC)s).$noinline$g();
172   }
173 
174   /// CHECK-START: void Main.testPhiFromCall(int) instruction_simplifier (before)
175   /// CHECK:         CheckCast
176 
177   /// CHECK-START: void Main.testPhiFromCall(int) instruction_simplifier (after)
178   /// CHECK:         CheckCast
testPhiFromCall(int i)179   public void testPhiFromCall(int i) {
180     Object x;
181     if (i % 2 == 0) {
182       x = new SubclassC();
183     } else {
184       x = newObject();  // this one will have an unknown type.
185     }
186     ((SubclassC)x).$noinline$g();
187   }
188 
189   /// CHECK-START: void Main.testInstanceOf(java.lang.Object) instruction_simplifier (before)
190   /// CHECK:         CheckCast
191   /// CHECK:         CheckCast
192   /// CHECK-NOT:     CheckCast
193 
194   /// CHECK-START: void Main.testInstanceOf(java.lang.Object) instruction_simplifier (after)
195   /// CHECK-NOT:     CheckCast
testInstanceOf(Object o)196   public void testInstanceOf(Object o) {
197     if (o instanceof SubclassC) {
198       ((SubclassC)o).$noinline$g();
199     }
200     if (o instanceof SubclassB) {
201       ((SubclassB)o).$noinline$g();
202     }
203   }
204 
$inline$InstanceofSubclassB(Object o)205   public static boolean $inline$InstanceofSubclassB(Object o) { return o instanceof SubclassB; }
$inline$InstanceofSubclassC(Object o)206   public static boolean $inline$InstanceofSubclassC(Object o) { return o instanceof SubclassC; }
207 
208   /// CHECK-START: void Main.testInstanceOf_Inlined(java.lang.Object) inliner (after)
209   /// CHECK-DAG:     <<IOf:z\d+>>  InstanceOf
210   /// CHECK-DAG:                   If [<<IOf>>]
211 
212   /// CHECK-START: void Main.testInstanceOf_Inlined(java.lang.Object) instruction_simplifier_after_bce (before)
213   /// CHECK:         CheckCast
214   /// CHECK-NOT:     CheckCast
215 
216   /// CHECK-START: void Main.testInstanceOf_Inlined(java.lang.Object) instruction_simplifier_after_bce (after)
217   /// CHECK-NOT:     CheckCast
testInstanceOf_Inlined(Object o)218   public void testInstanceOf_Inlined(Object o) {
219     if (!$inline$InstanceofSubclassC(o)) {
220       // Empty branch to flip the condition.
221     } else {
222       ((SubclassC)o).$noinline$g();
223     }
224   }
225 
226   /// CHECK-START: void Main.testInstanceOfKeep(java.lang.Object) instruction_simplifier (before)
227   /// CHECK:         CheckCast
228   /// CHECK:         CheckCast
229 
230   /// CHECK-START: void Main.testInstanceOfKeep(java.lang.Object) instruction_simplifier (after)
231   /// CHECK:         CheckCast
232   /// CHECK:         CheckCast
testInstanceOfKeep(Object o)233   public void testInstanceOfKeep(Object o) {
234     if (o instanceof SubclassC) {
235       ((SubclassB)o).$noinline$g();
236     }
237     if (o instanceof SubclassB) {
238       ((SubclassA)o).$noinline$g();
239     }
240   }
241 
242   /// CHECK-START: void Main.testInstanceOfNested(java.lang.Object) instruction_simplifier (before)
243   /// CHECK:         CheckCast
244   /// CHECK:         CheckCast
245 
246   /// CHECK-START: void Main.testInstanceOfNested(java.lang.Object) instruction_simplifier (after)
247   /// CHECK-NOT:     CheckCast
testInstanceOfNested(Object o)248   public void testInstanceOfNested(Object o) {
249     if (o instanceof SubclassC) {
250       if (o instanceof SubclassB) {
251         ((SubclassB)o).$noinline$g();
252       } else {
253         ((SubclassC)o).$noinline$g();
254       }
255     }
256   }
257 
258   /// CHECK-START: void Main.testInstanceOfWithPhi(int) instruction_simplifier (before)
259   /// CHECK:         CheckCast
260 
261   /// CHECK-START: void Main.testInstanceOfWithPhi(int) instruction_simplifier (after)
262   /// CHECK-NOT:     CheckCast
testInstanceOfWithPhi(int i)263   public void testInstanceOfWithPhi(int i) {
264     Object o;
265     if (i == 0) {
266       o = new SubclassA();
267     } else {
268       o = new SubclassB();
269     }
270 
271     if (o instanceof SubclassB) {
272       ((SubclassB)o).$noinline$g();
273     }
274   }
275 
276   /// CHECK-START: void Main.testInstanceOfInFor(int) instruction_simplifier (before)
277   /// CHECK:         CheckCast
278 
279   /// CHECK-START: void Main.testInstanceOfInFor(int) instruction_simplifier (after)
280   /// CHECK-NOT:     CheckCast
testInstanceOfInFor(int n)281   public void testInstanceOfInFor(int n) {
282     Object o = new SubclassA();
283     for (int i = 0; i < n; i++) {
284       if (i / 2 == 0) {
285         o = new SubclassB();
286       }
287       if (o instanceof SubclassB) {
288         ((SubclassB)o).$noinline$g();
289       }
290     }
291   }
292 
293   /// CHECK-START: void Main.testInstanceOfSubclass() instruction_simplifier (before)
294   /// CHECK:         CheckCast
295 
296   /// CHECK-START: void Main.testInstanceOfSubclass() instruction_simplifier (after)
297   /// CHECK-NOT:     CheckCast
testInstanceOfSubclass()298   public void testInstanceOfSubclass() {
299     Object o = new SubclassA();
300     if (o instanceof Super) {
301       ((SubclassA)o).$noinline$g();
302     }
303   }
304 
305   /// CHECK-START: void Main.testInstanceOfWithPhiSubclass(int) instruction_simplifier (before)
306   /// CHECK:         CheckCast
307 
308   /// CHECK-START: void Main.testInstanceOfWithPhiSubclass(int) instruction_simplifier (after)
309   /// CHECK-NOT:     CheckCast
testInstanceOfWithPhiSubclass(int i)310   public void testInstanceOfWithPhiSubclass(int i) {
311     Object o;
312     if (i == 0) {
313       o = new SubclassA();
314     } else {
315       o = new SubclassC();
316     }
317 
318     if (o instanceof Super) {
319       ((SubclassA)o).$noinline$g();
320     }
321   }
322 
323   /// CHECK-START: void Main.testInstanceOfWithPhiTop(int) instruction_simplifier (before)
324   /// CHECK:         CheckCast
325 
326   /// CHECK-START: void Main.testInstanceOfWithPhiTop(int) instruction_simplifier (after)
327   /// CHECK-NOT:     CheckCast
testInstanceOfWithPhiTop(int i)328   public void testInstanceOfWithPhiTop(int i) {
329     Object o;
330     if (i == 0) {
331       o = new Object();
332     } else {
333       o = new SubclassC();
334     }
335 
336     if (o instanceof Super) {
337       ((Super)o).$noinline$f();
338     }
339   }
340 
341   /// CHECK-START: void Main.testInstanceOfSubclassInFor(int) instruction_simplifier (before)
342   /// CHECK:         CheckCast
343 
344   /// CHECK-START: void Main.testInstanceOfSubclassInFor(int) instruction_simplifier (after)
345   /// CHECK-NOT:     CheckCast
testInstanceOfSubclassInFor(int n)346   public void testInstanceOfSubclassInFor(int n) {
347     Object o = new SubclassA();
348     for (int i = 0; i < n; i++) {
349       if (o instanceof Super) {
350         ((SubclassA)o).$noinline$g();
351       }
352       if (i / 2 == 0) {
353         o = new SubclassC();
354       }
355     }
356   }
357 
358   /// CHECK-START: void Main.testInstanceOfTopInFor(int) instruction_simplifier (before)
359   /// CHECK:         CheckCast
360 
361   /// CHECK-START: void Main.testInstanceOfTopInFor(int) instruction_simplifier (after)
362   /// CHECK-NOT:     CheckCast
testInstanceOfTopInFor(int n)363   public void testInstanceOfTopInFor(int n) {
364     Object o = new SubclassA();
365     for (int i = 0; i < n; i++) {
366       if (o instanceof Super) {
367         ((Super)o).$noinline$f();
368       }
369       if (i / 2 == 0) {
370         o = new Object();
371       }
372     }
373   }
374 
newObject()375   public Object newObject() {
376     try {
377       return Object.class.newInstance();
378     } catch (Exception e) {
379       return null;
380     }
381   }
382 
383   public SubclassA a = new SubclassA();
384   public static SubclassA b = new SubclassA();
385 
386   /// CHECK-START: void Main.testInstanceFieldGetSimpleRemove() instruction_simplifier (before)
387   /// CHECK:         CheckCast
388 
389   /// CHECK-START: void Main.testInstanceFieldGetSimpleRemove() instruction_simplifier (after)
390   /// CHECK-NOT:     CheckCast
testInstanceFieldGetSimpleRemove()391   public void testInstanceFieldGetSimpleRemove() {
392     Main m = new Main();
393     Super a = m.a;
394     ((SubclassA)a).$noinline$g();
395   }
396 
397   /// CHECK-START: void Main.testStaticFieldGetSimpleRemove() instruction_simplifier (before)
398   /// CHECK:         CheckCast
399 
400   /// CHECK-START: void Main.testStaticFieldGetSimpleRemove() instruction_simplifier (after)
401   /// CHECK-NOT:     CheckCast
testStaticFieldGetSimpleRemove()402   public void testStaticFieldGetSimpleRemove() {
403     Super b = Main.b;
404     ((SubclassA)b).$noinline$g();
405   }
406 
$noinline$getSubclass()407   public SubclassA $noinline$getSubclass() { throw new RuntimeException(); }
408 
409   /// CHECK-START: void Main.testArraySimpleRemove() instruction_simplifier (before)
410   /// CHECK:         CheckCast
411 
412   /// CHECK-START: void Main.testArraySimpleRemove() instruction_simplifier (after)
413   /// CHECK-NOT:     CheckCast
testArraySimpleRemove()414   public void testArraySimpleRemove() {
415     Super[] b = new SubclassA[10];
416     SubclassA[] c = (SubclassA[])b;
417   }
418 
419   /// CHECK-START: void Main.testInvokeSimpleRemove() instruction_simplifier (before)
420   /// CHECK:         CheckCast
421 
422   /// CHECK-START: void Main.testInvokeSimpleRemove() instruction_simplifier (after)
423   /// CHECK-NOT:     CheckCast
testInvokeSimpleRemove()424   public void testInvokeSimpleRemove() {
425     Super b = $noinline$getSubclass();
426     ((SubclassA)b).$noinline$g();
427   }
428   /// CHECK-START: void Main.testArrayGetSimpleRemove() instruction_simplifier (before)
429   /// CHECK:         CheckCast
430 
431   /// CHECK-START: void Main.testArrayGetSimpleRemove() instruction_simplifier (after)
432   /// CHECK-NOT:     CheckCast
testArrayGetSimpleRemove()433   public void testArrayGetSimpleRemove() {
434     Super[] a = new SubclassA[10];
435     ((SubclassA)a[0]).$noinline$g();
436   }
437 
438   /// CHECK-START: int Main.testLoadExceptionInCatchNonExact(int, int) builder (after)
439   /// CHECK:         LoadException klass:java.lang.ArithmeticException can_be_null:false exact:false
testLoadExceptionInCatchNonExact(int x, int y)440   public int testLoadExceptionInCatchNonExact(int x, int y) {
441     try {
442       return x / y;
443     } catch (ArithmeticException ex) {
444       return ex.hashCode();
445     }
446   }
447 
448   /// CHECK-START: int Main.testLoadExceptionInCatchExact(int) builder (after)
449   /// CHECK:         LoadException klass:FinalException can_be_null:false exact:true
testLoadExceptionInCatchExact(int x)450   public int testLoadExceptionInCatchExact(int x) {
451     try {
452       if (x == 42) {
453         throw new FinalException();
454       } else {
455         return x;
456       }
457     } catch (FinalException ex) {
458       return ex.hashCode();
459     }
460   }
461 
462   /// CHECK-START: int Main.testLoadExceptionInCatchAll(int, int) builder (after)
463   /// CHECK:         LoadException klass:java.lang.Throwable can_be_null:false exact:false
testLoadExceptionInCatchAll(int x, int y)464   public int testLoadExceptionInCatchAll(int x, int y) {
465     try {
466       x = x / y;
467     } finally {
468       return x;
469     }
470   }
471 
472   private Generic<SubclassC> genericC = new Generic<SubclassC>();
473   private Generic<Final> genericFinal = new Generic<Final>();
474 
get()475   private SubclassC get() {
476     return genericC.get();
477   }
478 
getFinal()479   private Final getFinal() {
480     return genericFinal.get();
481   }
482 
483   /// CHECK-START: SubclassC Main.inlineGenerics() builder (after)
484   /// CHECK:      <<Invoke:l\d+>>    InvokeStaticOrDirect klass:SubclassC exact:false
485   /// CHECK-NEXT:                    Return [<<Invoke>>]
486 
487   /// CHECK-START: SubclassC Main.inlineGenerics() inliner (after)
488   /// CHECK:      <<BoundType:l\d+>> BoundType klass:SubclassC exact:false
489   /// CHECK:                         Return [<<BoundType>>]
inlineGenerics()490   private SubclassC inlineGenerics() {
491     SubclassC c = get();
492     return c;
493   }
494 
495   /// CHECK-START: Final Main.inlineGenericsFinal() builder (after)
496   /// CHECK:      <<Invoke:l\d+>>    InvokeStaticOrDirect klass:Final exact:true
497   /// CHECK-NEXT:                    Return [<<Invoke>>]
498 
499   /// CHECK-START: Final Main.inlineGenericsFinal() inliner (after)
500   /// CHECK:      <<BoundType:l\d+>> BoundType klass:Final exact:true
501   /// CHECK:                         Return [<<BoundType>>]
inlineGenericsFinal()502   private Final inlineGenericsFinal() {
503     Final f = getFinal();
504     return f;
505   }
506 
507   /// CHECK-START: void Main.boundOnlyOnceIfNotNull(java.lang.Object) inliner (after)
508   /// CHECK:      BoundType
509   /// CHECK-NOT:  BoundType
boundOnlyOnceIfNotNull(Object o)510   private void boundOnlyOnceIfNotNull(Object o) {
511     if (o != null) {
512       o.toString();
513     }
514   }
515 
516   /// CHECK-START: void Main.boundOnlyOnceIfInstanceOf(java.lang.Object) inliner (after)
517   /// CHECK:      BoundType
518   /// CHECK-NOT:  BoundType
boundOnlyOnceIfInstanceOf(Object o)519   private void boundOnlyOnceIfInstanceOf(Object o) {
520     if (o instanceof Main) {
521       o.toString();
522     }
523   }
524 
525   /// CHECK-START: Final Main.boundOnlyOnceCheckCast(Generic) inliner (after)
526   /// CHECK:      BoundType
527   /// CHECK-NOT:  BoundType
boundOnlyOnceCheckCast(Generic<Final> o)528   private Final boundOnlyOnceCheckCast(Generic<Final> o) {
529     Final f = o.get();
530     return f;
531   }
532 
getSuper()533   private Super getSuper() {
534     return new SubclassA();
535   }
536 
537   /// CHECK-START: void Main.updateNodesInTheSameBlockAsPhi(boolean) builder (after)
538   /// CHECK:      <<Phi:l\d+>> Phi klass:Super
539   /// CHECK:                   NullCheck [<<Phi>>] klass:Super
540 
541   /// CHECK-START: void Main.updateNodesInTheSameBlockAsPhi(boolean) inliner (after)
542   /// CHECK:      <<Phi:l\d+>> Phi klass:SubclassA
543   /// CHECK:                   NullCheck [<<Phi>>] klass:SubclassA
updateNodesInTheSameBlockAsPhi(boolean cond)544   private void updateNodesInTheSameBlockAsPhi(boolean cond) {
545     Super s = getSuper();
546     if (cond) {
547       s = new SubclassA();
548     }
549     s.$noinline$f();
550   }
551 
552   /// CHECK-START: java.lang.String Main.checkcastPreserveNullCheck(java.lang.Object) inliner (after)
553   /// CHECK:      <<This:l\d+>>     ParameterValue
554   /// CHECK:      <<Param:l\d+>>    ParameterValue
555   /// CHECK:      <<Clazz:l\d+>>    LoadClass
556   /// CHECK:                        CheckCast [<<Param>>,<<Clazz>>]
557   /// CHECK:                        BoundType [<<Param>>] can_be_null:true
558 
559   /// CHECK-START: java.lang.String Main.checkcastPreserveNullCheck(java.lang.Object) instruction_simplifier (after)
560   /// CHECK:      <<This:l\d+>>     ParameterValue
561   /// CHECK:      <<Param:l\d+>>    ParameterValue
562   /// CHECK:      <<Clazz:l\d+>>    LoadClass
563   /// CHECK:                        CheckCast [<<Param>>,<<Clazz>>]
564   /// CHECK:      <<Bound:l\d+>>    BoundType [<<Param>>]
565   /// CHECK:                        NullCheck [<<Bound>>]
checkcastPreserveNullCheck(Object a)566   public String checkcastPreserveNullCheck(Object a) {
567     return ((SubclassA)a).toString();
568   }
569 
570 
571   /// CHECK-START: void Main.argumentCheck(Super, double, SubclassA, Final) builder (after)
572   /// CHECK:      ParameterValue klass:Main can_be_null:false exact:false
573   /// CHECK:      ParameterValue klass:Super can_be_null:true exact:false
574   /// CHECK:      ParameterValue
575   /// CHECK:      ParameterValue klass:SubclassA can_be_null:true exact:false
576   /// CHECK:      ParameterValue klass:Final can_be_null:true exact:true
577   /// CHECK-NOT:  ParameterValue
argumentCheck(Super s, double d, SubclassA a, Final f)578   private void argumentCheck(Super s, double d, SubclassA a, Final f) {
579   }
580 
getNull()581   private Main getNull() {
582     return null;
583   }
584 
585   private int mainField = 0;
586 
587   /// CHECK-START: SuperInterface Main.getWiderType(boolean, Interface, OtherInterface) builder (after)
588   /// CHECK:      <<Phi:l\d+>>       Phi klass:java.lang.Object
589   /// CHECK:                         Return [<<Phi>>]
getWiderType(boolean cond, Interface a, OtherInterface b)590   private SuperInterface getWiderType(boolean cond, Interface a, OtherInterface b) {
591     return cond ? a : b;
592   }
593 
594   /// CHECK-START: void Main.testInlinerWidensReturnType(boolean, Interface, OtherInterface) inliner (before)
595   /// CHECK:      <<Invoke:l\d+>>    InvokeStaticOrDirect klass:SuperInterface
596   /// CHECK:      <<NullCheck:l\d+>> NullCheck [<<Invoke>>] klass:SuperInterface exact:false
597   /// CHECK:                         InvokeInterface [<<NullCheck>>]
598 
599   /// CHECK-START: void Main.testInlinerWidensReturnType(boolean, Interface, OtherInterface) inliner (after)
600   /// CHECK:      <<Phi:l\d+>>       Phi klass:java.lang.Object
601   /// CHECK:      <<NullCheck:l\d+>> NullCheck [<<Phi>>] klass:SuperInterface exact:false
602   /// CHECK:                         InvokeInterface [<<NullCheck>>]
testInlinerWidensReturnType(boolean cond, Interface a, OtherInterface b)603   private void testInlinerWidensReturnType(boolean cond, Interface a, OtherInterface b) {
604     getWiderType(cond, a, b).superInterfaceMethod();
605   }
606 
607   /// CHECK-START: void Main.testInlinerReturnsNull() inliner (before)
608   /// CHECK:      <<Int:i\d+>>       IntConstant 0
609   /// CHECK:      <<Invoke:l\d+>>    InvokeStaticOrDirect klass:Main
610   /// CHECK:      <<NullCheck:l\d+>> NullCheck [<<Invoke>>] klass:Main exact:false
611   /// CHECK:                         InstanceFieldSet [<<NullCheck>>,<<Int>>]
612 
613   /// CHECK-START: void Main.testInlinerReturnsNull() inliner (after)
614   /// CHECK:      <<Int:i\d+>>       IntConstant 0
615   /// CHECK:      <<Null:l\d+>>      NullConstant klass:java.lang.Object
616   /// CHECK:      <<NullCheck:l\d+>> NullCheck [<<Null>>] klass:Main exact:false
617   /// CHECK:                         InstanceFieldSet [<<NullCheck>>,<<Int>>]
testInlinerReturnsNull()618   private void testInlinerReturnsNull() {
619     Main o = getNull();
620     o.mainField = 0;
621   }
622 
623   /// CHECK-START: void Main.testPhiHasOnlyNullInputs(boolean) inliner (before)
624   /// CHECK:      <<Int:i\d+>>       IntConstant 0
625   /// CHECK:      <<Phi:l\d+>>       Phi klass:Main exact:false
626   /// CHECK:      <<NullCheck:l\d+>> NullCheck [<<Phi>>] klass:Main exact:false
627   /// CHECK:                         InstanceFieldSet [<<NullCheck>>,<<Int>>]
628 
629   /// CHECK-START: void Main.testPhiHasOnlyNullInputs(boolean) inliner (after)
630   /// CHECK:      <<Int:i\d+>>       IntConstant 0
631   /// CHECK:      <<Null:l\d+>>      NullConstant klass:java.lang.Object
632   /// CHECK:      <<Phi:l\d+>>       Phi [<<Null>>,<<Null>>] klass:java.lang.Object exact:false
633   /// CHECK:      <<NullCheck:l\d+>> NullCheck [<<Phi>>] klass:java.lang.Object exact:false
634   /// CHECK:                         InstanceFieldSet [<<NullCheck>>,<<Int>>]
testPhiHasOnlyNullInputs(boolean cond)635   private void testPhiHasOnlyNullInputs(boolean cond) {
636     Main o = cond ? null : getNull();
637     o.mainField = 0;
638     // getSuper() will force a type propagation after inlining
639     // because returns a more precise type.
640     getSuper();
641   }
642 
643   /// CHECK-START: void Main.testLoopPhiWithNullFirstInput(boolean) builder (after)
644   /// CHECK-DAG:  <<Null:l\d+>>      NullConstant
645   /// CHECK-DAG:  <<Main:l\d+>>      NewInstance klass:Main exact:true
646   /// CHECK-DAG:  <<LoopPhi:l\d+>>   Phi [<<Null>>,<<LoopPhi>>,<<Main>>] klass:Main exact:true
testLoopPhiWithNullFirstInput(boolean cond)647   private void testLoopPhiWithNullFirstInput(boolean cond) {
648     Main a = null;
649     while (a == null) {
650       if (cond) {
651         a = new Main();
652       }
653     }
654   }
655 
656   /// CHECK-START: java.lang.Object[] Main.testInstructionsWithUntypedParent() builder (after)
657   /// CHECK-DAG:  <<Null:l\d+>>      NullConstant
658   /// CHECK-DAG:  <<LoopPhi:l\d+>>   Phi [<<Null>>,<<Phi:l\d+>>] klass:java.lang.Object[] exact:true
659   /// CHECK-DAG:  <<Array:l\d+>>     NewArray klass:java.lang.Object[] exact:true
660   /// CHECK-DAG:  <<Phi>>            Phi [<<Array>>,<<LoopPhi>>] klass:java.lang.Object[] exact:true
661   /// CHECK-DAG:  <<NC:l\d+>>        NullCheck [<<LoopPhi>>] klass:java.lang.Object[] exact:true
662   /// CHECK-DAG:                     ArrayGet [<<NC>>,{{i\d+}}] klass:java.lang.Object exact:false
testInstructionsWithUntypedParent()663   private Object[] testInstructionsWithUntypedParent() {
664     Object[] array = null;
665     boolean cond = true;
666     for (int i = 0; i < 10; ++i) {
667       if (cond) {
668         array = new Object[10];
669         array[0] = new Object();
670         cond = false;
671       } else {
672         array[i] = array[0];
673       }
674     }
675     return array;
676   }
677 
main(String[] args)678   public static void main(String[] args) {
679   }
680 }
681