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
This commit is contained in:
Kenneth Uildriks
2010-10-09 22:06:36 +00:00
parent ea1fe2c0a7
commit 74fa7327d6
4 changed files with 181 additions and 40 deletions

View File

@@ -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) {