195a059793c4c194f026afc74c713cc295d75d91aVladimir Marko/*
295a059793c4c194f026afc74c713cc295d75d91aVladimir Marko * Copyright (C) 2014 The Android Open Source Project
395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko *
495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko * Licensed under the Apache License, Version 2.0 (the "License");
595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko * you may not use this file except in compliance with the License.
695a059793c4c194f026afc74c713cc295d75d91aVladimir Marko * You may obtain a copy of the License at
795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko *
895a059793c4c194f026afc74c713cc295d75d91aVladimir Marko *      http://www.apache.org/licenses/LICENSE-2.0
995a059793c4c194f026afc74c713cc295d75d91aVladimir Marko *
1095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko * Unless required by applicable law or agreed to in writing, software
1195a059793c4c194f026afc74c713cc295d75d91aVladimir Marko * distributed under the License is distributed on an "AS IS" BASIS,
1295a059793c4c194f026afc74c713cc295d75d91aVladimir Marko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko * See the License for the specific language governing permissions and
1495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko * limitations under the License.
1595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko */
1695a059793c4c194f026afc74c713cc295d75d91aVladimir Marko
1795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko#include "global_value_numbering.h"
1895a059793c4c194f026afc74c713cc295d75d91aVladimir Marko
1995a059793c4c194f026afc74c713cc295d75d91aVladimir Marko#include "local_value_numbering.h"
2095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko
2195a059793c4c194f026afc74c713cc295d75d91aVladimir Markonamespace art {
2295a059793c4c194f026afc74c713cc295d75d91aVladimir Marko
2395a059793c4c194f026afc74c713cc295d75d91aVladimir MarkoGlobalValueNumbering::GlobalValueNumbering(CompilationUnit* cu, ScopedArenaAllocator* allocator)
2495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    : cu_(cu),
2555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko      mir_graph_(cu->mir_graph.get()),
2695a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      allocator_(allocator),
2755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko      bbs_processed_(0u),
2855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko      max_bbs_to_process_(kMaxBbsToProcessMultiplyFactor * mir_graph_->GetNumReachableBlocks()),
2995a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      last_value_(0u),
3095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      modifications_allowed_(false),
3195a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      global_value_map_(std::less<uint64_t>(), allocator->Adapter()),
3295a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      field_index_map_(FieldReferenceComparator(), allocator->Adapter()),
3395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      field_index_reverse_map_(allocator->Adapter()),
3495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      array_location_map_(ArrayLocationComparator(), allocator->Adapter()),
3595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      array_location_reverse_map_(allocator->Adapter()),
3695a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      ref_set_map_(std::less<ValueNameSet>(), allocator->Adapter()),
3755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko      lvns_(mir_graph_->GetNumBlocks(), nullptr, allocator->Adapter()),
3895a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      work_lvn_(nullptr),
3995a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      merge_lvns_(allocator->Adapter()) {
4095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko}
4195a059793c4c194f026afc74c713cc295d75d91aVladimir Marko
4295a059793c4c194f026afc74c713cc295d75d91aVladimir MarkoGlobalValueNumbering::~GlobalValueNumbering() {
4395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  STLDeleteElements(&lvns_);
4495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko}
4595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko
46b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir MarkoLocalValueNumbering* GlobalValueNumbering::PrepareBasicBlock(BasicBlock* bb,
47b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko                                                             ScopedArenaAllocator* allocator) {
4895a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  if (UNLIKELY(!Good())) {
4995a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    return nullptr;
5095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  }
5155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko  if (UNLIKELY(bb->data_flow_info == nullptr)) {
5295a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    return nullptr;
5395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  }
5455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko  if (UNLIKELY(bb->block_type == kExitBlock)) {
5595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    DCHECK(bb->first_mir_insn == nullptr);
5695a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    return nullptr;
5795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  }
5855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko  if (UNLIKELY(bbs_processed_ == max_bbs_to_process_)) {
5955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    last_value_ = kNoValue;  // Make bad.
6095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    return nullptr;
6195a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  }
62b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko  if (allocator == nullptr) {
63b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko    allocator = allocator_;
64b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko  }
6595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  DCHECK(work_lvn_.get() == nullptr);
66b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko  work_lvn_.reset(new (allocator) LocalValueNumbering(this, bb->id, allocator));
6795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  if (bb->block_type == kEntryBlock) {
6895a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    if ((cu_->access_flags & kAccStatic) == 0) {
6995a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      // If non-static method, mark "this" as non-null
7095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      int this_reg = cu_->num_dalvik_registers - cu_->num_ins;
71b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko      uint16_t value_name = work_lvn_->GetSRegValueName(this_reg);
72b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko      work_lvn_->SetValueNameNullChecked(value_name);
7395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    }
7495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  } else {
7595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    // To avoid repeated allocation on the ArenaStack, reuse a single vector kept as a member.
7695a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    DCHECK(merge_lvns_.empty());
7755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    // If we're running the full GVN, the RepeatingTopologicalSortIterator keeps the loop
7855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    // head stack in the MIRGraph up to date and for a loop head we need to check whether
7955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    // we're making the initial computation and need to merge only preceding blocks in the
8055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    // topological order, or we're recalculating a loop head and need to merge all incoming
8155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    // LVNs. When we're not at a loop head (including having an empty loop head stack) all
8255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    // predecessors should be preceding blocks and we shall merge all of them anyway.
8355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    //
8455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    // If we're running the modification phase of the full GVN, the loop head stack will be
8555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    // empty and we need to merge all incoming LVNs. If we're running just a simple LVN,
8655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    // the loop head stack will also be empty and there will be nothing to merge anyway.
8755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    bool use_all_predecessors = true;
8855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    uint16_t loop_head_idx = 0u;  // Used only if !use_all_predecessors.
8955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    if (mir_graph_->GetTopologicalSortOrderLoopHeadStack()->Size() != 0) {
9055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko      // Full GVN inside a loop, see if we're at the loop head for the first time.
9155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko      auto top = mir_graph_->GetTopologicalSortOrderLoopHeadStack()->Peek();
9255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko      loop_head_idx = top.first;
9355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko      bool recalculating = top.second;
9455fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko      use_all_predecessors = recalculating ||
9555fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko          loop_head_idx != mir_graph_->GetTopologicalSortOrderIndexes()->Get(bb->id);
9655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    }
9795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    GrowableArray<BasicBlockId>::Iterator iter(bb->predecessors);
9855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko    for (BasicBlock* pred_bb = mir_graph_->GetBasicBlock(iter.Next());
9955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko         pred_bb != nullptr; pred_bb = mir_graph_->GetBasicBlock(iter.Next())) {
10055fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko      if (lvns_[pred_bb->id] != nullptr &&
10155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko          (use_all_predecessors ||
10255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko              mir_graph_->GetTopologicalSortOrderIndexes()->Get(pred_bb->id) < loop_head_idx)) {
10395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko        merge_lvns_.push_back(lvns_[pred_bb->id]);
10495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      }
10595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    }
10695a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    // Determine merge type.
10795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    LocalValueNumbering::MergeType merge_type = LocalValueNumbering::kNormalMerge;
10895a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    if (bb->catch_entry) {
10995a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      merge_type = LocalValueNumbering::kCatchMerge;
11095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    } else if (bb->last_mir_insn != nullptr &&
11155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko        (bb->last_mir_insn->dalvikInsn.opcode == Instruction::RETURN_VOID ||
11255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko         bb->last_mir_insn->dalvikInsn.opcode == Instruction::RETURN ||
11395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko         bb->last_mir_insn->dalvikInsn.opcode == Instruction::RETURN_OBJECT ||
11495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko         bb->last_mir_insn->dalvikInsn.opcode == Instruction::RETURN_WIDE) &&
11595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko        (bb->first_mir_insn == bb->last_mir_insn ||
11655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko         (static_cast<int>(bb->first_mir_insn->dalvikInsn.opcode) == kMirOpPhi &&
11755fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko          (bb->first_mir_insn->next == bb->last_mir_insn ||
11855fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko           (static_cast<int>(bb->first_mir_insn->next->dalvikInsn.opcode) == kMirOpPhi &&
11955fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko            bb->first_mir_insn->next->next == bb->last_mir_insn))))) {
12095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      merge_type = LocalValueNumbering::kReturnMerge;
12195a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    }
12295a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    // At least one predecessor must have been processed before this bb.
12395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    CHECK(!merge_lvns_.empty());
12495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    if (merge_lvns_.size() == 1u) {
12595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      work_lvn_->MergeOne(*merge_lvns_[0], merge_type);
12655fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko      BasicBlock* pred_bb = mir_graph_->GetBasicBlock(merge_lvns_[0]->Id());
12795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      if (HasNullCheckLastInsn(pred_bb, bb->id)) {
128b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko        int s_reg = pred_bb->last_mir_insn->ssa_rep->uses[0];
129b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko        uint16_t value_name = merge_lvns_[0]->GetSRegValueName(s_reg);
130b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko        work_lvn_->SetValueNameNullChecked(value_name);
13195a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      }
13295a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    } else {
13395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      work_lvn_->Merge(merge_type);
13495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    }
13595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  }
13695a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  return work_lvn_.get();
13795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko}
13895a059793c4c194f026afc74c713cc295d75d91aVladimir Marko
13995a059793c4c194f026afc74c713cc295d75d91aVladimir Markobool GlobalValueNumbering::FinishBasicBlock(BasicBlock* bb) {
14095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  DCHECK(work_lvn_ != nullptr);
14155fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko  DCHECK_EQ(bb->id, work_lvn_->Id());
14255fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko  ++bbs_processed_;
14395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  merge_lvns_.clear();
14495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko
145b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko  bool change = (lvns_[bb->id] == nullptr) || !lvns_[bb->id]->Equals(*work_lvn_);
146b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko  if (change) {
147b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko    std::unique_ptr<const LocalValueNumbering> old_lvn(lvns_[bb->id]);
148b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko    lvns_[bb->id] = work_lvn_.release();
149b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko  } else {
150b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko    work_lvn_.reset();
151b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko  }
152b19955d3c8fbd9588f7e17299e559d02938154b6Vladimir Marko  return change;
15395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko}
15495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko
15595a059793c4c194f026afc74c713cc295d75d91aVladimir Markouint16_t GlobalValueNumbering::GetFieldId(const MirFieldInfo& field_info, uint16_t type) {
15695a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  FieldReference key = { field_info.DeclaringDexFile(), field_info.DeclaringFieldIndex(), type };
15795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  auto lb = field_index_map_.lower_bound(key);
15895a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  if (lb != field_index_map_.end() && !field_index_map_.key_comp()(key, lb->first)) {
15995a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    return lb->second;
16095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  }
16195a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  DCHECK_LT(field_index_map_.size(), kNoValue);
16295a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  uint16_t id = field_index_map_.size();
16395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  auto it = field_index_map_.PutBefore(lb, key, id);
16495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  field_index_reverse_map_.push_back(&*it);
16595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  return id;
16695a059793c4c194f026afc74c713cc295d75d91aVladimir Marko}
16795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko
16895a059793c4c194f026afc74c713cc295d75d91aVladimir Markouint16_t GlobalValueNumbering::GetArrayLocation(uint16_t base, uint16_t index) {
16995a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  auto cmp = array_location_map_.key_comp();
17095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  ArrayLocation key = { base, index };
17195a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  auto lb = array_location_map_.lower_bound(key);
17295a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  if (lb != array_location_map_.end() && !cmp(key, lb->first)) {
17395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    return lb->second;
17495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  }
17595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  uint16_t location = static_cast<uint16_t>(array_location_reverse_map_.size());
17695a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  DCHECK_EQ(location, array_location_reverse_map_.size());  // No overflow.
17795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  auto it = array_location_map_.PutBefore(lb, key, location);
17895a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  array_location_reverse_map_.push_back(&*it);
17995a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  return location;
18095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko}
18195a059793c4c194f026afc74c713cc295d75d91aVladimir Marko
18295a059793c4c194f026afc74c713cc295d75d91aVladimir Markobool GlobalValueNumbering::HasNullCheckLastInsn(const BasicBlock* pred_bb,
18395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko                                                BasicBlockId succ_id) {
18495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  if (pred_bb->block_type != kDalvikByteCode || pred_bb->last_mir_insn == nullptr) {
18595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    return false;
18695a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  }
18795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  Instruction::Code last_opcode = pred_bb->last_mir_insn->dalvikInsn.opcode;
18895a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  return ((last_opcode == Instruction::IF_EQZ && pred_bb->fall_through == succ_id) ||
18995a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      (last_opcode == Instruction::IF_NEZ && pred_bb->taken == succ_id));
19095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko}
19195a059793c4c194f026afc74c713cc295d75d91aVladimir Marko
19295a059793c4c194f026afc74c713cc295d75d91aVladimir Markobool GlobalValueNumbering::NullCheckedInAllPredecessors(
19395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    const ScopedArenaVector<uint16_t>& merge_names) const {
19495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  // Implicit parameters:
19595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  //   - *work_lvn: the LVN for which we're checking predecessors.
19695a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  //   - merge_lvns_: the predecessor LVNs.
19795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  DCHECK_EQ(merge_lvns_.size(), merge_names.size());
19895a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  for (size_t i = 0, size = merge_lvns_.size(); i != size; ++i) {
19995a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    const LocalValueNumbering* pred_lvn = merge_lvns_[i];
20095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    uint16_t value_name = merge_names[i];
20195a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    if (!pred_lvn->IsValueNullChecked(value_name)) {
20295a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      // Check if the predecessor has an IF_EQZ/IF_NEZ as the last insn.
20355fff044d3a4f7196098e25bab1dad106d9b54a2Vladimir Marko      const BasicBlock* pred_bb = mir_graph_->GetBasicBlock(pred_lvn->Id());
20495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      if (!HasNullCheckLastInsn(pred_bb, work_lvn_->Id())) {
20595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko        return false;
20695a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      }
20795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      // IF_EQZ/IF_NEZ checks some sreg, see if that sreg contains the value_name.
20895a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      int s_reg = pred_bb->last_mir_insn->ssa_rep->uses[0];
20995a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      if (!pred_lvn->IsSregValue(s_reg, value_name)) {
21095a059793c4c194f026afc74c713cc295d75d91aVladimir Marko        return false;
21195a059793c4c194f026afc74c713cc295d75d91aVladimir Marko      }
21295a059793c4c194f026afc74c713cc295d75d91aVladimir Marko    }
21395a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  }
21495a059793c4c194f026afc74c713cc295d75d91aVladimir Marko  return true;
21595a059793c4c194f026afc74c713cc295d75d91aVladimir Marko}
21695a059793c4c194f026afc74c713cc295d75d91aVladimir Marko
21795a059793c4c194f026afc74c713cc295d75d91aVladimir Marko}  // namespace art
218