content: /*
   * 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.
   */
  
  public class Main {
  
    public static void main(String[] args) {
      testNoInline(args);
      System.out.println(staticField);
      testInline(args);
      System.out.println(staticField);
      testNonConstantInputs(args);
      System.out.println(staticField);
      testNonConstantEqual(args);
      System.out.println(staticField);
      testGreaterCondition(args);
      System.out.println(staticField);
      testSwitch(args);
      System.out.println(staticField);
      testFP(args);
      System.out.println(staticField);
    }
  
    // Test when a condition is the input of the if.
  
    /// CHECK-START: void Main.testNoInline(java.lang.String[]) dead_code_elimination$initial (before)
    /// CHECK: <<Const0:i\d+>>   IntConstant 0
    /// CHECK:                   If
    /// CHECK: <<Phi:i\d+>>      Phi
    /// CHECK: <<Equal:z\d+>>    Equal [<<Phi>>,<<Const0>>]
    /// CHECK:                   If [<<Equal>>]
  
    /// CHECK-START: void Main.testNoInline(java.lang.String[]) dead_code_elimination$initial (after)
    /// CHECK:      If
    /// CHECK-NOT:  Phi
    /// CHECK-NOT:  Equal
    /// CHECK-NOT:  If
    public static void testNoInline(String[] args) {
      boolean myVar = false;
      if (args.length == 42) {
        myVar = true;
      } else {
        staticField = 32;
        myVar = false;
      }
      if (myVar) {
        staticField = 12;
      } else {
        staticField = 54;
      }
    }
  
    // Test when the phi is the input of the if.
  
    /// CHECK-START: void Main.testInline(java.lang.String[]) dead_code_elimination$after_inlining (before)
    /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0
    /// CHECK-DAG:                   If
    /// CHECK-DAG: <<Phi:i\d+>>      Phi
    /// CHECK-DAG:                   If [<<Phi>>]
  
    /// CHECK-START: void Main.testInline(java.lang.String[]) dead_code_elimination$after_inlining (after)
    /// CHECK:      If
    /// CHECK-NOT:  Phi
    /// CHECK-NOT:  If
    public static void testInline(String[] args) {
      boolean myVar = $inline$doTest(args);
      if (myVar) {
        staticField = 12;
      } else {
        staticField = 54;
      }
    }
  
    public static boolean $inline$doTest(String[] args) {
      boolean myVar;
      if (args.length == 42) {
        myVar = true;
      } else {
        staticField = 32;
        myVar = false;
      }
      return myVar;
    }
  
    // Test when one input is not a constant. We can only optimize the constant input.
  
    /// CHECK-START: void Main.testNonConstantInputs(java.lang.String[]) dead_code_elimination$initial (before)
    /// CHECK-DAG: <<Const34:i\d+>>         IntConstant 34
    /// CHECK-DAG: <<Const42:i\d+>>         IntConstant 42
    /// CHECK-DAG:                          If
    /// CHECK-DAG: <<StaticFieldGet:i\d+>>  StaticFieldGet
    /// CHECK-DAG: <<Phi:i\d+>>             Phi [<<Const34>>,<<StaticFieldGet>>]
    /// CHECK-DAG: <<NotEqual:z\d+>>        NotEqual [<<Phi>>,<<Const42>>]
    /// CHECK-DAG:                          If [<<NotEqual>>]
  
    /// CHECK-START: void Main.testNonConstantInputs(java.lang.String[]) dead_code_elimination$initial (after)
    /// CHECK-DAG: <<Const42:i\d+>>         IntConstant 42
    /// CHECK-DAG:                          If
    /// CHECK-DAG: <<StaticFieldGet:i\d+>>  StaticFieldGet
    /// CHECK-NOT:                          Phi
    /// CHECK-DAG: <<NotEqual:z\d+>>        NotEqual [<<StaticFieldGet>>,<<Const42>>]
    /// CHECK-DAG:                          If [<<NotEqual>>]
    public static void testNonConstantInputs(String[] args) {
      int a = 42;
      if (args.length == 42) {
        a = 34;
      } else {
        staticField = 32;
        a = otherStaticField;
      }
      if (a == 42) {
        staticField = 12;
      } else {
        staticField = 54;
      }
    }
  
    // Test with a condition.
  
    /// CHECK-START: void Main.testGreaterCondition(java.lang.String[]) dead_code_elimination$initial (before)
    /// CHECK-DAG: <<Const34:i\d+>>         IntConstant 34
    /// CHECK-DAG: <<Const22:i\d+>>         IntConstant 22
    /// CHECK-DAG: <<Const25:i\d+>>         IntConstant 25
    /// CHECK-DAG:                          If
    /// CHECK-DAG: <<Phi:i\d+>>             Phi [<<Const34>>,<<Const22>>]
    /// CHECK-DAG: <<GE:z\d+>>              GreaterThanOrEqual [<<Phi>>,<<Const25>>]
    /// CHECK-DAG:                          If [<<GE>>]
  
    /// CHECK-START: void Main.testGreaterCondition(java.lang.String[]) dead_code_elimination$initial (after)
    /// CHECK-DAG:                          If
    /// CHECK-NOT:                          Phi
    /// CHECK-NOT:                          GreaterThanOrEqual
    /// CHECK-NOT:                          If
    public static void testGreaterCondition(String[] args) {
      int a = 42;
      if (args.length == 42) {
        a = 34;
      } else {
        staticField = 32;
        a = 22;
      }
      if (a < 25) {
        staticField = 12;
      } else {
        staticField = 54;
      }
    }
  
    // Test when comparing non constants.
  
    /// CHECK-START: void Main.testNonConstantEqual(java.lang.String[]) dead_code_elimination$initial (before)
    /// CHECK-DAG: <<Const34:i\d+>>         IntConstant 34
    /// CHECK-DAG: <<Const42:i\d+>>         IntConstant 42
    /// CHECK-DAG:                          If
    /// CHECK-DAG: <<StaticFieldGet:i\d+>>  StaticFieldGet
    /// CHECK-DAG: <<Phi:i\d+>>             Phi [<<Const34>>,<<StaticFieldGet>>]
    /// CHECK-DAG: <<NotEqual:z\d+>>        NotEqual [<<Phi>>,<<StaticFieldGet>>]
    /// CHECK-DAG:                          If [<<NotEqual>>]
  
    /// CHECK-START: void Main.testNonConstantEqual(java.lang.String[]) dead_code_elimination$initial (after)
    /// CHECK-DAG: <<Const34:i\d+>>         IntConstant 34
    /// CHECK-DAG:                          If
    /// CHECK-DAG: <<StaticFieldGet:i\d+>>  StaticFieldGet
    /// CHECK-NOT:                          Phi
    /// CHECK-DAG: <<NotEqual:z\d+>>        NotEqual [<<Const34>>,<<StaticFieldGet>>]
    /// CHECK-DAG:                          If [<<NotEqual>>]
    public static void testNonConstantEqual(String[] args) {
      int a = 42;
      int b = otherStaticField;
      if (args.length == 42) {
        a = 34;
      } else {
        staticField = 32;
        a = b;
      }
      if (a == b) {
        staticField = 12;
      } else {
        staticField = 54;
      }
    }
  
    // Make sure we don't "simplify" a loop and potentially turn it into
    // an irreducible loop. The suspend check at the loop header prevents
    // us from doing the simplification.
  
    /// CHECK-START: void Main.testLoop(boolean) disassembly (after)
    /// CHECK-DAG: SuspendCheck
    /// CHECK:     irreducible:false
    /// CHECK-NOT: irreducible:true
    public static void testLoop(boolean c) {
      while (true) {
        if (c) {
          if ($noinline$foo()) return;
          c = false;
        } else {
          $noinline$foo();
          c = true;
        }
      }
    }
  
    static boolean $noinline$foo() {
      if (doThrow) throw new Error("");
      return true;
    }
  
    /// CHECK-START: void Main.testSwitch(java.lang.String[]) dead_code_elimination$initial (before)
    /// CHECK:      If
    /// CHECK:      If
    /// CHECK:      If
  
    /// CHECK-START: void Main.testSwitch(java.lang.String[]) dead_code_elimination$initial (after)
    /// CHECK:      If
    /// CHECK:      If
    /// CHECK-NOT:  If
    public static void testSwitch(String[] args) {
      boolean cond = false;
      switch (args.length) {
        case 42:
          staticField = 11;
          cond = true;
          break;
        case 43:
          staticField = 33;
          cond = true;
          break;
        default:
          cond = false;
          break;
      }
      if (cond) {
        // Redirect case 42 and 43 here.
        staticField = 2;
      }
      // Redirect default here.
    }
  
    /// CHECK-START: void Main.testFP(java.lang.String[]) dead_code_elimination$initial (before)
    /// CHECK:      If
    /// CHECK:      If
  
    /// CHECK-START: void Main.testFP(java.lang.String[]) dead_code_elimination$initial (after)
    /// CHECK:      If
    /// CHECK:      If
    public static void testFP(String[] args) {
      float f = 2.2f;
      float nan = $noinline$getNaN();
      if (args.length == 42) {
        f = 4.3f;
      } else {
        staticField = 33;
        f = nan;
      }
      if (f == nan) {
        staticField = 5;
      }
    }
  
    // No inline variant to avoid having the compiler see it's a NaN.
    static float $noinline$getNaN() {
      if (doThrow) throw new Error("");
      return Float.NaN;
    }
  
    static boolean doThrow;
    static int staticField;
    static int otherStaticField;
  }
  