/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Dalvik.h"
#include "Dataflow.h"

namespace art {

/*
 * Main table containing data flow attributes for each bytecode. The
 * first kNumPackedOpcodes entries are for Dalvik bytecode
 * instructions, where extended opcode at the MIR level are appended
 * afterwards.
 *
 * TODO - many optimization flags are incomplete - they will only limit the
 * scope of optimizations but will not cause mis-optimizations.
 */
const int oatDataFlowAttributes[kMirOpLast] = {
  // 00 NOP
  DF_NOP,

  // 01 MOVE vA, vB
  DF_DA | DF_UB | DF_IS_MOVE,

  // 02 MOVE_FROM16 vAA, vBBBB
  DF_DA | DF_UB | DF_IS_MOVE,

  // 03 MOVE_16 vAAAA, vBBBB
  DF_DA | DF_UB | DF_IS_MOVE,

  // 04 MOVE_WIDE vA, vB
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_IS_MOVE,

  // 05 MOVE_WIDE_FROM16 vAA, vBBBB
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_IS_MOVE,

  // 06 MOVE_WIDE_16 vAAAA, vBBBB
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_IS_MOVE,

  // 07 MOVE_OBJECT vA, vB
  DF_DA | DF_UB | DF_NULL_TRANSFER_0 | DF_IS_MOVE | DF_REF_A | DF_REF_B,

  // 08 MOVE_OBJECT_FROM16 vAA, vBBBB
  DF_DA | DF_UB | DF_NULL_TRANSFER_0 | DF_IS_MOVE | DF_REF_A | DF_REF_B,

  // 09 MOVE_OBJECT_16 vAAAA, vBBBB
  DF_DA | DF_UB | DF_NULL_TRANSFER_0 | DF_IS_MOVE | DF_REF_A | DF_REF_B,

  // 0A MOVE_RESULT vAA
  DF_DA,

  // 0B MOVE_RESULT_WIDE vAA
  DF_DA | DF_A_WIDE,

  // 0C MOVE_RESULT_OBJECT vAA
  DF_DA | DF_REF_A,

  // 0D MOVE_EXCEPTION vAA
  DF_DA | DF_CORE_A,

  // 0E RETURN_VOID
  DF_NOP,

  // 0F RETURN vAA
  DF_UA,

  // 10 RETURN_WIDE vAA
  DF_UA | DF_A_WIDE,

  // 11 RETURN_OBJECT vAA
  DF_UA | DF_REF_A,

  // 12 CONST_4 vA, #+B
  DF_DA | DF_SETS_CONST,

  // 13 CONST_16 vAA, #+BBBB
  DF_DA | DF_SETS_CONST,

  // 14 CONST vAA, #+BBBBBBBB
  DF_DA | DF_SETS_CONST,

  // 15 CONST_HIGH16 VAA, #+BBBB0000
  DF_DA | DF_SETS_CONST,

  // 16 CONST_WIDE_16 vAA, #+BBBB
  DF_DA | DF_A_WIDE | DF_SETS_CONST,

  // 17 CONST_WIDE_32 vAA, #+BBBBBBBB
  DF_DA | DF_A_WIDE | DF_SETS_CONST,

  // 18 CONST_WIDE vAA, #+BBBBBBBBBBBBBBBB
  DF_DA | DF_A_WIDE | DF_SETS_CONST,

  // 19 CONST_WIDE_HIGH16 vAA, #+BBBB000000000000
  DF_DA | DF_A_WIDE | DF_SETS_CONST,

  // 1A CONST_STRING vAA, string@BBBB
  DF_DA | DF_REF_A,

  // 1B CONST_STRING_JUMBO vAA, string@BBBBBBBB
  DF_DA | DF_REF_A,

  // 1C CONST_CLASS vAA, type@BBBB
  DF_DA | DF_REF_A,

  // 1D MONITOR_ENTER vAA
  DF_UA | DF_NULL_CHK_0 | DF_REF_A,

  // 1E MONITOR_EXIT vAA
  DF_UA | DF_NULL_CHK_0 | DF_REF_A,

  // 1F CHK_CAST vAA, type@BBBB
  DF_UA | DF_REF_A | DF_UMS,

  // 20 INSTANCE_OF vA, vB, type@CCCC
  DF_DA | DF_UB | DF_CORE_A | DF_REF_B | DF_UMS,

  // 21 ARRAY_LENGTH vA, vB
  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_CORE_A | DF_REF_B,

  // 22 NEW_INSTANCE vAA, type@BBBB
  DF_DA | DF_NON_NULL_DST | DF_REF_A | DF_UMS,

  // 23 NEW_ARRAY vA, vB, type@CCCC
  DF_DA | DF_UB | DF_NON_NULL_DST | DF_REF_A | DF_CORE_B | DF_UMS,

  // 24 FILLED_NEW_ARRAY {vD, vE, vF, vG, vA}
  DF_FORMAT_35C | DF_NON_NULL_RET | DF_UMS,

  // 25 FILLED_NEW_ARRAY_RANGE {vCCCC .. vNNNN}, type@BBBB
  DF_FORMAT_3RC | DF_NON_NULL_RET | DF_UMS,

  // 26 FILL_ARRAY_DATA vAA, +BBBBBBBB
  DF_UA | DF_REF_A | DF_UMS,

  // 27 THROW vAA
  DF_UA | DF_REF_A | DF_UMS,

  // 28 GOTO
  DF_NOP,

  // 29 GOTO_16
  DF_NOP,

  // 2A GOTO_32
  DF_NOP,

  // 2B PACKED_SWITCH vAA, +BBBBBBBB
  DF_UA,

  // 2C SPARSE_SWITCH vAA, +BBBBBBBB
  DF_UA,

  // 2D CMPL_FLOAT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C | DF_CORE_A,

  // 2E CMPG_FLOAT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_FP_B | DF_FP_C | DF_CORE_A,

  // 2F CMPL_DOUBLE vAA, vBB, vCC
  DF_DA | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_FP_B | DF_FP_C | DF_CORE_A,

  // 30 CMPG_DOUBLE vAA, vBB, vCC
  DF_DA | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_FP_B | DF_FP_C | DF_CORE_A,

  // 31 CMP_LONG vAA, vBB, vCC
  DF_DA | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 32 IF_EQ vA, vB, +CCCC
  DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // 33 IF_NE vA, vB, +CCCC
  DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // 34 IF_LT vA, vB, +CCCC
  DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // 35 IF_GE vA, vB, +CCCC
  DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // 36 IF_GT vA, vB, +CCCC
  DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // 37 IF_LE vA, vB, +CCCC
  DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,


  // 38 IF_EQZ vAA, +BBBB
  DF_UA | DF_CORE_A,

  // 39 IF_NEZ vAA, +BBBB
  DF_UA | DF_CORE_A,

  // 3A IF_LTZ vAA, +BBBB
  DF_UA | DF_CORE_A,

  // 3B IF_GEZ vAA, +BBBB
  DF_UA | DF_CORE_A,

  // 3C IF_GTZ vAA, +BBBB
  DF_UA | DF_CORE_A,

  // 3D IF_LEZ vAA, +BBBB
  DF_UA | DF_CORE_A,

  // 3E UNUSED_3E
  DF_NOP,

  // 3F UNUSED_3F
  DF_NOP,

  // 40 UNUSED_40
  DF_NOP,

  // 41 UNUSED_41
  DF_NOP,

  // 42 UNUSED_42
  DF_NOP,

  // 43 UNUSED_43
  DF_NOP,

  // 44 AGET vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_REF_B | DF_CORE_C,

  // 45 AGET_WIDE vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_REF_B | DF_CORE_C,

  // 46 AGET_OBJECT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_REF_A | DF_REF_B | DF_CORE_C,

  // 47 AGET_BOOLEAN vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_REF_B | DF_CORE_C,

  // 48 AGET_BYTE vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_REF_B | DF_CORE_C,

  // 49 AGET_CHAR vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_REF_B | DF_CORE_C,

  // 4A AGET_SHORT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_NULL_CHK_0 | DF_RANGE_CHK_1 | DF_REF_B | DF_CORE_C,

  // 4B APUT vAA, vBB, vCC
  DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_REF_B | DF_CORE_C,

  // 4C APUT_WIDE vAA, vBB, vCC
  DF_UA | DF_A_WIDE | DF_UB | DF_UC | DF_NULL_CHK_2 | DF_RANGE_CHK_3 | DF_REF_B | DF_CORE_C,

  // 4D APUT_OBJECT vAA, vBB, vCC
  DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_REF_A | DF_REF_B | DF_CORE_C,

  // 4E APUT_BOOLEAN vAA, vBB, vCC
  DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_REF_B | DF_CORE_C,

  // 4F APUT_BYTE vAA, vBB, vCC
  DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_REF_B | DF_CORE_C,

  // 50 APUT_CHAR vAA, vBB, vCC
  DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_REF_B | DF_CORE_C,

  // 51 APUT_SHORT vAA, vBB, vCC
  DF_UA | DF_UB | DF_UC | DF_NULL_CHK_1 | DF_RANGE_CHK_2 | DF_REF_B | DF_CORE_C,

  // 52 IGET vA, vB, field@CCCC
  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B,

  // 53 IGET_WIDE vA, vB, field@CCCC
  DF_DA | DF_A_WIDE | DF_UB | DF_NULL_CHK_0 | DF_REF_B,

  // 54 IGET_OBJECT vA, vB, field@CCCC
  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_A | DF_REF_B,

  // 55 IGET_BOOLEAN vA, vB, field@CCCC
  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B,

  // 56 IGET_BYTE vA, vB, field@CCCC
  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B,

  // 57 IGET_CHAR vA, vB, field@CCCC
  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B,

  // 58 IGET_SHORT vA, vB, field@CCCC
  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B,

  // 59 IPUT vA, vB, field@CCCC
  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B,

  // 5A IPUT_WIDE vA, vB, field@CCCC
  DF_UA | DF_A_WIDE | DF_UB | DF_NULL_CHK_2 | DF_REF_B,

  // 5B IPUT_OBJECT vA, vB, field@CCCC
  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_A | DF_REF_B,

  // 5C IPUT_BOOLEAN vA, vB, field@CCCC
  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B,

  // 5D IPUT_BYTE vA, vB, field@CCCC
  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B,

  // 5E IPUT_CHAR vA, vB, field@CCCC
  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B,

  // 5F IPUT_SHORT vA, vB, field@CCCC
  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B,

  // 60 SGET vAA, field@BBBB
  DF_DA | DF_UMS,

  // 61 SGET_WIDE vAA, field@BBBB
  DF_DA | DF_A_WIDE | DF_UMS,

  // 62 SGET_OBJECT vAA, field@BBBB
  DF_DA | DF_REF_A | DF_UMS,

  // 63 SGET_BOOLEAN vAA, field@BBBB
  DF_DA | DF_UMS,

  // 64 SGET_BYTE vAA, field@BBBB
  DF_DA | DF_UMS,

  // 65 SGET_CHAR vAA, field@BBBB
  DF_DA | DF_UMS,

  // 66 SGET_SHORT vAA, field@BBBB
  DF_DA | DF_UMS,

  // 67 SPUT vAA, field@BBBB
  DF_UA | DF_UMS,

  // 68 SPUT_WIDE vAA, field@BBBB
  DF_UA | DF_A_WIDE | DF_UMS,

  // 69 SPUT_OBJECT vAA, field@BBBB
  DF_UA | DF_REF_A | DF_UMS,

  // 6A SPUT_BOOLEAN vAA, field@BBBB
  DF_UA | DF_UMS,

  // 6B SPUT_BYTE vAA, field@BBBB
  DF_UA | DF_UMS,

  // 6C SPUT_CHAR vAA, field@BBBB
  DF_UA | DF_UMS,

  // 6D SPUT_SHORT vAA, field@BBBB
  DF_UA | DF_UMS,

  // 6E INVOKE_VIRTUAL {vD, vE, vF, vG, vA}
  DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,

  // 6F INVOKE_SUPER {vD, vE, vF, vG, vA}
  DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,

  // 70 INVOKE_DIRECT {vD, vE, vF, vG, vA}
  DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,

  // 71 INVOKE_STATIC {vD, vE, vF, vG, vA}
  DF_FORMAT_35C | DF_UMS,

  // 72 INVOKE_INTERFACE {vD, vE, vF, vG, vA}
  DF_FORMAT_35C | DF_UMS,

  // 73 UNUSED_73
  DF_NOP,

  // 74 INVOKE_VIRTUAL_RANGE {vCCCC .. vNNNN}
  DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,

  // 75 INVOKE_SUPER_RANGE {vCCCC .. vNNNN}
  DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,

  // 76 INVOKE_DIRECT_RANGE {vCCCC .. vNNNN}
  DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,

  // 77 INVOKE_STATIC_RANGE {vCCCC .. vNNNN}
  DF_FORMAT_3RC | DF_UMS,

  // 78 INVOKE_INTERFACE_RANGE {vCCCC .. vNNNN}
  DF_FORMAT_3RC | DF_UMS,

  // 79 UNUSED_79
  DF_NOP,

  // 7A UNUSED_7A
  DF_NOP,

  // 7B NEG_INT vA, vB
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // 7C NOT_INT vA, vB
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // 7D NEG_LONG vA, vB
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,

  // 7E NOT_LONG vA, vB
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,

  // 7F NEG_FLOAT vA, vB
  DF_DA | DF_UB | DF_FP_A | DF_FP_B,

  // 80 NEG_DOUBLE vA, vB
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,

  // 81 INT_TO_LONG vA, vB
  DF_DA | DF_A_WIDE | DF_UB | DF_CORE_A | DF_CORE_B,

  // 82 INT_TO_FLOAT vA, vB
  DF_DA | DF_UB | DF_FP_A | DF_CORE_B,

  // 83 INT_TO_DOUBLE vA, vB
  DF_DA | DF_A_WIDE | DF_UB | DF_FP_A | DF_CORE_B,

  // 84 LONG_TO_INT vA, vB
  DF_DA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,

  // 85 LONG_TO_FLOAT vA, vB
  DF_DA | DF_UB | DF_B_WIDE | DF_FP_A | DF_CORE_B,

  // 86 LONG_TO_DOUBLE vA, vB
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_FP_A | DF_CORE_B,

  // 87 FLOAT_TO_INT vA, vB
  DF_DA | DF_UB | DF_FP_B | DF_CORE_A,

  // 88 FLOAT_TO_LONG vA, vB
  DF_DA | DF_A_WIDE | DF_UB | DF_FP_B | DF_CORE_A,

  // 89 FLOAT_TO_DOUBLE vA, vB
  DF_DA | DF_A_WIDE | DF_UB | DF_FP_A | DF_FP_B,

  // 8A DOUBLE_TO_INT vA, vB
  DF_DA | DF_UB | DF_B_WIDE | DF_FP_B | DF_CORE_A,

  // 8B DOUBLE_TO_LONG vA, vB
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_FP_B | DF_CORE_A,

  // 8C DOUBLE_TO_FLOAT vA, vB
  DF_DA | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,

  // 8D INT_TO_BYTE vA, vB
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // 8E INT_TO_CHAR vA, vB
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // 8F INT_TO_SHORT vA, vB
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // 90 ADD_INT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 91 SUB_INT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 92 MUL_INT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 93 DIV_INT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 94 REM_INT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 95 AND_INT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 96 OR_INT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 97 XOR_INT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 98 SHL_INT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 99 SHR_INT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 9A USHR_INT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 9B ADD_LONG vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 9C SUB_LONG vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 9D MUL_LONG vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 9E DIV_LONG vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // 9F REM_LONG vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // A0 AND_LONG vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // A1 OR_LONG vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // A2 XOR_LONG vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // A3 SHL_LONG vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // A4 SHR_LONG vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // A5 USHR_LONG vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_CORE_A | DF_CORE_B | DF_CORE_C,

  // A6 ADD_FLOAT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,

  // A7 SUB_FLOAT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,

  // A8 MUL_FLOAT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,

  // A9 DIV_FLOAT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,

  // AA REM_FLOAT vAA, vBB, vCC
  DF_DA | DF_UB | DF_UC | DF_FP_A | DF_FP_B | DF_FP_C,

  // AB ADD_DOUBLE vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,

  // AC SUB_DOUBLE vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,

  // AD MUL_DOUBLE vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,

  // AE DIV_DOUBLE vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,

  // AF REM_DOUBLE vAA, vBB, vCC
  DF_DA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_UC | DF_C_WIDE | DF_FP_A | DF_FP_B | DF_FP_C,

  // B0 ADD_INT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // B1 SUB_INT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // B2 MUL_INT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // B3 DIV_INT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // B4 REM_INT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // B5 AND_INT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // B6 OR_INT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // B7 XOR_INT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // B8 SHL_INT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // B9 SHR_INT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // BA USHR_INT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // BB ADD_LONG_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,

  // BC SUB_LONG_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,

  // BD MUL_LONG_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,

  // BE DIV_LONG_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,

  // BF REM_LONG_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,

  // C0 AND_LONG_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,

  // C1 OR_LONG_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,

  // C2 XOR_LONG_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,

  // C3 SHL_LONG_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // C4 SHR_LONG_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // C5 USHR_LONG_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_CORE_A | DF_CORE_B,

  // C6 ADD_FLOAT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,

  // C7 SUB_FLOAT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,

  // C8 MUL_FLOAT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,

  // C9 DIV_FLOAT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,

  // CA REM_FLOAT_2ADDR vA, vB
  DF_DA | DF_UA | DF_UB | DF_FP_A | DF_FP_B,

  // CB ADD_DOUBLE_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,

  // CC SUB_DOUBLE_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,

  // CD MUL_DOUBLE_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,

  // CE DIV_DOUBLE_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,

  // CF REM_DOUBLE_2ADDR vA, vB
  DF_DA | DF_A_WIDE | DF_UA | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,

  // D0 ADD_INT_LIT16 vA, vB, #+CCCC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // D1 RSUB_INT vA, vB, #+CCCC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // D2 MUL_INT_LIT16 vA, vB, #+CCCC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // D3 DIV_INT_LIT16 vA, vB, #+CCCC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // D4 REM_INT_LIT16 vA, vB, #+CCCC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // D5 AND_INT_LIT16 vA, vB, #+CCCC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // D6 OR_INT_LIT16 vA, vB, #+CCCC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // D7 XOR_INT_LIT16 vA, vB, #+CCCC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // D8 ADD_INT_LIT8 vAA, vBB, #+CC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // D9 RSUB_INT_LIT8 vAA, vBB, #+CC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // DA MUL_INT_LIT8 vAA, vBB, #+CC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // DB DIV_INT_LIT8 vAA, vBB, #+CC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // DC REM_INT_LIT8 vAA, vBB, #+CC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // DD AND_INT_LIT8 vAA, vBB, #+CC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // DE OR_INT_LIT8 vAA, vBB, #+CC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // DF XOR_INT_LIT8 vAA, vBB, #+CC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // E0 SHL_INT_LIT8 vAA, vBB, #+CC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // E1 SHR_INT_LIT8 vAA, vBB, #+CC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // E2 USHR_INT_LIT8 vAA, vBB, #+CC
  DF_DA | DF_UB | DF_CORE_A | DF_CORE_B,

  // E3 IGET_VOLATILE
  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_B,

  // E4 IPUT_VOLATILE
  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_B,

  // E5 SGET_VOLATILE
  DF_DA | DF_UMS,

  // E6 SPUT_VOLATILE
  DF_UA | DF_UMS,

  // E7 IGET_OBJECT_VOLATILE
  DF_DA | DF_UB | DF_NULL_CHK_0 | DF_REF_A | DF_REF_B,

  // E8 IGET_WIDE_VOLATILE
  DF_DA | DF_A_WIDE | DF_UB | DF_NULL_CHK_0 | DF_REF_B,

  // E9 IPUT_WIDE_VOLATILE
  DF_UA | DF_A_WIDE | DF_UB | DF_NULL_CHK_2 | DF_REF_B,

  // EA SGET_WIDE_VOLATILE
  DF_DA | DF_A_WIDE | DF_UMS,

  // EB SPUT_WIDE_VOLATILE
  DF_UA | DF_A_WIDE | DF_UMS,

  // EC BREAKPOINT
  DF_NOP,

  // ED THROW_VERIFICATION_ERROR
  DF_NOP | DF_UMS,

  // EE EXECUTE_INLINE
  DF_FORMAT_35C,

  // EF EXECUTE_INLINE_RANGE
  DF_FORMAT_3RC,

  // F0 INVOKE_OBJECT_INIT_RANGE
  DF_NOP | DF_NULL_CHK_0,

  // F1 RETURN_VOID_BARRIER
  DF_NOP,

  // F2 IGET_QUICK
  DF_DA | DF_UB | DF_NULL_CHK_0,

  // F3 IGET_WIDE_QUICK
  DF_DA | DF_A_WIDE | DF_UB | DF_NULL_CHK_0,

  // F4 IGET_OBJECT_QUICK
  DF_DA | DF_UB | DF_NULL_CHK_0,

  // F5 IPUT_QUICK
  DF_UA | DF_UB | DF_NULL_CHK_1,

  // F6 IPUT_WIDE_QUICK
  DF_UA | DF_A_WIDE | DF_UB | DF_NULL_CHK_2,

  // F7 IPUT_OBJECT_QUICK
  DF_UA | DF_UB | DF_NULL_CHK_1,

  // F8 INVOKE_VIRTUAL_QUICK
  DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,

  // F9 INVOKE_VIRTUAL_QUICK_RANGE
  DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,

  // FA INVOKE_SUPER_QUICK
  DF_FORMAT_35C | DF_NULL_CHK_OUT0 | DF_UMS,

  // FB INVOKE_SUPER_QUICK_RANGE
  DF_FORMAT_3RC | DF_NULL_CHK_OUT0 | DF_UMS,

  // FC IPUT_OBJECT_VOLATILE
  DF_UA | DF_UB | DF_NULL_CHK_1 | DF_REF_A | DF_REF_B,

  // FD SGET_OBJECT_VOLATILE
  DF_DA | DF_REF_A | DF_UMS,

  // FE SPUT_OBJECT_VOLATILE
  DF_UA | DF_REF_A | DF_UMS,

  // FF UNUSED_FF
  DF_NOP,

  // Beginning of extended MIR opcodes
  // 100 MIR_PHI
  DF_DA | DF_NULL_TRANSFER_N,

  // 101 MIR_COPY
  DF_DA | DF_UB | DF_IS_MOVE,

  // 102 MIR_FUSED_CMPL_FLOAT
  DF_UA | DF_UB | DF_FP_A | DF_FP_B,

  // 103 MIR_FUSED_CMPG_FLOAT
  DF_UA | DF_UB | DF_FP_A | DF_FP_B,

  // 104 MIR_FUSED_CMPL_DOUBLE
  DF_UA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,

  // 105 MIR_FUSED_CMPG_DOUBLE
  DF_UA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_FP_A | DF_FP_B,

  // 106 MIR_FUSED_CMP_LONG
  DF_UA | DF_A_WIDE | DF_UB | DF_B_WIDE | DF_CORE_A | DF_CORE_B,

  // 107 MIR_NOP
  DF_NOP,

  // 108 MIR_NULL_RANGE_UP_CHECK
  0,

  // 109 MIR_NULL_RANGE_DOWN_CHECK
  0,

  // 110 MIR_LOWER_BOUND
  0,
};

/* Return the base virtual register for a SSA name */
int SRegToVReg(const CompilationUnit* cUnit, int ssaReg)
{
  DCHECK_LT(ssaReg, (int)cUnit->ssaBaseVRegs->numUsed);
  return GET_ELEM_N(cUnit->ssaBaseVRegs, int, ssaReg);
}

int SRegToSubscript(const CompilationUnit* cUnit, int ssaReg)
{
  DCHECK(ssaReg < (int)cUnit->ssaSubscripts->numUsed);
  return GET_ELEM_N(cUnit->ssaSubscripts, int, ssaReg);
}

int getSSAUseCount(CompilationUnit* cUnit, int sReg)
{
  DCHECK(sReg < (int)cUnit->rawUseCounts.numUsed);
  return cUnit->rawUseCounts.elemList[sReg];
}


char* oatGetDalvikDisassembly(CompilationUnit* cUnit,
                              const DecodedInstruction& insn, const char* note)
{
  char buffer[256];
  Instruction::Code opcode = insn.opcode;
  int dfAttributes = oatDataFlowAttributes[opcode];
  int flags;
  char* ret;

  buffer[0] = 0;
  if ((int)opcode >= (int)kMirOpFirst) {
    if ((int)opcode == (int)kMirOpPhi) {
      strcpy(buffer, "PHI");
    } else {
      sprintf(buffer, "Opcode %#x", opcode);
    }
    flags = 0;
  } else {
    strcpy(buffer, Instruction::Name(opcode));
    flags = Instruction::Flags(opcode);
  }

  if (note)
    strcat(buffer, note);

  /* For branches, decode the instructions to print out the branch targets */
  if (flags & Instruction::kBranch) {
    Instruction::Format dalvikFormat = Instruction::FormatOf(insn.opcode);
    int offset = 0;
    switch (dalvikFormat) {
      case Instruction::k21t:
        snprintf(buffer + strlen(buffer), 256, " v%d,", insn.vA);
        offset = (int) insn.vB;
        break;
      case Instruction::k22t:
        snprintf(buffer + strlen(buffer), 256, " v%d, v%d,", insn.vA, insn.vB);
        offset = (int) insn.vC;
        break;
      case Instruction::k10t:
      case Instruction::k20t:
      case Instruction::k30t:
        offset = (int) insn.vA;
        break;
      default:
        LOG(FATAL) << "Unexpected branch format " << (int)dalvikFormat
                   << " / opcode " << (int)opcode;
    }
    snprintf(buffer + strlen(buffer), 256, " (%c%x)",
             offset > 0 ? '+' : '-',
             offset > 0 ? offset : -offset);
  } else if (dfAttributes & DF_FORMAT_35C) {
    unsigned int i;
    for (i = 0; i < insn.vA; i++) {
      if (i != 0) strcat(buffer, ",");
        snprintf(buffer + strlen(buffer), 256, " v%d", insn.arg[i]);
    }
  }
  else if (dfAttributes & DF_FORMAT_3RC) {
    snprintf(buffer + strlen(buffer), 256,
             " v%d..v%d", insn.vC, insn.vC + insn.vA - 1);
  } else {
    if (dfAttributes & DF_A_IS_REG) {
      snprintf(buffer + strlen(buffer), 256, " v%d", insn.vA);
    }
    if (dfAttributes & DF_B_IS_REG) {
      snprintf(buffer + strlen(buffer), 256, ", v%d", insn.vB);
    } else if ((int)opcode < (int)kMirOpFirst) {
      snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn.vB);
    }
    if (dfAttributes & DF_C_IS_REG) {
      snprintf(buffer + strlen(buffer), 256, ", v%d", insn.vC);
    } else if ((int)opcode < (int)kMirOpFirst) {
      snprintf(buffer + strlen(buffer), 256, ", (#%d)", insn.vC);
    }
  }
  int length = strlen(buffer) + 1;
  ret = (char*)oatNew(cUnit, length, false, kAllocDFInfo);
  memcpy(ret, buffer, length);
  return ret;
}

char* getSSAName(const CompilationUnit* cUnit, int ssaReg, char* name)
{
  sprintf(name, "v%d_%d", SRegToVReg(cUnit, ssaReg),
          SRegToSubscript(cUnit, ssaReg));
  return name;
}

/*
 * Dalvik instruction disassembler with optional SSA printing.
 */
char* oatFullDisassembler(CompilationUnit* cUnit, const MIR* mir)
{
  char buffer[256];
  char operand0[32], operand1[32];
  const DecodedInstruction* insn = &mir->dalvikInsn;
  Instruction::Code opcode = insn->opcode;
  int dfAttributes = oatDataFlowAttributes[opcode];
  char* ret;
  int length;

  buffer[0] = 0;
  if (static_cast<int>(opcode) >= static_cast<int>(kMirOpFirst)) {
    if (static_cast<int>(opcode) == static_cast<int>(kMirOpPhi)) {
      snprintf(buffer, 256, "PHI %s = (%s",
               getSSAName(cUnit, mir->ssaRep->defs[0], operand0),
               getSSAName(cUnit, mir->ssaRep->uses[0], operand1));
      int i;
      for (i = 1; i < mir->ssaRep->numUses; i++) {
        snprintf(buffer + strlen(buffer), 256, ", %s",
        getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
      }
      snprintf(buffer + strlen(buffer), 256, ")");
    } else {
      sprintf(buffer, "Opcode %#x", opcode);
    }
    goto done;
  } else {
    strcpy(buffer, Instruction::Name(opcode));
  }

  /* For branches, decode the instructions to print out the branch targets */
  if (Instruction::Flags(insn->opcode) & Instruction::kBranch) {
    Instruction::Format dalvikFormat = Instruction::FormatOf(insn->opcode);
    int delta = 0;
    switch (dalvikFormat) {
      case Instruction::k21t:
        snprintf(buffer + strlen(buffer), 256, " %s, ",
                 getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
        delta = (int) insn->vB;
        break;
      case Instruction::k22t:
        snprintf(buffer + strlen(buffer), 256, " %s, %s, ",
                 getSSAName(cUnit, mir->ssaRep->uses[0], operand0),
                 getSSAName(cUnit, mir->ssaRep->uses[1], operand1));
        delta = (int) insn->vC;
        break;
      case Instruction::k10t:
      case Instruction::k20t:
      case Instruction::k30t:
        delta = (int) insn->vA;
        break;
      default:
        LOG(FATAL) << "Unexpected branch format: " << (int)dalvikFormat;
      }
      snprintf(buffer + strlen(buffer), 256, " %04x",
               mir->offset + delta);
  } else if (dfAttributes & (DF_FORMAT_35C | DF_FORMAT_3RC)) {
    unsigned int i;
    for (i = 0; i < insn->vA; i++) {
      if (i != 0) strcat(buffer, ",");
        snprintf(buffer + strlen(buffer), 256, " %s",
                 getSSAName(cUnit, mir->ssaRep->uses[i], operand0));
    }
  } else {
    int udIdx;
    if (mir->ssaRep->numDefs) {

      for (udIdx = 0; udIdx < mir->ssaRep->numDefs; udIdx++) {
        snprintf(buffer + strlen(buffer), 256, " %s",
                 getSSAName(cUnit, mir->ssaRep->defs[udIdx], operand0));
      }
      strcat(buffer, ",");
    }
    if (mir->ssaRep->numUses) {
      /* No leading ',' for the first use */
      snprintf(buffer + strlen(buffer), 256, " %s",
               getSSAName(cUnit, mir->ssaRep->uses[0], operand0));
      for (udIdx = 1; udIdx < mir->ssaRep->numUses; udIdx++) {
        snprintf(buffer + strlen(buffer), 256, ", %s",
                 getSSAName(cUnit, mir->ssaRep->uses[udIdx], operand0));
        }
      }
      if (static_cast<int>(opcode) < static_cast<int>(kMirOpFirst)) {
        Instruction::Format dalvikFormat = Instruction::FormatOf(opcode);
        switch (dalvikFormat) {
          case Instruction::k11n:        // op vA, #+B
          case Instruction::k21s:        // op vAA, #+BBBB
          case Instruction::k21h:        // op vAA, #+BBBB00000[00000000]
          case Instruction::k31i:        // op vAA, #+BBBBBBBB
          case Instruction::k51l:        // op vAA, #+BBBBBBBBBBBBBBBB
            snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vB);
            break;
          case Instruction::k21c:        // op vAA, thing@BBBB
          case Instruction::k31c:        // op vAA, thing@BBBBBBBB
            snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vB);
            break;
          case Instruction::k22b:        // op vAA, vBB, #+CC
          case Instruction::k22s:        // op vA, vB, #+CCCC
            snprintf(buffer + strlen(buffer), 256, " #%#x", insn->vC);
            break;
          case Instruction::k22c:        // op vA, vB, thing@CCCC
            snprintf(buffer + strlen(buffer), 256, " @%#x", insn->vC);
            break;
          /* No need for special printing */
          default:
            break;
        }
     }
  }

done:
  length = strlen(buffer) + 1;
  ret = (char*) oatNew(cUnit, length, false, kAllocDFInfo);
  memcpy(ret, buffer, length);
  return ret;
}

char* oatGetSSAString(CompilationUnit* cUnit, SSARepresentation* ssaRep)
{
  char buffer[256];
  char* ret;
  int i;

  buffer[0] = 0;
  for (i = 0; i < ssaRep->numDefs; i++) {
    int ssaReg = ssaRep->defs[i];
    sprintf(buffer + strlen(buffer), "s%d(v%d_%d) ", ssaReg,
            SRegToVReg(cUnit, ssaReg), SRegToSubscript(cUnit, ssaReg));
  }

  if (ssaRep->numDefs) {
    strcat(buffer, "<- ");
  }

  for (i = 0; i < ssaRep->numUses; i++) {
    int len = strlen(buffer);
    int ssaReg = ssaRep->uses[i];

    if (snprintf(buffer + len, 250 - len, "s%d(v%d_%d) ", ssaReg,
                 SRegToVReg(cUnit, ssaReg),
                 SRegToSubscript(cUnit, ssaReg))) {
      strcat(buffer, "...");
      break;
    }
  }

  int length = strlen(buffer) + 1;
  ret = (char*)oatNew(cUnit, length, false, kAllocDFInfo);
  memcpy(ret, buffer, length);
  return ret;
}

/* Any register that is used before being defined is considered live-in */
inline void handleLiveInUse(CompilationUnit* cUnit, ArenaBitVector* useV,
                            ArenaBitVector* defV, ArenaBitVector* liveInV,
                            int dalvikRegId)
{
  oatSetBit(cUnit, useV, dalvikRegId);
  if (!oatIsBitSet(defV, dalvikRegId)) {
    oatSetBit(cUnit, liveInV, dalvikRegId);
  }
}

/* Mark a reg as being defined */
inline void handleDef(CompilationUnit* cUnit, ArenaBitVector* defV,
                      int dalvikRegId)
{
  oatSetBit(cUnit, defV, dalvikRegId);
}

/*
 * Find out live-in variables for natural loops. Variables that are live-in in
 * the main loop body are considered to be defined in the entry block.
 */
bool oatFindLocalLiveIn(CompilationUnit* cUnit, BasicBlock* bb)
{
  MIR* mir;
  ArenaBitVector *useV, *defV, *liveInV;

  if (bb->dataFlowInfo == NULL) return false;

  useV = bb->dataFlowInfo->useV =
      oatAllocBitVector(cUnit, cUnit->numDalvikRegisters, false, kBitMapUse);
  defV = bb->dataFlowInfo->defV =
      oatAllocBitVector(cUnit, cUnit->numDalvikRegisters, false, kBitMapDef);
  liveInV = bb->dataFlowInfo->liveInV =
      oatAllocBitVector(cUnit, cUnit->numDalvikRegisters, false,
                        kBitMapLiveIn);

  for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
    int dfAttributes = oatDataFlowAttributes[mir->dalvikInsn.opcode];
    DecodedInstruction *dInsn = &mir->dalvikInsn;

    if (dfAttributes & DF_HAS_USES) {
      if (dfAttributes & DF_UA) {
        handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vA);
        if (dfAttributes & DF_A_WIDE) {
          handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vA+1);
        }
      }
      if (dfAttributes & DF_UB) {
        handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vB);
        if (dfAttributes & DF_B_WIDE) {
          handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vB+1);
        }
      }
      if (dfAttributes & DF_UC) {
        handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vC);
        if (dfAttributes & DF_C_WIDE) {
          handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vC+1);
        }
      }
    }
    if (dfAttributes & DF_FORMAT_35C) {
      for (unsigned int i = 0; i < dInsn->vA; i++) {
        handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->arg[i]);
      }
    }
    if (dfAttributes & DF_FORMAT_3RC) {
      for (unsigned int i = 0; i < dInsn->vA; i++) {
        handleLiveInUse(cUnit, useV, defV, liveInV, dInsn->vC+i);
      }
    }
    if (dfAttributes & DF_HAS_DEFS) {
      handleDef(cUnit, defV, dInsn->vA);
      if (dfAttributes & DF_A_WIDE) {
        handleDef(cUnit, defV, dInsn->vA+1);
      }
    }
  }
  return true;
}

int addNewSReg(CompilationUnit* cUnit, int vReg)
{
  // Compiler temps always have a subscript of 0
  int subscript = (vReg < 0) ? 0 : ++cUnit->SSALastDefs[vReg];
  int ssaReg = cUnit->numSSARegs++;
  oatInsertGrowableList(cUnit, cUnit->ssaBaseVRegs, vReg);
  oatInsertGrowableList(cUnit, cUnit->ssaSubscripts, subscript);
  char* name = (char*)oatNew(cUnit, SSA_NAME_MAX, true, kAllocDFInfo);
  oatInsertGrowableList(cUnit, cUnit->ssaStrings, (intptr_t)getSSAName(cUnit, ssaReg, name));
  DCHECK_EQ(cUnit->ssaBaseVRegs->numUsed, cUnit->ssaSubscripts->numUsed);
  return ssaReg;
}

/* Find out the latest SSA register for a given Dalvik register */
void handleSSAUse(CompilationUnit* cUnit, int* uses, int dalvikReg,
                  int regIndex)
{
  DCHECK((dalvikReg >= 0) && (dalvikReg < cUnit->numDalvikRegisters));
  uses[regIndex] = cUnit->vRegToSSAMap[dalvikReg];
}

/* Setup a new SSA register for a given Dalvik register */
void handleSSADef(CompilationUnit* cUnit, int* defs, int dalvikReg,
                  int regIndex)
{
  DCHECK((dalvikReg >= 0) && (dalvikReg < cUnit->numDalvikRegisters));
  int ssaReg = addNewSReg(cUnit, dalvikReg);
  cUnit->vRegToSSAMap[dalvikReg] = ssaReg;
  defs[regIndex] = ssaReg;
}

/* Look up new SSA names for format_35c instructions */
void dataFlowSSAFormat35C(CompilationUnit* cUnit, MIR* mir)
{
  DecodedInstruction *dInsn = &mir->dalvikInsn;
  int numUses = dInsn->vA;
  int i;

  mir->ssaRep->numUses = numUses;
  mir->ssaRep->uses = (int *)oatNew(cUnit, sizeof(int) * numUses, true,
                                    kAllocDFInfo);
  // NOTE: will be filled in during type & size inference pass
  mir->ssaRep->fpUse = (bool *)oatNew(cUnit, sizeof(bool) * numUses, true,
                                      kAllocDFInfo);

  for (i = 0; i < numUses; i++) {
    handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->arg[i], i);
  }
}

/* Look up new SSA names for format_3rc instructions */
void dataFlowSSAFormat3RC(CompilationUnit* cUnit, MIR* mir)
{
  DecodedInstruction *dInsn = &mir->dalvikInsn;
  int numUses = dInsn->vA;
  int i;

  mir->ssaRep->numUses = numUses;
  mir->ssaRep->uses = (int *)oatNew(cUnit, sizeof(int) * numUses, true,
                                    kAllocDFInfo);
  // NOTE: will be filled in during type & size inference pass
  mir->ssaRep->fpUse = (bool *)oatNew(cUnit, sizeof(bool) * numUses, true,
                                      kAllocDFInfo);

  for (i = 0; i < numUses; i++) {
    handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+i, i);
  }
}

/* Entry function to convert a block into SSA representation */
bool oatDoSSAConversion(CompilationUnit* cUnit, BasicBlock* bb)
{
  MIR* mir;

  if (bb->dataFlowInfo == NULL) return false;

  for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
    mir->ssaRep = (struct SSARepresentation *)
        oatNew(cUnit, sizeof(SSARepresentation), true, kAllocDFInfo);

    int dfAttributes = oatDataFlowAttributes[mir->dalvikInsn.opcode];

      // If not a pseudo-op, note non-leaf or can throw
    if (static_cast<int>(mir->dalvikInsn.opcode) <
        static_cast<int>(kNumPackedOpcodes)) {
      int flags = Instruction::Flags(mir->dalvikInsn.opcode);

      if (flags & Instruction::kThrow) {
        cUnit->attrs &= ~METHOD_IS_THROW_FREE;
      }

      if (flags & Instruction::kInvoke) {
        cUnit->attrs &= ~METHOD_IS_LEAF;
      }
    }

    int numUses = 0;

    if (dfAttributes & DF_FORMAT_35C) {
      dataFlowSSAFormat35C(cUnit, mir);
      continue;
    }

    if (dfAttributes & DF_FORMAT_3RC) {
      dataFlowSSAFormat3RC(cUnit, mir);
      continue;
    }

    if (dfAttributes & DF_HAS_USES) {
      if (dfAttributes & DF_UA) {
        numUses++;
        if (dfAttributes & DF_A_WIDE) {
          numUses ++;
        }
      }
      if (dfAttributes & DF_UB) {
        numUses++;
        if (dfAttributes & DF_B_WIDE) {
          numUses ++;
        }
      }
      if (dfAttributes & DF_UC) {
        numUses++;
        if (dfAttributes & DF_C_WIDE) {
          numUses ++;
        }
      }
    }

    if (numUses) {
      mir->ssaRep->numUses = numUses;
      mir->ssaRep->uses = (int *)oatNew(cUnit, sizeof(int) * numUses,
                                        false, kAllocDFInfo);
      mir->ssaRep->fpUse = (bool *)oatNew(cUnit, sizeof(bool) * numUses,
                                          false, kAllocDFInfo);
    }

    int numDefs = 0;

    if (dfAttributes & DF_HAS_DEFS) {
      numDefs++;
      if (dfAttributes & DF_A_WIDE) {
        numDefs++;
      }
    }

    if (numDefs) {
      mir->ssaRep->numDefs = numDefs;
      mir->ssaRep->defs = (int *)oatNew(cUnit, sizeof(int) * numDefs,
                                        false, kAllocDFInfo);
      mir->ssaRep->fpDef = (bool *)oatNew(cUnit, sizeof(bool) * numDefs,
                                          false, kAllocDFInfo);
    }

    DecodedInstruction *dInsn = &mir->dalvikInsn;

    if (dfAttributes & DF_HAS_USES) {
      numUses = 0;
      if (dfAttributes & DF_UA) {
        mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
        handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA, numUses++);
        if (dfAttributes & DF_A_WIDE) {
          mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_A;
          handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vA+1, numUses++);
        }
      }
      if (dfAttributes & DF_UB) {
        mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
        handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB, numUses++);
        if (dfAttributes & DF_B_WIDE) {
          mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_B;
          handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vB+1, numUses++);
        }
      }
      if (dfAttributes & DF_UC) {
        mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
        handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC, numUses++);
        if (dfAttributes & DF_C_WIDE) {
          mir->ssaRep->fpUse[numUses] = dfAttributes & DF_FP_C;
          handleSSAUse(cUnit, mir->ssaRep->uses, dInsn->vC+1, numUses++);
        }
      }
    }
    if (dfAttributes & DF_HAS_DEFS) {
      mir->ssaRep->fpDef[0] = dfAttributes & DF_FP_A;
      handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA, 0);
      if (dfAttributes & DF_A_WIDE) {
        mir->ssaRep->fpDef[1] = dfAttributes & DF_FP_A;
        handleSSADef(cUnit, mir->ssaRep->defs, dInsn->vA+1, 1);
      }
    }
  }

  if (!cUnit->disableDataflow) {
    /*
     * Take a snapshot of Dalvik->SSA mapping at the end of each block. The
     * input to PHI nodes can be derived from the snapshot of all
     * predecessor blocks.
     */
    bb->dataFlowInfo->vRegToSSAMap =
        (int *)oatNew(cUnit, sizeof(int) * cUnit->numDalvikRegisters, false,
                      kAllocDFInfo);

    memcpy(bb->dataFlowInfo->vRegToSSAMap, cUnit->vRegToSSAMap,
           sizeof(int) * cUnit->numDalvikRegisters);
  }
  return true;
}

/* Setup a constant value for opcodes thare have the DF_SETS_CONST attribute */
void setConstant(CompilationUnit* cUnit, int ssaReg, int value)
{
  oatSetBit(cUnit, cUnit->isConstantV, ssaReg);
  cUnit->constantValues[ssaReg] = value;
}

bool oatDoConstantPropagation(CompilationUnit* cUnit, BasicBlock* bb)
{
  MIR* mir;
  ArenaBitVector *isConstantV = cUnit->isConstantV;

  for (mir = bb->firstMIRInsn; mir; mir = mir->next) {
    int dfAttributes = oatDataFlowAttributes[mir->dalvikInsn.opcode];

    DecodedInstruction *dInsn = &mir->dalvikInsn;

    if (!(dfAttributes & DF_HAS_DEFS)) continue;

    /* Handle instructions that set up constants directly */
    if (dfAttributes & DF_SETS_CONST) {
      if (dfAttributes & DF_DA) {
        switch (dInsn->opcode) {
          case Instruction::CONST_4:
          case Instruction::CONST_16:
          case Instruction::CONST:
            setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
            break;
          case Instruction::CONST_HIGH16:
            setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB << 16);
            break;
          case Instruction::CONST_WIDE_16:
          case Instruction::CONST_WIDE_32:
            setConstant(cUnit, mir->ssaRep->defs[0], dInsn->vB);
            setConstant(cUnit, mir->ssaRep->defs[1], 0);
            break;
          case Instruction::CONST_WIDE:
            setConstant(cUnit, mir->ssaRep->defs[0], (int) dInsn->vB_wide);
            setConstant(cUnit, mir->ssaRep->defs[1],
                        (int) (dInsn->vB_wide >> 32));
            break;
          case Instruction::CONST_WIDE_HIGH16:
            setConstant(cUnit, mir->ssaRep->defs[0], 0);
            setConstant(cUnit, mir->ssaRep->defs[1], dInsn->vB << 16);
            break;
          default:
            break;
        }
      }
      /* Handle instructions that set up constants directly */
    } else if (dfAttributes & DF_IS_MOVE) {
      int i;

      for (i = 0; i < mir->ssaRep->numUses; i++) {
        if (!oatIsBitSet(isConstantV, mir->ssaRep->uses[i])) break;
      }
      /* Move a register holding a constant to another register */
      if (i == mir->ssaRep->numUses) {
        setConstant(cUnit, mir->ssaRep->defs[0],
                    cUnit->constantValues[mir->ssaRep->uses[0]]);
        if (dfAttributes & DF_A_WIDE) {
          setConstant(cUnit, mir->ssaRep->defs[1],
                      cUnit->constantValues[mir->ssaRep->uses[1]]);
        }
      }
    }
  }
  /* TODO: implement code to handle arithmetic operations */
  return true;
}

/* Setup the basic data structures for SSA conversion */
void oatInitializeSSAConversion(CompilationUnit* cUnit)
{
  int i;
  int numDalvikReg = cUnit->numDalvikRegisters;

  cUnit->ssaBaseVRegs = (GrowableList *)oatNew(cUnit, sizeof(GrowableList),
                                               false, kAllocDFInfo);
  cUnit->ssaSubscripts = (GrowableList *)oatNew(cUnit, sizeof(GrowableList),
                                                false, kAllocDFInfo);
  cUnit->ssaStrings = (GrowableList *)oatNew(cUnit, sizeof(GrowableList),
                                             false, kAllocDFInfo);
  // Create the ssa mappings, estimating the max size
  oatInitGrowableList(cUnit, cUnit->ssaBaseVRegs,
                      numDalvikReg + cUnit->defCount + 128,
                      kListSSAtoDalvikMap);
  oatInitGrowableList(cUnit, cUnit->ssaSubscripts,
                      numDalvikReg + cUnit->defCount + 128,
                      kListSSAtoDalvikMap);
  oatInitGrowableList(cUnit, cUnit->ssaStrings,
                      numDalvikReg + cUnit->defCount + 128,
                      kListSSAtoDalvikMap);
  /*
   * Initial number of SSA registers is equal to the number of Dalvik
   * registers.
   */
  cUnit->numSSARegs = numDalvikReg;

  /*
   * Initialize the SSA2Dalvik map list. For the first numDalvikReg elements,
   * the subscript is 0 so we use the ENCODE_REG_SUB macro to encode the value
   * into "(0 << 16) | i"
   */
  for (i = 0; i < numDalvikReg; i++) {
    oatInsertGrowableList(cUnit, cUnit->ssaBaseVRegs, i);
    oatInsertGrowableList(cUnit, cUnit->ssaSubscripts, 0);
    char* name = (char*)oatNew(cUnit, SSA_NAME_MAX, true, kAllocDFInfo);
    oatInsertGrowableList(cUnit, cUnit->ssaStrings, (intptr_t)getSSAName(cUnit, i, name));
  }

  /*
   * Initialize the DalvikToSSAMap map. There is one entry for each
   * Dalvik register, and the SSA names for those are the same.
   */
  cUnit->vRegToSSAMap = (int *)oatNew(cUnit, sizeof(int) * numDalvikReg,
                                      false, kAllocDFInfo);
  /* Keep track of the higest def for each dalvik reg */
  cUnit->SSALastDefs = (int *)oatNew(cUnit, sizeof(int) * numDalvikReg,
                                     false, kAllocDFInfo);

  for (i = 0; i < numDalvikReg; i++) {
    cUnit->vRegToSSAMap[i] = i;
    cUnit->SSALastDefs[i] = 0;
  }

  /* Add ssa reg for Method* */
  cUnit->methodSReg = addNewSReg(cUnit, SSA_METHOD_BASEREG);

  /*
   * Allocate the BasicBlockDataFlow structure for the entry and code blocks
   */
  GrowableListIterator iterator;

  oatGrowableListIteratorInit(&cUnit->blockList, &iterator);

  while (true) {
    BasicBlock* bb = (BasicBlock *) oatGrowableListIteratorNext(&iterator);
    if (bb == NULL) break;
    if (bb->hidden == true) continue;
    if (bb->blockType == kDalvikByteCode ||
      bb->blockType == kEntryBlock ||
      bb->blockType == kExitBlock) {
      bb->dataFlowInfo = (BasicBlockDataFlow *)
          oatNew(cUnit, sizeof(BasicBlockDataFlow), true, kAllocDFInfo);
      }
  }
}

/* Clear the visited flag for each BB */
bool oatClearVisitedFlag(struct CompilationUnit* cUnit, struct BasicBlock* bb)
{
  bb->visited = false;
  return true;
}

void oatDataFlowAnalysisDispatcher(CompilationUnit* cUnit,
                                   bool (*func)(CompilationUnit*, BasicBlock*),
                                   DataFlowAnalysisMode dfaMode,
                                   bool isIterative)
{
  bool change = true;

  while (change) {
    change = false;

    switch (dfaMode) {
      /* Scan all blocks and perform the operations specified in func */
      case kAllNodes:
        {
          GrowableListIterator iterator;
          oatGrowableListIteratorInit(&cUnit->blockList, &iterator);
          while (true) {
            BasicBlock* bb =
                (BasicBlock *) oatGrowableListIteratorNext(&iterator);
            if (bb == NULL) break;
            if (bb->hidden == true) continue;
              change |= (*func)(cUnit, bb);
          }
        }
        break;
      /* Scan reachable blocks and perform the ops specified in func. */
      case kReachableNodes:
        {
          int numReachableBlocks = cUnit->numReachableBlocks;
          int idx;
          const GrowableList *blockList = &cUnit->blockList;

          for (idx = 0; idx < numReachableBlocks; idx++) {
            int blockIdx = cUnit->dfsOrder.elemList[idx];
            BasicBlock* bb = (BasicBlock *)
                oatGrowableListGetElement(blockList, blockIdx);
            change |= (*func)(cUnit, bb);
          }
        }
        break;

      /* Scan reachable blocks by pre-order dfs and invoke func on each. */
      case kPreOrderDFSTraversal:
        {
          int numReachableBlocks = cUnit->numReachableBlocks;
          int idx;
          const GrowableList *blockList = &cUnit->blockList;

          for (idx = 0; idx < numReachableBlocks; idx++) {
            int dfsIdx = cUnit->dfsOrder.elemList[idx];
            BasicBlock* bb = (BasicBlock *)
                oatGrowableListGetElement(blockList, dfsIdx);
            change |= (*func)(cUnit, bb);
            }
        }
        break;
      /* Scan reachable blocks post-order dfs and invoke func on each. */
      case kPostOrderDFSTraversal:
        {
          int numReachableBlocks = cUnit->numReachableBlocks;
          int idx;
          const GrowableList *blockList = &cUnit->blockList;

          for (idx = numReachableBlocks - 1; idx >= 0; idx--) {
            int dfsIdx = cUnit->dfsOrder.elemList[idx];
            BasicBlock* bb = (BasicBlock *)
                oatGrowableListGetElement(blockList, dfsIdx);
            change |= (*func)(cUnit, bb);
            }
        }
        break;
      /* Scan reachable post-order dom tree and invoke func on each. */
      case kPostOrderDOMTraversal:
        {
          int numReachableBlocks = cUnit->numReachableBlocks;
          int idx;
          const GrowableList *blockList = &cUnit->blockList;

          for (idx = 0; idx < numReachableBlocks; idx++) {
            int domIdx = cUnit->domPostOrderTraversal.elemList[idx];
            BasicBlock* bb = (BasicBlock *)
                oatGrowableListGetElement(blockList, domIdx);
            change |= (*func)(cUnit, bb);
          }
        }
        break;
      /* Scan reachable blocks reverse post-order dfs, invoke func on each */
      case kReversePostOrderTraversal:
        {
          int numReachableBlocks = cUnit->numReachableBlocks;
          int idx;
          const GrowableList *blockList = &cUnit->blockList;

          for (idx = numReachableBlocks - 1; idx >= 0; idx--) {
            int revIdx = cUnit->dfsPostOrder.elemList[idx];
            BasicBlock* bb = (BasicBlock *)
                oatGrowableListGetElement(blockList, revIdx);
            change |= (*func)(cUnit, bb);
            }
        }
        break;
      default:
        LOG(FATAL) << "Unknown traversal mode " << (int)dfaMode;
    }
    /* If isIterative is false, exit the loop after the first iteration */
    change &= isIterative;
  }
}

/* Advance to next strictly dominated MIR node in an extended basic block */
MIR* advanceMIR(CompilationUnit* cUnit, BasicBlock** pBb, MIR* mir,
                ArenaBitVector* bv, bool clearMark) {
  BasicBlock* bb = *pBb;
  if (mir != NULL) {
    mir = mir->next;
    if (mir == NULL) {
      bb = bb->fallThrough;
      if ((bb == NULL) || bb->predecessors->numUsed != 1) {
        mir = NULL;
      } else {
        if (bv) {
          oatSetBit(cUnit, bv, bb->id);
        }
      *pBb = bb;
      mir = bb->firstMIRInsn;
      }
    }
  }
  if (mir && clearMark) {
    mir->optimizationFlags &= ~MIR_MARK;
  }
  return mir;
}

/*
 * To be used at an invoke mir.  If the logically next mir node represents
 * a move-result, return it.  Else, return NULL.  If a move-result exists,
 * it is required to immediately follow the invoke with no intervening
 * opcodes or incoming arcs.  However, if the result of the invoke is not
 * used, a move-result may not be present.
 */
MIR* oatFindMoveResult(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
                     bool wide)
{
  BasicBlock* tbb = bb;
  mir = advanceMIR(cUnit, &tbb, mir, NULL, false);
  while (mir != NULL) {
    if (!wide && mir->dalvikInsn.opcode == Instruction::MOVE_RESULT) {
      break;
    }
    if (wide && mir->dalvikInsn.opcode == Instruction::MOVE_RESULT_WIDE) {
      break;
    }
    // Keep going if pseudo op, otherwise terminate
    if (mir->dalvikInsn.opcode <
        static_cast<Instruction::Code>(kNumPackedOpcodes)) {
      mir = NULL;
    } else {
      mir = advanceMIR(cUnit, &tbb, mir, NULL, false);
    }
  }
  return mir;
}

void squashDupRangeChecks(CompilationUnit* cUnit, BasicBlock** pBp, MIR* mir,
                        int arraySreg, int indexSreg)
{
  while (true) {
    mir = advanceMIR(cUnit, pBp, mir, NULL, false);
    if (!mir) {
      break;
    }
    if ((mir->ssaRep == NULL) ||
        (mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
       continue;
    }
    int checkArray = INVALID_SREG;
    int checkIndex = INVALID_SREG;
    switch (mir->dalvikInsn.opcode) {
      case Instruction::AGET:
      case Instruction::AGET_OBJECT:
      case Instruction::AGET_BOOLEAN:
      case Instruction::AGET_BYTE:
      case Instruction::AGET_CHAR:
      case Instruction::AGET_SHORT:
      case Instruction::AGET_WIDE:
        checkArray = mir->ssaRep->uses[0];
        checkIndex = mir->ssaRep->uses[1];
        break;
      case Instruction::APUT:
      case Instruction::APUT_OBJECT:
      case Instruction::APUT_SHORT:
      case Instruction::APUT_CHAR:
      case Instruction::APUT_BYTE:
      case Instruction::APUT_BOOLEAN:
        checkArray = mir->ssaRep->uses[1];
        checkIndex = mir->ssaRep->uses[2];
        break;
      case Instruction::APUT_WIDE:
        checkArray = mir->ssaRep->uses[2];
        checkIndex = mir->ssaRep->uses[3];
      default:
        break;
    }
    if (checkArray == INVALID_SREG) {
      continue;
    }
    if ((arraySreg == checkArray) && (indexSreg == checkIndex)) {
      if (cUnit->printMe) {
        LOG(INFO) << "Squashing range check @ 0x" << std::hex << mir->offset;
      }
      mir->optimizationFlags |= MIR_IGNORE_RANGE_CHECK;
    }
  }
}

/* Allocate a compiler temp, return Sreg.  Reuse existing if no conflict */
int allocCompilerTempSreg(CompilationUnit* cUnit, ArenaBitVector* bv)
{
  for (int i = 0; i < cUnit->numCompilerTemps; i++) {
    CompilerTemp* ct = (CompilerTemp*)cUnit->compilerTemps.elemList[i];
    ArenaBitVector* tBv = ct->bv;
    if (!oatTestBitVectors(bv, tBv)) {
      // Combine live maps and reuse existing temp
      oatUnifyBitVectors(tBv, tBv, bv);
      return ct->sReg;
    }
  }

  // Create a new compiler temp & associated live bitmap
  CompilerTemp* ct = (CompilerTemp*)oatNew(cUnit, sizeof(CompilerTemp),
                                           true, kAllocMisc);
  ArenaBitVector *nBv = oatAllocBitVector(cUnit, cUnit->numBlocks, true,
                                          kBitMapMisc);
  oatCopyBitVector(nBv, bv);
  ct->bv = nBv;
  ct->sReg = addNewSReg(cUnit, SSA_CTEMP_BASEREG - cUnit->numCompilerTemps);
  cUnit->numCompilerTemps++;
  oatInsertGrowableList(cUnit, &cUnit->compilerTemps, (intptr_t)ct);
  DCHECK_EQ(cUnit->numCompilerTemps, (int)cUnit->compilerTemps.numUsed);
  return ct->sReg;
}

/* Creata a new MIR node for a new pseudo op. */
MIR* rawMIR(CompilationUnit* cUnit, Instruction::Code opcode, int defs,
            int uses)
{
  MIR* res = (MIR*)oatNew( cUnit, sizeof(MIR), true, kAllocMIR);
  res->ssaRep =(struct SSARepresentation *)
      oatNew(cUnit, sizeof(SSARepresentation), true, kAllocDFInfo);
  if (uses) {
    res->ssaRep->numUses = uses;
    res->ssaRep->uses = (int*)oatNew(cUnit, sizeof(int) * uses, false,
                                     kAllocDFInfo);
  }
  if (defs) {
    res->ssaRep->numDefs = defs;
    res->ssaRep->defs = (int*)oatNew(cUnit, sizeof(int) * defs, false,
                                     kAllocDFInfo);
    res->ssaRep->fpDef = (bool*)oatNew(cUnit, sizeof(bool) * defs, true,
                                       kAllocDFInfo);
  }
  res->dalvikInsn.opcode = opcode;
  return res;
}

/* Do some MIR-level basic block optimizations */
bool basicBlockOpt(CompilationUnit* cUnit, BasicBlock* bb)
{
  int numTemps = 0;

  for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
    // Look for interesting opcodes, skip otherwise
    Instruction::Code opcode = mir->dalvikInsn.opcode;
    switch (opcode) {
      case Instruction::AGET:
      case Instruction::AGET_OBJECT:
      case Instruction::AGET_BOOLEAN:
      case Instruction::AGET_BYTE:
      case Instruction::AGET_CHAR:
      case Instruction::AGET_SHORT:
      case Instruction::AGET_WIDE:
        if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
          int arrSreg = mir->ssaRep->uses[0];
          int idxSreg = mir->ssaRep->uses[1];
          BasicBlock* tbb = bb;
          squashDupRangeChecks(cUnit, &tbb, mir, arrSreg, idxSreg);
        }
        break;
      case Instruction::APUT:
      case Instruction::APUT_OBJECT:
      case Instruction::APUT_SHORT:
      case Instruction::APUT_CHAR:
      case Instruction::APUT_BYTE:
      case Instruction::APUT_BOOLEAN:
      case Instruction::APUT_WIDE:
        if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
          int start = (opcode == Instruction::APUT_WIDE) ? 2 : 1;
          int arrSreg = mir->ssaRep->uses[start];
          int idxSreg = mir->ssaRep->uses[start + 1];
          BasicBlock* tbb = bb;
          squashDupRangeChecks(cUnit, &tbb, mir, arrSreg, idxSreg);
        }
        break;
      case Instruction::CMPL_FLOAT:
      case Instruction::CMPL_DOUBLE:
      case Instruction::CMPG_FLOAT:
      case Instruction::CMPG_DOUBLE:
      case Instruction::CMP_LONG:
        if (mir->next != NULL) {
          MIR* mirNext = mir->next;
          Instruction::Code brOpcode = mirNext->dalvikInsn.opcode;
          ConditionCode ccode = kCondNv;
          switch(brOpcode) {
            case Instruction::IF_EQZ:
              ccode = kCondEq;
              break;
            case Instruction::IF_NEZ:
              ccode = kCondNe;
              break;
            case Instruction::IF_LTZ:
              ccode = kCondLt;
              break;
            case Instruction::IF_GEZ:
              ccode = kCondGe;
              break;
            case Instruction::IF_GTZ:
              ccode = kCondGt;
              break;
            case Instruction::IF_LEZ:
              ccode = kCondLe;
              break;
            default:
              break;
          }
          // Make sure result of cmp is used by next insn and nowhere else
          if ((ccode != kCondNv) &&
              (mir->ssaRep->defs[0] == mirNext->ssaRep->uses[0]) &&
              (getSSAUseCount(cUnit, mir->ssaRep->defs[0]) == 1)) {
            mirNext->dalvikInsn.arg[0] = ccode;
            switch(opcode) {
              case Instruction::CMPL_FLOAT:
                mirNext->dalvikInsn.opcode =
                    static_cast<Instruction::Code>(kMirOpFusedCmplFloat);
                break;
              case Instruction::CMPL_DOUBLE:
                mirNext->dalvikInsn.opcode =
                    static_cast<Instruction::Code>(kMirOpFusedCmplDouble);
                break;
              case Instruction::CMPG_FLOAT:
                mirNext->dalvikInsn.opcode =
                    static_cast<Instruction::Code>(kMirOpFusedCmpgFloat);
                break;
              case Instruction::CMPG_DOUBLE:
                mirNext->dalvikInsn.opcode =
                    static_cast<Instruction::Code>(kMirOpFusedCmpgDouble);
                break;
              case Instruction::CMP_LONG:
                mirNext->dalvikInsn.opcode =
                    static_cast<Instruction::Code>(kMirOpFusedCmpLong);
                break;
              default: LOG(ERROR) << "Unexpected opcode: " << (int)opcode;
            }
            mir->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
            mirNext->ssaRep->numUses = mir->ssaRep->numUses;
            mirNext->ssaRep->uses = mir->ssaRep->uses;
            mirNext->ssaRep->fpUse = mir->ssaRep->fpUse;
            mirNext->ssaRep->numDefs = 0;
            mir->ssaRep->numUses = 0;
            mir->ssaRep->numDefs = 0;
          }
        }
        break;
      default:
        break;
    }
  }

  if (numTemps > cUnit->numCompilerTemps) {
    cUnit->numCompilerTemps = numTemps;
  }
  return true;
}

bool nullCheckEliminationInit(struct CompilationUnit* cUnit,
                              struct BasicBlock* bb)
{
  if (bb->dataFlowInfo == NULL) return false;
  bb->dataFlowInfo->endingNullCheckV =
      oatAllocBitVector(cUnit, cUnit->numSSARegs, false, kBitMapNullCheck);
  oatClearAllBits(bb->dataFlowInfo->endingNullCheckV);
  return true;
}

/* Eliminate unnecessary null checks for a basic block. */
bool eliminateNullChecks( struct CompilationUnit* cUnit, struct BasicBlock* bb)
{
  if (bb->dataFlowInfo == NULL) return false;

  /*
   * Set initial state.  Be conservative with catch
   * blocks and start with no assumptions about null check
   * status (except for "this").
   */
  if ((bb->blockType == kEntryBlock) | bb->catchEntry) {
    oatClearAllBits(cUnit->tempSSARegisterV);
    if ((cUnit->access_flags & kAccStatic) == 0) {
      // If non-static method, mark "this" as non-null
      int thisReg = cUnit->numDalvikRegisters - cUnit->numIns;
      oatSetBit(cUnit, cUnit->tempSSARegisterV, thisReg);
    }
  } else {
    // Starting state is intesection of all incoming arcs
    GrowableListIterator iter;
    oatGrowableListIteratorInit(bb->predecessors, &iter);
    BasicBlock* predBB = (BasicBlock*)oatGrowableListIteratorNext(&iter);
    DCHECK(predBB != NULL);
    oatCopyBitVector(cUnit->tempSSARegisterV,
                     predBB->dataFlowInfo->endingNullCheckV);
    while (true) {
      predBB = (BasicBlock*)oatGrowableListIteratorNext(&iter);
      if (!predBB) break;
      if ((predBB->dataFlowInfo == NULL) ||
          (predBB->dataFlowInfo->endingNullCheckV == NULL)) {
        continue;
      }
      oatIntersectBitVectors(cUnit->tempSSARegisterV,
                             cUnit->tempSSARegisterV,
                             predBB->dataFlowInfo->endingNullCheckV);
    }
  }

  // Walk through the instruction in the block, updating as necessary
  for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
    if (mir->ssaRep == NULL) {
        continue;
    }
    int dfAttributes = oatDataFlowAttributes[mir->dalvikInsn.opcode];

    // Mark target of NEW* as non-null
    if (dfAttributes & DF_NON_NULL_DST) {
      oatSetBit(cUnit, cUnit->tempSSARegisterV, mir->ssaRep->defs[0]);
    }

    // Mark non-null returns from invoke-style NEW*
    if (dfAttributes & DF_NON_NULL_RET) {
      MIR* nextMir = mir->next;
      // Next should be an MOVE_RESULT_OBJECT
      if (nextMir &&
          nextMir->dalvikInsn.opcode == Instruction::MOVE_RESULT_OBJECT) {
        // Mark as null checked
        oatSetBit(cUnit, cUnit->tempSSARegisterV, nextMir->ssaRep->defs[0]);
      } else {
        if (nextMir) {
          LOG(WARNING) << "Unexpected opcode following new: "
                       << (int)nextMir->dalvikInsn.opcode;
        } else if (bb->fallThrough) {
          // Look in next basic block
          struct BasicBlock* nextBB = bb->fallThrough;
          for (MIR* tmir = nextBB->firstMIRInsn; tmir;
            tmir =tmir->next) {
            if ((int)tmir->dalvikInsn.opcode >= (int)kMirOpFirst) {
              continue;
            }
            // First non-pseudo should be MOVE_RESULT_OBJECT
            if (tmir->dalvikInsn.opcode == Instruction::MOVE_RESULT_OBJECT) {
              // Mark as null checked
              oatSetBit(cUnit, cUnit->tempSSARegisterV, tmir->ssaRep->defs[0]);
            } else {
              LOG(WARNING) << "Unexpected op after new: "
                           << (int)tmir->dalvikInsn.opcode;
            }
            break;
          }
        }
      }
    }

    /*
     * Propagate nullcheck state on register copies (including
     * Phi pseudo copies.  For the latter, nullcheck state is
     * the "and" of all the Phi's operands.
     */
    if (dfAttributes & (DF_NULL_TRANSFER_0 | DF_NULL_TRANSFER_N)) {
      int tgtSreg = mir->ssaRep->defs[0];
      int operands = (dfAttributes & DF_NULL_TRANSFER_0) ? 1 :
          mir->ssaRep->numUses;
      bool nullChecked = true;
      for (int i = 0; i < operands; i++) {
        nullChecked &= oatIsBitSet(cUnit->tempSSARegisterV,
        mir->ssaRep->uses[i]);
      }
      if (nullChecked) {
        oatSetBit(cUnit, cUnit->tempSSARegisterV, tgtSreg);
      }
    }

    // Already nullchecked?
    if (dfAttributes & DF_HAS_NULL_CHKS) {
      int srcIdx;
      if (dfAttributes & DF_NULL_CHK_1) {
        srcIdx = 1;
      } else if (dfAttributes & DF_NULL_CHK_2) {
        srcIdx = 2;
      } else {
        srcIdx = 0;
      }
      int srcSreg = mir->ssaRep->uses[srcIdx];
        if (oatIsBitSet(cUnit->tempSSARegisterV, srcSreg)) {
          // Eliminate the null check
          mir->optimizationFlags |= MIR_IGNORE_NULL_CHECK;
        } else {
          // Mark sReg as null-checked
          oatSetBit(cUnit, cUnit->tempSSARegisterV, srcSreg);
        }
     }
  }

  // Did anything change?
  bool res = oatCompareBitVectors(bb->dataFlowInfo->endingNullCheckV,
                                  cUnit->tempSSARegisterV);
  if (res) {
    oatCopyBitVector(bb->dataFlowInfo->endingNullCheckV,
                     cUnit->tempSSARegisterV);
  }
  return res;
}

void oatMethodNullCheckElimination(CompilationUnit *cUnit)
{
  if (!(cUnit->disableOpt & (1 << kNullCheckElimination))) {
    DCHECK(cUnit->tempSSARegisterV != NULL);
    oatDataFlowAnalysisDispatcher(cUnit, nullCheckEliminationInit, kAllNodes,
                                  false /* isIterative */);
    oatDataFlowAnalysisDispatcher(cUnit, eliminateNullChecks,
                                  kPreOrderDFSTraversal,
                                  true /* isIterative */);
  }
}

void oatMethodBasicBlockOptimization(CompilationUnit *cUnit)
{
  if (!(cUnit->disableOpt & (1 << kBBOpt))) {
    oatInitGrowableList(cUnit, &cUnit->compilerTemps, 6, kListMisc);
    DCHECK_EQ(cUnit->numCompilerTemps, 0);
    if (!(cUnit->disableOpt & (1 << kBBOpt))) {
      oatDataFlowAnalysisDispatcher(cUnit, basicBlockOpt,
                                    kAllNodes, false /* isIterative */);
    }
  }
}

void addLoopHeader(CompilationUnit* cUnit, BasicBlock* header,
                 BasicBlock* backEdge)
{
  GrowableListIterator iter;
  oatGrowableListIteratorInit(&cUnit->loopHeaders, &iter);
  for (LoopInfo* loop = (LoopInfo*)oatGrowableListIteratorNext(&iter);
      (loop != NULL); loop = (LoopInfo*)oatGrowableListIteratorNext(&iter)) {
    if (loop->header == header) {
      oatInsertGrowableList(cUnit, &loop->incomingBackEdges,
                            (intptr_t)backEdge);
      return;
    }
  }
  LoopInfo* info = (LoopInfo*)oatNew(cUnit, sizeof(LoopInfo), true,
                                     kAllocDFInfo);
  info->header = header;
  oatInitGrowableList(cUnit, &info->incomingBackEdges, 2, kListMisc);
  oatInsertGrowableList(cUnit, &info->incomingBackEdges, (intptr_t)backEdge);
  oatInsertGrowableList(cUnit, &cUnit->loopHeaders, (intptr_t)info);
}

bool findBackEdges(struct CompilationUnit* cUnit, struct BasicBlock* bb)
{
  if ((bb->dataFlowInfo == NULL) || (bb->lastMIRInsn == NULL)) {
    return false;
  }
  Instruction::Code opcode = bb->lastMIRInsn->dalvikInsn.opcode;
  if (Instruction::Flags(opcode) & Instruction::kBranch) {
    if (bb->taken && (bb->taken->startOffset <= bb->startOffset)) {
      DCHECK(bb->dominators != NULL);
      if (oatIsBitSet(bb->dominators, bb->taken->id)) {
        if (cUnit->printMe) {
          LOG(INFO) << "Loop backedge from 0x"
                    << std::hex << bb->lastMIRInsn->offset
                    << " to 0x" << std::hex << bb->taken->startOffset;
        }
        addLoopHeader(cUnit, bb->taken, bb);
      }
    }
  }
  return false;
}

void addBlocksToLoop(CompilationUnit* cUnit, ArenaBitVector* blocks,
                   BasicBlock* bb, int headId)
{
  if (!oatIsBitSet(bb->dominators, headId) ||
    oatIsBitSet(blocks, bb->id)) {
    return;
  }
  oatSetBit(cUnit, blocks, bb->id);
  GrowableListIterator iter;
  oatGrowableListIteratorInit(bb->predecessors, &iter);
  BasicBlock* predBB;
  for (predBB = (BasicBlock*)oatGrowableListIteratorNext(&iter); predBB;
       predBB = (BasicBlock*)oatGrowableListIteratorNext(&iter)) {
    addBlocksToLoop(cUnit, blocks, predBB, headId);
  }
}

void oatDumpLoops(CompilationUnit *cUnit)
{
  GrowableListIterator iter;
  oatGrowableListIteratorInit(&cUnit->loopHeaders, &iter);
  for (LoopInfo* loop = (LoopInfo*)oatGrowableListIteratorNext(&iter);
      (loop != NULL); loop = (LoopInfo*)oatGrowableListIteratorNext(&iter)) {
    LOG(INFO) << "Loop head block id " << loop->header->id
              << ", offset 0x" << std::hex << loop->header->startOffset
              << ", Depth: " << loop->header->nestingDepth;
    GrowableListIterator iter;
    oatGrowableListIteratorInit(&loop->incomingBackEdges, &iter);
    BasicBlock* edgeBB;
    for (edgeBB = (BasicBlock*)oatGrowableListIteratorNext(&iter); edgeBB;
         edgeBB = (BasicBlock*)oatGrowableListIteratorNext(&iter)) {
      LOG(INFO) << "    Backedge block id " << edgeBB->id
                << ", offset 0x" << std::hex << edgeBB->startOffset;
      ArenaBitVectorIterator bIter;
      oatBitVectorIteratorInit(loop->blocks, &bIter);
      for (int bbId = oatBitVectorIteratorNext(&bIter); bbId != -1;
           bbId = oatBitVectorIteratorNext(&bIter)) {
        BasicBlock *bb;
        bb = (BasicBlock*)
            oatGrowableListGetElement(&cUnit->blockList, bbId);
        LOG(INFO) << "        (" << bb->id << ", 0x" << std::hex
                  << bb->startOffset << ")";
      }
    }
  }
}

void oatMethodLoopDetection(CompilationUnit *cUnit)
{
  if (cUnit->disableOpt & (1 << kPromoteRegs)) {
    return;
  }
  oatInitGrowableList(cUnit, &cUnit->loopHeaders, 6, kListMisc);
  // Find the loop headers
  oatDataFlowAnalysisDispatcher(cUnit, findBackEdges,
                                kAllNodes, false /* isIterative */);
  GrowableListIterator iter;
  oatGrowableListIteratorInit(&cUnit->loopHeaders, &iter);
  // Add blocks to each header
  for (LoopInfo* loop = (LoopInfo*)oatGrowableListIteratorNext(&iter);
       loop; loop = (LoopInfo*)oatGrowableListIteratorNext(&iter)) {
    loop->blocks = oatAllocBitVector(cUnit, cUnit->numBlocks, true,
                                     kBitMapMisc);
    oatSetBit(cUnit, loop->blocks, loop->header->id);
    GrowableListIterator iter;
    oatGrowableListIteratorInit(&loop->incomingBackEdges, &iter);
    BasicBlock* edgeBB;
    for (edgeBB = (BasicBlock*)oatGrowableListIteratorNext(&iter); edgeBB;
         edgeBB = (BasicBlock*)oatGrowableListIteratorNext(&iter)) {
      addBlocksToLoop(cUnit, loop->blocks, edgeBB, loop->header->id);
    }
  }
  // Compute the nesting depth of each header
  oatGrowableListIteratorInit(&cUnit->loopHeaders, &iter);
  for (LoopInfo* loop = (LoopInfo*)oatGrowableListIteratorNext(&iter);
       loop; loop = (LoopInfo*)oatGrowableListIteratorNext(&iter)) {
    GrowableListIterator iter2;
    oatGrowableListIteratorInit(&cUnit->loopHeaders, &iter2);
    LoopInfo* loop2;
    for (loop2 = (LoopInfo*)oatGrowableListIteratorNext(&iter2);
         loop2; loop2 = (LoopInfo*)oatGrowableListIteratorNext(&iter2)) {
      if (oatIsBitSet(loop2->blocks, loop->header->id)) {
         loop->header->nestingDepth++;
      }
    }
  }
  // Assign nesting depth to each block in all loops
  oatGrowableListIteratorInit(&cUnit->loopHeaders, &iter);
  for (LoopInfo* loop = (LoopInfo*)oatGrowableListIteratorNext(&iter);
       (loop != NULL); loop = (LoopInfo*)oatGrowableListIteratorNext(&iter)) {
    ArenaBitVectorIterator bIter;
    oatBitVectorIteratorInit(loop->blocks, &bIter);
    for (int bbId = oatBitVectorIteratorNext(&bIter); bbId != -1;
        bbId = oatBitVectorIteratorNext(&bIter)) {
      BasicBlock *bb;
      bb = (BasicBlock*) oatGrowableListGetElement(&cUnit->blockList, bbId);
      bb->nestingDepth = std::max(bb->nestingDepth,
                                  loop->header->nestingDepth);
    }
  }
  if (cUnit->printMe) {
    oatDumpLoops(cUnit);
  }
}

/*
 * This function will make a best guess at whether the invoke will
 * end up using Method*.  It isn't critical to get it exactly right,
 * and attempting to do would involve more complexity than it's
 * worth.
 */
bool invokeUsesMethodStar(CompilationUnit* cUnit, MIR* mir)
{
  InvokeType type;
  Instruction::Code opcode = mir->dalvikInsn.opcode;
  switch (opcode) {
    case Instruction::INVOKE_STATIC:
    case Instruction::INVOKE_STATIC_RANGE:
      type = kStatic;
      break;
    case Instruction::INVOKE_DIRECT:
    case Instruction::INVOKE_DIRECT_RANGE:
      type = kDirect;
      break;
    case Instruction::INVOKE_VIRTUAL:
    case Instruction::INVOKE_VIRTUAL_RANGE:
      type = kVirtual;
      break;
    case Instruction::INVOKE_INTERFACE:
    case Instruction::INVOKE_INTERFACE_RANGE:
      return false;
    case Instruction::INVOKE_SUPER_RANGE:
    case Instruction::INVOKE_SUPER:
      type = kSuper;
      break;
    default:
      LOG(WARNING) << "Unexpected invoke op: " << (int)opcode;
      return false;
  }
  OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
                           *cUnit->dex_file, *cUnit->dex_cache,
                           cUnit->code_item, cUnit->method_idx,
                           cUnit->access_flags);
  // TODO: add a flag so we don't counts the stats for this twice
  uint32_t dexMethodIdx = mir->dalvikInsn.vB;
  int vtableIdx;
  uintptr_t directCode;
  uintptr_t directMethod;
  bool fastPath =
      cUnit->compiler->ComputeInvokeInfo(dexMethodIdx, &mUnit, type,
                                         vtableIdx, directCode,
                                         directMethod) &&
      !SLOW_INVOKE_PATH;
  return (((type == kDirect) || (type == kStatic)) &&
          fastPath && ((directCode == 0) || (directMethod == 0)));
}

/*
 * Count uses, weighting by loop nesting depth.  This code only
 * counts explicitly used sRegs.  A later phase will add implicit
 * counts for things such as Method*, null-checked references, etc.
 */
bool countUses(struct CompilationUnit* cUnit, struct BasicBlock* bb)
{
  if (bb->blockType != kDalvikByteCode) {
    return false;
  }
  for (MIR* mir = bb->firstMIRInsn; (mir != NULL); mir = mir->next) {
    if (mir->ssaRep == NULL) {
      continue;
    }
    uint32_t weight = std::min(16U, (uint32_t)bb->nestingDepth);
    for (int i = 0; i < mir->ssaRep->numUses; i++) {
      int sReg = mir->ssaRep->uses[i];
      DCHECK_LT(sReg, (int)cUnit->useCounts.numUsed);
      cUnit->rawUseCounts.elemList[sReg]++;
      cUnit->useCounts.elemList[sReg] += (1 << weight);
    }
    if (!(cUnit->disableOpt & (1 << kPromoteCompilerTemps))) {
      int dfAttributes = oatDataFlowAttributes[mir->dalvikInsn.opcode];
      // Implicit use of Method* ? */
      if (dfAttributes & DF_UMS) {
        /*
         * Some invokes will not use Method* - need to perform test similar
         * to that found in genInvoke() to decide whether to count refs
         * for Method* on invoke-class opcodes.
         * TODO: refactor for common test here, save results for genInvoke
         */
        int usesMethodStar = true;
        if ((dfAttributes & (DF_FORMAT_35C | DF_FORMAT_3RC)) &&
            !(dfAttributes & DF_NON_NULL_RET)) {
          usesMethodStar &= invokeUsesMethodStar(cUnit, mir);
        }
        if (usesMethodStar) {
          cUnit->rawUseCounts.elemList[cUnit->methodSReg]++;
          cUnit->useCounts.elemList[cUnit->methodSReg] += (1 << weight);
        }
      }
    }
  }
  return false;
}

void oatMethodUseCount(CompilationUnit *cUnit)
{
  oatInitGrowableList(cUnit, &cUnit->useCounts, cUnit->numSSARegs + 32,
                      kListMisc);
  oatInitGrowableList(cUnit, &cUnit->rawUseCounts, cUnit->numSSARegs + 32,
                      kListMisc);
  // Initialize list
  for (int i = 0; i < cUnit->numSSARegs; i++) {
    oatInsertGrowableList(cUnit, &cUnit->useCounts, 0);
    oatInsertGrowableList(cUnit, &cUnit->rawUseCounts, 0);
  }
  if (cUnit->disableOpt & (1 << kPromoteRegs)) {
    return;
  }
  oatDataFlowAnalysisDispatcher(cUnit, countUses,
                                kAllNodes, false /* isIterative */);
}

}  // namespace art
