/*
 * 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_REF_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,

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

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

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

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

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

  // 38 IF_EQZ vAA, +BBBB
  DF_UA,

  // 39 IF_NEZ vAA, +BBBB
  DF_UA,

  // 3A IF_LTZ vAA, +BBBB
  DF_UA,

  // 3B IF_GEZ vAA, +BBBB
  DF_UA,

  // 3C IF_GTZ vAA, +BBBB
  DF_UA,

  // 3D IF_LEZ vAA, +BBBB
  DF_UA,

  // 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_CHECK
  0,

  // 109 MIR_RANGE_CHECK
  0,

  // 110 MIR_DIV_ZERO_CHECK
  0,

  // 111 MIR_CHECK
  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)
{
  std::string str;
  int opcode = insn.opcode;
  int dfAttributes = oatDataFlowAttributes[opcode];
  int flags;
  char* ret;

  if (opcode >= kMirOpFirst) {
    if (opcode == kMirOpPhi) {
      str.append("PHI");
    } else if (opcode == kMirOpCheck) {
      str.append("Check");
    } else {
      str.append(StringPrintf("Opcode %#x", opcode));
    }
    flags = 0;
  } else {
    str.append(Instruction::Name(insn.opcode));
    flags = Instruction::FlagsOf(insn.opcode);
  }

  if (note) {
    str.append(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:
        str.append(StringPrintf(" v%d,", insn.vA));
        offset = (int) insn.vB;
        break;
      case Instruction::k22t:
        str.append(StringPrintf(" 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;
    }
    str.append(StringPrintf(" (%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) str.append(",");
      str.append(StringPrintf(" v%d", insn.arg[i]));
    }
  }
  else if (dfAttributes & DF_FORMAT_3RC) {
    str.append(StringPrintf(" v%d..v%d", insn.vC, insn.vC + insn.vA - 1));
  } else {
    if (dfAttributes & DF_A_IS_REG) {
      str.append(StringPrintf(" v%d", insn.vA));
    }
    if (dfAttributes & DF_B_IS_REG) {
      str.append(StringPrintf(", v%d", insn.vB));
    } else if ((int)opcode < (int)kMirOpFirst) {
      str.append(StringPrintf(", (#%d)", insn.vB));
    }
    if (dfAttributes & DF_C_IS_REG) {
      str.append(StringPrintf(", v%d", insn.vC));
    } else if ((int)opcode < (int)kMirOpFirst) {
      str.append(StringPrintf(", (#%d)", insn.vC));
    }
  }
  int length = str.length() + 1;
  ret = (char*)oatNew(cUnit, length, false, kAllocDFInfo);
  strncpy(ret, str.c_str(), length);
  return ret;
}

std::string getSSAName(const CompilationUnit* cUnit, int ssaReg)
{
  return StringPrintf("v%d_%d", SRegToVReg(cUnit, ssaReg),
                     SRegToSubscript(cUnit, ssaReg));
}

/*
 * Dalvik instruction disassembler with optional SSA printing.
 */
char* oatFullDisassembler(CompilationUnit* cUnit, const MIR* mir)
{
  std::string str;
  const DecodedInstruction* insn = &mir->dalvikInsn;
  int opcode = insn->opcode;
  int dfAttributes = oatDataFlowAttributes[opcode];
  char* ret;
  int length;

  if (opcode >= kMirOpFirst) {
    if (opcode == kMirOpPhi) {
      int* incoming = (int*)mir->dalvikInsn.vB;
      str.append(StringPrintf("PHI %s = (%s",
                 getSSAName(cUnit, mir->ssaRep->defs[0]).c_str(),
                 getSSAName(cUnit, mir->ssaRep->uses[0]).c_str()));
      str.append(StringPrintf(":%d",incoming[0]));
      int i;
      for (i = 1; i < mir->ssaRep->numUses; i++) {
        str.append(StringPrintf(", %s:%d",
                                getSSAName(cUnit, mir->ssaRep->uses[i]).c_str(),
                                incoming[i]));
      }
      str.append(")");
    } else if (opcode == kMirOpCheck) {
      str.append("Check ");
      str.append(Instruction::Name(mir->meta.throwInsn->dalvikInsn.opcode));
    } else if (opcode == kMirOpNop) {
      str.append("MirNop");
    } else {
      str.append(StringPrintf("Opcode %#x", opcode));
    }
    goto done;
  } else {
    str.append(Instruction::Name(insn->opcode));
  }

  /* For branches, decode the instructions to print out the branch targets */
  if (Instruction::FlagsOf(insn->opcode) & Instruction::kBranch) {
    Instruction::Format dalvikFormat = Instruction::FormatOf(insn->opcode);
    int delta = 0;
    switch (dalvikFormat) {
      case Instruction::k21t:
        str.append(StringPrintf(" %s, ",
                   getSSAName(cUnit, mir->ssaRep->uses[0]).c_str()));
        delta = (int) insn->vB;
        break;
      case Instruction::k22t:
        str.append(StringPrintf(" %s, %s, ",
                 getSSAName(cUnit, mir->ssaRep->uses[0]).c_str(),
                 getSSAName(cUnit, mir->ssaRep->uses[1]).c_str()));
        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;
      }
      str.append(StringPrintf(" %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) str.append(",");
        str.append(" ");
        str.append(getSSAName(cUnit, mir->ssaRep->uses[i]));
    }
  } else {
    int udIdx;
    if (mir->ssaRep->numDefs) {

      for (udIdx = 0; udIdx < mir->ssaRep->numDefs; udIdx++) {
        str.append(" ");
        str.append(getSSAName(cUnit, mir->ssaRep->defs[udIdx]));
      }
      str.append(",");
    }
    if (mir->ssaRep->numUses) {
      /* No leading ',' for the first use */
      str.append(" ");
      str.append(getSSAName(cUnit, mir->ssaRep->uses[0]));
      for (udIdx = 1; udIdx < mir->ssaRep->numUses; udIdx++) {
        str.append(", ");
        str.append(getSSAName(cUnit, mir->ssaRep->uses[udIdx]));
        }
      }
      if (static_cast<int>(opcode) < static_cast<int>(kMirOpFirst)) {
        Instruction::Format dalvikFormat = Instruction::FormatOf(insn->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
            str.append(StringPrintf(" #%#x", insn->vB));
            break;
          case Instruction::k21c:        // op vAA, thing@BBBB
          case Instruction::k31c:        // op vAA, thing@BBBBBBBB
            str.append(StringPrintf(" @%#x", insn->vB));
            break;
          case Instruction::k22b:        // op vAA, vBB, #+CC
          case Instruction::k22s:        // op vA, vB, #+CCCC
            str.append(StringPrintf(" #%#x", insn->vC));
            break;
          case Instruction::k22c:        // op vA, vB, thing@CCCC
            str.append(StringPrintf(" @%#x", insn->vC));
            break;
          /* No need for special printing */
          default:
            break;
        }
     }
  }

done:
  length = str.length() + 1;
  ret = (char*) oatNew(cUnit, length, false, kAllocDFInfo);
  strncpy(ret, str.c_str(), length);
  return ret;
}

char* oatGetSSAString(CompilationUnit* cUnit, SSARepresentation* ssaRep)
{
  std::string str;
  char* ret;
  int i;

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

  if (ssaRep->numDefs) {
    str.append("<- ");
  }

  for (i = 0; i < ssaRep->numUses; i++) {
    int ssaReg = ssaRep->uses[i];
    str.append(StringPrintf("s%d(v%d_%d) ", ssaReg, SRegToVReg(cUnit, ssaReg),
               SRegToSubscript(cUnit, ssaReg)));
  }

  int length = str.length() + 1;
  ret = (char*)oatNew(cUnit, length, false, kAllocDFInfo);
  strncpy(ret, str.c_str(), 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);
  std::string ssaName = getSSAName(cUnit, ssaReg);
  char* name = (char*)oatNew(cUnit, ssaName.length() + 1, false, kAllocDFInfo);
  strncpy(name, ssaName.c_str(), ssaName.length() + 1);
  oatInsertGrowableList(cUnit, cUnit->ssaStrings, (intptr_t)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::FlagsOf(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);
    std::string ssaName = getSSAName(cUnit, i);
    char* name = (char*)oatNew(cUnit, ssaName.length() + 1, true, kAllocDFInfo);
    strncpy(name, ssaName.c_str(), ssaName.length() + 1);
    oatInsertGrowableList(cUnit, cUnit->ssaStrings, (intptr_t)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)
{
  BasicBlock* tbb = bb;
  mir = advanceMIR(cUnit, &tbb, mir, NULL, false);
  while (mir != NULL) {
    int opcode = mir->dalvikInsn.opcode;
    if ((mir->dalvikInsn.opcode == Instruction::MOVE_RESULT) ||
        (mir->dalvikInsn.opcode == Instruction::MOVE_RESULT_OBJECT) ||
        (mir->dalvikInsn.opcode == Instruction::MOVE_RESULT_WIDE)) {
      break;
    }
    // Keep going if pseudo op, otherwise terminate
    if (opcode < 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 defined(ART_USE_QUICK_COMPILER)
        if (cUnit->genBitcode) {
          // Bitcode doesn't allow this optimization.
          break;
        }
#endif
        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;
}

/* Collect stats on number of checks removed */
bool countChecks( struct CompilationUnit* cUnit, struct BasicBlock* bb)
{
  if (bb->dataFlowInfo == NULL) return false;
  for (MIR* mir = bb->firstMIRInsn; mir; mir = mir->next) {
    if (mir->ssaRep == NULL) {
      continue;
    }
    int dfAttributes = oatDataFlowAttributes[mir->dalvikInsn.opcode];
    if (dfAttributes & DF_HAS_NULL_CHKS) {
      cUnit->checkstats->nullChecks++;
      if (mir->optimizationFlags & MIR_IGNORE_NULL_CHECK) {
        cUnit->checkstats->nullChecksEliminated++;
      }
    }
    if (dfAttributes & DF_HAS_RANGE_CHKS) {
      cUnit->checkstats->rangeChecks++;
      if (mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK) {
        cUnit->checkstats->rangeChecksEliminated++;
      }
    }
  }
  return false;
}

/* Try to make common case the fallthrough path */
bool layoutBlocks(struct CompilationUnit* cUnit, struct BasicBlock* bb)
{
  // TODO: For now, just looking for direct throws.  Consider generalizing for profile feedback
  if (!bb->explicitThrow) {
    return false;
  }
  BasicBlock* walker = bb;
  while (true) {
    // Check termination conditions
    if ((walker->blockType == kEntryBlock) || (walker->predecessors->numUsed != 1)) {
      break;
    }
    BasicBlock* prev = GET_ELEM_N(walker->predecessors, BasicBlock*, 0);
    if (prev->conditionalBranch) {
      if (prev->fallThrough == walker) {
        // Already done - return
        break;
      }
      DCHECK_EQ(walker, prev->taken);
      // Got one.  Flip it and exit
      Instruction::Code opcode = prev->lastMIRInsn->dalvikInsn.opcode;
      switch (opcode) {
        case Instruction::IF_EQ: opcode = Instruction::IF_NE; break;
        case Instruction::IF_NE: opcode = Instruction::IF_EQ; break;
        case Instruction::IF_LT: opcode = Instruction::IF_GE; break;
        case Instruction::IF_GE: opcode = Instruction::IF_LT; break;
        case Instruction::IF_GT: opcode = Instruction::IF_LE; break;
        case Instruction::IF_LE: opcode = Instruction::IF_GT; break;
        case Instruction::IF_EQZ: opcode = Instruction::IF_NEZ; break;
        case Instruction::IF_NEZ: opcode = Instruction::IF_EQZ; break;
        case Instruction::IF_LTZ: opcode = Instruction::IF_GEZ; break;
        case Instruction::IF_GEZ: opcode = Instruction::IF_LTZ; break;
        case Instruction::IF_GTZ: opcode = Instruction::IF_LEZ; break;
        case Instruction::IF_LEZ: opcode = Instruction::IF_GTZ; break;
        default: LOG(FATAL) << "Unexpected opcode 0x" << std::hex << (int)opcode;
      }
      prev->lastMIRInsn->dalvikInsn.opcode = opcode;
      BasicBlock* tBB = prev->taken;
      prev->taken = prev->fallThrough;
      prev->fallThrough = tBB;
      break;
    }
    walker = prev;
  }
  return false;
}

/* Combine any basic blocks terminated by instructions that we now know can't throw */
bool combineBlocks(struct CompilationUnit* cUnit, struct BasicBlock* bb)
{
  // Loop here to allow combining a sequence of blocks
  while (true) {
    // Check termination conditions
    if ((bb->firstMIRInsn == NULL)
        || (bb->dataFlowInfo == NULL)
        || (bb->blockType == kExceptionHandling)
        || (bb->blockType == kExitBlock)
        || (bb->blockType == kDead)
        || ((bb->taken == NULL) || (bb->taken->blockType != kExceptionHandling))
        || (bb->successorBlockList.blockListType != kNotUsed)
        || ((int)bb->lastMIRInsn->dalvikInsn.opcode != kMirOpCheck)) {
      break;
    }

    // Test the kMirOpCheck instruction
    MIR* mir = bb->lastMIRInsn;
    // Grab the attributes from the paired opcode
    MIR* throwInsn = mir->meta.throwInsn;
    int dfAttributes = oatDataFlowAttributes[throwInsn->dalvikInsn.opcode];
    bool canCombine = true;
    if (dfAttributes & DF_HAS_NULL_CHKS) {
      canCombine &= ((throwInsn->optimizationFlags & MIR_IGNORE_NULL_CHECK) != 0);
    }
    if (dfAttributes & DF_HAS_RANGE_CHKS) {
      canCombine &= ((throwInsn->optimizationFlags & MIR_IGNORE_RANGE_CHECK) != 0);
    }
    if (!canCombine) {
      break;
    }
    // OK - got one.  Combine
    BasicBlock* bbNext = bb->fallThrough;
    DCHECK(!bbNext->catchEntry);
    DCHECK_EQ(bbNext->predecessors->numUsed, 1U);
    MIR* tMir = bb->lastMIRInsn->prev;
    // Overwrite the kOpCheck insn with the paired opcode
    DCHECK_EQ(bbNext->firstMIRInsn, throwInsn);
    *bb->lastMIRInsn = *throwInsn;
    bb->lastMIRInsn->prev = tMir;
    // Use the successor info from the next block
    bb->successorBlockList = bbNext->successorBlockList;
    // Use the ending block linkage from the next block
    bb->fallThrough = bbNext->fallThrough;
    bb->taken->blockType = kDead;  // Kill the unused exception block
    bb->taken = bbNext->taken;
    // Include the rest of the instructions
    bb->lastMIRInsn = bbNext->lastMIRInsn;

    /*
     * NOTE: we aren't updating all dataflow info here.  Should either make sure this pass
     * happens after uses of iDominated, domFrontier or update the dataflow info here.
     */

    // Kill bbNext and remap now-dead id to parent
    bbNext->blockType = kDead;
    cUnit->blockIdMap.Overwrite(bbNext->id, bb->id);

    // Now, loop back and see if we can keep going
  }
  return false;
}

/* 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) && !(mir->optimizationFlags & MIR_IGNORE_NULL_CHECK)) {
      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 oatMethodBasicBlockCombine(CompilationUnit* cUnit)
{
  oatDataFlowAnalysisDispatcher(cUnit, combineBlocks, kPreOrderDFSTraversal, false);
}

void oatMethodCodeLayout(CompilationUnit* cUnit)
{
  oatDataFlowAnalysisDispatcher(cUnit, layoutBlocks, kAllNodes, false);
}

void oatDumpCheckStats(CompilationUnit *cUnit)
{
  Checkstats* stats = (Checkstats*)oatNew(cUnit, sizeof(Checkstats), true, kAllocDFInfo);
  cUnit->checkstats = stats;
  oatDataFlowAnalysisDispatcher(cUnit, countChecks, kAllNodes, false /* isIterative */);
  if (stats->nullChecks > 0) {
    LOG(INFO) << "Null Checks: " << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " "
              << stats->nullChecksEliminated << " of " << stats->nullChecks << " -> "
              << ((float)stats->nullChecksEliminated/(float)stats->nullChecks) * 100.0 << "%";
    }
  if (stats->rangeChecks > 0) {
    LOG(INFO) << "Range Checks: " << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " "
              << stats->rangeChecksEliminated << " of " << stats->rangeChecks << " -> "
              << ((float)stats->rangeChecksEliminated/(float)stats->rangeChecks) * 100.0 << "%";
  }
}

void oatMethodBasicBlockOptimization(CompilationUnit *cUnit)
{
  if (!(cUnit->disableOpt & (1 << kBBOpt))) {
    oatInitGrowableList(cUnit, &cUnit->compilerTemps, 6, kListMisc);
    DCHECK_EQ(cUnit->numCompilerTemps, 0);
    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::FlagsOf(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->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
