/*
 * 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_(num_vregs, 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
