diff options
Diffstat (limited to 'compiler/optimizing/nodes.cc')
-rw-r--r-- | compiler/optimizing/nodes.cc | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 1a24677261..09412a9c86 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -351,6 +351,16 @@ static void Remove(HInstructionList* instruction_list, for (size_t i = 0; i < instruction->InputCount(); i++) { instruction->InputAt(i)->RemoveUser(instruction, i); } + + HEnvironment* environment = instruction->GetEnvironment(); + if (environment != nullptr) { + for (size_t i = 0, e = environment->Size(); i < e; ++i) { + HInstruction* vreg = environment->GetInstructionAt(i); + if (vreg != nullptr) { + vreg->RemoveEnvironmentUser(environment, i); + } + } + } } void HBasicBlock::RemoveInstruction(HInstruction* instruction) { @@ -361,13 +371,16 @@ void HBasicBlock::RemovePhi(HPhi* phi) { Remove(&phis_, this, phi); } -void HInstruction::RemoveUser(HInstruction* user, size_t input_index) { - HUseListNode<HInstruction>* previous = nullptr; - HUseListNode<HInstruction>* current = uses_; +template <typename T> +static void RemoveFromUseList(T* user, + size_t input_index, + HUseListNode<T>** list) { + HUseListNode<T>* previous = nullptr; + HUseListNode<T>* current = *list; while (current != nullptr) { if (current->GetUser() == user && current->GetIndex() == input_index) { if (previous == NULL) { - uses_ = current->GetTail(); + *list = current->GetTail(); } else { previous->SetTail(current->GetTail()); } @@ -377,6 +390,14 @@ void HInstruction::RemoveUser(HInstruction* user, size_t input_index) { } } +void HInstruction::RemoveUser(HInstruction* user, size_t input_index) { + RemoveFromUseList(user, input_index, &uses_); +} + +void HInstruction::RemoveEnvironmentUser(HEnvironment* user, size_t input_index) { + RemoveFromUseList(user, input_index, &env_uses_); +} + void HInstructionList::AddInstruction(HInstruction* instruction) { if (first_instruction_ == nullptr) { DCHECK(last_instruction_ == nullptr); @@ -534,14 +555,22 @@ bool HCondition::NeedsMaterialization() const { return true; } - // TODO: should we allow intervening instructions with no side-effect between this condition - // and the If instruction? + // TODO: if there is no intervening instructions with side-effect between this condition + // and the If instruction, we should move the condition just before the If. if (GetNext() != user) { return true; } return false; } +bool HCondition::IsBeforeWhenDisregardMoves(HIf* if_) const { + HInstruction* previous = if_->GetPrevious(); + while (previous != nullptr && previous->IsParallelMove()) { + previous = previous->GetPrevious(); + } + return previous == this; +} + bool HInstruction::Equals(HInstruction* other) const { if (!InstructionTypeEquals(other)) return false; DCHECK_EQ(GetKind(), other->GetKind()); |