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