LLVM 22.0.0git
InlineAdvisor.h
Go to the documentation of this file.
1//===- InlineAdvisor.h - Inlining decision making abstraction -*- C++ ---*-===//
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#ifndef LLVM_ANALYSIS_INLINEADVISOR_H
10#define LLVM_ANALYSIS_INLINEADVISOR_H
11
15#include "llvm/IR/PassManager.h"
17#include <memory>
18
19namespace llvm {
20class BasicBlock;
21class CallBase;
22class Function;
23class Module;
24class OptimizationRemark;
25class ImportedFunctionsInliningStatistics;
26class OptimizationRemarkEmitter;
27struct ReplayInlinerSettings;
28
29/// There are 4 scenarios we can use the InlineAdvisor:
30/// - Default - use manual heuristics.
31///
32/// - Release mode, the expected mode for production, day to day deployments.
33/// In this mode, when building the compiler, we also compile a pre-trained ML
34/// model to native code, and link it as a static library. This mode has low
35/// overhead and no additional dependencies for the compiler runtime.
36///
37/// - Development mode, for training new models.
38/// In this mode, we trade off runtime performance for flexibility. This mode
39/// requires the TFLite library, and evaluates models dynamically. This mode
40/// also permits generating training logs, for offline training.
41///
42/// - Dynamically load an advisor via a plugin (PluginInlineAdvisorAnalysis)
44
45// Each entry represents an inline driver.
46enum class InlinePass : int {
55};
56
57/// Provides context on when an inline advisor is constructed in the pipeline
58/// (e.g., link phase, inline driver).
61
63};
64
66
67class InlineAdvisor;
68/// Capture state between an inlining decision having had been made, and
69/// its impact being observable. When collecting model training data, this
70/// allows recording features/decisions/partial reward data sets.
71///
72/// Derivations of this type are expected to be tightly coupled with their
73/// InliningAdvisors. The base type implements the minimal contractual
74/// obligations.
76public:
80
82 InlineAdvice(const InlineAdvice &) = delete;
83 virtual ~InlineAdvice() {
84 assert(Recorded && "InlineAdvice should have been informed of the "
85 "inliner's decision in all cases");
86 }
87
88 /// Exactly one of the record* APIs must be called. Implementers may extend
89 /// behavior by implementing the corresponding record*Impl.
90 ///
91 /// Call after inlining succeeded, and did not result in deleting the callee.
93
94 /// Call after inlining succeeded, and results in the callee being
95 /// delete-able, meaning, it has no more users, and will be cleaned up
96 /// subsequently.
98
99 /// Call after the decision for a call site was to not inline.
101 markRecorded();
103 }
104
105 /// Call to indicate inlining was not attempted.
107 markRecorded();
109 }
110
111 /// Get the inlining recommendation.
113 const DebugLoc &getOriginalCallSiteDebugLoc() const { return DLoc; }
115
116protected:
117 virtual void recordInliningImpl() {}
119 virtual void recordUnsuccessfulInliningImpl(const InlineResult &Result) {}
121
123 /// Caller and Callee are pre-inlining.
126
127 // Capture the context of CB before inlining, as a successful inlining may
128 // change that context, and we want to report success or failure in the
129 // original context.
131 const BasicBlock *const Block;
134
135private:
136 void markRecorded() {
137 assert(!Recorded && "Recording should happen exactly once");
138 Recorded = true;
139 }
140 void recordInlineStatsIfNeeded();
141
142 bool Recorded = false;
143};
144
146public:
148 std::optional<InlineCost> OIC,
149 OptimizationRemarkEmitter &ORE, bool EmitRemarks = true)
150 : InlineAdvice(Advisor, CB, ORE, OIC.has_value()), OriginalCB(&CB),
151 OIC(OIC), EmitRemarks(EmitRemarks) {}
152
153private:
154 void recordUnsuccessfulInliningImpl(const InlineResult &Result) override;
155 void recordInliningWithCalleeDeletedImpl() override;
156 void recordInliningImpl() override;
157
158private:
159 CallBase *const OriginalCB;
160 std::optional<InlineCost> OIC;
161 bool EmitRemarks;
162};
163
164/// Interface for deciding whether to inline a call site or not.
166public:
168 virtual ~InlineAdvisor();
169
170 /// Get an InlineAdvice containing a recommendation on whether to
171 /// inline or not. \p CB is assumed to be a direct call. \p FAM is assumed to
172 /// be up-to-date wrt previous inlining decisions. \p MandatoryOnly indicates
173 /// only mandatory (always-inline) call sites should be recommended - this
174 /// allows the InlineAdvisor track such inlininings.
175 /// Returns:
176 /// - An InlineAdvice with the inlining recommendation.
177 /// - Null when no recommendation is made (https://reviews.llvm.org/D110658).
178 /// TODO: Consider removing the Null return scenario by incorporating the
179 /// SampleProfile inliner into an InlineAdvisor
180 std::unique_ptr<InlineAdvice> getAdvice(CallBase &CB,
181 bool MandatoryOnly = false);
182
183 /// This must be called when the Inliner pass is entered, to allow the
184 /// InlineAdvisor update internal state, as result of function passes run
185 /// between Inliner pass runs (for the same module).
186 virtual void onPassEntry(LazyCallGraph::SCC *SCC = nullptr) {}
187
188 /// This must be called when the Inliner pass is exited, as function passes
189 /// may be run subsequently. This allows an implementation of InlineAdvisor
190 /// to prepare for a partial update, based on the optional SCC.
191 virtual void onPassExit(LazyCallGraph::SCC *SCC = nullptr) {}
192
193 /// Support for printer pass
194 virtual void print(raw_ostream &OS) const {
195 OS << "Unimplemented InlineAdvisor print\n";
196 }
197
198 /// NOTE pass name is annotated only when inline advisor constructor provides InlineContext.
199 const char *getAnnotatedInlinePassName() const {
200 return AnnotatedInlinePassName.c_str();
201 }
202
203protected:
205 std::optional<InlineContext> IC = std::nullopt);
206 virtual std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) = 0;
207 virtual std::unique_ptr<InlineAdvice> getMandatoryAdvice(CallBase &CB,
208 bool Advice);
209
212 const std::optional<InlineContext> IC;
213 const std::string AnnotatedInlinePassName;
214 std::unique_ptr<ImportedFunctionsInliningStatistics> ImportedFunctionsStats;
215
216 enum class MandatoryInliningKind { NotMandatory, Always, Never };
217
218 static MandatoryInliningKind getMandatoryKind(CallBase &CB,
221
222 OptimizationRemarkEmitter &getCallerORE(CallBase &CB);
223
224private:
225 friend class InlineAdvice;
226};
227
228/// The default (manual heuristics) implementation of the InlineAdvisor. This
229/// implementation does not need to keep state between inliner pass runs, and is
230/// reusable as-is for inliner pass test scenarios, as well as for regular use.
232public:
234 InlineParams Params, InlineContext IC)
235 : InlineAdvisor(M, FAM, IC), Params(Params) {}
236
237private:
238 std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) override;
239
240 InlineParams Params;
241};
242
243/// Used for dynamically registering InlineAdvisors as plugins
244///
245/// An advisor plugin adds a new advisor at runtime by registering an instance
246/// of PluginInlineAdvisorAnalysis in the current ModuleAnalysisManager.
247/// For example, the following code dynamically registers a
248/// DefaultInlineAdvisor:
249///
250/// namespace {
251///
252/// InlineAdvisor *defaultAdvisorFactory(Module &M,
253/// FunctionAnalysisManager &FAM,
254/// InlineParams Params,
255/// InlineContext IC) {
256/// return new DefaultInlineAdvisor(M, FAM, Params, IC);
257/// }
258///
259/// } // namespace
260///
261/// extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
262/// llvmGetPassPluginInfo() {
263/// return {LLVM_PLUGIN_API_VERSION, "DynamicDefaultAdvisor",
264/// LLVM_VERSION_STRING,
265/// [](PassBuilder &PB) {
266/// PB.registerAnalysisRegistrationCallback(
267/// [](ModuleAnalysisManager &MAM) {
268/// PluginInlineAdvisorAnalysis PA(defaultAdvisorFactory);
269/// MAM.registerPass([&] { return PA; });
270/// });
271/// }};
272/// }
273///
274/// A plugin must implement an AdvisorFactory and register it with a
275/// PluginInlineAdvisorAnlysis to the provided ModuleAnalysisManager.
276///
277/// If such a plugin has been registered
278/// InlineAdvisorAnalysis::Result::tryCreate will return the dynamically loaded
279/// advisor.
280///
282 : public AnalysisInfoMixin<PluginInlineAdvisorAnalysis> {
283public:
285
286 typedef InlineAdvisor *(*AdvisorFactory)(Module &M,
288 InlineParams Params,
289 InlineContext IC);
290
291 PluginInlineAdvisorAnalysis(AdvisorFactory Factory) : Factory(Factory) {
292 assert(Factory != nullptr &&
293 "The plugin advisor factory should not be a null pointer.");
294 }
295
296 struct Result {
298 };
299
300 Result run(Module &M, ModuleAnalysisManager &MAM) { return {Factory}; }
301 Result getResult() { return {Factory}; }
302
303private:
304 AdvisorFactory Factory;
305};
306
307/// The InlineAdvisorAnalysis is a module pass because the InlineAdvisor
308/// needs to capture state right before inlining commences over a module.
309class InlineAdvisorAnalysis : public AnalysisInfoMixin<InlineAdvisorAnalysis> {
310public:
313 struct Result {
317 // Check whether the analysis has been explicitly invalidated. Otherwise,
318 // it's stateless and remains preserved.
319 auto PAC = PA.getChecker<InlineAdvisorAnalysis>();
320 return !PAC.preservedWhenStateless();
321 }
323 const ReplayInlinerSettings &ReplaySettings,
324 InlineContext IC);
325 InlineAdvisor *getAdvisor() const { return Advisor.get(); }
326
327 private:
328 Module &M;
330 std::unique_ptr<InlineAdvisor> Advisor;
331 };
332
334
335private:
336 static bool initializeIR2VecVocabIfRequested(Module &M,
338};
339
340/// Printer pass for the InlineAdvisorAnalysis results.
342 : public PassInfoMixin<InlineAdvisorAnalysisPrinterPass> {
343 raw_ostream &OS;
344
345public:
347
349
353 static bool isRequired() { return true; }
354};
355
356LLVM_ABI std::unique_ptr<InlineAdvisor>
358 std::function<bool(CallBase &)> GetDefaultAdvice);
359
360LLVM_ABI std::unique_ptr<InlineAdvisor>
362 std::function<bool(CallBase &)> GetDefaultAdvice);
363
364// Default (manual policy) decision making helper APIs. Shared with the legacy
365// pass manager inliner.
366
367/// Return the cost only if the inliner should attempt to inline at the given
368/// CallSite. If we return the cost, we will emit an optimisation remark later
369/// using that cost, so we won't do so from this function. Return std::nullopt
370/// if inlining should not be attempted.
371LLVM_ABI std::optional<InlineCost>
373 function_ref<InlineCost(CallBase &CB)> GetInlineCost,
374 OptimizationRemarkEmitter &ORE, bool EnableDeferral = true);
375
376/// Emit ORE message.
377LLVM_ABI void
379 const BasicBlock *Block, const Function &Callee,
380 const Function &Caller, bool IsMandatory,
381 function_ref<void(OptimizationRemark &)> ExtraContext = {},
382 const char *PassName = nullptr);
383
384/// Emit ORE message based in cost (default heuristic).
386 OptimizationRemarkEmitter &ORE, DebugLoc DLoc, const BasicBlock *Block,
387 const Function &Callee, const Function &Caller, const InlineCost &IC,
388 bool ForProfileContext = false, const char *PassName = nullptr);
389
390/// Add location info to ORE message.
391LLVM_ABI void addLocationToRemarks(OptimizationRemark &Remark, DebugLoc DLoc);
392
393/// Set the inline-remark attribute.
394LLVM_ABI void setInlineRemark(CallBase &CB, StringRef Message);
395
396/// Utility for extracting the inline cost message to a string.
397LLVM_ABI std::string inlineCostStr(const InlineCost &IC);
398} // namespace llvm
399#endif // LLVM_ANALYSIS_INLINEADVISOR_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This header provides classes for managing passes over SCCs of the call graph.
#define LLVM_ABI
Definition: Compiler.h:213
This header defines various interfaces for pass management in LLVM.
Implements a lazy call graph analysis and related passes for the new pass manager.
Machine Check Debug Module
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
raw_pwrite_stream & OS
static const char PassName[]
API to communicate dependencies between analyses during invalidation.
Definition: PassManager.h:294
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:255
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1116
A debug info location.
Definition: DebugLoc.h:124
DefaultInlineAdvice(InlineAdvisor *Advisor, CallBase &CB, std::optional< InlineCost > OIC, OptimizationRemarkEmitter &ORE, bool EmitRemarks=true)
The default (manual heuristics) implementation of the InlineAdvisor.
DefaultInlineAdvisor(Module &M, FunctionAnalysisManager &FAM, InlineParams Params, InlineContext IC)
Capture state between an inlining decision having had been made, and its impact being observable.
Definition: InlineAdvisor.h:75
Function *const Callee
Function *const Caller
Caller and Callee are pre-inlining.
InlineAdvice(InlineAdvice &&)=delete
void recordUnsuccessfulInlining(const InlineResult &Result)
Call after the decision for a call site was to not inline.
InlineAdvice(const InlineAdvice &)=delete
virtual void recordInliningWithCalleeDeletedImpl()
void recordUnattemptedInlining()
Call to indicate inlining was not attempted.
const DebugLoc & getOriginalCallSiteDebugLoc() const
virtual void recordInliningImpl()
const BasicBlock *const Block
const BasicBlock * getOriginalCallSiteBasicBlock() const
LLVM_ABI void recordInlining()
Exactly one of the record* APIs must be called.
OptimizationRemarkEmitter & ORE
virtual void recordUnsuccessfulInliningImpl(const InlineResult &Result)
virtual ~InlineAdvice()
Definition: InlineAdvisor.h:83
InlineAdvisor *const Advisor
virtual void recordUnattemptedInliningImpl()
const DebugLoc DLoc
LLVM_ABI void recordInliningWithCalleeDeleted()
Call after inlining succeeded, and results in the callee being delete-able, meaning,...
bool isInliningRecommended() const
Get the inlining recommendation.
const bool IsInliningRecommended
Printer pass for the InlineAdvisorAnalysis results.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
InlineAdvisorAnalysisPrinterPass(raw_ostream &OS)
The InlineAdvisorAnalysis is a module pass because the InlineAdvisor needs to capture state right bef...
Result run(Module &M, ModuleAnalysisManager &MAM)
static LLVM_ABI AnalysisKey Key
Interface for deciding whether to inline a call site or not.
const std::optional< InlineContext > IC
FunctionAnalysisManager & FAM
virtual void print(raw_ostream &OS) const
Support for printer pass.
const std::string AnnotatedInlinePassName
std::unique_ptr< ImportedFunctionsInliningStatistics > ImportedFunctionsStats
virtual void onPassEntry(LazyCallGraph::SCC *SCC=nullptr)
This must be called when the Inliner pass is entered, to allow the InlineAdvisor update internal stat...
const char * getAnnotatedInlinePassName() const
NOTE pass name is annotated only when inline advisor constructor provides InlineContext.
virtual void onPassExit(LazyCallGraph::SCC *SCC=nullptr)
This must be called when the Inliner pass is exited, as function passes may be run subsequently.
InlineAdvisor(InlineAdvisor &&)=delete
virtual std::unique_ptr< InlineAdvice > getAdviceImpl(CallBase &CB)=0
Represents the cost of inlining a function.
Definition: InlineCost.h:91
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 Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
The optimization diagnostic interface.
Diagnostic information for applied optimization remarks.
Used for dynamically registering InlineAdvisors as plugins.
PluginInlineAdvisorAnalysis(AdvisorFactory Factory)
InlineAdvisor *(* AdvisorFactory)(Module &M, FunctionAnalysisManager &FAM, InlineParams Params, InlineContext IC)
Result run(Module &M, ModuleAnalysisManager &MAM)
static LLVM_ABI AnalysisKey Key
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:112
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
Definition: Analysis.h:275
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
@ BasicBlock
Various leaf nodes.
Definition: ISDOpcodes.h:81
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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.
InliningAdvisorMode
There are 4 scenarios we can use the InlineAdvisor:
Definition: InlineAdvisor.h:43
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.
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)
LLVM_ABI void setInlineRemark(CallBase &CB, StringRef Message)
Set the inline-remark attribute.
LLVM_ABI std::string AnnotateInlinePassName(InlineContext IC)
ThinOrFullLTOPhase
This enumerates the LLVM full LTO or ThinLTO optimization phases.
Definition: Pass.h:77
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 void addLocationToRemarks(OptimizationRemark &Remark, DebugLoc DLoc)
Add location info to ORE message.
@ Default
The result values are uniform if and only if all operands are uniform.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition: MIRParser.h:39
A CRTP mix-in that provides informational APIs needed for analysis passes.
Definition: PassManager.h:93
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)
InlineAdvisor * getAdvisor() const
Result(Module &M, ModuleAnalysisManager &MAM)
bool invalidate(Module &, const PreservedAnalyses &PA, ModuleAnalysisManager::Invalidator &)
Provides context on when an inline advisor is constructed in the pipeline (e.g., link phase,...
Definition: InlineAdvisor.h:59
ThinOrFullLTOPhase LTOPhase
Definition: InlineAdvisor.h:60
Thresholds to tune inline cost analysis.
Definition: InlineCost.h:207
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:70