/*
 * Copyright (C) 2017 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.
 */

// This base class has a single final field;
// the constructor should have one fence.
class Circle {
  Circle(double radius) {
    this.radius = radius;
  }
  public double getRadius() {
    return radius;
  }
  public double getArea() {
    return radius * radius * Math.PI;
  }

  public double getCircumference() {
    return 2 * Math.PI * radius;
  }

  private final double radius;
}

// This subclass adds an extra final field;
// there should be an extra constructor fence added
// (for a total of 2 after inlining).
class Ellipse extends Circle {
  Ellipse(double vertex, double covertex) {
    super(vertex);

    this.covertex = covertex;
  }

  public double getVertex() {
    return getRadius();
  }

  public double getCovertex() {
    return covertex;
  }

  @Override
  public double getArea() {
    return getRadius() * covertex * Math.PI;
  }

  private final double covertex;
}

class CalcCircleAreaOrCircumference {
  public static final int TYPE_AREA = 0;
  public static final int TYPE_CIRCUMFERENCE = 1;

  double value;

  public CalcCircleAreaOrCircumference(int type) {
    this.type = type;
  }

  final int type;
}

public class Main {

  /// CHECK-START: double Main.calcCircleArea(double) load_store_elimination (before)
  /// CHECK: NewInstance
  /// CHECK: InstanceFieldSet
  /// CHECK: ConstructorFence
  /// CHECK: InstanceFieldGet

  /// CHECK-START: double Main.calcCircleArea(double) load_store_elimination (after)
  /// CHECK-NOT: NewInstance
  /// CHECK-NOT: InstanceFieldSet
  /// CHECK-NOT: ConstructorFence
  /// CHECK-NOT: InstanceFieldGet

  // Make sure the constructor fence gets eliminated when the allocation is eliminated.
  static double calcCircleArea(double radius) {
    return new Circle(radius).getArea();
  }

  /// CHECK-START: double Main.calcEllipseArea(double, double) load_store_elimination (before)
  /// CHECK: NewInstance
  /// CHECK: InstanceFieldSet
  /// CHECK: InstanceFieldSet
  /// CHECK: ConstructorFence
  /// CHECK: InstanceFieldGet
  /// CHECK: InstanceFieldGet

  /// CHECK-START: double Main.calcEllipseArea(double, double) load_store_elimination (after)
  /// CHECK-NOT: NewInstance
  /// CHECK-NOT: InstanceFieldSet
  /// CHECK-NOT: ConstructorFence
  /// CHECK-NOT: InstanceFieldGet

  // Multiple constructor fences can accumulate through inheritance, make sure
  // they are all eliminated when the allocation is eliminated.
  static double calcEllipseArea(double vertex, double covertex) {
    return new Ellipse(vertex, covertex).getArea();
  }

  /// CHECK-START: double Main.calcCircleAreaOrCircumference(double, boolean) load_store_elimination (before)
  /// CHECK-DAG: NewInstance
  /// CHECK-DAG: InstanceFieldSet
  /// CHECK-DAG: ConstructorFence
  /// CHECK-DAG: InstanceFieldGet

  /// CHECK-START: double Main.calcCircleAreaOrCircumference(double, boolean) load_store_elimination (after)
  /// CHECK:     Phi
  /// CHECK-NOT: Phi

  /// CHECK-START: double Main.calcCircleAreaOrCircumference(double, boolean) load_store_elimination (after)
  /// CHECK-NOT: NewInstance
  /// CHECK-NOT: ConstructorFence

  // The object allocation shall be eliminated by LSE and the load shall be replaced
  // by a Phi with the values that were previously being stored.
  static double calcCircleAreaOrCircumference(double radius, boolean area_or_circumference) {
    CalcCircleAreaOrCircumference calc =
      new CalcCircleAreaOrCircumference(
          area_or_circumference ? CalcCircleAreaOrCircumference.TYPE_AREA :
          CalcCircleAreaOrCircumference.TYPE_CIRCUMFERENCE);

    if (area_or_circumference) {
      // Area
      calc.value = Math.PI * Math.PI * radius;
    } else {
      // Circumference
      calc.value = 2 * Math.PI * radius;
    }

    return calc.value;
  }

  /// CHECK-START: Circle Main.makeCircle(double) load_store_elimination (after)
  /// CHECK: NewInstance
  /// CHECK: ConstructorFence

  // The object allocation is considered a singleton by LSE,
  // but we cannot eliminate the new because it is returned.
  //
  // The constructor fence must also not be removed because the object could escape the
  // current thread (in the caller).
  static Circle makeCircle(double radius) {
    return new Circle(radius);
  }

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

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

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

  static void assertInstanceOf(Object result, Class<?> expected) {
    if (result.getClass() != expected) {
      throw new Error("Expected type: " + expected + ", found : " + result.getClass());
    }
  }

  public static void main(String[] args) {
    assertDoubleEquals(Math.PI * Math.PI * Math.PI, calcCircleArea(Math.PI));
    assertDoubleEquals(Math.PI * Math.PI * Math.PI, calcEllipseArea(Math.PI, Math.PI));
    assertDoubleEquals(2 * Math.PI * Math.PI, calcCircleAreaOrCircumference(Math.PI, false));
    assertInstanceOf(makeCircle(Math.PI), Circle.class);
  }

  static boolean sFlag;
}
