diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/optimizing/nodes.cc | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 461be25887..926bc156cf 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -1460,6 +1460,24 @@ void HInstructionList::Add(const HInstructionList& instruction_list) { } } +// Should be called on instructions in a dead block in post order. This method +// assumes `insn` has been removed from all users with the exception of catch +// phis because of missing exceptional edges in the graph. It removes the +// instruction from catch phi uses, together with inputs of other catch phis in +// the catch block at the same index, as these must be dead too. +static void RemoveUsesOfDeadInstruction(HInstruction* insn) { + DCHECK(!insn->HasEnvironmentUses()); + while (insn->HasNonEnvironmentUses()) { + HUseListNode<HInstruction*>* use = insn->GetUses().GetFirst(); + size_t use_index = use->GetIndex(); + HBasicBlock* user_block = use->GetUser()->GetBlock(); + DCHECK(use->GetUser()->IsPhi() && user_block->IsCatchBlock()); + for (HInstructionIterator phi_it(user_block->GetPhis()); !phi_it.Done(); phi_it.Advance()) { + phi_it.Current()->AsPhi()->RemoveInputAt(use_index); + } + } +} + void HBasicBlock::DisconnectAndDelete() { // Dominators must be removed after all the blocks they dominate. This way // a loop header is removed last, a requirement for correct loop information @@ -1562,21 +1580,13 @@ void HBasicBlock::DisconnectAndDelete() { // graph will always remain consistent. for (HBackwardInstructionIterator it(GetInstructions()); !it.Done(); it.Advance()) { HInstruction* insn = it.Current(); - while (insn->HasUses()) { - DCHECK(IsTryBlock()); - HUseListNode<HInstruction*>* use = insn->GetUses().GetFirst(); - size_t use_index = use->GetIndex(); - HBasicBlock* user_block = use->GetUser()->GetBlock(); - DCHECK(use->GetUser()->IsPhi() && user_block->IsCatchBlock()); - for (HInstructionIterator phi_it(user_block->GetPhis()); !phi_it.Done(); phi_it.Advance()) { - phi_it.Current()->AsPhi()->RemoveInputAt(use_index); - } - } - + RemoveUsesOfDeadInstruction(insn); RemoveInstruction(insn); } for (HInstructionIterator it(GetPhis()); !it.Done(); it.Advance()) { - RemovePhi(it.Current()->AsPhi()); + HPhi* insn = it.Current()->AsPhi(); + RemoveUsesOfDeadInstruction(insn); + RemovePhi(insn); } // Disconnect from the dominator. |