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