LLVM  4.0.0
AlwaysInliner.cpp
Go to the documentation of this file.
1 //===- InlineAlways.cpp - Code to inline always_inline functions ----------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements a custom inliner that handles only functions that
11 // are marked as "always inline".
12 //
13 //===----------------------------------------------------------------------===//
14 
16 #include "llvm/ADT/SetVector.h"
22 #include "llvm/IR/CallSite.h"
23 #include "llvm/IR/CallingConv.h"
24 #include "llvm/IR/DataLayout.h"
25 #include "llvm/IR/Instructions.h"
26 #include "llvm/IR/IntrinsicInst.h"
27 #include "llvm/IR/Module.h"
28 #include "llvm/IR/Type.h"
29 #include "llvm/Transforms/IPO.h"
33 
34 using namespace llvm;
35 
36 #define DEBUG_TYPE "inline"
37 
41  bool Changed = false;
42  SmallVector<Function *, 16> InlinedFunctions;
43  for (Function &F : M)
44  if (!F.isDeclaration() && F.hasFnAttribute(Attribute::AlwaysInline) &&
45  isInlineViable(F)) {
46  Calls.clear();
47 
48  for (User *U : F.users())
49  if (auto CS = CallSite(U))
50  if (CS.getCalledFunction() == &F)
51  Calls.insert(CS);
52 
53  for (CallSite CS : Calls)
54  // FIXME: We really shouldn't be able to fail to inline at this point!
55  // We should do something to log or check the inline failures here.
56  Changed |= InlineFunction(CS, IFI);
57 
58  // Remember to try and delete this function afterward. This both avoids
59  // re-walking the rest of the module and avoids dealing with any iterator
60  // invalidation issues while deleting functions.
61  InlinedFunctions.push_back(&F);
62  }
63 
64  // Remove any live functions.
65  erase_if(InlinedFunctions, [&](Function *F) {
67  return !F->isDefTriviallyDead();
68  });
69 
70  // Delete the non-comdat ones from the module and also from our vector.
71  auto NonComdatBegin = partition(
72  InlinedFunctions, [&](Function *F) { return F->hasComdat(); });
73  for (Function *F : make_range(NonComdatBegin, InlinedFunctions.end()))
74  M.getFunctionList().erase(F);
75  InlinedFunctions.erase(NonComdatBegin, InlinedFunctions.end());
76 
77  if (!InlinedFunctions.empty()) {
78  // Now we just have the comdat functions. Filter out the ones whose comdats
79  // are not actually dead.
80  filterDeadComdatFunctions(M, InlinedFunctions);
81  // The remaining functions are actually dead.
82  for (Function *F : InlinedFunctions)
83  M.getFunctionList().erase(F);
84  }
85 
86  return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
87 }
88 
89 namespace {
90 
91 /// Inliner pass which only handles "always inline" functions.
92 ///
93 /// Unlike the \c AlwaysInlinerPass, this uses the more heavyweight \c Inliner
94 /// base class to provide several facilities such as array alloca merging.
95 class AlwaysInlinerLegacyPass : public LegacyInlinerBase {
96 
97 public:
98  AlwaysInlinerLegacyPass() : LegacyInlinerBase(ID, /*InsertLifetime*/ true) {
100  }
101 
102  AlwaysInlinerLegacyPass(bool InsertLifetime)
103  : LegacyInlinerBase(ID, InsertLifetime) {
105  }
106 
107  /// Main run interface method. We override here to avoid calling skipSCC().
108  bool runOnSCC(CallGraphSCC &SCC) override { return inlineCalls(SCC); }
109 
110  static char ID; // Pass identification, replacement for typeid
111 
112  InlineCost getInlineCost(CallSite CS) override;
113 
115  bool doFinalization(CallGraph &CG) override {
116  return removeDeadFunctions(CG, /*AlwaysInlineOnly=*/true);
117  }
118 };
119 }
120 
122 INITIALIZE_PASS_BEGIN(AlwaysInlinerLegacyPass, "always-inline",
123  "Inliner for always_inline functions", false, false)
128 INITIALIZE_PASS_END(AlwaysInlinerLegacyPass, "always-inline",
129  "Inliner for always_inline functions", false, false)
130 
131 Pass *llvm::createAlwaysInlinerLegacyPass(bool InsertLifetime) {
132  return new AlwaysInlinerLegacyPass(InsertLifetime);
133 }
134 
135 /// \brief Get the inline cost for the always-inliner.
136 ///
137 /// The always inliner *only* handles functions which are marked with the
138 /// attribute to force inlining. As such, it is dramatically simpler and avoids
139 /// using the powerful (but expensive) inline cost analysis. Instead it uses
140 /// a very simple and boring direct walk of the instructions looking for
141 /// impossible-to-inline constructs.
142 ///
143 /// Note, it would be possible to go to some lengths to cache the information
144 /// computed here, but as we only expect to do this for relatively few and
145 /// small functions which have the explicit attribute to force inlining, it is
146 /// likely not worth it in practice.
148  Function *Callee = CS.getCalledFunction();
149 
150  // Only inline direct calls to functions with always-inline attributes
151  // that are viable for inlining. FIXME: We shouldn't even get here for
152  // declarations.
153  if (Callee && !Callee->isDeclaration() &&
154  CS.hasFnAttr(Attribute::AlwaysInline) && isInlineViable(*Callee))
155  return InlineCost::getAlways();
156 
157  return InlineCost::getNever();
158 }
Pass interface - Implemented by all 'passes'.
Definition: Pass.h:81
bool isDefTriviallyDead() const
isDefTriviallyDead - Return true if it is trivially safe to remove this function definition from the ...
Definition: Function.cpp:1191
bool hasComdat() const
Definition: GlobalObject.h:91
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
partial Partial Inliner
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:52
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.
InlineFunctionInfo - This class captures the data input to the InlineFunction call, and records the auxiliary results produced by it.
Definition: Cloning.h:177
Represents the cost of inlining a function.
Definition: InlineCost.h:63
bool InlineFunction(CallInst *C, InlineFunctionInfo &IFI, AAResults *CalleeAAR=nullptr, bool InsertLifetime=true)
InlineFunction - This function inlines the called function into the basic block of the caller...
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:53
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
InlineCost getInlineCost(CallSite CS, const InlineParams &Params, TargetTransformInfo &CalleeTTI, std::function< AssumptionCache &(Function &)> &GetAssumptionCache, ProfileSummaryInfo *PSI)
Get an InlineCost object representing the cost of inlining this callsite.
This class contains all of the helper code which is used to perform the inlining operations that do n...
Definition: Inliner.h:31
bool isInlineViable(Function &Callee)
Minimal filter to detect invalid constructs for inlining.
virtual bool doFinalization(Module &)
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
Definition: Pass.h:115
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...
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:60
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
#define F(x, y, z)
Definition: MD5.cpp:51
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:136
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:110
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:107
The ModulePass which wraps up a CallGraph and the logic to build it.
Definition: CallGraph.h:328
always Inliner for always_inline false
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
static InlineCost getNever()
Definition: InlineCost.h:87
for(unsigned i=0, e=MI->getNumOperands();i!=e;++i)
Pass * createAlwaysInlinerLegacyPass(bool InsertLifetime=true)
Create a legacy pass manager instance of a pass to inline and remove functions marked as "always_inli...
bool hasFnAttr(Attribute::AttrKind Kind) const
Return true if this function has the given attribute.
Definition: CallSite.h:349
void initializeAlwaysInlinerLegacyPassPass(PassRegistry &)
iterator erase(const_iterator CI)
Definition: SmallVector.h:431
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:113
Provides passes to inlining "always_inline" functions.
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:292
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
Module.h This file contains the declarations for the Module class.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
always inline
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:826
Basic Alias true
The basic data container for the call graph of a Module of IR.
Definition: CallGraph.h:76
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:119
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:188
auto partition(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::partition which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:814
void removeDeadConstantUsers() const
If there are any dead constant users dangling off of this constant, remove them.
Definition: Constants.cpp:463
FunTy * getCalledFunction() const
getCalledFunction - Return the function being called if this is a direct call, otherwise return null ...
Definition: CallSite.h:110
CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
A container for analyses that lazily runs them and caches their results.
static InlineCost getAlways()
Definition: InlineCost.h:84