diff options
author | 2015-04-15 18:22:45 +0100 | |
---|---|---|
committer | 2015-04-15 21:51:12 +0100 | |
commit | f776b92a0d52bb522043812dacb9c21ac11858e2 (patch) | |
tree | 619ae49853b201fc4ea9d0ac4b113c6226e3c339 /compiler/optimizing/nodes.cc | |
parent | acf9b7b7616a9b104e6f2146051d8e14d9cb9030 (diff) |
Remove dead blocks for the blocks_ array.
This prevents crashing because of structurally incorrect
blocks. Also we now don't need to remove its instructions.
Test case courtesy of Serguei I Katkov.
Change-Id: Ia3ef9580549fc3546e8cd5f346079b1f0ceb2a61
Diffstat (limited to 'compiler/optimizing/nodes.cc')
-rw-r--r-- | compiler/optimizing/nodes.cc | 22 |
1 files changed, 10 insertions, 12 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index d8a8554610..ada3487963 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -51,9 +51,7 @@ void HGraph::RemoveInstructionsAsUsersFromDeadBlocks(const ArenaBitVector& visit for (size_t i = 0; i < blocks_.Size(); ++i) { if (!visited.IsBitSet(i)) { HBasicBlock* block = blocks_.Get(i); - for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { - RemoveAsUser(it.Current()); - } + DCHECK(block->GetPhis().IsEmpty()) << "Phis are not inserted at this stage"; for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) { RemoveAsUser(it.Current()); } @@ -61,19 +59,17 @@ void HGraph::RemoveInstructionsAsUsersFromDeadBlocks(const ArenaBitVector& visit } } -void HGraph::RemoveDeadBlocks(const ArenaBitVector& visited) const { +void HGraph::RemoveDeadBlocks(const ArenaBitVector& visited) { for (size_t i = 0; i < blocks_.Size(); ++i) { if (!visited.IsBitSet(i)) { HBasicBlock* block = blocks_.Get(i); + // We only need to update the successor, which might be live. for (size_t j = 0; j < block->GetSuccessors().Size(); ++j) { block->GetSuccessors().Get(j)->RemovePredecessor(block); } - for (HInstructionIterator it(block->GetPhis()); !it.Done(); it.Advance()) { - block->RemovePhi(it.Current()->AsPhi(), /*ensure_safety=*/ false); - } - for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) { - block->RemoveInstruction(it.Current(), /*ensure_safety=*/ false); - } + // Remove the block from the list of blocks, so that further analyses + // never see it. + blocks_.Put(i, nullptr); } } } @@ -258,6 +254,7 @@ void HGraph::SimplifyCFG() { // (2): Simplify loops by having only one back edge, and one preheader. for (size_t i = 0; i < blocks_.Size(); ++i) { HBasicBlock* block = blocks_.Get(i); + if (block == nullptr) continue; if (block->GetSuccessors().Size() > 1) { for (size_t j = 0; j < block->GetSuccessors().Size(); ++j) { HBasicBlock* successor = block->GetSuccessors().Get(j); @@ -274,8 +271,9 @@ void HGraph::SimplifyCFG() { } bool HGraph::AnalyzeNaturalLoops() const { - for (size_t i = 0; i < blocks_.Size(); ++i) { - HBasicBlock* block = blocks_.Get(i); + // Order does not matter. + for (HReversePostOrderIterator it(*this); !it.Done(); it.Advance()) { + HBasicBlock* block = it.Current(); if (block->IsLoopHeader()) { HLoopInformation* info = block->GetLoopInformation(); if (!info->Populate()) { |