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 LSsaBuilder; 16 17 .super Ljava/lang/Object; 18 19 # Tests that catch blocks with both normal and exceptional predecessors are 20 # split in two. 21 22 ## CHECK-START: int SsaBuilder.testSimplifyCatchBlock(int, int, int) builder (after) 23 24 ## CHECK: name "B1" 25 ## CHECK-NEXT: from_bci 26 ## CHECK-NEXT: to_bci 27 ## CHECK-NEXT: predecessors 28 ## CHECK-NEXT: successors "<<BAdd:B\d+>>" 29 30 ## CHECK: name "<<BAdd>>" 31 ## CHECK-NEXT: from_bci 32 ## CHECK-NEXT: to_bci 33 ## CHECK-NEXT: predecessors "B1" "<<BCatch:B\d+>>" 34 ## CHECK-NEXT: successors 35 ## CHECK-NEXT: xhandlers 36 ## CHECK-NOT: end_block 37 ## CHECK: Add 38 39 ## CHECK: name "<<BCatch>>" 40 ## CHECK-NEXT: from_bci 41 ## CHECK-NEXT: to_bci 42 ## CHECK-NEXT: predecessors 43 ## CHECK-NEXT: successors "<<BAdd>>" 44 ## CHECK-NEXT: xhandlers 45 ## CHECK-NEXT: flags "catch_block" 46 47 .method public static testSimplifyCatchBlock(III)I 48 .registers 4 49 # Avoid entry block be a pre header, which leads to 50 # the cfg simplifier to add a synthesized block. 51 goto :catch_all 52 53 :catch_all 54 add-int/2addr p0, p1 55 56 :try_start 57 div-int/2addr p0, p2 58 :try_end 59 .catchall {:try_start .. :try_end} :catch_all 60 61 return p0 62 .end method 63 64 # Should be rejected because :catch_all is a loop header. 65 66 ## CHECK-START: int SsaBuilder.testCatchLoopHeader(int, int, int) builder (after, bad_state) 67 68 .method public static testCatchLoopHeader(III)I 69 .registers 4 70 71 :try_start_1 72 div-int/2addr p0, p1 73 return p0 74 :try_end_1 75 .catchall {:try_start_1 .. :try_end_1} :catch_all 76 77 :catch_all 78 :try_start_2 79 div-int/2addr p0, p2 80 return p0 81 :try_end_2 82 .catchall {:try_start_2 .. :try_end_2} :catch_all 83 84 .end method 85 86 # Tests creation of catch Phis. 87 88 ## CHECK-START: int SsaBuilder.testPhiCreation(int, int, int) builder (after) 89 ## CHECK-DAG: <<P0:i\d+>> ParameterValue 90 ## CHECK-DAG: <<P1:i\d+>> ParameterValue 91 ## CHECK-DAG: <<P2:i\d+>> ParameterValue 92 93 ## CHECK-DAG: <<DZC1:i\d+>> DivZeroCheck [<<P1>>] 94 ## CHECK-DAG: <<Div1:i\d+>> Div [<<P0>>,<<DZC1>>] 95 ## CHECK-DAG: <<DZC2:i\d+>> DivZeroCheck [<<P1>>] 96 ## CHECK-DAG: <<Div2:i\d+>> Div [<<Div1>>,<<DZC2>>] 97 ## CHECK-DAG: <<DZC3:i\d+>> DivZeroCheck [<<P1>>] 98 ## CHECK-DAG: <<Div3:i\d+>> Div [<<Div2>>,<<DZC3>>] 99 100 ## CHECK-DAG: <<Phi1:i\d+>> Phi [<<P0>>,<<P1>>,<<P2>>] reg:0 is_catch_phi:true 101 ## CHECK-DAG: <<Phi2:i\d+>> Phi [<<Div3>>,<<Phi1>>] reg:0 is_catch_phi:false 102 ## CHECK-DAG: Return [<<Phi2>>] 103 104 .method public static testPhiCreation(III)I 105 .registers 4 106 107 :try_start 108 move v0, p0 109 div-int/2addr p0, p1 110 111 move v0, p1 112 div-int/2addr p0, p1 113 114 move v0, p2 115 div-int/2addr p0, p1 116 117 move v0, p0 118 :try_end 119 .catchall {:try_start .. :try_end} :catch_all 120 121 :return 122 return v0 123 124 :catch_all 125 goto :return 126 .end method 127 128 # Tests that phi elimination does not remove catch phis where the value does 129 # not dominate the phi. 130 131 ## CHECK-START: int SsaBuilder.testPhiElimination_Domination(int, int) builder (after) 132 ## CHECK-DAG: <<P0:i\d+>> ParameterValue 133 ## CHECK-DAG: <<P1:i\d+>> ParameterValue 134 ## CHECK-DAG: <<Cst5:i\d+>> IntConstant 5 135 ## CHECK-DAG: <<Cst7:i\d+>> IntConstant 7 136 137 ## CHECK-DAG: <<Add1:i\d+>> Add [<<Cst7>>,<<Cst7>>] 138 ## CHECK-DAG: <<DZC:i\d+>> DivZeroCheck [<<P1>>] 139 ## CHECK-DAG: <<Div:i\d+>> Div [<<P0>>,<<DZC>>] 140 141 ## CHECK-DAG: <<Phi1:i\d+>> Phi [<<Add1>>] reg:1 is_catch_phi:true 142 ## CHECK-DAG: <<Add2:i\d+>> Add [<<Cst5>>,<<Phi1>>] 143 144 ## CHECK-DAG: <<Phi2:i\d+>> Phi [<<Cst5>>,<<Add2>>] reg:0 is_catch_phi:false 145 ## CHECK-DAG: Return [<<Phi2>>] 146 147 .method public static testPhiElimination_Domination(II)I 148 .registers 4 149 150 :try_start 151 # The constant in entry block will dominate the vreg 0 catch phi. 152 const v0, 5 153 154 # Insert addition so that the value of vreg 1 does not dominate the phi. 155 const v1, 7 156 add-int/2addr v1, v1 157 158 div-int/2addr p0, p1 159 :try_end 160 .catchall {:try_start .. :try_end} :catch_all 161 162 :return 163 return v0 164 165 :catch_all 166 add-int/2addr v0, v1 167 goto :return 168 .end method 169 170 # Tests that phi elimination loops until no more phis can be removed. 171 172 ## CHECK-START: int SsaBuilder.testPhiElimination_Dependencies(int, int, int) builder (after) 173 ## CHECK-NOT: Phi 174 175 .method public static testPhiElimination_Dependencies(III)I 176 .registers 4 177 178 # This constant reaches Return via the normal control-flow path and both 179 # exceptional paths. Since v0 is never changed, there should be no phis. 180 const v0, 5 181 182 :try_start 183 div-int/2addr p0, p1 184 div-int/2addr p0, p2 185 :try_end 186 .catch Ljava/lang/ArithmeticException; {:try_start .. :try_end} :catch_arith 187 .catchall {:try_start .. :try_end} :catch_all 188 189 :return 190 # Phi [v0, CatchPhi1, CatchPhi2] 191 return v0 192 193 :catch_arith 194 # CatchPhi1 [v0, v0] 195 goto :return 196 197 :catch_all 198 # CatchPhi2 [v0, v0] 199 goto :return 200 .end method 201 202 # Tests that dead catch blocks are removed. 203 204 ## CHECK-START: int SsaBuilder.testDeadCatchBlock(int, int, int) builder (after) 205 ## CHECK-DAG: <<P0:i\d+>> ParameterValue 206 ## CHECK-DAG: <<P1:i\d+>> ParameterValue 207 ## CHECK-DAG: <<P2:i\d+>> ParameterValue 208 ## CHECK-DAG: <<Add1:i\d+>> Add [<<P0>>,<<P1>>] 209 ## CHECK-DAG: <<Add2:i\d+>> Add [<<Add1>>,<<P2>>] 210 ## CHECK-DAG: Return [<<Add2>>] 211 212 ## CHECK-START: int SsaBuilder.testDeadCatchBlock(int, int, int) builder (after) 213 ## CHECK-NOT: flags "catch_block" 214 ## CHECK-NOT: Mul 215 216 .method public static testDeadCatchBlock(III)I 217 .registers 4 218 219 :try_start 220 add-int/2addr p0, p1 221 add-int/2addr p0, p2 222 move v0, p0 223 :try_end 224 .catchall {:try_start .. :try_end} :catch_all 225 226 :return 227 return v0 228 229 :catch_all 230 mul-int/2addr v1, v1 231 goto :return 232 .end method 233