LLVM 19.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/Config/llvm-config.h"
16#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:
79
81 InlineAdvice(const InlineAdvice &) = delete;
82 virtual ~InlineAdvice() {
83 assert(Recorded && "InlineAdvice should have been informed of the "
84 "inliner's decision in all cases");
85 }
86
87 /// Exactly one of the record* APIs must be called. Implementers may extend
88 /// behavior by implementing the corresponding record*Impl.
89 ///
90 /// Call after inlining succeeded, and did not result in deleting the callee.
91 void recordInlining();
92
93 /// Call after inlining succeeded, and results in the callee being
94 /// delete-able, meaning, it has no more users, and will be cleaned up
95 /// subsequently.
97
98 /// Call after the decision for a call site was to not inline.
100 markRecorded();
102 }
103
104 /// Call to indicate inlining was not attempted.
106 markRecorded();
108 }
109
110 /// Get the inlining recommendation.
112 const DebugLoc &getOriginalCallSiteDebugLoc() const { return DLoc; }
114
115protected:
116 virtual void recordInliningImpl() {}
118 virtual void recordUnsuccessfulInliningImpl(const InlineResult &Result) {}
120
122 /// Caller and Callee are pre-inlining.
125
126 // Capture the context of CB before inlining, as a successful inlining may
127 // change that context, and we want to report success or failure in the
128 // original context.
130 const BasicBlock *const Block;
133
134private:
135 void markRecorded() {
136 assert(!Recorded && "Recording should happen exactly once");
137 Recorded = true;
138 }
139 void recordInlineStatsIfNeeded();
140
141 bool Recorded = false;
142};
143
145public:
147 std::optional<InlineCost> OIC,
148 OptimizationRemarkEmitter &ORE, bool EmitRemarks = true)
149 : InlineAdvice(Advisor, CB, ORE, OIC.has_value()), OriginalCB(&CB),
150 OIC(OIC), EmitRemarks(EmitRemarks) {}
151
152private:
153 void recordUnsuccessfulInliningImpl(const InlineResult &Result) override;
154 void recordInliningWithCalleeDeletedImpl() override;
155 void recordInliningImpl() override;
156
157private:
158 CallBase *const OriginalCB;
159 std::optional<InlineCost> OIC;
160 bool EmitRemarks;
161};
162
163/// Interface for deciding whether to inline a call site or not.
165public:
167 virtual ~InlineAdvisor();
168
169 /// Get an InlineAdvice containing a recommendation on whether to
170 /// inline or not. \p CB is assumed to be a direct call. \p FAM is assumed to
171 /// be up-to-date wrt previous inlining decisions. \p MandatoryOnly indicates
172 /// only mandatory (always-inline) call sites should be recommended - this
173 /// allows the InlineAdvisor track such inlininings.
174 /// Returns:
175 /// - An InlineAdvice with the inlining recommendation.
176 /// - Null when no recommendation is made (https://reviews.llvm.org/D110658).
177 /// TODO: Consider removing the Null return scenario by incorporating the
178 /// SampleProfile inliner into an InlineAdvisor
179 std::unique_ptr<InlineAdvice> getAdvice(CallBase &CB,
180 bool MandatoryOnly = false);
181
182 /// This must be called when the Inliner pass is entered, to allow the
183 /// InlineAdvisor update internal state, as result of function passes run
184 /// between Inliner pass runs (for the same module).
185 virtual void onPassEntry(LazyCallGraph::SCC *SCC = nullptr) {}
186
187 /// This must be called when the Inliner pass is exited, as function passes
188 /// may be run subsequently. This allows an implementation of InlineAdvisor
189 /// to prepare for a partial update, based on the optional SCC.
190 virtual void onPassExit(LazyCallGraph::SCC *SCC = nullptr) {}
191
192 /// Support for printer pass
193 virtual void print(raw_ostream &OS) const {
194 OS << "Unimplemented InlineAdvisor print\n";
195 }
196
197 /// NOTE pass name is annotated only when inline advisor constructor provides InlineContext.
198 const char *getAnnotatedInlinePassName() const {
199 return AnnotatedInlinePassName.c_str();
200 }
201
202protected:
204 std::optional<InlineContext> IC = std::nullopt);
205 virtual std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) = 0;
206 virtual std::unique_ptr<InlineAdvice> getMandatoryAdvice(CallBase &CB,
207 bool Advice);
208
211 const std::optional<InlineContext> IC;
212 const std::string AnnotatedInlinePassName;
213 std::unique_ptr<ImportedFunctionsInliningStatistics> ImportedFunctionsStats;
214
216
220
222
223private:
224 friend class InlineAdvice;
225};
226
227/// The default (manual heuristics) implementation of the InlineAdvisor. This
228/// implementation does not need to keep state between inliner pass runs, and is
229/// reusable as-is for inliner pass test scenarios, as well as for regular use.
231public:
234 : InlineAdvisor(M, FAM, IC), Params(Params) {}
235
236private:
237 std::unique_ptr<InlineAdvice> getAdviceImpl(CallBase &CB) override;
238
239 InlineParams Params;
240};
241
242/// Used for dynamically registering InlineAdvisors as plugins
243///
244/// An advisor plugin adds a new advisor at runtime by registering an instance
245/// of PluginInlineAdvisorAnalysis in the current ModuleAnalysisManager.
246/// For example, the following code dynamically registers a
247/// DefaultInlineAdvisor:
248///
249/// namespace {
250///
251/// InlineAdvisor *defaultAdvisorFactory(Module &M, FunctionAnalysisManager
252/// &FAM,
253/// InlineParams Params, InlineContext IC)
254/// {
255/// return new DefaultInlineAdvisor(M, FAM, Params, IC);
256/// }
257///
258/// struct DefaultDynamicAdvisor : PassInfoMixin<DefaultDynamicAdvisor> {
259/// PreservedAnalyses run(Module &, ModuleAnalysisManager &MAM) {
260/// PluginInlineAdvisorAnalysis PA(defaultAdvisorFactory);
261/// MAM.registerPass([&] { return PA; });
262/// return PreservedAnalyses::all();
263/// }
264/// };
265///
266/// } // namespace
267///
268/// extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
269/// llvmGetPassPluginInfo() {
270/// return {LLVM_PLUGIN_API_VERSION, "DynamicDefaultAdvisor",
271/// LLVM_VERSION_STRING,
272/// [](PassBuilder &PB) {
273/// PB.registerPipelineStartEPCallback(
274/// [](ModulePassManager &MPM, OptimizationLevel Level) {
275/// MPM.addPass(DefaultDynamicAdvisor());
276/// });
277/// }};
278/// }
279///
280/// A plugin must implement an AdvisorFactory and register it with a
281/// PluginInlineAdvisorAnlysis to the provided ModuleanAlysisManager.
282///
283/// If such a plugin has been registered
284/// InlineAdvisorAnalysis::Result::tryCreate will return the dynamically loaded
285/// advisor.
286///
288 : public AnalysisInfoMixin<PluginInlineAdvisorAnalysis> {
289public:
291 static bool HasBeenRegistered;
292
293 typedef InlineAdvisor *(*AdvisorFactory)(Module &M,
295 InlineParams Params,
296 InlineContext IC);
297
298 PluginInlineAdvisorAnalysis(AdvisorFactory Factory) : Factory(Factory) {
299 HasBeenRegistered = true;
300 assert(Factory != nullptr &&
301 "The plugin advisor factory should not be a null pointer.");
302 }
303
304 struct Result {
306 };
307
308 Result run(Module &M, ModuleAnalysisManager &MAM) { return {Factory}; }
309 Result getResult() { return {Factory}; }
310
311private:
312 AdvisorFactory Factory;
313};
314
315/// The InlineAdvisorAnalysis is a module pass because the InlineAdvisor
316/// needs to capture state right before inlining commences over a module.
317class InlineAdvisorAnalysis : public AnalysisInfoMixin<InlineAdvisorAnalysis> {
318public:
321 struct Result {
325 // Check whether the analysis has been explicitly invalidated. Otherwise,
326 // it's stateless and remains preserved.
327 auto PAC = PA.getChecker<InlineAdvisorAnalysis>();
328 return !PAC.preservedWhenStateless();
329 }
331 const ReplayInlinerSettings &ReplaySettings,
332 InlineContext IC);
333 InlineAdvisor *getAdvisor() const { return Advisor.get(); }
334
335 private:
336 Module &M;
338 std::unique_ptr<InlineAdvisor> Advisor;
339 };
340
342};
343
344/// Printer pass for the InlineAdvisorAnalysis results.
346 : public PassInfoMixin<InlineAdvisorAnalysisPrinterPass> {
347 raw_ostream &OS;
348
349public:
351
353
356 static bool isRequired() { return true; }
357};
358
359std::unique_ptr<InlineAdvisor>
361 std::function<bool(CallBase &)> GetDefaultAdvice);
362
363std::unique_ptr<InlineAdvisor>
365 std::function<bool(CallBase &)> GetDefaultAdvice);
366
367// Default (manual policy) decision making helper APIs. Shared with the legacy
368// pass manager inliner.
369
370/// Return the cost only if the inliner should attempt to inline at the given
371/// CallSite. If we return the cost, we will emit an optimisation remark later
372/// using that cost, so we won't do so from this function. Return std::nullopt
373/// if inlining should not be attempted.
374std::optional<InlineCost>
375shouldInline(CallBase &CB, function_ref<InlineCost(CallBase &CB)> GetInlineCost,
376 OptimizationRemarkEmitter &ORE, bool EnableDeferral = true);
377
378/// Emit ORE message.
380 const BasicBlock *Block, const Function &Callee,
381 const Function &Caller, bool IsMandatory,
382 function_ref<void(OptimizationRemark &)> ExtraContext = {},
383 const char *PassName = nullptr);
384
385/// Emit ORE message based in cost (default heuristic).
386void emitInlinedIntoBasedOnCost(OptimizationRemarkEmitter &ORE, DebugLoc DLoc,
387 const BasicBlock *Block, const Function &Callee,
388 const Function &Caller, const InlineCost &IC,
389 bool ForProfileContext = false,
390 const char *PassName = nullptr);
391
392/// Add location info to ORE message.
393void addLocationToRemarks(OptimizationRemark &Remark, DebugLoc DLoc);
394
395/// Set the inline-remark attribute.
396void setInlineRemark(CallBase &CB, StringRef Message);
397
398/// Utility for extracting the inline cost message to a string.
399std::string inlineCostStr(const InlineCost &IC);
400} // namespace llvm
401#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:360
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:321
LLVM Basic Block Representation.
Definition: BasicBlock.h:60
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1494
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: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.
Definition: InlineAdvisor.h:99
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:82
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:109
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:43
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.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition: PassManager.h:605
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.
A CRTP mix-in that provides informational APIs needed for analysis passes.
Definition: PassManager.h:97
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: Analysis.h:26
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:59
ThinOrFullLTOPhase LTOPhase
Definition: InlineAdvisor.h:60
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:74