From 3ac17fcce8773388512ce72cb491b202872ca1c1 Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Wed, 6 Aug 2014 23:02:54 +0100 Subject: Fix SsaDeadPhiElimination in the presence of dependent phis. This fixes the problem of having a dead loop phi taking as back-edge input a phi that also has this loop phi as input. Walking backwards does not solve the problem because the loop phi will be visited last. Most of the time, dex removes dead locals like this. Change-Id: I797198cf9c15f8faa6585cca157810e23aaa4940 --- compiler/optimizing/ssa_phi_elimination.cc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'compiler/optimizing/ssa_phi_elimination.cc') 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 it(current->GetUses()); !it.Done(); it.Advance()) { + HUseListNode* 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; -- cgit v1.2.3-59-g8ed1b