diff options
author | 2022-08-19 10:28:11 +0100 | |
---|---|---|
committer | 2022-09-02 14:06:33 +0000 | |
commit | 7023bf8227b3f46f4c3cc98e18889f54a584cd16 (patch) | |
tree | ba7bbad88a339908faea59a19c3b17aad23c67d6 /compiler/optimizing/nodes.cc | |
parent | 70d95654bad53085e12a96864c38187c504bdaa1 (diff) |
Remove instructions from dead blocks when building the dominator tree
We now remove the instructions to free up memory. We have to refactor
methods a little bit to avoid removing instructions as users twice,
since we do not support that.
Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Change-Id: Ia34c4a6af204952d295e5a2cb534115ced97ab07
Diffstat (limited to 'compiler/optimizing/nodes.cc')
-rw-r--r-- | compiler/optimizing/nodes.cc | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 4fbb033c2f..cb07d2e45a 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -183,6 +183,7 @@ static void RemoveCatchPhiUsesOfDeadInstruction(HInstruction* insn) { } void HGraph::RemoveDeadBlocks(const ArenaBitVector& visited) { + DCHECK(reverse_post_order_.empty()) << "We shouldn't have dominance information."; for (size_t i = 0; i < blocks_.size(); ++i) { if (!visited.IsBitSet(i)) { HBasicBlock* block = blocks_[i]; @@ -190,7 +191,7 @@ void HGraph::RemoveDeadBlocks(const ArenaBitVector& visited) { // Disconnect from its sucessors, and remove all remaining uses. block->DisconnectFromSuccessors(&visited); - block->RemoveCatchPhiUses(/* remove_instruction = */ false); + block->RemoveCatchPhiUsesAndInstruction(/* building_dominator_tree = */ true); // Remove the block from the list of blocks, so that further analyses // never see it. @@ -2435,7 +2436,7 @@ void HBasicBlock::DisconnectAndDelete() { // remove `index`-th input of all phis in the catch block since they are // guaranteed dead. Note that we may miss dead inputs this way but the // graph will always remain consistent. - RemoveCatchPhiUses(/* remove_instruction = */ true); + RemoveCatchPhiUsesAndInstruction(/* building_dominator_tree = */ false); // (4) Disconnect the block from its predecessors and update their // control-flow instructions. @@ -2544,20 +2545,32 @@ void HBasicBlock::DisconnectFromSuccessors(const ArenaBitVector* visited) { successors_.clear(); } -void HBasicBlock::RemoveCatchPhiUses(bool remove_instruction) { +void HBasicBlock::RemoveCatchPhiUsesAndInstruction(bool building_dominator_tree) { for (HBackwardInstructionIterator it(GetInstructions()); !it.Done(); it.Advance()) { HInstruction* insn = it.Current(); RemoveCatchPhiUsesOfDeadInstruction(insn); - if (remove_instruction) { - RemoveInstruction(insn); + + // If we are building the dominator tree, we removed all input records previously. + // `RemoveInstruction` will try to remove them again but that's not something we support and we + // will crash. We check here since we won't be checking that in RemoveInstruction. + if (building_dominator_tree) { + DCHECK(insn->GetUses().empty()); + DCHECK(insn->GetEnvUses().empty()); } + RemoveInstruction(insn, /* ensure_safety= */ !building_dominator_tree); } for (HInstructionIterator it(GetPhis()); !it.Done(); it.Advance()) { HPhi* insn = it.Current()->AsPhi(); RemoveCatchPhiUsesOfDeadInstruction(insn); - if (remove_instruction) { - RemovePhi(insn); + + // If we are building the dominator tree, we removed all input records previously. + // `RemovePhi` will try to remove them again but that's not something we support and we + // will crash. We check here since we won't be checking that in RemovePhi. + if (building_dominator_tree) { + DCHECK(insn->GetUses().empty()); + DCHECK(insn->GetEnvUses().empty()); } + RemovePhi(insn, /* ensure_safety= */ !building_dominator_tree); } } |