blob: 7927d9b30d214c565ccd0741b2803e4416887a5d [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//
// Test on loop optimizations, in particular with try catches.
//
public class Main {
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Mul loop:<<Loop>>
/// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (after)
/// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none
/// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Int:i\d+>> IntConstant 1410065408 loop:none
/// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>] loop:none
/// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Zer>>] loop:none
/// CHECK-DAG: Return [<<Add>>] loop:none
/// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (after)
/// CHECK-NOT: Phi
private static int $noinline$geo1(int a) {
for (int i = 0; i < 10; i++) {
a *= 10;
}
// Outer try catch does not block loop optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
return a;
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Mul loop:<<Loop>>
/// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (after)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Mul loop:<<Loop>>
private static int $noinline$geo1_Blocking(int a) {
for (int i = 0; i < 10; i++) {
a *= 10;
// Try catch blocks optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
return a;
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Shl loop:<<Loop>>
/// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (after)
/// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none
/// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Int:i\d+>> IntConstant 1024 loop:none
/// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>] loop:none
/// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Zer>>] loop:none
/// CHECK-DAG: Return [<<Add>>] loop:none
/// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (after)
/// CHECK-NOT: Phi
private static int $noinline$geo2(int a) {
for (int i = 0; i < 10; i++) {
a <<= 1;
}
// Outer try catch does not block loop optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
return a;
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Shl loop:<<Loop>>
/// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (after)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Shl loop:<<Loop>>
private static int $noinline$geo2_Blocking(int a) {
for (int i = 0; i < 10; i++) {
a <<= 1;
// Try catch blocks optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
return a;
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Div loop:<<Loop>>
/// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (after)
/// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none
/// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Int:i\d+>> IntConstant 59049 loop:none
/// CHECK-DAG: <<Div:i\d+>> Div [<<Par>>,<<Int>>] loop:none
/// CHECK-DAG: <<Add:i\d+>> Add [<<Div>>,<<Zer>>] loop:none
/// CHECK-DAG: Return [<<Add>>] loop:none
/// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (after)
/// CHECK-NOT: Phi
private static int $noinline$geo3(int a) {
for (int i = 0; i < 10; i++) {
a /= 3;
}
// Outer try catch does not block loop optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
return a;
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Div loop:<<Loop>>
/// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (after)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Div loop:<<Loop>>
private static int $noinline$geo3_Blocking(int a) {
for (int i = 0; i < 10; i++) {
a /= 3;
// Try catch blocks optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
return a;
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Rem loop:<<Loop>>
/// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (after)
/// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none
/// CHECK-DAG: <<Int:i\d+>> IntConstant 7 loop:none
/// CHECK-DAG: <<Rem:i\d+>> Rem [<<Par>>,<<Int>>] loop:none
/// CHECK-DAG: Return [<<Rem>>] loop:none
/// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (after)
/// CHECK-NOT: Phi
private static int $noinline$geo4(int a) {
for (int i = 0; i < 10; i++) {
a %= 7; // a wrap-around induction
}
// Outer try catch does not block loop optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
return a;
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Rem loop:<<Loop>>
/// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (after)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Rem loop:<<Loop>>
private static int $noinline$geo4_Blocking(int a) {
for (int i = 0; i < 10; i++) {
a %= 7; // a wrap-around induction
// Try catch blocks optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
return a;
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$geo5() loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$geo5() loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Shr loop:<<Loop>>
/// CHECK-START: int Main.$noinline$geo5() loop_optimization (after)
/// CHECK-DAG: <<Zero:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Int1:i\d+>> IntConstant 2147483647 loop:none
/// CHECK-DAG: <<Int2:i\d+>> IntConstant 1024 loop:none
/// CHECK-DAG: <<Div:i\d+>> Div [<<Int1>>,<<Int2>>] loop:none
/// CHECK-DAG: <<Add:i\d+>> Add [<<Div>>,<<Zero>>] loop:none
/// CHECK-DAG: Return [<<Add>>] loop:none
/// CHECK-START: int Main.$noinline$geo5() loop_optimization (after)
/// CHECK-NOT: Phi
private static int $noinline$geo5() {
int a = 0x7fffffff;
for (int i = 0; i < 10; i++) {
a >>= 1;
}
// Outer try catch does not block loop optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
return a;
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Shr loop:<<Loop>>
/// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (after)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Shr loop:<<Loop>>
private static int $noinline$geo5_Blocking() {
int a = 0x7fffffff;
for (int i = 0; i < 10; i++) {
a >>= 1;
// Try catch blocks optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
return a;
}
// Tests taken from 530-checker-loops4
private static void $noinline$loops4Tests() {
int m = 1410065408;
for (int i = -100; i <= 100; i++) {
expectEquals(m * i, $noinline$geo1(i));
expectEquals(m * i, $noinline$geo1_Blocking(i));
}
for (int i = 1; i <= 1000000000; i *= 10) {
expectEquals(m * i, $noinline$geo1(i));
expectEquals(m * i, $noinline$geo1_Blocking(i));
expectEquals(-m * i, $noinline$geo1(-i));
expectEquals(-m * i, $noinline$geo1_Blocking(-i));
}
for (int i = -100; i <= 100; i++) {
expectEquals(i << 10, $noinline$geo2(i));
expectEquals(i << 10, $noinline$geo2_Blocking(i));
}
for (int i = 0; i < 22; i++) {
expectEquals(1 << (i + 10), $noinline$geo2(1 << i));
expectEquals(1 << (i + 10), $noinline$geo2_Blocking(1 << i));
}
expectEquals(0x80000400, $noinline$geo2(0x00200001));
expectEquals(0x80000400, $noinline$geo2_Blocking(0x00200001));
expectEquals(0x00000000, $noinline$geo2(0x00400000));
expectEquals(0x00000000, $noinline$geo2_Blocking(0x00400000));
expectEquals(0x00000400, $noinline$geo2(0x00400001));
expectEquals(0x00000400, $noinline$geo2_Blocking(0x00400001));
int d = 59049;
for (int i = -100; i <= 100; i++) {
expectEquals(0, $noinline$geo3(i));
expectEquals(0, $noinline$geo3_Blocking(i));
}
for (int i = 1; i <= 100; i++) {
expectEquals(i, $noinline$geo3(i * d));
expectEquals(i, $noinline$geo3_Blocking(i * d));
expectEquals(i, $noinline$geo3(i * d + 1));
expectEquals(i, $noinline$geo3_Blocking(i * d + 1));
expectEquals(-i, $noinline$geo3(-i * d));
expectEquals(-i, $noinline$geo3_Blocking(-i * d));
expectEquals(-i, $noinline$geo3(-i * d - 1));
expectEquals(-i, $noinline$geo3_Blocking(-i * d - 1));
}
for (int i = -100; i <= 100; i++) {
expectEquals(i % 7, $noinline$geo4(i));
expectEquals(i % 7, $noinline$geo4_Blocking(i));
}
expectEquals(0x1fffff, $noinline$geo5());
expectEquals(0x1fffff, $noinline$geo5_Blocking());
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$poly1() loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$poly1() loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-START: int Main.$noinline$poly1() loop_optimization (after)
/// CHECK-DAG: <<Zer:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Int:i\d+>> IntConstant 55 loop:none
/// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Zer>>] loop:none
/// CHECK-DAG: Return [<<Add>>] loop:none
/// CHECK-START: int Main.$noinline$poly1() instruction_simplifier$before_codegen (after)
/// CHECK-DAG: <<Int:i\d+>> IntConstant 55 loop:none
/// CHECK-DAG: Return [<<Int>>] loop:none
/// CHECK-START: int Main.$noinline$poly1() loop_optimization (after)
/// CHECK-NOT: Phi
private static int $noinline$poly1() {
int a = 0;
for (int i = 0; i <= 10; i++) {
a += i;
}
// Outer try catch does not block loop optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
return a;
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (after)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
private static int $noinline$poly1_Blocking() {
int a = 0;
for (int i = 0; i <= 10; i++) {
a += i;
// Try catch blocks optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
return a;
}
// Multiplication in linear induction has been optimized earlier,
// but that does not stop the induction variable recognition
// and loop optimizer.
//
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Shl loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (after)
/// CHECK-DAG: <<Par:i\d+>> ParameterValue loop:none
/// CHECK-DAG: <<Int:i\d+>> IntConstant 185 loop:none
/// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Par>>] loop:none
/// CHECK-DAG: Return [<<Add>>] loop:none
/// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (after)
/// CHECK-NOT: Phi
private static int $noinline$poly2(int a) {
for (int i = 0; i < 10; i++) {
int k = 3 * i + 5;
a += k;
}
// Outer try catch does not block loop optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
return a;
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Shl loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (after)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Shl loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
private static int $noinline$poly2_Blocking(int a) {
for (int i = 0; i < 10; i++) {
int k = 3 * i + 5;
a += k;
// Try catch blocks optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
return a;
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$poly3() loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$poly3() loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-START: int Main.$noinline$poly3() loop_optimization (after)
/// CHECK-DAG: <<Ini:i\d+>> IntConstant 12345 loop:none
/// CHECK-DAG: <<Int:i\d+>> IntConstant -2146736968 loop:none
/// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Ini>>] loop:none
/// CHECK-DAG: Return [<<Add>>] loop:none
/// CHECK-START: int Main.$noinline$poly3() instruction_simplifier$before_codegen (after)
/// CHECK-DAG: <<Int:i\d+>> IntConstant -2146724623 loop:none
/// CHECK-DAG: Return [<<Int>>] loop:none
/// CHECK-START: int Main.$noinline$poly3() loop_optimization (after)
/// CHECK-NOT: Phi
private static int $noinline$poly3() {
int a = 12345;
for (int i = 0; i <= 10; i++) {
a += (2147483646 * i + 67890);
}
// Outer try catch does not block loop optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
return a;
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (before)
/// CHECK: TryBoundary
/// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (before)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (after)
/// CHECK-DAG: Phi loop:<<Loop:B\d+>>
/// CHECK-DAG: Add loop:<<Loop>>
/// CHECK-DAG: Add loop:<<Loop>>
private static int $noinline$poly3_Blocking() {
int a = 12345;
for (int i = 0; i <= 10; i++) {
a += (2147483646 * i + 67890);
// Try catch blocks optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
return a;
}
// Tests taken from 530-checker-loops5
private static void $noinline$loops5Tests() {
expectEquals(55, $noinline$poly1());
expectEquals(55, $noinline$poly1_Blocking());
expectEquals(185, $noinline$poly2(0));
expectEquals(185, $noinline$poly2_Blocking(0));
expectEquals(192, $noinline$poly2(7));
expectEquals(192, $noinline$poly2_Blocking(7));
expectEquals(-2146724623, $noinline$poly3());
expectEquals(-2146724623, $noinline$poly3_Blocking());
}
// Constants used for peel unroll tests.
private static final int LENGTH = 4 * 1024;
private static final int RESULT_POS = 4;
private static final void initIntArray(int[] a) {
for (int i = 0; i < a.length; i++) {
a[i] = i % 4;
}
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
/// CHECK: TryBoundary
/// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (before)
/// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
/// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none
/// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (before)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (before)
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
/// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
/// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
/// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none
//
/// CHECK-DAG: <<CheckA:z\d+>> GreaterThanOrEqual [<<IndAdd>>,<<Limit>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<IfA:v\d+>> If [<<Const0>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Get0A:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<IndAddA:i\d+>> Add [<<IndAdd>>,<<Const1>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Get1A:i\d+>> ArrayGet [<<Array>>,<<IndAddA>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<AddA:i\d+>> Add [<<Get0A>>,<<Get1A>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet [<<Array>>,<<IndAdd>>,<<AddA>>] loop:<<Loop>> outer_loop:none
/// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
private static final void $noinline$unrollingLoadStoreElimination(int[] a) {
for (int i = 0; i < LENGTH - 2; i++) {
a[i] += a[i + 1];
}
// Outer try catch does not block loop optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
/// CHECK: TryBoundary
/// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (before)
/// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
/// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none
/// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (before)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (before)
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
/// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
/// CHECK-DAG: <<Array:l\d+>> ParameterValue loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 4094 loop:none
/// CHECK-DAG: <<Phi:i\d+>> Phi loop:<<Loop:B\d+>> outer_loop:none
/// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi>>,<<Limit>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<If:v\d+>> If [<<Check>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Get0:i\d+>> ArrayGet [<<Array>>,<<Phi>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<IndAdd:i\d+>> Add [<<Phi>>,<<Const1>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Get1:i\d+>> ArrayGet [<<Array>>,<<IndAdd>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: <<Add:i\d+>> Add [<<Get0>>,<<Get1>>] loop:<<Loop>> outer_loop:none
/// CHECK-DAG: ArraySet [<<Array>>,<<Phi>>,<<Add>>] loop:<<Loop>> outer_loop:none
/// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
private static final void $noinline$unrollingLoadStoreElimination_Blocking(int[] a) {
for (int i = 0; i < LENGTH - 2; i++) {
a[i] += a[i + 1];
// Try catch blocks optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
/// CHECK: TryBoundary
/// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
/// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
/// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
/// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>>
// Each one of the three `for` loops has an `if`. The try catch has the 4th `if`.
/// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK-NOT: If
/// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
/// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
/// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
/// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
/// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: <<AddI:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>>
//
/// CHECK-DAG: If [<<Const0>>] loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
// Loop unrolling adds a 5th `if`. It is the one with `Const0` above.
/// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK-NOT: If
/// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
private static final void $noinline$unrollingInTheNest(int[] a, int[] b, int x) {
for (int k = 0; k < 16; k++) {
for (int j = 0; j < 16; j++) {
for (int i = 0; i < 128; i++) {
b[x]++;
a[i] = a[i] + 1;
}
}
}
// Outer try catch does not block loop optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
/// CHECK: TryBoundary
/// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
/// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
/// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
/// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
//
/// CHECK-DAG: Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>>
// Each one of the three `for` loops has an `if`. The try catch has the 4th `if`.
/// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK-NOT: If
/// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
/// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
/// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
/// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
/// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
//
/// CHECK-DAG: Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK-NOT: If
/// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
private static final void $noinline$unrollingInTheNest_Blocking(int[] a, int[] b, int x) {
for (int k = 0; k < 16; k++) {
for (int j = 0; j < 16; j++) {
for (int i = 0; i < 128; i++) {
b[x]++;
a[i] = a[i] + 1;
// Try catch blocks optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
}
}
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: TryBoundary
/// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
/// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
/// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
/// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
//
/// CHECK-DAG: Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>>
// Each one of the three `for` loops has an `if`. The try catch has the 4th `if`.
/// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK-NOT: If
/// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
/// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
/// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
/// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
/// CHECK-DAG: <<Check:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: If [<<Check>>] loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: <<AddI:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop2>>
//
/// CHECK-DAG: If [<<Const0>>] loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop2>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop2>>
// Loop unrolling adds a 5th `if`. It is the one with `Const0` above.
/// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK-NOT: If
/// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
private static final void $noinline$unrollingInTheNest_TryCatchNotBlocking(int[] a, int[] b, int x) {
for (int k = 0; k < 16; k++) {
for (int j = 0; j < 16; j++) {
for (int i = 0; i < 128; i++) {
b[x]++;
a[i] = a[i] + 1;
}
// Try catch does not block the optimization in the innermost loop.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
}
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
/// CHECK: TryBoundary
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
/// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
/// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
//
/// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
//
/// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
// Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catch has the 5th `if`.
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK-NOT: If
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
/// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
/// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
//
/// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Const0>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: Add [<<AddI2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
//
/// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Const0>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: Add [<<AddI3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
// LoopOptimization adds two `if`s. One for each loop unrolling.
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK-NOT: If
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
private static final void $noinline$unrollingTwoLoopsInTheNest(int[] a, int[] b, int x) {
for (int k = 0; k < 128; k++) {
if (x > 100) {
for (int j = 0; j < 128; j++) {
a[x]++;
}
} else {
for (int i = 0; i < 128; i++) {
b[x]++;
}
}
}
// Outer try catch does not block loop optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: TryBoundary
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
/// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
/// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
//
/// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
//
/// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
//
/// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
// Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catch has the 5th `if`.
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK-NOT: If
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
/// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
/// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
//
/// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
//
// Unrelated to the optimization itself, the try catch has an if.
/// CHECK-DAG: <<Get:z\d+>> StaticFieldGet field_name:Main.doThrow
/// CHECK-DAG: If [<<Get>>]
//
/// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
//
/// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Const0>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: Add [<<AddI3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
// LoopOptimization adds two `if`s. One for each loop unrolling.
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK-NOT: If
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
private static final void $noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[] a, int[] b, int x) {
for (int k = 0; k < 128; k++) {
if (x > 100) {
for (int j = 0; j < 128; j++) {
a[x]++;
// Try catch blocks optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
} else {
for (int i = 0; i < 128; i++) {
b[x]++;
}
}
}
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: TryBoundary
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
/// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
/// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
//
/// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
//
/// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
//
/// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
// Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catch has the 5th `if`.
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK-NOT: If
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
/// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
/// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
//
/// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Const0>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: Add [<<AddI2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
//
/// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
//
/// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
// LoopOptimization adds two `if`s. One for each loop unrolling.
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK-NOT: If
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
private static final void $noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[] a, int[] b, int x) {
for (int k = 0; k < 128; k++) {
if (x > 100) {
for (int j = 0; j < 128; j++) {
a[x]++;
}
} else {
for (int i = 0; i < 128; i++) {
b[x]++;
// Try catch blocks optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
}
}
}
// Consistency check to see we haven't eliminated the try/catch.
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: TryBoundary
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
/// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
/// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
//
/// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
//
/// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
//
/// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
//
/// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
// 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`.
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK-NOT: If
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
/// CHECK-DAG: <<Const0:i\d+>> IntConstant 0 loop:none
/// CHECK-DAG: <<Const1:i\d+>> IntConstant 1 loop:none
/// CHECK-DAG: <<Limit:i\d+>> IntConstant 128 loop:none
/// CHECK-DAG: <<XThres:i\d+>> IntConstant 100 loop:none
/// CHECK-DAG: <<Phi1:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop1:B\d+>> outer_loop:none
//
/// CHECK-DAG: <<Phi2:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check2:z\d+>> GreaterThanOrEqual [<<Phi2>>,<<Limit>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check2>>] loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop2>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop2>> outer_loop:<<Loop1>>
//
// Unrelated to the optimization itself, the try catch has an if.
/// CHECK-DAG: <<Get1:z\d+>> StaticFieldGet field_name:Main.doThrow
/// CHECK-DAG: If [<<Get1>>]
//
/// CHECK-DAG: <<AddI2:i\d+>> Add [<<Phi2>>,<<Const1>>] loop:<<Loop2>> outer_loop:<<Loop1>>
//
/// CHECK-DAG: <<Phi3:i\d+>> Phi [<<Const0>>,{{i\d+}}] loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
/// CHECK-DAG: <<Check3:z\d+>> GreaterThanOrEqual [<<Phi3>>,<<Limit>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: If [<<Check3>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArrayGet loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-DAG: ArraySet loop:<<Loop3>> outer_loop:<<Loop1>>
//
/// CHECK-DAG: <<AddI3:i\d+>> Add [<<Phi3>>,<<Const1>>] loop:<<Loop3>> outer_loop:<<Loop1>>
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK: If
/// CHECK-NOT: If
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: ArrayGet
/// CHECK: ArrayGet
/// CHECK-NOT: ArrayGet
/// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
/// CHECK: ArraySet
/// CHECK: ArraySet
/// CHECK-NOT: ArraySet
private static final void $noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[] a, int[] b, int x) {
for (int k = 0; k < 128; k++) {
if (x > 100) {
for (int j = 0; j < 128; j++) {
a[x]++;
// Try catch blocks optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
} else {
for (int i = 0; i < 128; i++) {
b[x]++;
// Try catch blocks optimizations.
try {
if (doThrow) {
$noinline$unreachable();
}
} catch (Error e) {
System.out.println("Not expected");
}
}
}
}
}
// Tests taken from 530-checker-peel-unroll
private static void $noinline$peelUnrollTests() {
int[] a = new int[LENGTH];
int[] b = new int[LENGTH];
initIntArray(a);
initIntArray(b);
$noinline$unrollingLoadStoreElimination(a);
$noinline$unrollingLoadStoreElimination_Blocking(a);
$noinline$unrollingInTheNest(a, b, RESULT_POS);
$noinline$unrollingInTheNest_Blocking(a, b, RESULT_POS);
$noinline$unrollingInTheNest_TryCatchNotBlocking(a, b, RESULT_POS);
$noinline$unrollingTwoLoopsInTheNest(a, b, RESULT_POS);
$noinline$unrollingTwoLoopsInTheNest_OneBlocking(a, b, RESULT_POS);
$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(a, b, RESULT_POS);
$noinline$unrollingTwoLoopsInTheNest_BothBlocking(a, b, RESULT_POS);
}
public static void main(String[] args) {
// Use existing tests to show that the difference between having a try catch inside or outside
// the loop.
$noinline$loops4Tests();
$noinline$loops5Tests();
$noinline$peelUnrollTests();
System.out.println("passed");
}
private static void expectEquals(int expected, int result) {
if (expected != result) {
throw new Error("Expected: " + expected + ", found: " + result);
}
}
private static void $noinline$unreachable() {
throw new Error("Unreachable");
}
private static boolean doThrow = false;
}