/*
 * Copyright (C) 2015 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 <sstream>

#include "gvn_dead_code_elimination.h"

#include "base/bit_vector-inl.h"
#include "base/macros.h"
#include "base/allocator.h"
#include "compiler_enums.h"
#include "dataflow_iterator-inl.h"
#include "dex_instruction.h"
#include "dex/mir_graph.h"
#include "local_value_numbering.h"
#include "utils/arena_bit_vector.h"

namespace art {

constexpr uint16_t GvnDeadCodeElimination::kNoValue;
constexpr uint16_t GvnDeadCodeElimination::kNPos;

inline uint16_t GvnDeadCodeElimination::MIRData::PrevChange(int v_reg) const {
  DCHECK(has_def);
  DCHECK(v_reg == vreg_def || v_reg == vreg_def + 1);
  return (v_reg == vreg_def) ? prev_value.change : prev_value_high.change;
}

inline void GvnDeadCodeElimination::MIRData::SetPrevChange(int v_reg, uint16_t change) {
  DCHECK(has_def);
  DCHECK(v_reg == vreg_def || v_reg == vreg_def + 1);
  if (v_reg == vreg_def) {
    prev_value.change = change;
  } else {
    prev_value_high.change = change;
  }
}

inline void GvnDeadCodeElimination::MIRData::RemovePrevChange(int v_reg, MIRData* prev_data) {
  DCHECK_NE(PrevChange(v_reg), kNPos);
  DCHECK(v_reg == prev_data->vreg_def || v_reg == prev_data->vreg_def + 1);
  if (vreg_def == v_reg) {
    if (prev_data->vreg_def == v_reg) {
      prev_value = prev_data->prev_value;
      low_def_over_high_word = prev_data->low_def_over_high_word;
    } else {
      prev_value = prev_data->prev_value_high;
      low_def_over_high_word = !prev_data->high_def_over_low_word;
    }
  } else {
    if (prev_data->vreg_def == v_reg) {
      prev_value_high = prev_data->prev_value;
      high_def_over_low_word = !prev_data->low_def_over_high_word;
    } else {
      prev_value_high = prev_data->prev_value_high;
      high_def_over_low_word = prev_data->high_def_over_low_word;
    }
  }
}

GvnDeadCodeElimination::VRegChains::VRegChains(uint32_t num_vregs, ScopedArenaAllocator* alloc)
    : num_vregs_(num_vregs),
      vreg_data_(alloc->AllocArray<VRegValue>(num_vregs, kArenaAllocMisc)),
      vreg_high_words_(false, Allocator::GetNoopAllocator(),
                       BitVector::BitsToWords(num_vregs),
                       alloc->AllocArray<uint32_t>(BitVector::BitsToWords(num_vregs))),
      mir_data_(alloc->Adapter()) {
  mir_data_.reserve(100);
}

inline void GvnDeadCodeElimination::VRegChains::Reset() {
  DCHECK(mir_data_.empty());
  std::fill_n(vreg_data_, num_vregs_, VRegValue());
  vreg_high_words_.ClearAllBits();
}

void GvnDeadCodeElimination::VRegChains::AddMIRWithDef(MIR* mir, int v_reg, bool wide,
                                                       uint16_t new_value) {
  uint16_t pos = mir_data_.size();
  mir_data_.emplace_back(mir);
  MIRData* data = &mir_data_.back();
  data->has_def = true;
  data->wide_def = wide;
  data->vreg_def = v_reg;

  DCHECK_LT(static_cast<size_t>(v_reg), num_vregs_);
  data->prev_value = vreg_data_[v_reg];
  data->low_def_over_high_word =
      (vreg_data_[v_reg].change != kNPos)
      ? GetMIRData(vreg_data_[v_reg].change)->vreg_def + 1 == v_reg
      : vreg_high_words_.IsBitSet(v_reg);
  vreg_data_[v_reg].value = new_value;
  vreg_data_[v_reg].change = pos;
  vreg_high_words_.ClearBit(v_reg);

  if (wide) {
    DCHECK_LT(static_cast<size_t>(v_reg + 1), num_vregs_);
    data->prev_value_high = vreg_data_[v_reg + 1];
    data->high_def_over_low_word =
        (vreg_data_[v_reg + 1].change != kNPos)
        ? GetMIRData(vreg_data_[v_reg + 1].change)->vreg_def == v_reg + 1
        : !vreg_high_words_.IsBitSet(v_reg + 1);
    vreg_data_[v_reg + 1].value = new_value;
    vreg_data_[v_reg + 1].change = pos;
    vreg_high_words_.SetBit(v_reg + 1);
  }
}

inline void GvnDeadCodeElimination::VRegChains::AddMIRWithoutDef(MIR* mir) {
  mir_data_.emplace_back(mir);
}

void GvnDeadCodeElimination::VRegChains::RemoveLastMIRData() {
  MIRData* data = LastMIRData();
  if (data->has_def) {
    DCHECK_EQ(vreg_data_[data->vreg_def].change, NumMIRs() - 1u);
    vreg_data_[data->vreg_def] = data->prev_value;
    DCHECK(!vreg_high_words_.IsBitSet(data->vreg_def));
    if (data->low_def_over_high_word) {
      vreg_high_words_.SetBit(data->vreg_def);
    }
    if (data->wide_def) {
      DCHECK_EQ(vreg_data_[data->vreg_def + 1].change, NumMIRs() - 1u);
      vreg_data_[data->vreg_def + 1] = data->prev_value_high;
      DCHECK(vreg_high_words_.IsBitSet(data->vreg_def + 1));
      if (data->high_def_over_low_word) {
        vreg_high_words_.ClearBit(data->vreg_def + 1);
      }
    }
  }
  mir_data_.pop_back();
}

void GvnDeadCodeElimination::VRegChains::RemoveTrailingNops() {
  // There's at least one NOP to drop. There may be more.
  MIRData* last_data = LastMIRData();
  DCHECK(!last_data->must_keep && !last_data->has_def);
  do {
    DCHECK_EQ(static_cast<int>(last_data->mir->dalvikInsn.opcode), static_cast<int>(kMirOpNop));
    mir_data_.pop_back();
    if (mir_data_.empty()) {
      break;
    }
    last_data = LastMIRData();
  } while (!last_data->must_keep && !last_data->has_def);
}

inline size_t GvnDeadCodeElimination::VRegChains::NumMIRs() const {
  return mir_data_.size();
}

inline GvnDeadCodeElimination::MIRData* GvnDeadCodeElimination::VRegChains::GetMIRData(size_t pos) {
  DCHECK_LT(pos, mir_data_.size());
  return &mir_data_[pos];
}

inline GvnDeadCodeElimination::MIRData* GvnDeadCodeElimination::VRegChains::LastMIRData() {
  DCHECK(!mir_data_.empty());
  return &mir_data_.back();
}

uint32_t GvnDeadCodeElimination::VRegChains::NumVRegs() const {
  return num_vregs_;
}

void GvnDeadCodeElimination::VRegChains::InsertInitialValueHigh(int v_reg, uint16_t value) {
  DCHECK_NE(value, kNoValue);
  DCHECK_LT(static_cast<size_t>(v_reg), num_vregs_);
  uint16_t change = vreg_data_[v_reg].change;
  if (change == kNPos) {
    vreg_data_[v_reg].value = value;
    vreg_high_words_.SetBit(v_reg);
  } else {
    while (true) {
      MIRData* data = &mir_data_[change];
      DCHECK(data->vreg_def == v_reg || data->vreg_def + 1 == v_reg);
      if (data->vreg_def == v_reg) {  // Low word, use prev_value.
        if (data->prev_value.change == kNPos) {
          DCHECK_EQ(data->prev_value.value, kNoValue);
          data->prev_value.value = value;
          data->low_def_over_high_word = true;
          break;
        }
        change = data->prev_value.change;
      } else {  // High word, use prev_value_high.
        if (data->prev_value_high.change == kNPos) {
          DCHECK_EQ(data->prev_value_high.value, kNoValue);
          data->prev_value_high.value = value;
          break;
        }
        change = data->prev_value_high.change;
      }
    }
  }
}

void GvnDeadCodeElimination::VRegChains::UpdateInitialVRegValue(int v_reg, bool wide,
                                                                const LocalValueNumbering* lvn) {
  DCHECK_LT(static_cast<size_t>(v_reg), num_vregs_);
  if (!wide) {
    if (vreg_data_[v_reg].value == kNoValue) {
      uint16_t old_value = lvn->GetStartingVregValueNumber(v_reg);
      if (old_value == kNoValue) {
        // Maybe there was a wide value in v_reg before. Do not check for wide value in v_reg-1,
        // that will be done only if we see a definition of v_reg-1, otherwise it's unnecessary.
        old_value = lvn->GetStartingVregValueNumberWide(v_reg);
        if (old_value != kNoValue) {
          InsertInitialValueHigh(v_reg + 1, old_value);
        }
      }
      vreg_data_[v_reg].value = old_value;
      DCHECK(!vreg_high_words_.IsBitSet(v_reg));  // Keep marked as low word.
    }
  } else {
    DCHECK_LT(static_cast<size_t>(v_reg + 1), num_vregs_);
    bool check_high = true;
    if (vreg_data_[v_reg].value == kNoValue) {
      uint16_t old_value = lvn->GetStartingVregValueNumberWide(v_reg);
      if (old_value != kNoValue) {
        InsertInitialValueHigh(v_reg + 1, old_value);
        check_high = false;  // High word has been processed.
      } else {
        // Maybe there was a narrow value before. Do not check for wide value in v_reg-1,
        // that will be done only if we see a definition of v_reg-1, otherwise it's unnecessary.
        old_value = lvn->GetStartingVregValueNumber(v_reg);
      }
      vreg_data_[v_reg].value = old_value;
      DCHECK(!vreg_high_words_.IsBitSet(v_reg));  // Keep marked as low word.
    }
    if (check_high && vreg_data_[v_reg + 1].value == kNoValue) {
      uint16_t old_value = lvn->GetStartingVregValueNumber(v_reg + 1);
      if (old_value == kNoValue && static_cast<size_t>(v_reg + 2) < num_vregs_) {
        // Maybe there was a wide value before.
        old_value = lvn->GetStartingVregValueNumberWide(v_reg + 1);
        if (old_value != kNoValue) {
          InsertInitialValueHigh(v_reg + 2, old_value);
        }
      }
      vreg_data_[v_reg + 1].value = old_value;
      DCHECK(!vreg_high_words_.IsBitSet(v_reg + 1));  // Keep marked as low word.
    }
  }
}

inline uint16_t GvnDeadCodeElimination::VRegChains::LastChange(int v_reg) {
  DCHECK_LT(static_cast<size_t>(v_reg), num_vregs_);
  return vreg_data_[v_reg].change;
}

inline uint16_t GvnDeadCodeElimination::VRegChains::CurrentValue(int v_reg) {
  DCHECK_LT(static_cast<size_t>(v_reg), num_vregs_);
  return vreg_data_[v_reg].value;
}

uint16_t GvnDeadCodeElimination::VRegChains::FindKillHead(int v_reg, uint16_t cutoff) {
  uint16_t current_value = this->CurrentValue(v_reg);
  DCHECK_NE(current_value, kNoValue);
  uint16_t change = LastChange(v_reg);
  DCHECK_LT(change, mir_data_.size());
  DCHECK_GE(change, cutoff);
  bool match_high_word = (mir_data_[change].vreg_def != v_reg);
  do {
    MIRData* data = &mir_data_[change];
    DCHECK(data->vreg_def == v_reg || data->vreg_def + 1 == v_reg);
    if (data->vreg_def == v_reg) {  // Low word, use prev_value.
      if (data->prev_value.value == current_value &&
          match_high_word == data->low_def_over_high_word) {
        break;
      }
      change = data->prev_value.change;
    } else {  // High word, use prev_value_high.
      if (data->prev_value_high.value == current_value &&
          match_high_word != data->high_def_over_low_word) {
        break;
      }
      change = data->prev_value_high.change;
    }
    if (change < cutoff) {
      change = kNPos;
    }
  } while (change != kNPos);
  return change;
}

uint16_t GvnDeadCodeElimination::VRegChains::FindFirstChangeAfter(int v_reg,
                                                                  uint16_t change) const {
  DCHECK_LT(static_cast<size_t>(v_reg), num_vregs_);
  DCHECK_LT(change, mir_data_.size());
  uint16_t result = kNPos;
  uint16_t search_change = vreg_data_[v_reg].change;
  while (search_change != kNPos && search_change > change) {
    result = search_change;
    search_change = mir_data_[search_change].PrevChange(v_reg);
  }
  return result;
}

void GvnDeadCodeElimination::VRegChains::ReplaceChange(uint16_t old_change, uint16_t new_change) {
  const MIRData* old_data = GetMIRData(old_change);
  DCHECK(old_data->has_def);
  int count = old_data->wide_def ? 2 : 1;
  for (int v_reg = old_data->vreg_def, end = old_data->vreg_def + count; v_reg != end; ++v_reg) {
    uint16_t next_change = FindFirstChangeAfter(v_reg, old_change);
    if (next_change == kNPos) {
      DCHECK_EQ(vreg_data_[v_reg].change, old_change);
      vreg_data_[v_reg].change = new_change;
      DCHECK_EQ(vreg_high_words_.IsBitSet(v_reg), v_reg == old_data->vreg_def + 1);
      // No change in vreg_high_words_.
    } else {
      DCHECK_EQ(mir_data_[next_change].PrevChange(v_reg), old_change);
      mir_data_[next_change].SetPrevChange(v_reg, new_change);
    }
  }
}

void GvnDeadCodeElimination::VRegChains::RemoveChange(uint16_t change) {
  MIRData* data = &mir_data_[change];
  DCHECK(data->has_def);
  int count = data->wide_def ? 2 : 1;
  for (int v_reg = data->vreg_def, end = data->vreg_def + count; v_reg != end; ++v_reg) {
    uint16_t next_change = FindFirstChangeAfter(v_reg, change);
    if (next_change == kNPos) {
      DCHECK_EQ(vreg_data_[v_reg].change, change);
      vreg_data_[v_reg] = (data->vreg_def == v_reg) ? data->prev_value : data->prev_value_high;
      DCHECK_EQ(vreg_high_words_.IsBitSet(v_reg), v_reg == data->vreg_def + 1);
      if (data->vreg_def == v_reg && data->low_def_over_high_word) {
        vreg_high_words_.SetBit(v_reg);
      } else if (data->vreg_def != v_reg && data->high_def_over_low_word) {
        vreg_high_words_.ClearBit(v_reg);
      }
    } else {
      DCHECK_EQ(mir_data_[next_change].PrevChange(v_reg), change);
      mir_data_[next_change].RemovePrevChange(v_reg, data);
    }
  }
}

inline bool GvnDeadCodeElimination::VRegChains::IsTopChange(uint16_t change) const {
  DCHECK_LT(change, mir_data_.size());
  const MIRData* data = &mir_data_[change];
  DCHECK(data->has_def);
  DCHECK_LT(data->wide_def ? data->vreg_def + 1u : data->vreg_def, num_vregs_);
  return vreg_data_[data->vreg_def].change == change &&
      (!data->wide_def || vreg_data_[data->vreg_def + 1u].change == change);
}

bool GvnDeadCodeElimination::VRegChains::IsSRegUsed(uint16_t first_change, uint16_t last_change,
                                                    int s_reg) const {
  DCHECK_LE(first_change, last_change);
  DCHECK_LE(last_change, mir_data_.size());
  for (size_t c = first_change; c != last_change; ++c) {
    SSARepresentation* ssa_rep = mir_data_[c].mir->ssa_rep;
    for (int i = 0; i != ssa_rep->num_uses; ++i) {
      if (ssa_rep->uses[i] == s_reg) {
        return true;
      }
    }
  }
  return false;
}

bool GvnDeadCodeElimination::VRegChains::IsVRegUsed(uint16_t first_change, uint16_t last_change,
                                                    int v_reg, MIRGraph* mir_graph) const {
  DCHECK_LE(first_change, last_change);
  DCHECK_LE(last_change, mir_data_.size());
  for (size_t c = first_change; c != last_change; ++c) {
    SSARepresentation* ssa_rep = mir_data_[c].mir->ssa_rep;
    for (int i = 0; i != ssa_rep->num_uses; ++i) {
      if (mir_graph->SRegToVReg(ssa_rep->uses[i]) == v_reg) {
        return true;
      }
    }
  }
  return false;
}

void GvnDeadCodeElimination::VRegChains::RenameSRegUses(uint16_t first_change, uint16_t last_change,
                                                        int old_s_reg, int new_s_reg, bool wide) {
  for (size_t c = first_change; c != last_change; ++c) {
    SSARepresentation* ssa_rep = mir_data_[c].mir->ssa_rep;
    for (int i = 0; i != ssa_rep->num_uses; ++i) {
      if (ssa_rep->uses[i] == old_s_reg) {
        ssa_rep->uses[i] = new_s_reg;
        if (wide) {
          ++i;
          DCHECK_LT(i, ssa_rep->num_uses);
          ssa_rep->uses[i] = new_s_reg + 1;
        }
      }
    }
  }
}

void GvnDeadCodeElimination::VRegChains::RenameVRegUses(uint16_t first_change, uint16_t last_change,
                                                    int old_s_reg, int old_v_reg,
                                                    int new_s_reg, int new_v_reg) {
  for (size_t c = first_change; c != last_change; ++c) {
    MIR* mir = mir_data_[c].mir;
    if (IsInstructionBinOp2Addr(mir->dalvikInsn.opcode) &&
        mir->ssa_rep->uses[0] == old_s_reg && old_v_reg != new_v_reg) {
      // Rewrite binop_2ADDR with plain binop before doing the register rename.
      ChangeBinOp2AddrToPlainBinOp(mir);
    }
    uint64_t df_attr = MIRGraph::GetDataFlowAttributes(mir);
    size_t use = 0u;
#define REPLACE_VREG(REG) \
    if ((df_attr & DF_U##REG) != 0) {                                         \
      if (mir->ssa_rep->uses[use] == old_s_reg) {                             \
        DCHECK_EQ(mir->dalvikInsn.v##REG, static_cast<uint32_t>(old_v_reg));  \
        mir->dalvikInsn.v##REG = new_v_reg;                                   \
        mir->ssa_rep->uses[use] = new_s_reg;                                  \
        if ((df_attr & DF_##REG##_WIDE) != 0) {                               \
          DCHECK_EQ(mir->ssa_rep->uses[use + 1], old_s_reg + 1);              \
          mir->ssa_rep->uses[use + 1] = new_s_reg + 1;                        \
        }                                                                     \
      }                                                                       \
      use += ((df_attr & DF_##REG##_WIDE) != 0) ? 2 : 1;                      \
    }
    REPLACE_VREG(A)
    REPLACE_VREG(B)
    REPLACE_VREG(C)
#undef REPLACE_VREG
    // We may encounter an out-of-order Phi which we need to ignore, otherwise we should
    // only be asked to rename registers specified by DF_UA, DF_UB and DF_UC.
    DCHECK_EQ(use,
              static_cast<int>(mir->dalvikInsn.opcode) == kMirOpPhi
              ? 0u
              : static_cast<size_t>(mir->ssa_rep->num_uses));
  }
}

GvnDeadCodeElimination::GvnDeadCodeElimination(const GlobalValueNumbering* gvn,
                                         ScopedArenaAllocator* alloc)
    : gvn_(gvn),
      mir_graph_(gvn_->GetMirGraph()),
      vreg_chains_(mir_graph_->GetNumOfCodeAndTempVRs(), alloc),
      bb_(nullptr),
      lvn_(nullptr),
      no_uses_all_since_(0u),
      unused_vregs_(new (alloc) ArenaBitVector(alloc, vreg_chains_.NumVRegs(), false)),
      vregs_to_kill_(new (alloc) ArenaBitVector(alloc, vreg_chains_.NumVRegs(), false)),
      kill_heads_(alloc->AllocArray<uint16_t>(vreg_chains_.NumVRegs(), kArenaAllocMisc)),
      changes_to_kill_(alloc->Adapter()),
      dependent_vregs_(new (alloc) ArenaBitVector(alloc, vreg_chains_.NumVRegs(), false)) {
  changes_to_kill_.reserve(16u);
}

void GvnDeadCodeElimination::Apply(BasicBlock* bb) {
  bb_ = bb;
  lvn_ = gvn_->GetLvn(bb->id);

  RecordPass();
  BackwardPass();

  DCHECK_EQ(no_uses_all_since_, 0u);
  lvn_ = nullptr;
  bb_ = nullptr;
}

void GvnDeadCodeElimination::RecordPass() {
  // Record MIRs with vreg definition data, eliminate single instructions.
  vreg_chains_.Reset();
  DCHECK_EQ(no_uses_all_since_, 0u);
  for (MIR* mir = bb_->first_mir_insn; mir != nullptr; mir = mir->next) {
    if (RecordMIR(mir)) {
      RecordPassTryToKillOverwrittenMoveOrMoveSrc();
      RecordPassTryToKillLastMIR();
    }
  }
}

void GvnDeadCodeElimination::BackwardPass() {
  // Now process MIRs in reverse order, trying to eliminate them.
  unused_vregs_->ClearAllBits();  // Implicitly depend on all vregs at the end of BB.
  while (vreg_chains_.NumMIRs() != 0u) {
    if (BackwardPassTryToKillLastMIR()) {
      continue;
    }
    BackwardPassProcessLastMIR();
  }
}

void GvnDeadCodeElimination::KillMIR(MIRData* data) {
  DCHECK(!data->must_keep);
  DCHECK(!data->uses_all_vregs);
  DCHECK(data->has_def);
  DCHECK(data->mir->ssa_rep->num_defs == 1 || data->mir->ssa_rep->num_defs == 2);

  KillMIR(data->mir);
  data->has_def = false;
  data->is_move = false;
  data->is_move_src = false;
}

void GvnDeadCodeElimination::KillMIR(MIR* mir) {
  mir->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
  mir->ssa_rep->num_uses = 0;
  mir->ssa_rep->num_defs = 0;
}

void GvnDeadCodeElimination::ChangeBinOp2AddrToPlainBinOp(MIR* mir) {
  mir->dalvikInsn.vC = mir->dalvikInsn.vB;
  mir->dalvikInsn.vB = mir->dalvikInsn.vA;
  mir->dalvikInsn.opcode = static_cast<Instruction::Code>(
      mir->dalvikInsn.opcode - Instruction::ADD_INT_2ADDR +  Instruction::ADD_INT);
}

MIR* GvnDeadCodeElimination::CreatePhi(int s_reg) {
  int v_reg = mir_graph_->SRegToVReg(s_reg);
  MIR* phi = mir_graph_->NewMIR();
  phi->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpPhi);
  phi->dalvikInsn.vA = v_reg;
  phi->offset = bb_->start_offset;
  phi->m_unit_index = 0;  // Arbitrarily assign all Phi nodes to outermost method.

  phi->ssa_rep = static_cast<struct SSARepresentation *>(mir_graph_->GetArena()->Alloc(
      sizeof(SSARepresentation), kArenaAllocDFInfo));

  mir_graph_->AllocateSSADefData(phi, 1);
  phi->ssa_rep->defs[0] = s_reg;

  size_t num_uses = bb_->predecessors.size();
  mir_graph_->AllocateSSAUseData(phi, num_uses);
  size_t idx = 0u;
  for (BasicBlockId pred_id : bb_->predecessors) {
    BasicBlock* pred_bb = mir_graph_->GetBasicBlock(pred_id);
    DCHECK(pred_bb != nullptr);
    phi->ssa_rep->uses[idx] = pred_bb->data_flow_info->vreg_to_ssa_map_exit[v_reg];
    DCHECK_NE(phi->ssa_rep->uses[idx], INVALID_SREG);
    idx++;
  }

  phi->meta.phi_incoming = static_cast<BasicBlockId*>(mir_graph_->GetArena()->Alloc(
      sizeof(BasicBlockId) * num_uses, kArenaAllocDFInfo));
  std::copy(bb_->predecessors.begin(), bb_->predecessors.end(), phi->meta.phi_incoming);
  bb_->PrependMIR(phi);
  return phi;
}

MIR* GvnDeadCodeElimination::RenameSRegDefOrCreatePhi(uint16_t def_change, uint16_t last_change,
                                                      MIR* mir_to_kill) {
  DCHECK(mir_to_kill->ssa_rep->num_defs == 1 || mir_to_kill->ssa_rep->num_defs == 2);
  bool wide = (mir_to_kill->ssa_rep->num_defs != 1);
  int new_s_reg = mir_to_kill->ssa_rep->defs[0];

  // Just before we kill mir_to_kill, we need to replace the previous SSA reg assigned to the
  // same dalvik reg to keep consistency with subsequent instructions. However, if there's no
  // defining MIR for that dalvik reg, the preserved values must come from its predecessors
  // and we need to create a new Phi (a degenerate Phi if there's only a single predecessor).
  if (def_change == kNPos) {
    if (wide) {
      DCHECK_EQ(new_s_reg + 1, mir_to_kill->ssa_rep->defs[1]);
      DCHECK_EQ(mir_graph_->SRegToVReg(new_s_reg) + 1, mir_graph_->SRegToVReg(new_s_reg + 1));
      CreatePhi(new_s_reg + 1);  // High word Phi.
    }
    MIR* phi = CreatePhi(new_s_reg);
    // If this is a degenerate Phi with all inputs being the same SSA reg, we need to its uses.
    DCHECK_NE(phi->ssa_rep->num_uses, 0u);
    int old_s_reg = phi->ssa_rep->uses[0];
    bool all_same = true;
    for (size_t i = 1u, num = phi->ssa_rep->num_uses; i != num; ++i) {
      if (phi->ssa_rep->uses[i] != old_s_reg) {
        all_same = false;
        break;
      }
    }
    if (all_same) {
      vreg_chains_.RenameSRegUses(0u, last_change, old_s_reg, new_s_reg, wide);
    }
    return phi;
  } else {
    DCHECK_LT(def_change, last_change);
    DCHECK_LE(last_change, vreg_chains_.NumMIRs());
    MIRData* def_data = vreg_chains_.GetMIRData(def_change);
    DCHECK(def_data->has_def);
    int old_s_reg = def_data->mir->ssa_rep->defs[0];
    DCHECK_NE(old_s_reg, new_s_reg);
    DCHECK_EQ(mir_graph_->SRegToVReg(old_s_reg), mir_graph_->SRegToVReg(new_s_reg));
    def_data->mir->ssa_rep->defs[0] = new_s_reg;
    if (wide) {
      if (static_cast<int>(def_data->mir->dalvikInsn.opcode) == kMirOpPhi) {
        // Currently the high word Phi is always located after the low word Phi.
        MIR* phi_high = def_data->mir->next;
        DCHECK(phi_high != nullptr && static_cast<int>(phi_high->dalvikInsn.opcode) == kMirOpPhi);
        DCHECK_EQ(phi_high->ssa_rep->defs[0], old_s_reg + 1);
        phi_high->ssa_rep->defs[0] = new_s_reg + 1;
      } else {
        DCHECK_EQ(def_data->mir->ssa_rep->defs[1], old_s_reg + 1);
        def_data->mir->ssa_rep->defs[1] = new_s_reg + 1;
      }
    }
    vreg_chains_.RenameSRegUses(def_change + 1u, last_change, old_s_reg, new_s_reg, wide);
    return nullptr;
  }
}


void GvnDeadCodeElimination::BackwardPassProcessLastMIR() {
  MIRData* data = vreg_chains_.LastMIRData();
  if (data->uses_all_vregs) {
    DCHECK(data->must_keep);
    unused_vregs_->ClearAllBits();
    DCHECK_EQ(no_uses_all_since_, vreg_chains_.NumMIRs());
    --no_uses_all_since_;
    while (no_uses_all_since_ != 0u &&
        !vreg_chains_.GetMIRData(no_uses_all_since_ - 1u)->uses_all_vregs) {
      --no_uses_all_since_;
    }
  } else {
    if (data->has_def) {
      unused_vregs_->SetBit(data->vreg_def);
      if (data->wide_def) {
        unused_vregs_->SetBit(data->vreg_def + 1);
      }
    }
    for (int i = 0, num_uses = data->mir->ssa_rep->num_uses; i != num_uses; ++i) {
      int v_reg = mir_graph_->SRegToVReg(data->mir->ssa_rep->uses[i]);
      unused_vregs_->ClearBit(v_reg);
    }
  }
  vreg_chains_.RemoveLastMIRData();
}

void GvnDeadCodeElimination::RecordPassKillMoveByRenamingSrcDef(uint16_t src_change,
                                                                uint16_t move_change) {
  DCHECK_LT(src_change, move_change);
  MIRData* src_data = vreg_chains_.GetMIRData(src_change);
  MIRData* move_data = vreg_chains_.GetMIRData(move_change);
  DCHECK(src_data->is_move_src);
  DCHECK_EQ(src_data->wide_def, move_data->wide_def);
  DCHECK(move_data->prev_value.change == kNPos || move_data->prev_value.change <= src_change);
  DCHECK(!move_data->wide_def || move_data->prev_value_high.change == kNPos ||
         move_data->prev_value_high.change <= src_change);

  int old_s_reg = src_data->mir->ssa_rep->defs[0];
  // NOTE: old_s_reg may differ from move_data->mir->ssa_rep->uses[0]; value names must match.
  int new_s_reg = move_data->mir->ssa_rep->defs[0];
  DCHECK_NE(old_s_reg, new_s_reg);

  if (IsInstructionBinOp2Addr(src_data->mir->dalvikInsn.opcode) &&
      src_data->vreg_def != move_data->vreg_def) {
    // Rewrite binop_2ADDR with plain binop before doing the register rename.
    ChangeBinOp2AddrToPlainBinOp(src_data->mir);
  }
  // Remove src_change from the vreg chain(s).
  vreg_chains_.RemoveChange(src_change);
  // Replace the move_change with the src_change, copying all necessary data.
  src_data->is_move_src = move_data->is_move_src;
  src_data->low_def_over_high_word = move_data->low_def_over_high_word;
  src_data->high_def_over_low_word = move_data->high_def_over_low_word;
  src_data->vreg_def = move_data->vreg_def;
  src_data->prev_value = move_data->prev_value;
  src_data->prev_value_high = move_data->prev_value_high;
  src_data->mir->dalvikInsn.vA = move_data->vreg_def;
  src_data->mir->ssa_rep->defs[0] = new_s_reg;
  if (move_data->wide_def) {
    DCHECK_EQ(src_data->mir->ssa_rep->defs[1], old_s_reg + 1);
    src_data->mir->ssa_rep->defs[1] = new_s_reg + 1;
  }
  vreg_chains_.ReplaceChange(move_change, src_change);

  // Rename uses and kill the move.
  vreg_chains_.RenameVRegUses(src_change + 1u, vreg_chains_.NumMIRs(),
                              old_s_reg, mir_graph_->SRegToVReg(old_s_reg),
                              new_s_reg, mir_graph_->SRegToVReg(new_s_reg));
  KillMIR(move_data);
}

void GvnDeadCodeElimination::RecordPassTryToKillOverwrittenMoveOrMoveSrc(uint16_t check_change) {
  MIRData* data = vreg_chains_.GetMIRData(check_change);
  DCHECK(data->is_move || data->is_move_src);
  int32_t dest_s_reg = data->mir->ssa_rep->defs[0];

  if (data->is_move) {
    // Check if source vreg has changed since the MOVE.
    int32_t src_s_reg = data->mir->ssa_rep->uses[0];
    uint32_t src_v_reg = mir_graph_->SRegToVReg(src_s_reg);
    uint16_t src_change = vreg_chains_.FindFirstChangeAfter(src_v_reg, check_change);
    bool wide = data->wide_def;
    if (wide) {
      uint16_t src_change_high = vreg_chains_.FindFirstChangeAfter(src_v_reg + 1, check_change);
      if (src_change_high != kNPos && (src_change == kNPos || src_change_high < src_change)) {
        src_change = src_change_high;
      }
    }
    if (src_change == kNPos ||
        !vreg_chains_.IsSRegUsed(src_change + 1u, vreg_chains_.NumMIRs(), dest_s_reg)) {
      // We can simply change all uses of dest to src.
      size_t rename_end = (src_change != kNPos) ? src_change + 1u : vreg_chains_.NumMIRs();
      vreg_chains_.RenameVRegUses(check_change + 1u, rename_end,
                                  dest_s_reg, mir_graph_->SRegToVReg(dest_s_reg),
                                  src_s_reg,  mir_graph_->SRegToVReg(src_s_reg));

      // Now, remove the MOVE from the vreg chain(s) and kill it.
      vreg_chains_.RemoveChange(check_change);
      KillMIR(data);
      return;
    }
  }

  if (data->is_move_src) {
    // Try to find a MOVE to a vreg that wasn't changed since check_change.
    uint16_t value_name =
        data->wide_def ? lvn_->GetSregValueWide(dest_s_reg) : lvn_->GetSregValue(dest_s_reg);
    for (size_t c = check_change + 1u, size = vreg_chains_.NumMIRs(); c != size; ++c) {
      MIRData* d = vreg_chains_.GetMIRData(c);
      if (d->is_move && d->wide_def == data->wide_def &&
          (d->prev_value.change == kNPos || d->prev_value.change <= check_change) &&
          (!d->wide_def ||
           d->prev_value_high.change == kNPos || d->prev_value_high.change <= check_change)) {
        // Compare value names to find move to move.
        int32_t src_s_reg = d->mir->ssa_rep->uses[0];
        uint16_t src_name =
            (d->wide_def ? lvn_->GetSregValueWide(src_s_reg) : lvn_->GetSregValue(src_s_reg));
        if (value_name == src_name) {
          // Check if the move's destination vreg is unused between check_change and the move.
          uint32_t new_dest_v_reg = mir_graph_->SRegToVReg(d->mir->ssa_rep->defs[0]);
          if (!vreg_chains_.IsVRegUsed(check_change + 1u, c, new_dest_v_reg, mir_graph_) &&
              (!d->wide_def ||
               !vreg_chains_.IsVRegUsed(check_change + 1u, c, new_dest_v_reg + 1, mir_graph_))) {
            RecordPassKillMoveByRenamingSrcDef(check_change, c);
            return;
          }
        }
      }
    }
  }
}

void GvnDeadCodeElimination::RecordPassTryToKillOverwrittenMoveOrMoveSrc() {
  // Check if we're overwriting a the result of a move or the definition of a source of a move.
  // For MOVE_WIDE, we may be overwriting partially; if that's the case, check that the other
  // word wasn't previously overwritten - we would have tried to rename back then.
  MIRData* data = vreg_chains_.LastMIRData();
  if (!data->has_def) {
    return;
  }
  // NOTE: Instructions such as new-array implicitly use all vregs (if they throw) but they can
  // define a move source which can be renamed. Therefore we allow the checked change to be the
  // change before no_uses_all_since_. This has no effect on moves as they never use all vregs.
  if (data->prev_value.change != kNPos && data->prev_value.change + 1u >= no_uses_all_since_) {
    MIRData* check_data = vreg_chains_.GetMIRData(data->prev_value.change);
    bool try_to_kill = false;
    if (!check_data->is_move && !check_data->is_move_src) {
      DCHECK(!try_to_kill);
    } else if (!check_data->wide_def) {
      // Narrow move; always fully overwritten by the last MIR.
      try_to_kill = true;
    } else if (data->low_def_over_high_word) {
      // Overwriting only the high word; is the low word still valid?
      DCHECK_EQ(check_data->vreg_def + 1u, data->vreg_def);
      if (vreg_chains_.LastChange(check_data->vreg_def) == data->prev_value.change) {
        try_to_kill = true;
      }
    } else if (!data->wide_def) {
      // Overwriting only the low word, is the high word still valid?
      if (vreg_chains_.LastChange(data->vreg_def + 1) == data->prev_value.change) {
        try_to_kill = true;
      }
    } else {
      // Overwriting both words; was the high word still from the same move?
      if (data->prev_value_high.change == data->prev_value.change) {
        try_to_kill = true;
      }
    }
    if (try_to_kill) {
      RecordPassTryToKillOverwrittenMoveOrMoveSrc(data->prev_value.change);
    }
  }
  if (data->wide_def && data->high_def_over_low_word &&
      data->prev_value_high.change != kNPos &&
      data->prev_value_high.change + 1u >= no_uses_all_since_) {
    MIRData* check_data = vreg_chains_.GetMIRData(data->prev_value_high.change);
    bool try_to_kill = false;
    if (!check_data->is_move && !check_data->is_move_src) {
      DCHECK(!try_to_kill);
    } else if (!check_data->wide_def) {
      // Narrow move; always fully overwritten by the last MIR.
      try_to_kill = true;
    } else if (vreg_chains_.LastChange(check_data->vreg_def + 1) ==
        data->prev_value_high.change) {
      // High word is still valid.
      try_to_kill = true;
    }
    if (try_to_kill) {
      RecordPassTryToKillOverwrittenMoveOrMoveSrc(data->prev_value_high.change);
    }
  }
}

void GvnDeadCodeElimination::RecordPassTryToKillLastMIR() {
  MIRData* last_data = vreg_chains_.LastMIRData();
  if (last_data->must_keep) {
    return;
  }
  if (UNLIKELY(!last_data->has_def)) {
    // Must be an eliminated MOVE. Drop its data and data of all eliminated MIRs before it.
    vreg_chains_.RemoveTrailingNops();
    return;
  }

  // Try to kill a sequence of consecutive definitions of the same vreg. Allow mixing
  // wide and non-wide defs; consider high word dead if low word has been overwritten.
  uint16_t current_value = vreg_chains_.CurrentValue(last_data->vreg_def);
  uint16_t change = vreg_chains_.NumMIRs() - 1u;
  MIRData* data = last_data;
  while (data->prev_value.value != current_value) {
    --change;
    if (data->prev_value.change == kNPos || data->prev_value.change != change) {
      return;
    }
    data = vreg_chains_.GetMIRData(data->prev_value.change);
    if (data->must_keep || !data->has_def || data->vreg_def != last_data->vreg_def) {
      return;
    }
  }

  bool wide = last_data->wide_def;
  if (wide) {
    // Check that the low word is valid.
    if (data->low_def_over_high_word) {
      return;
    }
    // Check that the high word is valid.
    MIRData* high_data = data;
    if (!high_data->wide_def) {
      uint16_t high_change = vreg_chains_.FindFirstChangeAfter(data->vreg_def + 1, change);
      DCHECK_NE(high_change, kNPos);
      high_data = vreg_chains_.GetMIRData(high_change);
      DCHECK_EQ(high_data->vreg_def, data->vreg_def);
    }
    if (high_data->prev_value_high.value != current_value || high_data->high_def_over_low_word) {
      return;
    }
  }

  MIR* phi = RenameSRegDefOrCreatePhi(data->prev_value.change, change, last_data->mir);
  for (size_t i = 0, count = vreg_chains_.NumMIRs() - change; i != count; ++i) {
    KillMIR(vreg_chains_.LastMIRData()->mir);
    vreg_chains_.RemoveLastMIRData();
  }
  if (phi != nullptr) {
    // Though the Phi has been added to the beginning, we can put the MIRData at the end.
    vreg_chains_.AddMIRWithDef(phi, phi->dalvikInsn.vA, wide, current_value);
    // Reset the previous value to avoid eventually eliminating the Phi itself (unless unused).
    last_data = vreg_chains_.LastMIRData();
    last_data->prev_value.value = kNoValue;
    last_data->prev_value_high.value = kNoValue;
  }
}

uint16_t GvnDeadCodeElimination::FindChangesToKill(uint16_t first_change, uint16_t last_change) {
  // Process dependencies for changes in range [first_change, last_change) and record all
  // changes that we need to kill. Return kNPos if there's a dependent change that must be
  // kept unconditionally; otherwise the end of the range processed before encountering
  // a change that defines a dalvik reg that we need to keep (last_change on full success).
  changes_to_kill_.clear();
  dependent_vregs_->ClearAllBits();
  for (size_t change = first_change; change != last_change; ++change) {
    MIRData* data = vreg_chains_.GetMIRData(change);
    DCHECK(!data->uses_all_vregs);
    bool must_not_depend = data->must_keep;
    bool depends = false;
    // Check if the MIR defines a vreg we're trying to eliminate.
    if (data->has_def && vregs_to_kill_->IsBitSet(data->vreg_def)) {
      if (change < kill_heads_[data->vreg_def]) {
        must_not_depend = true;
      } else {
        depends = true;
      }
    }
    if (data->has_def && data->wide_def && vregs_to_kill_->IsBitSet(data->vreg_def + 1)) {
      if (change < kill_heads_[data->vreg_def + 1]) {
        must_not_depend = true;
      } else {
        depends = true;
      }
    }
    if (!depends) {
      // Check for dependency through SSA reg uses.
      SSARepresentation* ssa_rep = data->mir->ssa_rep;
      for (int i = 0; i != ssa_rep->num_uses; ++i) {
        if (dependent_vregs_->IsBitSet(mir_graph_->SRegToVReg(ssa_rep->uses[i]))) {
          depends = true;
          break;
        }
      }
    }
    // Now check if we can eliminate the insn if we need to.
    if (depends && must_not_depend) {
      return kNPos;
    }
    if (depends && data->has_def &&
        vreg_chains_.IsTopChange(change) && !vregs_to_kill_->IsBitSet(data->vreg_def) &&
        !unused_vregs_->IsBitSet(data->vreg_def) &&
        (!data->wide_def || !unused_vregs_->IsBitSet(data->vreg_def + 1))) {
      // This is a top change but neither unnecessary nor one of the top kill changes.
      return change;
    }
    // Finally, update the data.
    if (depends) {
      changes_to_kill_.push_back(change);
      if (data->has_def) {
        dependent_vregs_->SetBit(data->vreg_def);
        if (data->wide_def) {
          dependent_vregs_->SetBit(data->vreg_def + 1);
        }
      }
    } else {
      if (data->has_def) {
        dependent_vregs_->ClearBit(data->vreg_def);
        if (data->wide_def) {
          dependent_vregs_->ClearBit(data->vreg_def + 1);
        }
      }
    }
  }
  return last_change;
}

void GvnDeadCodeElimination::BackwardPassTryToKillRevertVRegs() {
}

bool GvnDeadCodeElimination::BackwardPassTryToKillLastMIR() {
  MIRData* last_data = vreg_chains_.LastMIRData();
  if (last_data->must_keep) {
    return false;
  }
  DCHECK(!last_data->uses_all_vregs);
  if (!last_data->has_def) {
    // Previously eliminated.
    DCHECK_EQ(static_cast<int>(last_data->mir->dalvikInsn.opcode), static_cast<int>(kMirOpNop));
    vreg_chains_.RemoveTrailingNops();
    return true;
  }
  if (unused_vregs_->IsBitSet(last_data->vreg_def) ||
      (last_data->wide_def && unused_vregs_->IsBitSet(last_data->vreg_def + 1))) {
    if (last_data->wide_def) {
      // For wide defs, one of the vregs may still be considered needed, fix that.
      unused_vregs_->SetBit(last_data->vreg_def);
      unused_vregs_->SetBit(last_data->vreg_def + 1);
    }
    KillMIR(last_data->mir);
    vreg_chains_.RemoveLastMIRData();
    return true;
  }

  vregs_to_kill_->ClearAllBits();
  size_t num_mirs = vreg_chains_.NumMIRs();
  DCHECK_NE(num_mirs, 0u);
  uint16_t kill_change = num_mirs - 1u;
  uint16_t start = num_mirs;
  size_t num_killed_top_changes = 0u;
  while (num_killed_top_changes != kMaxNumTopChangesToKill &&
      kill_change != kNPos && kill_change != num_mirs) {
    ++num_killed_top_changes;

    DCHECK(vreg_chains_.IsTopChange(kill_change));
    MIRData* data = vreg_chains_.GetMIRData(kill_change);
    int count = data->wide_def ? 2 : 1;
    for (int v_reg = data->vreg_def, end = data->vreg_def + count; v_reg != end; ++v_reg) {
      uint16_t kill_head = vreg_chains_.FindKillHead(v_reg, no_uses_all_since_);
      if (kill_head == kNPos) {
        return false;
      }
      kill_heads_[v_reg] = kill_head;
      vregs_to_kill_->SetBit(v_reg);
      start = std::min(start, kill_head);
    }
    DCHECK_LT(start, vreg_chains_.NumMIRs());

    kill_change = FindChangesToKill(start, num_mirs);
  }

  if (kill_change != num_mirs) {
    return false;
  }

  // Kill all MIRs marked as dependent.
  for (uint32_t v_reg : vregs_to_kill_->Indexes()) {
    // Rename s_regs or create Phi only once for each MIR (only for low word).
    MIRData* data = vreg_chains_.GetMIRData(vreg_chains_.LastChange(v_reg));
    DCHECK(data->has_def);
    if (data->vreg_def == v_reg) {
      MIRData* kill_head_data = vreg_chains_.GetMIRData(kill_heads_[v_reg]);
      RenameSRegDefOrCreatePhi(kill_head_data->PrevChange(v_reg), num_mirs, data->mir);
    } else {
      DCHECK_EQ(data->vreg_def + 1u, v_reg);
      DCHECK_EQ(vreg_chains_.GetMIRData(kill_heads_[v_reg - 1u])->PrevChange(v_reg - 1u),
                vreg_chains_.GetMIRData(kill_heads_[v_reg])->PrevChange(v_reg));
    }
  }
  for (auto it = changes_to_kill_.rbegin(), end = changes_to_kill_.rend(); it != end; ++it) {
    MIRData* data = vreg_chains_.GetMIRData(*it);
    DCHECK(!data->must_keep);
    DCHECK(data->has_def);
    vreg_chains_.RemoveChange(*it);
    KillMIR(data);
  }

  // Each dependent register not in vregs_to_kill_ is either already marked unused or
  // it's one word of a wide register where the other word has been overwritten.
  unused_vregs_->UnionIfNotIn(dependent_vregs_, vregs_to_kill_);

  vreg_chains_.RemoveTrailingNops();
  return true;
}

bool GvnDeadCodeElimination::RecordMIR(MIR* mir) {
  bool must_keep = false;
  bool uses_all_vregs = false;
  bool is_move = false;
  uint16_t opcode = mir->dalvikInsn.opcode;
  switch (opcode) {
    case kMirOpPhi: {
      // Determine if this Phi is merging wide regs.
      RegLocation raw_dest = gvn_->GetMirGraph()->GetRawDest(mir);
      if (raw_dest.high_word) {
        // This is the high part of a wide reg. Ignore the Phi.
        return false;
      }
      bool wide = raw_dest.wide;
      // Record the value.
      DCHECK_EQ(mir->ssa_rep->num_defs, 1);
      int s_reg = mir->ssa_rep->defs[0];
      uint16_t new_value = wide ? lvn_->GetSregValueWide(s_reg) : lvn_->GetSregValue(s_reg);

      int v_reg = mir_graph_->SRegToVReg(s_reg);
      DCHECK_EQ(vreg_chains_.CurrentValue(v_reg), kNoValue);  // No previous def for v_reg.
      if (wide) {
        DCHECK_EQ(vreg_chains_.CurrentValue(v_reg + 1), kNoValue);
      }
      vreg_chains_.AddMIRWithDef(mir, v_reg, wide, new_value);
      return true;  // Avoid the common processing.
    }

    case kMirOpNop:
    case Instruction::NOP:
      // Don't record NOPs.
      return false;

    case kMirOpCheck:
      must_keep = true;
      uses_all_vregs = true;
      break;

    case Instruction::RETURN_VOID:
    case Instruction::RETURN:
    case Instruction::RETURN_OBJECT:
    case Instruction::RETURN_WIDE:
    case Instruction::GOTO:
    case Instruction::GOTO_16:
    case Instruction::GOTO_32:
    case Instruction::PACKED_SWITCH:
    case Instruction::SPARSE_SWITCH:
    case Instruction::IF_EQ:
    case Instruction::IF_NE:
    case Instruction::IF_LT:
    case Instruction::IF_GE:
    case Instruction::IF_GT:
    case Instruction::IF_LE:
    case Instruction::IF_EQZ:
    case Instruction::IF_NEZ:
    case Instruction::IF_LTZ:
    case Instruction::IF_GEZ:
    case Instruction::IF_GTZ:
    case Instruction::IF_LEZ:
    case kMirOpFusedCmplFloat:
    case kMirOpFusedCmpgFloat:
    case kMirOpFusedCmplDouble:
    case kMirOpFusedCmpgDouble:
    case kMirOpFusedCmpLong:
      must_keep = true;
      uses_all_vregs = true;  // Keep the implicit dependencies on all vregs.
      break;

    case Instruction::CONST_CLASS:
    case Instruction::CONST_STRING:
    case Instruction::CONST_STRING_JUMBO:
      // NOTE: While we're currently treating CONST_CLASS, CONST_STRING and CONST_STRING_JUMBO
      // as throwing but we could conceivably try and eliminate those exceptions if we're
      // retrieving the class/string repeatedly.
      must_keep = true;
      uses_all_vregs = true;
      break;

    case Instruction::MONITOR_ENTER:
    case Instruction::MONITOR_EXIT:
      // We can actually try and optimize across the acquire operation of MONITOR_ENTER,
      // the value names provided by GVN reflect the possible changes to memory visibility.
      // NOTE: In ART, MONITOR_ENTER and MONITOR_EXIT can throw only NPE.
      must_keep = true;
      uses_all_vregs = (mir->optimization_flags & MIR_IGNORE_NULL_CHECK) == 0;
      break;

    case Instruction::INVOKE_DIRECT:
    case Instruction::INVOKE_DIRECT_RANGE:
    case Instruction::INVOKE_VIRTUAL:
    case Instruction::INVOKE_VIRTUAL_RANGE:
    case Instruction::INVOKE_SUPER:
    case Instruction::INVOKE_SUPER_RANGE:
    case Instruction::INVOKE_INTERFACE:
    case Instruction::INVOKE_INTERFACE_RANGE:
    case Instruction::INVOKE_STATIC:
    case Instruction::INVOKE_STATIC_RANGE:
    case Instruction::THROW:
    case Instruction::FILLED_NEW_ARRAY:
    case Instruction::FILLED_NEW_ARRAY_RANGE:
    case Instruction::FILL_ARRAY_DATA:
      must_keep = true;
      uses_all_vregs = true;
      break;

    case Instruction::NEW_INSTANCE:
    case Instruction::NEW_ARRAY:
      must_keep = true;
      uses_all_vregs = true;
      break;

    case Instruction::CHECK_CAST:
      DCHECK_EQ(mir->ssa_rep->num_uses, 1);
      must_keep = true;  // Keep for type information even if MIR_IGNORE_CHECK_CAST.
      uses_all_vregs = (mir->optimization_flags & MIR_IGNORE_CHECK_CAST) == 0;
      break;

    case kMirOpNullCheck:
      DCHECK_EQ(mir->ssa_rep->num_uses, 1);
      if ((mir->optimization_flags & MIR_IGNORE_NULL_CHECK) != 0) {
        mir->ssa_rep->num_uses = 0;
        mir->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
        return false;
      }
      must_keep = true;
      uses_all_vregs = true;
      break;

    case Instruction::MOVE_RESULT:
    case Instruction::MOVE_RESULT_OBJECT:
    case Instruction::MOVE_RESULT_WIDE:
      break;

    case Instruction::INSTANCE_OF:
      break;

    case Instruction::MOVE_EXCEPTION:
      must_keep = true;
      break;

    case kMirOpCopy:
    case Instruction::MOVE:
    case Instruction::MOVE_FROM16:
    case Instruction::MOVE_16:
    case Instruction::MOVE_WIDE:
    case Instruction::MOVE_WIDE_FROM16:
    case Instruction::MOVE_WIDE_16:
    case Instruction::MOVE_OBJECT:
    case Instruction::MOVE_OBJECT_FROM16:
    case Instruction::MOVE_OBJECT_16: {
      is_move = true;
      // If the MIR defining src vreg is known, allow renaming all uses of src vreg to dest vreg
      // while updating the defining MIR to directly define dest vreg. However, changing Phi's
      // def this way doesn't work without changing MIRs in other BBs.
      int src_v_reg = mir_graph_->SRegToVReg(mir->ssa_rep->uses[0]);
      int src_change = vreg_chains_.LastChange(src_v_reg);
      if (src_change != kNPos) {
        MIRData* src_data = vreg_chains_.GetMIRData(src_change);
        if (static_cast<int>(src_data->mir->dalvikInsn.opcode) != kMirOpPhi) {
          src_data->is_move_src = true;
        }
      }
      break;
    }

    case Instruction::CONST_4:
    case Instruction::CONST_16:
    case Instruction::CONST:
    case Instruction::CONST_HIGH16:
    case Instruction::CONST_WIDE_16:
    case Instruction::CONST_WIDE_32:
    case Instruction::CONST_WIDE:
    case Instruction::CONST_WIDE_HIGH16:
    case Instruction::CMPL_FLOAT:
    case Instruction::CMPG_FLOAT:
    case Instruction::CMPL_DOUBLE:
    case Instruction::CMPG_DOUBLE:
    case Instruction::CMP_LONG:
    case Instruction::NEG_INT:
    case Instruction::NOT_INT:
    case Instruction::NEG_LONG:
    case Instruction::NOT_LONG:
    case Instruction::NEG_FLOAT:
    case Instruction::NEG_DOUBLE:
    case Instruction::INT_TO_LONG:
    case Instruction::INT_TO_FLOAT:
    case Instruction::INT_TO_DOUBLE:
    case Instruction::LONG_TO_INT:
    case Instruction::LONG_TO_FLOAT:
    case Instruction::LONG_TO_DOUBLE:
    case Instruction::FLOAT_TO_INT:
    case Instruction::FLOAT_TO_LONG:
    case Instruction::FLOAT_TO_DOUBLE:
    case Instruction::DOUBLE_TO_INT:
    case Instruction::DOUBLE_TO_LONG:
    case Instruction::DOUBLE_TO_FLOAT:
    case Instruction::INT_TO_BYTE:
    case Instruction::INT_TO_CHAR:
    case Instruction::INT_TO_SHORT:
    case Instruction::ADD_INT:
    case Instruction::SUB_INT:
    case Instruction::MUL_INT:
    case Instruction::AND_INT:
    case Instruction::OR_INT:
    case Instruction::XOR_INT:
    case Instruction::SHL_INT:
    case Instruction::SHR_INT:
    case Instruction::USHR_INT:
    case Instruction::ADD_LONG:
    case Instruction::SUB_LONG:
    case Instruction::MUL_LONG:
    case Instruction::AND_LONG:
    case Instruction::OR_LONG:
    case Instruction::XOR_LONG:
    case Instruction::SHL_LONG:
    case Instruction::SHR_LONG:
    case Instruction::USHR_LONG:
    case Instruction::ADD_FLOAT:
    case Instruction::SUB_FLOAT:
    case Instruction::MUL_FLOAT:
    case Instruction::DIV_FLOAT:
    case Instruction::REM_FLOAT:
    case Instruction::ADD_DOUBLE:
    case Instruction::SUB_DOUBLE:
    case Instruction::MUL_DOUBLE:
    case Instruction::DIV_DOUBLE:
    case Instruction::REM_DOUBLE:
    case Instruction::ADD_INT_2ADDR:
    case Instruction::SUB_INT_2ADDR:
    case Instruction::MUL_INT_2ADDR:
    case Instruction::AND_INT_2ADDR:
    case Instruction::OR_INT_2ADDR:
    case Instruction::XOR_INT_2ADDR:
    case Instruction::SHL_INT_2ADDR:
    case Instruction::SHR_INT_2ADDR:
    case Instruction::USHR_INT_2ADDR:
    case Instruction::ADD_LONG_2ADDR:
    case Instruction::SUB_LONG_2ADDR:
    case Instruction::MUL_LONG_2ADDR:
    case Instruction::AND_LONG_2ADDR:
    case Instruction::OR_LONG_2ADDR:
    case Instruction::XOR_LONG_2ADDR:
    case Instruction::SHL_LONG_2ADDR:
    case Instruction::SHR_LONG_2ADDR:
    case Instruction::USHR_LONG_2ADDR:
    case Instruction::ADD_FLOAT_2ADDR:
    case Instruction::SUB_FLOAT_2ADDR:
    case Instruction::MUL_FLOAT_2ADDR:
    case Instruction::DIV_FLOAT_2ADDR:
    case Instruction::REM_FLOAT_2ADDR:
    case Instruction::ADD_DOUBLE_2ADDR:
    case Instruction::SUB_DOUBLE_2ADDR:
    case Instruction::MUL_DOUBLE_2ADDR:
    case Instruction::DIV_DOUBLE_2ADDR:
    case Instruction::REM_DOUBLE_2ADDR:
    case Instruction::ADD_INT_LIT16:
    case Instruction::RSUB_INT:
    case Instruction::MUL_INT_LIT16:
    case Instruction::AND_INT_LIT16:
    case Instruction::OR_INT_LIT16:
    case Instruction::XOR_INT_LIT16:
    case Instruction::ADD_INT_LIT8:
    case Instruction::RSUB_INT_LIT8:
    case Instruction::MUL_INT_LIT8:
    case Instruction::AND_INT_LIT8:
    case Instruction::OR_INT_LIT8:
    case Instruction::XOR_INT_LIT8:
    case Instruction::SHL_INT_LIT8:
    case Instruction::SHR_INT_LIT8:
    case Instruction::USHR_INT_LIT8:
      break;

    case Instruction::DIV_INT:
    case Instruction::REM_INT:
    case Instruction::DIV_LONG:
    case Instruction::REM_LONG:
    case Instruction::DIV_INT_2ADDR:
    case Instruction::REM_INT_2ADDR:
    case Instruction::DIV_LONG_2ADDR:
    case Instruction::REM_LONG_2ADDR:
      if ((mir->optimization_flags & MIR_IGNORE_DIV_ZERO_CHECK) == 0) {
        must_keep = true;
        uses_all_vregs = true;
      }
      break;

    case Instruction::DIV_INT_LIT16:
    case Instruction::REM_INT_LIT16:
    case Instruction::DIV_INT_LIT8:
    case Instruction::REM_INT_LIT8:
      if (mir->dalvikInsn.vC == 0) {  // Explicit division by 0?
        must_keep = true;
        uses_all_vregs = true;
      }
      break;

    case Instruction::ARRAY_LENGTH:
      if ((mir->optimization_flags & MIR_IGNORE_NULL_CHECK) == 0) {
        must_keep = true;
        uses_all_vregs = true;
      }
      break;

    case Instruction::AGET_OBJECT:
    case Instruction::AGET:
    case Instruction::AGET_WIDE:
    case Instruction::AGET_BOOLEAN:
    case Instruction::AGET_BYTE:
    case Instruction::AGET_CHAR:
    case Instruction::AGET_SHORT:
      if ((mir->optimization_flags & MIR_IGNORE_NULL_CHECK) == 0 ||
          (mir->optimization_flags & MIR_IGNORE_RANGE_CHECK) == 0) {
        must_keep = true;
        uses_all_vregs = true;
      }
      break;

    case Instruction::APUT_OBJECT:
    case Instruction::APUT:
    case Instruction::APUT_WIDE:
    case Instruction::APUT_BYTE:
    case Instruction::APUT_BOOLEAN:
    case Instruction::APUT_SHORT:
    case Instruction::APUT_CHAR:
      must_keep = true;
      if ((mir->optimization_flags & MIR_IGNORE_NULL_CHECK) == 0 ||
          (mir->optimization_flags & MIR_IGNORE_RANGE_CHECK) == 0) {
        uses_all_vregs = true;
      }
      break;

    case Instruction::IGET_OBJECT:
    case Instruction::IGET:
    case Instruction::IGET_WIDE:
    case Instruction::IGET_BOOLEAN:
    case Instruction::IGET_BYTE:
    case Instruction::IGET_CHAR:
    case Instruction::IGET_SHORT: {
      const MirIFieldLoweringInfo& info = mir_graph_->GetIFieldLoweringInfo(mir);
      if ((mir->optimization_flags & MIR_IGNORE_NULL_CHECK) == 0 ||
          !info.IsResolved() || !info.FastGet()) {
        must_keep = true;
        uses_all_vregs = true;
      } else if (info.IsVolatile()) {
        must_keep = true;
      }
      break;
    }

    case Instruction::IPUT_OBJECT:
    case Instruction::IPUT:
    case Instruction::IPUT_WIDE:
    case Instruction::IPUT_BOOLEAN:
    case Instruction::IPUT_BYTE:
    case Instruction::IPUT_CHAR:
    case Instruction::IPUT_SHORT: {
      must_keep = true;
      const MirIFieldLoweringInfo& info = mir_graph_->GetIFieldLoweringInfo(mir);
      if ((mir->optimization_flags & MIR_IGNORE_NULL_CHECK) == 0 ||
          !info.IsResolved() || !info.FastPut()) {
        uses_all_vregs = true;
      }
      break;
    }

    case Instruction::SGET_OBJECT:
    case Instruction::SGET:
    case Instruction::SGET_WIDE:
    case Instruction::SGET_BOOLEAN:
    case Instruction::SGET_BYTE:
    case Instruction::SGET_CHAR:
    case Instruction::SGET_SHORT: {
      const MirSFieldLoweringInfo& info = mir_graph_->GetSFieldLoweringInfo(mir);
      if ((mir->optimization_flags & MIR_CLASS_IS_INITIALIZED) == 0 ||
          !info.IsResolved() || !info.FastGet()) {
        must_keep = true;
        uses_all_vregs = true;
      } else if (info.IsVolatile()) {
        must_keep = true;
      }
      break;
    }

    case Instruction::SPUT_OBJECT:
    case Instruction::SPUT:
    case Instruction::SPUT_WIDE:
    case Instruction::SPUT_BOOLEAN:
    case Instruction::SPUT_BYTE:
    case Instruction::SPUT_CHAR:
    case Instruction::SPUT_SHORT: {
      must_keep = true;
      const MirSFieldLoweringInfo& info = mir_graph_->GetSFieldLoweringInfo(mir);
      if ((mir->optimization_flags & MIR_CLASS_IS_INITIALIZED) == 0 ||
          !info.IsResolved() || !info.FastPut()) {
        uses_all_vregs = true;
      }
      break;
    }

    default:
      LOG(FATAL) << "Unexpected opcode: " << opcode;
      UNREACHABLE();
  }

  if (mir->ssa_rep->num_defs != 0) {
    DCHECK(mir->ssa_rep->num_defs == 1 || mir->ssa_rep->num_defs == 2);
    bool wide = (mir->ssa_rep->num_defs == 2);
    int s_reg = mir->ssa_rep->defs[0];
    int v_reg = mir_graph_->SRegToVReg(s_reg);
    uint16_t new_value = wide ? lvn_->GetSregValueWide(s_reg) : lvn_->GetSregValue(s_reg);
    DCHECK_NE(new_value, kNoValue);

    vreg_chains_.UpdateInitialVRegValue(v_reg, wide, lvn_);
    vreg_chains_.AddMIRWithDef(mir, v_reg, wide, new_value);
    if (is_move) {
      // Allow renaming all uses of dest vreg to src vreg.
      vreg_chains_.LastMIRData()->is_move = true;
    }
  } else {
    vreg_chains_.AddMIRWithoutDef(mir);
    DCHECK(!is_move) << opcode;
  }

  if (must_keep) {
    MIRData* last_data = vreg_chains_.LastMIRData();
    last_data->must_keep = true;
    if (uses_all_vregs) {
      last_data->uses_all_vregs = true;
      no_uses_all_since_ = vreg_chains_.NumMIRs();
    }
  } else {
    DCHECK_NE(mir->ssa_rep->num_defs, 0) << opcode;
    DCHECK(!uses_all_vregs) << opcode;
  }
  return true;
}

}  // namespace art
