summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing/dead_code_elimination.cc
diff options
context:
space:
mode:
authorDavid Brazdil <dbrazdil@google.com>2015-05-07 09:59:30 +0100
committerDavid Brazdil <dbrazdil@google.com>2015-05-13 10:02:07 +0100
commite8ff50df01c89e1b5264a5a900cfebdde87a9b44 (patch)
treea2c0cc80afcf4cbce0f2293e09c49cee98e5a4bb /compiler/optimizing/dead_code_elimination.cc
parent6185884829333f0035de0488b1c4a2e84c7dd38b (diff)
downloadandroid_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.cc24
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();
}
}