summaryrefslogtreecommitdiff
path: root/compiler/optimizing/nodes.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/nodes.cc')
-rw-r--r--compiler/optimizing/nodes.cc41
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());