Home | History | Annotate | Download | only in smali
      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