/*
 * 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/arena_bit_vector.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"

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);
    uint32_t dest_v_reg = mir_graph_->SRegToVReg(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_))) {
            // If the move's destination vreg changed, check if the vreg we're trying
            // to rename is unused after that change.
            uint16_t dest_change = vreg_chains_.FindFirstChangeAfter(new_dest_v_reg, c);
            if (d->wide_def) {
              uint16_t dest_change_high = vreg_chains_.FindFirstChangeAfter(new_dest_v_reg + 1, c);
              if (dest_change_high != kNPos &&
                  (dest_change == kNPos || dest_change_high < dest_change)) {
                dest_change = dest_change_high;
              }
            }
            if (dest_change == kNPos ||
                !vreg_chains_.IsVRegUsed(dest_change + 1u, size, dest_v_reg, 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
