1 //===- AlwaysInliner.cpp - Code to inline always_inline functions ----------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements a custom inliner that handles only functions that
10 // are marked as "always inline".
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Transforms/IPO/AlwaysInliner.h"
15 #include "llvm/ADT/SetVector.h"
16 #include "llvm/Analysis/AliasAnalysis.h"
17 #include "llvm/Analysis/AssumptionCache.h"
18 #include "llvm/Analysis/InlineCost.h"
19 #include "llvm/Analysis/OptimizationRemarkEmitter.h"
20 #include "llvm/Analysis/ProfileSummaryInfo.h"
21 #include "llvm/IR/Module.h"
22 #include "llvm/InitializePasses.h"
23 #include "llvm/Transforms/IPO/Inliner.h"
24 #include "llvm/Transforms/Utils/Cloning.h"
25 #include "llvm/Transforms/Utils/ModuleUtils.h"
29 #define DEBUG_TYPE "inline"
31 PreservedAnalyses
AlwaysInlinerPass::run(Module
&M
,
32 ModuleAnalysisManager
&MAM
) {
33 // Add inline assumptions during code generation.
34 FunctionAnalysisManager
&FAM
=
35 MAM
.getResult
<FunctionAnalysisManagerModuleProxy
>(M
).getManager();
36 auto GetAssumptionCache
= [&](Function
&F
) -> AssumptionCache
& {
37 return FAM
.getResult
<AssumptionAnalysis
>(F
);
39 auto &PSI
= MAM
.getResult
<ProfileSummaryAnalysis
>(M
);
41 SmallSetVector
<CallBase
*, 16> Calls
;
43 SmallVector
<Function
*, 16> InlinedFunctions
;
44 for (Function
&F
: M
) {
45 // When callee coroutine function is inlined into caller coroutine function
46 // before coro-split pass,
47 // coro-early pass can not handle this quiet well.
48 // So we won't inline the coroutine function if it have not been unsplited
49 if (F
.isPresplitCoroutine())
52 if (!F
.isDeclaration() && isInlineViable(F
).isSuccess()) {
55 for (User
*U
: F
.users())
56 if (auto *CB
= dyn_cast
<CallBase
>(U
))
57 if (CB
->getCalledFunction() == &F
&&
58 CB
->hasFnAttr(Attribute::AlwaysInline
) &&
59 !CB
->getAttributes().hasFnAttr(Attribute::NoInline
))
62 for (CallBase
*CB
: Calls
) {
63 Function
*Caller
= CB
->getCaller();
64 OptimizationRemarkEmitter
ORE(Caller
);
65 DebugLoc DLoc
= CB
->getDebugLoc();
66 BasicBlock
*Block
= CB
->getParent();
68 InlineFunctionInfo
IFI(
69 /*cg=*/nullptr, GetAssumptionCache
, &PSI
,
70 &FAM
.getResult
<BlockFrequencyAnalysis
>(*Caller
),
71 &FAM
.getResult
<BlockFrequencyAnalysis
>(F
));
73 InlineResult Res
= InlineFunction(
74 *CB
, IFI
, &FAM
.getResult
<AAManager
>(F
), InsertLifetime
);
75 if (!Res
.isSuccess()) {
77 return OptimizationRemarkMissed(DEBUG_TYPE
, "NotInlined", DLoc
,
79 << "'" << ore::NV("Callee", &F
) << "' is not inlined into '"
80 << ore::NV("Caller", Caller
)
81 << "': " << ore::NV("Reason", Res
.getFailureReason());
86 emitInlinedIntoBasedOnCost(
87 ORE
, DLoc
, Block
, F
, *Caller
,
88 InlineCost::getAlways("always inline attribute"),
89 /*ForProfileContext=*/false, DEBUG_TYPE
);
91 // Merge the attributes based on the inlining.
92 AttributeFuncs::mergeAttributesForInlining(*Caller
, F
);
97 if (F
.hasFnAttribute(Attribute::AlwaysInline
)) {
98 // Remember to try and delete this function afterward. This both avoids
99 // re-walking the rest of the module and avoids dealing with any
100 // iterator invalidation issues while deleting functions.
101 InlinedFunctions
.push_back(&F
);
106 // Remove any live functions.
107 erase_if(InlinedFunctions
, [&](Function
*F
) {
108 F
->removeDeadConstantUsers();
109 return !F
->isDefTriviallyDead();
112 // Delete the non-comdat ones from the module and also from our vector.
113 auto NonComdatBegin
= partition(
114 InlinedFunctions
, [&](Function
*F
) { return F
->hasComdat(); });
115 for (Function
*F
: make_range(NonComdatBegin
, InlinedFunctions
.end())) {
116 M
.getFunctionList().erase(F
);
119 InlinedFunctions
.erase(NonComdatBegin
, InlinedFunctions
.end());
121 if (!InlinedFunctions
.empty()) {
122 // Now we just have the comdat functions. Filter out the ones whose comdats
123 // are not actually dead.
124 filterDeadComdatFunctions(InlinedFunctions
);
125 // The remaining functions are actually dead.
126 for (Function
*F
: InlinedFunctions
) {
127 M
.getFunctionList().erase(F
);
132 return Changed
? PreservedAnalyses::none() : PreservedAnalyses::all();
137 /// Inliner pass which only handles "always inline" functions.
139 /// Unlike the \c AlwaysInlinerPass, this uses the more heavyweight \c Inliner
140 /// base class to provide several facilities such as array alloca merging.
141 class AlwaysInlinerLegacyPass
: public LegacyInlinerBase
{
144 AlwaysInlinerLegacyPass() : LegacyInlinerBase(ID
, /*InsertLifetime*/ true) {
145 initializeAlwaysInlinerLegacyPassPass(*PassRegistry::getPassRegistry());
148 AlwaysInlinerLegacyPass(bool InsertLifetime
)
149 : LegacyInlinerBase(ID
, InsertLifetime
) {
150 initializeAlwaysInlinerLegacyPassPass(*PassRegistry::getPassRegistry());
153 /// Main run interface method. We override here to avoid calling skipSCC().
154 bool runOnSCC(CallGraphSCC
&SCC
) override
{ return inlineCalls(SCC
); }
156 static char ID
; // Pass identification, replacement for typeid
158 InlineCost
getInlineCost(CallBase
&CB
) override
;
160 using llvm::Pass::doFinalization
;
161 bool doFinalization(CallGraph
&CG
) override
{
162 return removeDeadFunctions(CG
, /*AlwaysInlineOnly=*/true);
167 char AlwaysInlinerLegacyPass::ID
= 0;
168 INITIALIZE_PASS_BEGIN(AlwaysInlinerLegacyPass
, "always-inline",
169 "Inliner for always_inline functions", false, false)
170 INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker
)
171 INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass
)
172 INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass
)
173 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass
)
174 INITIALIZE_PASS_END(AlwaysInlinerLegacyPass
, "always-inline",
175 "Inliner for always_inline functions", false, false)
177 Pass
*llvm::createAlwaysInlinerLegacyPass(bool InsertLifetime
) {
178 return new AlwaysInlinerLegacyPass(InsertLifetime
);
181 /// Get the inline cost for the always-inliner.
183 /// The always inliner *only* handles functions which are marked with the
184 /// attribute to force inlining. As such, it is dramatically simpler and avoids
185 /// using the powerful (but expensive) inline cost analysis. Instead it uses
186 /// a very simple and boring direct walk of the instructions looking for
187 /// impossible-to-inline constructs.
189 /// Note, it would be possible to go to some lengths to cache the information
190 /// computed here, but as we only expect to do this for relatively few and
191 /// small functions which have the explicit attribute to force inlining, it is
192 /// likely not worth it in practice.
193 InlineCost
AlwaysInlinerLegacyPass::getInlineCost(CallBase
&CB
) {
194 Function
*Callee
= CB
.getCalledFunction();
196 // Only inline direct calls to functions with always-inline attributes
197 // that are viable for inlining.
199 return InlineCost::getNever("indirect call");
201 // When callee coroutine function is inlined into caller coroutine function
202 // before coro-split pass,
203 // coro-early pass can not handle this quiet well.
204 // So we won't inline the coroutine function if it have not been unsplited
205 if (Callee
->isPresplitCoroutine())
206 return InlineCost::getNever("unsplited coroutine call");
208 // FIXME: We shouldn't even get here for declarations.
209 if (Callee
->isDeclaration())
210 return InlineCost::getNever("no definition");
212 if (!CB
.hasFnAttr(Attribute::AlwaysInline
))
213 return InlineCost::getNever("no alwaysinline attribute");
215 if (Callee
->hasFnAttribute(Attribute::AlwaysInline
) && CB
.isNoInline())
216 return InlineCost::getNever("noinline call site attribute");
218 auto IsViable
= isInlineViable(*Callee
);
219 if (!IsViable
.isSuccess())
220 return InlineCost::getNever(IsViable
.getFailureReason());
222 return InlineCost::getAlways("always inliner");