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_final (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_header:[[HeaderY:B\d+]] 33 # CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] 34 # CHECK-DAG: If [ [[Cst1]] ] loop_header:[[HeaderY]] 35 # CHECK-DAG: [[Add5]] Add [ [[PhiX]] [[Cst5]] ] loop_header:[[HeaderY]] 36 # CHECK-DAG: [[Add7]] Add [ [[PhiX]] [[Cst7]] ] loop_header:[[HeaderY]] 37 # CHECK-DAG: Return [ [[PhiX]] ] loop_header:null 38 39 # CHECK-START: int TestCase.testSingleExit(int, boolean) dead_code_elimination_final (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_header:[[HeaderY:B\d+]] 44 # CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] 45 # CHECK-DAG: [[AddX]] Add [ [[PhiX]] [[Cst7]] ] loop_header:[[HeaderY]] 46 # CHECK-DAG: Return [ [[PhiX]] ] loop_header:null 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_final (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_header:[[HeaderY:B\d+]] 84 # CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] 85 # CHECK-DAG: If [ [[ArgZ]] ] loop_header:[[HeaderY]] 86 # CHECK-DAG: If [ [[Cst1]] ] loop_header:[[HeaderY]] 87 # CHECK-DAG: [[Add5]] Add [ [[PhiX]] [[Cst5]] ] loop_header:[[HeaderY]] 88 # CHECK-DAG: [[Add7]] Add [ [[PhiX]] [[Cst7]] ] loop_header:[[HeaderY]] 89 # CHECK-DAG: Return [ [[PhiX]] ] loop_header:null 90 91 # CHECK-START: int TestCase.testMultipleExits(int, boolean, boolean) dead_code_elimination_final (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_header:[[HeaderY:B\d+]] 97 # CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] 98 # CHECK-DAG: [[Add7]] Add [ [[PhiX]] [[Cst7]] ] loop_header:[[HeaderY]] 99 # CHECK-DAG: If [ [[ArgZ]] ] loop_header:null 100 # CHECK-DAG: Return [ [[PhiX]] ] loop_header:null 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_final (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: [[Cst9:i\d+]] IntConstant 9 140 # CHECK-DAG: [[PhiX1:i\d+]] Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]] 141 # CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] 142 # CHECK-DAG: If [ [[ArgZ]] ] loop_header:[[HeaderY]] 143 # CHECK-DAG: [[Mul9:i\d+]] Mul [ [[PhiX1]] [[Cst9]] ] loop_header:[[HeaderY]] 144 # CHECK-DAG: [[PhiX2:i\d+]] Phi [ [[PhiX1]] [[Mul9]] ] loop_header:[[HeaderY]] 145 # CHECK-DAG: If [ [[Cst1]] ] loop_header:[[HeaderY]] 146 # CHECK-DAG: [[Add5]] Add [ [[PhiX2]] [[Cst5]] ] loop_header:[[HeaderY]] 147 # CHECK-DAG: [[Add7]] Add [ [[PhiX1]] [[Cst7]] ] loop_header:[[HeaderY]] 148 # CHECK-DAG: Return [ [[PhiX2]] ] loop_header:null 149 150 # CHECK-START: int TestCase.testExitPredecessors(int, boolean, boolean) dead_code_elimination_final (after) 151 # CHECK-DAG: [[ArgX:i\d+]] ParameterValue 152 # CHECK-DAG: [[ArgY:z\d+]] ParameterValue 153 # CHECK-DAG: [[ArgZ:z\d+]] ParameterValue 154 # CHECK-DAG: [[Cst7:i\d+]] IntConstant 7 155 # CHECK-DAG: [[Cst9:i\d+]] IntConstant 9 156 # CHECK-DAG: [[PhiX1:i\d+]] Phi [ [[ArgX]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]] 157 # CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] 158 # CHECK-DAG: [[Add7]] Add [ [[PhiX1]] [[Cst7]] ] loop_header:[[HeaderY]] 159 # CHECK-DAG: If [ [[ArgZ]] ] loop_header:null 160 # CHECK-DAG: [[Mul9:i\d+]] Mul [ [[PhiX1]] [[Cst9]] ] loop_header:null 161 # CHECK-DAG: [[PhiX2:i\d+]] Phi [ [[PhiX1]] [[Mul9]] ] loop_header:null 162 # CHECK-DAG: Return [ [[PhiX2]] ] loop_header:null 163 164 .method public static testExitPredecessors(IZZ)I 165 .registers 4 166 167 # p0 = int X 168 # p1 = boolean Y 169 # p2 = boolean Z 170 # v0 = true 171 172 invoke-static {}, LTestCase;->$inline$True()Z 173 move-result v0 174 175 :loop_start 176 if-eqz p1, :loop_body # cannot be determined statically 177 178 # Additional logic which will end up outside the loop 179 if-eqz p2, :skip_if 180 mul-int/lit8 p0, p0, 9 181 :skip_if 182 183 if-nez v0, :loop_end # will always take the branch 184 185 # Dead block 186 add-int/lit8 p0, p0, 5 187 goto :loop_start 188 189 # Live block 190 :loop_body 191 add-int/lit8 p0, p0, 7 192 goto :loop_start 193 194 :loop_end 195 return p0 196 .end method 197 198 199 # CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination_final (before) 200 # CHECK-DAG: [[ArgX:i\d+]] ParameterValue 201 # CHECK-DAG: [[ArgY:z\d+]] ParameterValue 202 # CHECK-DAG: [[ArgZ:z\d+]] ParameterValue 203 # CHECK-DAG: [[Cst0:i\d+]] IntConstant 0 204 # CHECK-DAG: [[Cst1:i\d+]] IntConstant 1 205 # CHECK-DAG: [[Cst5:i\d+]] IntConstant 5 206 # CHECK-DAG: [[Cst7:i\d+]] IntConstant 7 207 # 208 # CHECK-DAG: [[PhiX:i\d+]] Phi [ [[ArgX]] [[Add5:i\d+]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]] 209 # CHECK-DAG: [[PhiZ1:i\d+]] Phi [ [[ArgZ]] [[XorZ:i\d+]] [[PhiZ1]] ] loop_header:[[HeaderY]] 210 # CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] 211 # 212 # ### Inner loop ### 213 # CHECK-DAG: [[PhiZ2:i\d+]] Phi [ [[PhiZ1]] [[XorZ]] ] loop_header:[[HeaderZ:B\d+]] 214 # CHECK-DAG: [[XorZ]] Xor [ [[PhiZ2]] [[Cst1]] ] loop_header:[[HeaderZ]] 215 # CHECK-DAG: [[CondZ:z\d+]] Equal [ [[XorZ]] [[Cst0]] ] loop_header:[[HeaderZ]] 216 # CHECK-DAG: If [ [[CondZ]] ] loop_header:[[HeaderZ]] 217 # 218 # CHECK-DAG: [[Add5]] Add [ [[PhiX]] [[Cst5]] ] loop_header:[[HeaderY]] 219 # CHECK-DAG: [[Add7]] Add [ [[PhiX]] [[Cst7]] ] loop_header:[[HeaderY]] 220 # CHECK-DAG: Return [ [[PhiX]] ] loop_header:null 221 222 # CHECK-START: int TestCase.testInnerLoop(int, boolean, boolean) dead_code_elimination_final (after) 223 # CHECK-DAG: [[ArgX:i\d+]] ParameterValue 224 # CHECK-DAG: [[ArgY:z\d+]] ParameterValue 225 # CHECK-DAG: [[ArgZ:z\d+]] ParameterValue 226 # CHECK-DAG: [[Cst0:i\d+]] IntConstant 0 227 # CHECK-DAG: [[Cst1:i\d+]] IntConstant 1 228 # CHECK-DAG: [[Cst7:i\d+]] IntConstant 7 229 # 230 # CHECK-DAG: [[PhiX:i\d+]] Phi [ [[ArgX]] [[Add7:i\d+]] ] loop_header:[[HeaderY:B\d+]] 231 # CHECK-DAG: [[PhiZ1:i\d+]] Phi [ [[ArgZ]] [[PhiZ1]] ] loop_header:[[HeaderY]] 232 # CHECK-DAG: If [ [[ArgY]] ] loop_header:[[HeaderY]] 233 # CHECK-DAG: [[Add7]] Add [ [[PhiX]] [[Cst7]] ] loop_header:[[HeaderY]] 234 # 235 # ### Inner loop ### 236 # CHECK-DAG: [[PhiZ2:i\d+]] Phi [ [[PhiZ1]] [[XorZ:i\d+]] ] loop_header:[[HeaderZ:B\d+]] 237 # CHECK-DAG: [[XorZ]] Xor [ [[PhiZ2]] [[Cst1]] ] loop_header:[[HeaderZ]] 238 # CHECK-DAG: [[CondZ:z\d+]] Equal [ [[XorZ]] [[Cst0]] ] loop_header:[[HeaderZ]] 239 # CHECK-DAG: If [ [[CondZ]] ] loop_header:[[HeaderZ]] 240 # 241 # CHECK-DAG: Return [ [[PhiX]] ] loop_header:null 242 243 .method public static testInnerLoop(IZZ)I 244 .registers 4 245 246 # p0 = int X 247 # p1 = boolean Y 248 # p2 = boolean Z 249 # v0 = true 250 251 invoke-static {}, LTestCase;->$inline$True()Z 252 move-result v0 253 254 :loop_start 255 if-eqz p1, :loop_body # cannot be determined statically 256 257 # Inner loop which will end up outside its parent 258 :inner_loop_start 259 xor-int/lit8 p2, p2, 1 260 if-eqz p2, :inner_loop_start 261 262 if-nez v0, :loop_end # will always take the branch 263 264 # Dead block 265 add-int/lit8 p0, p0, 5 266 goto :loop_start 267 268 # Live block 269 :loop_body 270 add-int/lit8 p0, p0, 7 271 goto :loop_start 272 273 :loop_end 274 return p0 275 .end method 276