LLVM  4.0.0
PartialInlining.cpp
Go to the documentation of this file.
1 //===- PartialInlining.cpp - Inline parts of 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 pass performs partial inlining, typically by inlining an if statement
11 // that surrounds the body of the function.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 #include "llvm/ADT/Statistic.h"
19 #include "llvm/Analysis/LoopInfo.h"
20 #include "llvm/IR/CFG.h"
21 #include "llvm/IR/Dominators.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/Module.h"
24 #include "llvm/Pass.h"
25 #include "llvm/Transforms/IPO.h"
28 using namespace llvm;
29 
30 #define DEBUG_TYPE "partialinlining"
31 
32 STATISTIC(NumPartialInlined, "Number of functions partially inlined");
33 
34 namespace {
35 struct PartialInlinerImpl {
36  PartialInlinerImpl(InlineFunctionInfo IFI) : IFI(IFI) {}
37  bool run(Module &M);
38  Function *unswitchFunction(Function *F);
39 
40 private:
42 };
43 struct PartialInlinerLegacyPass : public ModulePass {
44  static char ID; // Pass identification, replacement for typeid
45  PartialInlinerLegacyPass() : ModulePass(ID) {
47  }
48 
49  void getAnalysisUsage(AnalysisUsage &AU) const override {
51  }
52  bool runOnModule(Module &M) override {
53  if (skipModule(M))
54  return false;
55 
56  AssumptionCacheTracker *ACT = &getAnalysis<AssumptionCacheTracker>();
57  std::function<AssumptionCache &(Function &)> GetAssumptionCache =
58  [&ACT](Function &F) -> AssumptionCache & {
59  return ACT->getAssumptionCache(F);
60  };
61  InlineFunctionInfo IFI(nullptr, &GetAssumptionCache);
62  return PartialInlinerImpl(IFI).run(M);
63  }
64 };
65 }
66 
67 Function *PartialInlinerImpl::unswitchFunction(Function *F) {
68  // First, verify that this function is an unswitching candidate...
69  BasicBlock *EntryBlock = &F->front();
70  BranchInst *BR = dyn_cast<BranchInst>(EntryBlock->getTerminator());
71  if (!BR || BR->isUnconditional())
72  return nullptr;
73 
74  BasicBlock *ReturnBlock = nullptr;
75  BasicBlock *NonReturnBlock = nullptr;
76  unsigned ReturnCount = 0;
77  for (BasicBlock *BB : successors(EntryBlock)) {
78  if (isa<ReturnInst>(BB->getTerminator())) {
79  ReturnBlock = BB;
80  ReturnCount++;
81  } else
82  NonReturnBlock = BB;
83  }
84 
85  if (ReturnCount != 1)
86  return nullptr;
87 
88  // Clone the function, so that we can hack away on it.
89  ValueToValueMapTy VMap;
90  Function *DuplicateFunction = CloneFunction(F, VMap);
91  DuplicateFunction->setLinkage(GlobalValue::InternalLinkage);
92  BasicBlock *NewEntryBlock = cast<BasicBlock>(VMap[EntryBlock]);
93  BasicBlock *NewReturnBlock = cast<BasicBlock>(VMap[ReturnBlock]);
94  BasicBlock *NewNonReturnBlock = cast<BasicBlock>(VMap[NonReturnBlock]);
95 
96  // Go ahead and update all uses to the duplicate, so that we can just
97  // use the inliner functionality when we're done hacking.
98  F->replaceAllUsesWith(DuplicateFunction);
99 
100  // Special hackery is needed with PHI nodes that have inputs from more than
101  // one extracted block. For simplicity, just split the PHIs into a two-level
102  // sequence of PHIs, some of which will go in the extracted region, and some
103  // of which will go outside.
104  BasicBlock *PreReturn = NewReturnBlock;
105  NewReturnBlock = NewReturnBlock->splitBasicBlock(
106  NewReturnBlock->getFirstNonPHI()->getIterator());
107  BasicBlock::iterator I = PreReturn->begin();
108  Instruction *Ins = &NewReturnBlock->front();
109  while (I != PreReturn->end()) {
110  PHINode *OldPhi = dyn_cast<PHINode>(I);
111  if (!OldPhi)
112  break;
113 
114  PHINode *RetPhi = PHINode::Create(OldPhi->getType(), 2, "", Ins);
115  OldPhi->replaceAllUsesWith(RetPhi);
116  Ins = NewReturnBlock->getFirstNonPHI();
117 
118  RetPhi->addIncoming(&*I, PreReturn);
119  RetPhi->addIncoming(OldPhi->getIncomingValueForBlock(NewEntryBlock),
120  NewEntryBlock);
121  OldPhi->removeIncomingValue(NewEntryBlock);
122 
123  ++I;
124  }
125  NewEntryBlock->getTerminator()->replaceUsesOfWith(PreReturn, NewReturnBlock);
126 
127  // Gather up the blocks that we're going to extract.
128  std::vector<BasicBlock *> ToExtract;
129  ToExtract.push_back(NewNonReturnBlock);
130  for (BasicBlock &BB : *DuplicateFunction)
131  if (&BB != NewEntryBlock && &BB != NewReturnBlock &&
132  &BB != NewNonReturnBlock)
133  ToExtract.push_back(&BB);
134 
135  // The CodeExtractor needs a dominator tree.
136  DominatorTree DT;
137  DT.recalculate(*DuplicateFunction);
138 
139  // Manually calculate a BlockFrequencyInfo and BranchProbabilityInfo.
140  LoopInfo LI(DT);
141  BranchProbabilityInfo BPI(*DuplicateFunction, LI);
142  BlockFrequencyInfo BFI(*DuplicateFunction, BPI, LI);
143 
144  // Extract the body of the if.
145  Function *ExtractedFunction =
146  CodeExtractor(ToExtract, &DT, /*AggregateArgs*/ false, &BFI, &BPI)
148 
149  // Inline the top-level if test into all callers.
150  std::vector<User *> Users(DuplicateFunction->user_begin(),
151  DuplicateFunction->user_end());
152  for (User *User : Users)
153  if (CallInst *CI = dyn_cast<CallInst>(User))
154  InlineFunction(CI, IFI);
155  else if (InvokeInst *II = dyn_cast<InvokeInst>(User))
156  InlineFunction(II, IFI);
157 
158  // Ditch the duplicate, since we're done with it, and rewrite all remaining
159  // users (function pointers, etc.) back to the original function.
160  DuplicateFunction->replaceAllUsesWith(F);
161  DuplicateFunction->eraseFromParent();
162 
163  ++NumPartialInlined;
164 
165  return ExtractedFunction;
166 }
167 
168 bool PartialInlinerImpl::run(Module &M) {
169  std::vector<Function *> Worklist;
170  Worklist.reserve(M.size());
171  for (Function &F : M)
172  if (!F.use_empty() && !F.isDeclaration())
173  Worklist.push_back(&F);
174 
175  bool Changed = false;
176  while (!Worklist.empty()) {
177  Function *CurrFunc = Worklist.back();
178  Worklist.pop_back();
179 
180  if (CurrFunc->use_empty())
181  continue;
182 
183  bool Recursive = false;
184  for (User *U : CurrFunc->users())
185  if (Instruction *I = dyn_cast<Instruction>(U))
186  if (I->getParent()->getParent() == CurrFunc) {
187  Recursive = true;
188  break;
189  }
190  if (Recursive)
191  continue;
192 
193  if (Function *NewFunc = unswitchFunction(CurrFunc)) {
194  Worklist.push_back(NewFunc);
195  Changed = true;
196  }
197  }
198 
199  return Changed;
200 }
201 
203 INITIALIZE_PASS_BEGIN(PartialInlinerLegacyPass, "partial-inliner",
204  "Partial Inliner", false, false)
206 INITIALIZE_PASS_END(PartialInlinerLegacyPass, "partial-inliner",
207  "Partial Inliner", false, false)
208 
210  return new PartialInlinerLegacyPass();
211 }
212 
214  ModuleAnalysisManager &AM) {
215  auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
216  std::function<AssumptionCache &(Function &)> GetAssumptionCache =
217  [&FAM](Function &F) -> AssumptionCache & {
218  return FAM.getResult<AssumptionAnalysis>(F);
219  };
220  InlineFunctionInfo IFI(nullptr, &GetAssumptionCache);
221  if (PartialInlinerImpl(IFI).run(M))
222  return PreservedAnalyses::none();
223  return PreservedAnalyses::all();
224 }
Utility class for extracting code into a new function.
Definition: CodeExtractor.h:47
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
STATISTIC(NumFunctions,"Total number of functions")
partial Partial Inliner
void initializePartialInlinerLegacyPassPass(PassRegistry &)
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:52
This class represents a function call, abstracting a target machine's calling convention.
Function * CloneFunction(Function *F, ValueToValueMapTy &VMap, ClonedCodeInfo *CodeInfo=nullptr)
CloneFunction - Return a copy of the specified function and add it to that function's module...
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of .assume calls within a function.
Function * extractCodeRegion()
Perform the extraction, returning the new function.
partial Partial false
iv Induction Variable Users
Definition: IVUsers.cpp:51
InlineFunctionInfo - This class captures the data input to the InlineFunction call, and records the auxiliary results produced by it.
Definition: Cloning.h:177
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:228
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...
AnalysisUsage & addRequired()
ModulePass * createPartialInliningPass()
createPartialInliningPass - This pass inlines parts of functions.
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:53
bool isUnconditional() const
Value * removeIncomingValue(unsigned Idx, bool DeletePHIIfEmpty=true)
Remove an incoming value.
partial inliner
#define F(x, y, z)
Definition: MD5.cpp:51
const BasicBlock & back() const
Definition: Function.h:544
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:401
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Definition: Dominators.h:96
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:110
void replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition: User.cpp:24
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Control flow instructions. These all have token chains.
Definition: ISDOpcodes.h:551
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:107
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs...ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:653
LLVM Basic Block Representation.
Definition: BasicBlock.h:51
Conditional or Unconditional Branch instruction.
Represent the analysis usage information of a pass.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:113
A function analysis which provides an AssumptionCache.
Iterator for intrusive lists based on ilist_node.
iterator end()
Definition: BasicBlock.h:230
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:230
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:424
Value * getIncomingValueForBlock(const BasicBlock *BB) const
iterator_range< user_iterator > users()
Definition: Value.h:370
size_t size() const
Definition: Module.h:543
Analysis providing branch probability information.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:188
#define I(x, y, z)
Definition: MD5.cpp:54
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.cpp:124
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:235
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:287
Rename collisions when linking (static functions).
Definition: GlobalValue.h:56
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
Definition: BasicBlock.cpp:374
bool use_empty() const
Definition: Value.h:299
const BasicBlock & front() const
Definition: Function.h:542
succ_range successors(BasicBlock *BB)
Definition: IR/CFG.h:143
Invoke instruction.
AssumptionCache & getAssumptionCache(Function &F)
Get the cached assumptions for a function.
void recalculate(FT &F)
recalculate - compute a dominator tree for the given function
A container for analyses that lazily runs them and caches their results.
INITIALIZE_PASS_BEGIN(PartialInlinerLegacyPass,"partial-inliner","Partial Inliner", false, false) INITIALIZE_PASS_END(PartialInlinerLegacyPass
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:905