Home | History | Annotate | Download | only in compiler
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "Dalvik.h"
     18 #include "Dataflow.h"
     19 #include "Loop.h"
     20 #include "libdex/DexOpcodes.h"
     21 
     22 /*
     23  * Main table containing data flow attributes for each bytecode. The
     24  * first kNumPackedOpcodes entries are for Dalvik bytecode
     25  * instructions, where extended opcode at the MIR level are appended
     26  * afterwards.
     27  *
     28  * TODO - many optimization flags are incomplete - they will only limit the
     29  * scope of optimizations but will not cause mis-optimizations.
     30  */
     31 int dvmCompilerDataFlowAttributes[kMirOpLast] = {
     32     // 00 OP_NOP
     33     DF_NOP,
     34 
     35     // 01 OP_MOVE vA, vB
     36     DF_DA | DF_UB | DF_IS_MOVE,
     37 
     38     // 02 OP_MOVE_FROM16 vAA, vBBBB
     39     DF_DA | DF_UB | DF_IS_MOVE,
     40 
     41     // 03 OP_MOVE_16 vAAAA, vBBBB
     42     DF_DA | DF_UB | DF_IS_MOVE,
     43 
     44     // 04 OP_MOVE_WIDE vA, vB
     45     DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
     46 
     47     // 05 OP_MOVE_WIDE_FROM16 vAA, vBBBB
     48     DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
     49 
     50     // 06 OP_MOVE_WIDE_16 vAAAA, vBBBB
     51     DF_DA_WIDE | DF_UB_WIDE | DF_IS_MOVE,
     52 
     53     // 07 OP_MOVE_OBJECT vA, vB
     54     DF_DA | DF_UB | DF_IS_MOVE,
     55 
     56     // 08 OP_MOVE_OBJECT_FROM16 vAA, vBBBB
     57     DF_DA | DF_UB | DF_IS_MOVE,
     58 
     59     // 09 OP_MOVE_OBJECT_16 vAAAA, vBBBB
     60     DF_DA | DF_UB | DF_IS_MOVE,
     61 
     62     // 0A OP_MOVE_RESULT vAA
     63     DF_DA,
     64 
     65     // 0B OP_MOVE_RESULT_WIDE vAA
     66     DF_DA_WIDE,
     67 
     68     // 0C OP_MOVE_RESULT_OBJECT vAA
     69     DF_DA,
     70 
     71     // 0D OP_MOVE_EXCEPTION vAA
     72     DF_DA,
     73 
     74     // 0E OP_RETURN_VOID
     75     DF_NOP,
     76 
     77     // 0F OP_RETURN vAA
     78     DF_UA,
     79 
     80     // 10 OP_RETURN_WIDE vAA
     81     DF_UA_WIDE,
     82 
     83     // 11 OP_RETURN_OBJECT vAA
     84     DF_UA,
     85 
     86     // 12 OP_CONST_4 vA, #+B
     87     DF_DA | DF_SETS_CONST,
     88 
     89     // 13 OP_CONST_16 vAA, #+BBBB
     90     DF_DA | DF_SETS_CONST,
     91 
     92     // 14 OP_CONST vAA, #+BBBBBBBB
     93     DF_DA | DF_SETS_CONST,
     94 
     95     // 15 OP_CONST_HIGH16 VAA, #+BBBB0000
     96     DF_DA | DF_SETS_CONST,
     97 
     98     // 16 OP_CONST_WIDE_16 vAA, #+BBBB
     99     DF_DA_WIDE | DF_SETS_CONST,
    100 
    101     // 17 OP_CONST_WIDE_32 vAA, #+BBBBBBBB
    102     DF_DA_WIDE | DF_SETS_CONST,
    103 
    104     // 18 OP_CONST_WIDE vAA, #+BBBBBBBBBBBBBBBB
    105     DF_DA_WIDE | DF_SETS_CONST,
    106 
    107     // 19 OP_CONST_WIDE_HIGH16 vAA, #+BBBB000000000000
    108     DF_DA_WIDE | DF_SETS_CONST,
    109 
    110     // 1A OP_CONST_STRING vAA, string@BBBB
    111     DF_DA,
    112 
    113     // 1B OP_CONST_STRING_JUMBO vAA, string@BBBBBBBB
    114     DF_DA,
    115 
    116     // 1C OP_CONST_CLASS vAA, type@BBBB
    117     DF_DA,
    118 
    119     // 1D OP_MONITOR_ENTER vAA
    120     DF_UA,
    121 
    122     // 1E OP_MONITOR_EXIT vAA
    123     DF_UA,
    124 
    125     // 1F OP_CHECK_CAST vAA, type@BBBB
    126     DF_UA,
    127 
    128     // 20 OP_INSTANCE_OF vA, vB, type@CCCC
    129     DF_DA | DF_UB,
    130 
    131     // 21 OP_ARRAY_LENGTH vA, vB
    132     DF_DA | DF_UB,
    133 
    134     // 22 OP_NEW_INSTANCE vAA, type@BBBB
    135     DF_DA,
    136 
    137     // 23 OP_NEW_ARRAY vA, vB, type@CCCC
    138     DF_DA | DF_UB,
    139 
    140     // 24 OP_FILLED_NEW_ARRAY {vD, vE, vF, vG, vA}
    141     DF_FORMAT_35C,
    142 
    143     // 25 OP_FILLED_NEW_ARRAY_RANGE {vCCCC .. vNNNN}, type@BBBB
    144     DF_FORMAT_3RC,
    145 
    146     // 26 OP_FILL_ARRAY_DATA vAA, +BBBBBBBB
    147     DF_UA,
    148 
    149     // 27 OP_THROW vAA
    150     DF_UA,
    151 
    152     // 28 OP_GOTO
    153     DF_NOP,
    154 
    155     // 29 OP_GOTO_16
    156     DF_NOP,
    157 
    158     // 2A OP_GOTO_32
    159     DF_NOP,
    160 
    161     // 2B OP_PACKED_SWITCH vAA, +BBBBBBBB
    162     DF_UA,
    163 
    164     // 2C OP_SPARSE_SWITCH vAA, +BBBBBBBB
    165     DF_UA,
    166 
    167     // 2D OP_CMPL_FLOAT vAA, vBB, vCC
    168     DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C,
    169 
    170     // 2E OP_CMPG_FLOAT vAA, vBB, vCC
    171     DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C,
    172 
    173     // 2F OP_CMPL_DOUBLE vAA, vBB, vCC
    174     DF_DA | DF_UB_WIDE | DF_UC_WIDE | DF_FP_B | DF_FP_C,
    175 
    176     // 30 OP_CMPG_DOUBLE vAA, vBB, vCC
    177     DF_DA | DF_UB_WIDE | DF_UC_WIDE | DF_FP_B | DF_FP_C,
    178 
    179     // 31 OP_CMP_LONG vAA, vBB, vCC
    180     DF_DA | DF_UB_WIDE | DF_UC_WIDE,
    181 
    182     // 32 OP_IF_EQ vA, vB, +CCCC
    183     DF_UA | DF_UB,
    184 
    185     // 33 OP_IF_NE vA, vB, +CCCC
    186     DF_UA | DF_UB,
    187 
    188     // 34 OP_IF_LT vA, vB, +CCCC
    189     DF_UA | DF_UB,
    190 
    191     // 35 OP_IF_GE vA, vB, +CCCC
    192     DF_UA | DF_UB,
    193 
    194     // 36 OP_IF_GT vA, vB, +CCCC
    195     DF_UA | DF_UB,
    196 
    197     // 37 OP_IF_LE vA, vB, +CCCC
    198     DF_UA | DF_UB,
    199 
    200 
    201     // 38 OP_IF_EQZ vAA, +BBBB
    202     DF_UA,
    203 
    204     // 39 OP_IF_NEZ vAA, +BBBB
    205     DF_UA,
    206 
    207     // 3A OP_IF_LTZ vAA, +BBBB
    208     DF_UA,
    209 
    210     // 3B OP_IF_GEZ vAA, +BBBB
    211     DF_UA,
    212 
    213     // 3C OP_IF_GTZ vAA, +BBBB
    214     DF_UA,
    215 
    216     // 3D OP_IF_LEZ vAA, +BBBB
    217     DF_UA,
    218 
    219     // 3E OP_UNUSED_3E
    220     DF_NOP,
    221 
    222     // 3F OP_UNUSED_3F
    223     DF_NOP,
    224 
    225     // 40 OP_UNUSED_40
    226     DF_NOP,
    227 
    228     // 41 OP_UNUSED_41
    229     DF_NOP,
    230 
    231     // 42 OP_UNUSED_42
    232     DF_NOP,
    233 
    234     // 43 OP_UNUSED_43
    235     DF_NOP,
    236 
    237     // 44 OP_AGET vAA, vBB, vCC
    238     DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
    239 
    240     // 45 OP_AGET_WIDE vAA, vBB, vCC
    241     DF_DA_WIDE | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
    242 
    243     // 46 OP_AGET_OBJECT vAA, vBB, vCC
    244     DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
    245 
    246     // 47 OP_AGET_BOOLEAN vAA, vBB, vCC
    247     DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
    248 
    249     // 48 OP_AGET_BYTE vAA, vBB, vCC
    250     DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
    251 
    252     // 49 OP_AGET_CHAR vAA, vBB, vCC
    253     DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
    254 
    255     // 4A OP_AGET_SHORT vAA, vBB, vCC
    256     DF_DA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_0 | DF_IS_GETTER,
    257 
    258     // 4B OP_APUT vAA, vBB, vCC
    259     DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
    260 
    261     // 4C OP_APUT_WIDE vAA, vBB, vCC
    262     DF_UA_WIDE | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_2 | DF_IS_SETTER,
    263 
    264     // 4D OP_APUT_OBJECT vAA, vBB, vCC
    265     DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
    266 
    267     // 4E OP_APUT_BOOLEAN vAA, vBB, vCC
    268     DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
    269 
    270     // 4F OP_APUT_BYTE vAA, vBB, vCC
    271     DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
    272 
    273     // 50 OP_APUT_CHAR vAA, vBB, vCC
    274     DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
    275 
    276     // 51 OP_APUT_SHORT vAA, vBB, vCC
    277     DF_UA | DF_UB | DF_UC | DF_NULL_N_RANGE_CHECK_1 | DF_IS_SETTER,
    278 
    279     // 52 OP_IGET vA, vB, field@CCCC
    280     DF_DA | DF_UB | DF_IS_GETTER,
    281 
    282     // 53 OP_IGET_WIDE vA, vB, field@CCCC
    283     DF_DA_WIDE | DF_UB | DF_IS_GETTER,
    284 
    285     // 54 OP_IGET_OBJECT vA, vB, field@CCCC
    286     DF_DA | DF_UB | DF_IS_GETTER,
    287 
    288     // 55 OP_IGET_BOOLEAN vA, vB, field@CCCC
    289     DF_DA | DF_UB | DF_IS_GETTER,
    290 
    291     // 56 OP_IGET_BYTE vA, vB, field@CCCC
    292     DF_DA | DF_UB | DF_IS_GETTER,
    293 
    294     // 57 OP_IGET_CHAR vA, vB, field@CCCC
    295     DF_DA | DF_UB | DF_IS_GETTER,
    296 
    297     // 58 OP_IGET_SHORT vA, vB, field@CCCC
    298     DF_DA | DF_UB | DF_IS_GETTER,
    299 
    300     // 59 OP_IPUT vA, vB, field@CCCC
    301     DF_UA | DF_UB | DF_IS_SETTER,
    302 
    303     // 5A OP_IPUT_WIDE vA, vB, field@CCCC
    304     DF_UA_WIDE | DF_UB | DF_IS_SETTER,
    305 
    306     // 5B OP_IPUT_OBJECT vA, vB, field@CCCC
    307     DF_UA | DF_UB | DF_IS_SETTER,
    308 
    309     // 5C OP_IPUT_BOOLEAN vA, vB, field@CCCC
    310     DF_UA | DF_UB | DF_IS_SETTER,
    311 
    312     // 5D OP_IPUT_BYTE vA, vB, field@CCCC
    313     DF_UA | DF_UB | DF_IS_SETTER,
    314 
    315     // 5E OP_IPUT_CHAR vA, vB, field@CCCC
    316     DF_UA | DF_UB | DF_IS_SETTER,
    317 
    318     // 5F OP_IPUT_SHORT vA, vB, field@CCCC
    319     DF_UA | DF_UB | DF_IS_SETTER,
    320 
    321     // 60 OP_SGET vAA, field@BBBB
    322     DF_DA | DF_IS_GETTER,
    323 
    324     // 61 OP_SGET_WIDE vAA, field@BBBB
    325     DF_DA_WIDE | DF_IS_GETTER,
    326 
    327     // 62 OP_SGET_OBJECT vAA, field@BBBB
    328     DF_DA | DF_IS_GETTER,
    329 
    330     // 63 OP_SGET_BOOLEAN vAA, field@BBBB
    331     DF_DA | DF_IS_GETTER,
    332 
    333     // 64 OP_SGET_BYTE vAA, field@BBBB
    334     DF_DA | DF_IS_GETTER,
    335 
    336     // 65 OP_SGET_CHAR vAA, field@BBBB
    337     DF_DA | DF_IS_GETTER,
    338 
    339     // 66 OP_SGET_SHORT vAA, field@BBBB
    340     DF_DA | DF_IS_GETTER,
    341 
    342     // 67 OP_SPUT vAA, field@BBBB
    343     DF_UA | DF_IS_SETTER,
    344 
    345     // 68 OP_SPUT_WIDE vAA, field@BBBB
    346     DF_UA_WIDE | DF_IS_SETTER,
    347 
    348     // 69 OP_SPUT_OBJECT vAA, field@BBBB
    349     DF_UA | DF_IS_SETTER,
    350 
    351     // 6A OP_SPUT_BOOLEAN vAA, field@BBBB
    352     DF_UA | DF_IS_SETTER,
    353 
    354     // 6B OP_SPUT_BYTE vAA, field@BBBB
    355     DF_UA | DF_IS_SETTER,
    356 
    357     // 6C OP_SPUT_CHAR vAA, field@BBBB
    358     DF_UA | DF_IS_SETTER,
    359 
    360     // 6D OP_SPUT_SHORT vAA, field@BBBB
    361     DF_UA | DF_IS_SETTER,
    362 
    363     // 6E OP_INVOKE_VIRTUAL {vD, vE, vF, vG, vA}
    364     DF_FORMAT_35C,
    365 
    366     // 6F OP_INVOKE_SUPER {vD, vE, vF, vG, vA}
    367     DF_FORMAT_35C,
    368 
    369     // 70 OP_INVOKE_DIRECT {vD, vE, vF, vG, vA}
    370     DF_FORMAT_35C,
    371 
    372     // 71 OP_INVOKE_STATIC {vD, vE, vF, vG, vA}
    373     DF_FORMAT_35C,
    374 
    375     // 72 OP_INVOKE_INTERFACE {vD, vE, vF, vG, vA}
    376     DF_FORMAT_35C,
    377 
    378     // 73 OP_UNUSED_73
    379     DF_NOP,
    380 
    381     // 74 OP_INVOKE_VIRTUAL_RANGE {vCCCC .. vNNNN}
    382     DF_FORMAT_3RC,
    383 
    384     // 75 OP_INVOKE_SUPER_RANGE {vCCCC .. vNNNN}
    385     DF_FORMAT_3RC,
    386 
    387     // 76 OP_INVOKE_DIRECT_RANGE {vCCCC .. vNNNN}
    388     DF_FORMAT_3RC,
    389 
    390     // 77 OP_INVOKE_STATIC_RANGE {vCCCC .. vNNNN}
    391     DF_FORMAT_3RC,
    392 
    393     // 78 OP_INVOKE_INTERFACE_RANGE {vCCCC .. vNNNN}
    394     DF_FORMAT_3RC,
    395 
    396     // 79 OP_UNUSED_79
    397     DF_NOP,
    398 
    399     // 7A OP_UNUSED_7A
    400     DF_NOP,
    401 
    402     // 7B OP_NEG_INT vA, vB
    403     DF_DA | DF_UB,
    404 
    405     // 7C OP_NOT_INT vA, vB
    406     DF_DA | DF_UB,
    407 
    408     // 7D OP_NEG_LONG vA, vB
    409     DF_DA_WIDE | DF_UB_WIDE,
    410 
    411     // 7E OP_NOT_LONG vA, vB
    412     DF_DA_WIDE | DF_UB_WIDE,
    413 
    414     // 7F OP_NEG_FLOAT vA, vB
    415     DF_DA | DF_UB | DF_FP_A | DF_FP_B,
    416 
    417     // 80 OP_NEG_DOUBLE vA, vB
    418     DF_DA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
    419 
    420     // 81 OP_INT_TO_LONG vA, vB
    421     DF_DA_WIDE | DF_UB,
    422 
    423     // 82 OP_INT_TO_FLOAT vA, vB
    424     DF_DA | DF_UB | DF_FP_A,
    425 
    426     // 83 OP_INT_TO_DOUBLE vA, vB
    427     DF_DA_WIDE | DF_UB | DF_FP_A,
    428 
    429     // 84 OP_LONG_TO_INT vA, vB
    430     DF_DA | DF_UB_WIDE,
    431 
    432     // 85 OP_LONG_TO_FLOAT vA, vB
    433     DF_DA | DF_UB_WIDE | DF_FP_A,
    434 
    435     // 86 OP_LONG_TO_DOUBLE vA, vB
    436     DF_DA_WIDE | DF_UB_WIDE | DF_FP_A,
    437 
    438     // 87 OP_FLOAT_TO_INT vA, vB
    439     DF_DA | DF_UB | DF_FP_B,
    440 
    441     // 88 OP_FLOAT_TO_LONG vA, vB
    442     DF_DA_WIDE | DF_UB | DF_FP_B,
    443 
    444     // 89 OP_FLOAT_TO_DOUBLE vA, vB
    445     DF_DA_WIDE | DF_UB | DF_FP_A | DF_FP_B,
    446 
    447     // 8A OP_DOUBLE_TO_INT vA, vB
    448     DF_DA | DF_UB_WIDE | DF_FP_B,
    449 
    450     // 8B OP_DOUBLE_TO_LONG vA, vB
    451     DF_DA_WIDE | DF_UB_WIDE | DF_FP_B,
    452 
    453     // 8C OP_DOUBLE_TO_FLOAT vA, vB
    454     DF_DA | DF_UB_WIDE | DF_FP_A | DF_FP_B,
    455 
    456     // 8D OP_INT_TO_BYTE vA, vB
    457     DF_DA | DF_UB,
    458 
    459     // 8E OP_INT_TO_CHAR vA, vB
    460     DF_DA | DF_UB,
    461 
    462     // 8F OP_INT_TO_SHORT vA, vB
    463     DF_DA | DF_UB,
    464 
    465     // 90 OP_ADD_INT vAA, vBB, vCC
    466     DF_DA | DF_UB | DF_UC | DF_IS_LINEAR,
    467 
    468     // 91 OP_SUB_INT vAA, vBB, vCC
    469     DF_DA | DF_UB | DF_UC | DF_IS_LINEAR,
    470 
    471     // 92 OP_MUL_INT vAA, vBB, vCC
    472     DF_DA | DF_UB | DF_UC,
    473 
    474     // 93 OP_DIV_INT vAA, vBB, vCC
    475     DF_DA | DF_UB | DF_UC,
    476 
    477     // 94 OP_REM_INT vAA, vBB, vCC
    478     DF_DA | DF_UB | DF_UC,
    479 
    480     // 95 OP_AND_INT vAA, vBB, vCC
    481     DF_DA | DF_UB | DF_UC,
    482 
    483     // 96 OP_OR_INT vAA, vBB, vCC
    484     DF_DA | DF_UB | DF_UC,
    485 
    486     // 97 OP_XOR_INT vAA, vBB, vCC
    487     DF_DA | DF_UB | DF_UC,
    488 
    489     // 98 OP_SHL_INT vAA, vBB, vCC
    490     DF_DA | DF_UB | DF_UC,
    491 
    492     // 99 OP_SHR_INT vAA, vBB, vCC
    493     DF_DA | DF_UB | DF_UC,
    494 
    495     // 9A OP_USHR_INT vAA, vBB, vCC
    496     DF_DA | DF_UB | DF_UC,
    497 
    498     // 9B OP_ADD_LONG vAA, vBB, vCC
    499     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
    500 
    501     // 9C OP_SUB_LONG vAA, vBB, vCC
    502     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
    503 
    504     // 9D OP_MUL_LONG vAA, vBB, vCC
    505     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
    506 
    507     // 9E OP_DIV_LONG vAA, vBB, vCC
    508     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
    509 
    510     // 9F OP_REM_LONG vAA, vBB, vCC
    511     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
    512 
    513     // A0 OP_AND_LONG vAA, vBB, vCC
    514     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
    515 
    516     // A1 OP_OR_LONG vAA, vBB, vCC
    517     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
    518 
    519     // A2 OP_XOR_LONG vAA, vBB, vCC
    520     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE,
    521 
    522     // A3 OP_SHL_LONG vAA, vBB, vCC
    523     DF_DA_WIDE | DF_UB_WIDE | DF_UC,
    524 
    525     // A4 OP_SHR_LONG vAA, vBB, vCC
    526     DF_DA_WIDE | DF_UB_WIDE | DF_UC,
    527 
    528     // A5 OP_USHR_LONG vAA, vBB, vCC
    529     DF_DA_WIDE | DF_UB_WIDE | DF_UC,
    530 
    531     // A6 OP_ADD_FLOAT vAA, vBB, vCC
    532     DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
    533 
    534     // A7 OP_SUB_FLOAT vAA, vBB, vCC
    535     DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
    536 
    537     // A8 OP_MUL_FLOAT vAA, vBB, vCC
    538     DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
    539 
    540     // A9 OP_DIV_FLOAT vAA, vBB, vCC
    541     DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
    542 
    543     // AA OP_REM_FLOAT vAA, vBB, vCC
    544     DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,
    545 
    546     // AB OP_ADD_DOUBLE vAA, vBB, vCC
    547     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
    548 
    549     // AC OP_SUB_DOUBLE vAA, vBB, vCC
    550     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
    551 
    552     // AD OP_MUL_DOUBLE vAA, vBB, vCC
    553     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
    554 
    555     // AE OP_DIV_DOUBLE vAA, vBB, vCC
    556     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
    557 
    558     // AF OP_REM_DOUBLE vAA, vBB, vCC
    559     DF_DA_WIDE | DF_UB_WIDE | DF_UC_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,
    560 
    561     // B0 OP_ADD_INT_2ADDR vA, vB
    562     DF_DA | DF_UA | DF_UB,
    563 
    564     // B1 OP_SUB_INT_2ADDR vA, vB
    565     DF_DA | DF_UA | DF_UB,
    566 
    567     // B2 OP_MUL_INT_2ADDR vA, vB
    568     DF_DA | DF_UA | DF_UB,
    569 
    570     // B3 OP_DIV_INT_2ADDR vA, vB
    571     DF_DA | DF_UA | DF_UB,
    572 
    573     // B4 OP_REM_INT_2ADDR vA, vB
    574     DF_DA | DF_UA | DF_UB,
    575 
    576     // B5 OP_AND_INT_2ADDR vA, vB
    577     DF_DA | DF_UA | DF_UB,
    578 
    579     // B6 OP_OR_INT_2ADDR vA, vB
    580     DF_DA | DF_UA | DF_UB,
    581 
    582     // B7 OP_XOR_INT_2ADDR vA, vB
    583     DF_DA | DF_UA | DF_UB,
    584 
    585     // B8 OP_SHL_INT_2ADDR vA, vB
    586     DF_DA | DF_UA | DF_UB,
    587 
    588     // B9 OP_SHR_INT_2ADDR vA, vB
    589     DF_DA | DF_UA | DF_UB,
    590 
    591     // BA OP_USHR_INT_2ADDR vA, vB
    592     DF_DA | DF_UA | DF_UB,
    593 
    594     // BB OP_ADD_LONG_2ADDR vA, vB
    595     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
    596 
    597     // BC OP_SUB_LONG_2ADDR vA, vB
    598     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
    599 
    600     // BD OP_MUL_LONG_2ADDR vA, vB
    601     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
    602 
    603     // BE OP_DIV_LONG_2ADDR vA, vB
    604     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
    605 
    606     // BF OP_REM_LONG_2ADDR vA, vB
    607     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
    608 
    609     // C0 OP_AND_LONG_2ADDR vA, vB
    610     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
    611 
    612     // C1 OP_OR_LONG_2ADDR vA, vB
    613     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
    614 
    615     // C2 OP_XOR_LONG_2ADDR vA, vB
    616     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE,
    617 
    618     // C3 OP_SHL_LONG_2ADDR vA, vB
    619     DF_DA_WIDE | DF_UA_WIDE | DF_UB,
    620 
    621     // C4 OP_SHR_LONG_2ADDR vA, vB
    622     DF_DA_WIDE | DF_UA_WIDE | DF_UB,
    623 
    624     // C5 OP_USHR_LONG_2ADDR vA, vB
    625     DF_DA_WIDE | DF_UA_WIDE | DF_UB,
    626 
    627     // C6 OP_ADD_FLOAT_2ADDR vA, vB
    628     DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
    629 
    630     // C7 OP_SUB_FLOAT_2ADDR vA, vB
    631     DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
    632 
    633     // C8 OP_MUL_FLOAT_2ADDR vA, vB
    634     DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
    635 
    636     // C9 OP_DIV_FLOAT_2ADDR vA, vB
    637     DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
    638 
    639     // CA OP_REM_FLOAT_2ADDR vA, vB
    640     DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,
    641 
    642     // CB OP_ADD_DOUBLE_2ADDR vA, vB
    643     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
    644 
    645     // CC OP_SUB_DOUBLE_2ADDR vA, vB
    646     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
    647 
    648     // CD OP_MUL_DOUBLE_2ADDR vA, vB
    649     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
    650 
    651     // CE OP_DIV_DOUBLE_2ADDR vA, vB
    652     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
    653 
    654     // CF OP_REM_DOUBLE_2ADDR vA, vB
    655     DF_DA_WIDE | DF_UA_WIDE | DF_UB_WIDE | DF_FP_A | DF_FP_B,
    656 
    657     // D0 OP_ADD_INT_LIT16 vA, vB, #+CCCC
    658     DF_DA | DF_UB,
    659 
    660     // D1 OP_RSUB_INT vA, vB, #+CCCC
    661     DF_DA | DF_UB,
    662 
    663     // D2 OP_MUL_INT_LIT16 vA, vB, #+CCCC
    664     DF_DA | DF_UB,
    665 
    666     // D3 OP_DIV_INT_LIT16 vA, vB, #+CCCC
    667     DF_DA | DF_UB,
    668 
    669     // D4 OP_REM_INT_LIT16 vA, vB, #+CCCC
    670     DF_DA | DF_UB,
    671 
    672     // D5 OP_AND_INT_LIT16 vA, vB, #+CCCC
    673     DF_DA | DF_UB,
    674 
    675     // D6 OP_OR_INT_LIT16 vA, vB, #+CCCC
    676     DF_DA | DF_UB,
    677 
    678     // D7 OP_XOR_INT_LIT16 vA, vB, #+CCCC
    679     DF_DA | DF_UB,
    680 
    681     // D8 OP_ADD_INT_LIT8 vAA, vBB, #+CC
    682     DF_DA | DF_UB | DF_IS_LINEAR,
    683 
    684     // D9 OP_RSUB_INT_LIT8 vAA, vBB, #+CC
    685     DF_DA | DF_UB,
    686 
    687     // DA OP_MUL_INT_LIT8 vAA, vBB, #+CC
    688     DF_DA | DF_UB,
    689 
    690     // DB OP_DIV_INT_LIT8 vAA, vBB, #+CC
    691     DF_DA | DF_UB,
    692 
    693     // DC OP_REM_INT_LIT8 vAA, vBB, #+CC
    694     DF_DA | DF_UB,
    695 
    696     // DD OP_AND_INT_LIT8 vAA, vBB, #+CC
    697     DF_DA | DF_UB,
    698 
    699     // DE OP_OR_INT_LIT8 vAA, vBB, #+CC
    700     DF_DA | DF_UB,
    701 
    702     // DF OP_XOR_INT_LIT8 vAA, vBB, #+CC
    703     DF_DA | DF_UB,
    704 
    705     // E0 OP_SHL_INT_LIT8 vAA, vBB, #+CC
    706     DF_DA | DF_UB,
    707 
    708     // E1 OP_SHR_INT_LIT8 vAA, vBB, #+CC
    709     DF_DA | DF_UB,
    710 
    711     // E2 OP_USHR_INT_LIT8 vAA, vBB, #+CC
    712     DF_DA | DF_UB,
    713 
    714     // E3 OP_IGET_VOLATILE
    715     DF_DA | DF_UB,
    716 
    717     // E4 OP_IPUT_VOLATILE
    718     DF_UA | DF_UB,
    719 
    720     // E5 OP_SGET_VOLATILE
    721     DF_DA,
    722 
    723     // E6 OP_SPUT_VOLATILE
    724     DF_UA,
    725 
    726     // E7 OP_IGET_OBJECT_VOLATILE
    727     DF_DA | DF_UB,
    728 
    729     // E8 OP_IGET_WIDE_VOLATILE
    730     DF_DA_WIDE | DF_UB,
    731 
    732     // E9 OP_IPUT_WIDE_VOLATILE
    733     DF_UA_WIDE | DF_UB,
    734 
    735     // EA OP_SGET_WIDE_VOLATILE
    736     DF_DA_WIDE,
    737 
    738     // EB OP_SPUT_WIDE_VOLATILE
    739     DF_UA_WIDE,
    740 
    741     // EC OP_BREAKPOINT
    742     DF_NOP,
    743 
    744     // ED OP_THROW_VERIFICATION_ERROR
    745     DF_NOP,
    746 
    747     // EE OP_EXECUTE_INLINE
    748     DF_FORMAT_35C,
    749 
    750     // EF OP_EXECUTE_INLINE_RANGE
    751     DF_FORMAT_3RC,
    752 
    753     // F0 OP_INVOKE_OBJECT_INIT_RANGE
    754     DF_NOP,
    755 
    756     // F1 OP_RETURN_VOID_BARRIER
    757     DF_NOP,
    758 
    759     // F2 OP_IGET_QUICK
    760     DF_DA | DF_UB | DF_IS_GETTER,
    761 
    762     // F3 OP_IGET_WIDE_QUICK
    763     DF_DA_WIDE | DF_UB | DF_IS_GETTER,
    764 
    765     // F4 OP_IGET_OBJECT_QUICK
    766     DF_DA | DF_UB | DF_IS_GETTER,
    767 
    768     // F5 OP_IPUT_QUICK
    769     DF_UA | DF_UB | DF_IS_SETTER,
    770 
    771     // F6 OP_IPUT_WIDE_QUICK
    772     DF_UA_WIDE | DF_UB | DF_IS_SETTER,
    773 
    774     // F7 OP_IPUT_OBJECT_QUICK
    775     DF_UA | DF_UB | DF_IS_SETTER,
    776 
    777     // F8 OP_INVOKE_VIRTUAL_QUICK
    778     DF_FORMAT_35C,
    779 
    780     // F9 OP_INVOKE_VIRTUAL_QUICK_RANGE
    781     DF_FORMAT_3RC,
    782 
    783     // FA OP_INVOKE_SUPER_QUICK
    784     DF_FORMAT_35C,
    785 
    786     // FB OP_INVOKE_SUPER_QUICK_RANGE
    787     DF_FORMAT_3RC,
    788 
    789     // FC OP_IPUT_OBJECT_VOLATILE
    790     DF_UA | DF_UB,
    791 
    792     // FD OP_SGET_OBJECT_VOLATILE
    793     DF_DA,
    794 
    795     // FE OP_SPUT_OBJECT_VOLATILE
    796     DF_UA,
    797 
    798     // FF OP_UNUSED_FF
    799     DF_NOP,
    800 
    801     // Beginning of extended MIR opcodes
    802     // 100 OP_MIR_PHI
    803     DF_PHI | DF_DA,
    804     /*
    805      * For extended MIR inserted at the MIR2LIR stage, it is okay to have
    806      * undefined values here.
    807      */
    808 };
    809 
    810 /* Return the Dalvik register/subscript pair of a given SSA register */
    811 int dvmConvertSSARegToDalvik(const CompilationUnit *cUnit, int ssaReg)
    812 {
    813       return GET_ELEM_N(cUnit->ssaToDalvikMap, int, ssaReg);
    814 }
    815 
    816 /*
    817  * Utility function to convert encoded SSA register value into Dalvik register
    818  * and subscript pair. Each SSA register can be used to index the
    819  * ssaToDalvikMap list to get the subscript[31..16]/dalvik_reg[15..0] mapping.
    820  */
    821 char *dvmCompilerGetDalvikDisassembly(const DecodedInstruction *insn,
    822                                       const char *note)
    823 {
    824     char buffer[256];
    825     Opcode opcode = insn->opcode;
    826     int dfAttributes = dvmCompilerDataFlowAttributes[opcode];
    827     int flags;
    828     char *ret;
    829 
    830     buffer[0] = 0;
    831     if ((int)opcode >= (int)kMirOpFirst) {
    832         if ((int)opcode == (int)kMirOpPhi) {
    833             strcpy(buffer, "PHI");
    834         }
    835         else {
    836             sprintf(buffer, "Opcode %#x", opcode);
    837         }
    838         flags = 0;
    839     } else {
    840         strcpy(buffer, dexGetOpcodeName(opcode));
    841         flags = dexGetFlagsFromOpcode(insn->opcode);
    842     }
    843 
    844     if (note)
    845         strcat(buffer, note);
    846 
    847     /* For branches, decode the instructions to print out the branch targets */
    848     if (flags & kInstrCanBranch) {
    849         InstructionFormat dalvikFormat = dexGetFormatFromOpcode(insn->opcode);
    850         int offset = 0;
    851         switch (dalvikFormat) {
    852             case kFmt21t:
    853                 snprintf(buffer + strlen(buffer), 256, " v%d,", insn->vA);
    854                 offset = (int) insn->vB;
    855                 break;
    856             case kFmt22t:
    857                 snprintf(buffer + strlen(buffer), 256, " v%d, v%d,",
    858                          insn->vA, insn->vB);
    859                 offset = (int) insn->vC;
    860                 break;
    861             case kFmt10t:
    862             case kFmt20t:
    863             case kFmt30t:
    864                 offset = (int) insn->vA;
    865                 break;
    866             default:
    867                 ALOGE("Unexpected branch format %d / opcode %#x", dalvikFormat,
    868                      opcode);
    869                 dvmAbort();
    870                 break;
    871         }
    872         snprintf(buffer + strlen(buffer), 256, " (%c%x)",
    873                  offset > 0 ? '+' : '-',
    874                  offset > 0 ? offset : -offset);
    875     } else if (dfAttributes & DF_FORMAT_35C) {
    876         unsigned int i;
    877         for (i = 0; i < insn->vA; i++) {
    878             if (i != 0) strcat(buffer, ",");
    879             snprintf(buffer + strlen(buffer), 256, " v%d", insn->arg[i]);
    880         }
    881     }
    882     else if (dfAttributes & DF_FORMAT_3RC) {
    883         snprintf(buffer + strlen(buffer), 256,
    884                  " v%d..v%d", insn->vC, insn->vC + insn->vA - 1);
    885     }
    886     else {
    887         if (dfAttributes & DF_A_IS_REG) {
    888             snprintf(buffer + strlen(buffer), 256, " v%d", insn->vA);
    889         }
    890         if (dfAttributes & DF_B_IS_REG) {
    891             snprintf(buffer + strlen(buffer), 256, ", v%d", insn->vB);
    892         }
    893         else if ((int)opcode < (int)kMirOpFirst) {
    894             snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn->vB);
    895         }
    896         if (dfAttributes & DF_C_IS_REG) {
    897             snprintf(buffer + strlen(buffer), 256, ", v%d", insn->vC);
    898         }
    899         else if ((int)opcode < (int)kMirOpFirst) {
    900             snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn->vC);
    901         }
    902     }
    903     int length = strlen(buffer) + 1;
    904     ret = (char *)dvmCompilerNew(length, false);
    905     memcpy(ret, buffer, length);
    906     return ret;
    907 }
    908 
    909 char *getSSAName(const CompilationUnit *cUnit, int ssaReg, char *name)
    910 {
    911     int ssa2DalvikValue = dvmConvertSSARegToDalvik(cUnit, ssaReg);
    912 
    913     sprintf(name, "v%d_%d",
    914             DECODE_REG(ssa2DalvikValue), DECODE_SUB(ssa2DalvikValue));
    915     return name;
    916 }
    917 
    918 /*
    919  * Dalvik instruction disassembler with optional SSA printing.
    920  */
    921 char *dvmCompilerFullDisassembler(const CompilationUnit *cUnit,
    922                                   const MIR *mir)
    923 {
    924     char buffer[256];
    925     char operand0[256], operand1[256];
    926     const DecodedInstruction *insn = &mir->dalvikInsn;
    927     int opcode = insn->opcode;
    928     int dfAttributes = dvmCompilerDataFlowAttributes[opcode];
    929     char *ret;
    930     int length;
    931     OpcodeFlags flags;
    932 
    933     buffer[0] = 0;
    934     if (opcode >= kMirOpFirst) {
    935         if (opcode == kMirOpPhi) {
    936             snprintf(buffer, 256, "PHI %s = (%s",
    937                      getSSAName(cUnit, mir->ssaRep->defs[0], operand0),
    938                      getSSAName(cUnit, mir->ssaRep->uses[0], operand1));
    939             int i;
    940             for (i = 1; i < mir->ssaRep->numUses; i++) {
    941                 snprintf(buffer + strlen(buffer), 256, ", %s",
    942                          getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
    943             }
    944             snprintf(buffer + strlen(buffer), 256, ")");
    945         }
    946         else {
    947             sprintf(buffer, "Opcode %#x", opcode);
    948         }
    949         goto done;
    950     } else {
    951         strcpy(buffer, dexGetOpcodeName((Opcode)opcode));
    952     }
    953 
    954     flags = dexGetFlagsFromOpcode((Opcode)opcode);
    955     /* For branches, decode the instructions to print out the branch targets */
    956     if (flags & kInstrCanBranch) {
    957         InstructionFormat dalvikFormat = dexGetFormatFromOpcode(insn->opcode);
    958         int delta = 0;
    959         switch (dalvikFormat) {
    960             case kFmt21t:
    961                 snprintf(buffer + strlen(buffer), 256, " %s, ",
    962                          getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
    963                 delta = (int) insn->vB;
    964                 break;
    965             case kFmt22t:
    966                 snprintf(buffer + strlen(buffer), 256, " %s, %s, ",
    967                          getSSAName(cUnit, mir->ssaRep->uses[0], operand0),
    968                          getSSAName(cUnit, mir->ssaRep->uses[1], operand1));
    969                 delta = (int) insn->vC;
    970                 break;
    971             case kFmt10t:
    972             case kFmt20t:
    973             case kFmt30t:
    974                 delta = (int) insn->vA;
    975                 break;
    976             default:
    977                 ALOGE("Unexpected branch format: %d", dalvikFormat);
    978                 dvmAbort();
    979                 break;
    980         }
    981         snprintf(buffer + strlen(buffer), 256, " %04x",
    982                  mir->offset + delta);
    983     } else if (dfAttributes & (DF_FORMAT_35C | DF_FORMAT_3RC)) {
    984         unsigned int i;
    985         for (i = 0; i < insn->vA; i++) {
    986             if (i != 0) strcat(buffer, ",");
    987             snprintf(buffer + strlen(buffer), 256, " %s",
    988                      getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
    989         }
    990     } else {
    991         int udIdx;
    992         if (mir->ssaRep->numDefs) {
    993 
    994             for (udIdx = 0; udIdx < mir->ssaRep->numDefs; udIdx++) {
    995                 snprintf(buffer + strlen(buffer), 256, " %s",
    996                          getSSAName(cUnit, mir->ssaRep->defs[udIdx], operand0));
    997             }
    998             strcat(buffer, ",");
    999         }
   1000         if (mir->ssaRep->numUses) {
   1001             /* No leading ',' for the first use */
   1002             snprintf(buffer + strlen(buffer), 256, " %s",
   1003                      getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
   1004             for (udIdx = 1; udIdx < mir->ssaRep->numUses; udIdx++) {
   1005                 snprintf(buffer + strlen(buffer), 256, ", %s",
   1006                          getSSAName(cUnit, mir->ssaRep->uses[udIdx], operand0));
   1007             }
   1008         }
   1009         if (opcode < kMirOpFirst) {
   1010             InstructionFormat dalvikFormat =
   1011                 dexGetFormatFromOpcode((Opcode)opcode);
   1012             switch (dalvikFormat) {
   1013                 case kFmt11n:        // op vA, #+B
   1014                 case kFmt21s:        // op vAA, #+BBBB
   1015                 case kFmt21h:        // op vAA, #+BBBB00000[00000000]
   1016                 case kFmt31i:        // op vAA, #+BBBBBBBB
   1017                 case kFmt51l:        // op vAA, #+BBBBBBBBBBBBBBBB
   1018                     snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vB);
   1019                     break;
   1020                 case kFmt21c:        // op vAA, thing@BBBB
   1021                 case kFmt31c:        // op vAA, thing@BBBBBBBB
   1022                     snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vB);
   1023                     break;
   1024                 case kFmt22b:        // op vAA, vBB, #+CC
   1025                 case kFmt22s:        // op vA, vB, #+CCCC
   1026                     snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vC);
   1027                     break;
   1028                 case kFmt22c:        // op vA, vB, thing@CCCC
   1029                 case kFmt22cs:       // [opt] op vA, vB, field offset CCCC
   1030                     snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vC);
   1031                     break;
   1032                     /* No need for special printing */
   1033                 default:
   1034                     break;
   1035             }
   1036         }
   1037     }
   1038 
   1039 done:
   1040     length = strlen(buffer) + 1;
   1041     ret = (char *) dvmCompilerNew(length, false);
   1042     memcpy(ret, buffer, length);
   1043     return ret;
   1044 }
   1045 
   1046 /*
   1047  * Utility function to convert encoded SSA register value into Dalvik register
   1048  * and subscript pair. Each SSA register can be used to index the
   1049  * ssaToDalvikMap list to get the subscript[31..16]/dalvik_reg[15..0] mapping.
   1050  */
   1051 char *dvmCompilerGetSSAString(CompilationUnit *cUnit, SSARepresentation *ssaRep)
   1052 {
   1053     char buffer[256];
   1054     char *ret;
   1055     int i;
   1056 
   1057     buffer[0] = 0;
   1058     for (i = 0; i < ssaRep->numDefs; i++) {
   1059         int ssa2DalvikValue = dvmConvertSSARegToDalvik(cUnit, ssaRep->defs[i]);
   1060 
   1061         sprintf(buffer + strlen(buffer), "s%d(v%d_%d) ",
   1062                 ssaRep->defs[i], DECODE_REG(ssa2DalvikValue),
   1063                 DECODE_SUB(ssa2DalvikValue));
   1064     }
   1065 
   1066     if (ssaRep->numDefs) {
   1067         strcat(buffer, "<- ");
   1068     }
   1069 
   1070     for (i = 0; i < ssaRep->numUses; i++) {
   1071         int ssa2DalvikValue = dvmConvertSSARegToDalvik(cUnit, ssaRep->uses[i]);
   1072         int len = strlen(buffer);
   1073 
   1074         if (snprintf(buffer + len, 250 - len, "s%d(v%d_%d) ",
   1075                      ssaRep->uses[i], DECODE_REG(ssa2DalvikValue),
   1076                      DECODE_SUB(ssa2DalvikValue)) >= (250 - len)) {
   1077             strcat(buffer, "...");
   1078             break;
   1079         }
   1080     }
   1081 
   1082     int length = strlen(buffer) + 1;
   1083     ret = (char *)dvmCompilerNew(length, false);
   1084     memcpy(ret, buffer, length);
   1085     return ret;
   1086 }
   1087 
   1088 /* Any register that is used before being defined is considered live-in */
   1089 static inline void handleLiveInUse(BitVector *useV, BitVector *defV,
   1090                                    BitVector *liveInV, int dalvikRegId)
   1091 {
   1092     dvmCompilerSetBit(useV, dalvikRegId);
   1093     if (!dvmIsBitSet(defV, dalvikRegId)) {
   1094         dvmCompilerSetBit(liveInV, dalvikRegId);
   1095     }
   1096 }
   1097 
   1098 /* Mark a reg as being defined */
   1099 static inline void handleDef(BitVector *defV, int dalvikRegId)
   1100 {
   1101     dvmCompilerSetBit(defV, dalvikRegId);
   1102 }
   1103 
   1104 /*
   1105  * Find out live-in variables for natural loops. Variables that are live-in in
   1106  * the main loop body are considered to be defined in the entry block.
   1107  */
   1108 bool dvmCompilerFindLocalLiveIn(CompilationUnit *cUnit, BasicBlock *bb)
   1109 {
   1110     MIR *mir;
   1111     BitVector *useV, *defV, *liveInV;
   1112 
   1113     if (bb->dataFlowInfo == NULL) return false;
   1114 
   1115     useV = bb->dataFlowInfo->useV =
   1116         dvmCompilerAllocBitVector(cUnit->numDalvikRegisters, false);
   1117     defV = bb->dataFlowInfo->defV =
   1118         dvmCompilerAllocBitVector(cUnit->numDalvikRegisters, false);
   1119     liveInV = bb->dataFlowInfo->liveInV =
   1120         dvmCompilerAllocBitVector(cUnit->numDalvikRegisters, false);
   1121 
   1122     for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
   1123         int dfAttributes =
   1124             dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
   1125         DecodedInstruction *dInsn = &mir->dalvikInsn;
   1126 
   1127         if (dfAttributes & DF_HAS_USES) {
   1128             if (dfAttributes & DF_UA) {
   1129                 handleLiveInUse(useV, defV, liveInV, dInsn->vA);
   1130             } else if (dfAttributes & DF_UA_WIDE) {
   1131                 handleLiveInUse(useV, defV, liveInV, dInsn->vA);
   1132                 handleLiveInUse(useV, defV, liveInV, dInsn->vA+1);
   1133             }
   1134             if (dfAttributes & DF_UB) {
   1135                 handleLiveInUse(useV, defV, liveInV, dInsn->vB);
   1136             } else if (dfAttributes & DF_UB_WIDE) {
   1137                 handleLiveInUse(useV, defV, liveInV, dInsn->vB);
   1138                 handleLiveInUse(useV, defV, liveInV, dInsn->vB+1);
   1139             }
   1140             if (dfAttributes & DF_UC) {
   1141                 handleLiveInUse(useV, defV, liveInV, dInsn->vC);
   1142             } else if (dfAttributes & DF_UC_WIDE) {
   1143                 handleLiveInUse(useV, defV, liveInV, dInsn->vC);
   1144                 handleLiveInUse(useV, defV, liveInV, dInsn->vC+1);
   1145             }
   1146         }
   1147         if (dfAttributes & DF_HAS_DEFS) {
   1148             handleDef(defV, dInsn->vA);
   1149             if (dfAttributes & DF_DA_WIDE) {
   1150                 handleDef(defV, dInsn->vA+1);
   1151             }
   1152         }
   1153     }
   1154     return true;
   1155 }
   1156 
   1157 /* Find out the latest SSA register for a given Dalvik register */
   1158 static void handleSSAUse(CompilationUnit *cUnit, int *uses, int dalvikReg,
   1159                          int regIndex)
   1160 {
   1161     int encodedValue = cUnit->dalvikToSSAMap[dalvikReg];
   1162     int ssaReg = DECODE_REG(encodedValue);
   1163     uses[regIndex] = ssaReg;
   1164 }
   1165 
   1166 /* Setup a new SSA register for a given Dalvik register */
   1167 static void handleSSADef(CompilationUnit *cUnit, int *defs, int dalvikReg,
   1168                          int regIndex)
   1169 {
   1170     int encodedValue = cUnit->dalvikToSSAMap[dalvikReg];
   1171     int ssaReg = cUnit->numSSARegs++;
   1172     /* Bump up the subscript */
   1173     int dalvikSub = DECODE_SUB(encodedValue) + 1;
   1174     int newD2SMapping = ENCODE_REG_SUB(ssaReg, dalvikSub);
   1175 
   1176     cUnit->dalvikToSSAMap[dalvikReg] = newD2SMapping;
   1177 
   1178     int newS2DMapping = ENCODE_REG_SUB(dalvikReg, dalvikSub);
   1179     dvmInsertGrowableList(cUnit->ssaToDalvikMap, newS2DMapping);
   1180 
   1181     defs[regIndex] = ssaReg;
   1182 }
   1183 
   1184 /* Loop up new SSA names for format_35c instructions */
   1185 static void dataFlowSSAFormat35C(CompilationUnit *cUnit, MIR *mir)
   1186 {
   1187     DecodedInstruction *dInsn = &mir->dalvikInsn;
   1188     int numUses = dInsn->vA;
   1189     int i;
   1190 
   1191     mir->ssaRep->numUses = numUses;
   1192     mir->ssaRep->uses = (int *)dvmCompilerNew(sizeof(int) * numUses, false);
   1193 
   1194     for (i = 0; i < numUses; i++) {
   1195         handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->arg[i], i);
   1196     }
   1197 }
   1198 
   1199 /* Loop up new SSA names for format_3rc instructions */
   1200 static void dataFlowSSAFormat3RC(CompilationUnit *cUnit, MIR *mir)
   1201 {
   1202     DecodedInstruction *dInsn = &mir->dalvikInsn;
   1203     int numUses = dInsn->vA;
   1204     int i;
   1205 
   1206     mir->ssaRep->numUses = numUses;
   1207     mir->ssaRep->uses = (int *)dvmCompilerNew(sizeof(int) * numUses, false);
   1208 
   1209     for (i = 0; i < numUses; i++) {
   1210         handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+i, i);
   1211     }
   1212 }
   1213 
   1214 /* Entry function to convert a block into SSA representation */
   1215 bool dvmCompilerDoSSAConversion(CompilationUnit *cUnit, BasicBlock *bb)
   1216 {
   1217     MIR *mir;
   1218 
   1219     if (bb->dataFlowInfo == NULL) return false;
   1220 
   1221     for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
   1222         mir->ssaRep = (struct SSARepresentation *)
   1223             dvmCompilerNew(sizeof(SSARepresentation), true);
   1224 
   1225         int dfAttributes =
   1226             dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
   1227 
   1228         int numUses = 0;
   1229 
   1230         if (dfAttributes & DF_FORMAT_35C) {
   1231             dataFlowSSAFormat35C(cUnit, mir);
   1232             continue;
   1233         }
   1234 
   1235         if (dfAttributes & DF_FORMAT_3RC) {
   1236             dataFlowSSAFormat3RC(cUnit, mir);
   1237             continue;
   1238         }
   1239 
   1240         if (dfAttributes & DF_HAS_USES) {
   1241             if (dfAttributes & DF_UA) {
   1242                 numUses++;
   1243             } else if (dfAttributes & DF_UA_WIDE) {
   1244                 numUses += 2;
   1245             }
   1246             if (dfAttributes & DF_UB) {
   1247                 numUses++;
   1248             } else if (dfAttributes & DF_UB_WIDE) {
   1249                 numUses += 2;
   1250             }
   1251             if (dfAttributes & DF_UC) {
   1252                 numUses++;
   1253             } else if (dfAttributes & DF_UC_WIDE) {
   1254                 numUses += 2;
   1255             }
   1256         }
   1257 
   1258         if (numUses) {
   1259             mir->ssaRep->numUses = numUses;
   1260             mir->ssaRep->uses = (int *)dvmCompilerNew(sizeof(int) * numUses,
   1261                                                       false);
   1262             mir->ssaRep->fpUse = (bool *)dvmCompilerNew(sizeof(bool) * numUses,
   1263                                                 false);
   1264         }
   1265 
   1266         int numDefs = 0;
   1267 
   1268         if (dfAttributes & DF_HAS_DEFS) {
   1269             numDefs++;
   1270             if (dfAttributes & DF_DA_WIDE) {
   1271                 numDefs++;
   1272             }
   1273         }
   1274 
   1275         if (numDefs) {
   1276             mir->ssaRep->numDefs = numDefs;
   1277             mir->ssaRep->defs = (int *)dvmCompilerNew(sizeof(int) * numDefs,
   1278                                                       false);
   1279             mir->ssaRep->fpDef = (bool *)dvmCompilerNew(sizeof(bool) * numDefs,
   1280                                                         false);
   1281         }
   1282 
   1283         DecodedInstruction *dInsn = &mir->dalvikInsn;
   1284 
   1285         if (dfAttributes & DF_HAS_USES) {
   1286             numUses = 0;
   1287             if (dfAttributes & DF_UA) {
   1288                 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
   1289                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA, numUses++);
   1290             } else if (dfAttributes & DF_UA_WIDE) {
   1291                 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
   1292                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA, numUses++);
   1293                 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
   1294                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA+1, numUses++);
   1295             }
   1296             if (dfAttributes & DF_UB) {
   1297                 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
   1298                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB, numUses++);
   1299             } else if (dfAttributes & DF_UB_WIDE) {
   1300                 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
   1301                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB, numUses++);
   1302                 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
   1303                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB+1, numUses++);
   1304             }
   1305             if (dfAttributes & DF_UC) {
   1306                 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
   1307                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC, numUses++);
   1308             } else if (dfAttributes & DF_UC_WIDE) {
   1309                 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
   1310                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC, numUses++);
   1311                 mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
   1312                 handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+1, numUses++);
   1313             }
   1314         }
   1315         if (dfAttributes & DF_HAS_DEFS) {
   1316             mir->ssaRep->fpDef[0] = dfAttributes & DF_FP_A;
   1317             handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA, 0);
   1318             if (dfAttributes & DF_DA_WIDE) {
   1319                 mir->ssaRep->fpDef[1] = dfAttributes & DF_FP_A;
   1320                 handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA+1, 1);
   1321             }
   1322         }
   1323     }
   1324 
   1325     /*
   1326      * Take a snapshot of Dalvik->SSA mapping at the end of each block. The
   1327      * input to PHI nodes can be derived from the snapshot of all predecessor
   1328      * blocks.
   1329      */
   1330     bb->dataFlowInfo->dalvikToSSAMap =
   1331         (int *)dvmCompilerNew(sizeof(int) * cUnit->method->registersSize,
   1332                               false);
   1333 
   1334     memcpy(bb->dataFlowInfo->dalvikToSSAMap, cUnit->dalvikToSSAMap,
   1335            sizeof(int) * cUnit->method->registersSize);
   1336     return true;
   1337 }
   1338 
   1339 /* Setup a constant value for opcodes thare have the DF_SETS_CONST attribute */
   1340 static void setConstant(CompilationUnit *cUnit, int ssaReg, int value)
   1341 {
   1342     dvmSetBit(cUnit->isConstantV, ssaReg);
   1343     cUnit->constantValues[ssaReg] = value;
   1344 }
   1345 
   1346 bool dvmCompilerDoConstantPropagation(CompilationUnit *cUnit, BasicBlock *bb)
   1347 {
   1348     MIR *mir;
   1349     BitVector *isConstantV = cUnit->isConstantV;
   1350 
   1351     for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
   1352         int dfAttributes =
   1353             dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
   1354 
   1355         DecodedInstruction *dInsn = &mir->dalvikInsn;
   1356 
   1357         if (!(dfAttributes & DF_HAS_DEFS)) continue;
   1358 
   1359         /* Handle instructions that set up constants directly */
   1360         if (dfAttributes & DF_SETS_CONST) {
   1361             if (dfAttributes & DF_DA) {
   1362                 switch (dInsn->opcode) {
   1363                     case OP_CONST_4:
   1364                     case OP_CONST_16:
   1365                     case OP_CONST:
   1366                         setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
   1367                         break;
   1368                     case OP_CONST_HIGH16:
   1369                         setConstant(cUnit, mir->ssaRep->defs[0],
   1370                                     dInsn->vB << 16);
   1371                         break;
   1372                     default:
   1373                         break;
   1374                 }
   1375             } else if (dfAttributes & DF_DA_WIDE) {
   1376                 switch (dInsn->opcode) {
   1377                     case OP_CONST_WIDE_16:
   1378                     case OP_CONST_WIDE_32:
   1379                         setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
   1380                         setConstant(cUnit, mir->ssaRep->defs[1], 0);
   1381                         break;
   1382                     case OP_CONST_WIDE:
   1383                         setConstant(cUnit, mir->ssaRep->defs[0],
   1384                                     (int) dInsn->vB_wide);
   1385                         setConstant(cUnit, mir->ssaRep->defs[1],
   1386                                     (int) (dInsn->vB_wide >> 32));
   1387                         break;
   1388                     case OP_CONST_WIDE_HIGH16:
   1389                         setConstant(cUnit, mir->ssaRep->defs[0], 0);
   1390                         setConstant(cUnit, mir->ssaRep->defs[1],
   1391                                     dInsn->vB << 16);
   1392                         break;
   1393                     default:
   1394                         break;
   1395                 }
   1396             }
   1397         /* Handle instructions that set up constants directly */
   1398         } else if (dfAttributes & DF_IS_MOVE) {
   1399             int i;
   1400 
   1401             for (i = 0; i < mir->ssaRep->numUses; i++) {
   1402                 if (!dvmIsBitSet(isConstantV, mir->ssaRep->uses[i])) break;
   1403             }
   1404             /* Move a register holding a constant to another register */
   1405             if (i == mir->ssaRep->numUses) {
   1406                 setConstant(cUnit, mir->ssaRep->defs[0],
   1407                             cUnit->constantValues[mir->ssaRep->uses[0]]);
   1408                 if (dfAttributes & DF_DA_WIDE) {
   1409                     setConstant(cUnit, mir->ssaRep->defs[1],
   1410                                 cUnit->constantValues[mir->ssaRep->uses[1]]);
   1411                 }
   1412             }
   1413         }
   1414     }
   1415     /* TODO: implement code to handle arithmetic operations */
   1416     return true;
   1417 }
   1418 
   1419 bool dvmCompilerFindInductionVariables(struct CompilationUnit *cUnit,
   1420                                        struct BasicBlock *bb)
   1421 {
   1422     BitVector *isIndVarV = cUnit->loopAnalysis->isIndVarV;
   1423     BitVector *isConstantV = cUnit->isConstantV;
   1424     GrowableList *ivList = cUnit->loopAnalysis->ivList;
   1425     MIR *mir;
   1426 
   1427     if (bb->blockType != kDalvikByteCode && bb->blockType != kEntryBlock) {
   1428         return false;
   1429     }
   1430 
   1431     /* If the bb doesn't have a phi it cannot contain an induction variable */
   1432     if (bb->firstMIRInsn == NULL ||
   1433         (int)bb->firstMIRInsn->dalvikInsn.opcode != (int)kMirOpPhi) {
   1434         return false;
   1435     }
   1436 
   1437     /* Find basic induction variable first */
   1438     for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
   1439         int dfAttributes =
   1440             dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
   1441 
   1442         if (!(dfAttributes & DF_IS_LINEAR)) continue;
   1443 
   1444         /*
   1445          * For a basic induction variable:
   1446          *   1) use[0] should belong to the output of a phi node
   1447          *   2) def[0] should belong to the input of the same phi node
   1448          *   3) the value added/subtracted is a constant
   1449          */
   1450         MIR *phi;
   1451         for (phi = bb->firstMIRInsn; phi; phi = phi->next) {
   1452             if ((int)phi->dalvikInsn.opcode != (int)kMirOpPhi) break;
   1453 
   1454             if (phi->ssaRep->defs[0] == mir->ssaRep->uses[0] &&
   1455                 phi->ssaRep->uses[1] == mir->ssaRep->defs[0]) {
   1456                 bool deltaIsConstant = false;
   1457                 int deltaValue;
   1458 
   1459                 switch (mir->dalvikInsn.opcode) {
   1460                     case OP_ADD_INT:
   1461                         if (dvmIsBitSet(isConstantV,
   1462                                         mir->ssaRep->uses[1])) {
   1463                             deltaValue =
   1464                                 cUnit->constantValues[mir->ssaRep->uses[1]];
   1465                             deltaIsConstant = true;
   1466                         }
   1467                         break;
   1468                     case OP_SUB_INT:
   1469                         if (dvmIsBitSet(isConstantV,
   1470                                         mir->ssaRep->uses[1])) {
   1471                             deltaValue =
   1472                                 -cUnit->constantValues[mir->ssaRep->uses[1]];
   1473                             deltaIsConstant = true;
   1474                         }
   1475                         break;
   1476                     case OP_ADD_INT_LIT8:
   1477                         deltaValue = mir->dalvikInsn.vC;
   1478                         deltaIsConstant = true;
   1479                         break;
   1480                     default:
   1481                         break;
   1482                 }
   1483                 if (deltaIsConstant) {
   1484                     dvmSetBit(isIndVarV, mir->ssaRep->uses[0]);
   1485                     InductionVariableInfo *ivInfo = (InductionVariableInfo *)
   1486                         dvmCompilerNew(sizeof(InductionVariableInfo),
   1487                                        false);
   1488 
   1489                     ivInfo->ssaReg = mir->ssaRep->uses[0];
   1490                     ivInfo->basicSSAReg = mir->ssaRep->uses[0];
   1491                     ivInfo->m = 1;         // always 1 to basic iv
   1492                     ivInfo->c = 0;         // N/A to basic iv
   1493                     ivInfo->inc = deltaValue;
   1494                     dvmInsertGrowableList(ivList, (intptr_t) ivInfo);
   1495                     cUnit->loopAnalysis->numBasicIV++;
   1496                     break;
   1497                 }
   1498             }
   1499         }
   1500     }
   1501 
   1502     /* Find dependent induction variable now */
   1503     for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
   1504         int dfAttributes =
   1505             dvmCompilerDataFlowAttributes[mir->dalvikInsn.opcode];
   1506 
   1507         if (!(dfAttributes & DF_IS_LINEAR)) continue;
   1508 
   1509         /* Skip already identified induction variables */
   1510         if (dvmIsBitSet(isIndVarV, mir->ssaRep->defs[0])) continue;
   1511 
   1512         /*
   1513          * For a dependent induction variable:
   1514          *  1) use[0] should be an induction variable (basic/dependent)
   1515          *  2) operand2 should be a constant
   1516          */
   1517         if (dvmIsBitSet(isIndVarV, mir->ssaRep->uses[0])) {
   1518             int srcDalvikReg = dvmConvertSSARegToDalvik(cUnit,
   1519                                                         mir->ssaRep->uses[0]);
   1520             int dstDalvikReg = dvmConvertSSARegToDalvik(cUnit,
   1521                                                         mir->ssaRep->defs[0]);
   1522 
   1523             bool cIsConstant = false;
   1524             int c = 0;
   1525 
   1526             switch (mir->dalvikInsn.opcode) {
   1527                 case OP_ADD_INT:
   1528                     if (dvmIsBitSet(isConstantV,
   1529                                     mir->ssaRep->uses[1])) {
   1530                         c = cUnit->constantValues[mir->ssaRep->uses[1]];
   1531                         cIsConstant = true;
   1532                     }
   1533                     break;
   1534                 case OP_SUB_INT:
   1535                     if (dvmIsBitSet(isConstantV,
   1536                                     mir->ssaRep->uses[1])) {
   1537                         c = -cUnit->constantValues[mir->ssaRep->uses[1]];
   1538                         cIsConstant = true;
   1539                     }
   1540                     break;
   1541                 case OP_ADD_INT_LIT8:
   1542                     c = mir->dalvikInsn.vC;
   1543                     cIsConstant = true;
   1544                     break;
   1545                 default:
   1546                     break;
   1547             }
   1548 
   1549             /* Ignore the update to the basic induction variable itself */
   1550             if (DECODE_REG(srcDalvikReg) == DECODE_REG(dstDalvikReg))  {
   1551                 cUnit->loopAnalysis->ssaBIV = mir->ssaRep->defs[0];
   1552                 cIsConstant = false;
   1553             }
   1554 
   1555             if (cIsConstant) {
   1556                 unsigned int i;
   1557                 dvmSetBit(isIndVarV, mir->ssaRep->defs[0]);
   1558                 InductionVariableInfo *ivInfo = (InductionVariableInfo *)
   1559                     dvmCompilerNew(sizeof(InductionVariableInfo),
   1560                                    false);
   1561                 InductionVariableInfo *ivInfoOld = NULL ;
   1562 
   1563                 for (i = 0; i < ivList->numUsed; i++) {
   1564                     ivInfoOld = (InductionVariableInfo *) ivList->elemList[i];
   1565                     if (ivInfoOld->ssaReg == mir->ssaRep->uses[0]) break;
   1566                 }
   1567 
   1568                 /* Guaranteed to find an element */
   1569                 assert(i < ivList->numUsed);
   1570 
   1571                 ivInfo->ssaReg = mir->ssaRep->defs[0];
   1572                 ivInfo->basicSSAReg = ivInfoOld->basicSSAReg;
   1573                 ivInfo->m = ivInfoOld->m;
   1574                 ivInfo->c = c + ivInfoOld->c;
   1575                 ivInfo->inc = ivInfoOld->inc;
   1576                 dvmInsertGrowableList(ivList, (intptr_t) ivInfo);
   1577             }
   1578         }
   1579     }
   1580     return true;
   1581 }
   1582 
   1583 /* Setup the basic data structures for SSA conversion */
   1584 void dvmInitializeSSAConversion(CompilationUnit *cUnit)
   1585 {
   1586     int i;
   1587     int numDalvikReg = cUnit->method->registersSize;
   1588 
   1589     cUnit->ssaToDalvikMap = (GrowableList *)dvmCompilerNew(sizeof(GrowableList),
   1590                                                            false);
   1591     dvmInitGrowableList(cUnit->ssaToDalvikMap, numDalvikReg);
   1592 
   1593     /*
   1594      * Initial number of SSA registers is equal to the number of Dalvik
   1595      * registers.
   1596      */
   1597     cUnit->numSSARegs = numDalvikReg;
   1598 
   1599     /*
   1600      * Initialize the SSA2Dalvik map list. For the first numDalvikReg elements,
   1601      * the subscript is 0 so we use the ENCODE_REG_SUB macro to encode the value
   1602      * into "(0 << 16) | i"
   1603      */
   1604     for (i = 0; i < numDalvikReg; i++) {
   1605         dvmInsertGrowableList(cUnit->ssaToDalvikMap, ENCODE_REG_SUB(i, 0));
   1606     }
   1607 
   1608     /*
   1609      * Initialize the DalvikToSSAMap map. The low 16 bit is the SSA register id,
   1610      * while the high 16 bit is the current subscript. The original Dalvik
   1611      * register N is mapped to SSA register N with subscript 0.
   1612      */
   1613     cUnit->dalvikToSSAMap = (int *)dvmCompilerNew(sizeof(int) * numDalvikReg,
   1614                                                   false);
   1615     for (i = 0; i < numDalvikReg; i++) {
   1616         cUnit->dalvikToSSAMap[i] = i;
   1617     }
   1618 
   1619     /*
   1620      * Allocate the BasicBlockDataFlow structure for the entry and code blocks
   1621      */
   1622     GrowableListIterator iterator;
   1623 
   1624     dvmGrowableListIteratorInit(&cUnit->blockList, &iterator);
   1625 
   1626     while (true) {
   1627         BasicBlock *bb = (BasicBlock *) dvmGrowableListIteratorNext(&iterator);
   1628         if (bb == NULL) break;
   1629         if (bb->hidden == true) continue;
   1630         if (bb->blockType == kDalvikByteCode ||
   1631             bb->blockType == kEntryBlock ||
   1632             bb->blockType == kExitBlock) {
   1633             bb->dataFlowInfo = (BasicBlockDataFlow *)
   1634                 dvmCompilerNew(sizeof(BasicBlockDataFlow),
   1635                                true);
   1636         }
   1637     }
   1638 }
   1639 
   1640 /* Clear the visited flag for each BB */
   1641 bool dvmCompilerClearVisitedFlag(struct CompilationUnit *cUnit,
   1642                                  struct BasicBlock *bb)
   1643 {
   1644     bb->visited = false;
   1645     return true;
   1646 }
   1647 
   1648 void dvmCompilerDataFlowAnalysisDispatcher(CompilationUnit *cUnit,
   1649                 bool (*func)(CompilationUnit *, BasicBlock *),
   1650                 DataFlowAnalysisMode dfaMode,
   1651                 bool isIterative)
   1652 {
   1653     bool change = true;
   1654 
   1655     while (change) {
   1656         change = false;
   1657 
   1658         /* Scan all blocks and perform the operations specified in func */
   1659         if (dfaMode == kAllNodes) {
   1660             GrowableListIterator iterator;
   1661             dvmGrowableListIteratorInit(&cUnit->blockList, &iterator);
   1662             while (true) {
   1663                 BasicBlock *bb =
   1664                     (BasicBlock *) dvmGrowableListIteratorNext(&iterator);
   1665                 if (bb == NULL) break;
   1666                 if (bb->hidden == true) continue;
   1667                 change |= (*func)(cUnit, bb);
   1668             }
   1669         }
   1670         /*
   1671          * Scan all reachable blocks and perform the operations specified in
   1672          * func.
   1673          */
   1674         else if (dfaMode == kReachableNodes) {
   1675             int numReachableBlocks = cUnit->numReachableBlocks;
   1676             int idx;
   1677             const GrowableList *blockList = &cUnit->blockList;
   1678 
   1679             for (idx = 0; idx < numReachableBlocks; idx++) {
   1680                 int blockIdx = cUnit->dfsOrder.elemList[idx];
   1681                 BasicBlock *bb =
   1682                     (BasicBlock *) dvmGrowableListGetElement(blockList,
   1683                                                              blockIdx);
   1684                 change |= (*func)(cUnit, bb);
   1685             }
   1686         }
   1687         /*
   1688          * Scan all reachable blocks by the pre-order in the depth-first-search
   1689          * CFG and perform the operations specified in func.
   1690          */
   1691         else if (dfaMode == kPreOrderDFSTraversal) {
   1692             int numReachableBlocks = cUnit->numReachableBlocks;
   1693             int idx;
   1694             const GrowableList *blockList = &cUnit->blockList;
   1695 
   1696             for (idx = 0; idx < numReachableBlocks; idx++) {
   1697                 int dfsIdx = cUnit->dfsOrder.elemList[idx];
   1698                 BasicBlock *bb =
   1699                     (BasicBlock *) dvmGrowableListGetElement(blockList, dfsIdx);
   1700                 change |= (*func)(cUnit, bb);
   1701             }
   1702         }
   1703         /*
   1704          * Scan all reachable blocks by the post-order in the depth-first-search
   1705          * CFG and perform the operations specified in func.
   1706          */
   1707         else if (dfaMode == kPostOrderDFSTraversal) {
   1708             int numReachableBlocks = cUnit->numReachableBlocks;
   1709             int idx;
   1710             const GrowableList *blockList = &cUnit->blockList;
   1711 
   1712             for (idx = numReachableBlocks - 1; idx >= 0; idx--) {
   1713                 int dfsIdx = cUnit->dfsOrder.elemList[idx];
   1714                 BasicBlock *bb =
   1715                     (BasicBlock *) dvmGrowableListGetElement(blockList, dfsIdx);
   1716                 change |= (*func)(cUnit, bb);
   1717             }
   1718         }
   1719         /*
   1720          * Scan all reachable blocks by the post-order in the dominator tree
   1721          * and perform the operations specified in func.
   1722          */
   1723         else if (dfaMode == kPostOrderDOMTraversal) {
   1724             int numReachableBlocks = cUnit->numReachableBlocks;
   1725             int idx;
   1726             const GrowableList *blockList = &cUnit->blockList;
   1727 
   1728             for (idx = 0; idx < numReachableBlocks; idx++) {
   1729                 int domIdx = cUnit->domPostOrderTraversal.elemList[idx];
   1730                 BasicBlock *bb =
   1731                     (BasicBlock *) dvmGrowableListGetElement(blockList, domIdx);
   1732                 change |= (*func)(cUnit, bb);
   1733             }
   1734         }
   1735         /* If isIterative is false, exit the loop after the first iteration */
   1736         change &= isIterative;
   1737     }
   1738 }
   1739 
   1740 /* Main entry point to do SSA conversion for non-loop traces */
   1741 void dvmCompilerNonLoopAnalysis(CompilationUnit *cUnit)
   1742 {
   1743     dvmCompilerDataFlowAnalysisDispatcher(cUnit, dvmCompilerDoSSAConversion,
   1744                                           kAllNodes,
   1745                                           false /* isIterative */);
   1746 }
   1747