summaryrefslogtreecommitdiffstats
path: root/lib/Analysis/InlineCost.cpp
diff options
context:
space:
mode:
authorKenneth Uildriks <kennethuil@gmail.com>2010-10-09 22:06:36 +0000
committerKenneth Uildriks <kennethuil@gmail.com>2010-10-09 22:06:36 +0000
commit74fa7327d690e6ceda6ce77e4e5b8ef75cb12538 (patch)
tree7ccda8d95ec34025c4695626a629f0a0d6ff2e25 /lib/Analysis/InlineCost.cpp
parentea1fe2c0a79e7984da5d4fbd538a0bdb2cd1d149 (diff)
downloadexternal_llvm-74fa7327d690e6ceda6ce77e4e5b8ef75cb12538.zip
external_llvm-74fa7327d690e6ceda6ce77e4e5b8ef75cb12538.tar.gz
external_llvm-74fa7327d690e6ceda6ce77e4e5b8ef75cb12538.tar.bz2
Now using a variant of the existing inlining heuristics to decide whether to create a given specialization of a function in PartialSpecialization. If the total performance bonus across all callsites passing the same constant exceeds the specialization cost, we create the specialization.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116158 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/InlineCost.cpp')
-rw-r--r--lib/Analysis/InlineCost.cpp70
1 files changed, 70 insertions, 0 deletions
diff --git a/lib/Analysis/InlineCost.cpp b/lib/Analysis/InlineCost.cpp
index a0e2ec7..b103897 100644
--- a/lib/Analysis/InlineCost.cpp
+++ b/lib/Analysis/InlineCost.cpp
@@ -312,6 +312,42 @@ bool InlineCostAnalyzer::FunctionInfo::NeverInline()
Metrics.containsIndirectBr);
}
+// getSpecializationBonus - The heuristic used to determine the per-call
+// performance boost for using a specialization of Callee with argument
+// specializedArgNo replaced by a constant.
+int InlineCostAnalyzer::getSpecializationBonus(Function *Callee,
+ SmallVectorImpl<unsigned> &SpecializedArgNos)
+{
+ if (Callee->mayBeOverridden())
+ return 0;
+
+ int Bonus = 0;
+ // If this function uses the coldcc calling convention, prefer not to
+ // specialize it.
+ if (Callee->getCallingConv() == CallingConv::Cold)
+ Bonus -= InlineConstants::ColdccPenalty;
+
+ // Get information about the callee.
+ FunctionInfo *CalleeFI = &CachedFunctionInfo[Callee];
+
+ // If we haven't calculated this information yet, do so now.
+ if (CalleeFI->Metrics.NumBlocks == 0)
+ CalleeFI->analyzeFunction(Callee);
+
+
+ for (unsigned i = 0, s = SpecializedArgNos.size();
+ i < s; ++i )
+ {
+ Bonus += CalleeFI->ArgumentWeights[SpecializedArgNos[i]].ConstantBonus;
+ }
+ // Calls usually take a long time, so they make the specialization gain
+ // smaller.
+ Bonus -= CalleeFI->Metrics.NumCalls * InlineConstants::CallPenalty;
+
+ return Bonus;
+}
+
+
// getInlineCost - The heuristic used to determine if we should inline the
// function call or not.
//
@@ -442,6 +478,40 @@ InlineCost InlineCostAnalyzer::getInlineCost(CallSite CS,
return llvm::InlineCost::get(InlineCost);
}
+// getSpecializationCost - The heuristic used to determine the code-size
+// impact of creating a specialized version of Callee with argument
+// SpecializedArgNo replaced by a constant.
+InlineCost InlineCostAnalyzer::getSpecializationCost(Function *Callee,
+ SmallVectorImpl<unsigned> &SpecializedArgNos)
+{
+ // Don't specialize functions which can be redefined at link-time to mean
+ // something else.
+ if (Callee->mayBeOverridden())
+ return llvm::InlineCost::getNever();
+
+ // Get information about the callee.
+ FunctionInfo *CalleeFI = &CachedFunctionInfo[Callee];
+
+ // If we haven't calculated this information yet, do so now.
+ if (CalleeFI->Metrics.NumBlocks == 0)
+ CalleeFI->analyzeFunction(Callee);
+
+ int Cost = 0;
+
+ // Look at the orginal size of the callee. Each instruction counts as 5.
+ Cost += CalleeFI->Metrics.NumInsts * InlineConstants::InstrCost;
+
+ // Offset that with the amount of code that can be constant-folded
+ // away with the given arguments replaced by constants.
+ for (SmallVectorImpl<unsigned>::iterator an = SpecializedArgNos.begin(),
+ ae = SpecializedArgNos.end(); an != ae; ++an)
+ {
+ Cost -= CalleeFI->ArgumentWeights[*an].ConstantWeight;
+ }
+
+ return llvm::InlineCost::get(Cost);
+}
+
// getInlineFudgeFactor - Return a > 1.0 factor if the inliner should use a
// higher threshold to determine if the function call should be inlined.
float InlineCostAnalyzer::getInlineFudgeFactor(CallSite CS) {