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