forked from OSchip/llvm-project
parent
bf60cc492c
commit
0552521b03
|
@ -69,10 +69,6 @@ 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,11 +227,38 @@ static void emitAnalysis(CallSite CS, const Twine &Msg) {
|
|||
emitOptimizationRemarkAnalysis(Ctx, DEBUG_TYPE, *Caller, DLoc, Msg);
|
||||
}
|
||||
|
||||
bool Inliner::shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC) {
|
||||
/// Return true if the inliner should attempt to inline at the given CallSite.
|
||||
bool Inliner::shouldInline(CallSite CS) {
|
||||
InlineCost IC = getInlineCost(CS);
|
||||
|
||||
// For now we only handle local or inline functions.
|
||||
if (!Caller->hasLocalLinkage() && !Caller->hasLinkOnceODRLinkage())
|
||||
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;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
@ -248,6 +275,7 @@ bool Inliner::shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC) {
|
|||
// 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);
|
||||
|
@ -290,54 +318,18 @@ bool Inliner::shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC) {
|
|||
if (callerWillBeRemoved && !Caller->use_empty())
|
||||
TotalSecondaryCost += InlineConstants::LastCallToStaticBonus;
|
||||
|
||||
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 " +
|
||||
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 " +
|
||||
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