LLVM  14.0.0git
AlwaysInliner.cpp
Go to the documentation of this file.
1 //===- InlineAlways.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/CallingConv.h"
22 #include "llvm/IR/DataLayout.h"
23 #include "llvm/IR/Instructions.h"
24 #include "llvm/IR/Module.h"
25 #include "llvm/IR/Type.h"
26 #include "llvm/InitializePasses.h"
27 #include "llvm/Transforms/IPO.h"
31 
32 using namespace llvm;
33 
34 #define DEBUG_TYPE "inline"
35 
38  // Add inline assumptions during code generation.
41  auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
43  };
44  auto &PSI = MAM.getResult<ProfileSummaryAnalysis>(M);
45 
47  bool Changed = false;
48  SmallVector<Function *, 16> InlinedFunctions;
49  for (Function &F : M) {
50  // When callee coroutine function is inlined into caller coroutine function
51  // before coro-split pass,
52  // coro-early pass can not handle this quiet well.
53  // So we won't inline the coroutine function if it have not been unsplited
54  if (F.isPresplitCoroutine())
55  continue;
56 
57  if (!F.isDeclaration() && F.hasFnAttribute(Attribute::AlwaysInline) &&
59  Calls.clear();
60 
61  for (User *U : F.users())
62  if (auto *CB = dyn_cast<CallBase>(U))
63  if (CB->getCalledFunction() == &F)
64  Calls.insert(CB);
65 
66  for (CallBase *CB : Calls) {
67  Function *Caller = CB->getCaller();
68  OptimizationRemarkEmitter ORE(Caller);
69  auto OIC = shouldInline(
70  *CB,
71  [&](CallBase &CB) {
72  return InlineCost::getAlways("always inline attribute");
73  },
74  ORE);
75  assert(OIC);
77  *Caller, *OIC, false, DEBUG_TYPE);
78 
80  /*cg=*/nullptr, GetAssumptionCache, &PSI,
83 
85  *CB, IFI, &FAM.getResult<AAManager>(F), InsertLifetime);
86  assert(Res.isSuccess() && "unexpected failure to inline");
87  (void)Res;
88 
89  // Merge the attributes based on the inlining.
91 
92  Changed = true;
93  }
94 
95  // Remember to try and delete this function afterward. This both avoids
96  // re-walking the rest of the module and avoids dealing with any iterator
97  // invalidation issues while deleting functions.
98  InlinedFunctions.push_back(&F);
99  }
100  }
101 
102  // Remove any live functions.
103  erase_if(InlinedFunctions, [&](Function *F) {
104  F->removeDeadConstantUsers();
105  return !F->isDefTriviallyDead();
106  });
107 
108  // Delete the non-comdat ones from the module and also from our vector.
109  auto NonComdatBegin = partition(
110  InlinedFunctions, [&](Function *F) { return F->hasComdat(); });
111  for (Function *F : make_range(NonComdatBegin, InlinedFunctions.end())) {
112  M.getFunctionList().erase(F);
113  Changed = true;
114  }
115  InlinedFunctions.erase(NonComdatBegin, InlinedFunctions.end());
116 
117  if (!InlinedFunctions.empty()) {
118  // Now we just have the comdat functions. Filter out the ones whose comdats
119  // are not actually dead.
120  filterDeadComdatFunctions(M, InlinedFunctions);
121  // The remaining functions are actually dead.
122  for (Function *F : InlinedFunctions) {
123  M.getFunctionList().erase(F);
124  Changed = true;
125  }
126  }
127 
128  return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
129 }
130 
131 namespace {
132 
133 /// Inliner pass which only handles "always inline" functions.
134 ///
135 /// Unlike the \c AlwaysInlinerPass, this uses the more heavyweight \c Inliner
136 /// base class to provide several facilities such as array alloca merging.
137 class AlwaysInlinerLegacyPass : public LegacyInlinerBase {
138 
139 public:
140  AlwaysInlinerLegacyPass() : LegacyInlinerBase(ID, /*InsertLifetime*/ true) {
142  }
143 
144  AlwaysInlinerLegacyPass(bool InsertLifetime)
145  : LegacyInlinerBase(ID, InsertLifetime) {
147  }
148 
149  /// Main run interface method. We override here to avoid calling skipSCC().
150  bool runOnSCC(CallGraphSCC &SCC) override { return inlineCalls(SCC); }
151 
152  static char ID; // Pass identification, replacement for typeid
153 
154  InlineCost getInlineCost(CallBase &CB) override;
155 
157  bool doFinalization(CallGraph &CG) override {
158  return removeDeadFunctions(CG, /*AlwaysInlineOnly=*/true);
159  }
160 };
161 }
162 
164 INITIALIZE_PASS_BEGIN(AlwaysInlinerLegacyPass, "always-inline",
165  "Inliner for always_inline functions", false, false)
170 INITIALIZE_PASS_END(AlwaysInlinerLegacyPass, "always-inline",
171  "Inliner for always_inline functions", false, false)
172 
173 Pass *llvm::createAlwaysInlinerLegacyPass(bool InsertLifetime) {
174  return new AlwaysInlinerLegacyPass(InsertLifetime);
175 }
176 
177 /// Get the inline cost for the always-inliner.
178 ///
179 /// The always inliner *only* handles functions which are marked with the
180 /// attribute to force inlining. As such, it is dramatically simpler and avoids
181 /// using the powerful (but expensive) inline cost analysis. Instead it uses
182 /// a very simple and boring direct walk of the instructions looking for
183 /// impossible-to-inline constructs.
184 ///
185 /// Note, it would be possible to go to some lengths to cache the information
186 /// computed here, but as we only expect to do this for relatively few and
187 /// small functions which have the explicit attribute to force inlining, it is
188 /// likely not worth it in practice.
191 
192  // Only inline direct calls to functions with always-inline attributes
193  // that are viable for inlining.
194  if (!Callee)
195  return InlineCost::getNever("indirect call");
196 
197  // When callee coroutine function is inlined into caller coroutine function
198  // before coro-split pass,
199  // coro-early pass can not handle this quiet well.
200  // So we won't inline the coroutine function if it have not been unsplited
201  if (Callee->isPresplitCoroutine())
202  return InlineCost::getNever("unsplited coroutine call");
203 
204  // FIXME: We shouldn't even get here for declarations.
205  if (Callee->isDeclaration())
206  return InlineCost::getNever("no definition");
207 
208  if (!CB.hasFnAttr(Attribute::AlwaysInline))
209  return InlineCost::getNever("no alwaysinline attribute");
210 
211  auto IsViable = isInlineViable(*Callee);
212  if (!IsViable.isSuccess())
213  return InlineCost::getNever(IsViable.getFailureReason());
214 
215  return InlineCost::getAlways("always inliner");
216 }
llvm::initializeAlwaysInlinerLegacyPassPass
void initializeAlwaysInlinerLegacyPassPass(PassRegistry &)
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:155
AssumptionCache.h
llvm::AAManager
A manager for alias analyses.
Definition: AliasAnalysis.h:1288
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::SmallVectorImpl::erase
iterator erase(const_iterator CI)
Definition: SmallVector.h:705
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:36
llvm::filterDeadComdatFunctions
void filterDeadComdatFunctions(Module &M, SmallVectorImpl< Function * > &DeadComdatFunctions)
Filter out potentially dead comdat functions where other entries keep the entire comdat group alive.
Definition: ModuleUtils.cpp:180
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:783
Inliner.h
llvm::Function
Definition: Function.h:62
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:173
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
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:1732
llvm::CallGraph
The basic data container for the call graph of a Module of IR.
Definition: CallGraph.h:73
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:1467
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:492
llvm::PreservedAnalyses::none
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:158
Module.h
llvm::InlineCost::getAlways
static InlineCost getAlways(const char *Reason, Optional< CostBenefitPair > CostBenefit=None)
Definition: InlineCost.h:112
llvm::isInlineViable
InlineResult isInlineViable(Function &Callee)
Minimal filter to detect invalid constructs for inlining.
Definition: InlineCost.cpp:2960
F
#define F(x, y, z)
Definition: MD5.cpp:56
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:2788
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.
Definition: InstrTypes.h:1383
MAM
ModuleAnalysisManager MAM
Definition: PassBuilderBindings.cpp:61
llvm::InlineCost
Represents the cost of inlining a function.
Definition: InlineCost.h:82
TargetLibraryInfo.h
false
Definition: StackSlotColoring.cpp:142
llvm::InlineResult::isSuccess
bool isSuccess() const
Definition: InlineCost.h:168
llvm::BlockFrequencyAnalysis
Analysis pass which computes BlockFrequencyInfo.
Definition: BlockFrequencyInfo.h:112
Type.h
llvm::CallBase::getCaller
Function * getCaller()
Helper to get the caller (the parent function).
Definition: Instructions.cpp:282
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:58
llvm::TargetLibraryInfoWrapperPass
Definition: TargetLibraryInfo.h:465
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:30
llvm::AssumptionAnalysis
A function analysis which provides an AssumptionCache.
Definition: AssumptionCache.h:169
INITIALIZE_PASS_DEPENDENCY
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
IPO.h
llvm::CallGraphWrapperPass
The ModulePass which wraps up a CallGraph and the logic to build it.
Definition: CallGraph.h:337
Cloning.h
llvm::ProfileSummaryInfoWrapperPass
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Definition: ProfileSummaryInfo.h:193
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
InlineCost.h
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::InlineCost::getNever
static InlineCost getNever(const char *Reason, Optional< CostBenefitPair > CostBenefit=None)
Definition: InlineCost.h:116
llvm::AMDGPU::CPol::SCC
@ SCC
Definition: SIDefines.h:295
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:200
llvm::OptimizationRemarkEmitter
The optimization diagnostic interface.
Definition: OptimizationRemarkEmitter.h:33
DataLayout.h
llvm::AssumptionCache
A cache of @llvm.assume calls within a function.
Definition: AssumptionCache.h:41
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:1655
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:171
Callee
amdgpu Simplify well known AMD library false FunctionCallee Callee
Definition: AMDGPULibCalls.cpp:206
CallingConv.h
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:161
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:201
Inliner
partial Partial Inliner
Definition: PartialInlining.cpp:1522
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:585
llvm::Pass
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
Instructions.h
llvm::Instruction::getDebugLoc
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Definition: Instruction.h:370
ModuleUtils.h
llvm::Instruction::getParent
const BasicBlock * getParent() const
Definition: Instruction.h:94
inline
always inline
Definition: AlwaysInliner.cpp:170
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:1754
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1161
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:44
llvm::InnerAnalysisManagerProxy
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:940
llvm::AttributeFuncs::mergeAttributesForInlining
void mergeAttributesForInlining(Function &Caller, const Function &Callee)
Merge caller's and callee's attributes.
Definition: Attributes.cpp:2029
true
basic Basic Alias true
Definition: BasicAliasAnalysis.cpp:1879
InitializePasses.h
llvm::InlineResult
InlineResult is basically true or false.
Definition: InlineCost.h:159
SetVector.h
llvm::shouldInline
Optional< InlineCost > shouldInline(CallBase &CB, function_ref< InlineCost(CallBase &CB)> GetInlineCost, OptimizationRemarkEmitter &ORE, bool EnableDeferral=true)
Return the cost only if the inliner should attempt to inline at the given CallSite.
Definition: InlineAdvisor.cpp:360
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37
DEBUG_TYPE
#define DEBUG_TYPE
Definition: AlwaysInliner.cpp:34