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"
32
33using namespace llvm;
34#define DEBUG_TYPE "inline"
35#ifdef LLVM_HAVE_TF_AOT_INLINERSIZEMODEL
36#define LLVM_HAVE_TF_AOT
37#endif
38
39// This weirdly named statistic tracks the number of times that, when attempting
40// to inline a function A into B, we analyze the callers of B in order to see
41// if those would be more profitable and blocked inline steps.
42STATISTIC(NumCallerCallersAnalyzed, "Number of caller-callers analyzed");
43
44namespace {
45using namespace llvm::ore;
46class MandatoryInlineAdvice : public InlineAdvice {
47public:
48 MandatoryInlineAdvice(InlineAdvisor *Advisor, CallBase &CB,
50 bool IsInliningMandatory)
51 : InlineAdvice(Advisor, CB, ORE, IsInliningMandatory) {}
52
53private:
54 void recordInliningWithCalleeDeletedImpl() override { recordInliningImpl(); }
55
56 void recordInliningImpl() override {
57 if (IsInliningRecommended)
58 emitInlinedInto(ORE, DLoc, Block, *Callee, *Caller, IsInliningRecommended,
59 [&](OptimizationRemark &Remark) {
60 Remark << ": always inline attribute";
61 });
62 }
63
64 void recordUnsuccessfulInliningImpl(const InlineResult &Result) override {
65 if (IsInliningRecommended)
66 ORE.emit([&]() {
67 return OptimizationRemarkMissed(Advisor->getAnnotatedInlinePassName(),
68 "NotInlined", DLoc, Block)
69 << "'" << NV("Callee", Callee) << "' is not AlwaysInline into '"
70 << NV("Caller", Caller)
71 << "': " << NV("Reason", Result.getFailureReason());
72 });
73 }
74
75 void recordUnattemptedInliningImpl() override {
76 assert(!IsInliningRecommended && "Expected to attempt inlining");
77 }
78};
79} // namespace
80
81void DefaultInlineAdvice::recordUnsuccessfulInliningImpl(
82 const InlineResult &Result) {
83 using namespace ore;
84 llvm::setInlineRemark(*OriginalCB, std::string(Result.getFailureReason()) +
85 "; " + inlineCostStr(*OIC));
86 ORE.emit([&]() {
87 return OptimizationRemarkMissed(Advisor->getAnnotatedInlinePassName(),
88 "NotInlined", DLoc, Block)
89 << "'" << NV("Callee", Callee) << "' is not inlined into '"
90 << NV("Caller", Caller)
91 << "': " << NV("Reason", Result.getFailureReason());
92 });
93}
94
96 if (EmitRemarks)
98 /* ForProfileContext= */ false,
99 Advisor->getAnnotatedInlinePassName());
100}
101
103 if (EmitRemarks)
105 /* ForProfileContext= */ false,
106 Advisor->getAnnotatedInlinePassName());
107}
108
109std::optional<llvm::InlineCost> static getDefaultInlineAdvice(
110 CallBase &CB, FunctionAnalysisManager &FAM, const InlineParams &Params) {
111 Function &Caller = *CB.getCaller();
112 ProfileSummaryInfo *PSI =
113 FAM.getResult<ModuleAnalysisManagerFunctionProxy>(Caller)
114 .getCachedResult<ProfileSummaryAnalysis>(
115 *CB.getParent()->getParent()->getParent());
116
117 auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(Caller);
118 auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
119 return FAM.getResult<AssumptionAnalysis>(F);
120 };
121 auto GetBFI = [&](Function &F) -> BlockFrequencyInfo & {
122 return FAM.getResult<BlockFrequencyAnalysis>(F);
123 };
124 auto GetTLI = [&](Function &F) -> const TargetLibraryInfo & {
125 return FAM.getResult<TargetLibraryAnalysis>(F);
126 };
127 auto GetEphValuesCache =
129 return FAM.getResult<EphemeralValuesAnalysis>(F);
130 };
131
132 Function &Callee = *CB.getCalledFunction();
133 auto &CallerTTI = FAM.getResult<TargetIRAnalysis>(Caller);
134 auto GetInlineCost = [&](CallBase &CB) {
135 bool RemarksEnabled =
136 Callee.getContext().getDiagHandlerPtr()->isMissedOptRemarkEnabled(
137 DEBUG_TYPE);
138 return getInlineCost(CB, Params, CallerTTI, GetAssumptionCache, GetTLI,
139 GetBFI, PSI, RemarksEnabled ? &ORE : nullptr,
140 GetEphValuesCache);
141 };
142 return llvm::shouldInline(CB, CallerTTI, GetInlineCost, ORE,
143 Params.EnableDeferral
144 ? *Params.EnableDeferral
145 : getAnalysisOptions(Caller).inline_deferral);
146}
147
148std::unique_ptr<InlineAdvice>
149DefaultInlineAdvisor::getAdviceImpl(CallBase &CB) {
150 auto OIC = getDefaultInlineAdvice(CB, FAM, Params);
151 return std::make_unique<DefaultInlineAdvice>(
152 this, CB, OIC,
153 FAM.getResult<OptimizationRemarkEmitterAnalysis>(*CB.getCaller()));
154}
155
162
163void InlineAdvice::recordInlineStatsIfNeeded() {
165 Advisor->ImportedFunctionsStats->recordInline(*Caller, *Callee);
166}
167
169 markRecorded();
170 recordInlineStatsIfNeeded();
172}
173
175 markRecorded();
176 recordInlineStatsIfNeeded();
178}
179
182
183bool InlineAdvisorAnalysis::initializeIR2VecVocabIfRequested(
185 if (!getAnalysisOptions(M).ml_inliner_ir2vec_vocab_file.empty()) {
186 auto &IR2VecVocabResult = MAM.getResult<IR2VecVocabAnalysis>(M);
187 if (!IR2VecVocabResult.isValid()) {
188 M.getContext().emitError("Failed to load IR2Vec vocabulary");
189 return false;
190 }
191 }
192 // No vocab file specified is OK; We just don't use IR2Vec
193 // embeddings.
194 return true;
195}
196
199 const ReplayInlinerSettings &ReplaySettings, InlineContext IC) {
200 auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
201 if (MAM.isPassRegistered<PluginInlineAdvisorAnalysis>()) {
202 auto &DA = MAM.getResult<PluginInlineAdvisorAnalysis>(M);
203 Advisor.reset(DA.Factory(M, FAM, Params, IC));
204 return !!Advisor;
205 }
206 auto GetDefaultAdvice = [&FAM, Params](CallBase &CB) {
207 auto OIC = getDefaultInlineAdvice(CB, FAM, Params);
208 return OIC.has_value();
209 };
210 switch (Mode) {
212 LLVM_DEBUG(dbgs() << "Using default inliner heuristic.\n");
213 Advisor.reset(new DefaultInlineAdvisor(M, FAM, Params, IC));
214 // Restrict replay to default advisor, ML advisors are stateful so
215 // replay will need augmentations to interleave with them correctly.
216 if (!ReplaySettings.ReplayFile.empty()) {
217 Advisor = llvm::getReplayInlineAdvisor(M, FAM, M.getContext(),
218 std::move(Advisor), ReplaySettings,
219 /* EmitRemarks =*/true, IC);
220 }
221 break;
222 // Run IR2VecVocabAnalysis once per module to get the vocabulary.
223 // We run it here because it is immutable and we want to avoid running it
224 // multiple times.
226#ifdef LLVM_HAVE_TFLITE
227 LLVM_DEBUG(dbgs() << "Using development-mode inliner policy.\n");
228 if (!InlineAdvisorAnalysis::initializeIR2VecVocabIfRequested(M, MAM))
229 return false;
230 Advisor = llvm::getDevelopmentModeAdvisor(M, MAM, GetDefaultAdvice);
231#endif
232 break;
234 LLVM_DEBUG(dbgs() << "Using release-mode inliner policy.\n");
235 if (!InlineAdvisorAnalysis::initializeIR2VecVocabIfRequested(M, MAM))
236 return false;
237 Advisor = llvm::getReleaseModeAdvisor(M, MAM, GetDefaultAdvice);
238 break;
239 }
240
241 return !!Advisor;
242}
243
244/// Return true if inlining of CB can block the caller from being
245/// inlined which is proved to be more beneficial. \p IC is the
246/// estimated inline cost associated with callsite \p CB.
247/// \p TotalSecondaryCost will be set to the estimated cost of inlining the
248/// caller if \p CB is suppressed for inlining.
249static bool
251 InlineCost IC, int &TotalSecondaryCost,
252 function_ref<InlineCost(CallBase &CB)> GetInlineCost) {
253 // For now we only handle local or inline functions.
254 if (!Caller->hasLocalLinkage() && !Caller->hasLinkOnceODRLinkage())
255 return false;
256 // If the cost of inlining CB is non-positive, it is not going to prevent the
257 // caller from being inlined into its callers and hence we don't need to
258 // defer.
259 if (IC.getCost() <= 0)
260 return false;
261 // Try to detect the case where the current inlining candidate caller (call
262 // it B) is a static or linkonce-ODR function and is an inlining candidate
263 // elsewhere, and the current candidate callee (call it C) is large enough
264 // that inlining it into B would make B too big to inline later. In these
265 // circumstances it may be best not to inline C into B, but to inline B into
266 // its callers.
267 //
268 // This only applies to static and linkonce-ODR functions because those are
269 // expected to be available for inlining in the translation units where they
270 // are used. Thus we will always have the opportunity to make local inlining
271 // decisions. Importantly the linkonce-ODR linkage covers inline functions
272 // and templates in C++.
273 //
274 // FIXME: All of this logic should be sunk into getInlineCost. It relies on
275 // the internal implementation of the inline cost metrics rather than
276 // treating them as truly abstract units etc.
277 TotalSecondaryCost = 0;
278 // The candidate cost to be imposed upon the current function.
279 int CandidateCost = IC.getCost() - 1;
280 // If the caller has local linkage and can be inlined to all its callers, we
281 // can apply a huge negative bonus to TotalSecondaryCost.
282 bool ApplyLastCallBonus = Caller->hasLocalLinkage() && !Caller->hasOneUse();
283 // This bool tracks what happens if we DO inline C into B.
284 bool InliningPreventsSomeOuterInline = false;
285 unsigned NumCallerUsers = 0;
286 for (User *U : Caller->users()) {
288
289 // If this isn't a call to Caller (it could be some other sort
290 // of reference) skip it. Such references will prevent the caller
291 // from being removed.
292 if (!CS2 || CS2->getCalledFunction() != Caller) {
293 ApplyLastCallBonus = false;
294 continue;
295 }
296
297 InlineCost IC2 = GetInlineCost(*CS2);
298 ++NumCallerCallersAnalyzed;
299 if (!IC2) {
300 ApplyLastCallBonus = false;
301 continue;
302 }
303 if (IC2.isAlways())
304 continue;
305
306 // See if inlining of the original callsite would erase the cost delta of
307 // this callsite. We subtract off the penalty for the call instruction,
308 // which we would be deleting.
309 if (IC2.getCostDelta() <= CandidateCost) {
310 InliningPreventsSomeOuterInline = true;
311 TotalSecondaryCost += IC2.getCost();
312 NumCallerUsers++;
313 }
314 }
315
316 if (!InliningPreventsSomeOuterInline)
317 return false;
318
319 // If all outer calls to Caller would get inlined, the cost for the last
320 // one is set very low by getInlineCost, in anticipation that Caller will
321 // be removed entirely. We did not account for this above unless there
322 // is only one caller of Caller.
323 if (ApplyLastCallBonus)
324 TotalSecondaryCost -= CallerTTI.getInliningLastCallToStaticBonus();
325
326 // If InlineDeferralScale is negative, then ignore the cost of primary
327 // inlining -- IC.getCost() multiplied by the number of callers to Caller.
328 int InlineDeferralScale = getAnalysisOptions(*Caller).inline_deferral_scale;
329 if (InlineDeferralScale < 0)
330 return TotalSecondaryCost < IC.getCost();
331
332 int TotalCost = TotalSecondaryCost + IC.getCost() * NumCallerUsers;
333 int Allowance = IC.getCost() * InlineDeferralScale;
334 return TotalCost < Allowance;
335}
336
337namespace llvm {
338static raw_ostream &operator<<(raw_ostream &R, const ore::NV &Arg) {
339 return R << Arg.Val;
340}
341
342template <class RemarkT>
343decltype(auto) operator<<(RemarkT &&R, const InlineCost &IC) {
344 using namespace ore;
345 if (IC.isAlways()) {
346 R << "(cost=always)";
347 } else if (IC.isNever()) {
348 R << "(cost=never)";
349 } else {
350 R << "(cost=" << ore::NV("Cost", IC.getCost())
351 << ", threshold=" << ore::NV("Threshold", IC.getThreshold()) << ")";
352 }
353 if (const char *Reason = IC.getReason())
354 R << ": " << ore::NV("Reason", Reason);
355 return std::forward<RemarkT>(R);
356}
357} // namespace llvm
358
359std::string llvm::inlineCostStr(const InlineCost &IC) {
360 std::string Buffer;
362 Remark << IC;
363 return Remark.str();
364}
365
367 if (!getAnalysisOptions(CB.getContext()).inline_remark_attribute)
368 return;
369
370 Attribute Attr = Attribute::get(CB.getContext(), "inline-remark", Message);
371 CB.addFnAttr(Attr);
372}
373
374/// Return the cost only if the inliner should attempt to inline at the given
375/// CallSite. If we return the cost, we will emit an optimisation remark later
376/// using that cost, so we won't do so from this function. Return std::nullopt
377/// if inlining should not be attempted.
378std::optional<InlineCost>
380 function_ref<InlineCost(CallBase &CB)> GetInlineCost,
381 OptimizationRemarkEmitter &ORE, bool EnableDeferral) {
382 using namespace ore;
383
384 InlineCost IC = GetInlineCost(CB);
385 Instruction *Call = &CB;
386 Function *Callee = CB.getCalledFunction();
387 Function *Caller = CB.getCaller();
388
389 if (IC.isAlways()) {
390 LLVM_DEBUG(dbgs() << " Inlining " << inlineCostStr(IC)
391 << ", Call: " << CB << "\n");
392 return IC;
393 }
394
395 if (!IC) {
396 LLVM_DEBUG(dbgs() << " NOT Inlining " << inlineCostStr(IC)
397 << ", Call: " << CB << "\n");
398 if (IC.isNever()) {
399 ORE.emit([&]() {
400 return OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline", Call)
401 << "'" << NV("Callee", Callee) << "' not inlined into '"
402 << NV("Caller", Caller)
403 << "' because it should never be inlined " << IC;
404 });
405 } else {
406 ORE.emit([&]() {
407 return OptimizationRemarkMissed(DEBUG_TYPE, "TooCostly", Call)
408 << "'" << NV("Callee", Callee) << "' not inlined into '"
409 << NV("Caller", Caller) << "' because too costly to inline "
410 << IC;
411 });
412 }
414 return std::nullopt;
415 }
416
417 int TotalSecondaryCost = 0;
418 if (EnableDeferral && shouldBeDeferred(Caller, CallerTTI, IC,
419 TotalSecondaryCost, GetInlineCost)) {
420 LLVM_DEBUG(dbgs() << " NOT Inlining: " << CB
421 << " Cost = " << IC.getCost()
422 << ", outer Cost = " << TotalSecondaryCost << '\n');
423 ORE.emit([&]() {
424 return OptimizationRemarkMissed(DEBUG_TYPE, "IncreaseCostInOtherContexts",
425 Call)
426 << "Not inlining. Cost of inlining '" << NV("Callee", Callee)
427 << "' increases the cost of inlining '" << NV("Caller", Caller)
428 << "' in other contexts";
429 });
430 setInlineRemark(CB, "deferred");
431 return std::nullopt;
432 }
433
434 LLVM_DEBUG(dbgs() << " Inlining " << inlineCostStr(IC) << ", Call: " << CB
435 << '\n');
436 return IC;
437}
438
440 const CallSiteFormat &Format) {
441 std::string Buffer;
442 raw_string_ostream CallSiteLoc(Buffer);
443 ListSeparator LS(" @ ");
444 for (DILocation *DIL = DLoc.get(); DIL; DIL = DIL->getInlinedAt()) {
445 CallSiteLoc << LS;
446 // Note that negative line offset is actually possible, but we use
447 // unsigned int to match line offset representation in remarks so
448 // it's directly consumable by relay advisor.
450 DIL->getLine() - DIL->getScope()->getSubprogram()->getLine();
451 uint32_t Discriminator = DIL->getBaseDiscriminator();
452 StringRef Name = DIL->getScope()->getSubprogram()->getLinkageName();
453 if (Name.empty())
454 Name = DIL->getScope()->getSubprogram()->getName();
455 CallSiteLoc << Name.str() << ":" << llvm::utostr(Offset);
456 if (Format.outputColumn())
457 CallSiteLoc << ":" << llvm::utostr(DIL->getColumn());
458 if (Format.outputDiscriminator() && Discriminator)
459 CallSiteLoc << "." << llvm::utostr(Discriminator);
460 }
461
462 return CallSiteLoc.str();
463}
464
466 if (!DLoc)
467 return;
468
469 bool First = true;
470 Remark << " at callsite ";
471 for (DILocation *DIL = DLoc.get(); DIL; DIL = DIL->getInlinedAt()) {
472 if (!First)
473 Remark << " @ ";
474 unsigned int Offset = DIL->getLine();
475 Offset -= DIL->getScope()->getSubprogram()->getLine();
476 unsigned int Discriminator = DIL->getBaseDiscriminator();
477 StringRef Name = DIL->getScope()->getSubprogram()->getLinkageName();
478 if (Name.empty())
479 Name = DIL->getScope()->getSubprogram()->getName();
480 Remark << Name << ":" << ore::NV("Line", Offset) << ":"
481 << ore::NV("Column", DIL->getColumn());
482 if (Discriminator)
483 Remark << "." << ore::NV("Disc", Discriminator);
484 First = false;
485 }
486
487 Remark << ";";
488}
489
492 const Function &Callee, const Function &Caller, bool AlwaysInline,
493 function_ref<void(OptimizationRemark &)> ExtraContext,
494 const char *PassName) {
495 ORE.emit([&]() {
496 StringRef RemarkName = AlwaysInline ? "AlwaysInline" : "Inlined";
498 DLoc, Block);
499 Remark << "'" << ore::NV("Callee", &Callee) << "' inlined into '"
500 << ore::NV("Caller", &Caller) << "'";
501 if (ExtraContext)
502 ExtraContext(Remark);
504 return Remark;
505 });
506}
507
510 const Function &Callee, const Function &Caller, const InlineCost &IC,
511 bool ForProfileContext, const char *PassName) {
513 ORE, DLoc, Block, Callee, Caller, IC.isAlways(),
515 if (ForProfileContext)
516 Remark << " to match profiling context";
517 Remark << " with " << IC;
518 },
519 PassName);
520}
521
523 std::optional<InlineContext> IC)
524 : M(M), FAM(FAM), IC(IC),
526 (IC && getAnalysisOptions(M).annotate_inline_phase)
528 : DEBUG_TYPE) {
529 if (getAnalysisOptions(M).inliner_function_import_stats !=
532 std::make_unique<ImportedFunctionsInliningStatistics>();
533 ImportedFunctionsStats->setModuleInfo(M);
534 }
535}
536
543
544std::unique_ptr<InlineAdvice> InlineAdvisor::getMandatoryAdvice(CallBase &CB,
545 bool Advice) {
546 return std::make_unique<MandatoryInlineAdvice>(this, CB, getCallerORE(CB),
547 Advice);
548}
549
550static inline const char *getLTOPhase(ThinOrFullLTOPhase LTOPhase) {
551 switch (LTOPhase) {
553 return "main";
556 return "prelink";
559 return "postlink";
560 }
561 llvm_unreachable("unreachable");
562}
563
564static inline const char *getInlineAdvisorContext(InlinePass IP) {
565 switch (IP) {
567 return "always-inline";
569 return "cgscc-inline";
571 return "early-inline";
573 return "ml-inline";
575 return "module-inline";
577 return "replay-cgscc-inline";
579 return "replay-sample-profile-inline";
581 return "sample-profile-inline";
582 }
583
584 llvm_unreachable("unreachable");
585}
586
588 return std::string(getLTOPhase(IC.LTOPhase)) + "-" +
589 std::string(getInlineAdvisorContext(IC.Pass));
590}
591
595 auto &Callee = *CB.getCalledFunction();
596
597 auto GetTLI = [&](Function &F) -> const TargetLibraryInfo & {
598 return FAM.getResult<TargetLibraryAnalysis>(F);
599 };
600
601 auto &TIR = FAM.getResult<TargetIRAnalysis>(*CB.getCaller());
602
603 auto TrivialDecision =
604 llvm::getAttributeBasedInliningDecision(CB, &Callee, TIR, GetTLI);
605
606 if (TrivialDecision) {
607 if (TrivialDecision->isSuccess())
609 else
611 }
613}
614
615std::unique_ptr<InlineAdvice> InlineAdvisor::getAdvice(CallBase &CB,
616 bool MandatoryOnly) {
617 if (!MandatoryOnly)
618 return getAdviceImpl(CB);
619 bool Advice = CB.getCaller() != CB.getCalledFunction() &&
622 return getMandatoryAdvice(CB, Advice);
623}
624
628
631 const auto *IA = MAM.getCachedResult<InlineAdvisorAnalysis>(M);
632 if (!IA)
633 OS << "No Inline Advisor\n";
634 else
635 IA->getAdvisor()->print(OS);
636 return PreservedAnalyses::all();
637}
638
641 CGSCCUpdateResult &UR) {
642 const auto &MAMProxy =
644
645 if (InitialC.size() == 0) {
646 OS << "SCC is empty!\n";
647 return PreservedAnalyses::all();
648 }
649 Module &M = *InitialC.begin()->getFunction().getParent();
650 const auto *IA = MAMProxy.getCachedResult<InlineAdvisorAnalysis>(M);
651 if (!IA)
652 OS << "No Inline Advisor\n";
653 else
654 IA->getAdvisor()->print(OS);
655 return PreservedAnalyses::all();
656}
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 &CallerTTI, 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:628
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
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 InlineCost getInlineCost(CallBase &Call, const InlineParams &Params, TargetTransformInfo &CallerTTI, function_ref< AssumptionCache &(Function &)> GetAssumptionCache, function_ref< const TargetLibraryInfo &(Function &)> GetTLI, function_ref< BlockFrequencyInfo &(Function &)> GetBFI=nullptr, ProfileSummaryInfo *PSI=nullptr, OptimizationRemarkEmitter *ORE=nullptr, function_ref< EphemeralValuesCache &(Function &)> GetEphValuesCache=nullptr)
Get an InlineCost object representing the cost of inlining this callsite.
LLVM_ABI 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:
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.
LLVM_ABI std::optional< InlineResult > getAttributeBasedInliningDecision(CallBase &Call, Function *Callee, TargetTransformInfo &CallerTTI, function_ref< const TargetLibraryInfo &(Function &)> GetTLI)
Returns InlineResult::success() if the call site should be always inlined because of user directives,...
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)
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
LLVM_ABI std::optional< InlineCost > shouldInline(CallBase &CB, TargetTransformInfo &CallerTTI, 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, LazyCallGraph::SCC, LazyCallGraph & > ModuleAnalysisManagerCGSCCProxy
A proxy from a ModuleAnalysisManager to an SCC.
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