summaryrefslogtreecommitdiffstats
path: root/lib/Transforms
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2006-07-10 19:03:49 +0000
committerOwen Anderson <resistor@mac.com>2006-07-10 19:03:49 +0000
commitd1b78a12ef841720b3319eb773daae7b0cffb4e3 (patch)
treee40f5d6b0fe5652da05cb53d1e1cf178d7e5aaff /lib/Transforms
parent7267bd6c1a2772f93b376745c24218e612188d56 (diff)
downloadexternal_llvm-d1b78a12ef841720b3319eb773daae7b0cffb4e3.zip
external_llvm-d1b78a12ef841720b3319eb773daae7b0cffb4e3.tar.gz
external_llvm-d1b78a12ef841720b3319eb773daae7b0cffb4e3.tar.bz2
Make instcombine not remove Phi nodes when LCSSA is live.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29083 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp98
1 files changed, 51 insertions, 47 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index e48953b..ebefdb3 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -96,6 +96,7 @@ namespace {
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<TargetData>();
+ AU.addPreservedID(LCSSAID);
AU.setPreservesCFG();
}
@@ -6251,56 +6252,59 @@ static bool DeadPHICycle(PHINode *PN, std::set<PHINode*> &PotentiallyDeadPHIs) {
// PHINode simplification
//
Instruction *InstCombiner::visitPHINode(PHINode &PN) {
- if (Value *V = PN.hasConstantValue())
- return ReplaceInstUsesWith(PN, V);
-
- // If the only user of this instruction is a cast instruction, and all of the
- // incoming values are constants, change this PHI to merge together the casted
- // constants.
- if (PN.hasOneUse())
- if (CastInst *CI = dyn_cast<CastInst>(PN.use_back()))
- if (CI->getType() != PN.getType()) { // noop casts will be folded
- bool AllConstant = true;
- for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
- if (!isa<Constant>(PN.getIncomingValue(i))) {
- AllConstant = false;
- break;
- }
- if (AllConstant) {
- // Make a new PHI with all casted values.
- PHINode *New = new PHINode(CI->getType(), PN.getName(), &PN);
- for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
- Constant *OldArg = cast<Constant>(PN.getIncomingValue(i));
- New->addIncoming(ConstantExpr::getCast(OldArg, New->getType()),
- PN.getIncomingBlock(i));
- }
+ // If LCSSA is around, don't nuke PHIs.
+ if (!mustPreserveAnalysisID(LCSSAID)) {
+ if (Value *V = PN.hasConstantValue())
+ return ReplaceInstUsesWith(PN, V);
+
+ // If the only user of this instruction is a cast instruction, and all of
+ //the incoming values are constants, change this PHI to merge together the
+ // casted constants.
+ if (PN.hasOneUse())
+ if (CastInst *CI = dyn_cast<CastInst>(PN.use_back()))
+ if (CI->getType() != PN.getType()) { // noop casts will be folded
+ bool AllConstant = true;
+ for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
+ if (!isa<Constant>(PN.getIncomingValue(i))) {
+ AllConstant = false;
+ break;
+ }
+ if (AllConstant) {
+ // Make a new PHI with all casted values.
+ PHINode *New = new PHINode(CI->getType(), PN.getName(), &PN);
+ for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
+ Constant *OldArg = cast<Constant>(PN.getIncomingValue(i));
+ New->addIncoming(ConstantExpr::getCast(OldArg, New->getType()),
+ PN.getIncomingBlock(i));
+ }
- // Update the cast instruction.
- CI->setOperand(0, New);
- WorkList.push_back(CI); // revisit the cast instruction to fold.
- WorkList.push_back(New); // Make sure to revisit the new Phi
- return &PN; // PN is now dead!
+ // Update the cast instruction.
+ CI->setOperand(0, New);
+ WorkList.push_back(CI); // revisit the cast instruction to fold.
+ WorkList.push_back(New); // Make sure to revisit the new Phi
+ return &PN; // PN is now dead!
+ }
}
- }
-
- // If all PHI operands are the same operation, pull them through the PHI,
- // reducing code size.
- if (isa<Instruction>(PN.getIncomingValue(0)) &&
- PN.getIncomingValue(0)->hasOneUse())
- if (Instruction *Result = FoldPHIArgOpIntoPHI(PN))
- return Result;
-
- // If this is a trivial cycle in the PHI node graph, remove it. Basically, if
- // this PHI only has a single use (a PHI), and if that PHI only has one use (a
- // PHI)... break the cycle.
- if (PN.hasOneUse())
- if (PHINode *PU = dyn_cast<PHINode>(PN.use_back())) {
- std::set<PHINode*> PotentiallyDeadPHIs;
- PotentiallyDeadPHIs.insert(&PN);
- if (DeadPHICycle(PU, PotentiallyDeadPHIs))
- return ReplaceInstUsesWith(PN, UndefValue::get(PN.getType()));
- }
+ // If all PHI operands are the same operation, pull them through the PHI,
+ // reducing code size.
+ if (isa<Instruction>(PN.getIncomingValue(0)) &&
+ PN.getIncomingValue(0)->hasOneUse())
+ if (Instruction *Result = FoldPHIArgOpIntoPHI(PN))
+ return Result;
+
+ // If this is a trivial cycle in the PHI node graph, remove it. Basically,
+ // if this PHI only has a single use (a PHI), and if that PHI only has one
+ // use (a PHI)... break the cycle.
+ if (PN.hasOneUse())
+ if (PHINode *PU = dyn_cast<PHINode>(PN.use_back())) {
+ std::set<PHINode*> PotentiallyDeadPHIs;
+ PotentiallyDeadPHIs.insert(&PN);
+ if (DeadPHICycle(PU, PotentiallyDeadPHIs))
+ return ReplaceInstUsesWith(PN, UndefValue::get(PN.getType()));
+ }
+ }
+
return 0;
}