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: <<SelX:i\d+>> Select [<<PhiX>>,<<Mul9>>,<<ArgZ>>] loop:<<HeaderY>> 144## CHECK-DAG: If [<<Cst1>>] loop:<<HeaderY>> 145## CHECK-DAG: <<Add5>> Add [<<SelX>>,<<Cst5>>] loop:<<HeaderY>> 146## CHECK-DAG: <<Add7>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>> 147## CHECK-DAG: Return [<<SelX>>] 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: <<SelX:i\d+>> Select [<<PhiX>>,<<Mul9>>,<<ArgZ>>] loop:none 160## CHECK-DAG: Return [<<SelX>>] loop:none 161 162.method public static testExitPredecessors(IZZ)I 163 .registers 4 164 165 # p0 = int X 166 # p1 = boolean Y 167 # p2 = boolean Z 168 # v0 = true 169 170 invoke-static {}, LTestCase;->$inline$True()Z 171 move-result v0 172 173 :loop_start 174 if-eqz p1, :loop_body # cannot be determined statically 175 176 # Additional logic which will end up outside the loop 177 if-eqz p2, :skip_if 178 mul-int/lit8 p0, p0, 11 179 :skip_if 180 181 if-nez v0, :loop_end # will always take the branch 182 183 # Dead block 184 add-int/lit8 p0, p0, 5 185 goto :loop_start 186 187 # Live block 188 :loop_body 189 add-int/lit8 p0, p0, 7 190 goto :loop_start 191 192 :loop_end 193 return p0 194.end method 195 196 197## CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination$after_inlining (before) 198## CHECK-DAG: <<ArgX:i\d+>> ParameterValue 199## CHECK-DAG: <<ArgY:z\d+>> ParameterValue 200## CHECK-DAG: <<ArgZ:z\d+>> ParameterValue 201## CHECK-DAG: <<Cst0:i\d+>> IntConstant 0 202## CHECK-DAG: <<Cst1:i\d+>> IntConstant 1 203## CHECK-DAG: <<Cst5:i\d+>> IntConstant 5 204## CHECK-DAG: <<Cst7:i\d+>> IntConstant 7 205# 206## CHECK-DAG: <<PhiX:i\d+>> Phi [<<ArgX>>,<<Add5:i\d+>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>> 207## CHECK-DAG: <<PhiZ1:i\d+>> Phi [<<ArgZ>>,<<XorZ:i\d+>>,<<PhiZ1>>] loop:<<HeaderY>> 208## CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>> 209# 210# ### Inner loop ### 211## CHECK-DAG: <<PhiZ2:i\d+>> Phi [<<PhiZ1>>,<<XorZ>>] loop:<<HeaderZ:B\d+>> 212## CHECK-DAG: <<XorZ>> Xor [<<PhiZ2>>,<<Cst1>>] loop:<<HeaderZ>> 213## CHECK-DAG: <<CondZ:z\d+>> Equal [<<XorZ>>,<<Cst0>>] loop:<<HeaderZ>> 214## CHECK-DAG: If [<<CondZ>>] loop:<<HeaderZ>> 215# 216## CHECK-DAG: <<Add5>> Add [<<PhiX>>,<<Cst5>>] loop:<<HeaderY>> 217## CHECK-DAG: <<Add7>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>> 218## CHECK-DAG: Return [<<PhiX>>] loop:none 219 220## CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination$after_inlining (after) 221## CHECK-DAG: <<ArgX:i\d+>> ParameterValue 222## CHECK-DAG: <<ArgY:z\d+>> ParameterValue 223## CHECK-DAG: <<ArgZ:z\d+>> ParameterValue 224## CHECK-DAG: <<Cst0:i\d+>> IntConstant 0 225## CHECK-DAG: <<Cst1:i\d+>> IntConstant 1 226## CHECK-DAG: <<Cst7:i\d+>> IntConstant 7 227# 228## CHECK-DAG: <<PhiX:i\d+>> Phi [<<ArgX>>,<<Add7:i\d+>>] loop:<<HeaderY:B\d+>> 229## CHECK-DAG: If [<<ArgY>>] loop:<<HeaderY>> 230## CHECK-DAG: <<Add7>> Add [<<PhiX>>,<<Cst7>>] loop:<<HeaderY>> 231# 232# ### Inner loop ### 233## CHECK-DAG: <<PhiZ:i\d+>> Phi [<<ArgZ>>,<<XorZ:i\d+>>] loop:<<HeaderZ:B\d+>> 234## CHECK-DAG: <<XorZ>> Xor [<<PhiZ>>,<<Cst1>>] loop:<<HeaderZ>> 235## CHECK-DAG: <<CondZ:z\d+>> Equal [<<XorZ>>,<<Cst0>>] loop:<<HeaderZ>> 236## CHECK-DAG: If [<<CondZ>>] loop:<<HeaderZ>> 237# 238## CHECK-DAG: Return [<<PhiX>>] loop:none 239 240.method public static testInnerLoop(IZZ)I 241 .registers 4 242 243 # p0 = int X 244 # p1 = boolean Y 245 # p2 = boolean Z 246 # v0 = true 247 248 invoke-static {}, LTestCase;->$inline$True()Z 249 move-result v0 250 251 :loop_start 252 if-eqz p1, :loop_body # cannot be determined statically 253 254 # Inner loop which will end up outside its parent 255 :inner_loop_start 256 xor-int/lit8 p2, p2, 1 257 if-eqz p2, :inner_loop_start 258 259 if-nez v0, :loop_end # will always take the branch 260 261 # Dead block 262 add-int/lit8 p0, p0, 5 263 goto :loop_start 264 265 # Live block 266 :loop_body 267 add-int/lit8 p0, p0, 7 268 goto :loop_start 269 270 :loop_end 271 return p0 272.end method 273