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