Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 public class Main {
     18 
     19   public static void main(String[] args) {
     20     testNoInline(args);
     21     System.out.println(staticField);
     22     testInline(args);
     23     System.out.println(staticField);
     24     testNonConstantInputs(args);
     25     System.out.println(staticField);
     26     testNonConstantEqual(args);
     27     System.out.println(staticField);
     28     testGreaterCondition(args);
     29     System.out.println(staticField);
     30     testSwitch(args);
     31     System.out.println(staticField);
     32     testFP(args);
     33     System.out.println(staticField);
     34   }
     35 
     36   // Test when a condition is the input of the if.
     37 
     38   /// CHECK-START: void Main.testNoInline(java.lang.String[]) dead_code_elimination$initial (before)
     39   /// CHECK: <<Const0:i\d+>>   IntConstant 0
     40   /// CHECK:                   If
     41   /// CHECK: <<Phi:i\d+>>      Phi
     42   /// CHECK: <<Equal:z\d+>>    Equal [<<Phi>>,<<Const0>>]
     43   /// CHECK:                   If [<<Equal>>]
     44 
     45   /// CHECK-START: void Main.testNoInline(java.lang.String[]) dead_code_elimination$initial (after)
     46   /// CHECK:      If
     47   /// CHECK-NOT:  Phi
     48   /// CHECK-NOT:  Equal
     49   /// CHECK-NOT:  If
     50   public static void testNoInline(String[] args) {
     51     boolean myVar = false;
     52     if (args.length == 42) {
     53       myVar = true;
     54     } else {
     55       staticField = 32;
     56       myVar = false;
     57     }
     58     if (myVar) {
     59       staticField = 12;
     60     } else {
     61       staticField = 54;
     62     }
     63   }
     64 
     65   // Test when the phi is the input of the if.
     66 
     67   /// CHECK-START: void Main.testInline(java.lang.String[]) dead_code_elimination$after_inlining (before)
     68   /// CHECK-DAG: <<Const0:i\d+>>   IntConstant 0
     69   /// CHECK-DAG:                   If
     70   /// CHECK-DAG: <<Phi:i\d+>>      Phi
     71   /// CHECK-DAG:                   If [<<Phi>>]
     72 
     73   /// CHECK-START: void Main.testInline(java.lang.String[]) dead_code_elimination$after_inlining (after)
     74   /// CHECK:      If
     75   /// CHECK-NOT:  Phi
     76   /// CHECK-NOT:  If
     77   public static void testInline(String[] args) {
     78     boolean myVar = $inline$doTest(args);
     79     if (myVar) {
     80       staticField = 12;
     81     } else {
     82       staticField = 54;
     83     }
     84   }
     85 
     86   public static boolean $inline$doTest(String[] args) {
     87     boolean myVar;
     88     if (args.length == 42) {
     89       myVar = true;
     90     } else {
     91       staticField = 32;
     92       myVar = false;
     93     }
     94     return myVar;
     95   }
     96 
     97   // Test when one input is not a constant. We can only optimize the constant input.
     98 
     99   /// CHECK-START: void Main.testNonConstantInputs(java.lang.String[]) dead_code_elimination$initial (before)
    100   /// CHECK-DAG: <<Const34:i\d+>>         IntConstant 34
    101   /// CHECK-DAG: <<Const42:i\d+>>         IntConstant 42
    102   /// CHECK-DAG:                          If
    103   /// CHECK-DAG: <<StaticFieldGet:i\d+>>  StaticFieldGet
    104   /// CHECK-DAG: <<Phi:i\d+>>             Phi [<<Const34>>,<<StaticFieldGet>>]
    105   /// CHECK-DAG: <<NotEqual:z\d+>>        NotEqual [<<Phi>>,<<Const42>>]
    106   /// CHECK-DAG:                          If [<<NotEqual>>]
    107 
    108   /// CHECK-START: void Main.testNonConstantInputs(java.lang.String[]) dead_code_elimination$initial (after)
    109   /// CHECK-DAG: <<Const42:i\d+>>         IntConstant 42
    110   /// CHECK-DAG:                          If
    111   /// CHECK-DAG: <<StaticFieldGet:i\d+>>  StaticFieldGet
    112   /// CHECK-NOT:                          Phi
    113   /// CHECK-DAG: <<NotEqual:z\d+>>        NotEqual [<<StaticFieldGet>>,<<Const42>>]
    114   /// CHECK-DAG:                          If [<<NotEqual>>]
    115   public static void testNonConstantInputs(String[] args) {
    116     int a = 42;
    117     if (args.length == 42) {
    118       a = 34;
    119     } else {
    120       staticField = 32;
    121       a = otherStaticField;
    122     }
    123     if (a == 42) {
    124       staticField = 12;
    125     } else {
    126       staticField = 54;
    127     }
    128   }
    129 
    130   // Test with a condition.
    131 
    132   /// CHECK-START: void Main.testGreaterCondition(java.lang.String[]) dead_code_elimination$initial (before)
    133   /// CHECK-DAG: <<Const34:i\d+>>         IntConstant 34
    134   /// CHECK-DAG: <<Const22:i\d+>>         IntConstant 22
    135   /// CHECK-DAG: <<Const25:i\d+>>         IntConstant 25
    136   /// CHECK-DAG:                          If
    137   /// CHECK-DAG: <<Phi:i\d+>>             Phi [<<Const34>>,<<Const22>>]
    138   /// CHECK-DAG: <<GE:z\d+>>              GreaterThanOrEqual [<<Phi>>,<<Const25>>]
    139   /// CHECK-DAG:                          If [<<GE>>]
    140 
    141   /// CHECK-START: void Main.testGreaterCondition(java.lang.String[]) dead_code_elimination$initial (after)
    142   /// CHECK-DAG:                          If
    143   /// CHECK-NOT:                          Phi
    144   /// CHECK-NOT:                          GreaterThanOrEqual
    145   /// CHECK-NOT:                          If
    146   public static void testGreaterCondition(String[] args) {
    147     int a = 42;
    148     if (args.length == 42) {
    149       a = 34;
    150     } else {
    151       staticField = 32;
    152       a = 22;
    153     }
    154     if (a < 25) {
    155       staticField = 12;
    156     } else {
    157       staticField = 54;
    158     }
    159   }
    160 
    161   // Test when comparing non constants.
    162 
    163   /// CHECK-START: void Main.testNonConstantEqual(java.lang.String[]) dead_code_elimination$initial (before)
    164   /// CHECK-DAG: <<Const34:i\d+>>         IntConstant 34
    165   /// CHECK-DAG: <<Const42:i\d+>>         IntConstant 42
    166   /// CHECK-DAG:                          If
    167   /// CHECK-DAG: <<StaticFieldGet:i\d+>>  StaticFieldGet
    168   /// CHECK-DAG: <<Phi:i\d+>>             Phi [<<Const34>>,<<StaticFieldGet>>]
    169   /// CHECK-DAG: <<NotEqual:z\d+>>        NotEqual [<<Phi>>,<<StaticFieldGet>>]
    170   /// CHECK-DAG:                          If [<<NotEqual>>]
    171 
    172   /// CHECK-START: void Main.testNonConstantEqual(java.lang.String[]) dead_code_elimination$initial (after)
    173   /// CHECK-DAG: <<Const34:i\d+>>         IntConstant 34
    174   /// CHECK-DAG:                          If
    175   /// CHECK-DAG: <<StaticFieldGet:i\d+>>  StaticFieldGet
    176   /// CHECK-NOT:                          Phi
    177   /// CHECK-DAG: <<NotEqual:z\d+>>        NotEqual [<<Const34>>,<<StaticFieldGet>>]
    178   /// CHECK-DAG:                          If [<<NotEqual>>]
    179   public static void testNonConstantEqual(String[] args) {
    180     int a = 42;
    181     int b = otherStaticField;
    182     if (args.length == 42) {
    183       a = 34;
    184     } else {
    185       staticField = 32;
    186       a = b;
    187     }
    188     if (a == b) {
    189       staticField = 12;
    190     } else {
    191       staticField = 54;
    192     }
    193   }
    194 
    195   // Make sure we don't "simplify" a loop and potentially turn it into
    196   // an irreducible loop. The suspend check at the loop header prevents
    197   // us from doing the simplification.
    198 
    199   /// CHECK-START: void Main.testLoop(boolean) disassembly (after)
    200   /// CHECK-DAG: SuspendCheck
    201   /// CHECK:     irreducible:false
    202   /// CHECK-NOT: irreducible:true
    203   public static void testLoop(boolean c) {
    204     while (true) {
    205       if (c) {
    206         if ($noinline$foo()) return;
    207         c = false;
    208       } else {
    209         $noinline$foo();
    210         c = true;
    211       }
    212     }
    213   }
    214 
    215   static boolean $noinline$foo() {
    216     if (doThrow) throw new Error("");
    217     return true;
    218   }
    219 
    220   /// CHECK-START: void Main.testSwitch(java.lang.String[]) dead_code_elimination$initial (before)
    221   /// CHECK:      If
    222   /// CHECK:      If
    223   /// CHECK:      If
    224 
    225   /// CHECK-START: void Main.testSwitch(java.lang.String[]) dead_code_elimination$initial (after)
    226   /// CHECK:      If
    227   /// CHECK:      If
    228   /// CHECK-NOT:  If
    229   public static void testSwitch(String[] args) {
    230     boolean cond = false;
    231     switch (args.length) {
    232       case 42:
    233         staticField = 11;
    234         cond = true;
    235         break;
    236       case 43:
    237         staticField = 33;
    238         cond = true;
    239         break;
    240       default:
    241         cond = false;
    242         break;
    243     }
    244     if (cond) {
    245       // Redirect case 42 and 43 here.
    246       staticField = 2;
    247     }
    248     // Redirect default here.
    249   }
    250 
    251   /// CHECK-START: void Main.testFP(java.lang.String[]) dead_code_elimination$initial (before)
    252   /// CHECK:      If
    253   /// CHECK:      If
    254 
    255   /// CHECK-START: void Main.testFP(java.lang.String[]) dead_code_elimination$initial (after)
    256   /// CHECK:      If
    257   /// CHECK:      If
    258   public static void testFP(String[] args) {
    259     float f = 2.2f;
    260     float nan = $noinline$getNaN();
    261     if (args.length == 42) {
    262       f = 4.3f;
    263     } else {
    264       staticField = 33;
    265       f = nan;
    266     }
    267     if (f == nan) {
    268       staticField = 5;
    269     }
    270   }
    271 
    272   // No inline variant to avoid having the compiler see it's a NaN.
    273   static float $noinline$getNaN() {
    274     if (doThrow) throw new Error("");
    275     return Float.NaN;
    276   }
    277 
    278   static boolean doThrow;
    279   static int staticField;
    280   static int otherStaticField;
    281 }
    282