Home | History | Annotate | Download | only in smali
      1 # Copyright (C) 2015 The Android Open Source Project
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #      http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 
     15 .class public LTestCase;
     16 
     17 .super Ljava/lang/Object;
     18 
     19 .method public static $inline$True()Z
     20   .registers 1
     21   const/4 v0, 1
     22   return v0
     23 .end method
     24 
     25 
     26 ## CHECK-START: int TestCase.testSingleExit(int, boolean) dead_code_elimination$after_inlining (before)
     27 ## CHECK-DAG:     <<ArgX:i\d+>>  ParameterValue
     28 ## CHECK-DAG:     <<ArgY:z\d+>>  ParameterValue
     29 ## CHECK-DAG:     <<Cst1:i\d+>>  IntConstant 1
     30 ## CHECK-DAG:     <<Cst5:i\d+>>  IntConstant 5
     31 ## CHECK-DAG:     <<Cst7:i\d+>>  IntConstant 7
     32 ## CHECK-DAG:     <<PhiX:i\d+>>  Phi [<<ArgX>>,<<Add5:i\d+>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
     33 ## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
     34 ## CHECK-DAG:                    If [<<Cst1>>]                              loop:<<HeaderY>>
     35 ## CHECK-DAG:     <<Add5>>       Add [<<PhiX>>,<<Cst5>>]                    loop:<<HeaderY>>
     36 ## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
     37 ## CHECK-DAG:                    Return [<<PhiX>>]                          loop:none
     38 
     39 ## CHECK-START: int TestCase.testSingleExit(int, boolean) dead_code_elimination$after_inlining (after)
     40 ## CHECK-DAG:     <<ArgX:i\d+>>  ParameterValue
     41 ## CHECK-DAG:     <<ArgY:z\d+>>  ParameterValue
     42 ## CHECK-DAG:     <<Cst7:i\d+>>  IntConstant 7
     43 ## CHECK-DAG:     <<PhiX:i\d+>>  Phi [<<ArgX>>,<<AddX:i\d+>>]               loop:<<HeaderY:B\d+>>
     44 ## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
     45 ## CHECK-DAG:     <<AddX>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
     46 ## CHECK-DAG:                    Return [<<PhiX>>]                          loop:none
     47 
     48 .method public static testSingleExit(IZ)I
     49   .registers 3
     50 
     51   # p0 = int X
     52   # p1 = boolean Y
     53   # v0 = true
     54 
     55   invoke-static {}, LTestCase;->$inline$True()Z
     56   move-result v0
     57 
     58   :loop_start
     59   if-eqz p1, :loop_body   # cannot be determined statically
     60   if-nez v0, :loop_end    # will always exit
     61 
     62   # Dead block
     63   add-int/lit8 p0, p0, 5
     64   goto :loop_start
     65 
     66   # Live block
     67   :loop_body
     68   add-int/lit8 p0, p0, 7
     69   goto :loop_start
     70 
     71   :loop_end
     72   return p0
     73 .end method
     74 
     75 
     76 ## CHECK-START: int TestCase.testMultipleExits(int, boolean, boolean) dead_code_elimination$after_inlining (before)
     77 ## CHECK-DAG:     <<ArgX:i\d+>>  ParameterValue
     78 ## CHECK-DAG:     <<ArgY:z\d+>>  ParameterValue
     79 ## CHECK-DAG:     <<ArgZ:z\d+>>  ParameterValue
     80 ## CHECK-DAG:     <<Cst1:i\d+>>  IntConstant 1
     81 ## CHECK-DAG:     <<Cst5:i\d+>>  IntConstant 5
     82 ## CHECK-DAG:     <<Cst7:i\d+>>  IntConstant 7
     83 ## CHECK-DAG:     <<PhiX:i\d+>>  Phi [<<ArgX>>,<<Add5:i\d+>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
     84 ## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
     85 ## CHECK-DAG:                    If [<<ArgZ>>]                              loop:<<HeaderY>>
     86 ## CHECK-DAG:                    If [<<Cst1>>]                              loop:<<HeaderY>>
     87 ## CHECK-DAG:     <<Add5>>       Add [<<PhiX>>,<<Cst5>>]                    loop:<<HeaderY>>
     88 ## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
     89 ## CHECK-DAG:                    Return [<<PhiX>>]                          loop:none
     90 
     91 ## CHECK-START: int TestCase.testMultipleExits(int, boolean, boolean) dead_code_elimination$after_inlining (after)
     92 ## CHECK-DAG:     <<ArgX:i\d+>>  ParameterValue
     93 ## CHECK-DAG:     <<ArgY:z\d+>>  ParameterValue
     94 ## CHECK-DAG:     <<ArgZ:z\d+>>  ParameterValue
     95 ## CHECK-DAG:     <<Cst7:i\d+>>  IntConstant 7
     96 ## CHECK-DAG:     <<PhiX:i\d+>>  Phi [<<ArgX>>,<<Add7:i\d+>>]               loop:<<HeaderY:B\d+>>
     97 ## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
     98 ## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
     99 ## CHECK-DAG:                    If [<<ArgZ>>]                              loop:none
    100 ## CHECK-DAG:                    Return [<<PhiX>>]                          loop:none
    101 
    102 .method public static testMultipleExits(IZZ)I
    103   .registers 4
    104 
    105   # p0 = int X
    106   # p1 = boolean Y
    107   # p2 = boolean Z
    108   # v0 = true
    109 
    110   invoke-static {}, LTestCase;->$inline$True()Z
    111   move-result v0
    112 
    113   :loop_start
    114   if-eqz p1, :loop_body   # cannot be determined statically
    115   if-nez p2, :loop_end    # may exit
    116   if-nez v0, :loop_end    # will always exit
    117 
    118   # Dead block
    119   add-int/lit8 p0, p0, 5
    120   goto :loop_start
    121 
    122   # Live block
    123   :loop_body
    124   add-int/lit8 p0, p0, 7
    125   goto :loop_start
    126 
    127   :loop_end
    128   return p0
    129 .end method
    130 
    131 
    132 ## CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) dead_code_elimination$after_inlining (before)
    133 ## CHECK-DAG:     <<ArgX:i\d+>>  ParameterValue
    134 ## CHECK-DAG:     <<ArgY:z\d+>>  ParameterValue
    135 ## CHECK-DAG:     <<ArgZ:z\d+>>  ParameterValue
    136 ## CHECK-DAG:     <<Cst1:i\d+>>  IntConstant 1
    137 ## CHECK-DAG:     <<Cst5:i\d+>>  IntConstant 5
    138 ## CHECK-DAG:     <<Cst7:i\d+>>  IntConstant 7
    139 ## CHECK-DAG:     <<Cst11:i\d+>> IntConstant 11
    140 ## CHECK-DAG:     <<PhiX:i\d+>>  Phi [<<ArgX>>,<<Add5:i\d+>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
    141 ## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
    142 ## CHECK-DAG:     <<Mul9:i\d+>>  Mul [<<PhiX>>,<<Cst11>>]                   loop:<<HeaderY>>
    143 ## CHECK-DAG:     <<PhiY:i\d+>>  Phi [<<PhiX>>,<<Mul9>>]                    loop:<<HeaderY>>
    144 ## CHECK-DAG:                    If [<<Cst1>>]                              loop:<<HeaderY>>
    145 ## CHECK-DAG:     <<Add5>>       Add [<<PhiY>>,<<Cst5>>]                    loop:<<HeaderY>>
    146 ## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
    147 ## CHECK-DAG:                    Return [<<PhiY>>]                          loop:none
    148 
    149 ## CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) dead_code_elimination$after_inlining (after)
    150 ## CHECK-DAG:     <<ArgX:i\d+>>  ParameterValue
    151 ## CHECK-DAG:     <<ArgY:z\d+>>  ParameterValue
    152 ## CHECK-DAG:     <<ArgZ:z\d+>>  ParameterValue
    153 ## CHECK-DAG:     <<Cst7:i\d+>>  IntConstant 7
    154 ## CHECK-DAG:     <<Cst11:i\d+>> IntConstant 11
    155 ## CHECK-DAG:     <<PhiX:i\d+>>  Phi [<<ArgX>>,<<Add7:i\d+>>]               loop:<<HeaderY:B\d+>>
    156 ## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
    157 ## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
    158 ## CHECK-DAG:     <<Mul9:i\d+>>  Mul [<<PhiX>>,<<Cst11>>]                   loop:none
    159 ## CHECK-DAG:     <<Phi:i\d+>>   Phi [<<PhiX>>,<<Mul9>>]                    loop:none
    160 ## CHECK-DAG:                    Return [<<Phi>>]                           loop:none
    161 
    162 ## CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) dead_code_elimination$after_inlining (after)
    163 ## CHECK-NOT:                    IntConstant 5
    164 
    165 ## CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) select_generator (after)
    166 ## CHECK-DAG:     <<ArgX:i\d+>>  ParameterValue
    167 ## CHECK-DAG:     <<ArgY:z\d+>>  ParameterValue
    168 ## CHECK-DAG:     <<ArgZ:z\d+>>  ParameterValue
    169 ## CHECK-DAG:     <<Cst7:i\d+>>  IntConstant 7
    170 ## CHECK-DAG:     <<Cst11:i\d+>> IntConstant 11
    171 ## CHECK-DAG:     <<PhiX:i\d+>>  Phi [<<ArgX>>,<<Add7:i\d+>>]               loop:<<HeaderY:B\d+>>
    172 ## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
    173 ## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
    174 ## CHECK-DAG:     <<Mul9:i\d+>>  Mul [<<PhiX>>,<<Cst11>>]                   loop:none
    175 ## CHECK-DAG:     <<SelX:i\d+>>  Select [<<PhiX>>,<<Mul9>>,<<ArgZ>>]        loop:none
    176 ## CHECK-DAG:                    Return [<<SelX>>]                          loop:none
    177 
    178 .method public static testExitPredecessors(IZZ)I
    179   .registers 4
    180 
    181   # p0 = int X
    182   # p1 = boolean Y
    183   # p2 = boolean Z
    184   # v0 = true
    185 
    186   invoke-static {}, LTestCase;->$inline$True()Z
    187   move-result v0
    188 
    189   :loop_start
    190   if-eqz p1, :loop_body   # cannot be determined statically
    191 
    192   # Additional logic which will end up outside the loop
    193   if-eqz p2, :skip_if
    194   mul-int/lit8 p0, p0, 11
    195   :skip_if
    196 
    197   if-nez v0, :loop_end    # will always take the branch
    198 
    199   # Dead block
    200   add-int/lit8 p0, p0, 5
    201   goto :loop_start
    202 
    203   # Live block
    204   :loop_body
    205   add-int/lit8 p0, p0, 7
    206   goto :loop_start
    207 
    208   :loop_end
    209   return p0
    210 .end method
    211 
    212 
    213 ## CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination$after_inlining (before)
    214 ## CHECK-DAG:     <<ArgX:i\d+>>  ParameterValue
    215 ## CHECK-DAG:     <<ArgY:z\d+>>  ParameterValue
    216 ## CHECK-DAG:     <<ArgZ:z\d+>>  ParameterValue
    217 ## CHECK-DAG:     <<Cst0:i\d+>>  IntConstant 0
    218 ## CHECK-DAG:     <<Cst1:i\d+>>  IntConstant 1
    219 ## CHECK-DAG:     <<Cst5:i\d+>>  IntConstant 5
    220 ## CHECK-DAG:     <<Cst7:i\d+>>  IntConstant 7
    221 #
    222 ## CHECK-DAG:     <<PhiX:i\d+>>  Phi [<<ArgX>>,<<Add5:i\d+>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>>
    223 ## CHECK-DAG:     <<PhiZ1:i\d+>> Phi [<<ArgZ>>,<<XorZ:i\d+>>,<<PhiZ1>>]     loop:<<HeaderY>>
    224 ## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
    225 #
    226 #                                ### Inner loop ###
    227 ## CHECK-DAG:     <<PhiZ2:i\d+>> Phi [<<PhiZ1>>,<<XorZ>>]                   loop:<<HeaderZ:B\d+>>
    228 ## CHECK-DAG:     <<XorZ>>       Xor [<<PhiZ2>>,<<Cst1>>]                   loop:<<HeaderZ>>
    229 ## CHECK-DAG:     <<CondZ:z\d+>> Equal [<<XorZ>>,<<Cst0>>]                  loop:<<HeaderZ>>
    230 ## CHECK-DAG:                    If [<<CondZ>>]                             loop:<<HeaderZ>>
    231 #
    232 ## CHECK-DAG:     <<Add5>>       Add [<<PhiX>>,<<Cst5>>]                    loop:<<HeaderY>>
    233 ## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
    234 ## CHECK-DAG:                    Return [<<PhiX>>]                          loop:none
    235 
    236 ## CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination$after_inlining (after)
    237 ## CHECK-DAG:     <<ArgX:i\d+>>  ParameterValue
    238 ## CHECK-DAG:     <<ArgY:z\d+>>  ParameterValue
    239 ## CHECK-DAG:     <<ArgZ:z\d+>>  ParameterValue
    240 ## CHECK-DAG:     <<Cst0:i\d+>>  IntConstant 0
    241 ## CHECK-DAG:     <<Cst1:i\d+>>  IntConstant 1
    242 ## CHECK-DAG:     <<Cst7:i\d+>>  IntConstant 7
    243 #
    244 ## CHECK-DAG:     <<PhiX:i\d+>>  Phi [<<ArgX>>,<<Add7:i\d+>>]               loop:<<HeaderY:B\d+>>
    245 ## CHECK-DAG:                    If [<<ArgY>>]                              loop:<<HeaderY>>
    246 ## CHECK-DAG:     <<Add7>>       Add [<<PhiX>>,<<Cst7>>]                    loop:<<HeaderY>>
    247 #
    248 #                                ### Inner loop ###
    249 ## CHECK-DAG:     <<PhiZ:i\d+>>  Phi [<<ArgZ>>,<<XorZ:i\d+>>]               loop:<<HeaderZ:B\d+>>
    250 ## CHECK-DAG:     <<XorZ>>       Xor [<<PhiZ>>,<<Cst1>>]                    loop:<<HeaderZ>>
    251 ## CHECK-DAG:     <<CondZ:z\d+>> Equal [<<XorZ>>,<<Cst0>>]                  loop:<<HeaderZ>>
    252 ## CHECK-DAG:                    If [<<CondZ>>]                             loop:<<HeaderZ>>
    253 #
    254 ## CHECK-DAG:                    Return [<<PhiX>>]                          loop:none
    255 
    256 .method public static testInnerLoop(IZZ)I
    257   .registers 4
    258 
    259   # p0 = int X
    260   # p1 = boolean Y
    261   # p2 = boolean Z
    262   # v0 = true
    263 
    264   invoke-static {}, LTestCase;->$inline$True()Z
    265   move-result v0
    266 
    267   :loop_start
    268   if-eqz p1, :loop_body   # cannot be determined statically
    269 
    270   # Inner loop which will end up outside its parent
    271   :inner_loop_start
    272   xor-int/lit8 p2, p2, 1
    273   if-eqz p2, :inner_loop_start
    274 
    275   if-nez v0, :loop_end    # will always take the branch
    276 
    277   # Dead block
    278   add-int/lit8 p0, p0, 5
    279   goto :loop_start
    280 
    281   # Live block
    282   :loop_body
    283   add-int/lit8 p0, p0, 7
    284   goto :loop_start
    285 
    286   :loop_end
    287   return p0
    288 .end method
    289