LLVM  12.0.0git
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 //===----------------------------------------------------------------------===//
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"
32 using namespace llvm;
34 #define DEBUG_TYPE "inline"
37  ModuleAnalysisManager &MAM) {
38  // Add inline assumptions during code generation.
40  MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
41  auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
42  return FAM.getResult<AssumptionAnalysis>(F);
43  };
44  auto &PSI = MAM.getResult<ProfileSummaryAnalysis>(M);
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;
57  if (!F.isDeclaration() && F.hasFnAttribute(Attribute::AlwaysInline) &&
59  Calls.clear();
61  for (User *U : F.users())
62  if (auto *CB = dyn_cast<CallBase>(U))
63  if (CB->getCalledFunction() == &F)
64  Calls.insert(CB);
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);
76  emitInlinedInto(ORE, CB->getDebugLoc(), CB->getParent(), F, *Caller,
77  *OIC, false, DEBUG_TYPE);
80  /*cg=*/nullptr, GetAssumptionCache, &PSI,
85  *CB, IFI, &FAM.getResult<AAManager>(F), InsertLifetime);
86  assert(Res.isSuccess() && "unexpected failure to inline");
87  (void)Res;
89  // Merge the attributes based on the inlining.
92  Changed = true;
93  }
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  }
102  // Remove any live functions.
103  erase_if(InlinedFunctions, [&](Function *F) {
104  F->removeDeadConstantUsers();
105  return !F->isDefTriviallyDead();
106  });
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  InlinedFunctions.erase(NonComdatBegin, InlinedFunctions.end());
115  if (!InlinedFunctions.empty()) {
116  // Now we just have the comdat functions. Filter out the ones whose comdats
117  // are not actually dead.
118  filterDeadComdatFunctions(M, InlinedFunctions);
119  // The remaining functions are actually dead.
120  for (Function *F : InlinedFunctions)
121  M.getFunctionList().erase(F);
122  }
124  return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
125 }
127 namespace {
129 /// Inliner pass which only handles "always inline" functions.
130 ///
131 /// Unlike the \c AlwaysInlinerPass, this uses the more heavyweight \c Inliner
132 /// base class to provide several facilities such as array alloca merging.
133 class AlwaysInlinerLegacyPass : public LegacyInlinerBase {
135 public:
136  AlwaysInlinerLegacyPass() : LegacyInlinerBase(ID, /*InsertLifetime*/ true) {
138  }
140  AlwaysInlinerLegacyPass(bool InsertLifetime)
141  : LegacyInlinerBase(ID, InsertLifetime) {
143  }
145  /// Main run interface method. We override here to avoid calling skipSCC().
146  bool runOnSCC(CallGraphSCC &SCC) override { return inlineCalls(SCC); }
148  static char ID; // Pass identification, replacement for typeid
150  InlineCost getInlineCost(CallBase &CB) override;
153  bool doFinalization(CallGraph &CG) override {
154  return removeDeadFunctions(CG, /*AlwaysInlineOnly=*/true);
155  }
156 };
157 }
160 INITIALIZE_PASS_BEGIN(AlwaysInlinerLegacyPass, "always-inline",
161  "Inliner for always_inline functions", false, false)
166 INITIALIZE_PASS_END(AlwaysInlinerLegacyPass, "always-inline",
167  "Inliner for always_inline functions", false, false)
169 Pass *llvm::createAlwaysInlinerLegacyPass(bool InsertLifetime) {
170  return new AlwaysInlinerLegacyPass(InsertLifetime);
171 }
173 /// Get the inline cost for the always-inliner.
174 ///
175 /// The always inliner *only* handles functions which are marked with the
176 /// attribute to force inlining. As such, it is dramatically simpler and avoids
177 /// using the powerful (but expensive) inline cost analysis. Instead it uses
178 /// a very simple and boring direct walk of the instructions looking for
179 /// impossible-to-inline constructs.
180 ///
181 /// Note, it would be possible to go to some lengths to cache the information
182 /// computed here, but as we only expect to do this for relatively few and
183 /// small functions which have the explicit attribute to force inlining, it is
184 /// likely not worth it in practice.
188  // Only inline direct calls to functions with always-inline attributes
189  // that are viable for inlining.
190  if (!Callee)
191  return InlineCost::getNever("indirect call");
193  // When callee coroutine function is inlined into caller coroutine function
194  // before coro-split pass,
195  // coro-early pass can not handle this quiet well.
196  // So we won't inline the coroutine function if it have not been unsplited
197  if (Callee->isPresplitCoroutine())
198  return InlineCost::getNever("unsplited coroutine call");
200  // FIXME: We shouldn't even get here for declarations.
201  if (Callee->isDeclaration())
202  return InlineCost::getNever("no definition");
204  if (!CB.hasFnAttr(Attribute::AlwaysInline))
205  return InlineCost::getNever("no alwaysinline attribute");
207  auto IsViable = isInlineViable(*Callee);
208  if (!IsViable.isSuccess())
209  return InlineCost::getNever(IsViable.getFailureReason());
211  return InlineCost::getAlways("always inliner");
212 }
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:91
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.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:785
partial Partial Inliner
This class represents lattice values for constants.
Definition: AllocatorList.h:23
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
Function * getCaller()
Helper to get the caller (the parent function).
INITIALIZE_PASS_BEGIN(AlwaysInlinerLegacyPass, "always-inline", "Inliner for always_inline functions", false, false) INITIALIZE_PASS_END(AlwaysInlinerLegacyPass
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1164
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.
This class captures the data input to the InlineFunction call, and records the auxiliary results prod...
Definition: Cloning.h:172
Represents the cost of inlining a function.
Definition: InlineCost.h:67
bool isSuccess() const
Definition: InlineCost.h:143
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
This class contains all of the helper code which is used to perform the inlining operations that do n...
Definition: Inliner.h:30
virtual bool doFinalization(Module &)
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
Definition: Pass.h:120
always Inliner for always_inline functions
void filterDeadComdatFunctions(Module &M, SmallVectorImpl< Function * > &DeadComdatFunctions)
Filter out potentially dead comdat functions where other entries keep the entire comdat group alive.
InlineResult is basically true or false.
Definition: InlineCost.h:134
static InlineCost getAlways(const char *Reason)
Definition: InlineCost.h:92
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:158
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:155
The ModulePass which wraps up a CallGraph and the logic to build it.
Definition: CallGraph.h:337
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
A manager for alias analyses.
InlineResult isInlineViable(Function &Callee)
Minimal filter to detect invalid constructs for inlining.
Pass * createAlwaysInlinerLegacyPass(bool InsertLifetime=true)
Create a legacy pass manager instance of a pass to inline and remove functions marked as "always_inli...
void initializeAlwaysInlinerLegacyPassPass(PassRegistry &)
iterator erase(const_iterator CI)
Definition: SmallVector.h:653
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:161
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
Definition: InstrTypes.h:1463
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
Provides passes to inlining "always_inline" functions.
A function analysis which provides an AssumptionCache.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:307
Analysis pass which computes BlockFrequencyInfo.
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.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1116
Module.h This file contains the declarations for the Module class.
always inline
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
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:1667
void mergeAttributesForInlining(Function &Caller, const Function &Callee)
Merge caller's and callee's attributes.
amdgpu Simplify well known AMD library false FunctionCallee Callee
basic Basic Alias true
The basic data container for the call graph of a Module of IR.
Definition: CallGraph.h:73
static InlineCost getNever(const char *Reason)
Definition: InlineCost.h:95
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Definition: Instruction.h:365
void emitInlinedInto(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.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
Definition: InstrTypes.h:1378
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:1602
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
A container for analyses that lazily runs them and caches their results.
for(auto &MBB :MF)
#define DEBUG_TYPE
The optimization diagnostic interface.
const BasicBlock * getParent() const
Definition: Instruction.h:94
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:969