diff options
Diffstat (limited to 'compiler/optimizing/nodes.cc')
| -rw-r--r-- | compiler/optimizing/nodes.cc | 45 |
1 files changed, 24 insertions, 21 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 9b26de44fe..926bc156cf 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -587,15 +587,8 @@ bool HLoopInformation::IsIn(const HLoopInformation& other) const { return other.blocks_.IsBitSet(header_->GetBlockId()); } -bool HLoopInformation::IsLoopInvariant(HInstruction* instruction, bool must_dominate) const { - HLoopInformation* other_loop = instruction->GetBlock()->GetLoopInformation(); - if (other_loop != this && (other_loop == nullptr || !other_loop->IsIn(*this))) { - if (must_dominate) { - return instruction->GetBlock()->Dominates(GetHeader()); - } - return true; - } - return false; +bool HLoopInformation::IsDefinedOutOfTheLoop(HInstruction* instruction) const { + return !blocks_.IsBitSet(instruction->GetBlock()->GetBlockId()); } size_t HLoopInformation::GetLifetimeEnd() const { @@ -1467,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 @@ -1569,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. |