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