forked from OSchip/llvm-project
Make instcombine not remove Phi nodes when LCSSA is live.
llvm-svn: 29083
This commit is contained in:
parent
7ac78b99e6
commit
a6968f83b2
|
@ -96,6 +96,7 @@ namespace {
|
||||||
|
|
||||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
AU.addRequired<TargetData>();
|
AU.addRequired<TargetData>();
|
||||||
|
AU.addPreservedID(LCSSAID);
|
||||||
AU.setPreservesCFG();
|
AU.setPreservesCFG();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6251,56 +6252,59 @@ static bool DeadPHICycle(PHINode *PN, std::set<PHINode*> &PotentiallyDeadPHIs) {
|
||||||
// PHINode simplification
|
// PHINode simplification
|
||||||
//
|
//
|
||||||
Instruction *InstCombiner::visitPHINode(PHINode &PN) {
|
Instruction *InstCombiner::visitPHINode(PHINode &PN) {
|
||||||
if (Value *V = PN.hasConstantValue())
|
// If LCSSA is around, don't nuke PHIs.
|
||||||
return ReplaceInstUsesWith(PN, V);
|
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
|
// If the only user of this instruction is a cast instruction, and all of
|
||||||
// incoming values are constants, change this PHI to merge together the casted
|
//the incoming values are constants, change this PHI to merge together the
|
||||||
// constants.
|
// casted constants.
|
||||||
if (PN.hasOneUse())
|
if (PN.hasOneUse())
|
||||||
if (CastInst *CI = dyn_cast<CastInst>(PN.use_back()))
|
if (CastInst *CI = dyn_cast<CastInst>(PN.use_back()))
|
||||||
if (CI->getType() != PN.getType()) { // noop casts will be folded
|
if (CI->getType() != PN.getType()) { // noop casts will be folded
|
||||||
bool AllConstant = true;
|
bool AllConstant = true;
|
||||||
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
|
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
|
||||||
if (!isa<Constant>(PN.getIncomingValue(i))) {
|
if (!isa<Constant>(PN.getIncomingValue(i))) {
|
||||||
AllConstant = false;
|
AllConstant = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (AllConstant) {
|
if (AllConstant) {
|
||||||
// Make a new PHI with all casted values.
|
// Make a new PHI with all casted values.
|
||||||
PHINode *New = new PHINode(CI->getType(), PN.getName(), &PN);
|
PHINode *New = new PHINode(CI->getType(), PN.getName(), &PN);
|
||||||
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
|
for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
|
||||||
Constant *OldArg = cast<Constant>(PN.getIncomingValue(i));
|
Constant *OldArg = cast<Constant>(PN.getIncomingValue(i));
|
||||||
New->addIncoming(ConstantExpr::getCast(OldArg, New->getType()),
|
New->addIncoming(ConstantExpr::getCast(OldArg, New->getType()),
|
||||||
PN.getIncomingBlock(i));
|
PN.getIncomingBlock(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the cast instruction.
|
// Update the cast instruction.
|
||||||
CI->setOperand(0, New);
|
CI->setOperand(0, New);
|
||||||
WorkList.push_back(CI); // revisit the cast instruction to fold.
|
WorkList.push_back(CI); // revisit the cast instruction to fold.
|
||||||
WorkList.push_back(New); // Make sure to revisit the new Phi
|
WorkList.push_back(New); // Make sure to revisit the new Phi
|
||||||
return &PN; // PN is now dead!
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue