diff options
author | Owen Anderson <resistor@mac.com> | 2006-07-10 19:03:49 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2006-07-10 19:03:49 +0000 |
commit | d1b78a12ef841720b3319eb773daae7b0cffb4e3 (patch) | |
tree | e40f5d6b0fe5652da05cb53d1e1cf178d7e5aaff /lib/Transforms | |
parent | 7267bd6c1a2772f93b376745c24218e612188d56 (diff) | |
download | external_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.cpp | 98 |
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; } |