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