diff options
Diffstat (limited to 'test/530-checker-loops-try-catch/src/Main.java')
-rw-r--r-- | test/530-checker-loops-try-catch/src/Main.java | 1558 |
1 files changed, 1558 insertions, 0 deletions
diff --git a/test/530-checker-loops-try-catch/src/Main.java b/test/530-checker-loops-try-catch/src/Main.java new file mode 100644 index 0000000000..8d44b65662 --- /dev/null +++ b/test/530-checker-loops-try-catch/src/Main.java @@ -0,0 +1,1558 @@ +/* + * 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$after_bce (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$after_bce (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; +} |