summaryrefslogtreecommitdiff
path: root/compiler/optimizing/ssa_phi_elimination.cc
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2014-08-06 23:03:21 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2014-08-06 17:20:04 +0000
commit8b2e9cde4aa3dc96b903c9eee3a7b3b7ee8422e4 (patch)
tree475c779c2ee973cf51a0a63c9d010c59c4b2d022 /compiler/optimizing/ssa_phi_elimination.cc
parent269c3360f8e69e9faf8bc8a51fd87ae7adadfb59 (diff)
parent3ac17fcce8773388512ce72cb491b202872ca1c1 (diff)
Merge "Fix SsaDeadPhiElimination in the presence of dependent phis."
Diffstat (limited to 'compiler/optimizing/ssa_phi_elimination.cc')
-rw-r--r--compiler/optimizing/ssa_phi_elimination.cc16
1 files changed, 14 insertions, 2 deletions
diff --git a/compiler/optimizing/ssa_phi_elimination.cc b/compiler/optimizing/ssa_phi_elimination.cc
index 13fa03f9a3..a079954166 100644
--- a/compiler/optimizing/ssa_phi_elimination.cc
+++ b/compiler/optimizing/ssa_phi_elimination.cc
@@ -53,8 +53,9 @@ void SsaDeadPhiElimination::Run() {
}
}
- // Remove phis that are not live. Visit in post order to ensure
- // we only remove phis with no users (dead phis might use dead phis).
+ // Remove phis that are not live. Visit in post order so that phis
+ // that are not inputs of loop phis can be removed when they have
+ // no users left (dead phis might use dead phis).
for (HPostOrderIterator it(*graph_); !it.Done(); it.Advance()) {
HBasicBlock* block = it.Current();
HInstruction* current = block->GetFirstPhi();
@@ -62,6 +63,17 @@ void SsaDeadPhiElimination::Run() {
while (current != nullptr) {
next = current->GetNext();
if (current->AsPhi()->IsDead()) {
+ if (current->HasUses()) {
+ for (HUseIterator<HInstruction> it(current->GetUses()); !it.Done(); it.Advance()) {
+ HUseListNode<HInstruction>* user_node = it.Current();
+ HInstruction* user = user_node->GetUser();
+ DCHECK(user->IsLoopHeaderPhi());
+ DCHECK(user->AsPhi()->IsDead());
+ // Just put itself as an input. The phi will be removed in this loop anyway.
+ user->SetRawInputAt(user_node->GetIndex(), user);
+ current->RemoveUser(user, user_node->GetIndex());
+ }
+ }
block->RemovePhi(current->AsPhi());
}
current = next;