forked from OSchip/llvm-project
				
			Start refactoring the inline cost estimation code so that it can be used
for purposes other than inlining. llvm-svn: 83997
This commit is contained in:
		
							parent
							
								
									19788ca686
								
							
						
					
					
						commit
						5b3e05bcaa
					
				| 
						 | 
				
			
			@ -23,6 +23,7 @@ namespace llvm {
 | 
			
		|||
 | 
			
		||||
  class Value;
 | 
			
		||||
  class Function;
 | 
			
		||||
  class BasicBlock;
 | 
			
		||||
  class CallSite;
 | 
			
		||||
  template<class PtrType, unsigned SmallSize>
 | 
			
		||||
  class SmallPtrSet;
 | 
			
		||||
| 
						 | 
				
			
			@ -96,9 +97,9 @@ namespace llvm {
 | 
			
		|||
        : ConstantWeight(CWeight), AllocaWeight(AWeight) {}
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    // FunctionInfo - For each function, calculate the size of it in blocks and
 | 
			
		||||
    // instructions.
 | 
			
		||||
    struct FunctionInfo {
 | 
			
		||||
    // RegionInfo - Calculate size and a few related metrics for a set of
 | 
			
		||||
    // basic blocks.
 | 
			
		||||
    struct RegionInfo {
 | 
			
		||||
      /// NeverInline - True if this callee should never be inlined into a
 | 
			
		||||
      /// caller.
 | 
			
		||||
      bool NeverInline;
 | 
			
		||||
| 
						 | 
				
			
			@ -115,17 +116,24 @@ namespace llvm {
 | 
			
		|||
      /// kernels.
 | 
			
		||||
      unsigned NumVectorInsts;
 | 
			
		||||
      
 | 
			
		||||
      /// NumRets - Keep track of how many Ret instructions the block contains.
 | 
			
		||||
      unsigned NumRets;
 | 
			
		||||
 | 
			
		||||
      /// ArgumentWeights - Each formal argument of the function is inspected to
 | 
			
		||||
      /// see if it is used in any contexts where making it a constant or alloca
 | 
			
		||||
      /// would reduce the code size.  If so, we add some value to the argument
 | 
			
		||||
      /// entry here.
 | 
			
		||||
      std::vector<ArgInfo> ArgumentWeights;
 | 
			
		||||
      
 | 
			
		||||
      FunctionInfo() : NeverInline(false), usesDynamicAlloca(false), NumInsts(0),
 | 
			
		||||
                       NumBlocks(0), NumVectorInsts(0) {}
 | 
			
		||||
      RegionInfo() : NeverInline(false), usesDynamicAlloca(false), NumInsts(0),
 | 
			
		||||
                     NumBlocks(0), NumVectorInsts(0), NumRets(0) {}
 | 
			
		||||
      
 | 
			
		||||
      /// analyzeFunction - Fill in the current structure with information
 | 
			
		||||
      /// gleaned from the specified function.
 | 
			
		||||
      /// analyzeBasicBlock - Add information about the specified basic block
 | 
			
		||||
      /// to the current structure.
 | 
			
		||||
      void analyzeBasicBlock(const BasicBlock *BB);
 | 
			
		||||
 | 
			
		||||
      /// analyzeFunction - Add information about the specified function
 | 
			
		||||
      /// to the current structure.
 | 
			
		||||
      void analyzeFunction(Function *F);
 | 
			
		||||
 | 
			
		||||
      /// CountCodeReductionForConstant - Figure out an approximation for how
 | 
			
		||||
| 
						 | 
				
			
			@ -140,7 +148,7 @@ namespace llvm {
 | 
			
		|||
      unsigned CountCodeReductionForAlloca(Value *V);
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    std::map<const Function *, FunctionInfo> CachedFunctionInfo;
 | 
			
		||||
    std::map<const Function *, RegionInfo> CachedFunctionInfo;
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@ using namespace llvm;
 | 
			
		|||
// CountCodeReductionForConstant - Figure out an approximation for how many
 | 
			
		||||
// instructions will be constant folded if the specified value is constant.
 | 
			
		||||
//
 | 
			
		||||
unsigned InlineCostAnalyzer::FunctionInfo::
 | 
			
		||||
unsigned InlineCostAnalyzer::RegionInfo::
 | 
			
		||||
         CountCodeReductionForConstant(Value *V) {
 | 
			
		||||
  unsigned Reduction = 0;
 | 
			
		||||
  for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +77,7 @@ unsigned InlineCostAnalyzer::FunctionInfo::
 | 
			
		|||
// the function will be if it is inlined into a context where an argument
 | 
			
		||||
// becomes an alloca.
 | 
			
		||||
//
 | 
			
		||||
unsigned InlineCostAnalyzer::FunctionInfo::
 | 
			
		||||
unsigned InlineCostAnalyzer::RegionInfo::
 | 
			
		||||
         CountCodeReductionForAlloca(Value *V) {
 | 
			
		||||
  if (!isa<PointerType>(V->getType())) return 0;  // Not a pointer
 | 
			
		||||
  unsigned Reduction = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -99,14 +99,11 @@ unsigned InlineCostAnalyzer::FunctionInfo::
 | 
			
		|||
  return Reduction;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// analyzeFunction - Fill in the current structure with information gleaned
 | 
			
		||||
/// from the specified function.
 | 
			
		||||
void InlineCostAnalyzer::FunctionInfo::analyzeFunction(Function *F) {
 | 
			
		||||
  unsigned NumInsts = 0, NumBlocks = 0, NumVectorInsts = 0, NumRets = 0;
 | 
			
		||||
/// analyzeBasicBlock - Fill in the current structure with information gleaned
 | 
			
		||||
/// from the specified block.
 | 
			
		||||
void InlineCostAnalyzer::RegionInfo::analyzeBasicBlock(const BasicBlock *BB) {
 | 
			
		||||
  ++NumBlocks;
 | 
			
		||||
 | 
			
		||||
  // Look at the size of the callee.  Each basic block counts as 20 units, and
 | 
			
		||||
  // each instruction counts as 5.
 | 
			
		||||
  for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
 | 
			
		||||
  for (BasicBlock::const_iterator II = BB->begin(), E = BB->end();
 | 
			
		||||
       II != E; ++II) {
 | 
			
		||||
    if (isa<PHINode>(II)) continue;           // PHI nodes don't count.
 | 
			
		||||
| 
						 | 
				
			
			@ -165,19 +162,22 @@ void InlineCostAnalyzer::FunctionInfo::analyzeFunction(Function *F) {
 | 
			
		|||
    
 | 
			
		||||
    ++NumInsts;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    ++NumBlocks;
 | 
			
		||||
  }
 | 
			
		||||
/// analyzeFunction - Fill in the current structure with information gleaned
 | 
			
		||||
/// from the specified function.
 | 
			
		||||
void InlineCostAnalyzer::RegionInfo::analyzeFunction(Function *F) {
 | 
			
		||||
  // Look at the size of the callee.  Each basic block counts as 20 units, and
 | 
			
		||||
  // each instruction counts as 5.
 | 
			
		||||
  for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
 | 
			
		||||
    analyzeBasicBlock(&*BB);
 | 
			
		||||
 | 
			
		||||
  // A function with exactly one return has it removed during the inlining
 | 
			
		||||
  // process (see InlineFunction), so don't count it.
 | 
			
		||||
  // FIXME: This knowledge should really be encoded outside of RegionInfo.
 | 
			
		||||
  if (NumRets==1)
 | 
			
		||||
    --NumInsts;
 | 
			
		||||
 | 
			
		||||
  this->NumBlocks      = NumBlocks;
 | 
			
		||||
  this->NumInsts       = NumInsts;
 | 
			
		||||
  this->NumVectorInsts = NumVectorInsts;
 | 
			
		||||
 | 
			
		||||
  // Check out all of the arguments to the function, figuring out how much
 | 
			
		||||
  // code can be eliminated if one of the arguments is a constant.
 | 
			
		||||
  for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
 | 
			
		||||
| 
						 | 
				
			
			@ -229,7 +229,7 @@ InlineCost InlineCostAnalyzer::getInlineCost(CallSite CS,
 | 
			
		|||
    InlineCost += InlineConstants::NoreturnPenalty;
 | 
			
		||||
  
 | 
			
		||||
  // Get information about the callee...
 | 
			
		||||
  FunctionInfo &CalleeFI = CachedFunctionInfo[Callee];
 | 
			
		||||
  RegionInfo &CalleeFI = CachedFunctionInfo[Callee];
 | 
			
		||||
  
 | 
			
		||||
  // If we haven't calculated this information yet, do so now.
 | 
			
		||||
  if (CalleeFI.NumBlocks == 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -240,7 +240,7 @@ InlineCost InlineCostAnalyzer::getInlineCost(CallSite CS,
 | 
			
		|||
    return InlineCost::getNever();
 | 
			
		||||
 | 
			
		||||
  // FIXME: It would be nice to kill off CalleeFI.NeverInline. Then we
 | 
			
		||||
  // could move this up and avoid computing the FunctionInfo for
 | 
			
		||||
  // could move this up and avoid computing the RegionInfo for
 | 
			
		||||
  // things we are going to just return always inline for. This
 | 
			
		||||
  // requires handling setjmp somewhere else, however.
 | 
			
		||||
  if (!Callee->isDeclaration() && Callee->hasFnAttr(Attribute::AlwaysInline))
 | 
			
		||||
| 
						 | 
				
			
			@ -248,7 +248,7 @@ InlineCost InlineCostAnalyzer::getInlineCost(CallSite CS,
 | 
			
		|||
    
 | 
			
		||||
  if (CalleeFI.usesDynamicAlloca) {
 | 
			
		||||
    // Get infomation about the caller...
 | 
			
		||||
    FunctionInfo &CallerFI = CachedFunctionInfo[Caller];
 | 
			
		||||
    RegionInfo &CallerFI = CachedFunctionInfo[Caller];
 | 
			
		||||
 | 
			
		||||
    // If we haven't calculated this information yet, do so now.
 | 
			
		||||
    if (CallerFI.NumBlocks == 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -316,7 +316,7 @@ float InlineCostAnalyzer::getInlineFudgeFactor(CallSite CS) {
 | 
			
		|||
  Function *Callee = CS.getCalledFunction();
 | 
			
		||||
  
 | 
			
		||||
  // Get information about the callee...
 | 
			
		||||
  FunctionInfo &CalleeFI = CachedFunctionInfo[Callee];
 | 
			
		||||
  RegionInfo &CalleeFI = CachedFunctionInfo[Callee];
 | 
			
		||||
  
 | 
			
		||||
  // If we haven't calculated this information yet, do so now.
 | 
			
		||||
  if (CalleeFI.NumBlocks == 0)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue