/*
 * Copyright (C) 2013 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 "mir_graph.h"

#include <inttypes.h>
#include <queue>
#include <unistd.h>

#include "base/bit_vector-inl.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "base/stringprintf.h"
#include "base/scoped_arena_containers.h"
#include "compiler_ir.h"
#include "dex_file-inl.h"
#include "dex_flags.h"
#include "dex_instruction-inl.h"
#include "driver/compiler_driver.h"
#include "driver/dex_compilation_unit.h"
#include "dex/quick/quick_compiler.h"
#include "leb128.h"
#include "pass_driver_me_post_opt.h"
#include "stack.h"

namespace art {

#define MAX_PATTERN_LEN 5

const char* MIRGraph::extended_mir_op_names_[kMirOpLast - kMirOpFirst] = {
  "Phi",
  "Copy",
  "FusedCmplFloat",
  "FusedCmpgFloat",
  "FusedCmplDouble",
  "FusedCmpgDouble",
  "FusedCmpLong",
  "Nop",
  "OpNullCheck",
  "OpRangeCheck",
  "OpDivZeroCheck",
  "Check1",
  "Check2",
  "Select",
  "ConstVector",
  "MoveVector",
  "PackedMultiply",
  "PackedAddition",
  "PackedSubtract",
  "PackedShiftLeft",
  "PackedSignedShiftRight",
  "PackedUnsignedShiftRight",
  "PackedAnd",
  "PackedOr",
  "PackedXor",
  "PackedAddReduce",
  "PackedReduce",
  "PackedSet",
  "ReserveVectorRegisters",
  "ReturnVectorRegisters",
  "MemBarrier",
  "PackedArrayGet",
  "PackedArrayPut",
  "MaddInt",
  "MsubInt",
  "MaddLong",
  "MsubLong",
};

MIRGraph::MIRGraph(CompilationUnit* cu, ArenaAllocator* arena)
    : reg_location_(nullptr),
      block_id_map_(std::less<unsigned int>(), arena->Adapter()),
      cu_(cu),
      ssa_base_vregs_(arena->Adapter(kArenaAllocSSAToDalvikMap)),
      ssa_subscripts_(arena->Adapter(kArenaAllocSSAToDalvikMap)),
      vreg_to_ssa_map_(nullptr),
      ssa_last_defs_(nullptr),
      is_constant_v_(nullptr),
      constant_values_(nullptr),
      use_counts_(arena->Adapter()),
      raw_use_counts_(arena->Adapter()),
      num_reachable_blocks_(0),
      max_num_reachable_blocks_(0),
      dfs_orders_up_to_date_(false),
      domination_up_to_date_(false),
      mir_ssa_rep_up_to_date_(false),
      topological_order_up_to_date_(false),
      dfs_order_(arena->Adapter(kArenaAllocDfsPreOrder)),
      dfs_post_order_(arena->Adapter(kArenaAllocDfsPostOrder)),
      dom_post_order_traversal_(arena->Adapter(kArenaAllocDomPostOrder)),
      topological_order_(arena->Adapter(kArenaAllocTopologicalSortOrder)),
      topological_order_loop_ends_(arena->Adapter(kArenaAllocTopologicalSortOrder)),
      topological_order_indexes_(arena->Adapter(kArenaAllocTopologicalSortOrder)),
      topological_order_loop_head_stack_(arena->Adapter(kArenaAllocTopologicalSortOrder)),
      max_nested_loops_(0u),
      i_dom_list_(nullptr),
      temp_scoped_alloc_(),
      block_list_(arena->Adapter(kArenaAllocBBList)),
      try_block_addr_(nullptr),
      entry_block_(nullptr),
      exit_block_(nullptr),
      current_code_item_(nullptr),
      m_units_(arena->Adapter()),
      method_stack_(arena->Adapter()),
      current_method_(kInvalidEntry),
      current_offset_(kInvalidEntry),
      def_count_(0),
      opcode_count_(nullptr),
      num_ssa_regs_(0),
      extended_basic_blocks_(arena->Adapter()),
      method_sreg_(0),
      attributes_(METHOD_IS_LEAF),  // Start with leaf assumption, change on encountering invoke.
      checkstats_(nullptr),
      arena_(arena),
      backward_branches_(0),
      forward_branches_(0),
      num_non_special_compiler_temps_(0),
      max_available_special_compiler_temps_(1),  // We only need the method ptr as a special temp for now.
      requested_backend_temp_(false),
      compiler_temps_committed_(false),
      punt_to_interpreter_(false),
      merged_df_flags_(0u),
      ifield_lowering_infos_(arena->Adapter(kArenaAllocLoweringInfo)),
      sfield_lowering_infos_(arena->Adapter(kArenaAllocLoweringInfo)),
      method_lowering_infos_(arena->Adapter(kArenaAllocLoweringInfo)),
      suspend_checks_in_loops_(nullptr) {
  memset(&temp_, 0, sizeof(temp_));
  use_counts_.reserve(256);
  raw_use_counts_.reserve(256);
  block_list_.reserve(100);
  try_block_addr_ = new (arena_) ArenaBitVector(arena_, 0, true /* expandable */);


  if (cu_->instruction_set == kX86 || cu_->instruction_set == kX86_64) {
    // X86 requires a temp to keep track of the method address.
    // TODO For x86_64, addressing can be done with RIP. When that is implemented,
    // this needs to be updated to reserve 0 temps for BE.
    max_available_non_special_compiler_temps_ = cu_->target64 ? 2 : 1;
    reserved_temps_for_backend_ = max_available_non_special_compiler_temps_;
  } else {
    // Other architectures do not have a known lower bound for non-special temps.
    // We allow the update of the max to happen at BE initialization stage and simply set 0 for now.
    max_available_non_special_compiler_temps_ = 0;
    reserved_temps_for_backend_ = 0;
  }
}

MIRGraph::~MIRGraph() {
  STLDeleteElements(&block_list_);
  STLDeleteElements(&m_units_);
}

/*
 * Parse an instruction, return the length of the instruction
 */
int MIRGraph::ParseInsn(const uint16_t* code_ptr, MIR::DecodedInstruction* decoded_instruction) {
  const Instruction* inst = Instruction::At(code_ptr);
  decoded_instruction->opcode = inst->Opcode();
  decoded_instruction->vA = inst->HasVRegA() ? inst->VRegA() : 0;
  decoded_instruction->vB = inst->HasVRegB() ? inst->VRegB() : 0;
  decoded_instruction->vB_wide = inst->HasWideVRegB() ? inst->WideVRegB() : 0;
  decoded_instruction->vC = inst->HasVRegC() ?  inst->VRegC() : 0;
  if (inst->HasVarArgs()) {
    inst->GetVarArgs(decoded_instruction->arg);
  }
  return inst->SizeInCodeUnits();
}


/* Split an existing block from the specified code offset into two */
BasicBlock* MIRGraph::SplitBlock(DexOffset code_offset,
                                 BasicBlock* orig_block, BasicBlock** immed_pred_block_p) {
  DCHECK_GT(code_offset, orig_block->start_offset);
  MIR* insn = orig_block->first_mir_insn;
  MIR* prev = nullptr;  // Will be set to instruction before split.
  while (insn) {
    if (insn->offset == code_offset) break;
    prev = insn;
    insn = insn->next;
  }
  if (insn == nullptr) {
    LOG(FATAL) << "Break split failed";
  }
  // Now insn is at the instruction where we want to split, namely
  // insn will be the first instruction of the "bottom" block.
  // Similarly, prev will be the last instruction of the "top" block

  BasicBlock* bottom_block = CreateNewBB(kDalvikByteCode);

  bottom_block->start_offset = code_offset;
  bottom_block->first_mir_insn = insn;
  bottom_block->last_mir_insn = orig_block->last_mir_insn;

  /* If this block was terminated by a return, conditional branch or throw,
   * the flag needs to go with the bottom block
   */
  bottom_block->terminated_by_return = orig_block->terminated_by_return;
  orig_block->terminated_by_return = false;

  bottom_block->conditional_branch = orig_block->conditional_branch;
  orig_block->conditional_branch = false;

  bottom_block->explicit_throw = orig_block->explicit_throw;
  orig_block->explicit_throw = false;

  /* Handle the taken path */
  bottom_block->taken = orig_block->taken;
  if (bottom_block->taken != NullBasicBlockId) {
    orig_block->taken = NullBasicBlockId;
    BasicBlock* bb_taken = GetBasicBlock(bottom_block->taken);
    bb_taken->ErasePredecessor(orig_block->id);
    bb_taken->predecessors.push_back(bottom_block->id);
  }

  /* Handle the fallthrough path */
  bottom_block->fall_through = orig_block->fall_through;
  orig_block->fall_through = bottom_block->id;
  bottom_block->predecessors.push_back(orig_block->id);
  if (bottom_block->fall_through != NullBasicBlockId) {
    BasicBlock* bb_fall_through = GetBasicBlock(bottom_block->fall_through);
    bb_fall_through->ErasePredecessor(orig_block->id);
    bb_fall_through->predecessors.push_back(bottom_block->id);
  }

  /* Handle the successor list */
  if (orig_block->successor_block_list_type != kNotUsed) {
    bottom_block->successor_block_list_type = orig_block->successor_block_list_type;
    bottom_block->successor_blocks.swap(orig_block->successor_blocks);
    orig_block->successor_block_list_type = kNotUsed;
    DCHECK(orig_block->successor_blocks.empty());  // Empty after the swap() above.
    for (SuccessorBlockInfo* successor_block_info : bottom_block->successor_blocks) {
      BasicBlock* bb = GetBasicBlock(successor_block_info->block);
      if (bb != nullptr) {
        bb->ErasePredecessor(orig_block->id);
        bb->predecessors.push_back(bottom_block->id);
      }
    }
  }

  orig_block->last_mir_insn = prev;
  prev->next = nullptr;

  /*
   * Update the immediate predecessor block pointer so that outgoing edges
   * can be applied to the proper block.
   */
  if (immed_pred_block_p) {
    DCHECK_EQ(*immed_pred_block_p, orig_block);
    *immed_pred_block_p = bottom_block;
  }

  // Associate dex instructions in the bottom block with the new container.
  DCHECK(insn != nullptr);
  DCHECK(insn != orig_block->first_mir_insn);
  DCHECK(insn == bottom_block->first_mir_insn);
  DCHECK_EQ(insn->offset, bottom_block->start_offset);
  // Scan the "bottom" instructions, remapping them to the
  // newly created "bottom" block.
  MIR* p = insn;
  p->bb = bottom_block->id;
  while (p != bottom_block->last_mir_insn) {
    p = p->next;
    DCHECK(p != nullptr);
    p->bb = bottom_block->id;
  }

  return bottom_block;
}

/*
 * Given a code offset, find out the block that starts with it. If the offset
 * is in the middle of an existing block, split it into two.  If immed_pred_block_p
 * is not non-null and is the block being split, update *immed_pred_block_p to
 * point to the bottom block so that outgoing edges can be set up properly
 * (by the caller)
 * Utilizes a map for fast lookup of the typical cases.
 */
BasicBlock* MIRGraph::FindBlock(DexOffset code_offset, bool create,
                                BasicBlock** immed_pred_block_p,
                                ScopedArenaVector<uint16_t>* dex_pc_to_block_map) {
  if (UNLIKELY(code_offset >= current_code_item_->insns_size_in_code_units_)) {
    // There can be a fall-through out of the method code. We shall record such a block
    // here (assuming create==true) and check that it's dead at the end of InlineMethod().
    // Though we're only aware of the cases where code_offset is exactly the same as
    // insns_size_in_code_units_, treat greater code_offset the same just in case.
    code_offset = current_code_item_->insns_size_in_code_units_;
  }

  int block_id = (*dex_pc_to_block_map)[code_offset];
  BasicBlock* bb = GetBasicBlock(block_id);

  if ((bb != nullptr) && (bb->start_offset == code_offset)) {
    // Does this containing block start with the desired instruction?
    return bb;
  }

  // No direct hit.
  if (!create) {
    return nullptr;
  }

  if (bb != nullptr) {
    // The target exists somewhere in an existing block.
    BasicBlock* bottom_block = SplitBlock(code_offset, bb, bb == *immed_pred_block_p ?  immed_pred_block_p : nullptr);
    DCHECK(bottom_block != nullptr);
    MIR* p = bottom_block->first_mir_insn;
    BasicBlock* orig_block = bb;
    DCHECK_EQ((*dex_pc_to_block_map)[p->offset], orig_block->id);
    // Scan the "bottom" instructions, remapping them to the
    // newly created "bottom" block.
    (*dex_pc_to_block_map)[p->offset] = bottom_block->id;
    while (p != bottom_block->last_mir_insn) {
      p = p->next;
      DCHECK(p != nullptr);
      int opcode = p->dalvikInsn.opcode;
      /*
       * Some messiness here to ensure that we only enter real opcodes and only the
       * first half of a potentially throwing instruction that has been split into
       * CHECK and work portions. Since the 2nd half of a split operation is always
       * the first in a BasicBlock, we can't hit it here.
       */
      if ((opcode == kMirOpCheck) || !MIR::DecodedInstruction::IsPseudoMirOp(opcode)) {
        BasicBlockId mapped_id = (*dex_pc_to_block_map)[p->offset];
        // At first glance the instructions should all be mapped to orig_block.
        // However, multiple instructions may correspond to the same dex, hence an earlier
        // instruction may have already moved the mapping for dex to bottom_block.
        DCHECK((mapped_id == orig_block->id) || (mapped_id == bottom_block->id));
        (*dex_pc_to_block_map)[p->offset] = bottom_block->id;
      }
    }
    return bottom_block;
  }

  // Create a new block.
  bb = CreateNewBB(kDalvikByteCode);
  bb->start_offset = code_offset;
  (*dex_pc_to_block_map)[bb->start_offset] = bb->id;
  return bb;
}


/* Identify code range in try blocks and set up the empty catch blocks */
void MIRGraph::ProcessTryCatchBlocks(ScopedArenaVector<uint16_t>* dex_pc_to_block_map) {
  int tries_size = current_code_item_->tries_size_;
  DexOffset offset;

  if (tries_size == 0) {
    return;
  }

  for (int i = 0; i < tries_size; i++) {
    const DexFile::TryItem* pTry =
        DexFile::GetTryItems(*current_code_item_, i);
    DexOffset start_offset = pTry->start_addr_;
    DexOffset end_offset = start_offset + pTry->insn_count_;
    for (offset = start_offset; offset < end_offset; offset++) {
      try_block_addr_->SetBit(offset);
    }
  }

  // Iterate over each of the handlers to enqueue the empty Catch blocks.
  const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(*current_code_item_, 0);
  uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
  for (uint32_t idx = 0; idx < handlers_size; idx++) {
    CatchHandlerIterator iterator(handlers_ptr);
    for (; iterator.HasNext(); iterator.Next()) {
      uint32_t address = iterator.GetHandlerAddress();
      FindBlock(address, true /*create*/, /* immed_pred_block_p */ nullptr, dex_pc_to_block_map);
    }
    handlers_ptr = iterator.EndDataPointer();
  }
}

bool MIRGraph::IsBadMonitorExitCatch(NarrowDexOffset monitor_exit_offset,
                                     NarrowDexOffset catch_offset) {
  // Catches for monitor-exit during stack unwinding have the pattern
  //   move-exception (move)* (goto)? monitor-exit throw
  // In the currently generated dex bytecode we see these catching a bytecode range including
  // either its own or an identical monitor-exit, http://b/15745363 . This function checks if
  // it's the case for a given monitor-exit and catch block so that we can ignore it.
  // (We don't want to ignore all monitor-exit catches since one could enclose a synchronized
  // block in a try-block and catch the NPE, Error or Throwable and we should let it through;
  // even though a throwing monitor-exit certainly indicates a bytecode error.)
  const Instruction* monitor_exit = Instruction::At(current_code_item_->insns_ + monitor_exit_offset);
  DCHECK(monitor_exit->Opcode() == Instruction::MONITOR_EXIT);
  int monitor_reg = monitor_exit->VRegA_11x();
  const Instruction* check_insn = Instruction::At(current_code_item_->insns_ + catch_offset);
  DCHECK(check_insn->Opcode() == Instruction::MOVE_EXCEPTION);
  if (check_insn->VRegA_11x() == monitor_reg) {
    // Unexpected move-exception to the same register. Probably not the pattern we're looking for.
    return false;
  }
  check_insn = check_insn->Next();
  while (true) {
    int dest = -1;
    bool wide = false;
    switch (check_insn->Opcode()) {
      case Instruction::MOVE_WIDE:
        wide = true;
        FALLTHROUGH_INTENDED;
      case Instruction::MOVE_OBJECT:
      case Instruction::MOVE:
        dest = check_insn->VRegA_12x();
        break;

      case Instruction::MOVE_WIDE_FROM16:
        wide = true;
        FALLTHROUGH_INTENDED;
      case Instruction::MOVE_OBJECT_FROM16:
      case Instruction::MOVE_FROM16:
        dest = check_insn->VRegA_22x();
        break;

      case Instruction::MOVE_WIDE_16:
        wide = true;
        FALLTHROUGH_INTENDED;
      case Instruction::MOVE_OBJECT_16:
      case Instruction::MOVE_16:
        dest = check_insn->VRegA_32x();
        break;

      case Instruction::GOTO:
      case Instruction::GOTO_16:
      case Instruction::GOTO_32:
        check_insn = check_insn->RelativeAt(check_insn->GetTargetOffset());
        FALLTHROUGH_INTENDED;
      default:
        return check_insn->Opcode() == Instruction::MONITOR_EXIT &&
            check_insn->VRegA_11x() == monitor_reg;
    }

    if (dest == monitor_reg || (wide && dest + 1 == monitor_reg)) {
      return false;
    }

    check_insn = check_insn->Next();
  }
}

/* Process instructions with the kBranch flag */
BasicBlock* MIRGraph::ProcessCanBranch(BasicBlock* cur_block, MIR* insn, DexOffset cur_offset,
                                       int width, int flags, const uint16_t* code_ptr,
                                       const uint16_t* code_end,
                                       ScopedArenaVector<uint16_t>* dex_pc_to_block_map) {
  DexOffset target = cur_offset;
  switch (insn->dalvikInsn.opcode) {
    case Instruction::GOTO:
    case Instruction::GOTO_16:
    case Instruction::GOTO_32:
      target += insn->dalvikInsn.vA;
      break;
    case Instruction::IF_EQ:
    case Instruction::IF_NE:
    case Instruction::IF_LT:
    case Instruction::IF_GE:
    case Instruction::IF_GT:
    case Instruction::IF_LE:
      cur_block->conditional_branch = true;
      target += insn->dalvikInsn.vC;
      break;
    case Instruction::IF_EQZ:
    case Instruction::IF_NEZ:
    case Instruction::IF_LTZ:
    case Instruction::IF_GEZ:
    case Instruction::IF_GTZ:
    case Instruction::IF_LEZ:
      cur_block->conditional_branch = true;
      target += insn->dalvikInsn.vB;
      break;
    default:
      LOG(FATAL) << "Unexpected opcode(" << insn->dalvikInsn.opcode << ") with kBranch set";
  }
  CountBranch(target);
  BasicBlock* taken_block = FindBlock(target, /* create */ true,
                                      /* immed_pred_block_p */ &cur_block,
                                      dex_pc_to_block_map);
  DCHECK(taken_block != nullptr);
  cur_block->taken = taken_block->id;
  taken_block->predecessors.push_back(cur_block->id);

  /* Always terminate the current block for conditional branches */
  if (flags & Instruction::kContinue) {
    BasicBlock* fallthrough_block = FindBlock(cur_offset +  width,
                                             /* create */
                                             true,
                                             /* immed_pred_block_p */
                                             &cur_block,
                                             dex_pc_to_block_map);
    DCHECK(fallthrough_block != nullptr);
    cur_block->fall_through = fallthrough_block->id;
    fallthrough_block->predecessors.push_back(cur_block->id);
  } else if (code_ptr < code_end) {
    FindBlock(cur_offset + width, /* create */ true, /* immed_pred_block_p */ nullptr, dex_pc_to_block_map);
  }
  return cur_block;
}

/* Process instructions with the kSwitch flag */
BasicBlock* MIRGraph::ProcessCanSwitch(BasicBlock* cur_block, MIR* insn, DexOffset cur_offset,
                                       int width, int flags,
                                       ScopedArenaVector<uint16_t>* dex_pc_to_block_map) {
  UNUSED(flags);
  const uint16_t* switch_data =
      reinterpret_cast<const uint16_t*>(GetCurrentInsns() + cur_offset +
          static_cast<int32_t>(insn->dalvikInsn.vB));
  int size;
  const int* keyTable;
  const int* target_table;
  int i;
  int first_key;

  /*
   * Packed switch data format:
   *  ushort ident = 0x0100   magic value
   *  ushort size             number of entries in the table
   *  int first_key           first (and lowest) switch case value
   *  int targets[size]       branch targets, relative to switch opcode
   *
   * Total size is (4+size*2) 16-bit code units.
   */
  if (insn->dalvikInsn.opcode == Instruction::PACKED_SWITCH) {
    DCHECK_EQ(static_cast<int>(switch_data[0]),
              static_cast<int>(Instruction::kPackedSwitchSignature));
    size = switch_data[1];
    first_key = switch_data[2] | (switch_data[3] << 16);
    target_table = reinterpret_cast<const int*>(&switch_data[4]);
    keyTable = nullptr;        // Make the compiler happy.
  /*
   * Sparse switch data format:
   *  ushort ident = 0x0200   magic value
   *  ushort size             number of entries in the table; > 0
   *  int keys[size]          keys, sorted low-to-high; 32-bit aligned
   *  int targets[size]       branch targets, relative to switch opcode
   *
   * Total size is (2+size*4) 16-bit code units.
   */
  } else {
    DCHECK_EQ(static_cast<int>(switch_data[0]),
              static_cast<int>(Instruction::kSparseSwitchSignature));
    size = switch_data[1];
    keyTable = reinterpret_cast<const int*>(&switch_data[2]);
    target_table = reinterpret_cast<const int*>(&switch_data[2 + size*2]);
    first_key = 0;   // To make the compiler happy.
  }

  if (cur_block->successor_block_list_type != kNotUsed) {
    LOG(FATAL) << "Successor block list already in use: "
               << static_cast<int>(cur_block->successor_block_list_type);
  }
  cur_block->successor_block_list_type =
      (insn->dalvikInsn.opcode == Instruction::PACKED_SWITCH) ?  kPackedSwitch : kSparseSwitch;
  cur_block->successor_blocks.reserve(size);

  for (i = 0; i < size; i++) {
    BasicBlock* case_block = FindBlock(cur_offset + target_table[i],  /* create */ true,
                                       /* immed_pred_block_p */ &cur_block,
                                       dex_pc_to_block_map);
    DCHECK(case_block != nullptr);
    SuccessorBlockInfo* successor_block_info =
        static_cast<SuccessorBlockInfo*>(arena_->Alloc(sizeof(SuccessorBlockInfo),
                                                       kArenaAllocSuccessor));
    successor_block_info->block = case_block->id;
    successor_block_info->key =
        (insn->dalvikInsn.opcode == Instruction::PACKED_SWITCH) ?
        first_key + i : keyTable[i];
    cur_block->successor_blocks.push_back(successor_block_info);
    case_block->predecessors.push_back(cur_block->id);
  }

  /* Fall-through case */
  BasicBlock* fallthrough_block = FindBlock(cur_offset +  width, /* create */ true,
                                            /* immed_pred_block_p */ nullptr,
                                            dex_pc_to_block_map);
  DCHECK(fallthrough_block != nullptr);
  cur_block->fall_through = fallthrough_block->id;
  fallthrough_block->predecessors.push_back(cur_block->id);
  return cur_block;
}

/* Process instructions with the kThrow flag */
BasicBlock* MIRGraph::ProcessCanThrow(BasicBlock* cur_block, MIR* insn, DexOffset cur_offset,
                                      int width, int flags, ArenaBitVector* try_block_addr,
                                      const uint16_t* code_ptr, const uint16_t* code_end,
                                      ScopedArenaVector<uint16_t>* dex_pc_to_block_map) {
  UNUSED(flags);
  bool in_try_block = try_block_addr->IsBitSet(cur_offset);
  bool is_throw = (insn->dalvikInsn.opcode == Instruction::THROW);

  /* In try block */
  if (in_try_block) {
    CatchHandlerIterator iterator(*current_code_item_, cur_offset);

    if (cur_block->successor_block_list_type != kNotUsed) {
      LOG(INFO) << PrettyMethod(cu_->method_idx, *cu_->dex_file);
      LOG(FATAL) << "Successor block list already in use: "
                 << static_cast<int>(cur_block->successor_block_list_type);
    }

    for (; iterator.HasNext(); iterator.Next()) {
      BasicBlock* catch_block = FindBlock(iterator.GetHandlerAddress(), false /* create */,
                                          nullptr /* immed_pred_block_p */,
                                          dex_pc_to_block_map);
      if (insn->dalvikInsn.opcode == Instruction::MONITOR_EXIT &&
          IsBadMonitorExitCatch(insn->offset, catch_block->start_offset)) {
        // Don't allow monitor-exit to catch its own exception, http://b/15745363 .
        continue;
      }
      if (cur_block->successor_block_list_type == kNotUsed) {
        cur_block->successor_block_list_type = kCatch;
      }
      catch_block->catch_entry = true;
      if (kIsDebugBuild) {
        catches_.insert(catch_block->start_offset);
      }
      SuccessorBlockInfo* successor_block_info = reinterpret_cast<SuccessorBlockInfo*>
          (arena_->Alloc(sizeof(SuccessorBlockInfo), kArenaAllocSuccessor));
      successor_block_info->block = catch_block->id;
      successor_block_info->key = iterator.GetHandlerTypeIndex();
      cur_block->successor_blocks.push_back(successor_block_info);
      catch_block->predecessors.push_back(cur_block->id);
    }
    in_try_block = (cur_block->successor_block_list_type != kNotUsed);
  }
  bool build_all_edges =
      (cu_->disable_opt & (1 << kSuppressExceptionEdges)) || is_throw || in_try_block;
  if (!in_try_block && build_all_edges) {
    BasicBlock* eh_block = CreateNewBB(kExceptionHandling);
    cur_block->taken = eh_block->id;
    eh_block->start_offset = cur_offset;
    eh_block->predecessors.push_back(cur_block->id);
  }

  if (is_throw) {
    cur_block->explicit_throw = true;
    if (code_ptr < code_end) {
      // Force creation of new block following THROW via side-effect.
      FindBlock(cur_offset + width, /* create */ true, /* immed_pred_block_p */ nullptr, dex_pc_to_block_map);
    }
    if (!in_try_block) {
       // Don't split a THROW that can't rethrow - we're done.
      return cur_block;
    }
  }

  if (!build_all_edges) {
    /*
     * Even though there is an exception edge here, control cannot return to this
     * method.  Thus, for the purposes of dataflow analysis and optimization, we can
     * ignore the edge.  Doing this reduces compile time, and increases the scope
     * of the basic-block level optimization pass.
     */
    return cur_block;
  }

  /*
   * Split the potentially-throwing instruction into two parts.
   * The first half will be a pseudo-op that captures the exception
   * edges and terminates the basic block.  It always falls through.
   * Then, create a new basic block that begins with the throwing instruction
   * (minus exceptions).  Note: this new basic block must NOT be entered into
   * the block_map.  If the potentially-throwing instruction is the target of a
   * future branch, we need to find the check psuedo half.  The new
   * basic block containing the work portion of the instruction should
   * only be entered via fallthrough from the block containing the
   * pseudo exception edge MIR.  Note also that this new block is
   * not automatically terminated after the work portion, and may
   * contain following instructions.
   *
   * Note also that the dex_pc_to_block_map entry for the potentially
   * throwing instruction will refer to the original basic block.
   */
  BasicBlock* new_block = CreateNewBB(kDalvikByteCode);
  new_block->start_offset = insn->offset;
  cur_block->fall_through = new_block->id;
  new_block->predecessors.push_back(cur_block->id);
  MIR* new_insn = NewMIR();
  *new_insn = *insn;
  insn->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpCheck);
  // Associate the two halves.
  insn->meta.throw_insn = new_insn;
  new_block->AppendMIR(new_insn);
  return new_block;
}

/* Parse a Dex method and insert it into the MIRGraph at the current insert point. */
void MIRGraph::InlineMethod(const DexFile::CodeItem* code_item, uint32_t access_flags,
                           InvokeType invoke_type ATTRIBUTE_UNUSED, uint16_t class_def_idx,
                           uint32_t method_idx, jobject class_loader, const DexFile& dex_file) {
  current_code_item_ = code_item;
  method_stack_.push_back(std::make_pair(current_method_, current_offset_));
  current_method_ = m_units_.size();
  current_offset_ = 0;
  // TODO: will need to snapshot stack image and use that as the mir context identification.
  m_units_.push_back(new (arena_) DexCompilationUnit(
      cu_, class_loader, Runtime::Current()->GetClassLinker(), dex_file,
      current_code_item_, class_def_idx, method_idx, access_flags,
      cu_->compiler_driver->GetVerifiedMethod(&dex_file, method_idx)));
  const uint16_t* code_ptr = current_code_item_->insns_;
  const uint16_t* code_end =
      current_code_item_->insns_ + current_code_item_->insns_size_in_code_units_;

  // TODO: need to rework expansion of block list & try_block_addr when inlining activated.
  // TUNING: use better estimate of basic blocks for following resize.
  block_list_.reserve(block_list_.size() + current_code_item_->insns_size_in_code_units_);
  // FindBlock lookup cache.
  ScopedArenaAllocator allocator(&cu_->arena_stack);
  ScopedArenaVector<uint16_t> dex_pc_to_block_map(allocator.Adapter());
  dex_pc_to_block_map.resize(current_code_item_->insns_size_in_code_units_ +
                             1 /* Fall-through on last insn; dead or punt to interpreter. */);

  // TODO: replace with explicit resize routine.  Using automatic extension side effect for now.
  try_block_addr_->SetBit(current_code_item_->insns_size_in_code_units_);
  try_block_addr_->ClearBit(current_code_item_->insns_size_in_code_units_);

  // If this is the first method, set up default entry and exit blocks.
  if (current_method_ == 0) {
    DCHECK(entry_block_ == nullptr);
    DCHECK(exit_block_ == nullptr);
    DCHECK_EQ(GetNumBlocks(), 0U);
    // Use id 0 to represent a null block.
    BasicBlock* null_block = CreateNewBB(kNullBlock);
    DCHECK_EQ(null_block->id, NullBasicBlockId);
    null_block->hidden = true;
    entry_block_ = CreateNewBB(kEntryBlock);
    exit_block_ = CreateNewBB(kExitBlock);
  } else {
    UNIMPLEMENTED(FATAL) << "Nested inlining not implemented.";
    /*
     * Will need to manage storage for ins & outs, push prevous state and update
     * insert point.
     */
  }

  /* Current block to record parsed instructions */
  BasicBlock* cur_block = CreateNewBB(kDalvikByteCode);
  DCHECK_EQ(current_offset_, 0U);
  cur_block->start_offset = current_offset_;
  // TODO: for inlining support, insert at the insert point rather than entry block.
  entry_block_->fall_through = cur_block->id;
  cur_block->predecessors.push_back(entry_block_->id);

  /* Identify code range in try blocks and set up the empty catch blocks */
  ProcessTryCatchBlocks(&dex_pc_to_block_map);

  uint64_t merged_df_flags = 0u;

  /* Parse all instructions and put them into containing basic blocks */
  while (code_ptr < code_end) {
    MIR *insn = NewMIR();
    insn->offset = current_offset_;
    insn->m_unit_index = current_method_;
    int width = ParseInsn(code_ptr, &insn->dalvikInsn);
    Instruction::Code opcode = insn->dalvikInsn.opcode;
    if (opcode_count_ != nullptr) {
      opcode_count_[static_cast<int>(opcode)]++;
    }

    int flags = insn->dalvikInsn.FlagsOf();
    int verify_flags = Instruction::VerifyFlagsOf(insn->dalvikInsn.opcode);

    uint64_t df_flags = GetDataFlowAttributes(insn);
    merged_df_flags |= df_flags;

    if (df_flags & DF_HAS_DEFS) {
      def_count_ += (df_flags & DF_A_WIDE) ? 2 : 1;
    }

    if (df_flags & DF_LVN) {
      cur_block->use_lvn = true;  // Run local value numbering on this basic block.
    }

    // Check for inline data block signatures.
    if (opcode == Instruction::NOP) {
      // A simple NOP will have a width of 1 at this point, embedded data NOP > 1.
      if ((width == 1) && ((current_offset_ & 0x1) == 0x1) && ((code_end - code_ptr) > 1)) {
        // Could be an aligning nop.  If an embedded data NOP follows, treat pair as single unit.
        uint16_t following_raw_instruction = code_ptr[1];
        if ((following_raw_instruction == Instruction::kSparseSwitchSignature) ||
            (following_raw_instruction == Instruction::kPackedSwitchSignature) ||
            (following_raw_instruction == Instruction::kArrayDataSignature)) {
          width += Instruction::At(code_ptr + 1)->SizeInCodeUnits();
        }
      }
      if (width == 1) {
        // It is a simple nop - treat normally.
        cur_block->AppendMIR(insn);
      } else {
        DCHECK(cur_block->fall_through == NullBasicBlockId);
        DCHECK(cur_block->taken == NullBasicBlockId);
        // Unreachable instruction, mark for no continuation and end basic block.
        flags &= ~Instruction::kContinue;
        FindBlock(current_offset_ + width, /* create */ true,
                  /* immed_pred_block_p */ nullptr, &dex_pc_to_block_map);
      }
    } else {
      cur_block->AppendMIR(insn);
    }

    // Associate the starting dex_pc for this opcode with its containing basic block.
    dex_pc_to_block_map[insn->offset] = cur_block->id;

    code_ptr += width;

    if (flags & Instruction::kBranch) {
      cur_block = ProcessCanBranch(cur_block, insn, current_offset_,
                                   width, flags, code_ptr, code_end, &dex_pc_to_block_map);
    } else if (flags & Instruction::kReturn) {
      cur_block->terminated_by_return = true;
      cur_block->fall_through = exit_block_->id;
      exit_block_->predecessors.push_back(cur_block->id);
      /*
       * Terminate the current block if there are instructions
       * afterwards.
       */
      if (code_ptr < code_end) {
        /*
         * Create a fallthrough block for real instructions
         * (incl. NOP).
         */
         FindBlock(current_offset_ + width, /* create */ true,
                   /* immed_pred_block_p */ nullptr, &dex_pc_to_block_map);
      }
    } else if (flags & Instruction::kThrow) {
      cur_block = ProcessCanThrow(cur_block, insn, current_offset_, width, flags, try_block_addr_,
                                  code_ptr, code_end, &dex_pc_to_block_map);
    } else if (flags & Instruction::kSwitch) {
      cur_block = ProcessCanSwitch(cur_block, insn, current_offset_, width,
                                   flags, &dex_pc_to_block_map);
    }
    if (verify_flags & Instruction::kVerifyVarArgRange ||
        verify_flags & Instruction::kVerifyVarArgRangeNonZero) {
      /*
       * The Quick backend's runtime model includes a gap between a method's
       * argument ("in") vregs and the rest of its vregs.  Handling a range instruction
       * which spans the gap is somewhat complicated, and should not happen
       * in normal usage of dx.  Punt to the interpreter.
       */
      int first_reg_in_range = insn->dalvikInsn.vC;
      int last_reg_in_range = first_reg_in_range + insn->dalvikInsn.vA - 1;
      if (IsInVReg(first_reg_in_range) != IsInVReg(last_reg_in_range)) {
        punt_to_interpreter_ = true;
      }
    }
    current_offset_ += width;
    BasicBlock* next_block = FindBlock(current_offset_, /* create */ false,
                                       /* immed_pred_block_p */ nullptr,
                                       &dex_pc_to_block_map);
    if (next_block) {
      /*
       * The next instruction could be the target of a previously parsed
       * forward branch so a block is already created. If the current
       * instruction is not an unconditional branch, connect them through
       * the fall-through link.
       */
      DCHECK(cur_block->fall_through == NullBasicBlockId ||
             GetBasicBlock(cur_block->fall_through) == next_block ||
             GetBasicBlock(cur_block->fall_through) == exit_block_);

      if ((cur_block->fall_through == NullBasicBlockId) && (flags & Instruction::kContinue)) {
        cur_block->fall_through = next_block->id;
        next_block->predecessors.push_back(cur_block->id);
      }
      cur_block = next_block;
    }
  }
  merged_df_flags_ = merged_df_flags;

  if (cu_->enable_debug & (1 << kDebugDumpCFG)) {
    DumpCFG("/sdcard/1_post_parse_cfg/", true);
  }

  if (cu_->verbose) {
    DumpMIRGraph();
  }

  // Check if there's been a fall-through out of the method code.
  BasicBlockId out_bb_id = dex_pc_to_block_map[current_code_item_->insns_size_in_code_units_];
  if (UNLIKELY(out_bb_id != NullBasicBlockId)) {
    // Eagerly calculate DFS order to determine if the block is dead.
    DCHECK(!DfsOrdersUpToDate());
    ComputeDFSOrders();
    BasicBlock* out_bb = GetBasicBlock(out_bb_id);
    DCHECK(out_bb != nullptr);
    if (out_bb->block_type != kDead) {
      LOG(WARNING) << "Live fall-through out of method in " << PrettyMethod(method_idx, dex_file);
      SetPuntToInterpreter(true);
    }
  }
}

void MIRGraph::ShowOpcodeStats() {
  DCHECK(opcode_count_ != nullptr);
  LOG(INFO) << "Opcode Count";
  for (int i = 0; i < kNumPackedOpcodes; i++) {
    if (opcode_count_[i] != 0) {
      LOG(INFO) << "-C- " << Instruction::Name(static_cast<Instruction::Code>(i))
                << " " << opcode_count_[i];
    }
  }
}

uint64_t MIRGraph::GetDataFlowAttributes(Instruction::Code opcode) {
  DCHECK_LT((size_t) opcode, (sizeof(oat_data_flow_attributes_) / sizeof(oat_data_flow_attributes_[0])));
  return oat_data_flow_attributes_[opcode];
}

uint64_t MIRGraph::GetDataFlowAttributes(MIR* mir) {
  DCHECK(mir != nullptr);
  Instruction::Code opcode = mir->dalvikInsn.opcode;
  return GetDataFlowAttributes(opcode);
}

// The path can easily surpass FS limits because of parameters etc. Use pathconf to get FS
// restrictions here. Note that a successful invocation will return an actual value. If the path
// is too long for some reason, the return will be ENAMETOOLONG. Then cut off part of the name.
//
// It's possible the path is not valid, or some other errors appear. In that case return false.
static bool CreateDumpFile(std::string& fname, const char* dir_prefix, NarrowDexOffset start_offset,
                           const char *suffix, int nr, std::string* output) {
  std::string dir = StringPrintf("./%s", dir_prefix);
  int64_t max_name_length = pathconf(dir.c_str(), _PC_NAME_MAX);
  if (max_name_length <= 0) {
    PLOG(ERROR) << "Could not get file name restrictions for " << dir;
    return false;
  }

  std::string name = StringPrintf("%s%x%s_%d.dot", fname.c_str(), start_offset,
                                  suffix == nullptr ? "" : suffix, nr);
  std::string fpath;
  if (static_cast<int64_t>(name.size()) > max_name_length) {
    std::string suffix_str = StringPrintf("_%d.dot", nr);
    name = name.substr(0, static_cast<size_t>(max_name_length) - suffix_str.size()) + suffix_str;
  }
  // Sanity check.
  DCHECK_LE(name.size(), static_cast<size_t>(max_name_length));

  *output = StringPrintf("%s%s", dir_prefix, name.c_str());
  return true;
}

// TODO: use a configurable base prefix, and adjust callers to supply pass name.
/* Dump the CFG into a DOT graph */
void MIRGraph::DumpCFG(const char* dir_prefix, bool all_blocks, const char *suffix) {
  FILE* file;
  static AtomicInteger cnt(0);

  // Increment counter to get a unique file number.
  cnt++;
  int nr = cnt.LoadRelaxed();

  std::string fname(PrettyMethod(cu_->method_idx, *cu_->dex_file));
  ReplaceSpecialChars(fname);
  std::string fpath;
  if (!CreateDumpFile(fname, dir_prefix, GetBasicBlock(GetEntryBlock()->fall_through)->start_offset,
                      suffix, nr, &fpath)) {
    LOG(ERROR) << "Could not create dump file name for " << fname;
    return;
  }
  file = fopen(fpath.c_str(), "w");
  if (file == nullptr) {
    PLOG(ERROR) << "Could not open " << fpath << " for DumpCFG.";
    return;
  }
  fprintf(file, "digraph G {\n");

  fprintf(file, "  rankdir=TB\n");

  int num_blocks = all_blocks ? GetNumBlocks() : num_reachable_blocks_;
  int idx;

  for (idx = 0; idx < num_blocks; idx++) {
    int block_idx = all_blocks ? idx : dfs_order_[idx];
    BasicBlock* bb = GetBasicBlock(block_idx);
    if (bb == nullptr) continue;
    if (bb->block_type == kDead) continue;
    if (bb->hidden) continue;
    if (bb->block_type == kEntryBlock) {
      fprintf(file, "  entry_%d [shape=Mdiamond];\n", bb->id);
    } else if (bb->block_type == kExitBlock) {
      fprintf(file, "  exit_%d [shape=Mdiamond];\n", bb->id);
    } else if (bb->block_type == kDalvikByteCode) {
      fprintf(file, "  block%04x_%d [shape=record,label = \"{ \\\n",
              bb->start_offset, bb->id);
      const MIR* mir;
        fprintf(file, "    {block id %d\\l}%s\\\n", bb->id,
                bb->first_mir_insn ? " | " : " ");
        for (mir = bb->first_mir_insn; mir; mir = mir->next) {
            int opcode = mir->dalvikInsn.opcode;
            fprintf(file, "    {%04x %s %s %s %s %s %s %s %s %s\\l}%s\\\n", mir->offset,
                      mir->ssa_rep ? GetDalvikDisassembly(mir) :
                      !MIR::DecodedInstruction::IsPseudoMirOp(opcode) ?
                        Instruction::Name(mir->dalvikInsn.opcode) :
                        extended_mir_op_names_[opcode - kMirOpFirst],
                      (mir->optimization_flags & MIR_IGNORE_RANGE_CHECK) != 0 ? " no_rangecheck" : " ",
                      (mir->optimization_flags & MIR_IGNORE_NULL_CHECK) != 0 ? " no_nullcheck" : " ",
                      (mir->optimization_flags & MIR_IGNORE_SUSPEND_CHECK) != 0 ? " no_suspendcheck" : " ",
                      (mir->optimization_flags & MIR_STORE_NON_TEMPORAL) != 0 ? " non_temporal" : " ",
                      (mir->optimization_flags & MIR_CALLEE) != 0 ? " inlined" : " ",
                      (mir->optimization_flags & MIR_CLASS_IS_INITIALIZED) != 0 ? " cl_inited" : " ",
                      (mir->optimization_flags & MIR_CLASS_IS_IN_DEX_CACHE) != 0 ? " cl_in_cache" : " ",
                      (mir->optimization_flags & MIR_IGNORE_DIV_ZERO_CHECK) != 0 ? " no_div_check" : " ",
                      mir->next ? " | " : " ");
        }
        fprintf(file, "  }\"];\n\n");
    } else if (bb->block_type == kExceptionHandling) {
      char block_name[BLOCK_NAME_LEN];

      GetBlockName(bb, block_name);
      fprintf(file, "  %s [shape=invhouse];\n", block_name);
    }

    char block_name1[BLOCK_NAME_LEN], block_name2[BLOCK_NAME_LEN];

    if (bb->taken != NullBasicBlockId) {
      GetBlockName(bb, block_name1);
      GetBlockName(GetBasicBlock(bb->taken), block_name2);
      fprintf(file, "  %s:s -> %s:n [style=dotted]\n",
              block_name1, block_name2);
    }
    if (bb->fall_through != NullBasicBlockId) {
      GetBlockName(bb, block_name1);
      GetBlockName(GetBasicBlock(bb->fall_through), block_name2);
      fprintf(file, "  %s:s -> %s:n\n", block_name1, block_name2);
    }

    if (bb->successor_block_list_type != kNotUsed) {
      fprintf(file, "  succ%04x_%d [shape=%s,label = \"{ \\\n",
              bb->start_offset, bb->id,
              (bb->successor_block_list_type == kCatch) ?  "Mrecord" : "record");

      int last_succ_id = static_cast<int>(bb->successor_blocks.size() - 1u);
      int succ_id = 0;
      for (SuccessorBlockInfo* successor_block_info : bb->successor_blocks) {
        BasicBlock* dest_block = GetBasicBlock(successor_block_info->block);
        fprintf(file, "    {<f%d> %04x: %04x\\l}%s\\\n",
                succ_id,
                successor_block_info->key,
                dest_block->start_offset,
                (succ_id != last_succ_id) ? " | " : " ");
        ++succ_id;
      }
      fprintf(file, "  }\"];\n\n");

      GetBlockName(bb, block_name1);
      fprintf(file, "  %s:s -> succ%04x_%d:n [style=dashed]\n",
              block_name1, bb->start_offset, bb->id);

      // Link the successor pseudo-block with all of its potential targets.
      succ_id = 0;
      for (SuccessorBlockInfo* successor_block_info : bb->successor_blocks) {
        BasicBlock* dest_block = GetBasicBlock(successor_block_info->block);

        GetBlockName(dest_block, block_name2);
        fprintf(file, "  succ%04x_%d:f%d:e -> %s:n\n", bb->start_offset,
                bb->id, succ_id++, block_name2);
      }
    }
    fprintf(file, "\n");

    if (cu_->verbose) {
      /* Display the dominator tree */
      GetBlockName(bb, block_name1);
      fprintf(file, "  cfg%s [label=\"%s\", shape=none];\n",
              block_name1, block_name1);
      if (bb->i_dom) {
        GetBlockName(GetBasicBlock(bb->i_dom), block_name2);
        fprintf(file, "  cfg%s:s -> cfg%s:n\n\n", block_name2, block_name1);
      }
    }
  }
  fprintf(file, "}\n");
  fclose(file);
}

/* Insert an MIR instruction to the end of a basic block. */
void BasicBlock::AppendMIR(MIR* mir) {
  // Insert it after the last MIR.
  InsertMIRListAfter(last_mir_insn, mir, mir);
}

void BasicBlock::AppendMIRList(MIR* first_list_mir, MIR* last_list_mir) {
  // Insert it after the last MIR.
  InsertMIRListAfter(last_mir_insn, first_list_mir, last_list_mir);
}

void BasicBlock::AppendMIRList(const std::vector<MIR*>& insns) {
  for (std::vector<MIR*>::const_iterator it = insns.begin(); it != insns.end(); it++) {
    MIR* new_mir = *it;

    // Add a copy of each MIR.
    InsertMIRListAfter(last_mir_insn, new_mir, new_mir);
  }
}

/* Insert a MIR instruction after the specified MIR. */
void BasicBlock::InsertMIRAfter(MIR* current_mir, MIR* new_mir) {
  InsertMIRListAfter(current_mir, new_mir, new_mir);
}

void BasicBlock::InsertMIRListAfter(MIR* insert_after, MIR* first_list_mir, MIR* last_list_mir) {
  // If no MIR, we are done.
  if (first_list_mir == nullptr || last_list_mir == nullptr) {
    return;
  }

  // If insert_after is null, assume BB is empty.
  if (insert_after == nullptr) {
    first_mir_insn = first_list_mir;
    last_mir_insn = last_list_mir;
    last_list_mir->next = nullptr;
  } else {
    MIR* after_list = insert_after->next;
    insert_after->next = first_list_mir;
    last_list_mir->next = after_list;
    if (after_list == nullptr) {
      last_mir_insn = last_list_mir;
    }
  }

  // Set this BB to be the basic block of the MIRs.
  MIR* last = last_list_mir->next;
  for (MIR* mir = first_list_mir; mir != last; mir = mir->next) {
    mir->bb = id;
  }
}

/* Insert an MIR instruction to the head of a basic block. */
void BasicBlock::PrependMIR(MIR* mir) {
  InsertMIRListBefore(first_mir_insn, mir, mir);
}

void BasicBlock::PrependMIRList(MIR* first_list_mir, MIR* last_list_mir) {
  // Insert it before the first MIR.
  InsertMIRListBefore(first_mir_insn, first_list_mir, last_list_mir);
}

void BasicBlock::PrependMIRList(const std::vector<MIR*>& to_add) {
  for (std::vector<MIR*>::const_iterator it = to_add.begin(); it != to_add.end(); it++) {
    MIR* mir = *it;

    InsertMIRListBefore(first_mir_insn, mir, mir);
  }
}

/* Insert a MIR instruction before the specified MIR. */
void BasicBlock::InsertMIRBefore(MIR* current_mir, MIR* new_mir) {
  // Insert as a single element list.
  return InsertMIRListBefore(current_mir, new_mir, new_mir);
}

MIR* BasicBlock::FindPreviousMIR(MIR* mir) {
  MIR* current = first_mir_insn;

  while (current != nullptr) {
    MIR* next = current->next;

    if (next == mir) {
      return current;
    }

    current = next;
  }

  return nullptr;
}

void BasicBlock::InsertMIRListBefore(MIR* insert_before, MIR* first_list_mir, MIR* last_list_mir) {
  // If no MIR, we are done.
  if (first_list_mir == nullptr || last_list_mir == nullptr) {
    return;
  }

  // If insert_before is null, assume BB is empty.
  if (insert_before == nullptr) {
    first_mir_insn = first_list_mir;
    last_mir_insn = last_list_mir;
    last_list_mir->next = nullptr;
  } else {
    if (first_mir_insn == insert_before) {
      last_list_mir->next = first_mir_insn;
      first_mir_insn = first_list_mir;
    } else {
      // Find the preceding MIR.
      MIR* before_list = FindPreviousMIR(insert_before);
      DCHECK(before_list != nullptr);
      before_list->next = first_list_mir;
      last_list_mir->next = insert_before;
    }
  }

  // Set this BB to be the basic block of the MIRs.
  for (MIR* mir = first_list_mir; mir != last_list_mir->next; mir = mir->next) {
    mir->bb = id;
  }
}

bool BasicBlock::RemoveMIR(MIR* mir) {
  // Remove as a single element list.
  return RemoveMIRList(mir, mir);
}

bool BasicBlock::RemoveMIRList(MIR* first_list_mir, MIR* last_list_mir) {
  if (first_list_mir == nullptr) {
    return false;
  }

  // Try to find the MIR.
  MIR* before_list = nullptr;
  MIR* after_list = nullptr;

  // If we are removing from the beginning of the MIR list.
  if (first_mir_insn == first_list_mir) {
    before_list = nullptr;
  } else {
    before_list = FindPreviousMIR(first_list_mir);
    if (before_list == nullptr) {
      // We did not find the mir.
      return false;
    }
  }

  // Remove the BB information and also find the after_list.
  for (MIR* mir = first_list_mir; mir != last_list_mir->next; mir = mir->next) {
    mir->bb = NullBasicBlockId;
  }

  after_list = last_list_mir->next;

  // If there is nothing before the list, after_list is the first_mir.
  if (before_list == nullptr) {
    first_mir_insn = after_list;
  } else {
    before_list->next = after_list;
  }

  // If there is nothing after the list, before_list is last_mir.
  if (after_list == nullptr) {
    last_mir_insn = before_list;
  }

  return true;
}

MIR* BasicBlock::GetFirstNonPhiInsn() {
  MIR* mir = first_mir_insn;
  while (mir != nullptr && static_cast<int>(mir->dalvikInsn.opcode) == kMirOpPhi) {
    mir = mir->next;
  }
  return mir;
}

MIR* BasicBlock::GetNextUnconditionalMir(MIRGraph* mir_graph, MIR* current) {
  MIR* next_mir = nullptr;

  if (current != nullptr) {
    next_mir = current->next;
  }

  if (next_mir == nullptr) {
    // Only look for next MIR that follows unconditionally.
    if ((taken == NullBasicBlockId) && (fall_through != NullBasicBlockId)) {
      next_mir = mir_graph->GetBasicBlock(fall_through)->first_mir_insn;
    }
  }

  return next_mir;
}

static void FillTypeSizeString(uint32_t type_size, std::string* decoded_mir) {
  DCHECK(decoded_mir != nullptr);
  OpSize type = static_cast<OpSize>(type_size >> 16);
  uint16_t vect_size = (type_size & 0xFFFF);

  // Now print the type and vector size.
  std::stringstream ss;
  ss << " (type:";
  ss << type;
  ss << " vectsize:";
  ss << vect_size;
  ss << ")";

  decoded_mir->append(ss.str());
}

void MIRGraph::DisassembleExtendedInstr(const MIR* mir, std::string* decoded_mir) {
  DCHECK(decoded_mir != nullptr);
  int opcode = mir->dalvikInsn.opcode;
  SSARepresentation* ssa_rep = mir->ssa_rep;
  int defs = (ssa_rep != nullptr) ? ssa_rep->num_defs : 0;
  int uses = (ssa_rep != nullptr) ? ssa_rep->num_uses : 0;

  if (opcode < kMirOpFirst) {
    return;  // It is not an extended instruction.
  }

  decoded_mir->append(extended_mir_op_names_[opcode - kMirOpFirst]);

  switch (opcode) {
    case kMirOpPhi: {
      if (defs > 0 && uses > 0) {
        BasicBlockId* incoming = mir->meta.phi_incoming;
        decoded_mir->append(StringPrintf(" %s = (%s",
                           GetSSANameWithConst(ssa_rep->defs[0], true).c_str(),
                           GetSSANameWithConst(ssa_rep->uses[0], true).c_str()));
        decoded_mir->append(StringPrintf(":%d", incoming[0]));
        for (int i = 1; i < uses; i++) {
          decoded_mir->append(StringPrintf(", %s:%d", GetSSANameWithConst(ssa_rep->uses[i], true).c_str(), incoming[i]));
        }
        decoded_mir->append(")");
      }
      break;
    }
    case kMirOpCopy:
      if (ssa_rep != nullptr) {
        decoded_mir->append(" ");
        decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[0], false));
        if (defs > 1) {
          decoded_mir->append(", ");
          decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[1], false));
        }
        decoded_mir->append(" = ");
        decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[0], false));
        if (uses > 1) {
          decoded_mir->append(", ");
          decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[1], false));
        }
      } else {
        decoded_mir->append(StringPrintf(" v%d = v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB));
      }
      break;
    case kMirOpFusedCmplFloat:
    case kMirOpFusedCmpgFloat:
    case kMirOpFusedCmplDouble:
    case kMirOpFusedCmpgDouble:
    case kMirOpFusedCmpLong:
      if (ssa_rep != nullptr) {
        decoded_mir->append(" ");
        decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[0], false));
        for (int i = 1; i < uses; i++) {
          decoded_mir->append(", ");
          decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[i], false));
        }
      } else {
        decoded_mir->append(StringPrintf(" v%d, v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB));
      }
      break;
    case kMirOpMoveVector:
      decoded_mir->append(StringPrintf(" vect%d = vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB));
      FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir);
      break;
    case kMirOpPackedAddition:
      decoded_mir->append(StringPrintf(" vect%d = vect%d + vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB));
      FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir);
      break;
    case kMirOpPackedMultiply:
      decoded_mir->append(StringPrintf(" vect%d = vect%d * vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB));
      FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir);
      break;
    case kMirOpPackedSubtract:
      decoded_mir->append(StringPrintf(" vect%d = vect%d - vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB));
      FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir);
      break;
    case kMirOpPackedAnd:
      decoded_mir->append(StringPrintf(" vect%d = vect%d & vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB));
      FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir);
      break;
    case kMirOpPackedOr:
      decoded_mir->append(StringPrintf(" vect%d = vect%d \\| vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB));
      FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir);
      break;
    case kMirOpPackedXor:
      decoded_mir->append(StringPrintf(" vect%d = vect%d ^ vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB));
      FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir);
      break;
    case kMirOpPackedShiftLeft:
      decoded_mir->append(StringPrintf(" vect%d = vect%d \\<\\< %d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB));
      FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir);
      break;
    case kMirOpPackedUnsignedShiftRight:
      decoded_mir->append(StringPrintf(" vect%d = vect%d \\>\\>\\> %d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB));
      FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir);
      break;
    case kMirOpPackedSignedShiftRight:
      decoded_mir->append(StringPrintf(" vect%d = vect%d \\>\\> %d", mir->dalvikInsn.vA, mir->dalvikInsn.vA, mir->dalvikInsn.vB));
      FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir);
      break;
    case kMirOpConstVector:
      decoded_mir->append(StringPrintf(" vect%d = %x, %x, %x, %x", mir->dalvikInsn.vA, mir->dalvikInsn.arg[0],
                                      mir->dalvikInsn.arg[1], mir->dalvikInsn.arg[2], mir->dalvikInsn.arg[3]));
      break;
    case kMirOpPackedSet:
      if (ssa_rep != nullptr) {
        decoded_mir->append(StringPrintf(" vect%d = %s", mir->dalvikInsn.vA,
              GetSSANameWithConst(ssa_rep->uses[0], false).c_str()));
        if (uses > 1) {
          decoded_mir->append(", ");
          decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[1], false));
        }
      } else {
        decoded_mir->append(StringPrintf(" vect%d = v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB));
      }
      FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir);
      break;
    case kMirOpPackedAddReduce:
      if (ssa_rep != nullptr) {
        decoded_mir->append(" ");
        decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[0], false));
        if (defs > 1) {
          decoded_mir->append(", ");
          decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[1], false));
        }
        decoded_mir->append(StringPrintf(" = vect%d + %s", mir->dalvikInsn.vB,
            GetSSANameWithConst(ssa_rep->uses[0], false).c_str()));
        if (uses > 1) {
          decoded_mir->append(", ");
          decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[1], false));
        }
      } else {
        decoded_mir->append(StringPrintf("v%d = vect%d + v%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB, mir->dalvikInsn.vA));
      }
      FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir);
      break;
    case kMirOpPackedReduce:
      if (ssa_rep != nullptr) {
        decoded_mir->append(" ");
        decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[0], false));
        if (defs > 1) {
          decoded_mir->append(", ");
          decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[1], false));
        }
        decoded_mir->append(StringPrintf(" = vect%d (extr_idx:%d)", mir->dalvikInsn.vB, mir->dalvikInsn.arg[0]));
      } else {
        decoded_mir->append(StringPrintf(" v%d = vect%d (extr_idx:%d)", mir->dalvikInsn.vA,
                                         mir->dalvikInsn.vB, mir->dalvikInsn.arg[0]));
      }
      FillTypeSizeString(mir->dalvikInsn.vC, decoded_mir);
      break;
    case kMirOpReserveVectorRegisters:
    case kMirOpReturnVectorRegisters:
      decoded_mir->append(StringPrintf(" vect%d - vect%d", mir->dalvikInsn.vA, mir->dalvikInsn.vB));
      break;
    case kMirOpMemBarrier: {
      decoded_mir->append(" type:");
      std::stringstream ss;
      ss << static_cast<MemBarrierKind>(mir->dalvikInsn.vA);
      decoded_mir->append(ss.str());
      break;
    }
    case kMirOpPackedArrayGet:
    case kMirOpPackedArrayPut:
      decoded_mir->append(StringPrintf(" vect%d", mir->dalvikInsn.vA));
      if (ssa_rep != nullptr) {
        decoded_mir->append(StringPrintf(", %s[%s]",
                                        GetSSANameWithConst(ssa_rep->uses[0], false).c_str(),
                                        GetSSANameWithConst(ssa_rep->uses[1], false).c_str()));
      } else {
        decoded_mir->append(StringPrintf(", v%d[v%d]", mir->dalvikInsn.vB, mir->dalvikInsn.vC));
      }
      FillTypeSizeString(mir->dalvikInsn.arg[0], decoded_mir);
      break;
    case kMirOpMaddInt:
    case kMirOpMsubInt:
    case kMirOpMaddLong:
    case kMirOpMsubLong:
      if (ssa_rep != nullptr) {
        decoded_mir->append(" ");
        decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[0], false));
        if (defs > 1) {
          decoded_mir->append(", ");
          decoded_mir->append(GetSSANameWithConst(ssa_rep->defs[1], false));
        }
        for (int i = 0; i < uses; i++) {
          decoded_mir->append(", ");
          decoded_mir->append(GetSSANameWithConst(ssa_rep->uses[i], false));
        }
      } else {
        decoded_mir->append(StringPrintf(" v%d, v%d, v%d, v%d",
                                         mir->dalvikInsn.vA, mir->dalvikInsn.vB,
                                         mir->dalvikInsn.vC, mir->dalvikInsn.arg[0]));
      }
      break;
    default:
      break;
  }
}

char* MIRGraph::GetDalvikDisassembly(const MIR* mir) {
  MIR::DecodedInstruction insn = mir->dalvikInsn;
  std::string str;
  int flags = 0;
  int opcode = insn.opcode;
  char* ret;
  bool nop = false;
  SSARepresentation* ssa_rep = mir->ssa_rep;
  Instruction::Format dalvik_format = Instruction::k10x;  // Default to no-operand format.

  // Handle special cases that recover the original dalvik instruction.
  if ((opcode == kMirOpCheck) || (opcode == kMirOpCheckPart2)) {
    str.append(extended_mir_op_names_[opcode - kMirOpFirst]);
    str.append(": ");
    // Recover the original Dex instruction.
    insn = mir->meta.throw_insn->dalvikInsn;
    ssa_rep = mir->meta.throw_insn->ssa_rep;
    opcode = insn.opcode;
  } else if (opcode == kMirOpNop) {
    str.append("[");
    if (mir->offset < current_code_item_->insns_size_in_code_units_) {
      // Recover original opcode.
      insn.opcode = Instruction::At(current_code_item_->insns_ + mir->offset)->Opcode();
      opcode = insn.opcode;
    }
    nop = true;
  }
  int defs = (ssa_rep != nullptr) ? ssa_rep->num_defs : 0;
  int uses = (ssa_rep != nullptr) ? ssa_rep->num_uses : 0;

  if (MIR::DecodedInstruction::IsPseudoMirOp(opcode)) {
    // Note that this does not check the MIR's opcode in all cases. In cases where it
    // recovered dalvik instruction, it uses opcode of that instead of the extended one.
    DisassembleExtendedInstr(mir, &str);
  } else {
    dalvik_format = Instruction::FormatOf(insn.opcode);
    flags = insn.FlagsOf();
    str.append(Instruction::Name(insn.opcode));

    // For invokes-style formats, treat wide regs as a pair of singles.
    bool show_singles = ((dalvik_format == Instruction::k35c) ||
                         (dalvik_format == Instruction::k3rc));
    if (defs != 0) {
      str.append(" ");
      str.append(GetSSANameWithConst(ssa_rep->defs[0], false));
      if (defs > 1) {
        str.append(", ");
        str.append(GetSSANameWithConst(ssa_rep->defs[1], false));
      }
      if (uses != 0) {
        str.append(", ");
      }
    }
    for (int i = 0; i < uses; i++) {
      str.append(" ");
      str.append(GetSSANameWithConst(ssa_rep->uses[i], show_singles));
      if (!show_singles && (reg_location_ != nullptr) && reg_location_[i].wide) {
        // For the listing, skip the high sreg.
        i++;
      }
      if (i != (uses - 1)) {
        str.append(",");
      }
    }

    switch (dalvik_format) {
      case Instruction::k11n:  // Add one immediate from vB.
      case Instruction::k21s:
      case Instruction::k31i:
      case Instruction::k21h:
        str.append(StringPrintf(", #0x%x", insn.vB));
        break;
      case Instruction::k51l:  // Add one wide immediate.
        str.append(StringPrintf(", #%" PRId64, insn.vB_wide));
        break;
      case Instruction::k21c:  // One register, one string/type/method index.
      case Instruction::k31c:
        str.append(StringPrintf(", index #0x%x", insn.vB));
        break;
      case Instruction::k22c:  // Two registers, one string/type/method index.
        str.append(StringPrintf(", index #0x%x", insn.vC));
        break;
      case Instruction::k22s:  // Add one immediate from vC.
      case Instruction::k22b:
        str.append(StringPrintf(", #0x%x", insn.vC));
        break;
      default:
        // Nothing left to print.
        break;
    }

    if ((flags & Instruction::kBranch) != 0) {
      // For branches, decode the instructions to print out the branch targets.
      int offset = 0;
      switch (dalvik_format) {
        case Instruction::k21t:
          offset = insn.vB;
          break;
        case Instruction::k22t:
          offset = insn.vC;
          break;
        case Instruction::k10t:
        case Instruction::k20t:
        case Instruction::k30t:
          offset = insn.vA;
          break;
        default:
          LOG(FATAL) << "Unexpected branch format " << dalvik_format << " from " << insn.opcode;
          break;
      }
      str.append(StringPrintf(", 0x%x (%c%x)", mir->offset + offset,
                              offset > 0 ? '+' : '-', offset > 0 ? offset : -offset));
    }

    if (nop) {
      str.append("]--optimized away");
    }
  }
  int length = str.length() + 1;
  ret = arena_->AllocArray<char>(length, kArenaAllocDFInfo);
  strncpy(ret, str.c_str(), length);
  return ret;
}

/* Turn method name into a legal Linux file name */
void MIRGraph::ReplaceSpecialChars(std::string& str) {
  static const struct { const char before; const char after; } match[] = {
    {'/', '-'}, {';', '#'}, {' ', '#'}, {'$', '+'},
    {'(', '@'}, {')', '@'}, {'<', '='}, {'>', '='}
  };
  for (unsigned int i = 0; i < sizeof(match)/sizeof(match[0]); i++) {
    std::replace(str.begin(), str.end(), match[i].before, match[i].after);
  }
}

std::string MIRGraph::GetSSAName(int ssa_reg) {
  // TODO: This value is needed for debugging. Currently, we compute this and then copy to the
  //       arena. We should be smarter and just place straight into the arena, or compute the
  //       value more lazily.
  int vreg = SRegToVReg(ssa_reg);
  if (vreg >= static_cast<int>(GetFirstTempVR())) {
    return StringPrintf("t%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg));
  } else {
    return StringPrintf("v%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg));
  }
}

// Similar to GetSSAName, but if ssa name represents an immediate show that as well.
std::string MIRGraph::GetSSANameWithConst(int ssa_reg, bool singles_only) {
  if (reg_location_ == nullptr) {
    // Pre-SSA - just use the standard name.
    return GetSSAName(ssa_reg);
  }
  if (IsConst(reg_location_[ssa_reg])) {
    if (!singles_only && reg_location_[ssa_reg].wide &&
        !reg_location_[ssa_reg].high_word) {
      return StringPrintf("v%d_%d#0x%" PRIx64, SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg),
                          ConstantValueWide(reg_location_[ssa_reg]));
    } else {
      return StringPrintf("v%d_%d#0x%x", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg),
                          ConstantValue(reg_location_[ssa_reg]));
    }
  } else {
    int vreg = SRegToVReg(ssa_reg);
    if (vreg >= static_cast<int>(GetFirstTempVR())) {
      return StringPrintf("t%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg));
    } else {
      return StringPrintf("v%d_%d", SRegToVReg(ssa_reg), GetSSASubscript(ssa_reg));
    }
  }
}

void MIRGraph::GetBlockName(BasicBlock* bb, char* name) {
  switch (bb->block_type) {
    case kEntryBlock:
      snprintf(name, BLOCK_NAME_LEN, "entry_%d", bb->id);
      break;
    case kExitBlock:
      snprintf(name, BLOCK_NAME_LEN, "exit_%d", bb->id);
      break;
    case kDalvikByteCode:
      snprintf(name, BLOCK_NAME_LEN, "block%04x_%d", bb->start_offset, bb->id);
      break;
    case kExceptionHandling:
      snprintf(name, BLOCK_NAME_LEN, "exception%04x_%d", bb->start_offset,
               bb->id);
      break;
    default:
      snprintf(name, BLOCK_NAME_LEN, "_%d", bb->id);
      break;
  }
}

const char* MIRGraph::GetShortyFromMethodReference(const MethodReference& target_method) {
  const DexFile::MethodId& method_id =
      target_method.dex_file->GetMethodId(target_method.dex_method_index);
  return target_method.dex_file->GetShorty(method_id.proto_idx_);
}

/* Debug Utility - dump a compilation unit */
void MIRGraph::DumpMIRGraph() {
  const char* block_type_names[] = {
    "Null Block",
    "Entry Block",
    "Code Block",
    "Exit Block",
    "Exception Handling",
    "Catch Block"
  };

  LOG(INFO) << "Compiling " << PrettyMethod(cu_->method_idx, *cu_->dex_file);
  LOG(INFO) << GetInsns(0) << " insns";
  LOG(INFO) << GetNumBlocks() << " blocks in total";

  for (BasicBlock* bb : block_list_) {
    LOG(INFO) << StringPrintf("Block %d (%s) (insn %04x - %04x%s)",
        bb->id,
        block_type_names[bb->block_type],
        bb->start_offset,
        bb->last_mir_insn ? bb->last_mir_insn->offset : bb->start_offset,
        bb->last_mir_insn ? "" : " empty");
    if (bb->taken != NullBasicBlockId) {
      LOG(INFO) << "  Taken branch: block " << bb->taken
                << "(0x" << std::hex << GetBasicBlock(bb->taken)->start_offset << ")";
    }
    if (bb->fall_through != NullBasicBlockId) {
      LOG(INFO) << "  Fallthrough : block " << bb->fall_through
                << " (0x" << std::hex << GetBasicBlock(bb->fall_through)->start_offset << ")";
    }
  }
}

/*
 * Build an array of location records for the incoming arguments.
 * Note: one location record per word of arguments, with dummy
 * high-word loc for wide arguments.  Also pull up any following
 * MOVE_RESULT and incorporate it into the invoke.
 */
CallInfo* MIRGraph::NewMemCallInfo(BasicBlock* bb, MIR* mir, InvokeType type, bool is_range) {
  CallInfo* info = static_cast<CallInfo*>(arena_->Alloc(sizeof(CallInfo),
                                                        kArenaAllocMisc));
  MIR* move_result_mir = FindMoveResult(bb, mir);
  if (move_result_mir == nullptr) {
    info->result.location = kLocInvalid;
  } else {
    info->result = GetRawDest(move_result_mir);
    move_result_mir->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
  }
  info->num_arg_words = mir->ssa_rep->num_uses;
  info->args = (info->num_arg_words == 0) ? nullptr :
      arena_->AllocArray<RegLocation>(info->num_arg_words, kArenaAllocMisc);
  for (size_t i = 0; i < info->num_arg_words; i++) {
    info->args[i] = GetRawSrc(mir, i);
  }
  info->opt_flags = mir->optimization_flags;
  info->type = type;
  info->is_range = is_range;
  if (IsInstructionQuickInvoke(mir->dalvikInsn.opcode)) {
    const auto& method_info = GetMethodLoweringInfo(mir);
    info->method_ref = method_info.GetTargetMethod();
  } else {
    info->method_ref = MethodReference(GetCurrentDexCompilationUnit()->GetDexFile(),
                                       mir->dalvikInsn.vB);
  }
  info->index = mir->dalvikInsn.vB;
  info->offset = mir->offset;
  info->mir = mir;
  return info;
}

// Allocate a new MIR.
MIR* MIRGraph::NewMIR() {
  MIR* mir = new (arena_) MIR();
  return mir;
}

// Allocate a new basic block.
BasicBlock* MIRGraph::NewMemBB(BBType block_type, int block_id) {
  BasicBlock* bb = new (arena_) BasicBlock(block_id, block_type, arena_);

  // TUNING: better estimate of the exit block predecessors?
  bb->predecessors.reserve((block_type == kExitBlock) ? 2048 : 2);
  block_id_map_.Put(block_id, block_id);
  return bb;
}

void MIRGraph::InitializeConstantPropagation() {
  is_constant_v_ = new (arena_) ArenaBitVector(arena_, GetNumSSARegs(), false);
  constant_values_ = arena_->AllocArray<int>(GetNumSSARegs(), kArenaAllocDFInfo);
}

void MIRGraph::InitializeMethodUses() {
  // The gate starts by initializing the use counts.
  int num_ssa_regs = GetNumSSARegs();
  use_counts_.clear();
  use_counts_.reserve(num_ssa_regs + 32);
  use_counts_.resize(num_ssa_regs, 0u);
  raw_use_counts_.clear();
  raw_use_counts_.reserve(num_ssa_regs + 32);
  raw_use_counts_.resize(num_ssa_regs, 0u);
}

void MIRGraph::SSATransformationStart() {
  DCHECK(temp_scoped_alloc_.get() == nullptr);
  temp_scoped_alloc_.reset(ScopedArenaAllocator::Create(&cu_->arena_stack));
  temp_.ssa.num_vregs = GetNumOfCodeAndTempVRs();
  temp_.ssa.work_live_vregs = new (temp_scoped_alloc_.get()) ArenaBitVector(
      temp_scoped_alloc_.get(), temp_.ssa.num_vregs, false, kBitMapRegisterV);
}

void MIRGraph::SSATransformationEnd() {
  // Verify the dataflow information after the pass.
  if (cu_->enable_debug & (1 << kDebugVerifyDataflow)) {
    VerifyDataflow();
  }

  temp_.ssa.num_vregs = 0u;
  temp_.ssa.work_live_vregs = nullptr;
  DCHECK(temp_.ssa.def_block_matrix == nullptr);
  temp_.ssa.phi_node_blocks = nullptr;
  DCHECK(temp_scoped_alloc_.get() != nullptr);
  temp_scoped_alloc_.reset();

  // Update the maximum number of reachable blocks.
  max_num_reachable_blocks_ = num_reachable_blocks_;

  // Mark MIR SSA representations as up to date.
  mir_ssa_rep_up_to_date_ = true;
}

size_t MIRGraph::GetNumDalvikInsns() const {
  size_t cumulative_size = 0u;
  bool counted_current_item = false;
  const uint8_t size_for_null_code_item = 2u;

  for (auto it : m_units_) {
    const DexFile::CodeItem* code_item = it->GetCodeItem();
    // Even if the code item is null, we still count non-zero value so that
    // each m_unit is counted as having impact.
    cumulative_size += (code_item == nullptr ?
        size_for_null_code_item : code_item->insns_size_in_code_units_);
    if (code_item == current_code_item_) {
      counted_current_item = true;
    }
  }

  // If the current code item was not counted yet, count it now.
  // This can happen for example in unit tests where some fields like m_units_
  // are not initialized.
  if (counted_current_item == false) {
    cumulative_size += (current_code_item_ == nullptr ?
        size_for_null_code_item : current_code_item_->insns_size_in_code_units_);
  }

  return cumulative_size;
}

static BasicBlock* SelectTopologicalSortOrderFallBack(
    MIRGraph* mir_graph, const ArenaBitVector* current_loop,
    const ScopedArenaVector<size_t>* visited_cnt_values, ScopedArenaAllocator* allocator,
    ScopedArenaVector<BasicBlockId>* tmp_stack) {
  // No true loop head has been found but there may be true loop heads after the mess we need
  // to resolve. To avoid taking one of those, pick the candidate with the highest number of
  // reachable unvisited nodes. That candidate will surely be a part of a loop.
  BasicBlock* fall_back = nullptr;
  size_t fall_back_num_reachable = 0u;
  // Reuse the same bit vector for each candidate to mark reachable unvisited blocks.
  ArenaBitVector candidate_reachable(allocator, mir_graph->GetNumBlocks(), false, kBitMapMisc);
  AllNodesIterator iter(mir_graph);
  for (BasicBlock* candidate = iter.Next(); candidate != nullptr; candidate = iter.Next()) {
    if (candidate->hidden ||                            // Hidden, or
        candidate->visited ||                           // already processed, or
        (*visited_cnt_values)[candidate->id] == 0u ||   // no processed predecessors, or
        (current_loop != nullptr &&                     // outside current loop.
         !current_loop->IsBitSet(candidate->id))) {
      continue;
    }
    DCHECK(tmp_stack->empty());
    tmp_stack->push_back(candidate->id);
    candidate_reachable.ClearAllBits();
    size_t num_reachable = 0u;
    while (!tmp_stack->empty()) {
      BasicBlockId current_id = tmp_stack->back();
      tmp_stack->pop_back();
      BasicBlock* current_bb = mir_graph->GetBasicBlock(current_id);
      DCHECK(current_bb != nullptr);
      ChildBlockIterator child_iter(current_bb, mir_graph);
      BasicBlock* child_bb = child_iter.Next();
      for ( ; child_bb != nullptr; child_bb = child_iter.Next()) {
        DCHECK(!child_bb->hidden);
        if (child_bb->visited ||                            // Already processed, or
            (current_loop != nullptr &&                     // outside current loop.
             !current_loop->IsBitSet(child_bb->id))) {
          continue;
        }
        if (!candidate_reachable.IsBitSet(child_bb->id)) {
          candidate_reachable.SetBit(child_bb->id);
          tmp_stack->push_back(child_bb->id);
          num_reachable += 1u;
        }
      }
    }
    if (fall_back_num_reachable < num_reachable) {
      fall_back_num_reachable = num_reachable;
      fall_back = candidate;
    }
  }
  return fall_back;
}

// Compute from which unvisited blocks is bb_id reachable through unvisited blocks.
static void ComputeUnvisitedReachableFrom(MIRGraph* mir_graph, BasicBlockId bb_id,
                                          ArenaBitVector* reachable,
                                          ScopedArenaVector<BasicBlockId>* tmp_stack) {
  // NOTE: Loop heads indicated by the "visited" flag.
  DCHECK(tmp_stack->empty());
  reachable->ClearAllBits();
  tmp_stack->push_back(bb_id);
  while (!tmp_stack->empty()) {
    BasicBlockId current_id = tmp_stack->back();
    tmp_stack->pop_back();
    BasicBlock* current_bb = mir_graph->GetBasicBlock(current_id);
    DCHECK(current_bb != nullptr);
    for (BasicBlockId pred_id : current_bb->predecessors) {
      BasicBlock* pred_bb = mir_graph->GetBasicBlock(pred_id);
      DCHECK(pred_bb != nullptr);
      if (!pred_bb->visited && !reachable->IsBitSet(pred_bb->id)) {
        reachable->SetBit(pred_bb->id);
        tmp_stack->push_back(pred_bb->id);
      }
    }
  }
}

void MIRGraph::ComputeTopologicalSortOrder() {
  ScopedArenaAllocator allocator(&cu_->arena_stack);
  unsigned int num_blocks = GetNumBlocks();

  ScopedArenaQueue<BasicBlock*> q(allocator.Adapter());
  ScopedArenaVector<size_t> visited_cnt_values(num_blocks, 0u, allocator.Adapter());
  ScopedArenaVector<BasicBlockId> loop_head_stack(allocator.Adapter());
  size_t max_nested_loops = 0u;
  ArenaBitVector loop_exit_blocks(&allocator, num_blocks, false, kBitMapMisc);
  loop_exit_blocks.ClearAllBits();

  // Count the number of blocks to process and add the entry block(s).
  unsigned int num_blocks_to_process = 0u;
  for (BasicBlock* bb : block_list_) {
    if (bb->hidden == true) {
      continue;
    }

    num_blocks_to_process += 1u;

    if (bb->predecessors.size() == 0u) {
      // Add entry block to the queue.
      q.push(bb);
    }
  }

  // Clear the topological order arrays.
  topological_order_.clear();
  topological_order_.reserve(num_blocks);
  topological_order_loop_ends_.clear();
  topological_order_loop_ends_.resize(num_blocks, 0u);
  topological_order_indexes_.clear();
  topological_order_indexes_.resize(num_blocks, static_cast<uint16_t>(-1));

  // Mark all blocks as unvisited.
  ClearAllVisitedFlags();

  // For loop heads, keep track from which blocks they are reachable not going through other
  // loop heads. Other loop heads are excluded to detect the heads of nested loops. The children
  // in this set go into the loop body, the other children are jumping over the loop.
  ScopedArenaVector<ArenaBitVector*> loop_head_reachable_from(allocator.Adapter());
  loop_head_reachable_from.resize(num_blocks, nullptr);
  // Reuse the same temp stack whenever calculating a loop_head_reachable_from[loop_head_id].
  ScopedArenaVector<BasicBlockId> tmp_stack(allocator.Adapter());

  while (num_blocks_to_process != 0u) {
    BasicBlock* bb = nullptr;
    if (!q.empty()) {
      num_blocks_to_process -= 1u;
      // Get top.
      bb = q.front();
      q.pop();
      if (bb->visited) {
        // Loop head: it was already processed, mark end and copy exit blocks to the queue.
        DCHECK(q.empty()) << PrettyMethod(cu_->method_idx, *cu_->dex_file);
        uint16_t idx = static_cast<uint16_t>(topological_order_.size());
        topological_order_loop_ends_[topological_order_indexes_[bb->id]] = idx;
        DCHECK_EQ(loop_head_stack.back(), bb->id);
        loop_head_stack.pop_back();
        ArenaBitVector* reachable =
            loop_head_stack.empty() ? nullptr : loop_head_reachable_from[loop_head_stack.back()];
        for (BasicBlockId candidate_id : loop_exit_blocks.Indexes()) {
          if (reachable == nullptr || reachable->IsBitSet(candidate_id)) {
            q.push(GetBasicBlock(candidate_id));
            // NOTE: The BitVectorSet::IndexIterator will not check the pointed-to bit again,
            // so clearing the bit has no effect on the iterator.
            loop_exit_blocks.ClearBit(candidate_id);
          }
        }
        continue;
      }
    } else {
      // Find the new loop head.
      AllNodesIterator iter(this);
      while (true) {
        BasicBlock* candidate = iter.Next();
        if (candidate == nullptr) {
          // We did not find a true loop head, fall back to a reachable block in any loop.
          ArenaBitVector* current_loop =
              loop_head_stack.empty() ? nullptr : loop_head_reachable_from[loop_head_stack.back()];
          bb = SelectTopologicalSortOrderFallBack(this, current_loop, &visited_cnt_values,
                                                  &allocator, &tmp_stack);
          DCHECK(bb != nullptr) << PrettyMethod(cu_->method_idx, *cu_->dex_file);
          if (kIsDebugBuild && cu_->dex_file != nullptr) {
            LOG(INFO) << "Topological sort order: Using fall-back in "
                << PrettyMethod(cu_->method_idx, *cu_->dex_file) << " BB #" << bb->id
                << " @0x" << std::hex << bb->start_offset
                << ", num_blocks = " << std::dec << num_blocks;
          }
          break;
        }
        if (candidate->hidden ||                            // Hidden, or
            candidate->visited ||                           // already processed, or
            visited_cnt_values[candidate->id] == 0u ||      // no processed predecessors, or
            (!loop_head_stack.empty() &&                    // outside current loop.
             !loop_head_reachable_from[loop_head_stack.back()]->IsBitSet(candidate->id))) {
          continue;
        }

        for (BasicBlockId pred_id : candidate->predecessors) {
          BasicBlock* pred_bb = GetBasicBlock(pred_id);
          DCHECK(pred_bb != nullptr);
          if (pred_bb != candidate && !pred_bb->visited &&
              !pred_bb->dominators->IsBitSet(candidate->id)) {
            candidate = nullptr;  // Set candidate to null to indicate failure.
            break;
          }
        }
        if (candidate != nullptr) {
          bb = candidate;
          break;
        }
      }
      // Compute blocks from which the loop head is reachable and process those blocks first.
      ArenaBitVector* reachable =
          new (&allocator) ArenaBitVector(&allocator, num_blocks, false, kBitMapMisc);
      loop_head_reachable_from[bb->id] = reachable;
      ComputeUnvisitedReachableFrom(this, bb->id, reachable, &tmp_stack);
      // Now mark as loop head. (Even if it's only a fall back when we don't find a true loop.)
      loop_head_stack.push_back(bb->id);
      max_nested_loops = std::max(max_nested_loops, loop_head_stack.size());
    }

    DCHECK_EQ(bb->hidden, false);
    DCHECK_EQ(bb->visited, false);
    bb->visited = true;
    bb->nesting_depth = loop_head_stack.size();

    // Now add the basic block.
    uint16_t idx = static_cast<uint16_t>(topological_order_.size());
    topological_order_indexes_[bb->id] = idx;
    topological_order_.push_back(bb->id);

    // Update visited_cnt_values for children.
    ChildBlockIterator succIter(bb, this);
    BasicBlock* successor = succIter.Next();
    for ( ; successor != nullptr; successor = succIter.Next()) {
      if (successor->hidden) {
        continue;
      }

      // One more predecessor was visited.
      visited_cnt_values[successor->id] += 1u;
      if (visited_cnt_values[successor->id] == successor->predecessors.size()) {
        if (loop_head_stack.empty() ||
            loop_head_reachable_from[loop_head_stack.back()]->IsBitSet(successor->id)) {
          q.push(successor);
        } else {
          DCHECK(!loop_exit_blocks.IsBitSet(successor->id));
          loop_exit_blocks.SetBit(successor->id);
        }
      }
    }
  }

  // Prepare the loop head stack for iteration.
  topological_order_loop_head_stack_.clear();
  topological_order_loop_head_stack_.reserve(max_nested_loops);
  max_nested_loops_ = max_nested_loops;
  topological_order_up_to_date_ = true;
}

bool BasicBlock::IsExceptionBlock() const {
  if (block_type == kExceptionHandling) {
    return true;
  }
  return false;
}

ChildBlockIterator::ChildBlockIterator(BasicBlock* bb, MIRGraph* mir_graph)
    : basic_block_(bb), mir_graph_(mir_graph), visited_fallthrough_(false),
      visited_taken_(false), have_successors_(false) {
  // Check if we actually do have successors.
  if (basic_block_ != 0 && basic_block_->successor_block_list_type != kNotUsed) {
    have_successors_ = true;
    successor_iter_ = basic_block_->successor_blocks.cbegin();
  }
}

BasicBlock* ChildBlockIterator::Next() {
  // We check if we have a basic block. If we don't we cannot get next child.
  if (basic_block_ == nullptr) {
    return nullptr;
  }

  // If we haven't visited fallthrough, return that.
  if (visited_fallthrough_ == false) {
    visited_fallthrough_ = true;

    BasicBlock* result = mir_graph_->GetBasicBlock(basic_block_->fall_through);
    if (result != nullptr) {
      return result;
    }
  }

  // If we haven't visited taken, return that.
  if (visited_taken_ == false) {
    visited_taken_ = true;

    BasicBlock* result = mir_graph_->GetBasicBlock(basic_block_->taken);
    if (result != nullptr) {
      return result;
    }
  }

  // We visited both taken and fallthrough. Now check if we have successors we need to visit.
  if (have_successors_ == true) {
    // Get information about next successor block.
    auto end = basic_block_->successor_blocks.cend();
    while (successor_iter_ != end) {
      SuccessorBlockInfo* successor_block_info = *successor_iter_;
      ++successor_iter_;
      // If block was replaced by zero block, take next one.
      if (successor_block_info->block != NullBasicBlockId) {
        return mir_graph_->GetBasicBlock(successor_block_info->block);
      }
    }
  }

  // We do not have anything.
  return nullptr;
}

BasicBlock* BasicBlock::Copy(CompilationUnit* c_unit) {
  MIRGraph* mir_graph = c_unit->mir_graph.get();
  return Copy(mir_graph);
}

BasicBlock* BasicBlock::Copy(MIRGraph* mir_graph) {
  BasicBlock* result_bb = mir_graph->CreateNewBB(block_type);

  // We don't do a memcpy style copy here because it would lead to a lot of things
  // to clean up. Let us do it by hand instead.
  // Copy in taken and fallthrough.
  result_bb->fall_through = fall_through;
  result_bb->taken = taken;

  // Copy successor links if needed.
  ArenaAllocator* arena = mir_graph->GetArena();

  result_bb->successor_block_list_type = successor_block_list_type;
  if (result_bb->successor_block_list_type != kNotUsed) {
    result_bb->successor_blocks.reserve(successor_blocks.size());
    for (SuccessorBlockInfo* sbi_old : successor_blocks) {
      SuccessorBlockInfo* sbi_new = static_cast<SuccessorBlockInfo*>(
          arena->Alloc(sizeof(SuccessorBlockInfo), kArenaAllocSuccessor));
      memcpy(sbi_new, sbi_old, sizeof(SuccessorBlockInfo));
      result_bb->successor_blocks.push_back(sbi_new);
    }
  }

  // Copy offset, method.
  result_bb->start_offset = start_offset;

  // Now copy instructions.
  for (MIR* mir = first_mir_insn; mir != 0; mir = mir->next) {
    // Get a copy first.
    MIR* copy = mir->Copy(mir_graph);

    // Append it.
    result_bb->AppendMIR(copy);
  }

  return result_bb;
}

MIR* MIR::Copy(MIRGraph* mir_graph) {
  MIR* res = mir_graph->NewMIR();
  *res = *this;

  // Remove links
  res->next = nullptr;
  res->bb = NullBasicBlockId;
  res->ssa_rep = nullptr;

  return res;
}

MIR* MIR::Copy(CompilationUnit* c_unit) {
  return Copy(c_unit->mir_graph.get());
}

uint32_t SSARepresentation::GetStartUseIndex(Instruction::Code opcode) {
  // Default result.
  int res = 0;

  // We are basically setting the iputs to their igets counterparts.
  switch (opcode) {
    case Instruction::IPUT:
    case Instruction::IPUT_OBJECT:
    case Instruction::IPUT_BOOLEAN:
    case Instruction::IPUT_BYTE:
    case Instruction::IPUT_CHAR:
    case Instruction::IPUT_SHORT:
    case Instruction::IPUT_QUICK:
    case Instruction::IPUT_OBJECT_QUICK:
    case Instruction::IPUT_BOOLEAN_QUICK:
    case Instruction::IPUT_BYTE_QUICK:
    case Instruction::IPUT_CHAR_QUICK:
    case Instruction::IPUT_SHORT_QUICK:
    case Instruction::APUT:
    case Instruction::APUT_OBJECT:
    case Instruction::APUT_BOOLEAN:
    case Instruction::APUT_BYTE:
    case Instruction::APUT_CHAR:
    case Instruction::APUT_SHORT:
    case Instruction::SPUT:
    case Instruction::SPUT_OBJECT:
    case Instruction::SPUT_BOOLEAN:
    case Instruction::SPUT_BYTE:
    case Instruction::SPUT_CHAR:
    case Instruction::SPUT_SHORT:
      // Skip the VR containing what to store.
      res = 1;
      break;
    case Instruction::IPUT_WIDE:
    case Instruction::IPUT_WIDE_QUICK:
    case Instruction::APUT_WIDE:
    case Instruction::SPUT_WIDE:
      // Skip the two VRs containing what to store.
      res = 2;
      break;
    default:
      // Do nothing in the general case.
      break;
  }

  return res;
}

/**
 * @brief Given a decoded instruction, it checks whether the instruction
 * sets a constant and if it does, more information is provided about the
 * constant being set.
 * @param ptr_value pointer to a 64-bit holder for the constant.
 * @param wide Updated by function whether a wide constant is being set by bytecode.
 * @return Returns false if the decoded instruction does not represent a constant bytecode.
 */
bool MIR::DecodedInstruction::GetConstant(int64_t* ptr_value, bool* wide) const {
  bool sets_const = true;
  int64_t value = vB;

  DCHECK(ptr_value != nullptr);
  DCHECK(wide != nullptr);

  switch (opcode) {
    case Instruction::CONST_4:
    case Instruction::CONST_16:
    case Instruction::CONST:
      *wide = false;
      value <<= 32;      // In order to get the sign extend.
      value >>= 32;
      break;
    case Instruction::CONST_HIGH16:
      *wide = false;
      value <<= 48;      // In order to get the sign extend.
      value >>= 32;
      break;
    case Instruction::CONST_WIDE_16:
    case Instruction::CONST_WIDE_32:
      *wide = true;
      value <<= 32;      // In order to get the sign extend.
      value >>= 32;
      break;
    case Instruction::CONST_WIDE:
      *wide = true;
      value = vB_wide;
      break;
    case Instruction::CONST_WIDE_HIGH16:
      *wide = true;
      value <<= 48;      // In order to get the sign extend.
      break;
    default:
      sets_const = false;
      break;
  }

  if (sets_const) {
    *ptr_value = value;
  }

  return sets_const;
}

void BasicBlock::ResetOptimizationFlags(uint16_t reset_flags) {
  // Reset flags for all MIRs in bb.
  for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) {
    mir->optimization_flags &= (~reset_flags);
  }
}

void BasicBlock::Kill(MIRGraph* mir_graph) {
  for (BasicBlockId pred_id : predecessors) {
    BasicBlock* pred_bb = mir_graph->GetBasicBlock(pred_id);
    DCHECK(pred_bb != nullptr);

    // Sadly we have to go through the children by hand here.
    pred_bb->ReplaceChild(id, NullBasicBlockId);
  }
  predecessors.clear();

  // Mark as dead and hidden.
  block_type = kDead;
  hidden = true;

  // Detach it from its MIRs so we don't generate code for them. Also detached MIRs
  // are updated to know that they no longer have a parent.
  for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) {
    mir->bb = NullBasicBlockId;
  }
  first_mir_insn = nullptr;
  last_mir_insn = nullptr;

  data_flow_info = nullptr;

  // Erase this bb from all children's predecessors and kill unreachable children.
  ChildBlockIterator iter(this, mir_graph);
  for (BasicBlock* succ_bb = iter.Next(); succ_bb != nullptr; succ_bb = iter.Next()) {
    succ_bb->ErasePredecessor(id);
  }

  // Remove links to children.
  fall_through = NullBasicBlockId;
  taken = NullBasicBlockId;
  successor_block_list_type = kNotUsed;

  if (kIsDebugBuild) {
    if (catch_entry) {
      DCHECK_EQ(mir_graph->catches_.count(start_offset), 1u);
      mir_graph->catches_.erase(start_offset);
    }
  }
}

bool BasicBlock::IsSSALiveOut(const CompilationUnit* c_unit, int ssa_reg) {
  // In order to determine if the ssa reg is live out, we scan all the MIRs. We remember
  // the last SSA number of the same dalvik register. At the end, if it is different than ssa_reg,
  // then it is not live out of this BB.
  int dalvik_reg = c_unit->mir_graph->SRegToVReg(ssa_reg);

  int last_ssa_reg = -1;

  // Walk through the MIRs backwards.
  for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) {
    // Get ssa rep.
    SSARepresentation *ssa_rep = mir->ssa_rep;

    // Go through the defines for this MIR.
    for (int i = 0; i < ssa_rep->num_defs; i++) {
      DCHECK(ssa_rep->defs != nullptr);

      // Get the ssa reg.
      int def_ssa_reg = ssa_rep->defs[i];

      // Get dalvik reg.
      int def_dalvik_reg = c_unit->mir_graph->SRegToVReg(def_ssa_reg);

      // Compare dalvik regs.
      if (dalvik_reg == def_dalvik_reg) {
        // We found a def of the register that we are being asked about.
        // Remember it.
        last_ssa_reg = def_ssa_reg;
      }
    }
  }

  if (last_ssa_reg == -1) {
    // If we get to this point we couldn't find a define of register user asked about.
    // Let's assume the user knows what he's doing so we can be safe and say that if we
    // couldn't find a def, it is live out.
    return true;
  }

  // If it is not -1, we found a match, is it ssa_reg?
  return (ssa_reg == last_ssa_reg);
}

bool BasicBlock::ReplaceChild(BasicBlockId old_bb, BasicBlockId new_bb) {
  // We need to check taken, fall_through, and successor_blocks to replace.
  bool found = false;
  if (taken == old_bb) {
    taken = new_bb;
    found = true;
  }

  if (fall_through == old_bb) {
    fall_through = new_bb;
    found = true;
  }

  if (successor_block_list_type != kNotUsed) {
    for (SuccessorBlockInfo* successor_block_info : successor_blocks) {
      if (successor_block_info->block == old_bb) {
        successor_block_info->block = new_bb;
        found = true;
      }
    }
  }

  return found;
}

void BasicBlock::ErasePredecessor(BasicBlockId old_pred) {
  auto pos = std::find(predecessors.begin(), predecessors.end(), old_pred);
  DCHECK(pos != predecessors.end());
  // It's faster to move the back() to *pos than erase(pos).
  *pos = predecessors.back();
  predecessors.pop_back();
  size_t idx = std::distance(predecessors.begin(), pos);
  for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) {
    if (static_cast<int>(mir->dalvikInsn.opcode) != kMirOpPhi) {
      break;
    }
    DCHECK_EQ(mir->ssa_rep->num_uses - 1u, predecessors.size());
    DCHECK_EQ(mir->meta.phi_incoming[idx], old_pred);
    mir->meta.phi_incoming[idx] = mir->meta.phi_incoming[predecessors.size()];
    mir->ssa_rep->uses[idx] = mir->ssa_rep->uses[predecessors.size()];
    mir->ssa_rep->num_uses = predecessors.size();
  }
}

void BasicBlock::UpdatePredecessor(BasicBlockId old_pred, BasicBlockId new_pred) {
  DCHECK_NE(new_pred, NullBasicBlockId);
  auto pos = std::find(predecessors.begin(), predecessors.end(), old_pred);
  DCHECK(pos != predecessors.end());
  *pos = new_pred;
  size_t idx = std::distance(predecessors.begin(), pos);
  for (MIR* mir = first_mir_insn; mir != nullptr; mir = mir->next) {
    if (static_cast<int>(mir->dalvikInsn.opcode) != kMirOpPhi) {
      break;
    }
    DCHECK_EQ(mir->meta.phi_incoming[idx], old_pred);
    mir->meta.phi_incoming[idx] = new_pred;
  }
}

// Create a new basic block with block_id as num_blocks_ that is
// post-incremented.
BasicBlock* MIRGraph::CreateNewBB(BBType block_type) {
  BasicBlockId id = static_cast<BasicBlockId>(block_list_.size());
  BasicBlock* res = NewMemBB(block_type, id);
  block_list_.push_back(res);
  return res;
}

void MIRGraph::CalculateBasicBlockInformation(const PassManager* const post_opt_pass_manager) {
  /* Create the pass driver and launch it */
  PassDriverMEPostOpt driver(post_opt_pass_manager, cu_);
  driver.Launch();
}

int MIR::DecodedInstruction::FlagsOf() const {
  // Calculate new index.
  int idx = static_cast<int>(opcode) - kNumPackedOpcodes;

  // Check if it is an extended or not.
  if (idx < 0) {
    return Instruction::FlagsOf(opcode);
  }

  // For extended, we use a switch.
  switch (static_cast<int>(opcode)) {
    case kMirOpPhi:
      return Instruction::kContinue;
    case kMirOpCopy:
      return Instruction::kContinue;
    case kMirOpFusedCmplFloat:
      return Instruction::kContinue | Instruction::kBranch;
    case kMirOpFusedCmpgFloat:
      return Instruction::kContinue | Instruction::kBranch;
    case kMirOpFusedCmplDouble:
      return Instruction::kContinue | Instruction::kBranch;
    case kMirOpFusedCmpgDouble:
      return Instruction::kContinue | Instruction::kBranch;
    case kMirOpFusedCmpLong:
      return Instruction::kContinue | Instruction::kBranch;
    case kMirOpNop:
      return Instruction::kContinue;
    case kMirOpNullCheck:
      return Instruction::kContinue | Instruction::kThrow;
    case kMirOpRangeCheck:
      return Instruction::kContinue | Instruction::kThrow;
    case kMirOpDivZeroCheck:
      return Instruction::kContinue | Instruction::kThrow;
    case kMirOpCheck:
      return Instruction::kContinue | Instruction::kThrow;
    case kMirOpCheckPart2:
      return Instruction::kContinue;
    case kMirOpSelect:
      return Instruction::kContinue;
    case kMirOpConstVector:
      return Instruction::kContinue;
    case kMirOpMoveVector:
      return Instruction::kContinue;
    case kMirOpPackedMultiply:
      return Instruction::kContinue;
    case kMirOpPackedAddition:
      return Instruction::kContinue;
    case kMirOpPackedSubtract:
      return Instruction::kContinue;
    case kMirOpPackedShiftLeft:
      return Instruction::kContinue;
    case kMirOpPackedSignedShiftRight:
      return Instruction::kContinue;
    case kMirOpPackedUnsignedShiftRight:
      return Instruction::kContinue;
    case kMirOpPackedAnd:
      return Instruction::kContinue;
    case kMirOpPackedOr:
      return Instruction::kContinue;
    case kMirOpPackedXor:
      return Instruction::kContinue;
    case kMirOpPackedAddReduce:
      return Instruction::kContinue;
    case kMirOpPackedReduce:
      return Instruction::kContinue;
    case kMirOpPackedSet:
      return Instruction::kContinue;
    case kMirOpReserveVectorRegisters:
      return Instruction::kContinue;
    case kMirOpReturnVectorRegisters:
      return Instruction::kContinue;
    case kMirOpMemBarrier:
      return Instruction::kContinue;
    case kMirOpPackedArrayGet:
      return Instruction::kContinue | Instruction::kThrow;
    case kMirOpPackedArrayPut:
      return Instruction::kContinue | Instruction::kThrow;
    case kMirOpMaddInt:
    case kMirOpMsubInt:
    case kMirOpMaddLong:
    case kMirOpMsubLong:
      return Instruction::kContinue;
    default:
      LOG(WARNING) << "ExtendedFlagsOf: Unhandled case: " << static_cast<int> (opcode);
      return 0;
  }
}

const uint16_t* MIRGraph::GetInsns(int m_unit_index) const {
  return m_units_[m_unit_index]->GetCodeItem()->insns_;
}

void MIRGraph::SetPuntToInterpreter(bool val) {
  punt_to_interpreter_ = val;
  if (val) {
    // Disable all subsequent optimizations. They may not be safe to run. (For example,
    // LVN/GVN assumes there are no conflicts found by the type inference pass.)
    cu_->disable_opt = ~static_cast<decltype(cu_->disable_opt)>(0);
  }
}

}  // namespace art
