LLVM 24.0.0git
SampleProfile.cpp
Go to the documentation of this file.
1//===- SampleProfile.cpp - Incorporate sample profiles into the IR --------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the SampleProfileLoader transformation. This pass
10// reads a profile file generated by a sampling profiler (e.g. Linux Perf -
11// http://perf.wiki.kernel.org/) and generates IR metadata to reflect the
12// profile information in the given profile.
13//
14// This pass generates branch weight annotations on the IR:
15//
16// - prof: Represents branch weights. This annotation is added to branches
17// to indicate the weights of each edge coming out of the branch.
18// The weight of each edge is the weight of the target block for
19// that edge. The weight of a block B is computed as the maximum
20// number of samples found in B.
21//
22//===----------------------------------------------------------------------===//
23
25#include "IPOOptions.h"
26#include "llvm/ADT/ArrayRef.h"
27#include "llvm/ADT/DenseMap.h"
28#include "llvm/ADT/DenseSet.h"
29#include "llvm/ADT/MapVector.h"
33#include "llvm/ADT/Statistic.h"
34#include "llvm/ADT/StringRef.h"
35#include "llvm/ADT/Twine.h"
46#include "llvm/IR/BasicBlock.h"
47#include "llvm/IR/DebugLoc.h"
49#include "llvm/IR/Function.h"
50#include "llvm/IR/GlobalValue.h"
51#include "llvm/IR/InstrTypes.h"
52#include "llvm/IR/Instruction.h"
55#include "llvm/IR/LLVMContext.h"
56#include "llvm/IR/MDBuilder.h"
57#include "llvm/IR/Module.h"
58#include "llvm/IR/PassManager.h"
60#include "llvm/IR/PseudoProbe.h"
67#include "llvm/Support/Debug.h"
71#include "llvm/Transforms/IPO.h"
82#include <algorithm>
83#include <cassert>
84#include <cstdint>
85#include <functional>
86#include <limits>
87#include <memory>
88#include <queue>
89#include <string>
90#include <system_error>
91#include <utility>
92#include <vector>
93
94using namespace llvm;
95using namespace sampleprof;
96using namespace llvm::sampleprofutil;
97#define DEBUG_TYPE "sample-profile"
98#define CSINLINE_DEBUG DEBUG_TYPE "-inline"
99
100STATISTIC(NumCSInlined,
101 "Number of functions inlined with context sensitive profile");
102STATISTIC(NumCSNotInlined,
103 "Number of functions not inlined with context sensitive profile");
104STATISTIC(NumMismatchedProfile,
105 "Number of functions with CFG mismatched profile");
106STATISTIC(NumMatchedProfile, "Number of functions with CFG matched profile");
107STATISTIC(NumDuplicatedInlinesite,
108 "Number of inlined callsites with a partial distribution factor");
109
110STATISTIC(NumCSInlinedHitMinLimit,
111 "Number of functions with FDO inline stopped due to min size limit");
112STATISTIC(NumCSInlinedHitMaxLimit,
113 "Number of functions with FDO inline stopped due to max size limit");
115 NumCSInlinedHitGrowthLimit,
116 "Number of functions with FDO inline stopped due to growth size limit");
117
118namespace llvm {
119
121 SortProfiledSCC("sort-profiled-scc-member", cl::init(true), cl::Hidden,
122 cl::desc("Sort profiled recursion by edge weights."));
123
125 "sample-profile-inline-growth-limit", cl::Hidden, cl::init(12),
126 cl::desc("The size growth ratio limit for priority-based sample profile "
127 "loader inlining."));
128
130 "sample-profile-inline-limit-min", cl::Hidden, cl::init(100),
131 cl::desc("The lower bound of size growth limit for "
132 "priority-based sample profile loader inlining."));
133
135 "sample-profile-inline-limit-max", cl::Hidden, cl::init(10000),
136 cl::desc("The upper bound of size growth limit for "
137 "priority-based sample profile loader inlining."));
138
140 "sample-profile-hot-inline-threshold", cl::Hidden, cl::init(3000),
141 cl::desc("Hot callsite threshold for priority-based sample profile loader "
142 "inlining."));
143
145 "sample-profile-cold-inline-threshold", cl::Hidden, cl::init(45),
146 cl::desc("Threshold for inlining cold callsites"));
147} // namespace llvm
148
149namespace llvm {
151}
152
153namespace {
154
155using BlockWeightMap = DenseMap<const BasicBlock *, uint64_t>;
156using EquivalenceClassMap = DenseMap<const BasicBlock *, const BasicBlock *>;
157using Edge = std::pair<const BasicBlock *, const BasicBlock *>;
158using BlockEdgeMap =
160
161class GUIDToFuncNameMapper {
162public:
163 GUIDToFuncNameMapper(Module &M, SampleProfileReader &Reader,
164 DenseMap<uint64_t, StringRef> &GUIDToFuncNameMap)
165 : CurrentReader(Reader), CurrentModule(M),
166 CurrentGUIDToFuncNameMap(GUIDToFuncNameMap) {
167 if (!CurrentReader.useMD5())
168 return;
169
170 for (const auto &F : CurrentModule) {
171 StringRef OrigName = F.getName();
172 CurrentGUIDToFuncNameMap.insert(
173 {Function::getGUIDAssumingExternalLinkage(OrigName), OrigName});
174
175 // Local to global var promotion used by optimization like thinlto
176 // will rename the var and add suffix like ".llvm.xxx" to the
177 // original local name. In sample profile, the suffixes of function
178 // names are all stripped. Since it is possible that the mapper is
179 // built in post-thin-link phase and var promotion has been done,
180 // we need to add the substring of function name without the suffix
181 // into the GUIDToFuncNameMap.
183 if (CanonName != OrigName)
184 CurrentGUIDToFuncNameMap.insert(
185 {Function::getGUIDAssumingExternalLinkage(CanonName), CanonName});
186 }
187
188 // Update GUIDToFuncNameMap for each function including inlinees.
189 SetGUIDToFuncNameMapForAll(&CurrentGUIDToFuncNameMap);
190 }
191
192 ~GUIDToFuncNameMapper() {
193 if (!CurrentReader.useMD5())
194 return;
195
196 CurrentGUIDToFuncNameMap.clear();
197
198 // Reset GUIDToFuncNameMap for of each function as they're no
199 // longer valid at this point.
200 SetGUIDToFuncNameMapForAll(nullptr);
201 }
202
203private:
204 void SetGUIDToFuncNameMapForAll(DenseMap<uint64_t, StringRef> *Map) {
205 std::queue<FunctionSamples *> FSToUpdate;
206 for (auto &IFS : CurrentReader.getProfiles()) {
207 FSToUpdate.push(&IFS.second);
208 }
209
210 while (!FSToUpdate.empty()) {
211 FunctionSamples *FS = FSToUpdate.front();
212 FSToUpdate.pop();
213 FS->GUIDToFuncNameMap = Map;
214 for (const auto &ICS : FS->getCallsiteSamples()) {
215 const FunctionSamplesMap &FSMap = ICS.second;
216 for (const auto &IFS : FSMap) {
217 FunctionSamples &FS = const_cast<FunctionSamples &>(IFS.second);
218 FSToUpdate.push(&FS);
219 }
220 }
221 }
222 }
223
225 Module &CurrentModule;
226 DenseMap<uint64_t, StringRef> &CurrentGUIDToFuncNameMap;
227};
228
229// Inline candidate used by iterative callsite prioritized inliner
230struct InlineCandidate {
231 CallBase *CallInstr;
232 const FunctionSamples *CalleeSamples;
233 // Prorated callsite count, which will be used to guide inlining. For example,
234 // if a callsite is duplicated in LTO prelink, then in LTO postlink the two
235 // copies will get their own distribution factors and their prorated counts
236 // will be used to decide if they should be inlined independently.
237 uint64_t CallsiteCount;
238 // Call site distribution factor to prorate the profile samples for a
239 // duplicated callsite. Default value is 1.0.
240 float CallsiteDistribution;
241};
242
243// Inline candidate comparer using call site weight
244struct CandidateComparer {
245 bool operator()(const InlineCandidate &LHS, const InlineCandidate &RHS) {
246 if (LHS.CallsiteCount != RHS.CallsiteCount)
247 return LHS.CallsiteCount < RHS.CallsiteCount;
248
249 const FunctionSamples *LCS = LHS.CalleeSamples;
250 const FunctionSamples *RCS = RHS.CalleeSamples;
251 // In inline replay mode, CalleeSamples may be null and the order doesn't
252 // matter.
253 if (!LCS || !RCS)
254 return LCS;
255
256 // Tie breaker using number of samples try to favor smaller functions first
257 if (LCS->getBodySamples().size() != RCS->getBodySamples().size())
258 return LCS->getBodySamples().size() > RCS->getBodySamples().size();
259
260 // Tie breaker using GUID so we have stable/deterministic inlining order
261 return LCS->getGUID() < RCS->getGUID();
262 }
263};
264
265using CandidateQueue =
267 CandidateComparer>;
268
269/// Sample profile pass.
270///
271/// This pass reads profile data from the file specified by
272/// -sample-profile-file and annotates every affected function with the
273/// profile information found in that file.
274class SampleProfileLoader final : public SampleProfileLoaderBaseImpl<Function> {
275public:
276 SampleProfileLoader(
277 const IPOOptions &Opts, StringRef Name, StringRef RemapName,
278 ThinOrFullLTOPhase LTOPhase, IntrusiveRefCntPtr<vfs::FileSystem> FS,
279 std::function<AssumptionCache &(Function &)> GetAssumptionCache,
280 std::function<TargetTransformInfo &(Function &)> GetTargetTransformInfo,
281 std::function<const TargetLibraryInfo &(Function &)> GetTLI,
282 LazyCallGraph &CG, bool DisableSampleProfileInlining,
283 bool UseFlattenedProfile)
284 : SampleProfileLoaderBaseImpl(std::string(Name), std::string(RemapName),
285 std::move(FS)),
286 Opts(Opts), ProfileMergeInlinee(Opts.sample_profile_merge_inlinee),
287 ProfileSizeInline(valueOr(Opts.sample_profile_inline_size, false)),
288 CallsitePrioritizedInline(
289 valueOr(Opts.sample_profile_prioritized_inline, false)),
290 AllowRecursiveInline(
291 valueOr(Opts.sample_profile_recursive_inline, false)),
292 UsePreInlinerDecision(
293 valueOr(Opts.sample_profile_use_preinliner, false)),
294 SalvageStaleProfile(valueOr(Opts.salvage_stale_profile, false)),
295 SalvageUnusedProfile(valueOr(Opts.salvage_unused_profile, false)),
296 GetAC(std::move(GetAssumptionCache)),
297 GetTTI(std::move(GetTargetTransformInfo)), GetTLI(std::move(GetTLI)),
298 CG(CG), LTOPhase(LTOPhase),
299 AnnotatedPassName(Opts.annotate_sample_profile_inline_phase
300 ? llvm::AnnotateInlinePassName(InlineContext{
303 DisableSampleProfileInlining(DisableSampleProfileInlining),
304 UseFlattenedProfile(UseFlattenedProfile) {}
305
306 bool doInitialization(Module &M, FunctionAnalysisManager *FAM = nullptr);
307 bool runOnModule(Module &M, ModuleAnalysisManager &AM,
308 ProfileSummaryInfo *_PSI);
309
310protected:
311 const IPOOptions &Opts;
312 // Options the loader adjusts according to the profile.
313 bool ProfileMergeInlinee;
314 bool ProfileSizeInline;
315 bool CallsitePrioritizedInline;
316 bool AllowRecursiveInline;
317 bool UsePreInlinerDecision;
318 bool SalvageStaleProfile;
319 bool SalvageUnusedProfile;
320
322 bool emitAnnotations(Function &F);
323 ErrorOr<uint64_t> getInstWeight(const Instruction &I) override;
324 const FunctionSamples *findCalleeFunctionSamples(const CallBase &I) const;
325 const FunctionSamples *
326 findFunctionSamples(const Instruction &I) const override;
327 std::vector<const FunctionSamples *>
328 findIndirectCallFunctionSamples(const Instruction &I, uint64_t &Sum) const;
329 void findExternalInlineCandidate(CallBase *CB, const FunctionSamples *Samples,
330 DenseSet<GlobalValue::GUID> &InlinedGUIDs,
331 uint64_t Threshold);
332 // Attempt to promote indirect call and also inline the promoted call
333 bool tryPromoteAndInlineCandidate(
334 Function &F, InlineCandidate &Candidate, uint64_t SumOrigin,
335 uint64_t &Sum, SmallVector<CallBase *, 8> *InlinedCallSites = nullptr);
336
337 bool inlineHotFunctions(Function &F,
338 DenseSet<GlobalValue::GUID> &InlinedGUIDs);
339 std::optional<InlineCost> getExternalInlineAdvisorCost(CallBase &CB);
340 bool getExternalInlineAdvisorShouldInline(CallBase &CB);
341 InlineCost shouldInlineCandidate(InlineCandidate &Candidate);
342 bool getInlineCandidate(InlineCandidate *NewCandidate, CallBase *CB);
343 bool
344 tryInlineCandidate(InlineCandidate &Candidate,
345 SmallVector<CallBase *, 8> *InlinedCallSites = nullptr);
346 bool
347 inlineHotFunctionsWithPriority(Function &F,
348 DenseSet<GlobalValue::GUID> &InlinedGUIDs);
349 // Inline cold/small functions in addition to hot ones
350 bool shouldInlineColdCallee(CallBase &CallInst);
351 void emitOptimizationRemarksForInlineCandidates(
352 const SmallVectorImpl<CallBase *> &Candidates, const Function &F,
353 bool Hot);
354 void promoteMergeNotInlinedContextSamples(
355 MapVector<CallBase *, const FunctionSamples *> NonInlinedCallSites,
356 const Function &F);
357 std::vector<Function *> buildFunctionOrder(Module &M, LazyCallGraph &CG);
358 std::unique_ptr<ProfiledCallGraph> buildProfiledCallGraph(Module &M);
359 void generateMDProfMetadata(Function &F);
360 bool rejectHighStalenessProfile(Module &M, ProfileSummaryInfo *PSI,
361 const SampleProfileMap &Profiles);
362 void removePseudoProbeInstsDiscriminator(Module &M);
363
364 /// Map from function name to Function *. Used to find the function from
365 /// the function name. If the function name contains suffix, additional
366 /// entry is added to map from the stripped name to the function if there
367 /// is one-to-one mapping.
368 HashKeyMap<DenseMap, FunctionId, Function *> SymbolMap;
369
370 /// Map from function name to profile name generated by call-graph based
371 /// profile fuzzy matching(--salvage-unused-profile).
372 HashKeyMap<DenseMap, FunctionId, FunctionId> FuncNameToProfNameMap;
373
374 std::function<AssumptionCache &(Function &)> GetAC;
375 std::function<TargetTransformInfo &(Function &)> GetTTI;
376 std::function<const TargetLibraryInfo &(Function &)> GetTLI;
377 LazyCallGraph &CG;
378
379 /// Profile tracker for different context.
380 std::unique_ptr<SampleContextTracker> ContextTracker;
381
382 /// Flag indicating which LTO/ThinLTO phase the pass is invoked in.
383 ///
384 /// We need to know the LTO phase because for example in ThinLTOPrelink
385 /// phase, in annotation, we should not promote indirect calls. Instead,
386 /// we will mark GUIDs that needs to be annotated to the function.
387 const ThinOrFullLTOPhase LTOPhase;
388 const std::string AnnotatedPassName;
389
390 /// Profle Symbol list tells whether a function name appears in the binary
391 /// used to generate the current profile.
392 std::shared_ptr<ProfileSymbolList> PSL;
393
394 // Information recorded when we declined to inline a call site
395 // because we have determined it is too cold is accumulated for
396 // each callee function. Initially this is just the entry count.
397 struct NotInlinedProfileInfo {
398 uint64_t entryCount;
399 };
400 DenseMap<Function *, NotInlinedProfileInfo> notInlinedCallInfo;
401
402 // GUIDToFuncNameMap saves the mapping from GUID to the symbol name, for
403 // all the function symbols defined or declared in current module.
404 DenseMap<uint64_t, StringRef> GUIDToFuncNameMap;
405
406 // For symbol in profile symbol list, whether to regard their profiles
407 // to be accurate. It is mainly decided by existance of profile symbol
408 // list and -profile-accurate-for-symsinlist flag, but it can be
409 // overriden by -profile-sample-accurate or profile-sample-accurate
410 // attribute.
411 bool ProfAccForSymsInList;
412
413 bool DisableSampleProfileInlining;
414
415 bool UseFlattenedProfile;
416
417 // External inline advisor used to replay inline decision from remarks.
418 std::unique_ptr<InlineAdvisor> ExternalInlineAdvisor;
419
420 // A helper to implement the sample profile matching algorithm.
421 std::unique_ptr<SampleProfileMatcher> MatchingManager;
422
423private:
424 const char *getAnnotatedRemarkPassName() const {
425 return AnnotatedPassName.c_str();
426 }
427};
428} // end anonymous namespace
429
430namespace llvm {
431template <>
432inline bool SampleProfileInference<Function>::isExit(const BasicBlock *BB) {
433 return succ_empty(BB);
434}
435
436template <>
437inline void SampleProfileInference<Function>::findUnlikelyJumps(
438 const std::vector<const BasicBlockT *> &BasicBlocks,
439 BlockEdgeMap &Successors, FlowFunction &Func) {
440 for (auto &Jump : Func.Jumps) {
441 const auto *BB = BasicBlocks[Jump.Source];
442 const auto *Succ = BasicBlocks[Jump.Target];
443 const Instruction *TI = BB->getTerminator();
444 // Check if a block ends with InvokeInst and mark non-taken branch unlikely.
445 // In that case block Succ should be a landing pad
446 const auto &Succs = Successors[BB];
447 if (Succs.size() == 2 && Succs.back() == Succ) {
448 if (isa<InvokeInst>(TI)) {
449 Jump.IsUnlikely = true;
450 }
451 }
452 const Instruction *SuccTI = Succ->getTerminator();
453 // Check if the target block contains UnreachableInst and mark it unlikely
454 if (SuccTI->getNumSuccessors() == 0) {
455 if (isa<UnreachableInst>(SuccTI)) {
456 Jump.IsUnlikely = true;
457 }
458 }
459 }
460}
461
462template <>
464 Function &F) {
465 DT.reset(new DominatorTree);
466 DT->recalculate(F);
467
468 PDT.reset(new PostDominatorTree(F));
469
470 LI.reset(new LoopInfo);
471 LI->analyze(*DT);
472}
473} // namespace llvm
474
475ErrorOr<uint64_t> SampleProfileLoader::getInstWeight(const Instruction &Inst) {
477 return getProbeWeight(Inst);
478
479 const DebugLoc &DLoc = Inst.getDebugLoc();
480 if (!DLoc)
481 return std::error_code();
482
483 // Ignore all intrinsics, phinodes and branch instructions.
484 // Branch and phinodes instruction usually contains debug info from sources
485 // outside of the residing basic block, thus we ignore them during annotation.
487 return std::error_code();
488
489 // For non-CS profile, if a direct call/invoke instruction is inlined in
490 // profile (findCalleeFunctionSamples returns non-empty result), but not
491 // inlined here, it means that the inlined callsite has no sample, thus the
492 // call instruction should have 0 count.
493 // For CS profile, the callsite count of previously inlined callees is
494 // populated with the entry count of the callees.
496 if (const auto *CB = dyn_cast<CallBase>(&Inst))
497 if (!CB->isIndirectCall() && findCalleeFunctionSamples(*CB))
498 return 0;
499
500 return getInstWeightImpl(Inst);
501}
502
503/// Get the FunctionSamples for a call instruction.
504///
505/// The FunctionSamples of a call/invoke instruction \p Inst is the inlined
506/// instance in which that call instruction is calling to. It contains
507/// all samples that resides in the inlined instance. We first find the
508/// inlined instance in which the call instruction is from, then we
509/// traverse its children to find the callsite with the matching
510/// location.
511///
512/// \param Inst Call/Invoke instruction to query.
513///
514/// \returns The FunctionSamples pointer to the inlined instance.
515const FunctionSamples *
516SampleProfileLoader::findCalleeFunctionSamples(const CallBase &Inst) const {
517 const DILocation *DIL = Inst.getDebugLoc();
518 if (!DIL) {
519 return nullptr;
520 }
521
522 StringRef CalleeName;
523 if (Function *Callee = Inst.getCalledFunction())
524 CalleeName = Callee->getName();
525
527 return ContextTracker->getCalleeContextSamplesFor(Inst, CalleeName);
528
529 const FunctionSamples *FS = findFunctionSamples(Inst);
530 if (FS == nullptr)
531 return nullptr;
532
533 return FS->findFunctionSamplesAt(FunctionSamples::getCallSiteIdentifier(DIL),
534 CalleeName, Reader->getRemapper(),
535 &FuncNameToProfNameMap);
536}
537
538/// Returns a vector of FunctionSamples that are the indirect call targets
539/// of \p Inst. The vector is sorted by the total number of samples. Stores
540/// the total call count of the indirect call in \p Sum.
541std::vector<const FunctionSamples *>
542SampleProfileLoader::findIndirectCallFunctionSamples(
543 const Instruction &Inst, uint64_t &Sum) const {
544 const DILocation *DIL = Inst.getDebugLoc();
545 std::vector<const FunctionSamples *> R;
546
547 if (!DIL) {
548 return R;
549 }
550
551 auto FSCompare = [](const FunctionSamples *L, const FunctionSamples *R) {
552 assert(L && R && "Expect non-null FunctionSamples");
553 if (L->getHeadSamplesEstimate() != R->getHeadSamplesEstimate())
554 return L->getHeadSamplesEstimate() > R->getHeadSamplesEstimate();
555 return L->getGUID() < R->getGUID();
556 };
557
559 auto CalleeSamples =
560 ContextTracker->getIndirectCalleeContextSamplesFor(DIL);
561 if (CalleeSamples.empty())
562 return R;
563
564 // For CSSPGO, we only use target context profile's entry count
565 // as that already includes both inlined callee and non-inlined ones..
566 Sum = 0;
567 for (const auto *const FS : CalleeSamples) {
568 Sum += FS->getHeadSamplesEstimate();
569 R.push_back(FS);
570 }
571 llvm::sort(R, FSCompare);
572 return R;
573 }
574
575 const FunctionSamples *FS = findFunctionSamples(Inst);
576 if (FS == nullptr)
577 return R;
578
580 Sum = 0;
581 if (auto T = FS->findCallTargetMapAt(CallSite))
582 for (const auto &T_C : *T)
583 Sum += T_C.second;
584 if (const FunctionSamplesMap *M = FS->findFunctionSamplesMapAt(CallSite)) {
585 if (M->empty())
586 return R;
587 for (const auto &NameFS : *M) {
588 Sum += NameFS.second.getHeadSamplesEstimate();
589 R.push_back(&NameFS.second);
590 }
591 llvm::sort(R, FSCompare);
592 }
593 return R;
594}
595
596const FunctionSamples *
597SampleProfileLoader::findFunctionSamples(const Instruction &Inst) const {
599 std::optional<PseudoProbe> Probe = extractProbe(Inst);
600 if (!Probe)
601 return nullptr;
602 }
603
604 const DILocation *DIL = Inst.getDebugLoc();
605 if (!DIL)
606 return Samples;
607
608 auto it = DILocation2SampleMap.try_emplace(DIL,nullptr);
609 if (it.second) {
611 it.first->second = ContextTracker->getContextSamplesFor(DIL);
612 else
613 it.first->second = Samples->findFunctionSamples(
614 DIL, Reader->getRemapper(), &FuncNameToProfNameMap);
615 }
616 return it.first->second;
617}
618
619/// Check whether the indirect call promotion history of \p Inst allows
620/// the promotion for \p Candidate.
621/// If the profile count for the promotion candidate \p Candidate is
622/// NOMORE_ICP_MAGICNUM, it means \p Candidate has already been promoted
623/// for \p Inst. If we already have at least MaxNumPromotions
624/// NOMORE_ICP_MAGICNUM count values in the value profile of \p Inst, we
625/// cannot promote for \p Inst anymore.
626static bool doesHistoryAllowICP(const IPOOptions &Opts, const Instruction &Inst,
627 StringRef Candidate) {
628 uint64_t TotalCount = 0;
629 auto ValueData = getValueProfDataFromInst(Inst, IPVK_IndirectCallTarget,
630 Opts.sample_profile_icp_max_prom,
631 TotalCount, true);
632 // No valid value profile so no promoted targets have been recorded
633 // before. Ok to do ICP.
634 if (ValueData.empty())
635 return true;
636
637 unsigned NumPromoted = 0;
638 for (const auto &V : ValueData) {
639 if (V.Count != NOMORE_ICP_MAGICNUM)
640 continue;
641
642 // If the promotion candidate has NOMORE_ICP_MAGICNUM count in the
643 // metadata, it means the candidate has been promoted for this
644 // indirect call.
645 if (V.Value == Function::getGUIDAssumingExternalLinkage(Candidate))
646 return false;
647 NumPromoted++;
648 // If already have MaxNumPromotions promotion, don't do it anymore.
649 if (NumPromoted == Opts.sample_profile_icp_max_prom)
650 return false;
651 }
652 return true;
653}
654
655/// Update indirect call target profile metadata for \p Inst.
656/// Usually \p Sum is the sum of counts of all the targets for \p Inst.
657/// If it is 0, it means updateIDTMetaData is used to mark a
658/// certain target to be promoted already. If it is not zero,
659/// we expect to use it to update the total count in the value profile.
660static void
661updateIDTMetaData(const IPOOptions &Opts, Instruction &Inst,
662 const SmallVectorImpl<InstrProfValueData> &CallTargets,
663 uint64_t Sum) {
664 // Bail out early if MaxNumPromotions is zero.
665 // This prevents allocating an array of zero length below.
666 //
667 // Note `updateIDTMetaData` is called in two places so check
668 // `MaxNumPromotions` inside it.
669 if (Opts.sample_profile_icp_max_prom == 0)
670 return;
671 // OldSum is the existing total count in the value profile data.
672 uint64_t OldSum = 0;
673 auto ValueData =
674 getValueProfDataFromInst(Inst, IPVK_IndirectCallTarget,
675 Opts.sample_profile_icp_max_prom, OldSum, true);
676
677 DenseMap<uint64_t, uint64_t> ValueCountMap;
678 if (Sum == 0) {
679 assert((CallTargets.size() == 1 &&
680 CallTargets[0].Count == NOMORE_ICP_MAGICNUM) &&
681 "If sum is 0, assume only one element in CallTargets "
682 "with count being NOMORE_ICP_MAGICNUM");
683 // Initialize ValueCountMap with existing value profile data.
684 for (const auto &V : ValueData)
685 ValueCountMap[V.Value] = V.Count;
686 auto Pair =
687 ValueCountMap.try_emplace(CallTargets[0].Value, CallTargets[0].Count);
688 // If the target already exists in value profile, decrease the total
689 // count OldSum and reset the target's count to NOMORE_ICP_MAGICNUM.
690 if (!Pair.second) {
691 OldSum -= Pair.first->second;
692 Pair.first->second = NOMORE_ICP_MAGICNUM;
693 }
694 Sum = OldSum;
695 } else {
696 // Initialize ValueCountMap with existing NOMORE_ICP_MAGICNUM
697 // counts in the value profile.
698 for (const auto &V : ValueData) {
699 if (V.Count == NOMORE_ICP_MAGICNUM)
700 ValueCountMap[V.Value] = V.Count;
701 }
702
703 for (const auto &Data : CallTargets) {
704 auto Pair = ValueCountMap.try_emplace(Data.Value, Data.Count);
705 if (Pair.second)
706 continue;
707 // The target represented by Data.Value has already been promoted.
708 // Keep the count as NOMORE_ICP_MAGICNUM in the profile and decrease
709 // Sum by Data.Count.
710 assert(Sum >= Data.Count && "Sum should never be less than Data.Count");
711 Sum -= Data.Count;
712 }
713 }
714
716 for (const auto &ValueCount : ValueCountMap) {
717 NewCallTargets.emplace_back(
718 InstrProfValueData{ValueCount.first, ValueCount.second});
719 }
720
721 llvm::sort(NewCallTargets,
722 [](const InstrProfValueData &L, const InstrProfValueData &R) {
723 return std::tie(L.Count, L.Value) > std::tie(R.Count, R.Value);
724 });
725
726 uint32_t MaxMDCount =
727 std::min(NewCallTargets.size(),
728 static_cast<size_t>(Opts.sample_profile_icp_max_prom));
729 annotateValueSite(*Inst.getParent()->getParent()->getParent(), Inst,
730 NewCallTargets, Sum, IPVK_IndirectCallTarget, MaxMDCount);
731}
732
733/// Attempt to promote indirect call and also inline the promoted call.
734///
735/// \param F Caller function.
736/// \param Candidate ICP and inline candidate.
737/// \param SumOrigin Original sum of target counts for indirect call before
738/// promoting given candidate.
739/// \param Sum Prorated sum of remaining target counts for indirect call
740/// after promoting given candidate.
741/// \param InlinedCallSite Output vector for new call sites exposed after
742/// inlining.
743bool SampleProfileLoader::tryPromoteAndInlineCandidate(
744 Function &F, InlineCandidate &Candidate, uint64_t SumOrigin, uint64_t &Sum,
745 SmallVector<CallBase *, 8> *InlinedCallSite) {
746 // Bail out early if sample-loader inliner is disabled.
747 if (DisableSampleProfileInlining)
748 return false;
749
750 // Bail out early if MaxNumPromotions is zero.
751 // This prevents allocating an array of zero length in callees below.
752 if (Opts.sample_profile_icp_max_prom == 0)
753 return false;
754 auto CalleeFunctionName = Candidate.CalleeSamples->getFunction();
755 auto R = SymbolMap.find(CalleeFunctionName);
756 if (R == SymbolMap.end() || !R->second)
757 return false;
758
759 auto &CI = *Candidate.CallInstr;
760 if (!doesHistoryAllowICP(Opts, CI, R->second->getName()))
761 return false;
762
763 const char *Reason = "Callee function not available";
764 // R->getValue() != &F is to prevent promoting a recursive call.
765 // If it is a recursive call, we do not inline it as it could bloat
766 // the code exponentially. There is way to better handle this, e.g.
767 // clone the caller first, and inline the cloned caller if it is
768 // recursive. As llvm does not inline recursive calls, we will
769 // simply ignore it instead of handling it explicitly.
770 if (!R->second->isDeclaration() && R->second->getSubprogram() &&
771 R->second->hasFnAttribute("use-sample-profile") &&
772 R->second != &F && isLegalToPromote(CI, R->second, &Reason)) {
773 // For promoted target, set its value with NOMORE_ICP_MAGICNUM count
774 // in the value profile metadata so the target won't be promoted again.
775 SmallVector<InstrProfValueData, 1> SortedCallTargets = {InstrProfValueData{
776 Function::getGUIDAssumingExternalLinkage(R->second->getName()),
778 updateIDTMetaData(Opts, CI, SortedCallTargets, 0);
779
780 auto *DI = &pgo::promoteIndirectCall(
781 CI, R->second, Candidate.CallsiteCount, Sum, false, ORE);
782 if (DI) {
783 Sum -= Candidate.CallsiteCount;
784 // Do not prorate the indirect callsite distribution since the original
785 // distribution will be used to scale down non-promoted profile target
786 // counts later. By doing this we lose track of the real callsite count
787 // for the leftover indirect callsite as a trade off for accurate call
788 // target counts.
789 // TODO: Ideally we would have two separate factors, one for call site
790 // counts and one is used to prorate call target counts.
791 // Do not update the promoted direct callsite distribution at this
792 // point since the original distribution combined with the callee profile
793 // will be used to prorate callsites from the callee if inlined. Once not
794 // inlined, the direct callsite distribution should be prorated so that
795 // the it will reflect the real callsite counts.
796 Candidate.CallInstr = DI;
797 if (isa<CallInst>(DI) || isa<InvokeInst>(DI)) {
798 bool Inlined = tryInlineCandidate(Candidate, InlinedCallSite);
799 if (!Inlined) {
800 // Prorate the direct callsite distribution so that it reflects real
801 // callsite counts.
803 *DI, static_cast<float>(Candidate.CallsiteCount) / SumOrigin);
804 }
805 return Inlined;
806 }
807 }
808 } else {
809 LLVM_DEBUG(dbgs() << "\nFailed to promote indirect call to "
811 Candidate.CallInstr->getName())<< " because "
812 << Reason << "\n");
813 }
814 return false;
815}
816
817bool SampleProfileLoader::shouldInlineColdCallee(CallBase &CallInst) {
818 if (!ProfileSizeInline)
819 return false;
820
821 if (CallInst.getCalledFunction() == nullptr)
822 return false;
823
824 InlineCost Cost =
825 getInlineCost(CallInst, getInlineParams(CallInst.getContext()),
826 GetTTI(*CallInst.getCaller()), GetAC, GetTLI);
827
828 if (Cost.isNever())
829 return false;
830
831 if (Cost.isAlways())
832 return true;
833
834 return Cost.getCost() <= SampleColdCallSiteThreshold;
835}
836
837void SampleProfileLoader::emitOptimizationRemarksForInlineCandidates(
838 const SmallVectorImpl<CallBase *> &Candidates, const Function &F,
839 bool Hot) {
840 for (auto *I : Candidates) {
841 Function *CalledFunction = I->getCalledFunction();
842 if (CalledFunction) {
843 ORE->emit(OptimizationRemarkAnalysis(getAnnotatedRemarkPassName(),
844 "InlineAttempt", I->getDebugLoc(),
845 I->getParent())
846 << "previous inlining reattempted for "
847 << (Hot ? "hotness: '" : "size: '")
848 << ore::NV("Callee", CalledFunction) << "' into '"
849 << ore::NV("Caller", &F) << "'");
850 }
851 }
852}
853
854void SampleProfileLoader::findExternalInlineCandidate(
855 CallBase *CB, const FunctionSamples *Samples,
856 DenseSet<GlobalValue::GUID> &InlinedGUIDs, uint64_t Threshold) {
857
858 // If ExternalInlineAdvisor(ReplayInlineAdvisor) wants to inline an external
859 // function make sure it's imported
860 if (CB && getExternalInlineAdvisorShouldInline(*CB)) {
861 // Samples may not exist for replayed function, if so
862 // just add the direct GUID and move on
863 if (!Samples) {
864 InlinedGUIDs.insert(Function::getGUIDAssumingExternalLinkage(
865 CB->getCalledFunction()->getName()));
866 return;
867 }
868 // Otherwise, drop the threshold to import everything that we can
869 Threshold = 0;
870 }
871
872 // In some rare cases, call instruction could be changed after being pushed
873 // into inline candidate queue, this is because earlier inlining may expose
874 // constant propagation which can change indirect call to direct call. When
875 // this happens, we may fail to find matching function samples for the
876 // candidate later, even if a match was found when the candidate was enqueued.
877 if (!Samples)
878 return;
879
880 // For AutoFDO profile, retrieve candidate profiles by walking over
881 // the nested inlinee profiles.
883 // Set threshold to zero to honor pre-inliner decision.
884 if (UsePreInlinerDecision)
885 Threshold = 0;
886 Samples->findInlinedFunctions(InlinedGUIDs, SymbolMap, Threshold);
887 return;
888 }
889
890 ContextTrieNode *Caller = ContextTracker->getContextNodeForProfile(Samples);
891 std::queue<ContextTrieNode *> CalleeList;
892 CalleeList.push(Caller);
893 while (!CalleeList.empty()) {
894 ContextTrieNode *Node = CalleeList.front();
895 CalleeList.pop();
896 FunctionSamples *CalleeSample = Node->getFunctionSamples();
897 // For CSSPGO profile, retrieve candidate profile by walking over the
898 // trie built for context profile. Note that also take call targets
899 // even if callee doesn't have a corresponding context profile.
900 if (!CalleeSample)
901 continue;
902
903 // If pre-inliner decision is used, honor that for importing as well.
904 bool PreInline =
905 UsePreInlinerDecision &&
907 if (!PreInline && CalleeSample->getHeadSamplesEstimate() < Threshold)
908 continue;
909
910 Function *Func = SymbolMap.lookup(CalleeSample->getFunction());
911 // Add to the import list only when it's defined out of module.
912 if (!Func || Func->isDeclaration())
913 InlinedGUIDs.insert(CalleeSample->getGUID());
914
915 // Import hot CallTargets, which may not be available in IR because full
916 // profile annotation cannot be done until backend compilation in ThinLTO.
917 for (const auto &BS : CalleeSample->getBodySamples())
918 for (const auto &TS : BS.second.getCallTargets())
919 if (TS.second > Threshold) {
920 const Function *Callee = SymbolMap.lookup(TS.first);
921 if (!Callee || Callee->isDeclaration())
922 InlinedGUIDs.insert(TS.first.getHashCode());
923 }
924
925 // Import hot child context profile associted with callees. Note that this
926 // may have some overlap with the call target loop above, but doing this
927 // based child context profile again effectively allow us to use the max of
928 // entry count and call target count to determine importing.
929 for (auto &Child : Node->getAllChildContext()) {
930 ContextTrieNode *CalleeNode = &Child.second;
931 CalleeList.push(CalleeNode);
932 }
933 }
934}
935
936/// Iteratively inline hot callsites of a function.
937///
938/// Iteratively traverse all callsites of the function \p F, so as to
939/// find out callsites with corresponding inline instances.
940///
941/// For such callsites,
942/// - If it is hot enough, inline the callsites and adds callsites of the callee
943/// into the caller. If the call is an indirect call, first promote
944/// it to direct call. Each indirect call is limited with a single target.
945///
946/// - If a callsite is not inlined, merge the its profile to the outline
947/// version (if --sample-profile-merge-inlinee is true), or scale the
948/// counters of standalone function based on the profile of inlined
949/// instances (if --sample-profile-merge-inlinee is false).
950///
951/// Later passes may consume the updated profiles.
952///
953/// \param F function to perform iterative inlining.
954/// \param InlinedGUIDs a set to be updated to include all GUIDs that are
955/// inlined in the profiled binary.
956///
957/// \returns True if there is any inline happened.
958bool SampleProfileLoader::inlineHotFunctions(
959 Function &F, DenseSet<GlobalValue::GUID> &InlinedGUIDs) {
960 // ProfAccForSymsInList is used in callsiteIsHot. The assertion makes sure
961 // Profile symbol list is ignored when profile-sample-accurate is on.
962 assert((!ProfAccForSymsInList ||
963 (!Opts.profile_sample_accurate &&
964 !F.hasFnAttribute("profile-sample-accurate"))) &&
965 "ProfAccForSymsInList should be false when profile-sample-accurate "
966 "is enabled");
967
968 MapVector<CallBase *, const FunctionSamples *> LocalNotInlinedCallSites;
969 bool Changed = false;
970 bool LocalChanged = true;
971 while (LocalChanged) {
972 LocalChanged = false;
974 for (auto &BB : F) {
975 bool Hot = false;
976 SmallVector<CallBase *, 10> AllCandidates;
977 SmallVector<CallBase *, 10> ColdCandidates;
978 for (auto &I : BB) {
979 const FunctionSamples *FS = nullptr;
980 if (auto *CB = dyn_cast<CallBase>(&I)) {
981 if (!isa<IntrinsicInst>(I)) {
982 if ((FS = findCalleeFunctionSamples(*CB))) {
983 assert((!FunctionSamples::UseMD5 || FS->GUIDToFuncNameMap) &&
984 "GUIDToFuncNameMap has to be populated");
985 AllCandidates.push_back(CB);
986 if (FS->getHeadSamplesEstimate() > 0 ||
988 LocalNotInlinedCallSites.insert({CB, FS});
989 if (callsiteIsHot(FS, PSI, ProfAccForSymsInList))
990 Hot = true;
991 else if (shouldInlineColdCallee(*CB))
992 ColdCandidates.push_back(CB);
993 } else if (getExternalInlineAdvisorShouldInline(*CB)) {
994 AllCandidates.push_back(CB);
995 }
996 }
997 }
998 }
999 if (Hot || ExternalInlineAdvisor) {
1000 CIS.insert(CIS.begin(), AllCandidates.begin(), AllCandidates.end());
1001 emitOptimizationRemarksForInlineCandidates(AllCandidates, F, true);
1002 } else {
1003 CIS.insert(CIS.begin(), ColdCandidates.begin(), ColdCandidates.end());
1004 emitOptimizationRemarksForInlineCandidates(ColdCandidates, F, false);
1005 }
1006 }
1007 for (CallBase *I : CIS) {
1008 Function *CalledFunction = I->getCalledFunction();
1009 InlineCandidate Candidate = {I, LocalNotInlinedCallSites.lookup(I),
1010 0 /* dummy count */,
1011 1.0 /* dummy distribution factor */};
1012 // Do not inline recursive calls.
1013 if (CalledFunction == &F)
1014 continue;
1015 if (I->isIndirectCall()) {
1016 uint64_t Sum;
1017 for (const auto *FS : findIndirectCallFunctionSamples(*I, Sum)) {
1018 uint64_t SumOrigin = Sum;
1019 if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
1020 findExternalInlineCandidate(I, FS, InlinedGUIDs,
1021 PSI->getOrCompHotCountThreshold());
1022 continue;
1023 }
1024 if (!callsiteIsHot(FS, PSI, ProfAccForSymsInList))
1025 continue;
1026
1027 Candidate = {I, FS, FS->getHeadSamplesEstimate(), 1.0};
1028 if (tryPromoteAndInlineCandidate(F, Candidate, SumOrigin, Sum)) {
1029 LocalNotInlinedCallSites.erase(I);
1030 LocalChanged = true;
1031 }
1032 }
1033 } else if (CalledFunction && CalledFunction->getSubprogram() &&
1034 !CalledFunction->isDeclaration()) {
1035 if (tryInlineCandidate(Candidate)) {
1036 LocalNotInlinedCallSites.erase(I);
1037 LocalChanged = true;
1038 }
1039 } else if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
1040 findExternalInlineCandidate(I, findCalleeFunctionSamples(*I),
1041 InlinedGUIDs,
1042 PSI->getOrCompHotCountThreshold());
1043 }
1044 }
1045 Changed |= LocalChanged;
1046 }
1047
1048 // For CS profile, profile for not inlined context will be merged when
1049 // base profile is being retrieved.
1051 promoteMergeNotInlinedContextSamples(LocalNotInlinedCallSites, F);
1052 return Changed;
1053}
1054
1055bool SampleProfileLoader::tryInlineCandidate(
1056 InlineCandidate &Candidate, SmallVector<CallBase *, 8> *InlinedCallSites) {
1057 // Do not attempt to inline a candidate if
1058 // --disable-sample-loader-inlining is true.
1059 if (DisableSampleProfileInlining)
1060 return false;
1061
1062 CallBase &CB = *Candidate.CallInstr;
1063 Function *CalledFunction = CB.getCalledFunction();
1064 assert(CalledFunction && "Expect a callee with definition");
1065 DebugLoc DLoc = CB.getDebugLoc();
1066 BasicBlock *BB = CB.getParent();
1067
1068 InlineCost Cost = shouldInlineCandidate(Candidate);
1069 if (Cost.isNever()) {
1070 ORE->emit(OptimizationRemarkAnalysis(getAnnotatedRemarkPassName(),
1071 "InlineFail", DLoc, BB)
1072 << "incompatible inlining");
1073 return false;
1074 }
1075
1076 if (!Cost)
1077 return false;
1078
1079 InlineFunctionInfo IFI(GetAC);
1080 IFI.UpdateProfile = false;
1081 InlineResult IR = InlineFunction(CB, IFI,
1082 /*MergeAttributes=*/true);
1083 if (!IR.isSuccess())
1084 return false;
1085
1086 // The call to InlineFunction erases I, so we can't pass it here.
1087 emitInlinedIntoBasedOnCost(*ORE, DLoc, BB, *CalledFunction, *BB->getParent(),
1088 Cost, true, getAnnotatedRemarkPassName());
1089
1090 // Now populate the list of newly exposed call sites.
1091 if (InlinedCallSites) {
1092 InlinedCallSites->clear();
1093 llvm::append_range(*InlinedCallSites, IFI.InlinedCallSites);
1094 }
1095
1097 ContextTracker->markContextSamplesInlined(Candidate.CalleeSamples);
1098 ++NumCSInlined;
1099
1100 // Prorate inlined probes for a duplicated inlining callsite which probably
1101 // has a distribution less than 100%. Samples for an inlinee should be
1102 // distributed among the copies of the original callsite based on each
1103 // callsite's distribution factor for counts accuracy. Note that an inlined
1104 // probe may come with its own distribution factor if it has been duplicated
1105 // in the inlinee body. The two factor are multiplied to reflect the
1106 // aggregation of duplication.
1107 if (Candidate.CallsiteDistribution < 1) {
1108 for (auto &I : IFI.InlinedCallSites) {
1109 if (std::optional<PseudoProbe> Probe = extractProbe(*I))
1110 setProbeDistributionFactor(*I, Probe->Factor *
1111 Candidate.CallsiteDistribution);
1112 }
1113 NumDuplicatedInlinesite++;
1114 }
1115
1116 return true;
1117}
1118
1119bool SampleProfileLoader::getInlineCandidate(InlineCandidate *NewCandidate,
1120 CallBase *CB) {
1121 assert(CB && "Expect non-null call instruction");
1122
1123 if (isa<IntrinsicInst>(CB))
1124 return false;
1125
1126 // Find the callee's profile. For indirect call, find hottest target profile.
1127 const FunctionSamples *CalleeSamples = findCalleeFunctionSamples(*CB);
1128 // If ExternalInlineAdvisor wants to inline this site, do so even
1129 // if Samples are not present.
1130 if (!CalleeSamples && !getExternalInlineAdvisorShouldInline(*CB))
1131 return false;
1132
1133 float Factor = 1.0;
1134 if (std::optional<PseudoProbe> Probe = extractProbe(*CB))
1135 Factor = Probe->Factor;
1136
1137 uint64_t CallsiteCount =
1138 CalleeSamples ? CalleeSamples->getHeadSamplesEstimate() * Factor : 0;
1139 *NewCandidate = {CB, CalleeSamples, CallsiteCount, Factor};
1140 return true;
1141}
1142
1143std::optional<InlineCost>
1144SampleProfileLoader::getExternalInlineAdvisorCost(CallBase &CB) {
1145 std::unique_ptr<InlineAdvice> Advice = nullptr;
1146 if (ExternalInlineAdvisor) {
1147 Advice = ExternalInlineAdvisor->getAdvice(CB);
1148 if (Advice) {
1149 if (!Advice->isInliningRecommended()) {
1150 Advice->recordUnattemptedInlining();
1151 return InlineCost::getNever("not previously inlined");
1152 }
1153 Advice->recordInlining();
1154 return InlineCost::getAlways("previously inlined");
1155 }
1156 }
1157
1158 return {};
1159}
1160
1161bool SampleProfileLoader::getExternalInlineAdvisorShouldInline(CallBase &CB) {
1162 std::optional<InlineCost> Cost = getExternalInlineAdvisorCost(CB);
1163 return Cost ? !!*Cost : false;
1164}
1165
1166InlineCost
1167SampleProfileLoader::shouldInlineCandidate(InlineCandidate &Candidate) {
1168 if (std::optional<InlineCost> ReplayCost =
1169 getExternalInlineAdvisorCost(*Candidate.CallInstr))
1170 return *ReplayCost;
1171 // Adjust threshold based on call site hotness, only do this for callsite
1172 // prioritized inliner because otherwise cost-benefit check is done earlier.
1173 int SampleThreshold = SampleColdCallSiteThreshold;
1174 if (CallsitePrioritizedInline) {
1175 if (Candidate.CallsiteCount > PSI->getHotCountThreshold())
1176 SampleThreshold = SampleHotCallSiteThreshold;
1177 else if (!ProfileSizeInline)
1178 return InlineCost::getNever("cold callsite");
1179 }
1180
1181 Function *Caller = Candidate.CallInstr->getCaller();
1182 Function *Callee = Candidate.CallInstr->getCalledFunction();
1183 assert(Callee && "Expect a definition for inline candidate of direct call");
1184
1185 InlineParams Params = getInlineParams(Caller->getContext());
1186 // We will ignore the threshold from inline cost, so always get full cost.
1187 Params.ComputeFullInlineCost = true;
1188 Params.AllowRecursiveCall = AllowRecursiveInline;
1189 // Checks if there is anything in the reachable portion of the callee at
1190 // this callsite that makes this inlining potentially illegal. Need to
1191 // set ComputeFullInlineCost, otherwise getInlineCost may return early
1192 // when cost exceeds threshold without checking all IRs in the callee.
1193 // The acutal cost does not matter because we only checks isNever() to
1194 // see if it is legal to inline the callsite.
1195 InlineCost Cost = getInlineCost(*Candidate.CallInstr, Callee, Params,
1196 GetTTI(*Caller), GetAC, GetTLI);
1197
1198 // Honor always inline and never inline from call analyzer
1199 if (Cost.isNever() || Cost.isAlways())
1200 return Cost;
1201
1202 // With CSSPGO, the preinliner in llvm-profgen can estimate global inline
1203 // decisions based on hotness as well as accurate function byte sizes for
1204 // given context using function/inlinee sizes from previous build. It
1205 // stores the decision in profile, and also adjust/merge context profile
1206 // aiming at better context-sensitive post-inline profile quality, assuming
1207 // all inline decision estimates are going to be honored by compiler. Here
1208 // we replay that inline decision under `sample-profile-use-preinliner`.
1209 // Note that we don't need to handle negative decision from preinliner as
1210 // context profile for not inlined calls are merged by preinliner already.
1211 if (UsePreInlinerDecision && Candidate.CalleeSamples) {
1212 // Once two node are merged due to promotion, we're losing some context
1213 // so the original context-sensitive preinliner decision should be ignored
1214 // for SyntheticContext.
1215 SampleContext &Context = Candidate.CalleeSamples->getContext();
1216 if (!Context.hasState(SyntheticContext) &&
1217 Context.hasAttribute(ContextShouldBeInlined))
1218 return InlineCost::getAlways("preinliner");
1219 }
1220
1221 // For old FDO inliner, we inline the call site if it is below hot threshold,
1222 // even if the function is hot based on sample profile data. This is to
1223 // prevent huge functions from being inlined.
1224 if (!CallsitePrioritizedInline) {
1226 }
1227
1228 // Otherwise only use the cost from call analyzer, but overwite threshold with
1229 // Sample PGO threshold.
1230 return InlineCost::get(Cost.getCost(), SampleThreshold);
1231}
1232
1233bool SampleProfileLoader::inlineHotFunctionsWithPriority(
1234 Function &F, DenseSet<GlobalValue::GUID> &InlinedGUIDs) {
1235 // ProfAccForSymsInList is used in callsiteIsHot. The assertion makes sure
1236 // Profile symbol list is ignored when profile-sample-accurate is on.
1237 assert((!ProfAccForSymsInList ||
1238 (!Opts.profile_sample_accurate &&
1239 !F.hasFnAttribute("profile-sample-accurate"))) &&
1240 "ProfAccForSymsInList should be false when profile-sample-accurate "
1241 "is enabled");
1242
1243 // Populating worklist with initial call sites from root inliner, along
1244 // with call site weights.
1245 CandidateQueue CQueue;
1246 InlineCandidate NewCandidate;
1247 for (auto &BB : F) {
1248 for (CallBase &CB : make_isa_range<CallBase>(BB)) {
1249 if (getInlineCandidate(&NewCandidate, &CB))
1250 CQueue.push(NewCandidate);
1251 }
1252 }
1253
1254 // Cap the size growth from profile guided inlining. This is needed even
1255 // though cost of each inline candidate already accounts for callee size,
1256 // because with top-down inlining, we can grow inliner size significantly
1257 // with large number of smaller inlinees each pass the cost check.
1259 "Max inline size limit should not be smaller than min inline size "
1260 "limit.");
1261 unsigned SizeLimit = F.getInstructionCount() * ProfileInlineGrowthLimit;
1262 SizeLimit = std::min(SizeLimit, (unsigned)ProfileInlineLimitMax);
1263 SizeLimit = std::max(SizeLimit, (unsigned)ProfileInlineLimitMin);
1264 if (ExternalInlineAdvisor)
1265 SizeLimit = std::numeric_limits<unsigned>::max();
1266
1267 MapVector<CallBase *, const FunctionSamples *> LocalNotInlinedCallSites;
1268
1269 // Perform iterative BFS call site prioritized inlining
1270 bool Changed = false;
1271 while (!CQueue.empty() && F.getInstructionCount() < SizeLimit) {
1272 InlineCandidate Candidate = CQueue.top();
1273 CQueue.pop();
1274 CallBase *I = Candidate.CallInstr;
1275 Function *CalledFunction = I->getCalledFunction();
1276
1277 if (CalledFunction == &F)
1278 continue;
1279 if (I->isIndirectCall()) {
1280 uint64_t Sum = 0;
1281 auto CalleeSamples = findIndirectCallFunctionSamples(*I, Sum);
1282 uint64_t SumOrigin = Sum;
1283 Sum *= Candidate.CallsiteDistribution;
1284 unsigned ICPCount = 0;
1285 for (const auto *FS : CalleeSamples) {
1286 // TODO: Consider disable pre-lTO ICP for MonoLTO as well
1287 if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
1288 findExternalInlineCandidate(I, FS, InlinedGUIDs,
1289 PSI->getOrCompHotCountThreshold());
1290 continue;
1291 }
1292 uint64_t EntryCountDistributed =
1293 FS->getHeadSamplesEstimate() * Candidate.CallsiteDistribution;
1294 // In addition to regular inline cost check, we also need to make sure
1295 // ICP isn't introducing excessive speculative checks even if individual
1296 // target looks beneficial to promote and inline. That means we should
1297 // only do ICP when there's a small number dominant targets.
1298 if (ICPCount >= Opts.sample_profile_icp_relative_hotness_skip &&
1299 EntryCountDistributed * 100 <
1300 SumOrigin * Opts.sample_profile_icp_relative_hotness)
1301 break;
1302 // TODO: Fix CallAnalyzer to handle all indirect calls.
1303 // For indirect call, we don't run CallAnalyzer to get InlineCost
1304 // before actual inlining. This is because we could see two different
1305 // types from the same definition, which makes CallAnalyzer choke as
1306 // it's expecting matching parameter type on both caller and callee
1307 // side. See example from PR18962 for the triggering cases (the bug was
1308 // fixed, but we generate different types).
1309 if (!PSI->isHotCount(EntryCountDistributed))
1310 break;
1311 SmallVector<CallBase *, 8> InlinedCallSites;
1312 // Attach function profile for promoted indirect callee, and update
1313 // call site count for the promoted inline candidate too.
1314 Candidate = {I, FS, EntryCountDistributed,
1315 Candidate.CallsiteDistribution};
1316 if (tryPromoteAndInlineCandidate(F, Candidate, SumOrigin, Sum,
1317 &InlinedCallSites)) {
1318 for (auto *CB : InlinedCallSites) {
1319 if (getInlineCandidate(&NewCandidate, CB))
1320 CQueue.emplace(NewCandidate);
1321 }
1322 ICPCount++;
1323 Changed = true;
1324 } else if (!ContextTracker) {
1325 LocalNotInlinedCallSites.insert({I, FS});
1326 }
1327 }
1328 } else if (CalledFunction && CalledFunction->getSubprogram() &&
1329 !CalledFunction->isDeclaration()) {
1330 SmallVector<CallBase *, 8> InlinedCallSites;
1331 if (tryInlineCandidate(Candidate, &InlinedCallSites)) {
1332 for (auto *CB : InlinedCallSites) {
1333 if (getInlineCandidate(&NewCandidate, CB))
1334 CQueue.emplace(NewCandidate);
1335 }
1336 Changed = true;
1337 } else if (!ContextTracker) {
1338 LocalNotInlinedCallSites.insert({I, Candidate.CalleeSamples});
1339 }
1340 } else if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
1341 findExternalInlineCandidate(I, findCalleeFunctionSamples(*I),
1342 InlinedGUIDs,
1343 PSI->getOrCompHotCountThreshold());
1344 }
1345 }
1346
1347 if (!CQueue.empty()) {
1348 if (SizeLimit == (unsigned)ProfileInlineLimitMax)
1349 ++NumCSInlinedHitMaxLimit;
1350 else if (SizeLimit == (unsigned)ProfileInlineLimitMin)
1351 ++NumCSInlinedHitMinLimit;
1352 else
1353 ++NumCSInlinedHitGrowthLimit;
1354 }
1355
1356 // For CS profile, profile for not inlined context will be merged when
1357 // base profile is being retrieved.
1359 promoteMergeNotInlinedContextSamples(LocalNotInlinedCallSites, F);
1360 return Changed;
1361}
1362
1363void SampleProfileLoader::promoteMergeNotInlinedContextSamples(
1364 MapVector<CallBase *, const FunctionSamples *> NonInlinedCallSites,
1365 const Function &F) {
1366 // Accumulate not inlined callsite information into notInlinedSamples
1367 for (const auto &Pair : NonInlinedCallSites) {
1368 CallBase *I = Pair.first;
1369 Function *Callee = I->getCalledFunction();
1370 if (!Callee || Callee->isDeclaration())
1371 continue;
1372
1373 ORE->emit(
1374 OptimizationRemarkAnalysis(getAnnotatedRemarkPassName(), "NotInline",
1375 I->getDebugLoc(), I->getParent())
1376 << "previous inlining not repeated: '" << ore::NV("Callee", Callee)
1377 << "' into '" << ore::NV("Caller", &F) << "'");
1378
1379 ++NumCSNotInlined;
1380 const FunctionSamples *FS = Pair.second;
1381 if (FS->getTotalSamples() == 0 && FS->getHeadSamplesEstimate() == 0) {
1382 continue;
1383 }
1384
1385 // Do not merge a context that is already duplicated into the base profile.
1386 if (FS->getContext().hasAttribute(sampleprof::ContextDuplicatedIntoBase))
1387 continue;
1388
1389 if (ProfileMergeInlinee) {
1390 // A function call can be replicated by optimizations like callsite
1391 // splitting or jump threading and the replicates end up sharing the
1392 // sample nested callee profile instead of slicing the original
1393 // inlinee's profile. We want to do merge exactly once by filtering out
1394 // callee profiles with a non-zero head sample count.
1395 if (FS->getHeadSamples() == 0) {
1396 // Use entry samples as head samples during the merge, as inlinees
1397 // don't have head samples.
1398 const_cast<FunctionSamples *>(FS)->addHeadSamples(
1399 FS->getHeadSamplesEstimate());
1400
1401 // Note that we have to do the merge right after processing function.
1402 // This allows OutlineFS's profile to be used for annotation during
1403 // top-down processing of functions' annotation.
1404 FunctionSamples *OutlineFS = Reader->getSamplesFor(*Callee);
1405 // If outlined function does not exist in the profile, add it to a
1406 // separate map so that it does not rehash the original profile.
1407 if (!OutlineFS)
1408 OutlineFS = &OutlineFunctionSamples[
1409 FunctionId(FunctionSamples::getCanonicalFnName(Callee->getName()))];
1410 OutlineFS->merge(*FS, 1);
1411 // Set outlined profile to be synthetic to not bias the inliner.
1412 OutlineFS->setContextSynthetic();
1413 }
1414 } else {
1415 auto pair =
1416 notInlinedCallInfo.try_emplace(Callee, NotInlinedProfileInfo{0});
1417 pair.first->second.entryCount += FS->getHeadSamplesEstimate();
1418 }
1419 }
1420}
1421
1422/// Returns the sorted CallTargetMap \p M by count in descending order.
1426 for (const auto &I : SampleRecord::sortCallTargets(M)) {
1427 R.emplace_back(
1428 InstrProfValueData{I.first.getHashCode(), I.second});
1429 }
1430 return R;
1431}
1432
1433// Generate MD_prof metadata for every branch instruction using the
1434// edge weights computed during propagation.
1435void SampleProfileLoader::generateMDProfMetadata(Function &F) {
1436 // Generate MD_prof metadata for every branch instruction using the
1437 // edge weights computed during propagation.
1438 LLVM_DEBUG(dbgs() << "\nPropagation complete. Setting branch weights\n");
1439 LLVMContext &Ctx = F.getContext();
1440 MDBuilder MDB(Ctx);
1441 for (auto &BI : F) {
1442 BasicBlock *BB = &BI;
1443
1444 if (BlockWeights[BB]) {
1445 for (auto &I : *BB) {
1446 if (!isa<CallInst>(I) && !isa<InvokeInst>(I))
1447 continue;
1449 const DebugLoc &DLoc = I.getDebugLoc();
1450 if (!DLoc)
1451 continue;
1452 const DILocation *DIL = DLoc;
1453 const FunctionSamples *FS = findFunctionSamples(I);
1454 if (!FS)
1455 continue;
1457 ErrorOr<SampleRecord::CallTargetMap> T =
1458 FS->findCallTargetMapAt(CallSite);
1459 if (!T || T.get().empty())
1460 continue;
1462 // Prorate the callsite counts based on the pre-ICP distribution
1463 // factor to reflect what is already done to the callsite before
1464 // ICP, such as calliste cloning.
1465 if (std::optional<PseudoProbe> Probe = extractProbe(I)) {
1466 if (Probe->Factor < 1)
1467 T = SampleRecord::adjustCallTargets(T.get(), Probe->Factor);
1468 }
1469 }
1470 SmallVector<InstrProfValueData, 2> SortedCallTargets =
1472 uint64_t Sum = 0;
1473 for (const auto &C : T.get())
1474 Sum += C.second;
1475 // With CSSPGO all indirect call targets are counted torwards the
1476 // original indirect call site in the profile, including both
1477 // inlined and non-inlined targets.
1479 if (const FunctionSamplesMap *M =
1480 FS->findFunctionSamplesMapAt(CallSite)) {
1481 for (const auto &NameFS : *M)
1482 Sum += NameFS.second.getHeadSamplesEstimate();
1483 }
1484 }
1485 if (Sum)
1486 updateIDTMetaData(Opts, I, SortedCallTargets, Sum);
1487 else if (Opts.overwrite_existing_weights)
1488 I.setMetadata(LLVMContext::MD_prof, nullptr);
1489 } else if (!isa<IntrinsicInst>(&I)) {
1491 I, ArrayRef<uint32_t>{static_cast<uint32_t>(BlockWeights[BB])},
1492 /*IsExpected=*/false);
1493 }
1494 }
1495 } else if (Opts.overwrite_existing_weights ||
1496 Opts.profile_sample_block_accurate) {
1497 // Set profile metadata (possibly annotated by LTO prelink) to zero or
1498 // clear it for cold code.
1499 for (auto &I : *BB) {
1500 if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
1502 I.setMetadata(LLVMContext::MD_prof, nullptr);
1503 } else {
1504 setBranchWeights(I, ArrayRef<uint32_t>{uint32_t(0)},
1505 /*IsExpected=*/false);
1506 }
1507 }
1508 }
1509 }
1510
1511 Instruction *TI = BB->getTerminator();
1512 if (TI->getNumSuccessors() == 1)
1513 continue;
1514 if (!isa<CondBrInst>(TI) && !isa<SwitchInst>(TI) &&
1516 continue;
1517
1518 DebugLoc BranchLoc = TI->getDebugLoc();
1519 LLVM_DEBUG(dbgs() << "\nGetting weights for branch at line "
1520 << ((BranchLoc) ? Twine(BranchLoc.getLine())
1521 : Twine("<UNKNOWN LOCATION>"))
1522 << ".\n");
1523 SmallVector<uint32_t, 4> Weights;
1524 uint32_t MaxWeight = 0;
1525 Instruction *MaxDestInst;
1526 // Since profi treats multiple edges (multiway branches) as a single edge,
1527 // we need to distribute the computed weight among the branches. We do
1528 // this by evenly splitting the edge weight among destinations.
1529 DenseMap<const BasicBlock *, uint64_t> EdgeMultiplicity;
1530 std::vector<uint64_t> EdgeIndex;
1532 EdgeIndex.resize(TI->getNumSuccessors());
1533 for (unsigned I = 0; I < TI->getNumSuccessors(); ++I) {
1534 const BasicBlock *Succ = TI->getSuccessor(I);
1535 EdgeIndex[I] = EdgeMultiplicity[Succ];
1536 EdgeMultiplicity[Succ]++;
1537 }
1538 }
1539 for (unsigned I = 0; I < TI->getNumSuccessors(); ++I) {
1540 BasicBlock *Succ = TI->getSuccessor(I);
1541 Edge E = std::make_pair(BB, Succ);
1542 uint64_t Weight = EdgeWeights[E];
1543 LLVM_DEBUG(dbgs() << "\t"; printEdgeWeight(dbgs(), E));
1544 // Use uint32_t saturated arithmetic to adjust the incoming weights,
1545 // if needed. Sample counts in profiles are 64-bit unsigned values,
1546 // but internally branch weights are expressed as 32-bit values.
1547 if (Weight > std::numeric_limits<uint32_t>::max()) {
1548 LLVM_DEBUG(dbgs() << " (saturated due to uint32_t overflow)\n");
1549 Weight = std::numeric_limits<uint32_t>::max();
1550 }
1551 if (!SampleProfileUseProfi) {
1552 // Weight is added by one to avoid propagation errors introduced by
1553 // 0 weights.
1554 Weights.push_back(static_cast<uint32_t>(
1555 Weight == std::numeric_limits<uint32_t>::max() ? Weight
1556 : Weight + 1));
1557 } else {
1558 // Profi creates proper weights that do not require "+1" adjustments but
1559 // we evenly split the weight among branches with the same destination.
1560 uint64_t W = Weight / EdgeMultiplicity[Succ];
1561 // Rounding up, if needed, so that first branches are hotter.
1562 if (EdgeIndex[I] < Weight % EdgeMultiplicity[Succ])
1563 W++;
1564 Weights.push_back(static_cast<uint32_t>(W));
1565 }
1566 if (Weight != 0) {
1567 if (Weight > MaxWeight) {
1568 MaxWeight = Weight;
1569 MaxDestInst = &*Succ->getFirstNonPHIOrLifetime();
1570 }
1571 }
1572 }
1573
1574 misexpect::checkExpectAnnotations(*TI, Weights, /*IsFrontend=*/false);
1575
1576 uint64_t TempWeight;
1577 // Only set weights if there is at least one non-zero weight.
1578 // In any other case, let the analyzer set weights.
1579 // Do not set weights if the weights are present unless under
1580 // OverwriteExistingWeights. In ThinLTO, the profile annotation is done
1581 // twice. If the first annotation already set the weights, the second pass
1582 // does not need to set it. With OverwriteExistingWeights, Blocks with zero
1583 // weight should have their existing metadata (possibly annotated by LTO
1584 // prelink) cleared.
1585 if (MaxWeight > 0 && (!TI->extractProfTotalWeight(TempWeight) ||
1586 Opts.overwrite_existing_weights)) {
1587 LLVM_DEBUG(dbgs() << "SUCCESS. Found non-zero weights.\n");
1588 setBranchWeights(*TI, Weights, /*IsExpected=*/false);
1589 ORE->emit([&]() {
1590 return OptimizationRemark(DEBUG_TYPE, "PopularDest", MaxDestInst)
1591 << "most popular destination for conditional branches at "
1592 << ore::NV("CondBranchesLoc", BranchLoc);
1593 });
1594 } else {
1595 if (Opts.overwrite_existing_weights) {
1596 TI->setMetadata(LLVMContext::MD_prof, nullptr);
1597 LLVM_DEBUG(dbgs() << "CLEARED. All branch weights are zero.\n");
1598 } else {
1599 LLVM_DEBUG(dbgs() << "SKIPPED. All branch weights are zero.\n");
1600 }
1601 }
1602 }
1603}
1604
1605/// Once all the branch weights are computed, we emit the MD_prof
1606/// metadata on BB using the computed values for each of its branches.
1607///
1608/// \param F The function to query.
1609///
1610/// \returns true if \p F was modified. Returns false, otherwise.
1611bool SampleProfileLoader::emitAnnotations(Function &F) {
1612 bool Changed = false;
1613
1615 LLVM_DEBUG({
1616 if (!ProbeManager->getDesc(F))
1617 dbgs() << "Probe descriptor missing for Function " << F.getName()
1618 << "\n";
1619 });
1620
1621 if (ProbeManager->profileIsValid(F, *Samples)) {
1622 ++NumMatchedProfile;
1623 } else {
1624 ++NumMismatchedProfile;
1625 LLVM_DEBUG(
1626 dbgs() << "Profile is invalid due to CFG mismatch for Function "
1627 << F.getName() << "\n");
1628 if (!SalvageStaleProfile)
1629 return false;
1630 }
1631 } else {
1632 if (getFunctionLoc(F) == 0)
1633 return false;
1634
1635 LLVM_DEBUG(dbgs() << "Line number for the first instruction in "
1636 << F.getName() << ": " << getFunctionLoc(F) << "\n");
1637 }
1638
1639 DenseSet<GlobalValue::GUID> InlinedGUIDs;
1640 if (CallsitePrioritizedInline)
1641 Changed |= inlineHotFunctionsWithPriority(F, InlinedGUIDs);
1642 else
1643 Changed |= inlineHotFunctions(F, InlinedGUIDs);
1644
1645 Changed |= computeAndPropagateWeights(F, InlinedGUIDs);
1646
1647 if (Changed)
1648 generateMDProfMetadata(F);
1649
1650 emitCoverageRemarks(F);
1651 return Changed;
1652}
1653
1654std::unique_ptr<ProfiledCallGraph>
1655SampleProfileLoader::buildProfiledCallGraph(Module &M) {
1656 std::unique_ptr<ProfiledCallGraph> ProfiledCG;
1658 ProfiledCG = std::make_unique<ProfiledCallGraph>(*ContextTracker);
1659 else
1660 ProfiledCG = std::make_unique<ProfiledCallGraph>(Reader->getProfiles());
1661
1662 // Add all functions into the profiled call graph even if they are not in
1663 // the profile. This makes sure functions missing from the profile still
1664 // gets a chance to be processed.
1665 for (Function &F : M) {
1667 continue;
1668 ProfiledCG->addProfiledFunction(
1670 }
1671
1672 return ProfiledCG;
1673}
1674
1675std::vector<Function *>
1676SampleProfileLoader::buildFunctionOrder(Module &M, LazyCallGraph &CG) {
1677 std::vector<Function *> FunctionOrderList;
1678 FunctionOrderList.reserve(M.size());
1679
1680 if (!Opts.sample_profile_top_down_load && Opts.use_profiled_call_graph)
1681 errs() << "WARNING: -use-profiled-call-graph ignored, should be used "
1682 "together with -sample-profile-top-down-load.\n";
1683
1684 if (!Opts.sample_profile_top_down_load) {
1685 if (ProfileMergeInlinee) {
1686 // Disable ProfileMergeInlinee if profile is not loaded in top down order,
1687 // because the profile for a function may be used for the profile
1688 // annotation of its outline copy before the profile merging of its
1689 // non-inlined inline instances, and that is not the way how
1690 // ProfileMergeInlinee is supposed to work.
1691 ProfileMergeInlinee = false;
1692 }
1693
1694 for (Function &F : M)
1696 FunctionOrderList.push_back(&F);
1697 return FunctionOrderList;
1698 }
1699
1700 if (Opts.use_profiled_call_graph) {
1701 // Use profiled call edges to augment the top-down order. There are cases
1702 // that the top-down order computed based on the static call graph doesn't
1703 // reflect real execution order. For example
1704 //
1705 // 1. Incomplete static call graph due to unknown indirect call targets.
1706 // Adjusting the order by considering indirect call edges from the
1707 // profile can enable the inlining of indirect call targets by allowing
1708 // the caller processed before them.
1709 // 2. Mutual call edges in an SCC. The static processing order computed for
1710 // an SCC may not reflect the call contexts in the context-sensitive
1711 // profile, thus may cause potential inlining to be overlooked. The
1712 // function order in one SCC is being adjusted to a top-down order based
1713 // on the profile to favor more inlining. This is only a problem with CS
1714 // profile.
1715 // 3. Transitive indirect call edges due to inlining. When a callee function
1716 // (say B) is inlined into a caller function (say A) in LTO prelink,
1717 // every call edge originated from the callee B will be transferred to
1718 // the caller A. If any transferred edge (say A->C) is indirect, the
1719 // original profiled indirect edge B->C, even if considered, would not
1720 // enforce a top-down order from the caller A to the potential indirect
1721 // call target C in LTO postlink since the inlined callee B is gone from
1722 // the static call graph.
1723 // 4. #3 can happen even for direct call targets, due to functions defined
1724 // in header files. A header function (say A), when included into source
1725 // files, is defined multiple times but only one definition survives due
1726 // to ODR. Therefore, the LTO prelink inlining done on those dropped
1727 // definitions can be useless based on a local file scope. More
1728 // importantly, the inlinee (say B), once fully inlined to a
1729 // to-be-dropped A, will have no profile to consume when its outlined
1730 // version is compiled. This can lead to a profile-less prelink
1731 // compilation for the outlined version of B which may be called from
1732 // external modules. while this isn't easy to fix, we rely on the
1733 // postlink AutoFDO pipeline to optimize B. Since the survived copy of
1734 // the A can be inlined in its local scope in prelink, it may not exist
1735 // in the merged IR in postlink, and we'll need the profiled call edges
1736 // to enforce a top-down order for the rest of the functions.
1737 //
1738 // Considering those cases, a profiled call graph completely independent of
1739 // the static call graph is constructed based on profile data, where
1740 // function objects are not even needed to handle case #3 and case 4.
1741 //
1742 // Note that static callgraph edges are completely ignored since they
1743 // can be conflicting with profiled edges for cyclic SCCs and may result in
1744 // an SCC order incompatible with profile-defined one. Using strictly
1745 // profile order ensures a maximum inlining experience. On the other hand,
1746 // static call edges are not so important when they don't correspond to a
1747 // context in the profile.
1748
1749 std::unique_ptr<ProfiledCallGraph> ProfiledCG = buildProfiledCallGraph(M);
1750 scc_iterator<ProfiledCallGraph *> CGI = scc_begin(ProfiledCG.get());
1751 while (!CGI.isAtEnd()) {
1752 auto Range = *CGI;
1753 if (SortProfiledSCC) {
1754 // Sort nodes in one SCC based on callsite hotness.
1755 scc_member_iterator<ProfiledCallGraph *> SI(*CGI);
1756 Range = *SI;
1757 }
1758 for (auto *Node : Range) {
1759 Function *F = SymbolMap.lookup(Node->Name);
1760 if (F && !skipProfileForFunction(*F))
1761 FunctionOrderList.push_back(F);
1762 }
1763 ++CGI;
1764 }
1765 std::reverse(FunctionOrderList.begin(), FunctionOrderList.end());
1766 } else
1767 buildTopDownFuncOrder(CG, FunctionOrderList);
1768
1769 LLVM_DEBUG({
1770 dbgs() << "Function processing order:\n";
1771 for (auto F : FunctionOrderList) {
1772 dbgs() << F->getName() << "\n";
1773 }
1774 });
1775
1776 return FunctionOrderList;
1777}
1778
1779bool SampleProfileLoader::doInitialization(Module &M,
1781 auto &Ctx = M.getContext();
1782
1783 auto ReaderOrErr = SampleProfileReader::create(
1784 Filename, Ctx, *FS, FSDiscriminatorPass::Base, RemappingFilename);
1785 if (std::error_code EC = ReaderOrErr.getError()) {
1786 std::string Msg = "Could not open profile: " + EC.message();
1787 Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg));
1788 return false;
1789 }
1790 Reader = std::move(ReaderOrErr.get());
1791 Reader->setSkipFlatProf(LTOPhase == ThinOrFullLTOPhase::ThinLTOPostLink);
1792 // set module before reading the profile so reader may be able to only
1793 // read the function profiles which are used by the current module.
1794 Reader->setModule(&M);
1795 if (std::error_code EC = Reader->read()) {
1796 std::string Msg = "profile reading failed: " + EC.message();
1797 Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg));
1798 return false;
1799 }
1800
1801 PSL = Reader->getProfileSymbolList();
1802
1803 DisableSampleProfileInlining =
1804 !valueOr(Opts.sample_loader_inlining, !DisableSampleProfileInlining);
1805
1806 if (UseFlattenedProfile)
1807 ProfileConverter::flattenProfile(Reader->getProfiles(),
1808 Reader->profileIsCS());
1809
1810 // While profile-sample-accurate is on, ignore symbol list.
1811 ProfAccForSymsInList = Opts.profile_accurate_for_symsinlist && PSL &&
1812 !Opts.profile_sample_accurate;
1813 if (ProfAccForSymsInList)
1814 CoverageTracker.setProfAccForSymsInList(true);
1815
1816 if (FAM && !Opts.sample_profile_inline_replay.empty()) {
1817 ExternalInlineAdvisor = getReplayInlineAdvisor(
1818 M, *FAM, Ctx, /*OriginalAdvisor=*/nullptr,
1819 ReplayInlinerSettings{Opts.sample_profile_inline_replay,
1820 Opts.sample_profile_inline_replay_scope,
1821 Opts.sample_profile_inline_replay_fallback,
1822 {Opts.sample_profile_inline_replay_format}},
1823 /*EmitRemarks=*/false,
1824 InlineContext{LTOPhase, InlinePass::ReplaySampleProfileInliner});
1825 }
1826
1827 // Apply tweaks if context-sensitive or probe-based profile is available.
1828 if (Reader->profileIsCS() || Reader->profileIsPreInlined() ||
1829 Reader->profileIsProbeBased()) {
1833 SampleProfileUseProfi = true;
1836 // Enable priority-base inliner and size inline by default for CSSPGO.
1837 ProfileSizeInline = valueOr(Opts.sample_profile_inline_size, true);
1838 CallsitePrioritizedInline =
1839 valueOr(Opts.sample_profile_prioritized_inline, true);
1840 // For CSSPGO, we also allow recursive inline to best use context profile.
1841 AllowRecursiveInline = valueOr(Opts.sample_profile_recursive_inline, true);
1842
1843 if (Reader->profileIsPreInlined())
1844 UsePreInlinerDecision = valueOr(Opts.sample_profile_use_preinliner, true);
1845
1846 // Enable stale profile matching by default for probe-based profile.
1847 // Currently the matching relies on if the checksum mismatch is detected,
1848 // which is currently only available for pseudo-probe mode. Removing the
1849 // checksum check could cause regressions for some cases, so further tuning
1850 // might be needed if we want to enable it for all cases.
1851 if (Reader->profileIsProbeBased()) {
1852 SalvageStaleProfile = valueOr(Opts.salvage_stale_profile, true);
1853 SalvageUnusedProfile = valueOr(Opts.salvage_unused_profile, true);
1854 }
1855
1856 if (!Reader->profileIsCS()) {
1857 // Non-CS profile should be fine without a function size budget for the
1858 // inliner since the contexts in the profile are either all from inlining
1859 // in the prevoius build or pre-computed by the preinliner with a size
1860 // cap, thus they are bounded.
1861 if (!ProfileInlineLimitMin.getNumOccurrences())
1862 ProfileInlineLimitMin = std::numeric_limits<unsigned>::max();
1863 if (!ProfileInlineLimitMax.getNumOccurrences())
1864 ProfileInlineLimitMax = std::numeric_limits<unsigned>::max();
1865 }
1866 }
1867
1868 if (Reader->profileIsCS()) {
1869 // Tracker for profiles under different context
1870 ContextTracker = std::make_unique<SampleContextTracker>(
1871 Reader->getProfiles(), &GUIDToFuncNameMap);
1872 }
1873
1874 // Load pseudo probe descriptors for probe-based function samples.
1875 if (Reader->profileIsProbeBased()) {
1876 ProbeManager = std::make_unique<PseudoProbeManager>(M);
1877 if (!ProbeManager->moduleIsProbed(M)) {
1878 const char *Msg =
1879 "Pseudo-probe-based profile requires SampleProfileProbePass";
1880 Ctx.diagnose(DiagnosticInfoSampleProfile(M.getModuleIdentifier(), Msg,
1881 DS_Warning));
1882 return false;
1883 }
1884 }
1885
1886 if (Opts.report_profile_staleness || Opts.persist_profile_staleness ||
1887 SalvageStaleProfile) {
1888 MatchingManager = std::make_unique<SampleProfileMatcher>(
1889 Opts, M, *Reader, CG, ProbeManager.get(), LTOPhase, SymbolMap, PSL,
1890 FuncNameToProfNameMap, SalvageStaleProfile, SalvageUnusedProfile);
1891 }
1892
1893 return true;
1894}
1895
1896// Note that this is a module-level check. Even if one module is errored out,
1897// the entire build will be errored out. However, the user could make big
1898// changes to functions in single module but those changes might not be
1899// performance significant to the whole binary. Therefore, to avoid those false
1900// positives, we select a reasonable big set of hot functions that are supposed
1901// to be globally performance significant, only compute and check the mismatch
1902// within those functions. The function selection is based on two criteria:
1903// 1) The function is hot enough, which is tuned by a hotness-based
1904// flag(HotFuncCutoffForStalenessError). 2) The num of function is large enough
1905// which is tuned by the MinfuncsForStalenessError flag.
1906bool SampleProfileLoader::rejectHighStalenessProfile(
1907 Module &M, ProfileSummaryInfo *PSI, const SampleProfileMap &Profiles) {
1909 "Only support for probe-based profile");
1910 uint64_t TotalHotFunc = 0;
1911 uint64_t NumMismatchedFunc = 0;
1912 for (const auto &I : Profiles) {
1913 const auto &FS = I.second;
1914 const auto *FuncDesc = ProbeManager->getDesc(FS.getGUID());
1915 if (!FuncDesc)
1916 continue;
1917
1918 // Use a hotness-based threshold to control the function selection.
1919 if (!PSI->isHotCountNthPercentile(Opts.hot_func_cutoff_for_staleness_error,
1920 FS.getTotalSamples()))
1921 continue;
1922
1923 TotalHotFunc++;
1924 if (ProbeManager->profileIsHashMismatched(*FuncDesc, FS) &&
1925 !ProbeManager->probeFromWeakSymbol(FS.getGUID()))
1926 NumMismatchedFunc++;
1927 }
1928 // Make sure that the num of selected function is not too small to distinguish
1929 // from the user's benign changes.
1930 if (TotalHotFunc < Opts.min_functions_for_staleness_error)
1931 return false;
1932
1933 // Finally check the mismatch percentage against the threshold.
1934 if (NumMismatchedFunc * 100 >=
1935 TotalHotFunc * Opts.percent_mismatch_for_staleness_error) {
1936 auto &Ctx = M.getContext();
1937 const char *Msg =
1938 "The input profile significantly mismatches current source code. "
1939 "Please recollect profile to avoid performance regression.";
1940 Ctx.diagnose(DiagnosticInfoSampleProfile(M.getModuleIdentifier(), Msg));
1941 return true;
1942 }
1943 return false;
1944}
1945
1946void SampleProfileLoader::removePseudoProbeInstsDiscriminator(Module &M) {
1947 for (auto &F : M) {
1948 std::vector<Instruction *> InstsToDel;
1949 for (auto &BB : F) {
1950 for (auto &I : BB) {
1951 if (isa<PseudoProbeInst>(&I))
1952 InstsToDel.push_back(&I);
1953 else if (isa<CallBase>(&I))
1954 if (const DILocation *DIL = I.getDebugLoc().get()) {
1955 // Restore dwarf discriminator for call.
1956 unsigned Discriminator = DIL->getDiscriminator();
1957 if (DILocation::isPseudoProbeDiscriminator(Discriminator)) {
1958 std::optional<uint32_t> DwarfDiscriminator =
1960 Discriminator);
1961 I.setDebugLoc(
1962 DIL->cloneWithDiscriminator(DwarfDiscriminator.value_or(0)));
1963 }
1964 }
1965 }
1966 }
1967 for (auto *I : InstsToDel)
1968 I->eraseFromParent();
1969 }
1970}
1971
1972bool SampleProfileLoader::runOnModule(Module &M, ModuleAnalysisManager &AM,
1973 ProfileSummaryInfo *_PSI) {
1974 GUIDToFuncNameMapper Mapper(M, *Reader, GUIDToFuncNameMap);
1975
1976 PSI = _PSI;
1977 if (M.getProfileSummary(/* IsCS */ false) == nullptr) {
1978 M.setProfileSummary(Reader->getSummary().getMD(M.getContext()),
1980 PSI->refresh();
1981 }
1982
1984 rejectHighStalenessProfile(M, PSI, Reader->getProfiles()))
1985 return false;
1986
1987 auto Remapper = Reader->getRemapper();
1988 // Populate the symbol map.
1989 for (const auto &N_F : M.getValueSymbolTable()) {
1990 StringRef OrigName = N_F.getKey();
1991 Function *F = dyn_cast<Function>(N_F.getValue());
1992 if (F == nullptr || OrigName.empty())
1993 continue;
1994 SymbolMap[FunctionId(OrigName)] = F;
1995 StringRef NewName = FunctionSamples::getCanonicalFnName(*F);
1996 if (OrigName != NewName && !NewName.empty()) {
1997 auto r = SymbolMap.emplace(FunctionId(NewName), F);
1998 // Failiing to insert means there is already an entry in SymbolMap,
1999 // thus there are multiple functions that are mapped to the same
2000 // stripped name. In this case of name conflicting, set the value
2001 // to nullptr to avoid confusion.
2002 if (!r.second)
2003 r.first->second = nullptr;
2004 OrigName = NewName;
2005 }
2006 // Insert the remapped names into SymbolMap.
2007 if (Remapper) {
2008 if (auto MapName = Remapper->lookUpNameInProfile(OrigName)) {
2009 if (*MapName != OrigName && !MapName->empty())
2010 SymbolMap.emplace(FunctionId(*MapName), F);
2011 }
2012 }
2013 }
2014
2015 // Stale profile matching.
2016 if (Opts.report_profile_staleness || Opts.persist_profile_staleness ||
2017 SalvageStaleProfile) {
2018 MatchingManager->runOnModule();
2019 MatchingManager->clearMatchingData();
2020 }
2021 assert(SymbolMap.count(FunctionId()) == 0 &&
2022 "No empty StringRef should be added in SymbolMap");
2023 assert((SalvageUnusedProfile || FuncNameToProfNameMap.empty()) &&
2024 "FuncNameToProfNameMap is not empty when --salvage-unused-profile is "
2025 "not enabled");
2026
2027 bool retval = false;
2028 for (auto *F : buildFunctionOrder(M, CG)) {
2029 assert(!F->isDeclaration());
2030 clearFunctionData();
2031 retval |= runOnFunction(*F, AM);
2032 }
2033
2034 // Account for cold calls not inlined....
2036 for (const auto &[Fn, Info] : notInlinedCallInfo)
2037 updateProfileCallee(Fn, Info.entryCount);
2038
2039 if (Opts.sample_profile_remove_probe &&
2041 removePseudoProbeInstsDiscriminator(M);
2042 if (auto *FuncInfo = M.getNamedMetadata(PseudoProbeDescMetadataName))
2043 M.eraseNamedMetadata(FuncInfo);
2044 }
2045
2046 return retval;
2047}
2048
2049bool SampleProfileLoader::runOnFunction(Function &F,
2051 LLVM_DEBUG(dbgs() << "\n\nProcessing Function " << F.getName() << "\n");
2052 DILocation2SampleMap.clear();
2053 // By default the entry count is initialized to -1, which will be treated
2054 // conservatively by getEntryCount as the same as unknown (None). This is
2055 // to avoid newly added code to be treated as cold. If we have samples
2056 // this will be overwritten in emitAnnotations.
2057 uint64_t initialEntryCount = -1;
2058
2059 ProfAccForSymsInList = Opts.profile_accurate_for_symsinlist && PSL;
2060 if (Opts.profile_sample_accurate ||
2061 F.hasFnAttribute("profile-sample-accurate")) {
2062 // initialize all the function entry counts to 0. It means all the
2063 // functions without profile will be regarded as cold.
2064 initialEntryCount = 0;
2065 // profile-sample-accurate is a user assertion which has a higher precedence
2066 // than symbol list. When profile-sample-accurate is on, ignore symbol list.
2067 ProfAccForSymsInList = false;
2068 }
2069 CoverageTracker.setProfAccForSymsInList(ProfAccForSymsInList);
2070
2071 // PSL -- profile symbol list include all the symbols in sampled binary.
2072 // If ProfileAccurateForSymsInList is enabled, PSL is used to treat
2073 // old functions without samples being cold, without having to worry
2074 // about new and hot functions being mistakenly treated as cold.
2075 if (ProfAccForSymsInList) {
2076 // Initialize the entry count to 0 for functions in the list.
2077 if (PSL->contains(F.getName()))
2078 initialEntryCount = 0;
2079
2080 // Function in the symbol list but without sample will be regarded as
2081 // cold. To minimize the potential negative performance impact it could
2082 // have, we want to be a little conservative here saying if a function
2083 // shows up in the profile, no matter as outline function, inline instance
2084 // or call targets, treat the function as not being cold. This will handle
2085 // the cases such as most callsites of a function are inlined in sampled
2086 // binary but not inlined in current build (because of source code drift,
2087 // imprecise debug information, or the callsites are all cold individually
2088 // but not cold accumulatively...), so the outline function showing up as
2089 // cold in sampled binary will actually not be cold after current build.
2090 StringRef CanonName = FunctionSamples::getCanonicalFnName(F);
2092 ? Reader->contains(
2093 Function::getGUIDAssumingExternalLinkage(CanonName))
2094 : Reader->contains(CanonName))
2095 initialEntryCount = -1;
2096 }
2097
2098 // Initialize entry count when the function has no existing entry
2099 // count value.
2100 if (!F.getEntryCount())
2101 F.setEntryCount(initialEntryCount);
2102 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(*F.getParent())
2103 .getManager();
2104 ORE = &FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
2105
2107 Samples = ContextTracker->getBaseSamplesFor(F);
2108 else {
2109 Samples = Reader->getSamplesFor(F);
2110 // Try search in previously inlined functions that were split or duplicated
2111 // into base.
2112 if (!Samples) {
2113 StringRef CanonName = FunctionSamples::getCanonicalFnName(F);
2114 auto It = OutlineFunctionSamples.find(FunctionId(CanonName));
2115 if (It != OutlineFunctionSamples.end()) {
2116 Samples = &It->second;
2117 } else if (auto Remapper = Reader->getRemapper()) {
2118 if (auto RemppedName = Remapper->lookUpNameInProfile(CanonName)) {
2119 It = OutlineFunctionSamples.find(FunctionId(*RemppedName));
2120 if (It != OutlineFunctionSamples.end())
2121 Samples = &It->second;
2122 }
2123 }
2124 }
2125 }
2126
2127 if (Samples && !Samples->empty())
2128 return emitAnnotations(F);
2129 return false;
2130}
2134
2136 std::string File, std::string RemappingFile, ThinOrFullLTOPhase LTOPhase,
2137 IntrusiveRefCntPtr<vfs::FileSystem> FS, bool DisableSampleProfileInlining,
2138 bool UseFlattenedProfile)
2139 : ProfileFileName(File), ProfileRemappingFileName(RemappingFile),
2140 LTOPhase(LTOPhase), FS(std::move(FS)),
2141 DisableSampleProfileInlining(DisableSampleProfileInlining),
2142 UseFlattenedProfile(UseFlattenedProfile) {}
2143
2148
2149 auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
2150 return FAM.getResult<AssumptionAnalysis>(F);
2151 };
2152 auto GetTTI = [&](Function &F) -> TargetTransformInfo & {
2153 return FAM.getResult<TargetIRAnalysis>(F);
2154 };
2155 auto GetTLI = [&](Function &F) -> const TargetLibraryInfo & {
2156 return FAM.getResult<TargetLibraryAnalysis>(F);
2157 };
2158
2159 if (!FS)
2162
2163 const IPOOptions &Opts = getIPOOptions(M);
2164 SampleProfileLoader SampleLoader(
2165 Opts,
2166 ProfileFileName.empty() ? Opts.sample_profile_file
2167 : StringRef(ProfileFileName),
2168 ProfileRemappingFileName.empty() ? Opts.sample_profile_remapping_file
2169 : StringRef(ProfileRemappingFileName),
2170 LTOPhase, FS, GetAssumptionCache, GetTTI, GetTLI, CG,
2171 DisableSampleProfileInlining, UseFlattenedProfile);
2172 if (!SampleLoader.doInitialization(M, &FAM))
2173 return PreservedAnalyses::all();
2174
2176 if (!SampleLoader.runOnModule(M, AM, PSI))
2177 return PreservedAnalyses::all();
2178
2179 return PreservedAnalyses::none();
2180}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
Function Alias Analysis false
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
static bool runOnFunction(Function &F, bool PostInlining)
Provides ErrorOr<T> smart pointer.
#define DEBUG_TYPE
static cl::opt< unsigned > SizeLimit("eif-limit", cl::init(6), cl::Hidden, cl::desc("Size limit in Hexagon early if-conversion"))
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
static LVReader * CurrentReader
Definition LVReader.cpp:179
Implements a lazy call graph analysis and related passes for the new pass manager.
Legalize the Machine IR a function s Machine IR
Definition Legalizer.cpp:85
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
static const Function * getCalledFunction(const Value *V)
#define T
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static constexpr StringLiteral Filename
FunctionAnalysisManager FAM
This file defines the PriorityQueue class.
This file contains the declarations for profiling metadata utility functions.
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
const char * Msg
std::pair< BasicBlock *, BasicBlock * > Edge
This file provides the interface for context-sensitive profile tracker used by CSSPGO.
This file provides the interface for the sampled PGO profile loader base implementation.
This file provides the utility functions for the sampled PGO loader base implementation.
This file provides the interface for SampleProfileMatcher.
This file provides the interface for the pseudo probe implementation for AutoFDO.
static void updateIDTMetaData(const IPOOptions &Opts, Instruction &Inst, const SmallVectorImpl< InstrProfValueData > &CallTargets, uint64_t Sum)
Update indirect call target profile metadata for Inst.
static bool doesHistoryAllowICP(const IPOOptions &Opts, const Instruction &Inst, StringRef Candidate)
Check whether the indirect call promotion history of Inst allows the promotion for Candidate.
static SmallVector< InstrProfValueData, 2 > GetSortedValueDataFromCallTargets(const SampleRecord::CallTargetMap &M)
Returns the sorted CallTargetMap M by count in descending order.
#define CSINLINE_DEBUG
This file provides the interface for the sampled PGO loader pass.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
This pass exposes codegen information to IR-level passes.
Defines the virtual file system interface vfs::FileSystem.
Value * RHS
Value * LHS
bool empty() const
Returns true if the analysis manager has an empty results cache.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
static bool isPseudoProbeDiscriminator(unsigned Discriminator)
const DILocation * cloneWithDiscriminator(unsigned Discriminator) const
Returns a new DILocation with updated Discriminator.
A debug info location.
Definition DebugLoc.h:126
LLVM_ABI unsigned getLine() const
Definition DebugLoc.cpp:43
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:856
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
Represents either an error or a value T.
Definition ErrorOr.h:56
DISubprogram * getSubprogram() const
Get the attached subprogram.
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
Definition Globals.cpp:80
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:408
static InlineCost getNever(const char *Reason, std::optional< CostBenefitPair > CostBenefit=std::nullopt)
Definition InlineCost.h:135
static InlineCost getAlways(const char *Reason, std::optional< CostBenefitPair > CostBenefit=std::nullopt)
Definition InlineCost.h:130
static InlineCost get(int Cost, int Threshold, int StaticBonus=0)
Definition InlineCost.h:124
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI bool extractProfTotalWeight(uint64_t &TotalVal) const
Retrieve total raw weight values of a branch.
LLVM_ABI BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
An analysis pass which computes the call graph for a module.
A lazily constructed view of the call graph of a module.
ValueT lookup(const KeyT &Key) const
Definition MapVector.h:111
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition MapVector.h:127
VectorType::iterator erase(typename VectorType::iterator Iterator)
Remove the element given by Iterator.
Definition MapVector.h:211
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PriorityQueue - This class behaves like std::priority_queue and provides a few additional convenience...
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
Analysis providing profile information.
LLVM_ABI void refresh(std::unique_ptr< ProfileSummary > &&Other=nullptr)
If a summary is provided as argument, use that.
LLVM_ABI bool isHotCountNthPercentile(int PercentileCutoff, uint64_t C) const
Returns true if count C is considered hot with regard to a given hot percentile cutoff value.
void computeDominanceAndLoopInfo(FunctionT &F)
static LLVM_ABI StringRef getSampleProfileFile(const LLVMContext &C)
Return -sample-profile-file.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI SampleProfileLoaderPass(std::string File="", std::string RemappingFile="", ThinOrFullLTOPhase LTOPhase=ThinOrFullLTOPhase::None, IntrusiveRefCntPtr< vfs::FileSystem > FS=nullptr, bool DisableSampleProfileInlining=false, bool UseFlattenedProfile=false)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
size_type size() const
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
LLVM Value Representation.
Definition Value.h:75
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:260
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:314
int getNumOccurrences() const
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:210
const ParentTy * getParent() const
Definition ilist_node.h:34
Representation of the samples collected for a function.
Definition SampleProf.h:854
static LLVM_ABI std::atomic< bool > UseMD5
Whether the profile uses MD5 to represent string.
FunctionId getFunction() const
Return the function name.
SampleContext & getContext() const LLVM_LIFETIME_BOUND
static StringRef getCanonicalFnName(const Function &F)
Return the canonical name for a function, taking into account suffix elision policy attributes.
static LLVM_ABI std::atomic< bool > ProfileIsProbeBased
const BodySampleMap & getBodySamples() const LLVM_LIFETIME_BOUND
Return all the samples collected in the body of the function.
sampleprof_error merge(const FunctionSamples &Other, uint64_t Weight=1)
Merge the samples in Other into this one.
static LLVM_ABI std::atomic< bool > ProfileIsCS
static LLVM_ABI LineLocation getCallSiteIdentifier(const DILocation *DIL, bool ProfileIsFS=false)
Returns a unique call site identifier for a given debug location of a call instruction.
void findInlinedFunctions(DenseSet< GlobalValue::GUID > &S, const HashKeyMap< DenseMap, FunctionId, Function * > &SymbolMap, uint64_t Threshold) const
Recursively traverses all children, if the total sample count of the corresponding function is no les...
uint64_t getHeadSamplesEstimate() const
Return an estimate of the sample count of the function entry basic block.
uint64_t getGUID() const
Return the GUID of the context's name.
static void flattenProfile(SampleProfileMap &ProfileMap, bool ProfileIsCS=false)
bool hasAttribute(ContextAttributeMask A)
Definition SampleProf.h:717
static LLVM_ABI ErrorOr< std::unique_ptr< SampleProfileReader > > create(StringRef Filename, LLVMContext &C, vfs::FileSystem &FS, FSDiscriminatorPass P=FSDiscriminatorPass::Base, StringRef RemapFilename="")
Create a sample profile reader appropriate to the file format.
static SortedCallTargetSet sortCallTargets(const CallTargetMap &Targets)
Sort call targets in descending order of call frequency.
Definition SampleProf.h:509
static const CallTargetMap adjustCallTargets(const CallTargetMap &Targets, float DistributionFactor)
Prorate call targets by a distribution factor.
Definition SampleProf.h:516
SortedVectorMap< FunctionId, uint64_t, 0 > CallTargetMap
Definition SampleProf.h:436
bool isAtEnd() const
Direct loop termination test which is more efficient than comparison with end().
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
initializer< Ty > init(const Ty &Val)
LLVM_ABI void checkExpectAnnotations(const Instruction &I, ArrayRef< uint32_t > ExistingWeights, bool IsFrontend)
checkExpectAnnotations - compares PGO counters to the thresholds used for llvm.expect and warns if th...
DiagnosticInfoOptimizationBase::Argument NV
LLVM_ABI CallBase & promoteIndirectCall(CallBase &CB, Function *F, uint64_t Count, uint64_t TotalCount, bool AttachProfToDirectCall, OptimizationRemarkEmitter *ORE)
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
NodeAddr< FuncNode * > Func
Definition RDFGraph.h:393
static FunctionId getRepInFormat(StringRef Name)
Get the proper representation of a string according to whether the current Format uses MD5 to represe...
std::map< FunctionId, FunctionSamples > FunctionSamplesMap
Definition SampleProf.h:844
LLVM_ABI bool callsiteIsHot(const FunctionSamples *CallsiteFS, ProfileSummaryInfo *PSI, bool ProfAccForSymsInList)
Return true if the given callsite is hot wrt to hot cutoff threshold.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
LLVM_ABI IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
This is an optimization pass for GlobalISel generic memory operations.
static bool isIndirectCall(const MachineInstr &MI)
LLVM_ABI bool isLegalToPromote(const CallBase &CB, Function *Callee, const char **FailureReason=nullptr)
Return true if the given indirect call site can be made to call Callee.
bool succ_empty(const Instruction *I)
Definition CFG.h:141
InstructionCost Cost
LLVM_ABI InlineCost getInlineCost(CallBase &Call, const InlineParams &Params, TargetTransformInfo &CallerTTI, function_ref< AssumptionCache &(Function &)> GetAssumptionCache, function_ref< const TargetLibraryInfo &(Function &)> GetTLI, function_ref< BlockFrequencyInfo &(Function &)> GetBFI=nullptr, ProfileSummaryInfo *PSI=nullptr, OptimizationRemarkEmitter *ORE=nullptr, function_ref< EphemeralValuesCache &(Function &)> GetEphValuesCache=nullptr)
Get an InlineCost object representing the cost of inlining this callsite.
LLVM_ABI InlineParams getInlineParams(const LLVMContext &C)
Generate the parameters to tune the inline cost analysis based only on the commandline options.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
LLVM_ABI cl::opt< int > SampleHotCallSiteThreshold
static void buildTopDownFuncOrder(LazyCallGraph &CG, std::vector< Function * > &FunctionOrderList)
LLVM_ABI InlineResult InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, bool MergeAttributes=false, AAResults *CalleeAAR=nullptr, bool InsertLifetime=true, bool TrackInlineHistory=false, Function *ForwardVarArgsTo=nullptr, OptimizationRemarkEmitter *ORE=nullptr)
This function inlines the called function into the basic block of the caller.
LLVM_ABI void setProbeDistributionFactor(Instruction &Inst, float Factor)
LLVM_ABI void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected, bool ElideAllZero=false)
Create a new branch_weights metadata node and add or overwrite a prof metadata reference to instructi...
LLVM_ABI cl::opt< int > ProfileInlineGrowthLimit
auto make_isa_range(RangeT &&Range)
Return a range over Range containing only elements for which isa<T> holds, casting each of them to T.
Definition STLExtras.h:567
LLVM_ABI std::string AnnotateInlinePassName(InlineContext IC)
ThinOrFullLTOPhase
This enumerates the LLVM full LTO or ThinLTO optimization phases.
Definition Pass.h:75
LLVM_ABI cl::opt< bool > SampleProfileUseProfi
const IPOOptions & getIPOOptions(const LLVMContext &C)
Definition IPOOptions.h:36
LLVM_ABI void annotateValueSite(Module &M, Instruction &Inst, const InstrProfRecord &InstrProfR, InstrProfValueKind ValueKind, uint32_t SiteIndx, uint32_t MaxMDCount=3)
Get the value profile data for value site SiteIdx from InstrProfR and annotate the instruction Inst w...
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI llvm::cl::opt< bool > UseIterativeBFIInference
LLVM_ABI std::optional< PseudoProbe > extractProbe(const Instruction &Inst)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void emitInlinedIntoBasedOnCost(OptimizationRemarkEmitter &ORE, DebugLoc DLoc, const BasicBlock *Block, const Function &Callee, const Function &Caller, const InlineCost &IC, bool ForProfileContext=false, const char *PassName=nullptr)
Emit ORE message based in cost (default heuristic).
LLVM_ABI SmallVector< InstrProfValueData, 4 > getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind, uint32_t MaxNumValueData, uint64_t &TotalC, bool GetNoICPValue=false)
Extract the value profile data from Inst and returns them if Inst is annotated with value profile dat...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI std::unique_ptr< InlineAdvisor > getReplayInlineAdvisor(Module &M, FunctionAnalysisManager &FAM, LLVMContext &Context, std::unique_ptr< InlineAdvisor > OriginalAdvisor, const ReplayInlinerSettings &ReplaySettings, bool EmitRemarks, InlineContext IC)
LLVM_ABI cl::opt< int > ProfileInlineLimitMax
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ABI void updateProfileCallee(Function *Callee, int64_t EntryDelta, const ValueMap< const Value *, WeakTrackingVH > *VMap=nullptr)
Updates profile information by adjusting the entry count by adding EntryDelta then scaling callsite i...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
LLVM_ABI cl::opt< int > SampleColdCallSiteThreshold
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
static bool skipProfileForFunction(const Function &F)
LLVM_ABI cl::opt< bool > SortProfiledSCC
constexpr bool valueOr(BoolOrDefault X, bool Default)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
cl::opt< bool > EnableExtTspBlockPlacement
const uint64_t NOMORE_ICP_MAGICNUM
Magic number in the value profile metadata showing a target has been promoted for the instruction and...
Definition Metadata.h:59
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
LLVM_ABI cl::opt< int > ProfileInlineLimitMin
constexpr const char * PseudoProbeDescMetadataName
Definition PseudoProbe.h:26
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:879
A wrapper of binary function with basic blocks and jumps.
std::optional< bool > AllowRecursiveCall
Indicate whether we allow inlining for recursive call.
Definition InlineCost.h:247
std::optional< bool > ComputeFullInlineCost
Compute inline cost even when the cost has exceeded the threshold.
Definition InlineCost.h:241
static std::optional< uint32_t > extractDwarfBaseDiscriminator(uint32_t Value)
Definition PseudoProbe.h:81