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 LArrayGet;
     16 .super Ljava/lang/Object;
     17 
     18 
     19 # Test phi with fixed-type ArrayGet as an input and a matching second input.
     20 # The phi should be typed accordingly.
     21 
     22 ## CHECK-START: void ArrayGet.matchingFixedType(float[], float) builder (after)
     23 ## CHECK-NOT: Phi
     24 
     25 ## CHECK-START-DEBUGGABLE: void ArrayGet.matchingFixedType(float[], float) builder (after)
     26 ## CHECK-DAG:  <<Arg1:f\d+>> ParameterValue
     27 ## CHECK-DAG:  <<Aget:f\d+>> ArrayGet
     28 ## CHECK-DAG:  {{f\d+}}      Phi [<<Aget>>,<<Arg1>>] reg:0
     29 .method public static matchingFixedType([FF)V
     30   .registers 8
     31 
     32   const v0, 0x0
     33   const v1, 0x1
     34 
     35   aget v0, p0, v0       # read value
     36   add-float v2, v0, v1  # float use fixes type
     37 
     38   float-to-int v2, p1
     39   if-eqz v2, :after
     40   move v0, p1
     41   :after
     42   # v0 = Phi [ArrayGet, Arg1] => float
     43 
     44   invoke-static {}, Ljava/lang/System;->nanoTime()J  # create an env use
     45   return-void
     46 .end method
     47 
     48 
     49 # Test phi with fixed-type ArrayGet as an input and a conflicting second input.
     50 # The phi should be eliminated due to the conflict.
     51 
     52 ## CHECK-START: void ArrayGet.conflictingFixedType(float[], int) builder (after)
     53 ## CHECK-NOT: Phi
     54 
     55 ## CHECK-START-DEBUGGABLE: void ArrayGet.conflictingFixedType(float[], int) builder (after)
     56 ## CHECK-NOT: Phi
     57 .method public static conflictingFixedType([FI)V
     58   .registers 8
     59 
     60   const v0, 0x0
     61   const v1, 0x1
     62 
     63   aget v0, p0, v0       # read value
     64   add-float v2, v0, v1  # float use fixes type
     65 
     66   if-eqz p1, :after
     67   move v0, p1
     68   :after
     69   # v0 = Phi [ArrayGet, Arg1] => conflict
     70 
     71   invoke-static {}, Ljava/lang/System;->nanoTime()J  # create an env use
     72   return-void
     73 .end method
     74 
     75 
     76 # Same test as the one above, only this time tests that type of ArrayGet is not
     77 # changed.
     78 
     79 ## CHECK-START: void ArrayGet.conflictingFixedType2(int[], float) builder (after)
     80 ## CHECK-NOT: Phi
     81 
     82 ## CHECK-START-DEBUGGABLE: void ArrayGet.conflictingFixedType2(int[], float) builder (after)
     83 ## CHECK-NOT: Phi
     84 
     85 ## CHECK-START-DEBUGGABLE: void ArrayGet.conflictingFixedType2(int[], float) builder (after)
     86 ## CHECK:     {{i\d+}} ArrayGet
     87 .method public static conflictingFixedType2([IF)V
     88   .registers 8
     89 
     90   const v0, 0x0
     91   const v1, 0x1
     92 
     93   aget v0, p0, v0       # read value
     94   add-int v2, v0, v1    # int use fixes type
     95 
     96   float-to-int v2, p1
     97   if-eqz v2, :after
     98   move v0, p1
     99   :after
    100   # v0 = Phi [ArrayGet, Arg1] => conflict
    101 
    102   invoke-static {}, Ljava/lang/System;->nanoTime()J  # create an env use
    103   return-void
    104 .end method
    105 
    106 
    107 # Test phi with free-type ArrayGet as an input and a matching second input.
    108 # The phi should be typed accordingly.
    109 
    110 ## CHECK-START: void ArrayGet.matchingFreeType(float[], float) builder (after)
    111 ## CHECK-NOT: Phi
    112 
    113 ## CHECK-START-DEBUGGABLE: void ArrayGet.matchingFreeType(float[], float) builder (after)
    114 ## CHECK-DAG:  <<Arg1:f\d+>> ParameterValue
    115 ## CHECK-DAG:  <<Aget:f\d+>> ArrayGet
    116 ## CHECK-DAG:                ArraySet [{{l\d+}},{{i\d+}},<<Aget>>]
    117 ## CHECK-DAG:  {{f\d+}}      Phi [<<Aget>>,<<Arg1>>] reg:0
    118 .method public static matchingFreeType([FF)V
    119   .registers 8
    120 
    121   const v0, 0x0
    122   const v1, 0x1
    123 
    124   aget v0, p0, v0       # read value, should be float but has no typed use
    125   aput v0, p0, v1       # aput does not disambiguate the type
    126 
    127   float-to-int v2, p1
    128   if-eqz v2, :after
    129   move v0, p1
    130   :after
    131   # v0 = Phi [ArrayGet, Arg1] => float
    132 
    133   invoke-static {}, Ljava/lang/System;->nanoTime()J  # create an env use
    134   return-void
    135 .end method
    136 
    137 
    138 # Test phi with free-type ArrayGet as an input and a conflicting second input.
    139 # The phi will be kept and typed according to the second input despite the
    140 # conflict.
    141 
    142 ## CHECK-START: void ArrayGet.conflictingFreeType(int[], float) builder (after)
    143 ## CHECK-NOT: Phi
    144 
    145 ## CHECK-START-DEBUGGABLE: void ArrayGet.conflictingFreeType(int[], float) builder (after)
    146 ## CHECK-NOT: Phi
    147 
    148 .method public static conflictingFreeType([IF)V
    149   .registers 8
    150 
    151   const v0, 0x0
    152   const v1, 0x1
    153 
    154   aget v0, p0, v0       # read value, should be int but has no typed use
    155   aput v0, p0, v1
    156 
    157   float-to-int v2, p1
    158   if-eqz v2, :after
    159   move v0, p1
    160   :after
    161   # v0 = Phi [ArrayGet, Arg1] => float
    162 
    163   invoke-static {}, Ljava/lang/System;->nanoTime()J  # create an env use
    164   return-void
    165 .end method
    166 
    167 
    168 # Test that real use of ArrayGet is propagated through phis. The following test
    169 # case uses ArrayGet indirectly through two phis. It also creates an unused
    170 # conflicting phi which should not be preserved.
    171 
    172 ## CHECK-START: void ArrayGet.conflictingPhiUses(int[], float, boolean, boolean, boolean) builder (after)
    173 ## CHECK:         InvokeStaticOrDirect env:[[{{i\d+}},{{i\d+}},_,{{i\d+}},{{.*}}
    174 
    175 .method public static conflictingPhiUses([IFZZZ)V
    176   .registers 10
    177 
    178   const v0, 0x0
    179 
    180   # Create v1 = Phi [0x0, int ArrayGet]
    181   move v1, v0
    182   if-eqz p2, :else1
    183   aget v1, p0, v0
    184   :else1
    185 
    186   # Create v2 = Phi [v1, float]
    187   move v2, v1
    188   if-eqz p3, :else2
    189   move v2, p1
    190   :else2
    191 
    192   # Create v3 = Phi [v1, int]
    193   move v3, v1
    194   if-eqz p4, :else3
    195   move v3, v0
    196   :else3
    197 
    198   # Use v3 as int.
    199   add-int/lit8 v4, v3, 0x2a
    200 
    201   # Create env uses.
    202   invoke-static {}, Ljava/lang/System;->nanoTime()J
    203 
    204   return-void
    205 .end method
    206 
    207 # Test that the right ArrayGet equivalent is always selected. The following test
    208 # case uses ArrayGet as float through one phi and as an indeterminate type through
    209 # another. The situation needs to be resolved so that only one instruction
    210 # remains.
    211 
    212 ## CHECK-START: void ArrayGet.typedVsUntypedPhiUse(float[], float, boolean, boolean) builder (after)
    213 ## CHECK:         {{f\d+}} ArrayGet
    214 
    215 ## CHECK-START: void ArrayGet.typedVsUntypedPhiUse(float[], float, boolean, boolean) builder (after)
    216 ## CHECK-NOT:     {{i\d+}} ArrayGet
    217 
    218 .method public static typedVsUntypedPhiUse([FFZZ)V
    219   .registers 10
    220 
    221   const v0, 0x0
    222 
    223   # v1 = float ArrayGet
    224   aget v1, p0, v0
    225 
    226   # Create v2 = Phi [v1, 0.0f]
    227   move v2, v1
    228   if-eqz p2, :else1
    229   move v2, v0
    230   :else1
    231 
    232   # Use v2 as float
    233   cmpl-float v2, v2, p1
    234 
    235   # Create v3 = Phi [v1, 0.0f]
    236   move v3, v1
    237   if-eqz p3, :else2
    238   move v3, v0
    239   :else2
    240 
    241   # Use v3 without a determinate type.
    242   aput v3, p0, v0
    243 
    244   return-void
    245 .end method
    246