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

public class Main {

  /// CHECK-START: Main Main.keepTest(Main) instruction_simplifier (before)
  /// CHECK:         NullCheck
  /// CHECK:         InvokeStaticOrDirect

  /// CHECK-START: Main Main.keepTest(Main) instruction_simplifier (after)
  /// CHECK:         NullCheck
  /// CHECK:         InvokeStaticOrDirect
  public Main keepTest(Main m) {
    return m.g();
  }

  /// CHECK-START: Main Main.thisTest() builder (after)
  /// CHECK-NOT:     NullCheck
  /// CHECK:         InvokeStaticOrDirect
  public Main thisTest() {
    return g();
  }

  /// CHECK-START: Main Main.newInstanceRemoveTest() builder (after)
  /// CHECK:         NewInstance
  /// CHECK:         InvokeStaticOrDirect
  /// CHECK:         InvokeStaticOrDirect

  /// CHECK-START: Main Main.newInstanceRemoveTest() builder (after)
  /// CHECK-NOT:     NullCheck
  public Main newInstanceRemoveTest() {
    Main m = new Main();
    return m.g();
  }

  /// CHECK-START: Main Main.newArrayRemoveTest() builder (after)
  /// CHECK:         NewArray
  /// CHECK:         ArrayGet

  /// CHECK-START: Main Main.newArrayRemoveTest() builder (after)
  /// CHECK-NOT:     NullCheck
  public Main newArrayRemoveTest() {
    Main[] ms = new Main[1];
    return ms[0];
  }

  /// CHECK-START: Main Main.ifRemoveTest(boolean) instruction_simplifier (before)
  /// CHECK:         NewInstance
  /// CHECK:         NullCheck

  /// CHECK-START: Main Main.ifRemoveTest(boolean) instruction_simplifier (after)
  /// CHECK:         NewInstance
  /// CHECK-NOT:     NullCheck
  public Main ifRemoveTest(boolean flag) {
    Main m = null;
    if (flag) {
      m = new Main();
    } else {
      m = new Main(1);
    }
    return m.g();
  }

  /// CHECK-START: Main Main.ifKeepTest(boolean) instruction_simplifier (before)
  /// CHECK:         NewInstance
  /// CHECK:         NullCheck

  /// CHECK-START: Main Main.ifKeepTest(boolean) instruction_simplifier (after)
  /// CHECK:         NewInstance
  /// CHECK:         NullCheck
  public Main ifKeepTest(boolean flag) {
    Main m = null;
    if (flag) {
      m = new Main(1);
    }
    return m.g();
  }

  /// CHECK-START: Main Main.forRemoveTest(int) instruction_simplifier (before)
  /// CHECK:         NullCheck

  /// CHECK-START: Main Main.forRemoveTest(int) instruction_simplifier (after)
  /// CHECK-NOT:     NullCheck
  public Main forRemoveTest(int count) {
    Main a = new Main();
    Main m = new Main();
    for (int i = 0; i < count; i++) {
      if (i % 2 == 0) {
        m = a;
      }
    }
    return m.g();
  }

  /// CHECK-START: Main Main.forKeepTest(int) instruction_simplifier (before)
  /// CHECK:         NullCheck

  /// CHECK-START: Main Main.forKeepTest(int) instruction_simplifier (after)
  /// CHECK:         NullCheck
  public Main forKeepTest(int count) {
    Main a = new Main();
    Main m = new Main();
    for (int i = 0; i < count; i++) {
      if (i % 2 == 0) {
        m = a;
      } else {
        m = null;
      }
    }
    return m.g();
  }

  /// CHECK-START: Main Main.phiFlowRemoveTest(int) instruction_simplifier (before)
  /// CHECK:         NullCheck

  /// CHECK-START: Main Main.phiFlowRemoveTest(int) instruction_simplifier (after)
  /// CHECK-NOT:     NullCheck
  public Main phiFlowRemoveTest(int count) {
    Main a = new Main();
    Main m = new Main();
    for (int i = 0; i < count; i++) {
      if (i % 2 == 0) {
        m = a;
      }
    }
    Main n = new Main();
    for (int i = 0; i < count; i++) {
      if (i % 3 == 0) {
        n = m;
      }
    }
    return n.g();
  }

  /// CHECK-START: Main Main.phiFlowKeepTest(int) instruction_simplifier (before)
  /// CHECK:         NullCheck

  /// CHECK-START: Main Main.phiFlowKeepTest(int) instruction_simplifier (after)
  /// CHECK:         NullCheck
  public Main phiFlowKeepTest(int count) {
    Main a = new Main();
    Main m = new Main();
    for (int i = 0; i < count; i++) {
      if (i % 2 == 0) {
        m = a;
      } else {
        m = null;
      }
    }
    Main n = new Main();
    for (int i = 0; i < count; i++) {
      if (i % 3 == 0) {
        n = m;
      }
    }
    return n.g();
  }

  /// CHECK-START: Main Main.scopeRemoveTest(int, Main) builder (after)
  /// CHECK-NOT:     NullCheck
  public Main scopeRemoveTest(int count, Main a) {
    Main m = null;
    for (int i = 0; i < count; i++) {
      if (i % 2 == 0) {
        m = new Main();
        m.g();
      } else {
        m = a;
      }
    }
    return m;
  }

  /// CHECK-START: Main Main.scopeKeepTest(int, Main) instruction_simplifier (before)
  /// CHECK:         NullCheck

  /// CHECK-START: Main Main.scopeKeepTest(int, Main) instruction_simplifier (after)
  /// CHECK:         NullCheck
  public Main scopeKeepTest(int count, Main a) {
    Main m = new Main();
    for (int i = 0; i < count; i++) {
      if (i % 2 == 0) {
        m = a;
      } else {
        m = a;
        m.g();
      }
    }
    return m;
  }

  /// CHECK-START: Main Main.scopeIfNotNullRemove(Main) instruction_simplifier (before)
  /// CHECK:         NullCheck

  /// CHECK-START: Main Main.scopeIfNotNullRemove(Main) instruction_simplifier (after)
  /// CHECK-NOT:     NullCheck
  public Main scopeIfNotNullRemove(Main m) {
    if (m != null) {
      return m.g();
    }
    return m;
  }

  /// CHECK-START: Main Main.scopeIfKeep(Main) instruction_simplifier (before)
  /// CHECK:         NullCheck

  /// CHECK-START: Main Main.scopeIfKeep(Main) instruction_simplifier (after)
  /// CHECK:         NullCheck
  public Main scopeIfKeep(Main m) {
    if (m == null) {
      m = new Main();
    }
    return m.g();
  }

  public Main() {}
  public Main(int unused) {}

  private Main g() {
    // avoids inlining
    throw new RuntimeException();
  }

  public static void main(String[] args) {
    new Main();
  }

}

// Regression for when we created and kept equivalent phis with the same type.
// The phi used in comparison would be different then the one used for access
// so we could not safely discard it.
class ListElement {
  private ListElement next;

  /// CHECK-START: boolean ListElement.isShorter(ListElement, ListElement) instruction_simplifier (before)
  /// CHECK:         NullCheck
  /// CHECK:         NullCheck

  /// CHECK-START: boolean ListElement.isShorter(ListElement, ListElement) instruction_simplifier (after)
  /// CHECK-NOT:     NullCheck
  static boolean isShorter(ListElement x, ListElement y) {
    ListElement xTail = x;
    ListElement yTail = y;
    while (yTail != null) {
      if (xTail == null) return true;
      xTail = xTail.next;
      yTail = yTail.next;
    }
    return false;
  }
}
