content: /*
   * 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 dummy) {}
  
    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;
    }
  }
  