/* * 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:<> /// CHECK-DAG: Mul loop:<> /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (after) /// CHECK-DAG: <> ParameterValue loop:none /// CHECK-DAG: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1410065408 loop:none /// CHECK-DAG: <> Mul [<>,<>] loop:none /// CHECK-DAG: <> Add [<>,<>] loop:none /// CHECK-DAG: Return [<>] 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:<> /// CHECK-DAG: Mul loop:<> /// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (after) /// CHECK-DAG: Phi loop:<> /// CHECK-DAG: Mul 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:<> /// CHECK-DAG: Shl loop:<> /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (after) /// CHECK-DAG: <> ParameterValue loop:none /// CHECK-DAG: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1024 loop:none /// CHECK-DAG: <> Mul [<>,<>] loop:none /// CHECK-DAG: <> Add [<>,<>] loop:none /// CHECK-DAG: Return [<>] 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:<> /// CHECK-DAG: Shl loop:<> /// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (after) /// CHECK-DAG: Phi loop:<> /// CHECK-DAG: Shl 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:<> /// CHECK-DAG: Div loop:<> /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (after) /// CHECK-DAG: <> ParameterValue loop:none /// CHECK-DAG: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 59049 loop:none /// CHECK-DAG: <> Div [<>,<>] loop:none /// CHECK-DAG: <> Add [<
>,<>] loop:none /// CHECK-DAG: Return [<>] 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:<> /// CHECK-DAG: Div loop:<> /// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (after) /// CHECK-DAG: Phi loop:<> /// CHECK-DAG: Div 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:<> /// CHECK-DAG: Rem loop:<> /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (after) /// CHECK-DAG: <> ParameterValue loop:none /// CHECK-DAG: <> IntConstant 7 loop:none /// CHECK-DAG: <> Rem [<>,<>] loop:none /// CHECK-DAG: Return [<>] 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:<> /// CHECK-DAG: Rem loop:<> /// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (after) /// CHECK-DAG: Phi loop:<> /// CHECK-DAG: Rem 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:<> /// CHECK-DAG: Shr loop:<> /// CHECK-START: int Main.$noinline$geo5() loop_optimization (after) /// CHECK-DAG: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 2147483647 loop:none /// CHECK-DAG: <> IntConstant 1024 loop:none /// CHECK-DAG: <> Div [<>,<>] loop:none /// CHECK-DAG: <> Add [<
>,<>] loop:none /// CHECK-DAG: Return [<>] 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:<> /// CHECK-DAG: Shr loop:<> /// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (after) /// CHECK-DAG: Phi loop:<> /// CHECK-DAG: Shr 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:<> /// CHECK-DAG: Add loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-START: int Main.$noinline$poly1() loop_optimization (after) /// CHECK-DAG: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 55 loop:none /// CHECK-DAG: <> Add [<>,<>] loop:none /// CHECK-DAG: Return [<>] loop:none /// CHECK-START: int Main.$noinline$poly1() instruction_simplifier$before_codegen (after) /// CHECK-DAG: <> IntConstant 55 loop:none /// CHECK-DAG: Return [<>] 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:<> /// CHECK-DAG: Add loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (after) /// CHECK-DAG: Phi loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-DAG: Add 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:<> /// CHECK-DAG: Shl loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (after) /// CHECK-DAG: <> ParameterValue loop:none /// CHECK-DAG: <> IntConstant 185 loop:none /// CHECK-DAG: <> Add [<>,<>] loop:none /// CHECK-DAG: Return [<>] 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:<> /// CHECK-DAG: Shl loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (after) /// CHECK-DAG: Phi loop:<> /// CHECK-DAG: Shl loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-DAG: Add 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:<> /// CHECK-DAG: Add loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-START: int Main.$noinline$poly3() loop_optimization (after) /// CHECK-DAG: <> IntConstant 12345 loop:none /// CHECK-DAG: <> IntConstant -2146736968 loop:none /// CHECK-DAG: <> Add [<>,<>] loop:none /// CHECK-DAG: Return [<>] loop:none /// CHECK-START: int Main.$noinline$poly3() instruction_simplifier$before_codegen (after) /// CHECK-DAG: <> IntConstant -2146724623 loop:none /// CHECK-DAG: Return [<>] 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:<> /// CHECK-DAG: Add loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (after) /// CHECK-DAG: Phi loop:<> /// CHECK-DAG: Add loop:<> /// CHECK-DAG: Add 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: <> ParameterValue loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 4094 loop:none /// CHECK-DAG: <> Phi loop:<> outer_loop:none /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> If [<>] loop:<> outer_loop:none /// CHECK-DAG: <> ArrayGet [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> ArrayGet [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: ArraySet [<>,<>,<>] 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: <> ParameterValue loop:none /// CHECK-DAG: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 4094 loop:none /// CHECK-DAG: <> Phi loop:<> outer_loop:none /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> If [<>] loop:<> outer_loop:none /// CHECK-DAG: <> ArrayGet [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> ArrayGet [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: ArraySet [<>,<>,<>] loop:<> outer_loop:none // /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> If [<>] loop:<> outer_loop:none /// CHECK-DAG: <> ArrayGet [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> ArrayGet [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: ArraySet [<>,<>,<>] 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: <> ParameterValue loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 4094 loop:none /// CHECK-DAG: <> Phi loop:<> outer_loop:none /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> If [<>] loop:<> outer_loop:none /// CHECK-DAG: <> ArrayGet [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> ArrayGet [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: ArraySet [<>,<>,<>] 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: <> ParameterValue loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 4094 loop:none /// CHECK-DAG: <> Phi loop:<> outer_loop:none /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> If [<>] loop:<> outer_loop:none /// CHECK-DAG: <> ArrayGet [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> ArrayGet [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:none /// CHECK-DAG: ArraySet [<>,<>,<>] 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: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 128 loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: Add [<>,<>] loop:<> outer_loop:<> // 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: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 128 loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> // /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> // 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: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 128 loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> // /// CHECK-DAG: Add [<>,<>] loop:<> outer_loop:<> // 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: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 128 loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> // /// CHECK-DAG: Add [<>,<>] loop:<> outer_loop:<> /// 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: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 128 loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> // /// CHECK-DAG: Add [<>,<>] loop:<> outer_loop:<> // 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: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 128 loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> // /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> // 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: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 128 loop:none /// CHECK-DAG: <> IntConstant 100 loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:none // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> // 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: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 128 loop:none /// CHECK-DAG: <> IntConstant 100 loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:none // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: Add [<>,<>] loop:<> outer_loop:<> // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: Add [<>,<>] loop:<> outer_loop:<> // 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: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 128 loop:none /// CHECK-DAG: <> IntConstant 100 loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:none // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> // /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> // 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: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 128 loop:none /// CHECK-DAG: <> IntConstant 100 loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:none // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> // // Unrelated to the optimization itself, the try catch has an if. /// CHECK-DAG: <> StaticFieldGet field_name:Main.doThrow /// CHECK-DAG: If [<>] // /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: Add [<>,<>] loop:<> outer_loop:<> // 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: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 128 loop:none /// CHECK-DAG: <> IntConstant 100 loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:none // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> // /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> // 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: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 128 loop:none /// CHECK-DAG: <> IntConstant 100 loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:none // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> /// CHECK-DAG: Add [<>,<>] loop:<> outer_loop:<> // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> // /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> // 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: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 128 loop:none /// CHECK-DAG: <> IntConstant 100 loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:none // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> // /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> // /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> // 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: <> IntConstant 0 loop:none /// CHECK-DAG: <> IntConstant 1 loop:none /// CHECK-DAG: <> IntConstant 128 loop:none /// CHECK-DAG: <> IntConstant 100 loop:none /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:none // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> // // Unrelated to the optimization itself, the try catch has an if. /// CHECK-DAG: <> StaticFieldGet field_name:Main.doThrow /// CHECK-DAG: If [<>] // /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> // /// CHECK-DAG: <> Phi [<>,{{i\d+}}] loop:<> outer_loop:<> /// CHECK-DAG: <> GreaterThanOrEqual [<>,<>] loop:<> outer_loop:<> /// CHECK-DAG: If [<>] loop:<> outer_loop:<> /// CHECK-DAG: ArrayGet loop:<> outer_loop:<> /// CHECK-DAG: ArraySet loop:<> outer_loop:<> // /// CHECK-DAG: <> Add [<>,<>] loop:<> outer_loop:<> /// 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; }