forked from OSchip/llvm-project
[Inliner] Optimize shouldBeDeferred
This has some minor optimizations to shouldBeDeferred. This is not strictly NFC because the early exit inside the loop assumes TotalSecondaryCost is monotonically non-decreasing, which is not true if the threshold used by CostAnalyzer is negative. AFAICT the thresholds do not go below 0 for the default values of the various options we use. llvm-svn: 350456
This commit is contained in:
parent
45ec002e25
commit
366a873f14
|
@ -311,6 +311,11 @@ shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
|
||||||
// For now we only handle local or inline functions.
|
// For now we only handle local or inline functions.
|
||||||
if (!Caller->hasLocalLinkage() && !Caller->hasLinkOnceODRLinkage())
|
if (!Caller->hasLocalLinkage() && !Caller->hasLinkOnceODRLinkage())
|
||||||
return false;
|
return false;
|
||||||
|
// If the cost of inlining CS is non-positive, it is not going to prevent the
|
||||||
|
// caller from being inlined into its callers and hence we don't need to
|
||||||
|
// defer.
|
||||||
|
if (IC.getCost() <= 0)
|
||||||
|
return false;
|
||||||
// Try to detect the case where the current inlining candidate caller (call
|
// 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
|
// 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
|
// elsewhere, and the current candidate callee (call it C) is large enough
|
||||||
|
@ -330,25 +335,31 @@ shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
|
||||||
TotalSecondaryCost = 0;
|
TotalSecondaryCost = 0;
|
||||||
// The candidate cost to be imposed upon the current function.
|
// The candidate cost to be imposed upon the current function.
|
||||||
int CandidateCost = IC.getCost() - 1;
|
int CandidateCost = IC.getCost() - 1;
|
||||||
// This bool tracks what happens if we do NOT inline C into B.
|
// If the caller has local linkage and can be inlined to all its callers, we
|
||||||
bool callerWillBeRemoved = Caller->hasLocalLinkage();
|
// can apply a huge negative bonus to TotalSecondaryCost.
|
||||||
|
bool ApplyLastCallBonus = Caller->hasLocalLinkage() && !Caller->hasOneUse();
|
||||||
// This bool tracks what happens if we DO inline C into B.
|
// This bool tracks what happens if we DO inline C into B.
|
||||||
bool inliningPreventsSomeOuterInline = false;
|
bool inliningPreventsSomeOuterInline = false;
|
||||||
for (User *U : Caller->users()) {
|
for (User *U : Caller->users()) {
|
||||||
|
// If the caller will not be removed (either because it does not have a
|
||||||
|
// local linkage or because the LastCallToStaticBonus has been already
|
||||||
|
// applied), then we can exit the loop early.
|
||||||
|
if (!ApplyLastCallBonus && TotalSecondaryCost >= IC.getCost())
|
||||||
|
return false;
|
||||||
CallSite CS2(U);
|
CallSite CS2(U);
|
||||||
|
|
||||||
// If this isn't a call to Caller (it could be some other sort
|
// If this isn't a call to Caller (it could be some other sort
|
||||||
// of reference) skip it. Such references will prevent the caller
|
// of reference) skip it. Such references will prevent the caller
|
||||||
// from being removed.
|
// from being removed.
|
||||||
if (!CS2 || CS2.getCalledFunction() != Caller) {
|
if (!CS2 || CS2.getCalledFunction() != Caller) {
|
||||||
callerWillBeRemoved = false;
|
ApplyLastCallBonus = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
InlineCost IC2 = GetInlineCost(CS2);
|
InlineCost IC2 = GetInlineCost(CS2);
|
||||||
++NumCallerCallersAnalyzed;
|
++NumCallerCallersAnalyzed;
|
||||||
if (!IC2) {
|
if (!IC2) {
|
||||||
callerWillBeRemoved = false;
|
ApplyLastCallBonus = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (IC2.isAlways())
|
if (IC2.isAlways())
|
||||||
|
@ -366,7 +377,7 @@ shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC,
|
||||||
// one is set very low by getInlineCost, in anticipation that Caller will
|
// one is set very low by getInlineCost, in anticipation that Caller will
|
||||||
// be removed entirely. We did not account for this above unless there
|
// be removed entirely. We did not account for this above unless there
|
||||||
// is only one caller of Caller.
|
// is only one caller of Caller.
|
||||||
if (callerWillBeRemoved && !Caller->hasOneUse())
|
if (ApplyLastCallBonus)
|
||||||
TotalSecondaryCost -= InlineConstants::LastCallToStaticBonus;
|
TotalSecondaryCost -= InlineConstants::LastCallToStaticBonus;
|
||||||
|
|
||||||
if (inliningPreventsSomeOuterInline && TotalSecondaryCost < IC.getCost())
|
if (inliningPreventsSomeOuterInline && TotalSecondaryCost < IC.getCost())
|
||||||
|
|
Loading…
Reference in New Issue