LLVM  15.0.0git
AlwaysInliner.cpp
Go to the documentation of this file.
1 //===- AlwaysInliner.cpp - Code to inline always_inline functions ----------===//
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 a custom inliner that handles only functions that
10 // are marked as "always inline".
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/ADT/SetVector.h"
21 #include "llvm/IR/Module.h"
22 #include "llvm/InitializePasses.h"
26 
27 using namespace llvm;
28 
29 #define DEBUG_TYPE "inline"
30 
33  // Add inline assumptions during code generation.
36  auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
38  };
39  auto &PSI = MAM.getResult<ProfileSummaryAnalysis>(M);
40 
42  bool Changed = false;
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())
50  continue;
51 
52  if (!F.isDeclaration() && isInlineViable(F).isSuccess()) {
53  Calls.clear();
54 
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))
60  Calls.insert(CB);
61 
62  for (CallBase *CB : Calls) {
63  Function *Caller = CB->getCaller();
64  OptimizationRemarkEmitter ORE(Caller);
65  DebugLoc DLoc = CB->getDebugLoc();
66  BasicBlock *Block = CB->getParent();
67 
69  /*cg=*/nullptr, GetAssumptionCache, &PSI,
72 
74  *CB, IFI, &FAM.getResult<AAManager>(F), InsertLifetime);
75  if (!Res.isSuccess()) {
76  ORE.emit([&]() {
77  return OptimizationRemarkMissed(DEBUG_TYPE, "NotInlined", DLoc,
78  Block)
79  << "'" << ore::NV("Callee", &F) << "' is not inlined into '"
80  << ore::NV("Caller", Caller)
81  << "': " << ore::NV("Reason", Res.getFailureReason());
82  });
83  continue;
84  }
85 
87  ORE, DLoc, Block, F, *Caller,
88  InlineCost::getAlways("always inline attribute"),
89  /*ForProfileContext=*/false, DEBUG_TYPE);
90 
91  // Merge the attributes based on the inlining.
93 
94  Changed = true;
95  }
96 
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);
102  }
103  }
104  }
105 
106  // Remove any live functions.
107  erase_if(InlinedFunctions, [&](Function *F) {
108  F->removeDeadConstantUsers();
109  return !F->isDefTriviallyDead();
110  });
111 
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);
117  Changed = true;
118  }
119  InlinedFunctions.erase(NonComdatBegin, InlinedFunctions.end());
120 
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);
128  Changed = true;
129  }
130  }
131 
132  return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
133 }
134 
135 namespace {
136 
137 /// Inliner pass which only handles "always inline" functions.
138 ///
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 {
142 
143 public:
144  AlwaysInlinerLegacyPass() : LegacyInlinerBase(ID, /*InsertLifetime*/ true) {
146  }
147 
148  AlwaysInlinerLegacyPass(bool InsertLifetime)
149  : LegacyInlinerBase(ID, InsertLifetime) {
151  }
152 
153  /// Main run interface method. We override here to avoid calling skipSCC().
154  bool runOnSCC(CallGraphSCC &SCC) override { return inlineCalls(SCC); }
155 
156  static char ID; // Pass identification, replacement for typeid
157 
158  InlineCost getInlineCost(CallBase &CB) override;
159 
161  bool doFinalization(CallGraph &CG) override {
162  return removeDeadFunctions(CG, /*AlwaysInlineOnly=*/true);
163  }
164 };
165 }
166 
168 INITIALIZE_PASS_BEGIN(AlwaysInlinerLegacyPass, "always-inline",
169  "Inliner for always_inline functions", false, false)
174 INITIALIZE_PASS_END(AlwaysInlinerLegacyPass, "always-inline",
175  "Inliner for always_inline functions", false, false)
176 
177 Pass *llvm::createAlwaysInlinerLegacyPass(bool InsertLifetime) {
178  return new AlwaysInlinerLegacyPass(InsertLifetime);
179 }
180 
181 /// Get the inline cost for the always-inliner.
182 ///
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.
188 ///
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.
195 
196  // Only inline direct calls to functions with always-inline attributes
197  // that are viable for inlining.
198  if (!Callee)
199  return InlineCost::getNever("indirect call");
200 
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");
207 
208  // FIXME: We shouldn't even get here for declarations.
209  if (Callee->isDeclaration())
210  return InlineCost::getNever("no definition");
211 
212  if (!CB.hasFnAttr(Attribute::AlwaysInline))
213  return InlineCost::getNever("no alwaysinline attribute");
214 
215  if (Callee->hasFnAttribute(Attribute::AlwaysInline) && CB.isNoInline())
216  return InlineCost::getNever("noinline call site attribute");
217 
218  auto IsViable = isInlineViable(*Callee);
219  if (!IsViable.isSuccess())
220  return InlineCost::getNever(IsViable.getFailureReason());
221 
222  return InlineCost::getAlways("always inliner");
223 }
llvm::initializeAlwaysInlinerLegacyPassPass
void initializeAlwaysInlinerLegacyPassPass(PassRegistry &)
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
AssumptionCache.h
llvm::AAManager
A manager for alias analyses.
Definition: AliasAnalysis.h:1303
llvm::OptimizationRemarkMissed
Diagnostic information for missed-optimization remarks.
Definition: DiagnosticInfo.h:735
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::SmallVectorImpl::erase
iterator erase(const_iterator CI)
Definition: SmallVector.h:724
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:53
llvm::AlwaysInlinerPass::run
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
Definition: AlwaysInliner.cpp:31
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:780
Inliner.h
llvm::Function
Definition: Function.h:60
llvm::createAlwaysInlinerLegacyPass
Pass * createAlwaysInlinerLegacyPass(bool InsertLifetime=true)
Create a legacy pass manager instance of a pass to inline and remove functions marked as "always_inli...
Definition: AlwaysInliner.cpp:177
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::erase_if
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition: STLExtras.h:1807
OptimizationRemarkEmitter.h
llvm::CallGraph
The basic data container for the call graph of a Module of IR.
Definition: CallGraph.h:72
FAM
FunctionAnalysisManager FAM
Definition: PassBuilderBindings.cpp:59
llvm::CallBase::hasFnAttr
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
Definition: InstrTypes.h:1483
llvm::emitInlinedIntoBasedOnCost
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).
Definition: InlineAdvisor.cpp:500
llvm::PreservedAnalyses::none
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:155
true
basic Basic Alias true
Definition: BasicAliasAnalysis.cpp:1886
Module.h
llvm::InlineCost::getAlways
static InlineCost getAlways(const char *Reason, Optional< CostBenefitPair > CostBenefit=None)
Definition: InlineCost.h:117
llvm::isInlineViable
InlineResult isInlineViable(Function &Callee)
Minimal filter to detect invalid constructs for inlining.
Definition: InlineCost.cpp:2969
llvm::ore::NV
DiagnosticInfoOptimizationBase::Argument NV
Definition: OptimizationRemarkEmitter.h:136
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
always
bar al al movzbl eax ret Missed when stored in a memory are stored as single byte objects the value of which is always(false) or 1(true). We are not using this fact
Definition: README.txt:1412
AliasAnalysis.h
llvm::CallGraphSCC
CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
Definition: CallGraphSCCPass.h:87
llvm::PassRegistry::getPassRegistry
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Definition: PassRegistry.cpp:31
AlwaysInliner.h
llvm::getInlineCost
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)
Get an InlineCost object representing the cost of inlining this callsite.
Definition: InlineCost.cpp:2803
llvm::User
Definition: User.h:44
llvm::CallBase::getCalledFunction
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1396
MAM
ModuleAnalysisManager MAM
Definition: PassBuilderBindings.cpp:61
llvm::InlineCost
Represents the cost of inlining a function.
Definition: InlineCost.h:87
false
Definition: StackSlotColoring.cpp:141
llvm::InlineResult::isSuccess
bool isSuccess() const
Definition: InlineCost.h:173
llvm::BlockFrequencyAnalysis
Analysis pass which computes BlockFrequencyInfo.
Definition: BlockFrequencyInfo.h:112
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
llvm::TargetLibraryInfoWrapperPass
Definition: TargetLibraryInfo.h:468
ProfileSummaryInfo.h
llvm::LegacyInlinerBase
This class contains all of the helper code which is used to perform the inlining operations that do n...
Definition: Inliner.h:29
llvm::AssumptionAnalysis
A function analysis which provides an AssumptionCache.
Definition: AssumptionCache.h:173
llvm::filterDeadComdatFunctions
void filterDeadComdatFunctions(SmallVectorImpl< Function * > &DeadComdatFunctions)
Filter out potentially dead comdat functions where other entries keep the entire comdat group alive.
Definition: ModuleUtils.cpp:179
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
llvm::CallGraphWrapperPass
The ModulePass which wraps up a CallGraph and the logic to build it.
Definition: CallGraph.h:336
Cloning.h
llvm::ProfileSummaryInfoWrapperPass
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Definition: ProfileSummaryInfo.h:193
llvm::OptimizationRemarkEmitter::emit
void emit(DiagnosticInfoOptimizationBase &OptDiag)
Output the remark via the diagnostic handler and to the optimization record file.
Definition: OptimizationRemarkEmitter.cpp:77
InlineCost.h
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::InlineCost::getNever
static InlineCost getNever(const char *Reason, Optional< CostBenefitPair > CostBenefit=None)
Definition: InlineCost.h:121
llvm::AMDGPU::CPol::SCC
@ SCC
Definition: SIDefines.h:304
llvm::ProfileSummaryAnalysis
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
Definition: ProfileSummaryInfo.h:211
llvm::Pass::doFinalization
virtual bool doFinalization(Module &)
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
Definition: Pass.h:120
llvm::AssumptionCacheTracker
An immutable pass that tracks lazily created AssumptionCache objects.
Definition: AssumptionCache.h:202
llvm::OptimizationRemarkEmitter
The optimization diagnostic interface.
Definition: OptimizationRemarkEmitter.h:33
llvm::AssumptionCache
A cache of @llvm.assume calls within a function.
Definition: AssumptionCache.h:42
llvm::InlineResult::getFailureReason
const char * getFailureReason() const
Definition: InlineCost.h:174
llvm::partition
auto partition(R &&Range, UnaryPredicate P)
Provide wrappers to std::partition which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1730
for
this could be done in SelectionDAGISel along with other special for
Definition: README.txt:104
functions
always Inliner for always_inline functions
Definition: AlwaysInliner.cpp:175
Callee
amdgpu Simplify well known AMD library false FunctionCallee Callee
Definition: AMDGPULibCalls.cpp:186
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:158
llvm::CallBase::isNoInline
bool isNoInline() const
Return true if the call should not be inlined.
Definition: InstrTypes.h:1848
INITIALIZE_PASS_BEGIN
INITIALIZE_PASS_BEGIN(AlwaysInlinerLegacyPass, "always-inline", "Inliner for always_inline functions", false, false) INITIALIZE_PASS_END(AlwaysInlinerLegacyPass
llvm::InlineFunctionInfo
This class captures the data input to the InlineFunction call, and records the auxiliary results prod...
Definition: Cloning.h:199
Inliner
partial Partial Inliner
Definition: PartialInlining.cpp:1523
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:591
llvm::Pass
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
ModuleUtils.h
inline
always inline
Definition: AlwaysInliner.cpp:174
llvm::InlineFunction
InlineResult InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, AAResults *CalleeAAR=nullptr, bool InsertLifetime=true, Function *ForwardVarArgsTo=nullptr)
This function inlines the called function into the basic block of the caller.
Definition: InlineFunction.cpp:1748
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1174
llvm::SmallSetVector
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:307
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:42
llvm::InnerAnalysisManagerProxy
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:937
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::AttributeFuncs::mergeAttributesForInlining
void mergeAttributesForInlining(Function &Caller, const Function &Callee)
Merge caller's and callee's attributes.
Definition: Attributes.cpp:2050
InitializePasses.h
llvm::InlineResult
InlineResult is basically true or false.
Definition: InlineCost.h:164
SetVector.h
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38
DEBUG_TYPE
#define DEBUG_TYPE
Definition: AlwaysInliner.cpp:29