From 366a873f144a065ef7ec1ec37d4bffdc55bb6baa Mon Sep 17 00:00:00 2001 From: Easwaran Raman Date: Sat, 5 Jan 2019 02:26:29 +0000 Subject: [PATCH] [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 --- llvm/lib/Transforms/IPO/Inliner.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Transforms/IPO/Inliner.cpp b/llvm/lib/Transforms/IPO/Inliner.cpp index 44001b5779cc..66a6f80f31e4 100644 --- a/llvm/lib/Transforms/IPO/Inliner.cpp +++ b/llvm/lib/Transforms/IPO/Inliner.cpp @@ -311,6 +311,11 @@ shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC, // For now we only handle local or inline functions. if (!Caller->hasLocalLinkage() && !Caller->hasLinkOnceODRLinkage()) 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 // 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 @@ -330,25 +335,31 @@ shouldBeDeferred(Function *Caller, CallSite CS, InlineCost IC, TotalSecondaryCost = 0; // The candidate cost to be imposed upon the current function. int CandidateCost = IC.getCost() - 1; - // This bool tracks what happens if we do NOT inline C into B. - bool callerWillBeRemoved = Caller->hasLocalLinkage(); + // If the caller has local linkage and can be inlined to all its callers, we + // 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. bool inliningPreventsSomeOuterInline = false; 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); // If this isn't a call to Caller (it could be some other sort // of reference) skip it. Such references will prevent the caller // from being removed. if (!CS2 || CS2.getCalledFunction() != Caller) { - callerWillBeRemoved = false; + ApplyLastCallBonus = false; continue; } InlineCost IC2 = GetInlineCost(CS2); ++NumCallerCallersAnalyzed; if (!IC2) { - callerWillBeRemoved = false; + ApplyLastCallBonus = false; continue; } 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 // be removed entirely. We did not account for this above unless there // is only one caller of Caller. - if (callerWillBeRemoved && !Caller->hasOneUse()) + if (ApplyLastCallBonus) TotalSecondaryCost -= InlineConstants::LastCallToStaticBonus; if (inliningPreventsSomeOuterInline && TotalSecondaryCost < IC.getCost())