Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  Main.java

  Sprache: JAVA
 

/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


//
// Test on loop optimizations, in particular with try catches.
//
public class Main {
  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Mul loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (after)
  /// CHECK-DAG: <<Par:i\d+>> ParameterValue         loop:none
  /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0          loop:none
  /// CHECK-DAG: <<Int:i\d+>> IntConstant 1410065408 loop:none
  /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>]  loop:none
  /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Zer>>]  loop:none
  /// CHECK-DAG:              Return [<<Add>>]       loop:none

  /// CHECK-START: int Main.$noinline$geo1(int) loop_optimization (after)
  /// CHECK-NOT: Phi
  private static int $noinline$geo1(int a) {
    for (int i = 0; i < 10; i++) {
      a *= 10;
    }

    // Outer try catch does not block loop optimizations.
    try {
      if (doThrow) {
        $noinline$unreachable();
      }
    } catch (Error e) {
      System.out.println("Not expected");
    }
    return a;
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Mul loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$geo1_Blocking(int) loop_optimization (after)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Mul loop:<<Loop>>
  private static int $noinline$geo1_Blocking(int a) {
    for (int i = 0; i < 10; i++) {
      a *= 10;

      // Try catch blocks optimizations.
      try {
        if (doThrow) {
          $noinline$unreachable();
        }
      } catch (Error e) {
        System.out.println("Not expected");
      }
    }
    return a;
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Shl loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (after)
  /// CHECK-DAG: <<Par:i\d+>> ParameterValue        loop:none
  /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0         loop:none
  /// CHECK-DAG: <<Int:i\d+>> IntConstant 1024      loop:none
  /// CHECK-DAG: <<Mul:i\d+>> Mul [<<Par>>,<<Int>>] loop:none
  /// CHECK-DAG: <<Add:i\d+>> Add [<<Mul>>,<<Zer>>] loop:none
  /// CHECK-DAG:              Return [<<Add>>]      loop:none

  /// CHECK-START: int Main.$noinline$geo2(int) loop_optimization (after)
  /// CHECK-NOT: Phi
  private static int $noinline$geo2(int a) {
    for (int i = 0; i < 10; i++) {
      a <<= 1;
    }

    // Outer try catch does not block loop optimizations.
    try {
      if (doThrow) {
        $noinline$unreachable();
      }
    } catch (Error e) {
      System.out.println("Not expected");
    }
    return a;
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Shl loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$geo2_Blocking(int) loop_optimization (after)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Shl loop:<<Loop>>
  private static int $noinline$geo2_Blocking(int a) {
    for (int i = 0; i < 10; i++) {
      a <<= 1;

      // Try catch blocks optimizations.
      try {
        if (doThrow) {
          $noinline$unreachable();
        }
      } catch (Error e) {
        System.out.println("Not expected");
      }
    }
    return a;
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Div loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (after)
  /// CHECK-DAG: <<Par:i\d+>> ParameterValue        loop:none
  /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0         loop:none
  /// CHECK-DAG: <<Int:i\d+>> IntConstant 59049     loop:none
  /// CHECK-DAG: <<Div:i\d+>> Div [<<Par>>,<<Int>>] loop:none
  /// CHECK-DAG: <<Add:i\d+>> Add [<<Div>>,<<Zer>>] loop:none
  /// CHECK-DAG:              Return [<<Add>>]      loop:none

  /// CHECK-START: int Main.$noinline$geo3(int) loop_optimization (after)
  /// CHECK-NOT: Phi
  private static int $noinline$geo3(int a) {
    for (int i = 0; i < 10; i++) {
      a /= 3;
    }

    // Outer try catch does not block loop optimizations.
    try {
      if (doThrow) {
        $noinline$unreachable();
      }
    } catch (Error e) {
      System.out.println("Not expected");
    }
    return a;
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Div loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$geo3_Blocking(int) loop_optimization (after)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Div loop:<<Loop>>
  private static int $noinline$geo3_Blocking(int a) {
    for (int i = 0; i < 10; i++) {
      a /= 3;

      // Try catch blocks optimizations.
      try {
        if (doThrow) {
          $noinline$unreachable();
        }
      } catch (Error e) {
        System.out.println("Not expected");
      }
    }
    return a;
  }


  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Rem loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (after)
  /// CHECK-DAG: <<Par:i\d+>> ParameterValue        loop:none
  /// CHECK-DAG: <<Int:i\d+>> IntConstant 7         loop:none
  /// CHECK-DAG: <<Rem:i\d+>> Rem [<<Par>>,<<Int>>] loop:none
  /// CHECK-DAG:              Return [<<Rem>>]      loop:none

  /// CHECK-START: int Main.$noinline$geo4(int) loop_optimization (after)
  /// CHECK-NOT: Phi
  private static int $noinline$geo4(int a) {
    for (int i = 0; i < 10; i++) {
      a %= 7// a wrap-around induction
    }

    // Outer try catch does not block loop optimizations.
    try {
      if (doThrow) {
        $noinline$unreachable();
      }
    } catch (Error e) {
      System.out.println("Not expected");
    }
    return a;
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Rem loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$geo4_Blocking(int) loop_optimization (after)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Rem loop:<<Loop>>
  private static int $noinline$geo4_Blocking(int a) {
    for (int i = 0; i < 10; i++) {
      a %= 7// a wrap-around induction

      // Try catch blocks optimizations.
      try {
        if (doThrow) {
          $noinline$unreachable();
        }
      } catch (Error e) {
        System.out.println("Not expected");
      }
    }
    return a;
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$geo5() loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$geo5() loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Shr loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$geo5() loop_optimization (after)
  /// CHECK-DAG: <<Zero:i\d+>> IntConstant 0          loop:none
  /// CHECK-DAG: <<Int1:i\d+>> IntConstant 2147483647 loop:none
  /// CHECK-DAG: <<Int2:i\d+>> IntConstant 1024       loop:none
  /// CHECK-DAG: <<Div:i\d+>>  Div [<<Int1>>,<<Int2>>] loop:none
  /// CHECK-DAG: <<Add:i\d+>>  Add [<<Div>>,<<Zero>>]  loop:none
  /// CHECK-DAG:               Return [<<Add>>]        loop:none

  /// CHECK-START: int Main.$noinline$geo5() loop_optimization (after)
  /// CHECK-NOT: Phi
  private static int $noinline$geo5() {
    int a = 0x7fffffff;
    for (int i = 0; i < 10; i++) {
      a >>= 1;
    }

    // Outer try catch does not block loop optimizations.
    try {
      if (doThrow) {
        $noinline$unreachable();
      }
    } catch (Error e) {
      System.out.println("Not expected");
    }
    return a;
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Shr loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$geo5_Blocking() loop_optimization (after)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Shr loop:<<Loop>>
  private static int $noinline$geo5_Blocking() {
    int a = 0x7fffffff;
    for (int i = 0; i < 10; i++) {
      a >>= 1;

      // Try catch blocks optimizations.
      try {
        if (doThrow) {
          $noinline$unreachable();
        }
      } catch (Error e) {
        System.out.println("Not expected");
      }
    }
    return a;
  }

  // Tests taken from 530-checker-loops4
  private static void $noinline$loops4Tests() {
    int m = 1410065408;
    for (int i = -100; i <= 100; i++) {
      expectEquals(m * i, $noinline$geo1(i));
      expectEquals(m * i, $noinline$geo1_Blocking(i));
    }
    for (int i = 1; i <= 1000000000; i *= 10) {
      expectEquals(m * i, $noinline$geo1(i));
      expectEquals(m * i, $noinline$geo1_Blocking(i));
      expectEquals(-m * i, $noinline$geo1(-i));
      expectEquals(-m * i, $noinline$geo1_Blocking(-i));
    }

    for (int i = -100; i <= 100; i++) {
      expectEquals(i << 10, $noinline$geo2(i));
      expectEquals(i << 10, $noinline$geo2_Blocking(i));
    }
    for (int i = 0; i < 22; i++) {
      expectEquals(1 << (i + 10), $noinline$geo2(1 << i));
      expectEquals(1 << (i + 10), $noinline$geo2_Blocking(1 << i));
    }
    expectEquals(0x80000400, $noinline$geo2(0x00200001));
    expectEquals(0x80000400, $noinline$geo2_Blocking(0x00200001));
    expectEquals(0x00000000, $noinline$geo2(0x00400000));
    expectEquals(0x00000000, $noinline$geo2_Blocking(0x00400000));
    expectEquals(0x00000400, $noinline$geo2(0x00400001));
    expectEquals(0x00000400, $noinline$geo2_Blocking(0x00400001));

    int d = 59049;
    for (int i = -100; i <= 100; i++) {
      expectEquals(0, $noinline$geo3(i));
      expectEquals(0, $noinline$geo3_Blocking(i));
    }
    for (int i = 1; i <= 100; i++) {
      expectEquals(i, $noinline$geo3(i * d));
      expectEquals(i, $noinline$geo3_Blocking(i * d));
      expectEquals(i, $noinline$geo3(i * d + 1));
      expectEquals(i, $noinline$geo3_Blocking(i * d + 1));
      expectEquals(-i, $noinline$geo3(-i * d));
      expectEquals(-i, $noinline$geo3_Blocking(-i * d));
      expectEquals(-i, $noinline$geo3(-i * d - 1));
      expectEquals(-i, $noinline$geo3_Blocking(-i * d - 1));
    }

    for (int i = -100; i <= 100; i++) {
      expectEquals(i % 7, $noinline$geo4(i));
      expectEquals(i % 7, $noinline$geo4_Blocking(i));
    }

    expectEquals(0x1fffff, $noinline$geo5());
    expectEquals(0x1fffff, $noinline$geo5_Blocking());
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$poly1() loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$poly1() loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Add loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$poly1() loop_optimization (after)
  /// CHECK-DAG: <<Zer:i\d+>> IntConstant 0         loop:none
  /// CHECK-DAG: <<Int:i\d+>> IntConstant 55        loop:none
  /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Zer>>] loop:none
  /// CHECK-DAG:              Return [<<Add>>]      loop:none

  /// CHECK-START: int Main.$noinline$poly1() instruction_simplifier$before_codegen (after)
  /// CHECK-DAG: <<Int:i\d+>>  IntConstant 55 loop:none
  /// CHECK-DAG:               Return [<<Int>>]  loop:none

  /// CHECK-START: int Main.$noinline$poly1() loop_optimization (after)
  /// CHECK-NOT: Phi
  private static int $noinline$poly1() {
    int a = 0;
    for (int i = 0; i <= 10; i++) {
      a += i;
    }

    // Outer try catch does not block loop optimizations.
    try {
      if (doThrow) {
        $noinline$unreachable();
      }
    } catch (Error e) {
      System.out.println("Not expected");
    }

    return a;
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Add loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$poly1_Blocking() loop_optimization (after)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Add loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>
  private static int $noinline$poly1_Blocking() {
    int a = 0;
    for (int i = 0; i <= 10; i++) {
      a += i;

      // Try catch blocks optimizations.
      try {
        if (doThrow) {
          $noinline$unreachable();
        }
      } catch (Error e) {
        System.out.println("Not expected");
      }
    }

    return a;
  }

  // Multiplication in linear induction has been optimized earlier,
  // but that does not stop the induction variable recognition
  // and loop optimizer.
  //
  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Shl loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (after)
  /// CHECK-DAG: <<Par:i\d+>> ParameterValue        loop:none
  /// CHECK-DAG: <<Int:i\d+>> IntConstant 185       loop:none
  /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Par>>] loop:none
  /// CHECK-DAG:              Return [<<Add>>]      loop:none

  /// CHECK-START: int Main.$noinline$poly2(int) loop_optimization (after)
  /// CHECK-NOT: Phi
  private static int $noinline$poly2(int a) {
    for (int i = 0; i < 10; i++) {
      int k = 3 * i + 5;
      a += k;
    }

    // Outer try catch does not block loop optimizations.
    try {
      if (doThrow) {
        $noinline$unreachable();
      }
    } catch (Error e) {
      System.out.println("Not expected");
    }
    return a;
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Shl loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$poly2_Blocking(int) loop_optimization (after)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Shl loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>
  private static int $noinline$poly2_Blocking(int a) {
    for (int i = 0; i < 10; i++) {
      int k = 3 * i + 5;
      a += k;

      // Try catch blocks optimizations.
      try {
        if (doThrow) {
          $noinline$unreachable();
        }
      } catch (Error e) {
        System.out.println("Not expected");
      }
    }

    return a;
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$poly3() loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$poly3() loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Add loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$poly3() loop_optimization (after)
  /// CHECK-DAG: <<Ini:i\d+>> IntConstant 12345       loop:none
  /// CHECK-DAG: <<Int:i\d+>> IntConstant -2146736968 loop:none
  /// CHECK-DAG: <<Add:i\d+>> Add [<<Int>>,<<Ini>>]   loop:none
  /// CHECK-DAG:              Return [<<Add>>]        loop:none

  /// CHECK-START: int Main.$noinline$poly3() instruction_simplifier$before_codegen (after)
  /// CHECK-DAG: <<Int:i\d+>>  IntConstant -2146724623 loop:none
  /// CHECK-DAG:               Return [<<Int>>]        loop:none

  /// CHECK-START: int Main.$noinline$poly3() loop_optimization (after)
  /// CHECK-NOT: Phi
  private static int $noinline$poly3() {
    int a = 12345;
    for (int i = 0; i <= 10; i++) {
      a += (2147483646 * i + 67890);
    }

    // Outer try catch does not block loop optimizations.
    try {
      if (doThrow) {
        $noinline$unreachable();
      }
    } catch (Error e) {
      System.out.println("Not expected");
    }
    return a;
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (before)
  /// CHECK:     TryBoundary

  /// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (before)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Add loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>

  /// CHECK-START: int Main.$noinline$poly3_Blocking() loop_optimization (after)
  /// CHECK-DAG: Phi loop:<<Loop:B\d+>>
  /// CHECK-DAG: Add loop:<<Loop>>
  /// CHECK-DAG: Add loop:<<Loop>>
  private static int $noinline$poly3_Blocking() {
    int a = 12345;
    for (int i = 0; i <= 10; i++) {
      a += (2147483646 * i + 67890);

      // Try catch blocks optimizations.
      try {
        if (doThrow) {
          $noinline$unreachable();
        }
      } catch (Error e) {
        System.out.println("Not expected");
      }
    }
    return a;
  }

  // Tests taken from 530-checker-loops5
  private static void $noinline$loops5Tests() {
    expectEquals(55, $noinline$poly1());
    expectEquals(55, $noinline$poly1_Blocking());
    expectEquals(185, $noinline$poly2(0));
    expectEquals(185, $noinline$poly2_Blocking(0));
    expectEquals(192, $noinline$poly2(7));
    expectEquals(192, $noinline$poly2_Blocking(7));
    expectEquals(-2146724623, $noinline$poly3());
    expectEquals(-2146724623, $noinline$poly3_Blocking());
  }

  // Constants used for peel unroll tests.
  private static final int LENGTH = 4 * 1024;
  private static final int RESULT_POS = 4;

  private static final void initIntArray(int[] a) {
    for (int i = 0; i < a.length; i++) {
      a[i] = i % 4;
    }
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
  /// CHECK:     TryBoundary

  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (before)
  /// CHECK-DAG: <<Array:l\d+>>   ParameterValue                            loop:none
  /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>   IntConstant 4094                          loop:none
  /// CHECK-DAG: <<Phi:i\d+>>     Phi                                       loop:<<Loop:B\d+>> outer_loop:none
  /// CHECK-DAG: <<Check:z\d+>>   GreaterThanOrEqual [<<Phi>>,<<Limit>>]    loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<If:v\d+>>      If [<<Check>>]                            loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<Get0:i\d+>>    ArrayGet [<<Array>>,<<Phi>>]              loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<IndAdd:i\d+>>  Add [<<Phi>>,<<Const1>>]                  loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<Get1:i\d+>>    ArrayGet [<<Array>>,<<IndAdd>>]           loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<Add:i\d+>>     Add [<<Get0>>,<<Get1>>]                   loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG:                  ArraySet [<<Array>>,<<Phi>>,<<Add>>]      loop:<<Loop>>      outer_loop:none

  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (before)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (before)
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet

  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
  /// CHECK-DAG: <<Array:l\d+>>   ParameterValue                            loop:none
  /// CHECK-DAG: <<Const0:i\d+>>  IntConstant 0                             loop:none
  /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>   IntConstant 4094                          loop:none
  /// CHECK-DAG: <<Phi:i\d+>>     Phi                                       loop:<<Loop:B\d+>> outer_loop:none
  /// CHECK-DAG: <<Check:z\d+>>   GreaterThanOrEqual [<<Phi>>,<<Limit>>]    loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<If:v\d+>>      If [<<Check>>]                            loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<Get0:i\d+>>    ArrayGet [<<Array>>,<<Phi>>]              loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<IndAdd:i\d+>>  Add [<<Phi>>,<<Const1>>]                  loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<Get1:i\d+>>    ArrayGet [<<Array>>,<<IndAdd>>]           loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<Add:i\d+>>     Add [<<Get0>>,<<Get1>>]                   loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG:                  ArraySet [<<Array>>,<<Phi>>,<<Add>>]      loop:<<Loop>>      outer_loop:none
  //
  /// CHECK-DAG: <<CheckA:z\d+>>  GreaterThanOrEqual [<<IndAdd>>,<<Limit>>] loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<IfA:v\d+>>     If [<<Const0>>]                           loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<Get0A:i\d+>>   ArrayGet [<<Array>>,<<IndAdd>>]           loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<IndAddA:i\d+>> Add [<<IndAdd>>,<<Const1>>]               loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<Get1A:i\d+>>   ArrayGet [<<Array>>,<<IndAddA>>]          loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<AddA:i\d+>>    Add [<<Get0A>>,<<Get1A>>]                 loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG:                  ArraySet [<<Array>>,<<IndAdd>>,<<AddA>>]  loop:<<Loop>>      outer_loop:none

  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination(int[]) loop_optimization (after)
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet
  private static final void $noinline$unrollingLoadStoreElimination(int[] a) {
    for (int i = 0; i < LENGTH - 2; i++) {
      a[i] += a[i + 1];
    }

    // Outer try catch does not block loop optimizations.
    try {
      if (doThrow) {
        $noinline$unreachable();
      }
    } catch (Error e) {
      System.out.println("Not expected");
    }
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
  /// CHECK:     TryBoundary

  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (before)
  /// CHECK-DAG: <<Array:l\d+>>   ParameterValue                            loop:none
  /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>   IntConstant 4094                          loop:none
  /// CHECK-DAG: <<Phi:i\d+>>     Phi                                       loop:<<Loop:B\d+>> outer_loop:none
  /// CHECK-DAG: <<Check:z\d+>>   GreaterThanOrEqual [<<Phi>>,<<Limit>>]    loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<If:v\d+>>      If [<<Check>>]                            loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<Get0:i\d+>>    ArrayGet [<<Array>>,<<Phi>>]              loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<IndAdd:i\d+>>  Add [<<Phi>>,<<Const1>>]                  loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<Get1:i\d+>>    ArrayGet [<<Array>>,<<IndAdd>>]           loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<Add:i\d+>>     Add [<<Get0>>,<<Get1>>]                   loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG:                  ArraySet [<<Array>>,<<Phi>>,<<Add>>]      loop:<<Loop>>      outer_loop:none

  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (before)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (before)
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet

  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
  /// CHECK-DAG: <<Array:l\d+>>   ParameterValue                            loop:none
  /// CHECK-DAG: <<Const1:i\d+>>  IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>   IntConstant 4094                          loop:none
  /// CHECK-DAG: <<Phi:i\d+>>     Phi                                       loop:<<Loop:B\d+>> outer_loop:none
  /// CHECK-DAG: <<Check:z\d+>>   GreaterThanOrEqual [<<Phi>>,<<Limit>>]    loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<If:v\d+>>      If [<<Check>>]                            loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<Get0:i\d+>>    ArrayGet [<<Array>>,<<Phi>>]              loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<IndAdd:i\d+>>  Add [<<Phi>>,<<Const1>>]                  loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<Get1:i\d+>>    ArrayGet [<<Array>>,<<IndAdd>>]           loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG: <<Add:i\d+>>     Add [<<Get0>>,<<Get1>>]                   loop:<<Loop>>      outer_loop:none
  /// CHECK-DAG:                  ArraySet [<<Array>>,<<Phi>>,<<Add>>]      loop:<<Loop>>      outer_loop:none

  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingLoadStoreElimination_Blocking(int[]) loop_optimization (after)
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet
  private static final void $noinline$unrollingLoadStoreElimination_Blocking(int[] a) {
    for (int i = 0; i < LENGTH - 2; i++) {
      a[i] += a[i + 1];

      // Try catch blocks optimizations.
      try {
        if (doThrow) {
          $noinline$unreachable();
        }
      } catch (Error e) {
        System.out.println("Not expected");
      }
    }
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
  /// CHECK:     TryBoundary

  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
  /// CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   If [<<Check>>]                            loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop2>>

  // Each one of the three `for` loops has an `if`. The try catch has the 4th `if`.
  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK-NOT:                   If

  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (before)
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet

  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
  /// CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   If [<<Check>>]                            loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG: <<AddI:i\d+>>     Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop2>>
  //
  /// CHECK-DAG:                   If [<<Const0>>]                           loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>

  // Loop unrolling adds a 5th `if`. It is the one with `Const0` above.
  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK-NOT:                   If

  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingInTheNest(int[], int[], int) loop_optimization (after)
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet
  private static final void $noinline$unrollingInTheNest(int[] a, int[] b, int x) {
    for (int k = 0; k < 16; k++) {
      for (int j = 0; j < 16; j++) {
        for (int i = 0; i < 128; i++) {
          b[x]++;
          a[i] = a[i] + 1;
        }
      }
    }

    // Outer try catch does not block loop optimizations.
    try {
      if (doThrow) {
        $noinline$unreachable();
      }
    } catch (Error e) {
      System.out.println("Not expected");
    }
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
  /// CHECK:     TryBoundary

  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
  /// CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   If [<<Check>>]                            loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  //
  /// CHECK-DAG:                   Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop2>>

  // Each one of the three `for` loops has an `if`. The try catch has the 4th `if`.
  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK-NOT:                   If

  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (before)
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet

  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
  /// CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   If [<<Check>>]                            loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  //
  /// CHECK-DAG:                   Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop2>>

  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK-NOT:                   If

  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingInTheNest_Blocking(int[], int[], int) loop_optimization (after)
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet
  private static final void $noinline$unrollingInTheNest_Blocking(int[] a, int[] b, int x) {
    for (int k = 0; k < 16; k++) {
      for (int j = 0; j < 16; j++) {
        for (int i = 0; i < 128; i++) {
          b[x]++;
          a[i] = a[i] + 1;

          // Try catch blocks optimizations.
          try {
            if (doThrow) {
              $noinline$unreachable();
            }
          } catch (Error e) {
            System.out.println("Not expected");
          }
        }
      }
    }
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:     TryBoundary

  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
  /// CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   If [<<Check>>]                            loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  //
  /// CHECK-DAG:                   Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop2>>

  // Each one of the three `for` loops has an `if`. The try catch has the 4th `if`.
  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK-NOT:                   If

  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet

  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop2>>
  /// CHECK-DAG: <<Check:z\d+>>    GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   If [<<Check>>]                            loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG: <<AddI:i\d+>>     Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop2>>
  //
  /// CHECK-DAG:                   If [<<Const0>>]                           loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop2>>

  // Loop unrolling adds a 5th `if`. It is the one with `Const0` above.
  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK-NOT:                   If

  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingInTheNest_TryCatchNotBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet
  private static final void $noinline$unrollingInTheNest_TryCatchNotBlocking(int[] a, int[] b, int x) {
    for (int k = 0; k < 16; k++) {
      for (int j = 0; j < 16; j++) {
        for (int i = 0; i < 128; i++) {
          b[x]++;
          a[i] = a[i] + 1;
        }
        // Try catch does not block the optimization in the innermost loop.
        try {
          if (doThrow) {
            $noinline$unreachable();
          }
        } catch (Error e) {
          System.out.println("Not expected");
        }
      }
    }
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
  /// CHECK:     TryBoundary

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
  //
  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
  //
  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>

  // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catch has the 5th `if`.
  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK-NOT:                   If

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (before)
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
  //
  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Const0>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   Add [<<AddI2>>,<<Const1>>]                loop:<<Loop2>>      outer_loop:<<Loop1>>
  //
  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Const0>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   Add [<<AddI3>>,<<Const1>>]                loop:<<Loop3>>      outer_loop:<<Loop1>>

  // LoopOptimization adds two `if`s. One for each loop unrolling.
  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK-NOT:                   If

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest(int[], int[], int) loop_optimization (after)
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet
  private static final void $noinline$unrollingTwoLoopsInTheNest(int[] a, int[] b, int x) {
    for (int k = 0; k < 128; k++) {
      if (x > 100) {
        for (int j = 0; j < 128; j++) {
          a[x]++;
        }
      } else {
        for (int i = 0; i < 128; i++) {
          b[x]++;
        }
      }
    }

    // Outer try catch does not block loop optimizations.
    try {
      if (doThrow) {
        $noinline$unreachable();
      }
    } catch (Error e) {
      System.out.println("Not expected");
    }
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:     TryBoundary

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
  //
  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  //
  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
  //
  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>

  // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catch has the 5th `if`.
  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK-NOT:                   If

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
  //
  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  //
  // Unrelated to the optimization itself, the try catch has an if.
  /// CHECK-DAG: <<Get:z\d+>>      StaticFieldGet field_name:Main.doThrow
  /// CHECK-DAG:                   If [<<Get>>]
  //
  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
  //
  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Const0>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   Add [<<AddI3>>,<<Const1>>]                loop:<<Loop3>>      outer_loop:<<Loop1>>

  // LoopOptimization adds two `if`s. One for each loop unrolling.
  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK-NOT:                   If

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet
  private static final void $noinline$unrollingTwoLoopsInTheNest_OneBlocking(int[] a, int[] b, int x) {
    for (int k = 0; k < 128; k++) {
      if (x > 100) {
        for (int j = 0; j < 128; j++) {
          a[x]++;
          // Try catch blocks optimizations.
          try {
            if (doThrow) {
              $noinline$unreachable();
            }
          } catch (Error e) {
            System.out.println("Not expected");
          }
        }
      } else {
        for (int i = 0; i < 128; i++) {
          b[x]++;
        }
      }
    }
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:     TryBoundary

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
  //
  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
  //
  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  //
  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>

  // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catch has the 5th `if`.
  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK-NOT:                   If

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
  //
  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Const0>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   Add [<<AddI2>>,<<Const1>>]                loop:<<Loop2>>      outer_loop:<<Loop1>>
  //
  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  //
  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>

  // LoopOptimization adds two `if`s. One for each loop unrolling.
  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK-NOT:                   If

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet
  private static final void $noinline$unrollingTwoLoopsInTheNest_OtherBlocking(int[] a, int[] b, int x) {
    for (int k = 0; k < 128; k++) {
      if (x > 100) {
        for (int j = 0; j < 128; j++) {
          a[x]++;
        }
      } else {
        for (int i = 0; i < 128; i++) {
          b[x]++;
          // Try catch blocks optimizations.
          try {
            if (doThrow) {
              $noinline$unreachable();
            }
          } catch (Error e) {
            System.out.println("Not expected");
          }
        }
      }
    }
  }

  // Consistency check to see we haven't eliminated the try/catch.
  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:     TryBoundary

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
  //
  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  //
  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
  //
  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  //
  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>

  // Each one of the three `for` loops has an `if`. Plus an `if` inside the outer `for`. The try catchs have the 5th and 6th `if`.
  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK-NOT:                   If

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (before)
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0                             loop:none
  /// CHECK-DAG: <<Const1:i\d+>>   IntConstant 1                             loop:none
  /// CHECK-DAG: <<Limit:i\d+>>    IntConstant 128                           loop:none
  /// CHECK-DAG: <<XThres:i\d+>>   IntConstant 100                           loop:none
  /// CHECK-DAG: <<Phi1:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop1:B\d+>> outer_loop:none
  //
  /// CHECK-DAG: <<Phi2:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop2:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check2:z\d+>>   GreaterThanOrEqual [<<Phi2>>,<<Limit>>]   loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check2>>]                           loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop2>>      outer_loop:<<Loop1>>
  //
  // Unrelated to the optimization itself, the try catch has an if.
  /// CHECK-DAG: <<Get1:z\d+>>     StaticFieldGet field_name:Main.doThrow
  /// CHECK-DAG:                   If [<<Get1>>]
  //
  /// CHECK-DAG: <<AddI2:i\d+>>    Add [<<Phi2>>,<<Const1>>]                 loop:<<Loop2>>      outer_loop:<<Loop1>>
  //
  /// CHECK-DAG: <<Phi3:i\d+>>     Phi [<<Const0>>,{{i\d+}}]                 loop:<<Loop3:B\d+>> outer_loop:<<Loop1>>
  /// CHECK-DAG: <<Check3:z\d+>>   GreaterThanOrEqual [<<Phi3>>,<<Limit>>]   loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   If [<<Check3>>]                           loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArrayGet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  /// CHECK-DAG:                   ArraySet                                  loop:<<Loop3>>      outer_loop:<<Loop1>>
  //
  /// CHECK-DAG: <<AddI3:i\d+>>    Add [<<Phi3>>,<<Const1>>]                 loop:<<Loop3>>      outer_loop:<<Loop1>>

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK:                       If
  /// CHECK-NOT:                   If

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:                      ArrayGet
  /// CHECK:                      ArrayGet
  /// CHECK-NOT:                  ArrayGet

  /// CHECK-START: void Main.$noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[], int[], int) loop_optimization (after)
  /// CHECK:                      ArraySet
  /// CHECK:                      ArraySet
  /// CHECK-NOT:                  ArraySet
  private static final void $noinline$unrollingTwoLoopsInTheNest_BothBlocking(int[] a, int[] b, int x) {
    for (int k = 0; k < 128; k++) {
      if (x > 100) {
        for (int j = 0; j < 128; j++) {
          a[x]++;
          // Try catch blocks optimizations.
          try {
            if (doThrow) {
              $noinline$unreachable();
            }
          } catch (Error e) {
            System.out.println("Not expected");
          }
        }
      } else {
        for (int i = 0; i < 128; i++) {
          b[x]++;
          // Try catch blocks optimizations.
          try {
            if (doThrow) {
              $noinline$unreachable();
            }
          } catch (Error e) {
            System.out.println("Not expected");
          }
        }
      }
    }
  }

  // Tests taken from 530-checker-peel-unroll
  private static void $noinline$peelUnrollTests() {
    int[] a = new int[LENGTH];
    int[] b = new int[LENGTH];
    initIntArray(a);
    initIntArray(b);

    $noinline$unrollingLoadStoreElimination(a);
    $noinline$unrollingLoadStoreElimination_Blocking(a);
    $noinline$unrollingInTheNest(a, b, RESULT_POS);
    $noinline$unrollingInTheNest_Blocking(a, b, RESULT_POS);
    $noinline$unrollingInTheNest_TryCatchNotBlocking(a, b, RESULT_POS);
    $noinline$unrollingTwoLoopsInTheNest(a, b, RESULT_POS);
    $noinline$unrollingTwoLoopsInTheNest_OneBlocking(a, b, RESULT_POS);
    $noinline$unrollingTwoLoopsInTheNest_OtherBlocking(a, b, RESULT_POS);
    $noinline$unrollingTwoLoopsInTheNest_BothBlocking(a, b, RESULT_POS);
  }

  public static void main(String[] args) {
    // Use existing tests to show that the difference between having a try catch inside or outside
    // the loop.
    $noinline$loops4Tests();
    $noinline$loops5Tests();
    $noinline$peelUnrollTests();

    System.out.println("passed");
  }

  private static void expectEquals(int expected, int result) {
    if (expected != result) {
      throw new Error("Expected: " + expected + ", found: " + result);
    }
  }

  private static void $noinline$unreachable() {
    throw new Error("Unreachable");
  }

  private static boolean doThrow = false;
}

Messung V0.5 in Prozent
C=78 H=89 G=83

¤ Dauer der Verarbeitung: 0.33 Sekunden  (vorverarbeitet am  2026-06-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik