diff options
author | Vladimir Marko <vmarko@google.com> | 2014-11-24 12:39:45 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-11-24 12:39:46 +0000 |
commit | c2155048075b4916536f3aa23a88cd483b0f64a2 (patch) | |
tree | 1a5b4cd931c8b5f0011c68318354cf21a5eea92c | |
parent | c12da2d91c26e74786a32e7583d996416a2f3494 (diff) | |
parent | c7a77bfecb77c7a4538775411049e76eb853641c (diff) | |
download | android_art-c2155048075b4916536f3aa23a88cd483b0f64a2.tar.gz android_art-c2155048075b4916536f3aa23a88cd483b0f64a2.tar.bz2 android_art-c2155048075b4916536f3aa23a88cd483b0f64a2.zip |
Merge "ART: Fix NullCheckElimination, BBCombine, and SplitBlock"
-rw-r--r-- | compiler/dex/mir_graph.cc | 2 | ||||
-rw-r--r-- | compiler/dex/mir_optimization.cc | 28 |
2 files changed, 16 insertions, 14 deletions
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc index f69d63c135..8190f95275 100644 --- a/compiler/dex/mir_graph.cc +++ b/compiler/dex/mir_graph.cc @@ -258,8 +258,6 @@ BasicBlock* MIRGraph::SplitBlock(DexOffset code_offset, DCHECK(insn != orig_block->first_mir_insn); DCHECK(insn == bottom_block->first_mir_insn); DCHECK_EQ(insn->offset, bottom_block->start_offset); - DCHECK(static_cast<int>(insn->dalvikInsn.opcode) == kMirOpCheck || - !MIR::DecodedInstruction::IsPseudoMirOp(insn->dalvikInsn.opcode)); DCHECK_EQ(dex_pc_to_block_map_[insn->offset], orig_block->id); // Scan the "bottom" instructions, remapping them to the // newly created "bottom" block. diff --git a/compiler/dex/mir_optimization.cc b/compiler/dex/mir_optimization.cc index fd564ed1da..9d52807725 100644 --- a/compiler/dex/mir_optimization.cc +++ b/compiler/dex/mir_optimization.cc @@ -798,17 +798,18 @@ void MIRGraph::CombineBlocks(class BasicBlock* bb) { BasicBlock* bb_next = GetBasicBlock(bb->fall_through); DCHECK(!bb_next->catch_entry); DCHECK_EQ(bb_next->predecessors.size(), 1u); - // Overwrite the kMirOpCheck insn with the paired opcode. + + // Now move instructions from bb_next to bb. Start off with doing a sanity check + // that kMirOpCheck's throw instruction is first one in the bb_next. DCHECK_EQ(bb_next->first_mir_insn, throw_insn); - *bb->last_mir_insn = *throw_insn; - // And grab the rest of the instructions from bb_next. - bb->last_mir_insn = bb_next->last_mir_insn; - throw_insn->next = nullptr; - bb_next->last_mir_insn = throw_insn; - // Mark acquired instructions as belonging to bb. - for (MIR* insn = mir; insn != nullptr; insn = insn->next) { - insn->bb = bb->id; - } + // Now move all instructions (throw instruction to last one) from bb_next to bb. + MIR* last_to_move = bb_next->last_mir_insn; + bb_next->RemoveMIRList(throw_insn, last_to_move); + bb->InsertMIRListAfter(bb->last_mir_insn, throw_insn, last_to_move); + // The kMirOpCheck instruction is not needed anymore. + mir->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop); + bb->RemoveMIR(mir); + // Before we overwrite successors, remove their predecessor links to bb. bb_next->ErasePredecessor(bb->id); if (bb->taken != NullBasicBlockId) { @@ -888,7 +889,7 @@ bool MIRGraph::EliminateNullChecksGate() { DCHECK(temp_scoped_alloc_.get() == nullptr); temp_scoped_alloc_.reset(ScopedArenaAllocator::Create(&cu_->arena_stack)); - temp_.nce.num_vregs = GetNumOfCodeVRs(); + temp_.nce.num_vregs = GetNumOfCodeAndTempVRs(); temp_.nce.work_vregs_to_check = new (temp_scoped_alloc_.get()) ArenaBitVector( temp_scoped_alloc_.get(), temp_.nce.num_vregs, false, kBitMapNullCheck); temp_.nce.ending_vregs_to_check_matrix = static_cast<ArenaBitVector**>( @@ -976,7 +977,10 @@ bool MIRGraph::EliminateNullChecks(BasicBlock* bb) { for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) { uint64_t df_attributes = GetDataFlowAttributes(mir); - DCHECK_EQ(df_attributes & DF_NULL_TRANSFER_N, 0u); // No Phis yet. + if ((df_attributes & DF_NULL_TRANSFER_N) != 0u) { + // The algorithm was written in a phi agnostic way. + continue; + } // Might need a null check? if (df_attributes & DF_HAS_NULL_CHKS) { |