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