[inliner]: Refactor inline deferring logic into its own method /NFC
The implemented heuristic has a large body of code which better sits in its own function for better readability. It also allows adding more heuristics easier in the future. llvm-svn: 268107
This commit is contained in:
parent
7da9b445ea
commit
1ffa28a3f1
|
@ -69,6 +69,10 @@ private:
|
|||
/// shouldInline - Return true if the inliner should attempt to
|
||||
/// inline at the given CallSite.
|
||||
bool shouldInline(CallSite CS);
|
||||
/// Return true if inlining of CS can block the caller from being
|
||||
/// inlined which is proved to be more beneficial. \p IC is the
|
||||
/// estimated inline cost associated with callsite \p CS.
|
||||
bool shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC);
|
||||
|
||||
protected:
|
||||
AssumptionCacheTracker *ACT;
|
||||
|
|
|
@ -227,38 +227,11 @@ static void emitAnalysis(CallSite CS, const Twine &Msg) {
|
|||
emitOptimizationRemarkAnalysis(Ctx, DEBUG_TYPE, *Caller, DLoc, Msg);
|
||||
}
|
||||
|
||||
/// Return true if the inliner should attempt to inline at the given CallSite.
|
||||
bool Inliner::shouldInline(CallSite CS) {
|
||||
InlineCost IC = getInlineCost(CS);
|
||||
bool Inliner::shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC) {
|
||||
|
||||
if (IC.isAlways()) {
|
||||
DEBUG(dbgs() << " Inlining: cost=always"
|
||||
<< ", Call: " << *CS.getInstruction() << "\n");
|
||||
emitAnalysis(CS, Twine(CS.getCalledFunction()->getName()) +
|
||||
" should always be inlined (cost=always)");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IC.isNever()) {
|
||||
DEBUG(dbgs() << " NOT Inlining: cost=never"
|
||||
<< ", Call: " << *CS.getInstruction() << "\n");
|
||||
emitAnalysis(CS, Twine(CS.getCalledFunction()->getName() +
|
||||
" should never be inlined (cost=never)"));
|
||||
// For now we only handle local or inline functions.
|
||||
if (!Caller->hasLocalLinkage() && !Caller->hasLinkOnceODRLinkage())
|
||||
return false;
|
||||
}
|
||||
|
||||
Function *Caller = CS.getCaller();
|
||||
if (!IC) {
|
||||
DEBUG(dbgs() << " NOT Inlining: cost=" << IC.getCost()
|
||||
<< ", thres=" << (IC.getCostDelta() + IC.getCost())
|
||||
<< ", Call: " << *CS.getInstruction() << "\n");
|
||||
emitAnalysis(CS, Twine(CS.getCalledFunction()->getName() +
|
||||
" too costly to inline (cost=") +
|
||||
Twine(IC.getCost()) + ", threshold=" +
|
||||
Twine(IC.getCostDelta() + IC.getCost()) + ")");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try to detect the case where the current inlining candidate caller (call
|
||||
// it B) is a static or linkonce-ODR function and is an inlining candidate
|
||||
// elsewhere, and the current candidate callee (call it C) is large enough
|
||||
|
@ -275,7 +248,6 @@ bool Inliner::shouldInline(CallSite CS) {
|
|||
// FIXME: All of this logic should be sunk into getInlineCost. It relies on
|
||||
// the internal implementation of the inline cost metrics rather than
|
||||
// treating them as truly abstract units etc.
|
||||
if (Caller->hasLocalLinkage() || Caller->hasLinkOnceODRLinkage()) {
|
||||
int TotalSecondaryCost = 0;
|
||||
// The candidate cost to be imposed upon the current function.
|
||||
int CandidateCost = IC.getCost() - (InlineConstants::CallPenalty + 1);
|
||||
|
@ -318,18 +290,54 @@ bool Inliner::shouldInline(CallSite CS) {
|
|||
if (callerWillBeRemoved && !Caller->use_empty())
|
||||
TotalSecondaryCost += InlineConstants::LastCallToStaticBonus;
|
||||
|
||||
if (inliningPreventsSomeOuterInline && TotalSecondaryCost < IC.getCost()) {
|
||||
DEBUG(dbgs() << " NOT Inlining: " << *CS.getInstruction() <<
|
||||
" Cost = " << IC.getCost() <<
|
||||
", outer Cost = " << TotalSecondaryCost << '\n');
|
||||
emitAnalysis(
|
||||
CS, Twine("Not inlining. Cost of inlining " +
|
||||
if (inliningPreventsSomeOuterInline && TotalSecondaryCost < IC.getCost())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Return true if the inliner should attempt to inline at the given CallSite.
|
||||
bool Inliner::shouldInline(CallSite CS) {
|
||||
InlineCost IC = getInlineCost(CS);
|
||||
|
||||
if (IC.isAlways()) {
|
||||
DEBUG(dbgs() << " Inlining: cost=always"
|
||||
<< ", Call: " << *CS.getInstruction() << "\n");
|
||||
emitAnalysis(CS, Twine(CS.getCalledFunction()->getName()) +
|
||||
" should always be inlined (cost=always)");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IC.isNever()) {
|
||||
DEBUG(dbgs() << " NOT Inlining: cost=never"
|
||||
<< ", Call: " << *CS.getInstruction() << "\n");
|
||||
emitAnalysis(CS, Twine(CS.getCalledFunction()->getName() +
|
||||
" should never be inlined (cost=never)"));
|
||||
return false;
|
||||
}
|
||||
|
||||
Function *Caller = CS.getCaller();
|
||||
if (!IC) {
|
||||
DEBUG(dbgs() << " NOT Inlining: cost=" << IC.getCost()
|
||||
<< ", thres=" << (IC.getCostDelta() + IC.getCost())
|
||||
<< ", Call: " << *CS.getInstruction() << "\n");
|
||||
emitAnalysis(CS, Twine(CS.getCalledFunction()->getName() +
|
||||
" too costly to inline (cost=") +
|
||||
Twine(IC.getCost()) + ", threshold=" +
|
||||
Twine(IC.getCostDelta() + IC.getCost()) + ")");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (shouldBeDeferred(Caller, CS, IC)) {
|
||||
DEBUG(dbgs() << " NOT Inlining: " << *CS.getInstruction()
|
||||
<< " Cost = " << IC.getCost()
|
||||
<< ", outer Cost = " << TotalSecondaryCost << '\n');
|
||||
emitAnalysis(CS, Twine("Not inlining. Cost of inlining " +
|
||||
CS.getCalledFunction()->getName() +
|
||||
" increases the cost of inlining " +
|
||||
CS.getCaller()->getName() + " in other contexts"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(dbgs() << " Inlining: cost=" << IC.getCost()
|
||||
<< ", thres=" << (IC.getCostDelta() + IC.getCost())
|
||||
|
|
Loading…
Reference in New Issue