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