enhance FoldOpIntoPhi in instcombine to try harder when a phi has

multiple uses.  In some cases, all the uses are the same operation,
so instcombine can go ahead and promote the phi.  In the testcase
this pushes an add out of the loop.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123568 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2011-01-16 05:28:59 +00:00
parent df55fea807
commit 192228edb1
3 changed files with 42 additions and 3 deletions

View File

@@ -519,9 +519,17 @@ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) {
return 0;
// We normally only transform phis with a single use, unless we're trying
// hard to make jump threading happen.
if (!PN->hasOneUse())
return 0;
// hard to make jump threading happen. However, if a PHI has multiple uses
// and they are all the same operation, we can fold *all* of the uses into the
// PHI.
if (!PN->hasOneUse()) {
// Walk the use list for the instruction, comparing them to I.
for (Value::use_iterator UI = PN->use_begin(), E = PN->use_end();
UI != E; ++UI)
if (!I.isIdenticalTo(cast<Instruction>(*UI)))
return 0;
// Otherwise, we can replace *all* users with the new PHI we form.
}
// Check to see if all of the operands of the PHI are simple constants
// (constantint/constantfp/undef). If there is one non-constant value,
@@ -628,6 +636,14 @@ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) {
NewPN->addIncoming(InV, PN->getIncomingBlock(i));
}
}
for (Value::use_iterator UI = PN->use_begin(), E = PN->use_end();
UI != E; ) {
Instruction *User = cast<Instruction>(*UI++);
if (User == &I) continue;
ReplaceInstUsesWith(*User, NewPN);
EraseInstFromFunction(*User);
}
return ReplaceInstUsesWith(I, NewPN);
}