Update CodeMetrics to count 'big' function calls explicitly.
authorJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 5 Feb 2010 23:21:18 +0000 (23:21 +0000)
committerJakob Stoklund Olesen <stoklund@2pi.dk>
Fri, 5 Feb 2010 23:21:18 +0000 (23:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95453 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/InlineCost.h
lib/Analysis/InlineCost.cpp

index 2d5142c5c31be613ddc38c414be597b0c04ff4a3..84acd7d5fee979f29a6796873432cc2ceac1edd6 100644 (file)
@@ -34,7 +34,7 @@ namespace llvm {
     /// NeverInline - True if this callee should never be inlined into a
     /// caller.
     bool NeverInline;
-    
+
     /// usesDynamicAlloca - True if this function calls alloca (in the C sense).
     bool usesDynamicAlloca;
 
@@ -42,17 +42,20 @@ namespace llvm {
     /// is used to estimate the code size cost of inlining it.
     unsigned NumInsts, NumBlocks;
 
+    /// NumCalls - Keep track of the number of calls to 'big' functions.
+    unsigned NumCalls;
+
     /// NumVectorInsts - Keep track of how many instructions produce vector
     /// values.  The inliner is being more aggressive with inlining vector
     /// kernels.
     unsigned NumVectorInsts;
-    
+
     /// NumRets - Keep track of how many Ret instructions the block contains.
     unsigned NumRets;
 
     CodeMetrics() : NeverInline(false), usesDynamicAlloca(false), NumInsts(0),
-                    NumBlocks(0), NumVectorInsts(0), NumRets(0) {}
-    
+                    NumBlocks(0), NumCalls(0), NumVectorInsts(0), NumRets(0) {}
+
     /// analyzeBasicBlock - Add information about the specified basic block
     /// to the current structure.
     void analyzeBasicBlock(const BasicBlock *BB);
@@ -66,7 +69,7 @@ namespace llvm {
     // Various magic constants used to adjust heuristics.
     const int InstrCost = 5;
     const int IndirectCallBonus = 500;
-    const int CallPenalty = 5;  // In instrs, so multiply by InstrCost.
+    const int CallPenalty = 25;
     const int LastCallToStaticBonus = -15000;
     const int ColdccPenalty = 2000;
     const int NoreturnPenalty = 10000;
@@ -121,18 +124,18 @@ namespace llvm {
       return getCost();
     }
   };
-  
+
   /// InlineCostAnalyzer - Cost analyzer used by inliner.
   class InlineCostAnalyzer {
     struct ArgInfo {
     public:
       unsigned ConstantWeight;
       unsigned AllocaWeight;
-      
+
       ArgInfo(unsigned CWeight, unsigned AWeight)
         : ConstantWeight(CWeight), AllocaWeight(AWeight) {}
     };
-    
+
     struct FunctionInfo {
       CodeMetrics Metrics;
 
@@ -141,12 +144,12 @@ namespace llvm {
       /// would reduce the code size.  If so, we add some value to the argument
       /// entry here.
       std::vector<ArgInfo> ArgumentWeights;
-    
+
       /// CountCodeReductionForConstant - Figure out an approximation for how
       /// many instructions will be constant folded if the specified value is
       /// constant.
       unsigned CountCodeReductionForConstant(Value *V);
-    
+
       /// CountCodeReductionForAlloca - Figure out an approximation of how much
       /// smaller the function will be if it is inlined into a context where an
       /// argument becomes an alloca.
index f74d712576ec5159818e5d50613f719bb7d40cdc..972d0349fd067bda07b9455924535157a913b880 100644 (file)
@@ -163,10 +163,11 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) {
             (F->getName() == "setjmp" || F->getName() == "_setjmp"))
           NeverInline = true;
 
-      // Each argument to a call takes on average one instruction to set up.
-      // Add an extra penalty because calls can take a long time to execute.
-      if (!isa<IntrinsicInst>(II) && !callIsSmall(CS.getCalledFunction()))
-        NumInsts += InlineConstants::CallPenalty + CS.arg_size();
+      if (!isa<IntrinsicInst>(II) && !callIsSmall(CS.getCalledFunction())) {
+        // Each argument to a call takes on average one instruction to set up.
+        NumInsts += CS.arg_size();
+        ++NumCalls;
+      }
     }
     
     if (const AllocaInst *AI = dyn_cast<AllocaInst>(II)) {
@@ -347,7 +348,10 @@ InlineCost InlineCostAnalyzer::getInlineCost(CallSite CS,
   
   // Now that we have considered all of the factors that make the call site more
   // likely to be inlined, look at factors that make us not want to inline it.
-  
+
+  // Calls usually take a long time, so they make the inlining gain smaller.
+  InlineCost += CalleeFI.Metrics.NumCalls * InlineConstants::CallPenalty;
+
   // Don't inline into something too big, which would make it bigger.
   // "size" here is the number of basic blocks, not instructions.
   //