34#define DEBUG_TYPE "inline" 
   35#ifdef LLVM_HAVE_TF_AOT_INLINERSIZEMODEL 
   36#define LLVM_HAVE_TF_AOT 
   42STATISTIC(NumCallerCallersAnalyzed, 
"Number of caller-callers analyzed");
 
   48                          cl::desc(
"Enable adding inline-remark attribute to" 
   49                                   " callsites processed by inliner but decided" 
   50                                   " to be not inlined"));
 
   54                                          cl::desc(
"Enable deferred inlining"));
 
   60                        cl::desc(
"Scale to limit the cost of inline deferral"),
 
   65                        cl::desc(
"If true, annotate inline advisor remarks " 
   66                                 "with LTO and pass information."));
 
   72    cl::desc(
"Vocab file for IR2Vec; Setting this enables " 
   73             "configuring the model to use IR2Vec embeddings."));
 
   85                        bool IsInliningMandatory)
 
   89  void recordInliningWithCalleeDeletedImpl()
 override { recordInliningImpl(); }
 
   91  void recordInliningImpl()
 override {
 
   92    if (IsInliningRecommended)
 
   95                        Remark << 
": always inline attribute";
 
   99  void recordUnsuccessfulInliningImpl(
const InlineResult &Result)
 override {
 
  100    if (IsInliningRecommended)
 
  103                                        "NotInlined", DLoc, 
Block)
 
  104               << 
"'" << 
NV(
"Callee", Callee) << 
"' is not AlwaysInline into '" 
  105               << 
NV(
"Caller", Caller)
 
  106               << 
"': " << 
NV(
"Reason", Result.getFailureReason());
 
  110  void recordUnattemptedInliningImpl()
 override {
 
  111    assert(!IsInliningRecommended && 
"Expected to attempt inlining");
 
  116void DefaultInlineAdvice::recordUnsuccessfulInliningImpl(
 
  122    return OptimizationRemarkMissed(
Advisor->getAnnotatedInlinePassName(),
 
  124           << 
"'" << 
NV(
"Callee", 
Callee) << 
"' is not inlined into '" 
  126           << 
"': " << 
NV(
"Reason", 
Result.getFailureReason());
 
  134                               Advisor->getAnnotatedInlinePassName());
 
  141                               Advisor->getAnnotatedInlinePassName());
 
  149          .getCachedResult<ProfileSummaryAnalysis>(
 
  150              *CB.
getParent()->getParent()->getParent());
 
  162  auto GetEphValuesCache =
 
  169  auto GetInlineCost = [&](
CallBase &CB) {
 
  170    bool RemarksEnabled =
 
  171        Callee.getContext().getDiagHandlerPtr()->isMissedOptRemarkEnabled(
 
  173    return getInlineCost(CB, Params, CalleeTTI, GetAssumptionCache, GetTLI,
 
  174                         GetBFI, PSI, RemarksEnabled ? &ORE : 
nullptr,
 
  178      CB, CalleeTTI, GetInlineCost, ORE,
 
 
  182std::unique_ptr<InlineAdvice>
 
  183DefaultInlineAdvisor::getAdviceImpl(
CallBase &CB) {
 
  185  return std::make_unique<DefaultInlineAdvice>(
 
  187      FAM.getResult<OptimizationRemarkEmitterAnalysis>(*CB.
getCaller()));
 
  197void InlineAdvice::recordInlineStatsIfNeeded() {
 
  204  recordInlineStatsIfNeeded();
 
 
  210  recordInlineStatsIfNeeded();
 
 
  217bool InlineAdvisorAnalysis::initializeIR2VecVocabIfRequested(
 
  221    if (!IR2VecVocabResult.isValid()) {
 
  222      M.getContext().emitError(
"Failed to load IR2Vec vocabulary");
 
  237    Advisor.reset(DA.Factory(M, 
FAM, Params, IC));
 
  240  auto GetDefaultAdvice = [&
FAM, Params](
CallBase &CB) {
 
  242    return OIC.has_value();
 
  252                                             std::move(Advisor), ReplaySettings,
 
  260#ifdef LLVM_HAVE_TFLITE 
  262    if (!InlineAdvisorAnalysis::initializeIR2VecVocabIfRequested(M, MAM))
 
  269    if (!InlineAdvisorAnalysis::initializeIR2VecVocabIfRequested(M, MAM))
 
 
  288  if (!Caller->hasLocalLinkage() && !Caller->hasLinkOnceODRLinkage())
 
  311  TotalSecondaryCost = 0;
 
  313  int CandidateCost = IC.
getCost() - 1;
 
  316  bool ApplyLastCallBonus = Caller->hasLocalLinkage() && !Caller->hasOneUse();
 
  318  bool InliningPreventsSomeOuterInline = 
false;
 
  319  unsigned NumCallerUsers = 0;
 
  320  for (
User *U : Caller->users()) {
 
  327      ApplyLastCallBonus = 
false;
 
  332    ++NumCallerCallersAnalyzed;
 
  334      ApplyLastCallBonus = 
false;
 
  344      InliningPreventsSomeOuterInline = 
true;
 
  345      TotalSecondaryCost += IC2.
getCost();
 
  350  if (!InliningPreventsSomeOuterInline)
 
  357  if (ApplyLastCallBonus)
 
  363    return TotalSecondaryCost < IC.
getCost();
 
  365  int TotalCost = TotalSecondaryCost + IC.
getCost() * NumCallerUsers;
 
  367  return TotalCost < Allowance;
 
 
  375template <
class RemarkT>
 
  376decltype(
auto) 
operator<<(RemarkT &&R, 
const InlineCost &IC) {
 
  379    R << 
"(cost=always)";
 
  387    R << 
": " << 
ore::NV(
"Reason", Reason);
 
  388  return std::forward<RemarkT>(R);
 
 
  411std::optional<InlineCost>
 
  424                      << 
", Call: " << CB << 
"\n");
 
  430                      << 
", Call: " << CB << 
"\n");
 
  434               << 
"'" << 
NV(
"Callee", Callee) << 
"' not inlined into '" 
  435               << 
NV(
"Caller", Caller)
 
  436               << 
"' because it should never be inlined " << IC;
 
  441               << 
"'" << 
NV(
"Callee", Callee) << 
"' not inlined into '" 
  442               << 
NV(
"Caller", Caller) << 
"' because too costly to inline " 
  450  int TotalSecondaryCost = 0;
 
  452                                         TotalSecondaryCost, GetInlineCost)) {
 
  455                      << 
", outer Cost = " << TotalSecondaryCost << 
'\n');
 
  459             << 
"Not inlining. Cost of inlining '" << 
NV(
"Callee", Callee)
 
  460             << 
"' increases the cost of inlining '" << 
NV(
"Caller", Caller)
 
  461             << 
"' in other contexts";
 
 
  477  for (
DILocation *DIL = DLoc.
get(); DIL; DIL = DIL->getInlinedAt()) {
 
  479      CallSiteLoc << 
" @ ";
 
  484        DIL->getLine() - DIL->getScope()->getSubprogram()->getLine();
 
  485    uint32_t Discriminator = DIL->getBaseDiscriminator();
 
  486    StringRef Name = DIL->getScope()->getSubprogram()->getLinkageName();
 
  488      Name = DIL->getScope()->getSubprogram()->getName();
 
  490    if (
Format.outputColumn())
 
  492    if (
Format.outputDiscriminator() && Discriminator)
 
  497  return CallSiteLoc.
str();
 
 
  506  Remark << 
" at callsite ";
 
  507  for (
DILocation *DIL = DLoc.
get(); DIL; DIL = DIL->getInlinedAt()) {
 
  510    unsigned int Offset = DIL->getLine();
 
  511    Offset -= DIL->getScope()->getSubprogram()->getLine();
 
  512    unsigned int Discriminator = DIL->getBaseDiscriminator();
 
  513    StringRef Name = DIL->getScope()->getSubprogram()->getLinkageName();
 
  515      Name = DIL->getScope()->getSubprogram()->getName();
 
  517           << 
ore::NV(
"Column", DIL->getColumn());
 
 
  532    StringRef RemarkName = AlwaysInline ? 
"AlwaysInline" : 
"Inlined";
 
  535    Remark << 
"'" << 
ore::NV(
"Callee", &Callee) << 
"' inlined into '" 
  536           << 
ore::NV(
"Caller", &Caller) << 
"'";
 
 
  547    bool ForProfileContext, 
const char *
PassName) {
 
  551        if (ForProfileContext)
 
  552          Remark << 
" to match profiling context";
 
  553        Remark << 
" with " << IC;
 
 
  559                             std::optional<InlineContext> 
IC)
 
  566        std::make_unique<ImportedFunctionsInliningStatistics>();
 
 
  581  return std::make_unique<MandatoryInlineAdvice>(
this, CB, 
getCallerORE(CB),
 
 
  602    return "always-inline";
 
  604    return "cgscc-inline";
 
  606    return "early-inline";
 
  610    return "module-inline";
 
  612    return "replay-cgscc-inline";
 
  614    return "replay-sample-profile-inline";
 
  616    return "sample-profile-inline";
 
 
  638  auto TrivialDecision =
 
  641  if (TrivialDecision) {
 
  642    if (TrivialDecision->isSuccess())
 
 
  651                                                       bool MandatoryOnly) {
 
 
  668    OS << 
"No Inline Advisor\n";
 
  670    IA->getAdvisor()->print(OS);
 
 
  677  const auto &MAMProxy =
 
  680  if (InitialC.
size() == 0) {
 
  681    OS << 
"SCC is empty!\n";
 
  684  Module &M = *InitialC.
begin()->getFunction().getParent();
 
  687    OS << 
"No Inline Advisor\n";
 
  689    IA->getAdvisor()->print(OS);
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static const Function * getParent(const Value *V)
This file defines the IR2Vec vocabulary analysis(IR2VecVocabAnalysis), the core ir2vec::Embedder inte...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
static bool shouldBeDeferred(Function *Caller, TargetTransformInfo &CalleeTTI, InlineCost IC, int &TotalSecondaryCost, function_ref< InlineCost(CallBase &CB)> GetInlineCost)
Return true if inlining of CB can block the caller from being inlined which is proved to be more bene...
static cl::opt< int > InlineDeferralScale("inline-deferral-scale", cl::desc("Scale to limit the cost of inline deferral"), cl::init(2), cl::Hidden)
static cl::opt< bool > InlineRemarkAttribute("inline-remark-attribute", cl::init(false), cl::Hidden, cl::desc("Enable adding inline-remark attribute to" " callsites processed by inliner but decided" " to be not inlined"))
Flag to add inline messages as callsite attributes 'inline-remark'.
static cl::opt< bool > EnableInlineDeferral("inline-deferral", cl::init(false), cl::Hidden, cl::desc("Enable deferred inlining"))
static cl::opt< bool > AnnotateInlinePhase("annotate-inline-phase", cl::Hidden, cl::init(false), cl::desc("If true, annotate inline advisor remarks " "with LTO and pass information."))
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)
static cl::opt< std::string > IR2VecVocabFile("ml-inliner-ir2vec-vocab-file", cl::Hidden, cl::desc("Vocab file for IR2Vec; Setting this enables " "configuring the model to use IR2Vec embeddings."))
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first found DebugLoc that has a DILocation, 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)
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...
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM Basic Block Representation.
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).
LLVM_ABI DILocation * get() const
Get the underlying DILocation.
The default (manual heuristics) implementation of the InlineAdvisor.
EphemeralValuesCache Result
This analysis provides the vocabulary for IR2Vec.
Capture state between an inlining decision having had been made, and its impact being observable.
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)
LLVM_ABI void recordInliningWithCalleeDeleted()
Call after inlining succeeded, and results in the callee being delete-able, meaning,...
const bool IsInliningRecommended
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
The InlineAdvisorAnalysis is a module pass because the InlineAdvisor needs to capture state right bef...
static LLVM_ABI AnalysisKey Key
Interface for deciding whether to inline a call site or not.
const std::optional< InlineContext > IC
OptimizationRemarkEmitter & getCallerORE(CallBase &CB)
FunctionAnalysisManager & FAM
static MandatoryInliningKind getMandatoryKind(CallBase &CB, FunctionAnalysisManager &FAM, OptimizationRemarkEmitter &ORE)
const std::string AnnotatedInlinePassName
virtual std::unique_ptr< InlineAdvice > getMandatoryAdvice(CallBase &CB, bool Advice)
std::unique_ptr< ImportedFunctionsInliningStatistics > ImportedFunctionsStats
const char * getAnnotatedInlinePassName() const
NOTE pass name is annotated only when inline advisor constructor provides InlineContext.
InlineAdvisor(InlineAdvisor &&)=delete
virtual std::unique_ptr< InlineAdvice > getAdviceImpl(CallBase &CB)=0
std::unique_ptr< InlineAdvice > getAdvice(CallBase &CB, bool MandatoryOnly=false)
Get an InlineAdvice containing a recommendation on whether to inline or not.
Represents the cost of inlining a function.
int getThreshold() const
Get the threshold against which the cost was computed.
const char * getReason() const
Get the reason of Always or Never.
int getCost() const
Get the inline cost estimate.
int getCostDelta() const
Get the cost delta from the threshold for inlining.
InlineResult is basically true or false.
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.
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.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Analysis providing profile information.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
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.
@ ReplaySampleProfileInliner
LLVM_ABI void emitInlinedInto(OptimizationRemarkEmitter &ORE, DebugLoc DLoc, const BasicBlock *Block, const Function &Callee, const Function &Caller, bool IsMandatory, function_ref< void(OptimizationRemark &)> ExtraContext={}, const char *PassName=nullptr)
Emit ORE message.
LLVM_ABI std::string inlineCostStr(const InlineCost &IC)
Utility for extracting the inline cost message to a string.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
InliningAdvisorMode
There are 4 scenarios we can use the InlineAdvisor:
LLVM_ABI std::optional< InlineCost > shouldInline(CallBase &CB, TargetTransformInfo &CalleeTTI, function_ref< InlineCost(CallBase &CB)> GetInlineCost, OptimizationRemarkEmitter &ORE, bool EnableDeferral=true)
Return the cost only if the inliner should attempt to inline at the given CallSite.
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI std::unique_ptr< InlineAdvisor > getDevelopmentModeAdvisor(Module &M, ModuleAnalysisManager &MAM, std::function< bool(CallBase &)> GetDefaultAdvice)
LLVM_ABI std::unique_ptr< InlineAdvisor > getReleaseModeAdvisor(Module &M, ModuleAnalysisManager &MAM, std::function< bool(CallBase &)> GetDefaultAdvice)
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
std::string utostr(uint64_t X, bool isNeg=false)
LLVM_ABI void setInlineRemark(CallBase &CB, StringRef Message)
Set the inline-remark attribute.
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
LLVM_ABI std::string AnnotateInlinePassName(InlineContext IC)
ThinOrFullLTOPhase
This enumerates the LLVM full LTO or ThinLTO optimization phases.
@ FullLTOPreLink
Full LTO prelink phase.
@ ThinLTOPostLink
ThinLTO postlink (backend compile) phase.
@ None
No LTO/ThinLTO behavior needed.
@ FullLTOPostLink
Full LTO postlink (backend compile) phase.
@ ThinLTOPreLink
ThinLTO prelink (summary) phase.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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).
std::unique_ptr< InlineAdvisor > getReplayInlineAdvisor(Module &M, FunctionAnalysisManager &FAM, LLVMContext &Context, std::unique_ptr< InlineAdvisor > OriginalAdvisor, const ReplayInlinerSettings &ReplaySettings, bool EmitRemarks, InlineContext IC)
LLVM_ABI InlineCost getInlineCost(CallBase &Call, const InlineParams &Params, TargetTransformInfo &CalleeTTI, function_ref< AssumptionCache &(Function &)> GetAssumptionCache, function_ref< const TargetLibraryInfo &(Function &)> GetTLI, function_ref< BlockFrequencyInfo &(Function &)> GetBFI=nullptr, ProfileSummaryInfo *PSI=nullptr, OptimizationRemarkEmitter *ORE=nullptr, function_ref< EphemeralValuesCache &(Function &)> GetEphValuesCache=nullptr)
Get an InlineCost object representing the cost of inlining this callsite.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI std::optional< InlineResult > getAttributeBasedInliningDecision(CallBase &Call, Function *Callee, TargetTransformInfo &CalleeTTI, function_ref< const TargetLibraryInfo &(Function &)> GetTLI)
Returns InlineResult::success() if the call site should be always inlined because of user directives,...
OuterAnalysisManagerProxy< ModuleAnalysisManager, LazyCallGraph::SCC, LazyCallGraph & > ModuleAnalysisManagerCGSCCProxy
A proxy from a ModuleAnalysisManager to an SCC.
cl::opt< InlinerFunctionImportStatsOpts > InlinerFunctionImportStats("inliner-function-import-stats", cl::init(InlinerFunctionImportStatsOpts::No), cl::values(clEnumValN(InlinerFunctionImportStatsOpts::Basic, "basic", "basic statistics"), clEnumValN(InlinerFunctionImportStatsOpts::Verbose, "verbose", "printing of statistics for each inlined function")), cl::Hidden, cl::desc("Enable inliner stats for imported functions"))
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LLVM_ABI void addLocationToRemarks(OptimizationRemark &Remark, DebugLoc DLoc)
Add location info to ORE message.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
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.
A special type used by analysis passes to provide an address that identifies that particular analysis...
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.
std::optional< bool > EnableDeferral
Indicate whether we should allow inline deferral.