Separate out the constant bonus from the size reduction metrics. Rework
authorEric Christopher <echristo@apple.com>
Wed, 26 Jan 2011 02:58:39 +0000 (02:58 +0000)
committerEric Christopher <echristo@apple.com>
Wed, 26 Jan 2011 02:58:39 +0000 (02:58 +0000)
a few loops accordingly. Should be no functional change.

This is a step for more accurate cost/benefit analysis of devirt/inlining
bonuses.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124275 91177308-0d34-0410-b5e6-96231b3b80d8

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

index a138fc41e95ebb07b8c18a1e8fcc6dd4d4c350f1..e53d7f65282e7db14b1cce2f81f8b5abe6844110 100644 (file)
@@ -96,10 +96,9 @@ namespace llvm {
     public:
       unsigned ConstantWeight;
       unsigned AllocaWeight;
-      unsigned ConstantBonus;
 
-      ArgInfo(unsigned CWeight, unsigned AWeight, unsigned CBonus)
-        : ConstantWeight(CWeight), AllocaWeight(AWeight), ConstantBonus(CBonus)
+      ArgInfo(unsigned CWeight, unsigned AWeight)
+        : ConstantWeight(CWeight), AllocaWeight(AWeight)
           {}
     };
 
@@ -125,6 +124,7 @@ namespace llvm {
     // the ValueMap will update itself when this happens.
     ValueMap<const Function *, FunctionInfo> CachedFunctionInfo;
 
+    unsigned CountBonusForConstant(Value *V);
   public:
 
     /// getInlineCost - The heuristic used to determine if we should inline the
index 76f134840297a3be3a9b7ff7f47b1b973ad5e07e..ccf89193c46eaff69d7e529e3f4495cecbdaf8da 100644 (file)
@@ -142,64 +142,6 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB) {
   NumBBInsts[BB] = NumInsts - NumInstsBeforeThisBB;
 }
 
-// CountBonusForConstant - Figure out an approximation for how much per-call
-// performance boost we can expect if the specified value is constant.
-unsigned CodeMetrics::CountBonusForConstant(Value *V) {
-  unsigned Bonus = 0;
-  bool indirectCallBonus = false;
-  for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI){
-    User *U = *UI;
-    if (CallInst *CI = dyn_cast<CallInst>(U)) {
-      // Turning an indirect call into a direct call is a BIG win
-      if (CI->getCalledValue() == V)
-        indirectCallBonus = true;
-    }
-    else if (InvokeInst *II = dyn_cast<InvokeInst>(U)) {
-      // Turning an indirect call into a direct call is a BIG win
-      if (II->getCalledValue() == V)
-        indirectCallBonus = true;
-    }
-    // FIXME: Eliminating conditional branches and switches should
-    // also yield a per-call performance boost.
-    else {
-      // Figure out the bonuses that wll accrue due to simple constant
-      // propagation.
-      Instruction &Inst = cast<Instruction>(*U);
-
-      // We can't constant propagate instructions which have effects or
-      // read memory.
-      //
-      // FIXME: It would be nice to capture the fact that a load from a
-      // pointer-to-constant-global is actually a *really* good thing to zap.
-      // Unfortunately, we don't know the pointer that may get propagated here,
-      // so we can't make this decision.
-      if (Inst.mayReadFromMemory() || Inst.mayHaveSideEffects() ||
-          isa<AllocaInst>(Inst))
-        continue;
-
-      bool AllOperandsConstant = true;
-      for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i)
-        if (!isa<Constant>(Inst.getOperand(i)) && Inst.getOperand(i) != V) {
-          AllOperandsConstant = false;
-          break;
-        }
-
-      if (AllOperandsConstant)
-        Bonus += CountBonusForConstant(&Inst);
-    }
-  }
-  
-  // FIXME: The only reason we're applying the bonus once is while it's great
-  // to devirtualize calls the magnitude of the bonus x number of call sites
-  // can lead to a huge code explosion when we prefer to inline 1000 instruction
-  // functions that have 10 call sites. This should be made a function of the
-  // estimated inline penalty/benefit + the indirect call bonus.
-  if (indirectCallBonus) Bonus += InlineConstants::IndirectCallBonus;
-  
-  return Bonus;
-}
-
-
 // CountCodeReductionForConstant - Figure out an approximation for how many
 // instructions will be constant folded if the specified value is constant.
 //
@@ -309,17 +251,14 @@ void InlineCostAnalyzer::FunctionInfo::analyzeFunction(Function *F) {
   ArgumentWeights.reserve(F->arg_size());
   for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
     ArgumentWeights.push_back(ArgInfo(Metrics.CountCodeReductionForConstant(I),
-                                      Metrics.CountCodeReductionForAlloca(I),
-                                      Metrics.CountBonusForConstant(I)));
+                                      Metrics.CountCodeReductionForAlloca(I)));
 }
 
 /// NeverInline - returns true if the function should never be inlined into
 /// any caller
-bool InlineCostAnalyzer::FunctionInfo::NeverInline()
-{
+bool InlineCostAnalyzer::FunctionInfo::NeverInline() {
   return (Metrics.callsSetJmp || Metrics.isRecursive || 
           Metrics.containsIndirectBr);
-
 }
 // getSpecializationBonus - The heuristic used to determine the per-call
 // performance boost for using a specialization of Callee with argument
@@ -343,8 +282,14 @@ int InlineCostAnalyzer::getSpecializationBonus(Function *Callee,
   if (CalleeFI->Metrics.NumBlocks == 0)
     CalleeFI->analyzeFunction(Callee);
 
-  for (unsigned i = 0, s = SpecializedArgNos.size(); i < s; ++i )
-    Bonus += CalleeFI->ArgumentWeights[SpecializedArgNos[i]].ConstantBonus;
+  unsigned ArgNo = 0;
+  unsigned i = 0;
+  for (Function::arg_iterator I = Callee->arg_begin(), E = Callee->arg_end();
+       I != E; ++I, ++ArgNo)
+    if (ArgNo == SpecializedArgNos[i]) {
+      ++i;
+      Bonus += CountBonusForConstant(I);
+    }
 
   // Calls usually take a long time, so they make the specialization gain 
   // smaller.
@@ -353,6 +298,62 @@ int InlineCostAnalyzer::getSpecializationBonus(Function *Callee,
   return Bonus;
 }
 
+// CountBonusForConstant - Figure out an approximation for how much per-call
+// performance boost we can expect if the specified value is constant.
+unsigned InlineCostAnalyzer::CountBonusForConstant(Value *V) {
+  unsigned Bonus = 0;
+  bool indirectCallBonus = false;
+  for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI){
+    User *U = *UI;
+    if (CallInst *CI = dyn_cast<CallInst>(U)) {
+      // Turning an indirect call into a direct call is a BIG win
+      if (CI->getCalledValue() == V)
+        indirectCallBonus = true;
+    }
+    else if (InvokeInst *II = dyn_cast<InvokeInst>(U)) {
+      // Turning an indirect call into a direct call is a BIG win
+      if (II->getCalledValue() == V)
+        indirectCallBonus = true;
+    }
+    // FIXME: Eliminating conditional branches and switches should
+    // also yield a per-call performance boost.
+    else {
+      // Figure out the bonuses that wll accrue due to simple constant
+      // propagation.
+      Instruction &Inst = cast<Instruction>(*U);
+
+      // We can't constant propagate instructions which have effects or
+      // read memory.
+      //
+      // FIXME: It would be nice to capture the fact that a load from a
+      // pointer-to-constant-global is actually a *really* good thing to zap.
+      // Unfortunately, we don't know the pointer that may get propagated here,
+      // so we can't make this decision.
+      if (Inst.mayReadFromMemory() || Inst.mayHaveSideEffects() ||
+          isa<AllocaInst>(Inst))
+        continue;
+
+      bool AllOperandsConstant = true;
+      for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i)
+        if (!isa<Constant>(Inst.getOperand(i)) && Inst.getOperand(i) != V) {
+          AllOperandsConstant = false;
+          break;
+        }
+
+      if (AllOperandsConstant)
+        Bonus += CountBonusForConstant(&Inst);
+    }
+  }
+  
+  // FIXME: The only reason we're applying the bonus once is while it's great
+  // to devirtualize calls the magnitude of the bonus x number of call sites
+  // can lead to a huge code explosion when we prefer to inline 1000 instruction
+  // functions that have 10 call sites. This should be made a function of the
+  // estimated inline penalty/benefit + the indirect call bonus.
+  if (indirectCallBonus) Bonus += InlineConstants::IndirectCallBonus;
+  
+  return Bonus;
+}
 
 // getInlineCost - The heuristic used to determine if we should inline the
 // function call or not.
@@ -427,31 +428,33 @@ InlineCost InlineCostAnalyzer::getInlineCost(CallSite CS,
   // passed into the function.
   //
   unsigned ArgNo = 0;
-  for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
-       I != E; ++I, ++ArgNo) {
-    // Each argument passed in has a cost at both the caller and the callee
-    // sides.  Measurements show that each argument costs about the same as an
-    // instruction.
-    InlineCost -= InlineConstants::InstrCost;
+  CallSite::arg_iterator I = CS.arg_begin();
+  for (Function::arg_iterator FI = Callee->arg_begin(), FE = Callee->arg_end();
+       FI != FE; ++I, ++FI, ++ArgNo) {
 
     // If an alloca is passed in, inlining this function is likely to allow
     // significant future optimization possibilities (like scalar promotion, and
     // scalarization), so encourage the inlining of the function.
     //
-    if (isa<AllocaInst>(I)) {
-      if (ArgNo < CalleeFI->ArgumentWeights.size())
-        InlineCost -= CalleeFI->ArgumentWeights[ArgNo].AllocaWeight;
-
-      // If this is a constant being passed into the function, use the argument
-      // weights calculated for the callee to determine how much will be folded
-      // away with this information.
-    } else if (isa<Constant>(I)) {
-      if (ArgNo < CalleeFI->ArgumentWeights.size())
-        InlineCost -= (CalleeFI->ArgumentWeights[ArgNo].ConstantWeight +
-                       CalleeFI->ArgumentWeights[ArgNo].ConstantBonus);
+    if (isa<AllocaInst>(I))
+      InlineCost -= CalleeFI->ArgumentWeights[ArgNo].AllocaWeight;
+
+    // If this is a constant being passed into the function, use the argument
+    // weights calculated for the callee to determine how much will be folded
+    // away with this information.
+    else if (isa<Constant>(I)) {
+      InlineCost -= CalleeFI->ArgumentWeights[ArgNo].ConstantWeight;
+       
+      // Compute any constant bonus due to inlining we want to give here.
+      InlineCost -= CountBonusForConstant(FI);
     }
   }
   
+  // Each argument passed in has a cost at both the caller and the callee
+  // sides.  Measurements show that each argument costs about the same as an
+  // instruction.
+  InlineCost -= (CS.arg_size() * InlineConstants::InstrCost);
+
   // If there is only one call of the function, and it has internal linkage,
   // make it almost guaranteed to be inlined.
   //