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