LLVM 24.0.0git
InlineAdvisor.cpp
Go to the documentation of this file.
1//===- InlineAdvisor.cpp - analysis pass implementation -------------------===//
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 InlineAdvisorAnalysis and DefaultInlineAdvisor, and
10// related types.
11//
12//===----------------------------------------------------------------------===//
13
15#include "AnalysisOptions.h"
16#include "llvm/ADT/Statistic.h"
29#include "llvm/IR/Module.h"
30#include "llvm/IR/PassManager.h"
33
34using namespace llvm;
35#define DEBUG_TYPE "inline"
36#ifdef LLVM_HAVE_TF_AOT_INLINERSIZEMODEL
37#define LLVM_HAVE_TF_AOT
38#endif
39
40// This weirdly named statistic tracks the number of times that, when attempting
41// to inline a function A into B, we analyze the callers of B in order to see
42// if those would be more profitable and blocked inline steps.
43STATISTIC(NumCallerCallersAnalyzed, "Number of caller-callers analyzed");
44
45namespace llvm {
47} // namespace llvm
48
49namespace {
50using namespace llvm::ore;
51class MandatoryInlineAdvice : public InlineAdvice {
52public:
53 MandatoryInlineAdvice(InlineAdvisor *Advisor, CallBase &CB,
55 bool IsInliningMandatory)
56 : InlineAdvice(Advisor, CB, ORE, IsInliningMandatory) {}
57
58private:
59 void recordInliningWithCalleeDeletedImpl() override { recordInliningImpl(); }
60
61 void recordInliningImpl() override {
62 if (IsInliningRecommended)
63 emitInlinedInto(ORE, DLoc, Block, *Callee, *Caller, IsInliningRecommended,
65 Remark << ": always inline attribute";
66 });
67 }
68
69 void recordUnsuccessfulInliningImpl(const InlineResult &Result) override {
70 if (IsInliningRecommended)
71 ORE.emit([&]() {
73 "NotInlined", DLoc, Block)
74 << "'" << NV("Callee", Callee) << "' is not AlwaysInline into '"
75 << NV("Caller", Caller)
76 << "': " << NV("Reason", Result.getFailureReason());
77 });
78 }
79
80 void recordUnattemptedInliningImpl() override {
81 assert(!IsInliningRecommended && "Expected to attempt inlining");
82 }
83};
84} // namespace
85
86void DefaultInlineAdvice::recordUnsuccessfulInliningImpl(
87 const InlineResult &Result) {
88 using namespace ore;
89 llvm::setInlineRemark(*OriginalCB, std::string(Result.getFailureReason()) +
90 "; " + inlineCostStr(*OIC));
91 ORE.emit([&]() {
92 return OptimizationRemarkMissed(Advisor->getAnnotatedInlinePassName(),
93 "NotInlined", DLoc, Block)
94 << "'" << NV("Callee", Callee) << "' is not inlined into '"
95 << NV("Caller", Caller)
96 << "': " << NV("Reason", Result.getFailureReason());
97 });
98}
99
101 if (EmitRemarks)
103 /* ForProfileContext= */ false,
104 Advisor->getAnnotatedInlinePassName());
105}
106
108 if (EmitRemarks)
110 /* ForProfileContext= */ false,
111 Advisor->getAnnotatedInlinePassName());
112}
113
114std::optional<llvm::InlineCost> static getDefaultInlineAdvice(
115 CallBase &CB, FunctionAnalysisManager &FAM, const InlineParams &Params) {
116 Function &Caller = *CB.getCaller();
117 ProfileSummaryInfo *PSI =
118 FAM.getResult<ModuleAnalysisManagerFunctionProxy>(Caller)
119 .getCachedResult<ProfileSummaryAnalysis>(
120 *CB.getParent()->getParent()->getParent());
121
122 auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(Caller);
123 auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
124 return FAM.getResult<AssumptionAnalysis>(F);
125 };
126 auto GetBFI = [&](Function &F) -> BlockFrequencyInfo & {
127 return FAM.getResult<BlockFrequencyAnalysis>(F);
128 };
129 auto GetTLI = [&](Function &F) -> const TargetLibraryInfo & {
130 return FAM.getResult<TargetLibraryAnalysis>(F);
131 };
132 auto GetEphValuesCache =
134 return FAM.getResult<EphemeralValuesAnalysis>(F);
135 };
136
137 Function &Callee = *CB.getCalledFunction();
138 auto &CalleeTTI = FAM.getResult<TargetIRAnalysis>(Callee);
139 auto GetInlineCost = [&](CallBase &CB) {
140 bool RemarksEnabled =
141 Callee.getContext().getDiagHandlerPtr()->isMissedOptRemarkEnabled(
142 DEBUG_TYPE);
143 return getInlineCost(CB, Params, CalleeTTI, GetAssumptionCache, GetTLI,
144 GetBFI, PSI, RemarksEnabled ? &ORE : nullptr,
145 GetEphValuesCache);
146 };
147 return llvm::shouldInline(CB, CalleeTTI, GetInlineCost, ORE,
148 Params.EnableDeferral
149 ? *Params.EnableDeferral
150 : getAnalysisOptions(Caller).inline_deferral);
151}
152
153std::unique_ptr<InlineAdvice>
154DefaultInlineAdvisor::getAdviceImpl(CallBase &CB) {
155 auto OIC = getDefaultInlineAdvice(CB, FAM, Params);
156 return std::make_unique<DefaultInlineAdvice>(
157 this, CB, OIC,
158 FAM.getResult<OptimizationRemarkEmitterAnalysis>(*CB.getCaller()));
159}
160
167
168void InlineAdvice::recordInlineStatsIfNeeded() {
170 Advisor->ImportedFunctionsStats->recordInline(*Caller, *Callee);
171}
172
174 markRecorded();
175 recordInlineStatsIfNeeded();
177}
178
180 markRecorded();
181 recordInlineStatsIfNeeded();
183}
184
187
188bool InlineAdvisorAnalysis::initializeIR2VecVocabIfRequested(
190 if (!getAnalysisOptions(M).ml_inliner_ir2vec_vocab_file.empty()) {
191 auto &IR2VecVocabResult = MAM.getResult<IR2VecVocabAnalysis>(M);
192 if (!IR2VecVocabResult.isValid()) {
193 M.getContext().emitError("Failed to load IR2Vec vocabulary");
194 return false;
195 }
196 }
197 // No vocab file specified is OK; We just don't use IR2Vec
198 // embeddings.
199 return true;
200}
201
204 const ReplayInlinerSettings &ReplaySettings, InlineContext IC) {
205 auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
206 if (MAM.isPassRegistered<PluginInlineAdvisorAnalysis>()) {
207 auto &DA = MAM.getResult<PluginInlineAdvisorAnalysis>(M);
208 Advisor.reset(DA.Factory(M, FAM, Params, IC));
209 return !!Advisor;
210 }
211 auto GetDefaultAdvice = [&FAM, Params](CallBase &CB) {
212 auto OIC = getDefaultInlineAdvice(CB, FAM, Params);
213 return OIC.has_value();
214 };
215 switch (Mode) {
217 LLVM_DEBUG(dbgs() << "Using default inliner heuristic.\n");
218 Advisor.reset(new DefaultInlineAdvisor(M, FAM, Params, IC));
219 // Restrict replay to default advisor, ML advisors are stateful so
220 // replay will need augmentations to interleave with them correctly.
221 if (!ReplaySettings.ReplayFile.empty()) {
222 Advisor = llvm::getReplayInlineAdvisor(M, FAM, M.getContext(),
223 std::move(Advisor), ReplaySettings,
224 /* EmitRemarks =*/true, IC);
225 }
226 break;
227 // Run IR2VecVocabAnalysis once per module to get the vocabulary.
228 // We run it here because it is immutable and we want to avoid running it
229 // multiple times.
231#ifdef LLVM_HAVE_TFLITE
232 LLVM_DEBUG(dbgs() << "Using development-mode inliner policy.\n");
233 if (!InlineAdvisorAnalysis::initializeIR2VecVocabIfRequested(M, MAM))
234 return false;
235 Advisor = llvm::getDevelopmentModeAdvisor(M, MAM, GetDefaultAdvice);
236#endif
237 break;
239 LLVM_DEBUG(dbgs() << "Using release-mode inliner policy.\n");
240 if (!InlineAdvisorAnalysis::initializeIR2VecVocabIfRequested(M, MAM))
241 return false;
242 Advisor = llvm::getReleaseModeAdvisor(M, MAM, GetDefaultAdvice);
243 break;
244 }
245
246 return !!Advisor;
247}
248
249/// Return true if inlining of CB can block the caller from being
250/// inlined which is proved to be more beneficial. \p IC is the
251/// estimated inline cost associated with callsite \p CB.
252/// \p TotalSecondaryCost will be set to the estimated cost of inlining the
253/// caller if \p CB is suppressed for inlining.
254static bool
256 InlineCost IC, int &TotalSecondaryCost,
257 function_ref<InlineCost(CallBase &CB)> GetInlineCost) {
258 // For now we only handle local or inline functions.
259 if (!Caller->hasLocalLinkage() && !Caller->hasLinkOnceODRLinkage())
260 return false;
261 // If the cost of inlining CB is non-positive, it is not going to prevent the
262 // caller from being inlined into its callers and hence we don't need to
263 // defer.
264 if (IC.getCost() <= 0)
265 return false;
266 // Try to detect the case where the current inlining candidate caller (call
267 // it B) is a static or linkonce-ODR function and is an inlining candidate
268 // elsewhere, and the current candidate callee (call it C) is large enough
269 // that inlining it into B would make B too big to inline later. In these
270 // circumstances it may be best not to inline C into B, but to inline B into
271 // its callers.
272 //
273 // This only applies to static and linkonce-ODR functions because those are
274 // expected to be available for inlining in the translation units where they
275 // are used. Thus we will always have the opportunity to make local inlining
276 // decisions. Importantly the linkonce-ODR linkage covers inline functions
277 // and templates in C++.
278 //
279 // FIXME: All of this logic should be sunk into getInlineCost. It relies on
280 // the internal implementation of the inline cost metrics rather than
281 // treating them as truly abstract units etc.
282 TotalSecondaryCost = 0;
283 // The candidate cost to be imposed upon the current function.
284 int CandidateCost = IC.getCost() - 1;
285 // If the caller has local linkage and can be inlined to all its callers, we
286 // can apply a huge negative bonus to TotalSecondaryCost.
287 bool ApplyLastCallBonus = Caller->hasLocalLinkage() && !Caller->hasOneUse();
288 // This bool tracks what happens if we DO inline C into B.
289 bool InliningPreventsSomeOuterInline = false;
290 unsigned NumCallerUsers = 0;
291 for (User *U : Caller->users()) {
293
294 // If this isn't a call to Caller (it could be some other sort
295 // of reference) skip it. Such references will prevent the caller
296 // from being removed.
297 if (!CS2 || CS2->getCalledFunction() != Caller) {
298 ApplyLastCallBonus = false;
299 continue;
300 }
301
302 InlineCost IC2 = GetInlineCost(*CS2);
303 ++NumCallerCallersAnalyzed;
304 if (!IC2) {
305 ApplyLastCallBonus = false;
306 continue;
307 }
308 if (IC2.isAlways())
309 continue;
310
311 // See if inlining of the original callsite would erase the cost delta of
312 // this callsite. We subtract off the penalty for the call instruction,
313 // which we would be deleting.
314 if (IC2.getCostDelta() <= CandidateCost) {
315 InliningPreventsSomeOuterInline = true;
316 TotalSecondaryCost += IC2.getCost();
317 NumCallerUsers++;
318 }
319 }
320
321 if (!InliningPreventsSomeOuterInline)
322 return false;
323
324 // If all outer calls to Caller would get inlined, the cost for the last
325 // one is set very low by getInlineCost, in anticipation that Caller will
326 // be removed entirely. We did not account for this above unless there
327 // is only one caller of Caller.
328 if (ApplyLastCallBonus)
329 TotalSecondaryCost -= CalleeTTI.getInliningLastCallToStaticBonus();
330
331 // If InlineDeferralScale is negative, then ignore the cost of primary
332 // inlining -- IC.getCost() multiplied by the number of callers to Caller.
333 int InlineDeferralScale = getAnalysisOptions(*Caller).inline_deferral_scale;
334 if (InlineDeferralScale < 0)
335 return TotalSecondaryCost < IC.getCost();
336
337 int TotalCost = TotalSecondaryCost + IC.getCost() * NumCallerUsers;
338 int Allowance = IC.getCost() * InlineDeferralScale;
339 return TotalCost < Allowance;
340}
341
342namespace llvm {
343static raw_ostream &operator<<(raw_ostream &R, const ore::NV &Arg) {
344 return R << Arg.Val;
345}
346
347template <class RemarkT>
348decltype(auto) operator<<(RemarkT &&R, const InlineCost &IC) {
349 using namespace ore;
350 if (IC.isAlways()) {
351 R << "(cost=always)";
352 } else if (IC.isNever()) {
353 R << "(cost=never)";
354 } else {
355 R << "(cost=" << ore::NV("Cost", IC.getCost())
356 << ", threshold=" << ore::NV("Threshold", IC.getThreshold()) << ")";
357 }
358 if (const char *Reason = IC.getReason())
359 R << ": " << ore::NV("Reason", Reason);
360 return std::forward<RemarkT>(R);
361}
362} // namespace llvm
363
364std::string llvm::inlineCostStr(const InlineCost &IC) {
365 std::string Buffer;
367 Remark << IC;
368 return Remark.str();
369}
370
372 if (!getAnalysisOptions(CB.getContext()).inline_remark_attribute)
373 return;
374
375 Attribute Attr = Attribute::get(CB.getContext(), "inline-remark", Message);
376 CB.addFnAttr(Attr);
377}
378
379/// Return the cost only if the inliner should attempt to inline at the given
380/// CallSite. If we return the cost, we will emit an optimisation remark later
381/// using that cost, so we won't do so from this function. Return std::nullopt
382/// if inlining should not be attempted.
383std::optional<InlineCost>
385 function_ref<InlineCost(CallBase &CB)> GetInlineCost,
386 OptimizationRemarkEmitter &ORE, bool EnableDeferral) {
387 using namespace ore;
388
389 InlineCost IC = GetInlineCost(CB);
390 Instruction *Call = &CB;
391 Function *Callee = CB.getCalledFunction();
392 Function *Caller = CB.getCaller();
393
394 if (IC.isAlways()) {
395 LLVM_DEBUG(dbgs() << " Inlining " << inlineCostStr(IC)
396 << ", Call: " << CB << "\n");
397 return IC;
398 }
399
400 if (!IC) {
401 LLVM_DEBUG(dbgs() << " NOT Inlining " << inlineCostStr(IC)
402 << ", Call: " << CB << "\n");
403 if (IC.isNever()) {
404 ORE.emit([&]() {
405 return OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline", Call)
406 << "'" << NV("Callee", Callee) << "' not inlined into '"
407 << NV("Caller", Caller)
408 << "' because it should never be inlined " << IC;
409 });
410 } else {
411 ORE.emit([&]() {
412 return OptimizationRemarkMissed(DEBUG_TYPE, "TooCostly", Call)
413 << "'" << NV("Callee", Callee) << "' not inlined into '"
414 << NV("Caller", Caller) << "' because too costly to inline "
415 << IC;
416 });
417 }
419 return std::nullopt;
420 }
421
422 int TotalSecondaryCost = 0;
423 if (EnableDeferral && shouldBeDeferred(Caller, CalleeTTI, IC,
424 TotalSecondaryCost, GetInlineCost)) {
425 LLVM_DEBUG(dbgs() << " NOT Inlining: " << CB
426 << " Cost = " << IC.getCost()
427 << ", outer Cost = " << TotalSecondaryCost << '\n');
428 ORE.emit([&]() {
429 return OptimizationRemarkMissed(DEBUG_TYPE, "IncreaseCostInOtherContexts",
430 Call)
431 << "Not inlining. Cost of inlining '" << NV("Callee", Callee)
432 << "' increases the cost of inlining '" << NV("Caller", Caller)
433 << "' in other contexts";
434 });
435 setInlineRemark(CB, "deferred");
436 return std::nullopt;
437 }
438
439 LLVM_DEBUG(dbgs() << " Inlining " << inlineCostStr(IC) << ", Call: " << CB
440 << '\n');
441 return IC;
442}
443
445 const CallSiteFormat &Format) {
446 std::string Buffer;
447 raw_string_ostream CallSiteLoc(Buffer);
448 ListSeparator LS(" @ ");
449 for (DILocation *DIL = DLoc.get(); DIL; DIL = DIL->getInlinedAt()) {
450 CallSiteLoc << LS;
451 // Note that negative line offset is actually possible, but we use
452 // unsigned int to match line offset representation in remarks so
453 // it's directly consumable by relay advisor.
455 DIL->getLine() - DIL->getScope()->getSubprogram()->getLine();
456 uint32_t Discriminator = DIL->getBaseDiscriminator();
457 StringRef Name = DIL->getScope()->getSubprogram()->getLinkageName();
458 if (Name.empty())
459 Name = DIL->getScope()->getSubprogram()->getName();
460 CallSiteLoc << Name.str() << ":" << llvm::utostr(Offset);
461 if (Format.outputColumn())
462 CallSiteLoc << ":" << llvm::utostr(DIL->getColumn());
463 if (Format.outputDiscriminator() && Discriminator)
464 CallSiteLoc << "." << llvm::utostr(Discriminator);
465 }
466
467 return CallSiteLoc.str();
468}
469
471 if (!DLoc)
472 return;
473
474 bool First = true;
475 Remark << " at callsite ";
476 for (DILocation *DIL = DLoc.get(); DIL; DIL = DIL->getInlinedAt()) {
477 if (!First)
478 Remark << " @ ";
479 unsigned int Offset = DIL->getLine();
480 Offset -= DIL->getScope()->getSubprogram()->getLine();
481 unsigned int Discriminator = DIL->getBaseDiscriminator();
482 StringRef Name = DIL->getScope()->getSubprogram()->getLinkageName();
483 if (Name.empty())
484 Name = DIL->getScope()->getSubprogram()->getName();
485 Remark << Name << ":" << ore::NV("Line", Offset) << ":"
486 << ore::NV("Column", DIL->getColumn());
487 if (Discriminator)
488 Remark << "." << ore::NV("Disc", Discriminator);
489 First = false;
490 }
491
492 Remark << ";";
493}
494
497 const Function &Callee, const Function &Caller, bool AlwaysInline,
498 function_ref<void(OptimizationRemark &)> ExtraContext,
499 const char *PassName) {
500 ORE.emit([&]() {
501 StringRef RemarkName = AlwaysInline ? "AlwaysInline" : "Inlined";
503 DLoc, Block);
504 Remark << "'" << ore::NV("Callee", &Callee) << "' inlined into '"
505 << ore::NV("Caller", &Caller) << "'";
506 if (ExtraContext)
507 ExtraContext(Remark);
509 return Remark;
510 });
511}
512
515 const Function &Callee, const Function &Caller, const InlineCost &IC,
516 bool ForProfileContext, const char *PassName) {
518 ORE, DLoc, Block, Callee, Caller, IC.isAlways(),
520 if (ForProfileContext)
521 Remark << " to match profiling context";
522 Remark << " with " << IC;
523 },
524 PassName);
525}
526
528 std::optional<InlineContext> IC)
529 : M(M), FAM(FAM), IC(IC),
531 (IC && getAnalysisOptions(M).annotate_inline_phase)
533 : DEBUG_TYPE) {
536 std::make_unique<ImportedFunctionsInliningStatistics>();
537 ImportedFunctionsStats->setModuleInfo(M);
538 }
539}
540
548
549std::unique_ptr<InlineAdvice> InlineAdvisor::getMandatoryAdvice(CallBase &CB,
550 bool Advice) {
551 return std::make_unique<MandatoryInlineAdvice>(this, CB, getCallerORE(CB),
552 Advice);
553}
554
555static inline const char *getLTOPhase(ThinOrFullLTOPhase LTOPhase) {
556 switch (LTOPhase) {
558 return "main";
561 return "prelink";
564 return "postlink";
565 }
566 llvm_unreachable("unreachable");
567}
568
569static inline const char *getInlineAdvisorContext(InlinePass IP) {
570 switch (IP) {
572 return "always-inline";
574 return "cgscc-inline";
576 return "early-inline";
578 return "ml-inline";
580 return "module-inline";
582 return "replay-cgscc-inline";
584 return "replay-sample-profile-inline";
586 return "sample-profile-inline";
587 }
588
589 llvm_unreachable("unreachable");
590}
591
593 return std::string(getLTOPhase(IC.LTOPhase)) + "-" +
594 std::string(getInlineAdvisorContext(IC.Pass));
595}
596
600 auto &Callee = *CB.getCalledFunction();
601
602 auto GetTLI = [&](Function &F) -> const TargetLibraryInfo & {
603 return FAM.getResult<TargetLibraryAnalysis>(F);
604 };
605
606 auto &TIR = FAM.getResult<TargetIRAnalysis>(Callee);
607
608 auto TrivialDecision =
609 llvm::getAttributeBasedInliningDecision(CB, &Callee, TIR, GetTLI);
610
611 if (TrivialDecision) {
612 if (TrivialDecision->isSuccess())
614 else
616 }
618}
619
620std::unique_ptr<InlineAdvice> InlineAdvisor::getAdvice(CallBase &CB,
621 bool MandatoryOnly) {
622 if (!MandatoryOnly)
623 return getAdviceImpl(CB);
624 bool Advice = CB.getCaller() != CB.getCalledFunction() &&
627 return getMandatoryAdvice(CB, Advice);
628}
629
633
636 const auto *IA = MAM.getCachedResult<InlineAdvisorAnalysis>(M);
637 if (!IA)
638 OS << "No Inline Advisor\n";
639 else
640 IA->getAdvisor()->print(OS);
641 return PreservedAnalyses::all();
642}
643
646 CGSCCUpdateResult &UR) {
647 const auto &MAMProxy =
649
650 if (InitialC.size() == 0) {
651 OS << "SCC is empty!\n";
652 return PreservedAnalyses::all();
653 }
654 Module &M = *InitialC.begin()->getFunction().getParent();
655 const auto *IA = MAMProxy.getCachedResult<InlineAdvisorAnalysis>(M);
656 if (!IA)
657 OS << "No Inline Advisor\n";
658 else
659 IA->getAdvisor()->print(OS);
660 return PreservedAnalyses::all();
661}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static const Function * getParent(const Value *V)
#define DEBUG_TYPE
This file defines the IR2Vec vocabulary analysis(IR2VecVocabAnalysis), the core ir2vec::Embedder inte...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
static bool shouldBeDeferred(Function *Caller, TargetTransformInfo &CalleeTTI, InlineCost IC, int &TotalSecondaryCost, function_ref< InlineCost(CallBase &CB)> GetInlineCost)
Return true if inlining of CB can block the caller from being inlined which is proved to be more bene...
static const char * getLTOPhase(ThinOrFullLTOPhase LTOPhase)
static std::optional< llvm::InlineCost > getDefaultInlineAdvice(CallBase &CB, FunctionAnalysisManager &FAM, const InlineParams &Params)
static const char * getInlineAdvisorContext(InlinePass IP)
#define F(x, y, z)
Definition MD5.cpp:54
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first DebugLoc that has line number information, given a range of instructions.
static const Function * getCalledFunction(const Value *V)
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
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
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:119
This pass exposes codegen information to IR-level passes.
static const char PassName[]
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.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:106
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
void addFnAttr(Attribute::AttrKind Kind)
Adds the attribute to the function.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
A debug info location.
Definition DebugLoc.h:126
DILocation * get() const
Get the underlying DILocation.
Definition DebugLoc.h:226
The default (manual heuristics) implementation of the InlineAdvisor.
This analysis provides the vocabulary for IR2Vec.
Definition IR2Vec.h:637
Capture state between an inlining decision having had been made, and its impact being observable.
Function *const Callee
Function *const Caller
Caller and Callee are pre-inlining.
virtual void recordInliningWithCalleeDeletedImpl()
virtual void recordInliningImpl()
const BasicBlock *const Block
LLVM_ABI void recordInlining()
Exactly one of the record* APIs must be called.
OptimizationRemarkEmitter & ORE
InlineAdvisor *const Advisor
LLVM_ABI InlineAdvice(InlineAdvisor *Advisor, CallBase &CB, OptimizationRemarkEmitter &ORE, bool IsInliningRecommended)
const DebugLoc DLoc
LLVM_ABI void recordInliningWithCalleeDeleted()
Call after inlining succeeded, and results in the callee being delete-able, meaning,...
const bool IsInliningRecommended
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
The InlineAdvisorAnalysis is a module pass because the InlineAdvisor needs to capture state right bef...
static LLVM_ABI AnalysisKey Key
Interface for deciding whether to inline a call site or not.
const std::optional< InlineContext > IC
OptimizationRemarkEmitter & getCallerORE(CallBase &CB)
FunctionAnalysisManager & FAM
static MandatoryInliningKind getMandatoryKind(CallBase &CB, FunctionAnalysisManager &FAM, OptimizationRemarkEmitter &ORE)
const std::string AnnotatedInlinePassName
virtual std::unique_ptr< InlineAdvice > getMandatoryAdvice(CallBase &CB, bool Advice)
std::unique_ptr< ImportedFunctionsInliningStatistics > ImportedFunctionsStats
const char * getAnnotatedInlinePassName() const
NOTE pass name is annotated only when inline advisor constructor provides InlineContext.
InlineAdvisor(InlineAdvisor &&)=delete
virtual std::unique_ptr< InlineAdvice > getAdviceImpl(CallBase &CB)=0
std::unique_ptr< InlineAdvice > getAdvice(CallBase &CB, bool MandatoryOnly=false)
Get an InlineAdvice containing a recommendation on whether to inline or not.
Represents the cost of inlining a function.
Definition InlineCost.h:91
int getThreshold() const
Get the threshold against which the cost was computed.
Definition InlineCost.h:152
const char * getReason() const
Get the reason of Always or Never.
Definition InlineCost.h:167
int getCost() const
Get the inline cost estimate.
Definition InlineCost.h:146
bool isAlways() const
Definition InlineCost.h:140
int getCostDelta() const
Get the cost delta from the threshold for inlining.
Definition InlineCost.h:176
bool isNever() const
Definition InlineCost.h:141
InlineResult is basically true or false.
Definition InlineCost.h:181
An SCC of the call graph.
A lazily constructed view of the call graph of a module.
A helper class to return the specified delimiter string after the first invocation of operator String...
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
The optimization diagnostic interface.
LLVM_ABI void emit(DiagnosticInfoOptimizationBase &OptDiag)
Output the remark via the diagnostic handler and to the optimization record file.
Diagnostic information for missed-optimization remarks.
Diagnostic information for applied optimization remarks.
Used for dynamically registering InlineAdvisors as plugins.
static LLVM_ABI AnalysisKey Key
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
Analysis providing profile information.
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_ABI int getInliningLastCallToStaticBonus() const
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:260
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition ilist_node.h:34
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
CallInst * Call
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Add a small namespace to avoid name clashes with the classes used in the streaming interface.
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
LLVM_ABI void emitInlinedInto(OptimizationRemarkEmitter &ORE, DebugLoc DLoc, const BasicBlock *Block, const Function &Callee, const Function &Caller, bool IsMandatory, function_ref< void(OptimizationRemark &)> ExtraContext={}, const char *PassName=nullptr)
Emit ORE message.
LLVM_ABI std::string inlineCostStr(const InlineCost &IC)
Utility for extracting the inline cost message to a string.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
InliningAdvisorMode
There are 4 scenarios we can use the InlineAdvisor:
LLVM_ABI std::optional< InlineCost > shouldInline(CallBase &CB, TargetTransformInfo &CalleeTTI, function_ref< InlineCost(CallBase &CB)> GetInlineCost, OptimizationRemarkEmitter &ORE, bool EnableDeferral=true)
Return the cost only if the inliner should attempt to inline at the given CallSite.
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI std::unique_ptr< InlineAdvisor > getDevelopmentModeAdvisor(Module &M, ModuleAnalysisManager &MAM, std::function< bool(CallBase &)> GetDefaultAdvice)
LLVM_ABI std::unique_ptr< InlineAdvisor > getReleaseModeAdvisor(Module &M, ModuleAnalysisManager &MAM, std::function< bool(CallBase &)> GetDefaultAdvice)
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
std::string utostr(uint64_t X, bool isNeg=false)
LLVM_ABI void setInlineRemark(CallBase &CB, StringRef Message)
Set the inline-remark attribute.
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
LLVM_ABI std::string AnnotateInlinePassName(InlineContext IC)
ThinOrFullLTOPhase
This enumerates the LLVM full LTO or ThinLTO optimization phases.
Definition Pass.h:75
@ FullLTOPreLink
Full LTO prelink phase.
Definition Pass.h:83
@ ThinLTOPostLink
ThinLTO postlink (backend compile) phase.
Definition Pass.h:81
@ None
No LTO/ThinLTO behavior needed.
Definition Pass.h:77
@ FullLTOPostLink
Full LTO postlink (backend compile) phase.
Definition Pass.h:85
@ ThinLTOPreLink
ThinLTO prelink (summary) phase.
Definition Pass.h:79
const AnalysisOptions & getAnalysisOptions(const LLVMContext &C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void emitInlinedIntoBasedOnCost(OptimizationRemarkEmitter &ORE, DebugLoc DLoc, const BasicBlock *Block, const Function &Callee, const Function &Caller, const InlineCost &IC, bool ForProfileContext=false, const char *PassName=nullptr)
Emit ORE message based in cost (default heuristic).
LLVM_ABI std::unique_ptr< InlineAdvisor > getReplayInlineAdvisor(Module &M, FunctionAnalysisManager &FAM, LLVMContext &Context, std::unique_ptr< InlineAdvisor > OriginalAdvisor, const ReplayInlinerSettings &ReplaySettings, bool EmitRemarks, InlineContext IC)
LLVM_ABI 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.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
LLVM_ABI std::optional< InlineResult > getAttributeBasedInliningDecision(CallBase &Call, Function *Callee, TargetTransformInfo &CalleeTTI, function_ref< const TargetLibraryInfo &(Function &)> GetTLI)
Returns InlineResult::success() if the call site should be always inlined because of user directives,...
OuterAnalysisManagerProxy< ModuleAnalysisManager, LazyCallGraph::SCC, LazyCallGraph & > ModuleAnalysisManagerCGSCCProxy
A proxy from a ModuleAnalysisManager to an SCC.
cl::opt< InlinerFunctionImportStatsOpts > InlinerFunctionImportStats("inliner-function-import-stats", cl::init(InlinerFunctionImportStatsOpts::No), cl::values(clEnumValN(InlinerFunctionImportStatsOpts::Basic, "basic", "basic statistics"), clEnumValN(InlinerFunctionImportStatsOpts::Verbose, "verbose", "printing of statistics for each inlined function")), cl::Hidden, cl::desc("Enable inliner stats for imported functions"))
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LLVM_ABI void addLocationToRemarks(OptimizationRemark &Remark, DebugLoc DLoc)
Add location info to ORE message.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI std::string formatCallSiteLocation(DebugLoc DLoc, const CallSiteFormat &Format)
Get call site location as a string with the given format.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29
Support structure for SCC passes to communicate updates the call graph back to the CGSCC pass manager...
LLVM_ABI bool tryCreate(InlineParams Params, InliningAdvisorMode Mode, const ReplayInlinerSettings &ReplaySettings, InlineContext IC)
Provides context on when an inline advisor is constructed in the pipeline (e.g., link phase,...
ThinOrFullLTOPhase LTOPhase
Thresholds to tune inline cost analysis.
Definition InlineCost.h:207
std::optional< bool > EnableDeferral
Indicate whether we should allow inline deferral.
Definition InlineCost.h:241