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 
14 #include "llvm/Analysis/InlineAdvisor.h"
15 #include "llvm/ADT/Statistic.h"
16 #include "llvm/Analysis/AssumptionCache.h"
17 #include "llvm/Analysis/InlineCost.h"
18 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
19 #include "llvm/Analysis/ProfileSummaryInfo.h"
20 #include "llvm/Analysis/ReplayInlineAdvisor.h"
21 #include "llvm/Analysis/TargetLibraryInfo.h"
22 #include "llvm/Analysis/TargetTransformInfo.h"
23 #include "llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h"
24 #include "llvm/IR/DebugInfoMetadata.h"
25 #include "llvm/IR/PassManager.h"
26 #include "llvm/Support/CommandLine.h"
27 #include "llvm/Support/raw_ostream.h"
28 
29 using namespace llvm;
30 #define DEBUG_TYPE "inline"
31 #ifdef LLVM_HAVE_TF_AOT_INLINERSIZEMODEL
32 #define LLVM_HAVE_TF_AOT
33 #endif
34 
35 // This weirdly named statistic tracks the number of times that, when attempting
36 // to inline a function A into B, we analyze the callers of B in order to see
37 // if those would be more profitable and blocked inline steps.
38 STATISTIC(NumCallerCallersAnalyzed, "Number of caller-callers analyzed");
39 
40 /// Flag to add inline messages as callsite attributes 'inline-remark'.
41 static cl::opt<bool>
42     InlineRemarkAttribute("inline-remark-attribute", cl::init(false),
43                           cl::Hidden,
44                           cl::desc("Enable adding inline-remark attribute to"
45                                    " callsites processed by inliner but decided"
46                                    " to be not inlined"));
47 
48 static cl::opt<bool> EnableInlineDeferral("inline-deferral", cl::init(false),
49                                           cl::Hidden,
50                                           cl::desc("Enable deferred inlining"));
51 
52 // An integer used to limit the cost of inline deferral.  The default negative
53 // number tells shouldBeDeferred to only take the secondary cost into account.
54 static cl::opt<int>
55     InlineDeferralScale("inline-deferral-scale",
56                         cl::desc("Scale to limit the cost of inline deferral"),
57                         cl::init(2), cl::Hidden);
58 
59 extern cl::opt<InlinerFunctionImportStatsOpts> InlinerFunctionImportStats;
60 
61 namespace {
62 using namespace llvm::ore;
63 class MandatoryInlineAdvice : public InlineAdvice {
64 public:
65   MandatoryInlineAdvice(InlineAdvisor *Advisor, CallBase &CB,
66                         OptimizationRemarkEmitter &ORE,
67                         bool IsInliningMandatory)
68       : InlineAdvice(Advisor, CB, ORE, IsInliningMandatory) {}
69 
70 private:
71   void recordInliningWithCalleeDeletedImpl() override { recordInliningImpl(); }
72 
73   void recordInliningImpl() override {
74     if (IsInliningRecommended)
75       emitInlinedInto(ORE, DLoc, Block, *Callee, *Caller, IsInliningRecommended,
76                       [&](OptimizationRemark &Remark) {
77                         Remark << ": always inline attribute";
78                       });
79   }
80 
81   void recordUnsuccessfulInliningImpl(const InlineResult &Result) override {
82     if (IsInliningRecommended)
83       ORE.emit([&]() {
84         return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
85                << "'" << NV("Callee", Callee) << "' is not AlwaysInline into '"
86                << NV("Caller", Caller)
87                << "': " << NV("Reason", Result.getFailureReason());
88       });
89   }
90 
91   void recordUnattemptedInliningImpl() override {
92     assert(!IsInliningRecommended && "Expected to attempt inlining");
93   }
94 };
95 } // namespace
96 
97 void DefaultInlineAdvice::recordUnsuccessfulInliningImpl(
98     const InlineResult &Result) {
99   using namespace ore;
100   llvm::setInlineRemark(*OriginalCB, std::string(Result.getFailureReason()) +
101                                          "; " + inlineCostStr(*OIC));
102   ORE.emit([&]() {
103     return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc, Block)
104            << "'" << NV("Callee", Callee) << "' is not inlined into '"
105            << NV("Caller", Caller)
106            << "': " << NV("Reason", Result.getFailureReason());
107   });
108 }
109 
110 void DefaultInlineAdvice::recordInliningWithCalleeDeletedImpl() {
111   if (EmitRemarks)
112     emitInlinedIntoBasedOnCost(ORE, DLoc, Block, *Callee, *Caller, *OIC);
113 }
114 
115 void DefaultInlineAdvice::recordInliningImpl() {
116   if (EmitRemarks)
117     emitInlinedIntoBasedOnCost(ORE, DLoc, Block, *Callee, *Caller, *OIC);
118 }
119 
120 llvm::Optional<llvm::InlineCost> static getDefaultInlineAdvice(
121     CallBase &CB, FunctionAnalysisManager &FAM, const InlineParams &Params) {
122   Function &Caller = *CB.getCaller();
123   ProfileSummaryInfo *PSI =
124       FAM.getResult<ModuleAnalysisManagerFunctionProxy>(Caller)
125           .getCachedResult<ProfileSummaryAnalysis>(
126               *CB.getParent()->getParent()->getParent());
127 
128   auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(Caller);
129   auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
130     return FAM.getResult<AssumptionAnalysis>(F);
131   };
132   auto GetBFI = [&](Function &F) -> BlockFrequencyInfo & {
133     return FAM.getResult<BlockFrequencyAnalysis>(F);
134   };
135   auto GetTLI = [&](Function &F) -> const TargetLibraryInfo & {
136     return FAM.getResult<TargetLibraryAnalysis>(F);
137   };
138 
139   auto GetInlineCost = [&](CallBase &CB) {
140     Function &Callee = *CB.getCalledFunction();
141     auto &CalleeTTI = FAM.getResult<TargetIRAnalysis>(Callee);
142     bool RemarksEnabled =
143         Callee.getContext().getDiagHandlerPtr()->isMissedOptRemarkEnabled(
144             DEBUG_TYPE);
145     return getInlineCost(CB, Params, CalleeTTI, GetAssumptionCache, GetTLI,
146                          GetBFI, PSI, RemarksEnabled ? &ORE : nullptr);
147   };
148   return llvm::shouldInline(
149       CB, GetInlineCost, ORE,
150       Params.EnableDeferral.getValueOr(EnableInlineDeferral));
151 }
152 
153 std::unique_ptr<InlineAdvice>
154 DefaultInlineAdvisor::getAdviceImpl(CallBase &CB) {
155   auto OIC = getDefaultInlineAdvice(CB, FAM, Params);
156   return std::make_unique<DefaultInlineAdvice>(
157       this, CB, OIC,
158       FAM.getResult<OptimizationRemarkEmitterAnalysis>(*CB.getCaller()));
159 }
160 
161 InlineAdvice::InlineAdvice(InlineAdvisor *Advisor, CallBase &CB,
162                            OptimizationRemarkEmitter &ORE,
163                            bool IsInliningRecommended)
164     : Advisor(Advisor), Caller(CB.getCaller()), Callee(CB.getCalledFunction()),
165       DLoc(CB.getDebugLoc()), Block(CB.getParent()), ORE(ORE),
166       IsInliningRecommended(IsInliningRecommended) {}
167 
168 void InlineAdvice::recordInlineStatsIfNeeded() {
169   if (Advisor->ImportedFunctionsStats)
170     Advisor->ImportedFunctionsStats->recordInline(*Caller, *Callee);
171 }
172 
173 void InlineAdvice::recordInlining() {
174   markRecorded();
175   recordInlineStatsIfNeeded();
176   recordInliningImpl();
177 }
178 
179 void InlineAdvice::recordInliningWithCalleeDeleted() {
180   markRecorded();
181   recordInlineStatsIfNeeded();
182   recordInliningWithCalleeDeletedImpl();
183 }
184 
185 AnalysisKey InlineAdvisorAnalysis::Key;
186 
187 bool InlineAdvisorAnalysis::Result::tryCreate(
188     InlineParams Params, InliningAdvisorMode Mode,
189     const ReplayInlinerSettings &ReplaySettings) {
190   auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
191   switch (Mode) {
192   case InliningAdvisorMode::Default:
193     LLVM_DEBUG(dbgs() << "Using default inliner heuristic.\n");
194     Advisor.reset(new DefaultInlineAdvisor(M, FAM, Params));
195     // Restrict replay to default advisor, ML advisors are stateful so
196     // replay will need augmentations to interleave with them correctly.
197     if (!ReplaySettings.ReplayFile.empty()) {
198       Advisor = llvm::getReplayInlineAdvisor(M, FAM, M.getContext(),
199                                              std::move(Advisor), ReplaySettings,
200                                              /* EmitRemarks =*/true);
201     }
202     break;
203   case InliningAdvisorMode::Development:
204 #ifdef LLVM_HAVE_TF_API
205     LLVM_DEBUG(dbgs() << "Using development-mode inliner policy.\n");
206     Advisor =
207         llvm::getDevelopmentModeAdvisor(M, MAM, [&FAM, Params](CallBase &CB) {
208           auto OIC = getDefaultInlineAdvice(CB, FAM, Params);
209           return OIC.hasValue();
210         });
211 #endif
212     break;
213   case InliningAdvisorMode::Release:
214 #ifdef LLVM_HAVE_TF_AOT
215     LLVM_DEBUG(dbgs() << "Using release-mode inliner policy.\n");
216     Advisor = llvm::getReleaseModeAdvisor(M, MAM);
217 #endif
218     break;
219   }
220 
221   return !!Advisor;
222 }
223 
224 /// Return true if inlining of CB can block the caller from being
225 /// inlined which is proved to be more beneficial. \p IC is the
226 /// estimated inline cost associated with callsite \p CB.
227 /// \p TotalSecondaryCost will be set to the estimated cost of inlining the
228 /// caller if \p CB is suppressed for inlining.
229 static bool
230 shouldBeDeferred(Function *Caller, InlineCost IC, int &TotalSecondaryCost,
231                  function_ref<InlineCost(CallBase &CB)> GetInlineCost) {
232   // For now we only handle local or inline functions.
233   if (!Caller->hasLocalLinkage() && !Caller->hasLinkOnceODRLinkage())
234     return false;
235   // If the cost of inlining CB is non-positive, it is not going to prevent the
236   // caller from being inlined into its callers and hence we don't need to
237   // defer.
238   if (IC.getCost() <= 0)
239     return false;
240   // Try to detect the case where the current inlining candidate caller (call
241   // it B) is a static or linkonce-ODR function and is an inlining candidate
242   // elsewhere, and the current candidate callee (call it C) is large enough
243   // that inlining it into B would make B too big to inline later. In these
244   // circumstances it may be best not to inline C into B, but to inline B into
245   // its callers.
246   //
247   // This only applies to static and linkonce-ODR functions because those are
248   // expected to be available for inlining in the translation units where they
249   // are used. Thus we will always have the opportunity to make local inlining
250   // decisions. Importantly the linkonce-ODR linkage covers inline functions
251   // and templates in C++.
252   //
253   // FIXME: All of this logic should be sunk into getInlineCost. It relies on
254   // the internal implementation of the inline cost metrics rather than
255   // treating them as truly abstract units etc.
256   TotalSecondaryCost = 0;
257   // The candidate cost to be imposed upon the current function.
258   int CandidateCost = IC.getCost() - 1;
259   // If the caller has local linkage and can be inlined to all its callers, we
260   // can apply a huge negative bonus to TotalSecondaryCost.
261   bool ApplyLastCallBonus = Caller->hasLocalLinkage() && !Caller->hasOneUse();
262   // This bool tracks what happens if we DO inline C into B.
263   bool InliningPreventsSomeOuterInline = false;
264   unsigned NumCallerUsers = 0;
265   for (User *U : Caller->users()) {
266     CallBase *CS2 = dyn_cast<CallBase>(U);
267 
268     // If this isn't a call to Caller (it could be some other sort
269     // of reference) skip it.  Such references will prevent the caller
270     // from being removed.
271     if (!CS2 || CS2->getCalledFunction() != Caller) {
272       ApplyLastCallBonus = false;
273       continue;
274     }
275 
276     InlineCost IC2 = GetInlineCost(*CS2);
277     ++NumCallerCallersAnalyzed;
278     if (!IC2) {
279       ApplyLastCallBonus = false;
280       continue;
281     }
282     if (IC2.isAlways())
283       continue;
284 
285     // See if inlining of the original callsite would erase the cost delta of
286     // this callsite. We subtract off the penalty for the call instruction,
287     // which we would be deleting.
288     if (IC2.getCostDelta() <= CandidateCost) {
289       InliningPreventsSomeOuterInline = true;
290       TotalSecondaryCost += IC2.getCost();
291       NumCallerUsers++;
292     }
293   }
294 
295   if (!InliningPreventsSomeOuterInline)
296     return false;
297 
298   // If all outer calls to Caller would get inlined, the cost for the last
299   // one is set very low by getInlineCost, in anticipation that Caller will
300   // be removed entirely.  We did not account for this above unless there
301   // is only one caller of Caller.
302   if (ApplyLastCallBonus)
303     TotalSecondaryCost -= InlineConstants::LastCallToStaticBonus;
304 
305   // If InlineDeferralScale is negative, then ignore the cost of primary
306   // inlining -- IC.getCost() multiplied by the number of callers to Caller.
307   if (InlineDeferralScale < 0)
308     return TotalSecondaryCost < IC.getCost();
309 
310   int TotalCost = TotalSecondaryCost + IC.getCost() * NumCallerUsers;
311   int Allowance = IC.getCost() * InlineDeferralScale;
312   return TotalCost < Allowance;
313 }
314 
315 namespace llvm {
316 static raw_ostream &operator<<(raw_ostream &R, const ore::NV &Arg) {
317   return R << Arg.Val;
318 }
319 
320 template <class RemarkT>
321 RemarkT &operator<<(RemarkT &&R, const InlineCost &IC) {
322   using namespace ore;
323   if (IC.isAlways()) {
324     R << "(cost=always)";
325   } else if (IC.isNever()) {
326     R << "(cost=never)";
327   } else {
328     R << "(cost=" << ore::NV("Cost", IC.getCost())
329       << ", threshold=" << ore::NV("Threshold", IC.getThreshold()) << ")";
330   }
331   if (const char *Reason = IC.getReason())
332     R << ": " << ore::NV("Reason", Reason);
333   return R;
334 }
335 } // namespace llvm
336 
337 std::string llvm::inlineCostStr(const InlineCost &IC) {
338   std::string Buffer;
339   raw_string_ostream Remark(Buffer);
340   Remark << IC;
341   return Remark.str();
342 }
343 
344 void llvm::setInlineRemark(CallBase &CB, StringRef Message) {
345   if (!InlineRemarkAttribute)
346     return;
347 
348   Attribute Attr = Attribute::get(CB.getContext(), "inline-remark", Message);
349   CB.addFnAttr(Attr);
350 }
351 
352 /// Return the cost only if the inliner should attempt to inline at the given
353 /// CallSite. If we return the cost, we will emit an optimisation remark later
354 /// using that cost, so we won't do so from this function. Return None if
355 /// inlining should not be attempted.
356 Optional<InlineCost>
357 llvm::shouldInline(CallBase &CB,
358                    function_ref<InlineCost(CallBase &CB)> GetInlineCost,
359                    OptimizationRemarkEmitter &ORE, bool EnableDeferral) {
360   using namespace ore;
361 
362   InlineCost IC = GetInlineCost(CB);
363   Instruction *Call = &CB;
364   Function *Callee = CB.getCalledFunction();
365   Function *Caller = CB.getCaller();
366 
367   if (IC.isAlways()) {
368     LLVM_DEBUG(dbgs() << "    Inlining " << inlineCostStr(IC)
369                       << ", Call: " << CB << "\n");
370     return IC;
371   }
372 
373   if (!IC) {
374     LLVM_DEBUG(dbgs() << "    NOT Inlining " << inlineCostStr(IC)
375                       << ", Call: " << CB << "\n");
376     if (IC.isNever()) {
377       ORE.emit([&]() {
378         return OptimizationRemarkMissed(DEBUG_TYPE, "NeverInline", Call)
379                << "'" << NV("Callee", Callee) << "' not inlined into '"
380                << NV("Caller", Caller)
381                << "' because it should never be inlined " << IC;
382       });
383     } else {
384       ORE.emit([&]() {
385         return OptimizationRemarkMissed(DEBUG_TYPE, "TooCostly", Call)
386                << "'" << NV("Callee", Callee) << "' not inlined into '"
387                << NV("Caller", Caller) << "' because too costly to inline "
388                << IC;
389       });
390     }
391     setInlineRemark(CB, inlineCostStr(IC));
392     return None;
393   }
394 
395   int TotalSecondaryCost = 0;
396   if (EnableDeferral &&
397       shouldBeDeferred(Caller, IC, TotalSecondaryCost, GetInlineCost)) {
398     LLVM_DEBUG(dbgs() << "    NOT Inlining: " << CB
399                       << " Cost = " << IC.getCost()
400                       << ", outer Cost = " << TotalSecondaryCost << '\n');
401     ORE.emit([&]() {
402       return OptimizationRemarkMissed(DEBUG_TYPE, "IncreaseCostInOtherContexts",
403                                       Call)
404              << "Not inlining. Cost of inlining '" << NV("Callee", Callee)
405              << "' increases the cost of inlining '" << NV("Caller", Caller)
406              << "' in other contexts";
407     });
408     setInlineRemark(CB, "deferred");
409     return None;
410   }
411 
412   LLVM_DEBUG(dbgs() << "    Inlining " << inlineCostStr(IC) << ", Call: " << CB
413                     << '\n');
414   return IC;
415 }
416 
417 std::string llvm::formatCallSiteLocation(DebugLoc DLoc,
418                                          const CallSiteFormat &Format) {
419   std::string Buffer;
420   raw_string_ostream CallSiteLoc(Buffer);
421   bool First = true;
422   for (DILocation *DIL = DLoc.get(); DIL; DIL = DIL->getInlinedAt()) {
423     if (!First)
424       CallSiteLoc << " @ ";
425     // Note that negative line offset is actually possible, but we use
426     // unsigned int to match line offset representation in remarks so
427     // it's directly consumable by relay advisor.
428     uint32_t Offset =
429         DIL->getLine() - DIL->getScope()->getSubprogram()->getLine();
430     uint32_t Discriminator = DIL->getBaseDiscriminator();
431     StringRef Name = DIL->getScope()->getSubprogram()->getLinkageName();
432     if (Name.empty())
433       Name = DIL->getScope()->getSubprogram()->getName();
434     CallSiteLoc << Name.str() << ":" << llvm::utostr(Offset);
435     if (Format.outputColumn())
436       CallSiteLoc << ":" << llvm::utostr(DIL->getColumn());
437     if (Format.outputDiscriminator() && Discriminator)
438       CallSiteLoc << "." << llvm::utostr(Discriminator);
439     First = false;
440   }
441 
442   return CallSiteLoc.str();
443 }
444 
445 void llvm::addLocationToRemarks(OptimizationRemark &Remark, DebugLoc DLoc) {
446   if (!DLoc.get()) {
447     return;
448   }
449 
450   bool First = true;
451   Remark << " at callsite ";
452   for (DILocation *DIL = DLoc.get(); DIL; DIL = DIL->getInlinedAt()) {
453     if (!First)
454       Remark << " @ ";
455     unsigned int Offset = DIL->getLine();
456     Offset -= DIL->getScope()->getSubprogram()->getLine();
457     unsigned int Discriminator = DIL->getBaseDiscriminator();
458     StringRef Name = DIL->getScope()->getSubprogram()->getLinkageName();
459     if (Name.empty())
460       Name = DIL->getScope()->getSubprogram()->getName();
461     Remark << Name << ":" << ore::NV("Line", Offset) << ":"
462            << ore::NV("Column", DIL->getColumn());
463     if (Discriminator)
464       Remark << "." << ore::NV("Disc", Discriminator);
465     First = false;
466   }
467 
468   Remark << ";";
469 }
470 
471 void llvm::emitInlinedInto(
472     OptimizationRemarkEmitter &ORE, DebugLoc DLoc, const BasicBlock *Block,
473     const Function &Callee, const Function &Caller, bool AlwaysInline,
474     function_ref<void(OptimizationRemark &)> ExtraContext,
475     const char *PassName) {
476   ORE.emit([&]() {
477     StringRef RemarkName = AlwaysInline ? "AlwaysInline" : "Inlined";
478     OptimizationRemark Remark(PassName ? PassName : DEBUG_TYPE, RemarkName,
479                               DLoc, Block);
480     Remark << "'" << ore::NV("Callee", &Callee) << "' inlined into '"
481            << ore::NV("Caller", &Caller) << "'";
482     if (ExtraContext)
483       ExtraContext(Remark);
484     addLocationToRemarks(Remark, DLoc);
485     return Remark;
486   });
487 }
488 
489 void llvm::emitInlinedIntoBasedOnCost(
490     OptimizationRemarkEmitter &ORE, DebugLoc DLoc, const BasicBlock *Block,
491     const Function &Callee, const Function &Caller, const InlineCost &IC,
492     bool ForProfileContext, const char *PassName) {
493   llvm::emitInlinedInto(
494       ORE, DLoc, Block, Callee, Caller, IC.isAlways(),
495       [&](OptimizationRemark &Remark) {
496         if (ForProfileContext)
497           Remark << " to match profiling context";
498         Remark << " with " << IC;
499       },
500       PassName);
501 }
502 
503 InlineAdvisor::InlineAdvisor(Module &M, FunctionAnalysisManager &FAM)
504     : M(M), FAM(FAM) {
505   if (InlinerFunctionImportStats != InlinerFunctionImportStatsOpts::No) {
506     ImportedFunctionsStats =
507         std::make_unique<ImportedFunctionsInliningStatistics>();
508     ImportedFunctionsStats->setModuleInfo(M);
509   }
510 }
511 
512 InlineAdvisor::~InlineAdvisor() {
513   if (ImportedFunctionsStats) {
514     assert(InlinerFunctionImportStats != InlinerFunctionImportStatsOpts::No);
515     ImportedFunctionsStats->dump(InlinerFunctionImportStats ==
516                                  InlinerFunctionImportStatsOpts::Verbose);
517   }
518 }
519 
520 std::unique_ptr<InlineAdvice> InlineAdvisor::getMandatoryAdvice(CallBase &CB,
521                                                                 bool Advice) {
522   return std::make_unique<MandatoryInlineAdvice>(this, CB, getCallerORE(CB),
523                                                  Advice);
524 }
525 
526 InlineAdvisor::MandatoryInliningKind
527 InlineAdvisor::getMandatoryKind(CallBase &CB, FunctionAnalysisManager &FAM,
528                                 OptimizationRemarkEmitter &ORE) {
529   auto &Callee = *CB.getCalledFunction();
530 
531   auto GetTLI = [&](Function &F) -> const TargetLibraryInfo & {
532     return FAM.getResult<TargetLibraryAnalysis>(F);
533   };
534 
535   auto &TIR = FAM.getResult<TargetIRAnalysis>(Callee);
536 
537   auto TrivialDecision =
538       llvm::getAttributeBasedInliningDecision(CB, &Callee, TIR, GetTLI);
539 
540   if (TrivialDecision.hasValue()) {
541     if (TrivialDecision->isSuccess())
542       return MandatoryInliningKind::Always;
543     else
544       return MandatoryInliningKind::Never;
545   }
546   return MandatoryInliningKind::NotMandatory;
547 }
548 
549 std::unique_ptr<InlineAdvice> InlineAdvisor::getAdvice(CallBase &CB,
550                                                        bool MandatoryOnly) {
551   if (!MandatoryOnly)
552     return getAdviceImpl(CB);
553   bool Advice = CB.getCaller() != CB.getCalledFunction() &&
554                 MandatoryInliningKind::Always ==
555                     getMandatoryKind(CB, FAM, getCallerORE(CB));
556   return getMandatoryAdvice(CB, Advice);
557 }
558 
559 OptimizationRemarkEmitter &InlineAdvisor::getCallerORE(CallBase &CB) {
560   return FAM.getResult<OptimizationRemarkEmitterAnalysis>(*CB.getCaller());
561 }
562 
563 PreservedAnalyses
564 InlineAdvisorAnalysisPrinterPass::run(Module &M, ModuleAnalysisManager &MAM) {
565   const auto *IA = MAM.getCachedResult<InlineAdvisorAnalysis>(M);
566   if (!IA)
567     OS << "No Inline Advisor\n";
568   else
569     IA->getAdvisor()->print(OS);
570   return PreservedAnalyses::all();
571 }
572