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,55 +6252,58 @@ 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