diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2015-06-24 12:20:24 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2015-06-24 16:33:23 +0100 |
commit | 18b236e5261d2b1f312e632a4d3bb2273c8bf641 (patch) | |
tree | 1f4b070a76ec80935a470a1245dd37c35b71ece2 /compiler | |
parent | 574cce14025e153d87ec051926d331c5a39e5f92 (diff) | |
download | art-18b236e5261d2b1f312e632a4d3bb2273c8bf641.zip art-18b236e5261d2b1f312e632a4d3bb2273c8bf641.tar.gz art-18b236e5261d2b1f312e632a4d3bb2273c8bf641.tar.bz2 |
Recompute dominator tree after DCE.
bug:22031382
(cherry picked from commit 1f82ecc6a0c9f88d03d6d1a6d95eeb8707bd06c1)
Change-Id: I9a74edb185cb806045903dfe9695d9cc1a02e86b
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/optimizing/boolean_simplifier.cc | 6 | ||||
-rw-r--r-- | compiler/optimizing/dead_code_elimination.cc | 9 | ||||
-rw-r--r-- | compiler/optimizing/nodes.cc | 37 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 8 |
4 files changed, 39 insertions, 21 deletions
diff --git a/compiler/optimizing/boolean_simplifier.cc b/compiler/optimizing/boolean_simplifier.cc index 8100a29..daf7d67 100644 --- a/compiler/optimizing/boolean_simplifier.cc +++ b/compiler/optimizing/boolean_simplifier.cc @@ -141,6 +141,12 @@ void HBooleanSimplifier::TryRemovingBooleanSelection(HBasicBlock* block) { block->MergeWith(false_block); block->MergeWith(merge_block); + // No need to update any dominance information, as we are simplifying + // a simple diamond shape, where the join block is merged with the + // entry block. Any following blocks would have had the join block + // as a dominator, and `MergeWith` handles changing that to the + // entry block. + // Remove the original condition if it is now unused. if (!if_condition->HasUses()) { if_condition->GetBlock()->RemoveInstructionOrPhi(if_condition); diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc index 6fbe75e..2362cc1 100644 --- a/compiler/optimizing/dead_code_elimination.cc +++ b/compiler/optimizing/dead_code_elimination.cc @@ -67,6 +67,7 @@ void HDeadCodeElimination::RemoveDeadBlocks() { ArenaBitVector affected_loops(allocator, graph_->GetBlocks().Size(), false); MarkReachableBlocks(graph_->GetEntryBlock(), &live_blocks); + bool removed_one_or_more_blocks = false; // Remove all dead blocks. Iterate in post order because removal needs the // block's chain of dominators and nested loops need to be updated from the @@ -83,9 +84,17 @@ void HDeadCodeElimination::RemoveDeadBlocks() { MaybeRecordDeadBlock(block); MarkLoopHeadersContaining(*block, &affected_loops); block->DisconnectAndDelete(); + removed_one_or_more_blocks = true; } } + // If we removed at least one block, we need to recompute the full + // dominator tree. + if (removed_one_or_more_blocks) { + graph_->ClearDominanceInformation(); + graph_->ComputeDominanceInformation(); + } + // Connect successive blocks created by dead branches. Order does not matter. for (HReversePostOrderIterator it(*graph_); !it.Done();) { HBasicBlock* block = it.Current(); diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index c01364a..88490d0 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -116,9 +116,24 @@ void HGraph::BuildDominatorTree() { // dominators and the reverse post order. SimplifyCFG(); - // (5) Compute the immediate dominator of each block. We visit - // the successors of a block only when all its forward branches - // have been processed. + // (5) Compute the dominance information and the reverse post order. + ComputeDominanceInformation(); +} + +void HGraph::ClearDominanceInformation() { + for (HReversePostOrderIterator it(*this); !it.Done(); it.Advance()) { + it.Current()->ClearDominanceInformation(); + } + reverse_post_order_.Reset(); +} + +void HBasicBlock::ClearDominanceInformation() { + dominated_blocks_.Reset(); + dominator_ = nullptr; +} + +void HGraph::ComputeDominanceInformation() { + DCHECK(reverse_post_order_.IsEmpty()); GrowableArray<size_t> visits(arena_, blocks_.Size()); visits.SetSize(blocks_.Size()); reverse_post_order_.Add(entry_block_); @@ -1037,8 +1052,7 @@ void HBasicBlock::DisconnectAndDelete() { } predecessors_.Reset(); - // Disconnect the block from its successors and update their dominators - // and phis. + // Disconnect the block from its successors and update their phis. for (size_t i = 0, e = successors_.Size(); i < e; ++i) { HBasicBlock* successor = successors_.Get(i); // Delete this block from the list of predecessors. @@ -1049,19 +1063,6 @@ void HBasicBlock::DisconnectAndDelete() { // dominator of `successor` which violates the order DCHECKed at the top. DCHECK(!successor->predecessors_.IsEmpty()); - // Recompute the successor's dominator. - HBasicBlock* old_dominator = successor->GetDominator(); - HBasicBlock* new_dominator = successor->predecessors_.Get(0); - for (size_t j = 1, f = successor->predecessors_.Size(); j < f; ++j) { - new_dominator = graph_->FindCommonDominator( - new_dominator, successor->predecessors_.Get(j)); - } - if (old_dominator != new_dominator) { - successor->SetDominator(new_dominator); - old_dominator->RemoveDominatedBlock(successor); - new_dominator->AddDominatedBlock(successor); - } - // Remove this block's entries in the successor's phis. if (successor->predecessors_.Size() == 1u) { // The successor has just one predecessor left. Replace phis with the only diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 394e3fc..b36d9b8 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -170,6 +170,9 @@ class HGraph : public ArenaObject<kArenaAllocMisc> { return true; } + void ComputeDominanceInformation(); + void ClearDominanceInformation(); + void BuildDominatorTree(); void TransformToSsa(); void SimplifyCFG(); @@ -547,11 +550,10 @@ class HBasicBlock : public ArenaObject<kArenaAllocMisc> { LOG(FATAL) << "Unreachable"; UNREACHABLE(); } + void ClearDominanceInformation(); int NumberOfBackEdges() const { - return loop_information_ == nullptr - ? 0 - : loop_information_->NumberOfBackEdges(); + return IsLoopHeader() ? loop_information_->NumberOfBackEdges() : 0; } HInstruction* GetFirstInstruction() const { return instructions_.first_instruction_; } |