1 /* 2 * Copyright (C) 2022 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 // 18 // Test on loop optimizations, in particular with try catches. 19 // 20 public class Main { 21 // Consistency check to see we haven't eliminated the try/catch. 22 /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (before) 23 /// CHECK: TryBoundary 24 25 /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (before) 26 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 27 /// CHECK-DAG: Mul loop:<<Loop>> 28 29 /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (after) 30 /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none 31 /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none 32 /// CHECK-DAG: <<Int:i\d+>> IntConstant 1410065408 loop:none 33 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>] loop:none 34 /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Zer>>] loop:none 35 /// CHECK-DAG: Return [<<Add>>] loop:none 36 37 /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (after) 38 /// CHECK-NOT: Phi $noinline$geo1(int a)39 private static int $noinline$geo1(int a) { 40 for (int i = 0; i < 10; i++) { 41 a *= 10; 42 } 43 44 // Outer try catch does not block loop optimizations. 45 try { 46 if (doThrow) { 47 $noinline$unreachable(); 48 } 49 } catch (Error e) { 50 System.out.println("Not expected"); 51 } 52 return a; 53 } 54 55 // Consistency check to see we haven't eliminated the try/catch. 56 /// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (before) 57 /// CHECK: TryBoundary 58 59 /// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (before) 60 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 61 /// CHECK-DAG: Mul loop:<<Loop>> 62 63 /// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (after) 64 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 65 /// CHECK-DAG: Mul loop:<<Loop>> $noinline$geo1_Blocking(int a)66 private static int $noinline$geo1_Blocking(int a) { 67 for (int i = 0; i < 10; i++) { 68 a *= 10; 69 70 // Try catch blocks optimizations. 71 try { 72 if (doThrow) { 73 $noinline$unreachable(); 74 } 75 } catch (Error e) { 76 System.out.println("Not expected"); 77 } 78 } 79 return a; 80 } 81 82 // Consistency check to see we haven't eliminated the try/catch. 83 /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (before) 84 /// CHECK: TryBoundary 85 86 /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (before) 87 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 88 /// CHECK-DAG: Shl loop:<<Loop>> 89 90 /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (after) 91 /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none 92 /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none 93 /// CHECK-DAG: <<Int:i\d+>> IntConstant 1024 loop:none 94 /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>] loop:none 95 /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Zer>>] loop:none 96 /// CHECK-DAG: Return [<<Add>>] loop:none 97 98 /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (after) 99 /// CHECK-NOT: Phi $noinline$geo2(int a)100 private static int $noinline$geo2(int a) { 101 for (int i = 0; i < 10; i++) { 102 a <<= 1; 103 } 104 105 // Outer try catch does not block loop optimizations. 106 try { 107 if (doThrow) { 108 $noinline$unreachable(); 109 } 110 } catch (Error e) { 111 System.out.println("Not expected"); 112 } 113 return a; 114 } 115 116 // Consistency check to see we haven't eliminated the try/catch. 117 /// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (before) 118 /// CHECK: TryBoundary 119 120 /// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (before) 121 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 122 /// CHECK-DAG: Shl loop:<<Loop>> 123 124 /// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (after) 125 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 126 /// CHECK-DAG: Shl loop:<<Loop>> $noinline$geo2_Blocking(int a)127 private static int $noinline$geo2_Blocking(int a) { 128 for (int i = 0; i < 10; i++) { 129 a <<= 1; 130 131 // Try catch blocks optimizations. 132 try { 133 if (doThrow) { 134 $noinline$unreachable(); 135 } 136 } catch (Error e) { 137 System.out.println("Not expected"); 138 } 139 } 140 return a; 141 } 142 143 // Consistency check to see we haven't eliminated the try/catch. 144 /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (before) 145 /// CHECK: TryBoundary 146 147 /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (before) 148 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 149 /// CHECK-DAG: Div loop:<<Loop>> 150 151 /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (after) 152 /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none 153 /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none 154 /// CHECK-DAG: <<Int:i\d+>> IntConstant 59049 loop:none 155 /// CHECK-DAG: <<Div:i\d+>> Div [<<Par>>,<<Int>>] loop:none 156 /// CHECK-DAG: <<Add:i\d+>> Add [<<Div>>,<<Zer>>] loop:none 157 /// CHECK-DAG: Return [<<Add>>] loop:none 158 159 /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (after) 160 /// CHECK-NOT: Phi $noinline$geo3(int a)161 private static int $noinline$geo3(int a) { 162 for (int i = 0; i < 10; i++) { 163 a /= 3; 164 } 165 166 // Outer try catch does not block loop optimizations. 167 try { 168 if (doThrow) { 169 $noinline$unreachable(); 170 } 171 } catch (Error e) { 172 System.out.println("Not expected"); 173 } 174 return a; 175 } 176 177 // Consistency check to see we haven't eliminated the try/catch. 178 /// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (before) 179 /// CHECK: TryBoundary 180 181 /// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (before) 182 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 183 /// CHECK-DAG: Div loop:<<Loop>> 184 185 /// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (after) 186 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 187 /// CHECK-DAG: Div loop:<<Loop>> $noinline$geo3_Blocking(int a)188 private static int $noinline$geo3_Blocking(int a) { 189 for (int i = 0; i < 10; i++) { 190 a /= 3; 191 192 // Try catch blocks optimizations. 193 try { 194 if (doThrow) { 195 $noinline$unreachable(); 196 } 197 } catch (Error e) { 198 System.out.println("Not expected"); 199 } 200 } 201 return a; 202 } 203 204 205 // Consistency check to see we haven't eliminated the try/catch. 206 /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (before) 207 /// CHECK: TryBoundary 208 209 /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (before) 210 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 211 /// CHECK-DAG: Rem loop:<<Loop>> 212 213 /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (after) 214 /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none 215 /// CHECK-DAG: <<Int:i\d+>> IntConstant 7 loop:none 216 /// CHECK-DAG: <<Rem:i\d+>> Rem [<<Par>>,<<Int>>] loop:none 217 /// CHECK-DAG: Return [<<Rem>>] loop:none 218 219 /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (after) 220 /// CHECK-NOT: Phi $noinline$geo4(int a)221 private static int $noinline$geo4(int a) { 222 for (int i = 0; i < 10; i++) { 223 a %= 7; // a wrap-around induction 224 } 225 226 // Outer try catch does not block loop optimizations. 227 try { 228 if (doThrow) { 229 $noinline$unreachable(); 230 } 231 } catch (Error e) { 232 System.out.println("Not expected"); 233 } 234 return a; 235 } 236 237 // Consistency check to see we haven't eliminated the try/catch. 238 /// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (before) 239 /// CHECK: TryBoundary 240 241 /// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (before) 242 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 243 /// CHECK-DAG: Rem loop:<<Loop>> 244 245 /// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (after) 246 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 247 /// CHECK-DAG: Rem loop:<<Loop>> $noinline$geo4_Blocking(int a)248 private static int $noinline$geo4_Blocking(int a) { 249 for (int i = 0; i < 10; i++) { 250 a %= 7; // a wrap-around induction 251 252 // Try catch blocks optimizations. 253 try { 254 if (doThrow) { 255 $noinline$unreachable(); 256 } 257 } catch (Error e) { 258 System.out.println("Not expected"); 259 } 260 } 261 return a; 262 } 263 264 // Consistency check to see we haven't eliminated the try/catch. 265 /// CHECK-START: int Main.$noinline$geo5() loop_optimization (before) 266 /// CHECK: TryBoundary 267 268 /// CHECK-START: int Main.$noinline$geo5() loop_optimization (before) 269 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 270 /// CHECK-DAG: Shr loop:<<Loop>> 271 272 /// CHECK-START: int Main.$noinline$geo5() loop_optimization (after) 273 /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 loop:none 274 /// CHECK-DAG: <<Int1:i\d+>> IntConstant 2147483647 loop:none 275 /// CHECK-DAG: <<Int2:i\d+>> IntConstant 1024 loop:none 276 /// CHECK-DAG: <<Div:i\d+>> Div [<<Int1>>,<<Int2>>] loop:none 277 /// CHECK-DAG: <<Add:i\d+>> Add [<<Div>>,<<Zero>>] loop:none 278 /// CHECK-DAG: Return [<<Add>>] loop:none 279 280 /// CHECK-START: int Main.$noinline$geo5() loop_optimization (after) 281 /// CHECK-NOT: Phi $noinline$geo5()282 private static int $noinline$geo5() { 283 int a = 0x7fffffff; 284 for (int i = 0; i < 10; i++) { 285 a >>= 1; 286 } 287 288 // Outer try catch does not block loop optimizations. 289 try { 290 if (doThrow) { 291 $noinline$unreachable(); 292 } 293 } catch (Error e) { 294 System.out.println("Not expected"); 295 } 296 return a; 297 } 298 299 // Consistency check to see we haven't eliminated the try/catch. 300 /// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (before) 301 /// CHECK: TryBoundary 302 303 /// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (before) 304 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 305 /// CHECK-DAG: Shr loop:<<Loop>> 306 307 /// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (after) 308 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 309 /// CHECK-DAG: Shr loop:<<Loop>> $noinline$geo5_Blocking()310 private static int $noinline$geo5_Blocking() { 311 int a = 0x7fffffff; 312 for (int i = 0; i < 10; i++) { 313 a >>= 1; 314 315 // Try catch blocks optimizations. 316 try { 317 if (doThrow) { 318 $noinline$unreachable(); 319 } 320 } catch (Error e) { 321 System.out.println("Not expected"); 322 } 323 } 324 return a; 325 } 326 327 // Tests taken from 530-checker-loops4 $noinline$loops4Tests()328 private static void $noinline$loops4Tests() { 329 int m = 1410065408; 330 for (int i = -100; i <= 100; i++) { 331 expectEquals(m * i, $noinline$geo1(i)); 332 expectEquals(m * i, $noinline$geo1_Blocking(i)); 333 } 334 for (int i = 1; i <= 1000000000; i *= 10) { 335 expectEquals(m * i, $noinline$geo1(i)); 336 expectEquals(m * i, $noinline$geo1_Blocking(i)); 337 expectEquals(-m * i, $noinline$geo1(-i)); 338 expectEquals(-m * i, $noinline$geo1_Blocking(-i)); 339 } 340 341 for (int i = -100; i <= 100; i++) { 342 expectEquals(i << 10, $noinline$geo2(i)); 343 expectEquals(i << 10, $noinline$geo2_Blocking(i)); 344 } 345 for (int i = 0; i < 22; i++) { 346 expectEquals(1 << (i + 10), $noinline$geo2(1 << i)); 347 expectEquals(1 << (i + 10), $noinline$geo2_Blocking(1 << i)); 348 } 349 expectEquals(0x80000400, $noinline$geo2(0x00200001)); 350 expectEquals(0x80000400, $noinline$geo2_Blocking(0x00200001)); 351 expectEquals(0x00000000, $noinline$geo2(0x00400000)); 352 expectEquals(0x00000000, $noinline$geo2_Blocking(0x00400000)); 353 expectEquals(0x00000400, $noinline$geo2(0x00400001)); 354 expectEquals(0x00000400, $noinline$geo2_Blocking(0x00400001)); 355 356 int d = 59049; 357 for (int i = -100; i <= 100; i++) { 358 expectEquals(0, $noinline$geo3(i)); 359 expectEquals(0, $noinline$geo3_Blocking(i)); 360 } 361 for (int i = 1; i <= 100; i++) { 362 expectEquals(i, $noinline$geo3(i * d)); 363 expectEquals(i, $noinline$geo3_Blocking(i * d)); 364 expectEquals(i, $noinline$geo3(i * d + 1)); 365 expectEquals(i, $noinline$geo3_Blocking(i * d + 1)); 366 expectEquals(-i, $noinline$geo3(-i * d)); 367 expectEquals(-i, $noinline$geo3_Blocking(-i * d)); 368 expectEquals(-i, $noinline$geo3(-i * d - 1)); 369 expectEquals(-i, $noinline$geo3_Blocking(-i * d - 1)); 370 } 371 372 for (int i = -100; i <= 100; i++) { 373 expectEquals(i % 7, $noinline$geo4(i)); 374 expectEquals(i % 7, $noinline$geo4_Blocking(i)); 375 } 376 377 expectEquals(0x1fffff, $noinline$geo5()); 378 expectEquals(0x1fffff, $noinline$geo5_Blocking()); 379 } 380 381 // Consistency check to see we haven't eliminated the try/catch. 382 /// CHECK-START: int Main.$noinline$poly1() loop_optimization (before) 383 /// CHECK: TryBoundary 384 385 /// CHECK-START: int Main.$noinline$poly1() loop_optimization (before) 386 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 387 /// CHECK-DAG: Add loop:<<Loop>> 388 /// CHECK-DAG: Add loop:<<Loop>> 389 390 /// CHECK-START: int Main.$noinline$poly1() loop_optimization (after) 391 /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none 392 /// CHECK-DAG: <<Int:i\d+>> IntConstant 55 loop:none 393 /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Zer>>] loop:none 394 /// CHECK-DAG: Return [<<Add>>] loop:none 395 396 /// CHECK-START: int Main.$noinline$poly1() instruction_simplifier$before_codegen (after) 397 /// CHECK-DAG: <<Int:i\d+>> IntConstant 55 loop:none 398 /// CHECK-DAG: Return [<<Int>>] loop:none 399 400 /// CHECK-START: int Main.$noinline$poly1() loop_optimization (after) 401 /// CHECK-NOT: Phi $noinline$poly1()402 private static int $noinline$poly1() { 403 int a = 0; 404 for (int i = 0; i <= 10; i++) { 405 a += i; 406 } 407 408 // Outer try catch does not block loop optimizations. 409 try { 410 if (doThrow) { 411 $noinline$unreachable(); 412 } 413 } catch (Error e) { 414 System.out.println("Not expected"); 415 } 416 417 return a; 418 } 419 420 // Consistency check to see we haven't eliminated the try/catch. 421 /// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (before) 422 /// CHECK: TryBoundary 423 424 /// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (before) 425 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 426 /// CHECK-DAG: Add loop:<<Loop>> 427 /// CHECK-DAG: Add loop:<<Loop>> 428 429 /// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (after) 430 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 431 /// CHECK-DAG: Add loop:<<Loop>> 432 /// CHECK-DAG: Add loop:<<Loop>> $noinline$poly1_Blocking()433 private static int $noinline$poly1_Blocking() { 434 int a = 0; 435 for (int i = 0; i <= 10; i++) { 436 a += i; 437 438 // Try catch blocks optimizations. 439 try { 440 if (doThrow) { 441 $noinline$unreachable(); 442 } 443 } catch (Error e) { 444 System.out.println("Not expected"); 445 } 446 } 447 448 return a; 449 } 450 451 // Multiplication in linear induction has been optimized earlier, 452 // but that does not stop the induction variable recognition 453 // and loop optimizer. 454 // 455 // Consistency check to see we haven't eliminated the try/catch. 456 /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (before) 457 /// CHECK: TryBoundary 458 459 /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (before) 460 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 461 /// CHECK-DAG: Shl loop:<<Loop>> 462 /// CHECK-DAG: Add loop:<<Loop>> 463 /// CHECK-DAG: Add loop:<<Loop>> 464 /// CHECK-DAG: Add loop:<<Loop>> 465 /// CHECK-DAG: Add loop:<<Loop>> 466 467 /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (after) 468 /// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none 469 /// CHECK-DAG: <<Int:i\d+>> IntConstant 185 loop:none 470 /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Par>>] loop:none 471 /// CHECK-DAG: Return [<<Add>>] loop:none 472 473 /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (after) 474 /// CHECK-NOT: Phi $noinline$poly2(int a)475 private static int $noinline$poly2(int a) { 476 for (int i = 0; i < 10; i++) { 477 int k = 3 * i + 5; 478 a += k; 479 } 480 481 // Outer try catch does not block loop optimizations. 482 try { 483 if (doThrow) { 484 $noinline$unreachable(); 485 } 486 } catch (Error e) { 487 System.out.println("Not expected"); 488 } 489 return a; 490 } 491 492 // Consistency check to see we haven't eliminated the try/catch. 493 /// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (before) 494 /// CHECK: TryBoundary 495 496 /// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (before) 497 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 498 /// CHECK-DAG: Shl loop:<<Loop>> 499 /// CHECK-DAG: Add loop:<<Loop>> 500 /// CHECK-DAG: Add loop:<<Loop>> 501 /// CHECK-DAG: Add loop:<<Loop>> 502 /// CHECK-DAG: Add loop:<<Loop>> 503 504 /// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (after) 505 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 506 /// CHECK-DAG: Shl loop:<<Loop>> 507 /// CHECK-DAG: Add loop:<<Loop>> 508 /// CHECK-DAG: Add loop:<<Loop>> 509 /// CHECK-DAG: Add loop:<<Loop>> 510 /// CHECK-DAG: Add loop:<<Loop>> $noinline$poly2_Blocking(int a)511 private static int $noinline$poly2_Blocking(int a) { 512 for (int i = 0; i < 10; i++) { 513 int k = 3 * i + 5; 514 a += k; 515 516 // Try catch blocks optimizations. 517 try { 518 if (doThrow) { 519 $noinline$unreachable(); 520 } 521 } catch (Error e) { 522 System.out.println("Not expected"); 523 } 524 } 525 526 return a; 527 } 528 529 // Consistency check to see we haven't eliminated the try/catch. 530 /// CHECK-START: int Main.$noinline$poly3() loop_optimization (before) 531 /// CHECK: TryBoundary 532 533 /// CHECK-START: int Main.$noinline$poly3() loop_optimization (before) 534 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 535 /// CHECK-DAG: Add loop:<<Loop>> 536 /// CHECK-DAG: Add loop:<<Loop>> 537 538 /// CHECK-START: int Main.$noinline$poly3() loop_optimization (after) 539 /// CHECK-DAG: <<Ini:i\d+>> IntConstant 12345 loop:none 540 /// CHECK-DAG: <<Int:i\d+>> IntConstant -2146736968 loop:none 541 /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Ini>>] loop:none 542 /// CHECK-DAG: Return [<<Add>>] loop:none 543 544 /// CHECK-START: int Main.$noinline$poly3() instruction_simplifier$before_codegen (after) 545 /// CHECK-DAG: <<Int:i\d+>> IntConstant -2146724623 loop:none 546 /// CHECK-DAG: Return [<<Int>>] loop:none 547 548 /// CHECK-START: int Main.$noinline$poly3() loop_optimization (after) 549 /// CHECK-NOT: Phi $noinline$poly3()550 private static int $noinline$poly3() { 551 int a = 12345; 552 for (int i = 0; i <= 10; i++) { 553 a += (2147483646 * i + 67890); 554 } 555 556 // Outer try catch does not block loop optimizations. 557 try { 558 if (doThrow) { 559 $noinline$unreachable(); 560 } 561 } catch (Error e) { 562 System.out.println("Not expected"); 563 } 564 return a; 565 } 566 567 // Consistency check to see we haven't eliminated the try/catch. 568 /// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (before) 569 /// CHECK: TryBoundary 570 571 /// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (before) 572 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 573 /// CHECK-DAG: Add loop:<<Loop>> 574 /// CHECK-DAG: Add loop:<<Loop>> 575 576 /// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (after) 577 /// CHECK-DAG: Phi loop:<<Loop:B\d+>> 578 /// CHECK-DAG: Add loop:<<Loop>> 579 /// CHECK-DAG: Add loop:<<Loop>> $noinline$poly3_Blocking()580 private static int $noinline$poly3_Blocking() { 581 int a = 12345; 582 for (int i = 0; i <= 10; i++) { 583 a += (2147483646 * i + 67890); 584 585 // Try catch blocks optimizations. 586 try { 587 if (doThrow) { 588 $noinline$unreachable(); 589 } 590 } catch (Error e) { 591 System.out.println("Not expected"); 592 } 593 } 594 return a; 595 } 596 597 // Tests taken from 530-checker-loops5 $noinline$loops5Tests()598 private static void $noinline$loops5Tests() { 599 expectEquals(55, $noinline$poly1()); 600 expectEquals(55, $noinline$poly1_Blocking()); 601 expectEquals(185, $noinline$poly2(0)); 602 expectEquals(185, $noinline$poly2_Blocking(0)); 603 expectEquals(192, $noinline$poly2(7)); 604 expectEquals(192, $noinline$poly2_Blocking(7)); 605 expectEquals(-2146724623, $noinline$poly3()); 606 expectEquals(-2146724623, $noinline$poly3_Blocking()); 607 } 608 609 // Constants used for peel unroll tests. 610 private static final int LENGTH = 4 * 1024; 611 private static final int RESULT_POS = 4; 612 initIntArray(int[] a)613 private static final void initIntArray(int[] a) { 614 for (int i = 0; i < a.length; i++) { 615 a[i] = i % 4; 616 } 617 } 618 619 // Consistency check to see we haven't eliminated the try/catch. 620 /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after) 621 /// CHECK: TryBoundary 622 623 /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (before) 624 /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none 625 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 626 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none 627 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 628 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none 629 /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none 630 /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none 631 /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none 632 /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none 633 /// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none 634 /// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none 635 636 /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (before) 637 /// CHECK: ArrayGet 638 /// CHECK: ArrayGet 639 /// CHECK-NOT: ArrayGet 640 641 /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (before) 642 /// CHECK: ArraySet 643 /// CHECK-NOT: ArraySet 644 645 /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after) 646 /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none 647 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 648 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 649 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none 650 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 651 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none 652 /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none 653 /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none 654 /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none 655 /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none 656 /// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none 657 /// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none 658 // 659 /// CHECK-DAG: <<CheckA:z\d+>> GreaterThanOrEqual [<<IndAdd>>,<<Limit>>] loop:<<Loop>> outer_loop:none 660 /// CHECK-DAG: <<IfA:v\d+>> If [<<Const0>>] loop:<<Loop>> outer_loop:none 661 /// CHECK-DAG: <<Get0A:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none 662 /// CHECK-DAG: <<IndAddA:i\d+>> Add [<<IndAdd>>,<<Const1>>] loop:<<Loop>> outer_loop:none 663 /// CHECK-DAG: <<Get1A:i\d+>> ArrayGet [<<Array>>,<<IndAddA>>] loop:<<Loop>> outer_loop:none 664 /// CHECK-DAG: <<AddA:i\d+>> Add [<<Get0A>>,<<Get1A>>] loop:<<Loop>> outer_loop:none 665 /// CHECK-DAG: ArraySet [<<Array>>,<<IndAdd>>,<<AddA>>] loop:<<Loop>> outer_loop:none 666 667 /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after) 668 /// CHECK: ArrayGet 669 /// CHECK: ArrayGet 670 /// CHECK: ArrayGet 671 /// CHECK: ArrayGet 672 /// CHECK-NOT: ArrayGet 673 674 /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after) 675 /// CHECK: ArraySet 676 /// CHECK: ArraySet 677 /// CHECK-NOT: ArraySet $noinline$unrollingLoadStoreElimination(int[] a)678 private static final void $noinline$unrollingLoadStoreElimination(int[] a) { 679 for (int i = 0; i < LENGTH - 2; i++) { 680 a[i] += a[i + 1]; 681 } 682 683 // Outer try catch does not block loop optimizations. 684 try { 685 if (doThrow) { 686 $noinline$unreachable(); 687 } 688 } catch (Error e) { 689 System.out.println("Not expected"); 690 } 691 } 692 693 // Consistency check to see we haven't eliminated the try/catch. 694 /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after) 695 /// CHECK: TryBoundary 696 697 /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (before) 698 /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none 699 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 700 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none 701 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 702 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none 703 /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none 704 /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none 705 /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none 706 /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none 707 /// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none 708 /// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none 709 710 /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (before) 711 /// CHECK: ArrayGet 712 /// CHECK: ArrayGet 713 /// CHECK-NOT: ArrayGet 714 715 /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (before) 716 /// CHECK: ArraySet 717 /// CHECK-NOT: ArraySet 718 719 /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after) 720 /// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none 721 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 722 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none 723 /// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none 724 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none 725 /// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none 726 /// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none 727 /// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none 728 /// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none 729 /// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none 730 /// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none 731 732 /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after) 733 /// CHECK: ArrayGet 734 /// CHECK: ArrayGet 735 /// CHECK-NOT: ArrayGet 736 737 /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after) 738 /// CHECK: ArraySet 739 /// CHECK-NOT: ArraySet $noinline$unrollingLoadStoreElimination_Blocking(int[] a)740 private static final void $noinline$unrollingLoadStoreElimination_Blocking(int[] a) { 741 for (int i = 0; i < LENGTH - 2; i++) { 742 a[i] += a[i + 1]; 743 744 // Try catch blocks optimizations. 745 try { 746 if (doThrow) { 747 $noinline$unreachable(); 748 } 749 } catch (Error e) { 750 System.out.println("Not expected"); 751 } 752 } 753 } 754 755 // Consistency check to see we haven't eliminated the try/catch. 756 /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after) 757 /// CHECK: TryBoundary 758 759 /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before) 760 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 761 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 762 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 763 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 764 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 765 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>> 766 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>> 767 /// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>> 768 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 769 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 770 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 771 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 772 /// CHECK-DAG: Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>> 773 774 // Each one of the three `for` loops has an `if`. The try catch has the 4th `if`. 775 /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before) 776 /// CHECK: If 777 /// CHECK: If 778 /// CHECK: If 779 /// CHECK: If 780 /// CHECK-NOT: If 781 782 /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before) 783 /// CHECK: ArrayGet 784 /// CHECK: ArrayGet 785 /// CHECK-NOT: ArrayGet 786 787 /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before) 788 /// CHECK: ArraySet 789 /// CHECK: ArraySet 790 /// CHECK-NOT: ArraySet 791 792 /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after) 793 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 794 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 795 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 796 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 797 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 798 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>> 799 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>> 800 /// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>> 801 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 802 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 803 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 804 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 805 /// CHECK-DAG: <<AddI:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>> 806 // 807 /// CHECK-DAG: If [<<Const0>>] loop:<<Loop3>> outer_loop:<<Loop2>> 808 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 809 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 810 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 811 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 812 813 // Loop unrolling adds a 5th `if`. It is the one with `Const0` above. 814 /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after) 815 /// CHECK: If 816 /// CHECK: If 817 /// CHECK: If 818 /// CHECK: If 819 /// CHECK: If 820 /// CHECK-NOT: If 821 822 /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after) 823 /// CHECK: ArrayGet 824 /// CHECK: ArrayGet 825 /// CHECK: ArrayGet 826 /// CHECK: ArrayGet 827 /// CHECK-NOT: ArrayGet 828 829 /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after) 830 /// CHECK: ArraySet 831 /// CHECK: ArraySet 832 /// CHECK: ArraySet 833 /// CHECK: ArraySet 834 /// CHECK-NOT: ArraySet $noinline$unrollingInTheNest(int[] a, int[] b, int x)835 private static final void $noinline$unrollingInTheNest(int[] a, int[] b, int x) { 836 for (int k = 0; k < 16; k++) { 837 for (int j = 0; j < 16; j++) { 838 for (int i = 0; i < 128; i++) { 839 b[x]++; 840 a[i] = a[i] + 1; 841 } 842 } 843 } 844 845 // Outer try catch does not block loop optimizations. 846 try { 847 if (doThrow) { 848 $noinline$unreachable(); 849 } 850 } catch (Error e) { 851 System.out.println("Not expected"); 852 } 853 } 854 855 // Consistency check to see we haven't eliminated the try/catch. 856 /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after) 857 /// CHECK: TryBoundary 858 859 /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before) 860 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 861 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 862 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 863 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 864 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 865 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>> 866 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>> 867 /// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>> 868 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 869 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 870 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 871 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 872 // 873 /// CHECK-DAG: Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>> 874 875 // Each one of the three `for` loops has an `if`. The try catch has the 4th `if`. 876 /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before) 877 /// CHECK: If 878 /// CHECK: If 879 /// CHECK: If 880 /// CHECK: If 881 /// CHECK-NOT: If 882 883 /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before) 884 /// CHECK: ArrayGet 885 /// CHECK: ArrayGet 886 /// CHECK-NOT: ArrayGet 887 888 /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before) 889 /// CHECK: ArraySet 890 /// CHECK: ArraySet 891 /// CHECK-NOT: ArraySet 892 893 /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after) 894 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 895 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 896 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 897 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 898 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 899 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>> 900 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>> 901 /// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>> 902 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 903 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 904 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 905 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 906 // 907 /// CHECK-DAG: Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>> 908 909 /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after) 910 /// CHECK: If 911 /// CHECK: If 912 /// CHECK: If 913 /// CHECK: If 914 /// CHECK-NOT: If 915 916 /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after) 917 /// CHECK: ArrayGet 918 /// CHECK: ArrayGet 919 /// CHECK-NOT: ArrayGet 920 921 /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after) 922 /// CHECK: ArraySet 923 /// CHECK: ArraySet 924 /// CHECK-NOT: ArraySet $noinline$unrollingInTheNest_Blocking(int[] a, int[] b, int x)925 private static final void $noinline$unrollingInTheNest_Blocking(int[] a, int[] b, int x) { 926 for (int k = 0; k < 16; k++) { 927 for (int j = 0; j < 16; j++) { 928 for (int i = 0; i < 128; i++) { 929 b[x]++; 930 a[i] = a[i] + 1; 931 932 // Try catch blocks optimizations. 933 try { 934 if (doThrow) { 935 $noinline$unreachable(); 936 } 937 } catch (Error e) { 938 System.out.println("Not expected"); 939 } 940 } 941 } 942 } 943 } 944 945 // Consistency check to see we haven't eliminated the try/catch. 946 /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after) 947 /// CHECK: TryBoundary 948 949 /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before) 950 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 951 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 952 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 953 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 954 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 955 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>> 956 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>> 957 /// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>> 958 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 959 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 960 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 961 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 962 // 963 /// CHECK-DAG: Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>> 964 965 // Each one of the three `for` loops has an `if`. The try catch has the 4th `if`. 966 /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before) 967 /// CHECK: If 968 /// CHECK: If 969 /// CHECK: If 970 /// CHECK: If 971 /// CHECK-NOT: If 972 973 /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before) 974 /// CHECK: ArrayGet 975 /// CHECK: ArrayGet 976 /// CHECK-NOT: ArrayGet 977 978 /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before) 979 /// CHECK: ArraySet 980 /// CHECK: ArraySet 981 /// CHECK-NOT: ArraySet 982 983 /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after) 984 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 985 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 986 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 987 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 988 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 989 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>> 990 /// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>> 991 /// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>> 992 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 993 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 994 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 995 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 996 /// CHECK-DAG: <<AddI:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>> 997 // 998 /// CHECK-DAG: If [<<Const0>>] loop:<<Loop3>> outer_loop:<<Loop2>> 999 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 1000 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 1001 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>> 1002 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>> 1003 1004 // Loop unrolling adds a 5th `if`. It is the one with `Const0` above. 1005 /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after) 1006 /// CHECK: If 1007 /// CHECK: If 1008 /// CHECK: If 1009 /// CHECK: If 1010 /// CHECK: If 1011 /// CHECK-NOT: If 1012 1013 /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after) 1014 /// CHECK: ArrayGet 1015 /// CHECK: ArrayGet 1016 /// CHECK: ArrayGet 1017 /// CHECK: ArrayGet 1018 /// CHECK-NOT: ArrayGet 1019 1020 /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after) 1021 /// CHECK: ArraySet 1022 /// CHECK: ArraySet 1023 /// CHECK: ArraySet 1024 /// CHECK: ArraySet 1025 /// CHECK-NOT: ArraySet $noinline$unrollingInTheNest_TryCatchNotBlocking(int[] a, int[] b, int x)1026 private static final void $noinline$unrollingInTheNest_TryCatchNotBlocking(int[] a, int[] b, int x) { 1027 for (int k = 0; k < 16; k++) { 1028 for (int j = 0; j < 16; j++) { 1029 for (int i = 0; i < 128; i++) { 1030 b[x]++; 1031 a[i] = a[i] + 1; 1032 } 1033 // Try catch does not block the optimization in the innermost loop. 1034 try { 1035 if (doThrow) { 1036 $noinline$unreachable(); 1037 } 1038 } catch (Error e) { 1039 System.out.println("Not expected"); 1040 } 1041 } 1042 } 1043 } 1044 1045 // Consistency check to see we haven't eliminated the try/catch. 1046 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after) 1047 /// CHECK: TryBoundary 1048 1049 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before) 1050 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 1051 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 1052 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 1053 /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none 1054 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 1055 // 1056 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 1057 /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1058 /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1059 /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>> 1060 /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>> 1061 /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1062 // 1063 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>> 1064 /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1065 /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1066 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>> 1067 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>> 1068 /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1069 1070 // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catch has the 5th `if`. 1071 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before) 1072 /// CHECK: If 1073 /// CHECK: If 1074 /// CHECK: If 1075 /// CHECK: If 1076 /// CHECK: If 1077 /// CHECK-NOT: If 1078 1079 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before) 1080 /// CHECK: ArrayGet 1081 /// CHECK: ArrayGet 1082 /// CHECK-NOT: ArrayGet 1083 1084 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before) 1085 /// CHECK: ArraySet 1086 /// CHECK: ArraySet 1087 /// CHECK-NOT: ArraySet 1088 1089 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after) 1090 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 1091 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 1092 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 1093 /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none 1094 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 1095 // 1096 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 1097 /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1098 /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1099 /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>> 1100 /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>> 1101 /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1102 /// CHECK-DAG: If [<<Const0>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1103 /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>> 1104 /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>> 1105 /// CHECK-DAG: Add [<<AddI2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1106 // 1107 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>> 1108 /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1109 /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1110 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>> 1111 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>> 1112 /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1113 /// CHECK-DAG: If [<<Const0>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1114 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>> 1115 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>> 1116 /// CHECK-DAG: Add [<<AddI3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1117 1118 // LoopOptimization adds two `if`s. One for each loop unrolling. 1119 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after) 1120 /// CHECK: If 1121 /// CHECK: If 1122 /// CHECK: If 1123 /// CHECK: If 1124 /// CHECK: If 1125 /// CHECK: If 1126 /// CHECK: If 1127 /// CHECK-NOT: If 1128 1129 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after) 1130 /// CHECK: ArrayGet 1131 /// CHECK: ArrayGet 1132 /// CHECK: ArrayGet 1133 /// CHECK: ArrayGet 1134 /// CHECK-NOT: ArrayGet 1135 1136 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after) 1137 /// CHECK: ArraySet 1138 /// CHECK: ArraySet 1139 /// CHECK: ArraySet 1140 /// CHECK: ArraySet 1141 /// CHECK-NOT: ArraySet $noinline$unrollingTwoLoopsInTheNest(int[] a, int[] b, int x)1142 private static final void $noinline$unrollingTwoLoopsInTheNest(int[] a, int[] b, int x) { 1143 for (int k = 0; k < 128; k++) { 1144 if (x > 100) { 1145 for (int j = 0; j < 128; j++) { 1146 a[x]++; 1147 } 1148 } else { 1149 for (int i = 0; i < 128; i++) { 1150 b[x]++; 1151 } 1152 } 1153 } 1154 1155 // Outer try catch does not block loop optimizations. 1156 try { 1157 if (doThrow) { 1158 $noinline$unreachable(); 1159 } 1160 } catch (Error e) { 1161 System.out.println("Not expected"); 1162 } 1163 } 1164 1165 // Consistency check to see we haven't eliminated the try/catch. 1166 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after) 1167 /// CHECK: TryBoundary 1168 1169 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before) 1170 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 1171 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 1172 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 1173 /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none 1174 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 1175 // 1176 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 1177 /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1178 /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1179 /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>> 1180 /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>> 1181 // 1182 /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1183 // 1184 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>> 1185 /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1186 /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1187 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>> 1188 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>> 1189 /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1190 1191 // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catch has the 5th `if`. 1192 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before) 1193 /// CHECK: If 1194 /// CHECK: If 1195 /// CHECK: If 1196 /// CHECK: If 1197 /// CHECK: If 1198 /// CHECK-NOT: If 1199 1200 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before) 1201 /// CHECK: ArrayGet 1202 /// CHECK: ArrayGet 1203 /// CHECK-NOT: ArrayGet 1204 1205 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before) 1206 /// CHECK: ArraySet 1207 /// CHECK: ArraySet 1208 /// CHECK-NOT: ArraySet 1209 1210 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after) 1211 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 1212 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 1213 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 1214 /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none 1215 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 1216 // 1217 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 1218 /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1219 /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1220 /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>> 1221 /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>> 1222 // 1223 // Unrelated to the optimization itself, the try catch has an if. 1224 /// CHECK-DAG: <<Get:z\d+>> StaticFieldGet field_name:Main.doThrow 1225 /// CHECK-DAG: If [<<Get>>] 1226 // 1227 /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1228 // 1229 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>> 1230 /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1231 /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1232 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>> 1233 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>> 1234 /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1235 /// CHECK-DAG: If [<<Const0>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1236 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>> 1237 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>> 1238 /// CHECK-DAG: Add [<<AddI3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1239 1240 // LoopOptimization adds two `if`s. One for each loop unrolling. 1241 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after) 1242 /// CHECK: If 1243 /// CHECK: If 1244 /// CHECK: If 1245 /// CHECK: If 1246 /// CHECK: If 1247 /// CHECK: If 1248 /// CHECK-NOT: If 1249 1250 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after) 1251 /// CHECK: ArrayGet 1252 /// CHECK: ArrayGet 1253 /// CHECK: ArrayGet 1254 /// CHECK-NOT: ArrayGet 1255 1256 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after) 1257 /// CHECK: ArraySet 1258 /// CHECK: ArraySet 1259 /// CHECK: ArraySet 1260 /// CHECK-NOT: ArraySet $noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[] a, int[] b, int x)1261 private static final void $noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[] a, int[] b, int x) { 1262 for (int k = 0; k < 128; k++) { 1263 if (x > 100) { 1264 for (int j = 0; j < 128; j++) { 1265 a[x]++; 1266 // Try catch blocks optimizations. 1267 try { 1268 if (doThrow) { 1269 $noinline$unreachable(); 1270 } 1271 } catch (Error e) { 1272 System.out.println("Not expected"); 1273 } 1274 } 1275 } else { 1276 for (int i = 0; i < 128; i++) { 1277 b[x]++; 1278 } 1279 } 1280 } 1281 } 1282 1283 // Consistency check to see we haven't eliminated the try/catch. 1284 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after) 1285 /// CHECK: TryBoundary 1286 1287 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before) 1288 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 1289 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 1290 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 1291 /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none 1292 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 1293 // 1294 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 1295 /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1296 /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1297 /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>> 1298 /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>> 1299 /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1300 // 1301 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>> 1302 /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1303 /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1304 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>> 1305 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>> 1306 // 1307 /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1308 1309 // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catch has the 5th `if`. 1310 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before) 1311 /// CHECK: If 1312 /// CHECK: If 1313 /// CHECK: If 1314 /// CHECK: If 1315 /// CHECK: If 1316 /// CHECK-NOT: If 1317 1318 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before) 1319 /// CHECK: ArrayGet 1320 /// CHECK: ArrayGet 1321 /// CHECK-NOT: ArrayGet 1322 1323 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before) 1324 /// CHECK: ArraySet 1325 /// CHECK: ArraySet 1326 /// CHECK-NOT: ArraySet 1327 1328 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after) 1329 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 1330 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 1331 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 1332 /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none 1333 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 1334 // 1335 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 1336 /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1337 /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1338 /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>> 1339 /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>> 1340 /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1341 /// CHECK-DAG: If [<<Const0>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1342 /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>> 1343 /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>> 1344 /// CHECK-DAG: Add [<<AddI2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1345 // 1346 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>> 1347 /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1348 /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1349 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>> 1350 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>> 1351 // 1352 /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1353 1354 // LoopOptimization adds two `if`s. One for each loop unrolling. 1355 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after) 1356 /// CHECK: If 1357 /// CHECK: If 1358 /// CHECK: If 1359 /// CHECK: If 1360 /// CHECK: If 1361 /// CHECK: If 1362 /// CHECK-NOT: If 1363 1364 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after) 1365 /// CHECK: ArrayGet 1366 /// CHECK: ArrayGet 1367 /// CHECK: ArrayGet 1368 /// CHECK-NOT: ArrayGet 1369 1370 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after) 1371 /// CHECK: ArraySet 1372 /// CHECK: ArraySet 1373 /// CHECK: ArraySet 1374 /// CHECK-NOT: ArraySet $noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[] a, int[] b, int x)1375 private static final void $noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[] a, int[] b, int x) { 1376 for (int k = 0; k < 128; k++) { 1377 if (x > 100) { 1378 for (int j = 0; j < 128; j++) { 1379 a[x]++; 1380 } 1381 } else { 1382 for (int i = 0; i < 128; i++) { 1383 b[x]++; 1384 // Try catch blocks optimizations. 1385 try { 1386 if (doThrow) { 1387 $noinline$unreachable(); 1388 } 1389 } catch (Error e) { 1390 System.out.println("Not expected"); 1391 } 1392 } 1393 } 1394 } 1395 } 1396 1397 // Consistency check to see we haven't eliminated the try/catch. 1398 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after) 1399 /// CHECK: TryBoundary 1400 1401 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before) 1402 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 1403 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 1404 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 1405 /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none 1406 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 1407 // 1408 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 1409 /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1410 /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1411 /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>> 1412 /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>> 1413 // 1414 /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1415 // 1416 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>> 1417 /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1418 /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1419 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>> 1420 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>> 1421 // 1422 /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1423 1424 // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catchs have the 5th and 6th `if`. 1425 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before) 1426 /// CHECK: If 1427 /// CHECK: If 1428 /// CHECK: If 1429 /// CHECK: If 1430 /// CHECK: If 1431 /// CHECK: If 1432 /// CHECK-NOT: If 1433 1434 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before) 1435 /// CHECK: ArrayGet 1436 /// CHECK: ArrayGet 1437 /// CHECK-NOT: ArrayGet 1438 1439 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before) 1440 /// CHECK: ArraySet 1441 /// CHECK: ArraySet 1442 /// CHECK-NOT: ArraySet 1443 1444 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after) 1445 /// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none 1446 /// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none 1447 /// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none 1448 /// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none 1449 /// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none 1450 // 1451 /// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>> 1452 /// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1453 /// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1454 /// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>> 1455 /// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>> 1456 // 1457 // Unrelated to the optimization itself, the try catch has an if. 1458 /// CHECK-DAG: <<Get1:z\d+>> StaticFieldGet field_name:Main.doThrow 1459 /// CHECK-DAG: If [<<Get1>>] 1460 // 1461 /// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>> 1462 // 1463 /// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>> 1464 /// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1465 /// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1466 /// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>> 1467 /// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>> 1468 // 1469 /// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>> 1470 1471 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after) 1472 /// CHECK: If 1473 /// CHECK: If 1474 /// CHECK: If 1475 /// CHECK: If 1476 /// CHECK: If 1477 /// CHECK: If 1478 /// CHECK-NOT: If 1479 1480 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after) 1481 /// CHECK: ArrayGet 1482 /// CHECK: ArrayGet 1483 /// CHECK-NOT: ArrayGet 1484 1485 /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after) 1486 /// CHECK: ArraySet 1487 /// CHECK: ArraySet 1488 /// CHECK-NOT: ArraySet $noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[] a, int[] b, int x)1489 private static final void $noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[] a, int[] b, int x) { 1490 for (int k = 0; k < 128; k++) { 1491 if (x > 100) { 1492 for (int j = 0; j < 128; j++) { 1493 a[x]++; 1494 // Try catch blocks optimizations. 1495 try { 1496 if (doThrow) { 1497 $noinline$unreachable(); 1498 } 1499 } catch (Error e) { 1500 System.out.println("Not expected"); 1501 } 1502 } 1503 } else { 1504 for (int i = 0; i < 128; i++) { 1505 b[x]++; 1506 // Try catch blocks optimizations. 1507 try { 1508 if (doThrow) { 1509 $noinline$unreachable(); 1510 } 1511 } catch (Error e) { 1512 System.out.println("Not expected"); 1513 } 1514 } 1515 } 1516 } 1517 } 1518 1519 // Tests taken from 530-checker-peel-unroll $noinline$peelUnrollTests()1520 private static void $noinline$peelUnrollTests() { 1521 int[] a = new int[LENGTH]; 1522 int[] b = new int[LENGTH]; 1523 initIntArray(a); 1524 initIntArray(b); 1525 1526 $noinline$unrollingLoadStoreElimination(a); 1527 $noinline$unrollingLoadStoreElimination_Blocking(a); 1528 $noinline$unrollingInTheNest(a, b, RESULT_POS); 1529 $noinline$unrollingInTheNest_Blocking(a, b, RESULT_POS); 1530 $noinline$unrollingInTheNest_TryCatchNotBlocking(a, b, RESULT_POS); 1531 $noinline$unrollingTwoLoopsInTheNest(a, b, RESULT_POS); 1532 $noinline$unrollingTwoLoopsInTheNest_OneBlocking(a, b, RESULT_POS); 1533 $noinline$unrollingTwoLoopsInTheNest_OtherBlocking(a, b, RESULT_POS); 1534 $noinline$unrollingTwoLoopsInTheNest_BothBlocking(a, b, RESULT_POS); 1535 } 1536 main(String[] args)1537 public static void main(String[] args) { 1538 // Use existing tests to show that the difference between having a try catch inside or outside 1539 // the loop. 1540 $noinline$loops4Tests(); 1541 $noinline$loops5Tests(); 1542 $noinline$peelUnrollTests(); 1543 1544 System.out.println("passed"); 1545 } 1546 expectEquals(int expected, int result)1547 private static void expectEquals(int expected, int result) { 1548 if (expected != result) { 1549 throw new Error("Expected: " + expected + ", found: " + result); 1550 } 1551 } 1552 $noinline$unreachable()1553 private static void $noinline$unreachable() { 1554 throw new Error("Unreachable"); 1555 } 1556 1557 private static boolean doThrow = false; 1558 } 1559