diff options
author | David Brazdil <dbrazdil@google.com> | 2015-05-07 09:59:30 +0100 |
---|---|---|
committer | David Brazdil <dbrazdil@google.com> | 2015-05-13 10:02:07 +0100 |
commit | e8ff50df01c89e1b5264a5a900cfebdde87a9b44 (patch) | |
tree | a2c0cc80afcf4cbce0f2293e09c49cee98e5a4bb /compiler/optimizing/dead_code_elimination.cc | |
parent | 6185884829333f0035de0488b1c4a2e84c7dd38b (diff) | |
download | android_art-e8ff50df01c89e1b5264a5a900cfebdde87a9b44.tar.gz android_art-e8ff50df01c89e1b5264a5a900cfebdde87a9b44.tar.bz2 android_art-e8ff50df01c89e1b5264a5a900cfebdde87a9b44.zip |
ART: Rediscover loops after deleting blocks in DCE
The way DCE currently updates loop information does not cover all
cases. This patch removes the logic, resets loop information of live
blocks to pre-SSA state and reanalyzes the affected loops.
Change-Id: I0b996a70235b95a8db0de9a23a03f71db57a21b8
(cherry picked from commit a4b8c21dae70ae34aee13628632c39a675c06022)
Diffstat (limited to 'compiler/optimizing/dead_code_elimination.cc')
-rw-r--r-- | compiler/optimizing/dead_code_elimination.cc | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc index cd427c5ed8..6fbe75e802 100644 --- a/compiler/optimizing/dead_code_elimination.cc +++ b/compiler/optimizing/dead_code_elimination.cc @@ -47,6 +47,12 @@ static void MarkReachableBlocks(HBasicBlock* block, ArenaBitVector* visited) { } } +static void MarkLoopHeadersContaining(const HBasicBlock& block, ArenaBitVector* set) { + for (HLoopInformationOutwardIterator it(block); !it.Done(); it.Advance()) { + set->SetBit(it.Current()->GetHeader()->GetBlockId()); + } +} + void HDeadCodeElimination::MaybeRecordDeadBlock(HBasicBlock* block) { if (stats_ != nullptr) { stats_->RecordStat(MethodCompilationStat::kRemovedDeadInstruction, @@ -58,18 +64,24 @@ void HDeadCodeElimination::RemoveDeadBlocks() { // Classify blocks as reachable/unreachable. ArenaAllocator* allocator = graph_->GetArena(); ArenaBitVector live_blocks(allocator, graph_->GetBlocks().Size(), false); + ArenaBitVector affected_loops(allocator, graph_->GetBlocks().Size(), false); + MarkReachableBlocks(graph_->GetEntryBlock(), &live_blocks); - // Remove all dead blocks. Process blocks in post-order, because removal needs - // the block's chain of dominators. + // 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 + // inside out. for (HPostOrderIterator it(*graph_); !it.Done(); it.Advance()) { HBasicBlock* block = it.Current(); - if (live_blocks.IsBitSet(block->GetBlockId())) { - // If this block is part of a loop that is being dismantled, we need to - // update its loop information. - block->UpdateLoopInformation(); + int id = block->GetBlockId(); + if (live_blocks.IsBitSet(id)) { + if (affected_loops.IsBitSet(id)) { + DCHECK(block->IsLoopHeader()); + block->GetLoopInformation()->Update(); + } } else { MaybeRecordDeadBlock(block); + MarkLoopHeadersContaining(*block, &affected_loops); block->DisconnectAndDelete(); } } |