diff --git a/llvm/include/llvm/Transforms/Utils/Cloning.h b/llvm/include/llvm/Transforms/Utils/Cloning.h --- a/llvm/include/llvm/Transforms/Utils/Cloning.h +++ b/llvm/include/llvm/Transforms/Utils/Cloning.h @@ -197,9 +197,10 @@ function_ref GetAssumptionCache = nullptr, ProfileSummaryInfo *PSI = nullptr, BlockFrequencyInfo *CallerBFI = nullptr, - BlockFrequencyInfo *CalleeBFI = nullptr) + BlockFrequencyInfo *CalleeBFI = nullptr, bool UpdateProfile = true) : CG(cg), GetAssumptionCache(GetAssumptionCache), PSI(PSI), - CallerBFI(CallerBFI), CalleeBFI(CalleeBFI) {} + CallerBFI(CallerBFI), CalleeBFI(CalleeBFI), + UpdateProfile(UpdateProfile) {} /// If non-null, InlineFunction will update the callgraph to reflect the /// changes it makes. @@ -223,6 +224,10 @@ /// `InlinedCalls` above is used. SmallVector InlinedCallSites; + /// Update profile for callee as well as cloned version. We need to do this + /// for regular inlining, but not for inlining from sample profile loader. + bool UpdateProfile; + void reset() { StaticAllocas.clear(); InlinedCalls.clear(); diff --git a/llvm/lib/Transforms/IPO/SampleProfile.cpp b/llvm/lib/Transforms/IPO/SampleProfile.cpp --- a/llvm/lib/Transforms/IPO/SampleProfile.cpp +++ b/llvm/lib/Transforms/IPO/SampleProfile.cpp @@ -1093,6 +1093,7 @@ return false; InlineFunctionInfo IFI(nullptr, GetAC); + IFI.UpdateProfile = false; if (InlineFunction(CB, IFI).isSuccess()) { // The call to InlineFunction erases I, so we can't pass it here. emitInlinedInto(*ORE, DLoc, BB, *CalledFunction, *BB->getParent(), Cost, diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -1954,13 +1954,19 @@ if (objcarc::hasAttachedCallOpBundle(&CB)) inlineRetainOrClaimRVCalls(CB, Returns); - if (IFI.CallerBFI != nullptr && IFI.CalleeBFI != nullptr) - // Update the BFI of blocks cloned into the caller. - updateCallerBFI(OrigBB, VMap, IFI.CallerBFI, IFI.CalleeBFI, - CalledFunc->front()); - - updateCallProfile(CalledFunc, VMap, CalledFunc->getEntryCount(), CB, - IFI.PSI, IFI.CallerBFI); + // Updated caller/callee profiles only when requested. For sample loader + // inlining, the context-sensitive inlinee profile doesn't need to be + // subtracted from callee profile, and the inlined clone also doesn't need + // to be scaled based on call site count. + if (IFI.UpdateProfile) { + if (IFI.CallerBFI != nullptr && IFI.CalleeBFI != nullptr) + // Update the BFI of blocks cloned into the caller. + updateCallerBFI(OrigBB, VMap, IFI.CallerBFI, IFI.CalleeBFI, + CalledFunc->front()); + + updateCallProfile(CalledFunc, VMap, CalledFunc->getEntryCount(), CB, + IFI.PSI, IFI.CallerBFI); + } // Inject byval arguments initialization. for (std::pair &Init : ByValInit)