xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/IPO/Inliner.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- Inliner.cpp - Code common to all inliners --------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the mechanics required to implement inlining without
100b57cec5SDimitry Andric // missing any calls and updating the call graph.  The decisions of which calls
110b57cec5SDimitry Andric // are profitable to inline are implemented elsewhere.
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #include "llvm/Transforms/IPO/Inliner.h"
1681ad6265SDimitry Andric #include "llvm/ADT/PriorityWorklist.h"
170b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
185ffd83dbSDimitry Andric #include "llvm/ADT/ScopeExit.h"
190b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h"
200b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
210b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
220b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
23fb03ea46SDimitry Andric #include "llvm/ADT/StringExtras.h"
240b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
250b57cec5SDimitry Andric #include "llvm/Analysis/AssumptionCache.h"
260b57cec5SDimitry Andric #include "llvm/Analysis/BasicAliasAnalysis.h"
270b57cec5SDimitry Andric #include "llvm/Analysis/BlockFrequencyInfo.h"
280b57cec5SDimitry Andric #include "llvm/Analysis/CGSCCPassManager.h"
295ffd83dbSDimitry Andric #include "llvm/Analysis/InlineAdvisor.h"
300b57cec5SDimitry Andric #include "llvm/Analysis/InlineCost.h"
310b57cec5SDimitry Andric #include "llvm/Analysis/LazyCallGraph.h"
320b57cec5SDimitry Andric #include "llvm/Analysis/OptimizationRemarkEmitter.h"
330b57cec5SDimitry Andric #include "llvm/Analysis/ProfileSummaryInfo.h"
34349cc55cSDimitry Andric #include "llvm/Analysis/ReplayInlineAdvisor.h"
350b57cec5SDimitry Andric #include "llvm/Analysis/TargetLibraryInfo.h"
36e8d8bef9SDimitry Andric #include "llvm/Analysis/Utils/ImportedFunctionsInliningStatistics.h"
370b57cec5SDimitry Andric #include "llvm/IR/Attributes.h"
380b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
390b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h"
400b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
410b57cec5SDimitry Andric #include "llvm/IR/DiagnosticInfo.h"
420b57cec5SDimitry Andric #include "llvm/IR/Function.h"
430b57cec5SDimitry Andric #include "llvm/IR/InstIterator.h"
440b57cec5SDimitry Andric #include "llvm/IR/Instruction.h"
450b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
460b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
470b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
480b57cec5SDimitry Andric #include "llvm/IR/Module.h"
490b57cec5SDimitry Andric #include "llvm/IR/PassManager.h"
500b57cec5SDimitry Andric #include "llvm/IR/User.h"
510b57cec5SDimitry Andric #include "llvm/IR/Value.h"
520b57cec5SDimitry Andric #include "llvm/Pass.h"
530b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
540b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
550b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
560b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
575ffd83dbSDimitry Andric #include "llvm/Transforms/Utils/CallPromotionUtils.h"
580b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Cloning.h"
595ffd83dbSDimitry Andric #include "llvm/Transforms/Utils/Local.h"
600b57cec5SDimitry Andric #include "llvm/Transforms/Utils/ModuleUtils.h"
610b57cec5SDimitry Andric #include <algorithm>
620b57cec5SDimitry Andric #include <cassert>
630b57cec5SDimitry Andric #include <functional>
640b57cec5SDimitry Andric #include <utility>
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric using namespace llvm;
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric #define DEBUG_TYPE "inline"
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric STATISTIC(NumInlined, "Number of functions inlined");
710b57cec5SDimitry Andric STATISTIC(NumDeleted, "Number of functions deleted because all callers found");
720b57cec5SDimitry Andric 
73fb03ea46SDimitry Andric static cl::opt<int> IntraSCCCostMultiplier(
74fb03ea46SDimitry Andric     "intra-scc-cost-multiplier", cl::init(2), cl::Hidden,
75fb03ea46SDimitry Andric     cl::desc(
76fb03ea46SDimitry Andric         "Cost multiplier to multiply onto inlined call sites where the "
77fb03ea46SDimitry Andric         "new call was previously an intra-SCC call (not relevant when the "
78fb03ea46SDimitry Andric         "original call was already intra-SCC). This can accumulate over "
79fb03ea46SDimitry Andric         "multiple inlinings (e.g. if a call site already had a cost "
80fb03ea46SDimitry Andric         "multiplier and one of its inlined calls was also subject to "
81fb03ea46SDimitry Andric         "this, the inlined call would have the original multiplier "
82fb03ea46SDimitry Andric         "multiplied by intra-scc-cost-multiplier). This is to prevent tons of "
83fb03ea46SDimitry Andric         "inlining through a child SCC which can cause terrible compile times"));
84fb03ea46SDimitry Andric 
8504eeddc0SDimitry Andric /// A flag for test, so we can print the content of the advisor when running it
8604eeddc0SDimitry Andric /// as part of the default (e.g. -O3) pipeline.
8704eeddc0SDimitry Andric static cl::opt<bool> KeepAdvisorForPrinting("keep-inline-advisor-for-printing",
8804eeddc0SDimitry Andric                                             cl::init(false), cl::Hidden);
8904eeddc0SDimitry Andric 
9081ad6265SDimitry Andric /// Allows printing the contents of the advisor after each SCC inliner pass.
9181ad6265SDimitry Andric static cl::opt<bool>
9281ad6265SDimitry Andric     EnablePostSCCAdvisorPrinting("enable-scc-inline-advisor-printing",
9381ad6265SDimitry Andric                                  cl::init(false), cl::Hidden);
9481ad6265SDimitry Andric 
950b57cec5SDimitry Andric 
96e8d8bef9SDimitry Andric static cl::opt<std::string> CGSCCInlineReplayFile(
97e8d8bef9SDimitry Andric     "cgscc-inline-replay", cl::init(""), cl::value_desc("filename"),
98e8d8bef9SDimitry Andric     cl::desc(
99e8d8bef9SDimitry Andric         "Optimization remarks file containing inline remarks to be replayed "
100349cc55cSDimitry Andric         "by cgscc inlining."),
101e8d8bef9SDimitry Andric     cl::Hidden);
1020b57cec5SDimitry Andric 
103349cc55cSDimitry Andric static cl::opt<ReplayInlinerSettings::Scope> CGSCCInlineReplayScope(
104349cc55cSDimitry Andric     "cgscc-inline-replay-scope",
105349cc55cSDimitry Andric     cl::init(ReplayInlinerSettings::Scope::Function),
106349cc55cSDimitry Andric     cl::values(clEnumValN(ReplayInlinerSettings::Scope::Function, "Function",
107349cc55cSDimitry Andric                           "Replay on functions that have remarks associated "
108349cc55cSDimitry Andric                           "with them (default)"),
109349cc55cSDimitry Andric                clEnumValN(ReplayInlinerSettings::Scope::Module, "Module",
110349cc55cSDimitry Andric                           "Replay on the entire module")),
111349cc55cSDimitry Andric     cl::desc("Whether inline replay should be applied to the entire "
112349cc55cSDimitry Andric              "Module or just the Functions (default) that are present as "
113349cc55cSDimitry Andric              "callers in remarks during cgscc inlining."),
114349cc55cSDimitry Andric     cl::Hidden);
115349cc55cSDimitry Andric 
116349cc55cSDimitry Andric static cl::opt<ReplayInlinerSettings::Fallback> CGSCCInlineReplayFallback(
117349cc55cSDimitry Andric     "cgscc-inline-replay-fallback",
118349cc55cSDimitry Andric     cl::init(ReplayInlinerSettings::Fallback::Original),
119349cc55cSDimitry Andric     cl::values(
120349cc55cSDimitry Andric         clEnumValN(
121349cc55cSDimitry Andric             ReplayInlinerSettings::Fallback::Original, "Original",
122349cc55cSDimitry Andric             "All decisions not in replay send to original advisor (default)"),
123349cc55cSDimitry Andric         clEnumValN(ReplayInlinerSettings::Fallback::AlwaysInline,
124349cc55cSDimitry Andric                    "AlwaysInline", "All decisions not in replay are inlined"),
125349cc55cSDimitry Andric         clEnumValN(ReplayInlinerSettings::Fallback::NeverInline, "NeverInline",
126349cc55cSDimitry Andric                    "All decisions not in replay are not inlined")),
127349cc55cSDimitry Andric     cl::desc(
128349cc55cSDimitry Andric         "How cgscc inline replay treats sites that don't come from the replay. "
129349cc55cSDimitry Andric         "Original: defers to original advisor, AlwaysInline: inline all sites "
130349cc55cSDimitry Andric         "not in replay, NeverInline: inline no sites not in replay"),
131349cc55cSDimitry Andric     cl::Hidden);
132349cc55cSDimitry Andric 
133349cc55cSDimitry Andric static cl::opt<CallSiteFormat::Format> CGSCCInlineReplayFormat(
134349cc55cSDimitry Andric     "cgscc-inline-replay-format",
135349cc55cSDimitry Andric     cl::init(CallSiteFormat::Format::LineColumnDiscriminator),
136349cc55cSDimitry Andric     cl::values(
137349cc55cSDimitry Andric         clEnumValN(CallSiteFormat::Format::Line, "Line", "<Line Number>"),
138349cc55cSDimitry Andric         clEnumValN(CallSiteFormat::Format::LineColumn, "LineColumn",
139349cc55cSDimitry Andric                    "<Line Number>:<Column Number>"),
140349cc55cSDimitry Andric         clEnumValN(CallSiteFormat::Format::LineDiscriminator,
141349cc55cSDimitry Andric                    "LineDiscriminator", "<Line Number>.<Discriminator>"),
142349cc55cSDimitry Andric         clEnumValN(CallSiteFormat::Format::LineColumnDiscriminator,
143349cc55cSDimitry Andric                    "LineColumnDiscriminator",
144349cc55cSDimitry Andric                    "<Line Number>:<Column Number>.<Discriminator> (default)")),
145349cc55cSDimitry Andric     cl::desc("How cgscc inline replay file is formatted"), cl::Hidden);
146349cc55cSDimitry Andric 
1470b57cec5SDimitry Andric /// Return true if the specified inline history ID
1480b57cec5SDimitry Andric /// indicates an inline history that includes the specified function.
1495ffd83dbSDimitry Andric static bool inlineHistoryIncludes(
1500b57cec5SDimitry Andric     Function *F, int InlineHistoryID,
1510b57cec5SDimitry Andric     const SmallVectorImpl<std::pair<Function *, int>> &InlineHistory) {
1520b57cec5SDimitry Andric   while (InlineHistoryID != -1) {
1530b57cec5SDimitry Andric     assert(unsigned(InlineHistoryID) < InlineHistory.size() &&
1540b57cec5SDimitry Andric            "Invalid inline history ID");
1550b57cec5SDimitry Andric     if (InlineHistory[InlineHistoryID].first == F)
1560b57cec5SDimitry Andric       return true;
1570b57cec5SDimitry Andric     InlineHistoryID = InlineHistory[InlineHistoryID].second;
1580b57cec5SDimitry Andric   }
1590b57cec5SDimitry Andric   return false;
1600b57cec5SDimitry Andric }
1610b57cec5SDimitry Andric 
1625ffd83dbSDimitry Andric InlineAdvisor &
1635ffd83dbSDimitry Andric InlinerPass::getAdvisor(const ModuleAnalysisManagerCGSCCProxy::Result &MAM,
1645ffd83dbSDimitry Andric                         FunctionAnalysisManager &FAM, Module &M) {
165e8d8bef9SDimitry Andric   if (OwnedAdvisor)
166e8d8bef9SDimitry Andric     return *OwnedAdvisor;
167e8d8bef9SDimitry Andric 
1685ffd83dbSDimitry Andric   auto *IAA = MAM.getCachedResult<InlineAdvisorAnalysis>(M);
1695ffd83dbSDimitry Andric   if (!IAA) {
1705ffd83dbSDimitry Andric     // It should still be possible to run the inliner as a stand-alone SCC pass,
1715ffd83dbSDimitry Andric     // for test scenarios. In that case, we default to the
1725ffd83dbSDimitry Andric     // DefaultInlineAdvisor, which doesn't need to keep state between SCC pass
1735ffd83dbSDimitry Andric     // runs. It also uses just the default InlineParams.
1745ffd83dbSDimitry Andric     // In this case, we need to use the provided FAM, which is valid for the
1755ffd83dbSDimitry Andric     // duration of the inliner pass, and thus the lifetime of the owned advisor.
1765ffd83dbSDimitry Andric     // The one we would get from the MAM can be invalidated as a result of the
1775ffd83dbSDimitry Andric     // inliner's activity.
17881ad6265SDimitry Andric     OwnedAdvisor = std::make_unique<DefaultInlineAdvisor>(
17981ad6265SDimitry Andric         M, FAM, getInlineParams(),
18081ad6265SDimitry Andric         InlineContext{LTOPhase, InlinePass::CGSCCInliner});
181e8d8bef9SDimitry Andric 
182e8d8bef9SDimitry Andric     if (!CGSCCInlineReplayFile.empty())
183349cc55cSDimitry Andric       OwnedAdvisor = getReplayInlineAdvisor(
184e8d8bef9SDimitry Andric           M, FAM, M.getContext(), std::move(OwnedAdvisor),
185349cc55cSDimitry Andric           ReplayInlinerSettings{CGSCCInlineReplayFile,
186349cc55cSDimitry Andric                                 CGSCCInlineReplayScope,
187349cc55cSDimitry Andric                                 CGSCCInlineReplayFallback,
188349cc55cSDimitry Andric                                 {CGSCCInlineReplayFormat}},
18981ad6265SDimitry Andric           /*EmitRemarks=*/true,
19006c3fb27SDimitry Andric           InlineContext{LTOPhase, InlinePass::ReplayCGSCCInliner});
191e8d8bef9SDimitry Andric 
192e8d8bef9SDimitry Andric     return *OwnedAdvisor;
1935ffd83dbSDimitry Andric   }
1945ffd83dbSDimitry Andric   assert(IAA->getAdvisor() &&
1955ffd83dbSDimitry Andric          "Expected a present InlineAdvisorAnalysis also have an "
1965ffd83dbSDimitry Andric          "InlineAdvisor initialized");
1975ffd83dbSDimitry Andric   return *IAA->getAdvisor();
1985ffd83dbSDimitry Andric }
1995ffd83dbSDimitry Andric 
200*0fca6ea1SDimitry Andric void makeFunctionBodyUnreachable(Function &F) {
201*0fca6ea1SDimitry Andric   F.dropAllReferences();
202*0fca6ea1SDimitry Andric   for (BasicBlock &BB : make_early_inc_range(F))
203*0fca6ea1SDimitry Andric     BB.eraseFromParent();
204*0fca6ea1SDimitry Andric   BasicBlock *BB = BasicBlock::Create(F.getContext(), "", &F);
205*0fca6ea1SDimitry Andric   new UnreachableInst(F.getContext(), BB);
206*0fca6ea1SDimitry Andric }
207*0fca6ea1SDimitry Andric 
2080b57cec5SDimitry Andric PreservedAnalyses InlinerPass::run(LazyCallGraph::SCC &InitialC,
2090b57cec5SDimitry Andric                                    CGSCCAnalysisManager &AM, LazyCallGraph &CG,
2100b57cec5SDimitry Andric                                    CGSCCUpdateResult &UR) {
2115ffd83dbSDimitry Andric   const auto &MAMProxy =
2125ffd83dbSDimitry Andric       AM.getResult<ModuleAnalysisManagerCGSCCProxy>(InitialC, CG);
2130b57cec5SDimitry Andric   bool Changed = false;
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric   assert(InitialC.size() > 0 && "Cannot handle an empty SCC!");
2160b57cec5SDimitry Andric   Module &M = *InitialC.begin()->getFunction().getParent();
2175ffd83dbSDimitry Andric   ProfileSummaryInfo *PSI = MAMProxy.getCachedResult<ProfileSummaryAnalysis>(M);
2185ffd83dbSDimitry Andric 
2195ffd83dbSDimitry Andric   FunctionAnalysisManager &FAM =
2205ffd83dbSDimitry Andric       AM.getResult<FunctionAnalysisManagerCGSCCProxy>(InitialC, CG)
2215ffd83dbSDimitry Andric           .getManager();
2225ffd83dbSDimitry Andric 
2235ffd83dbSDimitry Andric   InlineAdvisor &Advisor = getAdvisor(MAMProxy, FAM, M);
22481ad6265SDimitry Andric   Advisor.onPassEntry(&InitialC);
2255ffd83dbSDimitry Andric 
2260b57cec5SDimitry Andric   // We use a single common worklist for calls across the entire SCC. We
2270b57cec5SDimitry Andric   // process these in-order and append new calls introduced during inlining to
228fe6060f1SDimitry Andric   // the end. The PriorityInlineOrder is optional here, in which the smaller
229fe6060f1SDimitry Andric   // callee would have a higher priority to inline.
2300b57cec5SDimitry Andric   //
2310b57cec5SDimitry Andric   // Note that this particular order of processing is actually critical to
2320b57cec5SDimitry Andric   // avoid very bad behaviors. Consider *highly connected* call graphs where
233e8d8bef9SDimitry Andric   // each function contains a small amount of code and a couple of calls to
2340b57cec5SDimitry Andric   // other functions. Because the LLVM inliner is fundamentally a bottom-up
2350b57cec5SDimitry Andric   // inliner, it can handle gracefully the fact that these all appear to be
2360b57cec5SDimitry Andric   // reasonable inlining candidates as it will flatten things until they become
2370b57cec5SDimitry Andric   // too big to inline, and then move on and flatten another batch.
2380b57cec5SDimitry Andric   //
2390b57cec5SDimitry Andric   // However, when processing call edges *within* an SCC we cannot rely on this
2400b57cec5SDimitry Andric   // bottom-up behavior. As a consequence, with heavily connected *SCCs* of
2410b57cec5SDimitry Andric   // functions we can end up incrementally inlining N calls into each of
2420b57cec5SDimitry Andric   // N functions because each incremental inlining decision looks good and we
2430b57cec5SDimitry Andric   // don't have a topological ordering to prevent explosions.
2440b57cec5SDimitry Andric   //
2450b57cec5SDimitry Andric   // To compensate for this, we don't process transitive edges made immediate
2460b57cec5SDimitry Andric   // by inlining until we've done one pass of inlining across the entire SCC.
2470b57cec5SDimitry Andric   // Large, highly connected SCCs still lead to some amount of code bloat in
2480b57cec5SDimitry Andric   // this model, but it is uniformly spread across all the functions in the SCC
2490b57cec5SDimitry Andric   // and eventually they all become too large to inline, rather than
2500b57cec5SDimitry Andric   // incrementally maknig a single function grow in a super linear fashion.
251bdd1243dSDimitry Andric   SmallVector<std::pair<CallBase *, int>, 16> Calls;
2520b57cec5SDimitry Andric 
2530b57cec5SDimitry Andric   // Populate the initial list of calls in this SCC.
2540b57cec5SDimitry Andric   for (auto &N : InitialC) {
2550b57cec5SDimitry Andric     auto &ORE =
2560b57cec5SDimitry Andric         FAM.getResult<OptimizationRemarkEmitterAnalysis>(N.getFunction());
2570b57cec5SDimitry Andric     // We want to generally process call sites top-down in order for
2580b57cec5SDimitry Andric     // simplifications stemming from replacing the call with the returned value
2590b57cec5SDimitry Andric     // after inlining to be visible to subsequent inlining decisions.
2600b57cec5SDimitry Andric     // FIXME: Using instructions sequence is a really bad way to do this.
2610b57cec5SDimitry Andric     // Instead we should do an actual RPO walk of the function body.
2620b57cec5SDimitry Andric     for (Instruction &I : instructions(N.getFunction()))
2635ffd83dbSDimitry Andric       if (auto *CB = dyn_cast<CallBase>(&I))
2645ffd83dbSDimitry Andric         if (Function *Callee = CB->getCalledFunction()) {
2650b57cec5SDimitry Andric           if (!Callee->isDeclaration())
266bdd1243dSDimitry Andric             Calls.push_back({CB, -1});
2670b57cec5SDimitry Andric           else if (!isa<IntrinsicInst>(I)) {
2680b57cec5SDimitry Andric             using namespace ore;
2695ffd83dbSDimitry Andric             setInlineRemark(*CB, "unavailable definition");
2700b57cec5SDimitry Andric             ORE.emit([&]() {
2710b57cec5SDimitry Andric               return OptimizationRemarkMissed(DEBUG_TYPE, "NoDefinition", &I)
2720b57cec5SDimitry Andric                      << NV("Callee", Callee) << " will not be inlined into "
2735ffd83dbSDimitry Andric                      << NV("Caller", CB->getCaller())
2740b57cec5SDimitry Andric                      << " because its definition is unavailable"
2750b57cec5SDimitry Andric                      << setIsVerbose();
2760b57cec5SDimitry Andric             });
2770b57cec5SDimitry Andric           }
2780b57cec5SDimitry Andric         }
2790b57cec5SDimitry Andric   }
2800b57cec5SDimitry Andric 
281e8d8bef9SDimitry Andric   // Capture updatable variable for the current SCC.
2820b57cec5SDimitry Andric   auto *C = &InitialC;
2830b57cec5SDimitry Andric 
284*0fca6ea1SDimitry Andric   auto AdvisorOnExit = make_scope_exit([&] { Advisor.onPassExit(C); });
285*0fca6ea1SDimitry Andric 
286*0fca6ea1SDimitry Andric   if (Calls.empty())
287*0fca6ea1SDimitry Andric     return PreservedAnalyses::all();
288*0fca6ea1SDimitry Andric 
2890b57cec5SDimitry Andric   // When inlining a callee produces new call sites, we want to keep track of
2900b57cec5SDimitry Andric   // the fact that they were inlined from the callee.  This allows us to avoid
2910b57cec5SDimitry Andric   // infinite inlining in some obscure cases.  To represent this, we use an
2920b57cec5SDimitry Andric   // index into the InlineHistory vector.
2930b57cec5SDimitry Andric   SmallVector<std::pair<Function *, int>, 16> InlineHistory;
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric   // Track a set vector of inlined callees so that we can augment the caller
2960b57cec5SDimitry Andric   // with all of their edges in the call graph before pruning out the ones that
2970b57cec5SDimitry Andric   // got simplified away.
2980b57cec5SDimitry Andric   SmallSetVector<Function *, 4> InlinedCallees;
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   // Track the dead functions to delete once finished with inlining calls. We
3010b57cec5SDimitry Andric   // defer deleting these to make it easier to handle the call graph updates.
3020b57cec5SDimitry Andric   SmallVector<Function *, 4> DeadFunctions;
3030b57cec5SDimitry Andric 
30404eeddc0SDimitry Andric   // Track potentially dead non-local functions with comdats to see if they can
30504eeddc0SDimitry Andric   // be deleted as a batch after inlining.
30604eeddc0SDimitry Andric   SmallVector<Function *, 4> DeadFunctionsInComdats;
30704eeddc0SDimitry Andric 
308bdd1243dSDimitry Andric   // Loop forward over all of the calls. Note that we cannot cache the size as
309bdd1243dSDimitry Andric   // inlining can introduce new calls that need to be processed.
310bdd1243dSDimitry Andric   for (int I = 0; I < (int)Calls.size(); ++I) {
3110b57cec5SDimitry Andric     // We expect the calls to typically be batched with sequences of calls that
3120b57cec5SDimitry Andric     // have the same caller, so we first set up some shared infrastructure for
3130b57cec5SDimitry Andric     // this caller. We also do any pruning we can at this layer on the caller
3140b57cec5SDimitry Andric     // alone.
315bdd1243dSDimitry Andric     Function &F = *Calls[I].first->getCaller();
3160b57cec5SDimitry Andric     LazyCallGraph::Node &N = *CG.lookup(F);
317bdd1243dSDimitry Andric     if (CG.lookupSCC(N) != C)
3180b57cec5SDimitry Andric       continue;
3190b57cec5SDimitry Andric 
320fe6060f1SDimitry Andric     LLVM_DEBUG(dbgs() << "Inlining calls in: " << F.getName() << "\n"
321fe6060f1SDimitry Andric                       << "    Function size: " << F.getInstructionCount()
322fe6060f1SDimitry Andric                       << "\n");
3230b57cec5SDimitry Andric 
3245ffd83dbSDimitry Andric     auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
3250b57cec5SDimitry Andric       return FAM.getResult<AssumptionAnalysis>(F);
3260b57cec5SDimitry Andric     };
3270b57cec5SDimitry Andric 
3285ffd83dbSDimitry Andric     // Now process as many calls as we have within this caller in the sequence.
3290b57cec5SDimitry Andric     // We bail out as soon as the caller has to change so we can update the
3300b57cec5SDimitry Andric     // call graph and prepare the context of that new caller.
3310b57cec5SDimitry Andric     bool DidInline = false;
332bdd1243dSDimitry Andric     for (; I < (int)Calls.size() && Calls[I].first->getCaller() == &F; ++I) {
333bdd1243dSDimitry Andric       auto &P = Calls[I];
3345ffd83dbSDimitry Andric       CallBase *CB = P.first;
3355ffd83dbSDimitry Andric       const int InlineHistoryID = P.second;
3365ffd83dbSDimitry Andric       Function &Callee = *CB->getCalledFunction();
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric       if (InlineHistoryID != -1 &&
3395ffd83dbSDimitry Andric           inlineHistoryIncludes(&Callee, InlineHistoryID, InlineHistory)) {
34006c3fb27SDimitry Andric         LLVM_DEBUG(dbgs() << "Skipping inlining due to history: " << F.getName()
34106c3fb27SDimitry Andric                           << " -> " << Callee.getName() << "\n");
3425ffd83dbSDimitry Andric         setInlineRemark(*CB, "recursive");
34306c3fb27SDimitry Andric         // Set noinline so that we don't forget this decision across CGSCC
34406c3fb27SDimitry Andric         // iterations.
34506c3fb27SDimitry Andric         CB->setIsNoInline();
3460b57cec5SDimitry Andric         continue;
3470b57cec5SDimitry Andric       }
3480b57cec5SDimitry Andric 
3490b57cec5SDimitry Andric       // Check if this inlining may repeat breaking an SCC apart that has
3500b57cec5SDimitry Andric       // already been split once before. In that case, inlining here may
3510b57cec5SDimitry Andric       // trigger infinite inlining, much like is prevented within the inliner
3520b57cec5SDimitry Andric       // itself by the InlineHistory above, but spread across CGSCC iterations
3530b57cec5SDimitry Andric       // and thus hidden from the full inline history.
354fb03ea46SDimitry Andric       LazyCallGraph::SCC *CalleeSCC = CG.lookupSCC(*CG.lookup(Callee));
355fb03ea46SDimitry Andric       if (CalleeSCC == C && UR.InlinedInternalEdges.count({&N, C})) {
3560b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "Skipping inlining internal SCC edge from a node "
3570b57cec5SDimitry Andric                              "previously split out of this SCC by inlining: "
3580b57cec5SDimitry Andric                           << F.getName() << " -> " << Callee.getName() << "\n");
3595ffd83dbSDimitry Andric         setInlineRemark(*CB, "recursive SCC split");
3600b57cec5SDimitry Andric         continue;
3610b57cec5SDimitry Andric       }
3620b57cec5SDimitry Andric 
363349cc55cSDimitry Andric       std::unique_ptr<InlineAdvice> Advice =
364349cc55cSDimitry Andric           Advisor.getAdvice(*CB, OnlyMandatory);
365349cc55cSDimitry Andric 
3660b57cec5SDimitry Andric       // Check whether we want to inline this callsite.
367349cc55cSDimitry Andric       if (!Advice)
368349cc55cSDimitry Andric         continue;
369349cc55cSDimitry Andric 
3705ffd83dbSDimitry Andric       if (!Advice->isInliningRecommended()) {
3715ffd83dbSDimitry Andric         Advice->recordUnattemptedInlining();
3720b57cec5SDimitry Andric         continue;
3730b57cec5SDimitry Andric       }
3740b57cec5SDimitry Andric 
375fb03ea46SDimitry Andric       int CBCostMult =
376fb03ea46SDimitry Andric           getStringFnAttrAsInt(
377fb03ea46SDimitry Andric               *CB, InlineConstants::FunctionInlineCostMultiplierAttributeName)
37881ad6265SDimitry Andric               .value_or(1);
379fb03ea46SDimitry Andric 
3800b57cec5SDimitry Andric       // Setup the data structure used to plumb customization into the
3810b57cec5SDimitry Andric       // `InlineFunction` routine.
3820b57cec5SDimitry Andric       InlineFunctionInfo IFI(
38306c3fb27SDimitry Andric           GetAssumptionCache, PSI,
3845ffd83dbSDimitry Andric           &FAM.getResult<BlockFrequencyAnalysis>(*(CB->getCaller())),
3850b57cec5SDimitry Andric           &FAM.getResult<BlockFrequencyAnalysis>(Callee));
3860b57cec5SDimitry Andric 
387e8d8bef9SDimitry Andric       InlineResult IR =
388bdd1243dSDimitry Andric           InlineFunction(*CB, IFI, /*MergeAttributes=*/true,
389bdd1243dSDimitry Andric                          &FAM.getResult<AAManager>(*CB->getCaller()));
3905ffd83dbSDimitry Andric       if (!IR.isSuccess()) {
3915ffd83dbSDimitry Andric         Advice->recordUnsuccessfulInlining(IR);
3920b57cec5SDimitry Andric         continue;
3930b57cec5SDimitry Andric       }
3945ffd83dbSDimitry Andric 
3950b57cec5SDimitry Andric       DidInline = true;
3960b57cec5SDimitry Andric       InlinedCallees.insert(&Callee);
3970b57cec5SDimitry Andric       ++NumInlined;
3980b57cec5SDimitry Andric 
399fe6060f1SDimitry Andric       LLVM_DEBUG(dbgs() << "    Size after inlining: "
400fe6060f1SDimitry Andric                         << F.getInstructionCount() << "\n");
401fe6060f1SDimitry Andric 
4020b57cec5SDimitry Andric       // Add any new callsites to defined functions to the worklist.
4030b57cec5SDimitry Andric       if (!IFI.InlinedCallSites.empty()) {
4040b57cec5SDimitry Andric         int NewHistoryID = InlineHistory.size();
4050b57cec5SDimitry Andric         InlineHistory.push_back({&Callee, InlineHistoryID});
4065ffd83dbSDimitry Andric 
4075ffd83dbSDimitry Andric         for (CallBase *ICB : reverse(IFI.InlinedCallSites)) {
4085ffd83dbSDimitry Andric           Function *NewCallee = ICB->getCalledFunction();
409fe6060f1SDimitry Andric           assert(!(NewCallee && NewCallee->isIntrinsic()) &&
410fe6060f1SDimitry Andric                  "Intrinsic calls should not be tracked.");
4115ffd83dbSDimitry Andric           if (!NewCallee) {
4125ffd83dbSDimitry Andric             // Try to promote an indirect (virtual) call without waiting for
4135ffd83dbSDimitry Andric             // the post-inline cleanup and the next DevirtSCCRepeatedPass
4145ffd83dbSDimitry Andric             // iteration because the next iteration may not happen and we may
4155ffd83dbSDimitry Andric             // miss inlining it.
4165ffd83dbSDimitry Andric             if (tryPromoteCall(*ICB))
4175ffd83dbSDimitry Andric               NewCallee = ICB->getCalledFunction();
4185ffd83dbSDimitry Andric           }
419fb03ea46SDimitry Andric           if (NewCallee) {
420fb03ea46SDimitry Andric             if (!NewCallee->isDeclaration()) {
421bdd1243dSDimitry Andric               Calls.push_back({ICB, NewHistoryID});
422fb03ea46SDimitry Andric               // Continually inlining through an SCC can result in huge compile
423fb03ea46SDimitry Andric               // times and bloated code since we arbitrarily stop at some point
424fb03ea46SDimitry Andric               // when the inliner decides it's not profitable to inline anymore.
425fb03ea46SDimitry Andric               // We attempt to mitigate this by making these calls exponentially
426fb03ea46SDimitry Andric               // more expensive.
427fb03ea46SDimitry Andric               // This doesn't apply to calls in the same SCC since if we do
428fb03ea46SDimitry Andric               // inline through the SCC the function will end up being
429fb03ea46SDimitry Andric               // self-recursive which the inliner bails out on, and inlining
430fb03ea46SDimitry Andric               // within an SCC is necessary for performance.
431fb03ea46SDimitry Andric               if (CalleeSCC != C &&
432fb03ea46SDimitry Andric                   CalleeSCC == CG.lookupSCC(CG.get(*NewCallee))) {
433fb03ea46SDimitry Andric                 Attribute NewCBCostMult = Attribute::get(
434fb03ea46SDimitry Andric                     M.getContext(),
435fb03ea46SDimitry Andric                     InlineConstants::FunctionInlineCostMultiplierAttributeName,
436fb03ea46SDimitry Andric                     itostr(CBCostMult * IntraSCCCostMultiplier));
437fb03ea46SDimitry Andric                 ICB->addFnAttr(NewCBCostMult);
438fb03ea46SDimitry Andric               }
439fb03ea46SDimitry Andric             }
440fb03ea46SDimitry Andric           }
4415ffd83dbSDimitry Andric         }
4420b57cec5SDimitry Andric       }
4430b57cec5SDimitry Andric 
44404eeddc0SDimitry Andric       // For local functions or discardable functions without comdats, check
44504eeddc0SDimitry Andric       // whether this makes the callee trivially dead. In that case, we can drop
44604eeddc0SDimitry Andric       // the body of the function eagerly which may reduce the number of callers
44704eeddc0SDimitry Andric       // of other functions to one, changing inline cost thresholds. Non-local
44804eeddc0SDimitry Andric       // discardable functions with comdats are checked later on.
4495ffd83dbSDimitry Andric       bool CalleeWasDeleted = false;
45004eeddc0SDimitry Andric       if (Callee.isDiscardableIfUnused() && Callee.hasZeroLiveUses() &&
45104eeddc0SDimitry Andric           !CG.isLibFunction(Callee)) {
45204eeddc0SDimitry Andric         if (Callee.hasLocalLinkage() || !Callee.hasComdat()) {
453bdd1243dSDimitry Andric           Calls.erase(
454bdd1243dSDimitry Andric               std::remove_if(Calls.begin() + I + 1, Calls.end(),
455bdd1243dSDimitry Andric                              [&](const std::pair<CallBase *, int> &Call) {
4565ffd83dbSDimitry Andric                                return Call.first->getCaller() == &Callee;
457bdd1243dSDimitry Andric                              }),
458bdd1243dSDimitry Andric               Calls.end());
459bdd1243dSDimitry Andric 
460*0fca6ea1SDimitry Andric           // Clear the body and queue the function itself for call graph
461*0fca6ea1SDimitry Andric           // updating when we finish inlining.
462*0fca6ea1SDimitry Andric           makeFunctionBodyUnreachable(Callee);
463e8d8bef9SDimitry Andric           assert(!is_contained(DeadFunctions, &Callee) &&
4640b57cec5SDimitry Andric                  "Cannot put cause a function to become dead twice!");
4650b57cec5SDimitry Andric           DeadFunctions.push_back(&Callee);
4665ffd83dbSDimitry Andric           CalleeWasDeleted = true;
46704eeddc0SDimitry Andric         } else {
46804eeddc0SDimitry Andric           DeadFunctionsInComdats.push_back(&Callee);
4690b57cec5SDimitry Andric         }
4700b57cec5SDimitry Andric       }
4715ffd83dbSDimitry Andric       if (CalleeWasDeleted)
4725ffd83dbSDimitry Andric         Advice->recordInliningWithCalleeDeleted();
4735ffd83dbSDimitry Andric       else
4745ffd83dbSDimitry Andric         Advice->recordInlining();
4750b57cec5SDimitry Andric     }
4760b57cec5SDimitry Andric 
477bdd1243dSDimitry Andric     // Back the call index up by one to put us in a good position to go around
478bdd1243dSDimitry Andric     // the outer loop.
479bdd1243dSDimitry Andric     --I;
480bdd1243dSDimitry Andric 
4810b57cec5SDimitry Andric     if (!DidInline)
4820b57cec5SDimitry Andric       continue;
4830b57cec5SDimitry Andric     Changed = true;
4840b57cec5SDimitry Andric 
4850b57cec5SDimitry Andric     // At this point, since we have made changes we have at least removed
4860b57cec5SDimitry Andric     // a call instruction. However, in the process we do some incremental
4870b57cec5SDimitry Andric     // simplification of the surrounding code. This simplification can
4880b57cec5SDimitry Andric     // essentially do all of the same things as a function pass and we can
4890b57cec5SDimitry Andric     // re-use the exact same logic for updating the call graph to reflect the
4900b57cec5SDimitry Andric     // change.
4915ffd83dbSDimitry Andric 
4925ffd83dbSDimitry Andric     // Inside the update, we also update the FunctionAnalysisManager in the
4935ffd83dbSDimitry Andric     // proxy for this particular SCC. We do this as the SCC may have changed and
4945ffd83dbSDimitry Andric     // as we're going to mutate this particular function we want to make sure
4955ffd83dbSDimitry Andric     // the proxy is in place to forward any invalidation events.
4960b57cec5SDimitry Andric     LazyCallGraph::SCC *OldC = C;
497e8d8bef9SDimitry Andric     C = &updateCGAndAnalysisManagerForCGSCCPass(CG, *C, N, AM, UR, FAM);
4980b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Updated inlining SCC: " << *C << "\n");
4990b57cec5SDimitry Andric 
5000b57cec5SDimitry Andric     // If this causes an SCC to split apart into multiple smaller SCCs, there
5010b57cec5SDimitry Andric     // is a subtle risk we need to prepare for. Other transformations may
5020b57cec5SDimitry Andric     // expose an "infinite inlining" opportunity later, and because of the SCC
5030b57cec5SDimitry Andric     // mutation, we will revisit this function and potentially re-inline. If we
5040b57cec5SDimitry Andric     // do, and that re-inlining also has the potentially to mutate the SCC
5050b57cec5SDimitry Andric     // structure, the infinite inlining problem can manifest through infinite
5060b57cec5SDimitry Andric     // SCC splits and merges. To avoid this, we capture the originating caller
5070b57cec5SDimitry Andric     // node and the SCC containing the call edge. This is a slight over
5080b57cec5SDimitry Andric     // approximation of the possible inlining decisions that must be avoided,
5090b57cec5SDimitry Andric     // but is relatively efficient to store. We use C != OldC to know when
5100b57cec5SDimitry Andric     // a new SCC is generated and the original SCC may be generated via merge
5110b57cec5SDimitry Andric     // in later iterations.
5120b57cec5SDimitry Andric     //
5130b57cec5SDimitry Andric     // It is also possible that even if no new SCC is generated
5140b57cec5SDimitry Andric     // (i.e., C == OldC), the original SCC could be split and then merged
5150b57cec5SDimitry Andric     // into the same one as itself. and the original SCC will be added into
5160b57cec5SDimitry Andric     // UR.CWorklist again, we want to catch such cases too.
5170b57cec5SDimitry Andric     //
5180b57cec5SDimitry Andric     // FIXME: This seems like a very heavyweight way of retaining the inline
5190b57cec5SDimitry Andric     // history, we should look for a more efficient way of tracking it.
5200b57cec5SDimitry Andric     if ((C != OldC || UR.CWorklist.count(OldC)) &&
5210b57cec5SDimitry Andric         llvm::any_of(InlinedCallees, [&](Function *Callee) {
5220b57cec5SDimitry Andric           return CG.lookupSCC(*CG.lookup(*Callee)) == OldC;
5230b57cec5SDimitry Andric         })) {
5240b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Inlined an internal call edge and split an SCC, "
5250b57cec5SDimitry Andric                            "retaining this to avoid infinite inlining.\n");
5260b57cec5SDimitry Andric       UR.InlinedInternalEdges.insert({&N, OldC});
5270b57cec5SDimitry Andric     }
5280b57cec5SDimitry Andric     InlinedCallees.clear();
529349cc55cSDimitry Andric 
530349cc55cSDimitry Andric     // Invalidate analyses for this function now so that we don't have to
531349cc55cSDimitry Andric     // invalidate analyses for all functions in this SCC later.
532349cc55cSDimitry Andric     FAM.invalidate(F, PreservedAnalyses::none());
5330b57cec5SDimitry Andric   }
5340b57cec5SDimitry Andric 
53504eeddc0SDimitry Andric   // We must ensure that we only delete functions with comdats if every function
53604eeddc0SDimitry Andric   // in the comdat is going to be deleted.
53704eeddc0SDimitry Andric   if (!DeadFunctionsInComdats.empty()) {
53804eeddc0SDimitry Andric     filterDeadComdatFunctions(DeadFunctionsInComdats);
53904eeddc0SDimitry Andric     for (auto *Callee : DeadFunctionsInComdats)
540*0fca6ea1SDimitry Andric       makeFunctionBodyUnreachable(*Callee);
54104eeddc0SDimitry Andric     DeadFunctions.append(DeadFunctionsInComdats);
54204eeddc0SDimitry Andric   }
54304eeddc0SDimitry Andric 
5440b57cec5SDimitry Andric   // Now that we've finished inlining all of the calls across this SCC, delete
5450b57cec5SDimitry Andric   // all of the trivially dead functions, updating the call graph and the CGSCC
5460b57cec5SDimitry Andric   // pass manager in the process.
5470b57cec5SDimitry Andric   //
5480b57cec5SDimitry Andric   // Note that this walks a pointer set which has non-deterministic order but
5490b57cec5SDimitry Andric   // that is OK as all we do is delete things and add pointers to unordered
5500b57cec5SDimitry Andric   // sets.
5510b57cec5SDimitry Andric   for (Function *DeadF : DeadFunctions) {
552*0fca6ea1SDimitry Andric     CG.markDeadFunction(*DeadF);
5530b57cec5SDimitry Andric     // Get the necessary information out of the call graph and nuke the
5545ffd83dbSDimitry Andric     // function there. Also, clear out any cached analyses.
5550b57cec5SDimitry Andric     auto &DeadC = *CG.lookupSCC(*CG.lookup(*DeadF));
5560b57cec5SDimitry Andric     FAM.clear(*DeadF, DeadF->getName());
5570b57cec5SDimitry Andric     AM.clear(DeadC, DeadC.getName());
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric     // Mark the relevant parts of the call graph as invalid so we don't visit
5600b57cec5SDimitry Andric     // them.
5610b57cec5SDimitry Andric     UR.InvalidatedSCCs.insert(&DeadC);
5620b57cec5SDimitry Andric 
563*0fca6ea1SDimitry Andric     UR.DeadFunctions.push_back(DeadF);
5645ffd83dbSDimitry Andric 
5650b57cec5SDimitry Andric     ++NumDeleted;
5660b57cec5SDimitry Andric   }
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric   if (!Changed)
5690b57cec5SDimitry Andric     return PreservedAnalyses::all();
5700b57cec5SDimitry Andric 
571349cc55cSDimitry Andric   PreservedAnalyses PA;
5720b57cec5SDimitry Andric   // Even if we change the IR, we update the core CGSCC data structures and so
5730b57cec5SDimitry Andric   // can preserve the proxy to the function analysis manager.
5740b57cec5SDimitry Andric   PA.preserve<FunctionAnalysisManagerCGSCCProxy>();
575349cc55cSDimitry Andric   // We have already invalidated all analyses on modified functions.
576349cc55cSDimitry Andric   PA.preserveSet<AllAnalysesOn<Function>>();
5770b57cec5SDimitry Andric   return PA;
5780b57cec5SDimitry Andric }
5795ffd83dbSDimitry Andric 
5805ffd83dbSDimitry Andric ModuleInlinerWrapperPass::ModuleInlinerWrapperPass(InlineParams Params,
581e8d8bef9SDimitry Andric                                                    bool MandatoryFirst,
58281ad6265SDimitry Andric                                                    InlineContext IC,
5835ffd83dbSDimitry Andric                                                    InliningAdvisorMode Mode,
5845ffd83dbSDimitry Andric                                                    unsigned MaxDevirtIterations)
58581ad6265SDimitry Andric     : Params(Params), IC(IC), Mode(Mode),
58681ad6265SDimitry Andric       MaxDevirtIterations(MaxDevirtIterations) {
5875ffd83dbSDimitry Andric   // Run the inliner first. The theory is that we are walking bottom-up and so
5885ffd83dbSDimitry Andric   // the callees have already been fully optimized, and we want to inline them
5895ffd83dbSDimitry Andric   // into the callers so that our optimizations can reflect that.
5905ffd83dbSDimitry Andric   // For PreLinkThinLTO pass, we disable hot-caller heuristic for sample PGO
5915ffd83dbSDimitry Andric   // because it makes profile annotation in the backend inaccurate.
59281ad6265SDimitry Andric   if (MandatoryFirst) {
593e8d8bef9SDimitry Andric     PM.addPass(InlinerPass(/*OnlyMandatory*/ true));
59481ad6265SDimitry Andric     if (EnablePostSCCAdvisorPrinting)
59581ad6265SDimitry Andric       PM.addPass(InlineAdvisorAnalysisPrinterPass(dbgs()));
59681ad6265SDimitry Andric   }
5975ffd83dbSDimitry Andric   PM.addPass(InlinerPass());
59881ad6265SDimitry Andric   if (EnablePostSCCAdvisorPrinting)
59981ad6265SDimitry Andric     PM.addPass(InlineAdvisorAnalysisPrinterPass(dbgs()));
6005ffd83dbSDimitry Andric }
6015ffd83dbSDimitry Andric 
6025ffd83dbSDimitry Andric PreservedAnalyses ModuleInlinerWrapperPass::run(Module &M,
6035ffd83dbSDimitry Andric                                                 ModuleAnalysisManager &MAM) {
6045ffd83dbSDimitry Andric   auto &IAA = MAM.getResult<InlineAdvisorAnalysis>(M);
605349cc55cSDimitry Andric   if (!IAA.tryCreate(Params, Mode,
606349cc55cSDimitry Andric                      {CGSCCInlineReplayFile,
607349cc55cSDimitry Andric                       CGSCCInlineReplayScope,
608349cc55cSDimitry Andric                       CGSCCInlineReplayFallback,
60981ad6265SDimitry Andric                       {CGSCCInlineReplayFormat}},
61081ad6265SDimitry Andric                      IC)) {
6115ffd83dbSDimitry Andric     M.getContext().emitError(
6125ffd83dbSDimitry Andric         "Could not setup Inlining Advisor for the requested "
6135ffd83dbSDimitry Andric         "mode and/or options");
6145ffd83dbSDimitry Andric     return PreservedAnalyses::all();
6155ffd83dbSDimitry Andric   }
6165ffd83dbSDimitry Andric 
6175ffd83dbSDimitry Andric   // We wrap the CGSCC pipeline in a devirtualization repeater. This will try
6185ffd83dbSDimitry Andric   // to detect when we devirtualize indirect calls and iterate the SCC passes
6195ffd83dbSDimitry Andric   // in that case to try and catch knock-on inlining or function attrs
6205ffd83dbSDimitry Andric   // opportunities. Then we add it to the module pipeline by walking the SCCs
6215ffd83dbSDimitry Andric   // in postorder (or bottom-up).
6225ffd83dbSDimitry Andric   // If MaxDevirtIterations is 0, we just don't use the devirtualization
6235ffd83dbSDimitry Andric   // wrapper.
6245ffd83dbSDimitry Andric   if (MaxDevirtIterations == 0)
6255ffd83dbSDimitry Andric     MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(PM)));
6265ffd83dbSDimitry Andric   else
6275ffd83dbSDimitry Andric     MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
6285ffd83dbSDimitry Andric         createDevirtSCCRepeatedPass(std::move(PM), MaxDevirtIterations)));
629349cc55cSDimitry Andric 
630349cc55cSDimitry Andric   MPM.addPass(std::move(AfterCGMPM));
631fe6060f1SDimitry Andric   MPM.run(M, MAM);
6325ffd83dbSDimitry Andric 
633349cc55cSDimitry Andric   // Discard the InlineAdvisor, a subsequent inlining session should construct
634349cc55cSDimitry Andric   // its own.
635349cc55cSDimitry Andric   auto PA = PreservedAnalyses::all();
63604eeddc0SDimitry Andric   if (!KeepAdvisorForPrinting)
637349cc55cSDimitry Andric     PA.abandon<InlineAdvisorAnalysis>();
638349cc55cSDimitry Andric   return PA;
639349cc55cSDimitry Andric }
640fe6060f1SDimitry Andric 
641349cc55cSDimitry Andric void InlinerPass::printPipeline(
642349cc55cSDimitry Andric     raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
643349cc55cSDimitry Andric   static_cast<PassInfoMixin<InlinerPass> *>(this)->printPipeline(
644349cc55cSDimitry Andric       OS, MapClassName2PassName);
645349cc55cSDimitry Andric   if (OnlyMandatory)
646349cc55cSDimitry Andric     OS << "<only-mandatory>";
647349cc55cSDimitry Andric }
648349cc55cSDimitry Andric 
649349cc55cSDimitry Andric void ModuleInlinerWrapperPass::printPipeline(
650349cc55cSDimitry Andric     raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
651349cc55cSDimitry Andric   // Print some info about passes added to the wrapper. This is however
652349cc55cSDimitry Andric   // incomplete as InlineAdvisorAnalysis part isn't included (which also depends
653349cc55cSDimitry Andric   // on Params and Mode).
654349cc55cSDimitry Andric   if (!MPM.isEmpty()) {
655349cc55cSDimitry Andric     MPM.printPipeline(OS, MapClassName2PassName);
65606c3fb27SDimitry Andric     OS << ',';
657349cc55cSDimitry Andric   }
658349cc55cSDimitry Andric   OS << "cgscc(";
659349cc55cSDimitry Andric   if (MaxDevirtIterations != 0)
660349cc55cSDimitry Andric     OS << "devirt<" << MaxDevirtIterations << ">(";
661349cc55cSDimitry Andric   PM.printPipeline(OS, MapClassName2PassName);
662349cc55cSDimitry Andric   if (MaxDevirtIterations != 0)
66306c3fb27SDimitry Andric     OS << ')';
66406c3fb27SDimitry Andric   OS << ')';
6655ffd83dbSDimitry Andric }
666