/*
 * Copyright (C) 2016 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 around polynomial induction.
//
public class Main {

  /// CHECK-START: int Main.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.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.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.poly1() loop_optimization (after)
  /// CHECK-NOT: Phi
  public static int poly1() {
    int a = 0;
    for (int i = 0; i <= 10; i++) {
      a += i;
    }
    return a;
  }

  // Multiplication in linear induction has been optimized earlier,
  // but that does not stop the induction variable recognition
  // and loop optimizer.
  //
  /// CHECK-START: int Main.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.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.poly2(int) loop_optimization (after)
  /// CHECK-NOT: Phi
  public static int poly2(int a) {
    for (int i = 0; i < 10; i++) {
      int k = 3 * i + 5;
      a += k;
    }
    return a;
  }

  /// CHECK-START: int Main.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.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.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.poly3() loop_optimization (after)
  /// CHECK-NOT: Phi
  public static int poly3() {
    int a = 12345;
    for (int i = 0; i <= 10; i++) {
      a += (2147483646 * i + 67890);
    }
    return a;
  }

  /// CHECK-START: int Main.polyBCE1() BCE (before)
  /// CHECK-DAG: BoundsCheck loop:none
  /// CHECK-DAG: BoundsCheck loop:{{B\d+}}
  //
  /// CHECK-START: int Main.polyBCE1() BCE (after)
  /// CHECK-NOT: BoundsCheck
  /// CHECK-NOT: Deoptimize
  public static int polyBCE1() {
    int[] x = {  1,  2,  3,  4,  5,  6,  7,  8,  9, 10,
                11, 12, 13, 14, 15, 16, 17, 19, 19, 20,
                21, 22 };
    int a = 0;
    int r = 0;
    for (int i = 0; i < 8; i++) {
      r += x[a];
      a += i;
    }
    return r;
  }

  /// CHECK-START: int Main.polyBCE2() BCE (before)
  /// CHECK-DAG: BoundsCheck loop:none
  /// CHECK-DAG: BoundsCheck loop:{{B\d+}}
  //
  /// CHECK-START: int Main.polyBCE2() BCE (after)
  /// CHECK-NOT: BoundsCheck
  /// CHECK-NOT: Deoptimize
  public static int polyBCE2() {
    int[] x = {  1,  2,  3,  4,  5,  6,  7,  8,  9, 10,
                11, 12, 13, 14, 15, 16, 17, 19, 19, 20,
                21, 22, 23, 24, 25, 26, 27 };
    int a = 1;
    int r = 0;
    for (int i = 0; i < 6; i++) {
      int k = 2 * i + 1;
      r -= x[a];
      a += k;
    }
    return r;
  }

  /// CHECK-START: int Main.polyBCE3() BCE (before)
  /// CHECK-DAG: BoundsCheck loop:none
  /// CHECK-DAG: BoundsCheck loop:{{B\d+}}
  //
  /// CHECK-START: int Main.polyBCE3() BCE (after)
  /// CHECK-NOT: BoundsCheck
  /// CHECK-NOT: Deoptimize
  public static int polyBCE3() {
    int[] x = {  1,  2,  3,  4,  5,  6,  7,  8,  9, 10,
                11, 12, 13, 14, 15, 16, 17, 19, 19, 20,
                21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
                31, 32, 33, 34, 35, 36, 37, 38 };
    int r = 0;
    int a1 = 1;
    int a2 = 2;
    for (int i = 0; i < 5; i++) {
      int t = a1 + a2;  // two polynomials combined into new polynomial
      r -= x[t];
      a1 += (3 * i + 1);
      a2 += (2 * i);
    }
    return r;
  }

  //
  // Verifier.
  //

  public static void main(String[] args) {
    expectEquals(55, poly1());
    expectEquals(185, poly2(0));
    expectEquals(192, poly2(7));
    expectEquals(-2146724623, poly3());
    expectEquals(64, polyBCE1());
    expectEquals(-68, polyBCE2());
    expectEquals(-80, polyBCE3());

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

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