LLVM API Documentation
00001 //===- PartialInlining.cpp - Inline parts of functions --------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This pass performs partial inlining, typically by inlining an if statement 00011 // that surrounds the body of the function. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "llvm/Transforms/IPO.h" 00016 #include "llvm/ADT/Statistic.h" 00017 #include "llvm/IR/CFG.h" 00018 #include "llvm/IR/Dominators.h" 00019 #include "llvm/IR/Instructions.h" 00020 #include "llvm/IR/Module.h" 00021 #include "llvm/Pass.h" 00022 #include "llvm/Transforms/Utils/Cloning.h" 00023 #include "llvm/Transforms/Utils/CodeExtractor.h" 00024 using namespace llvm; 00025 00026 #define DEBUG_TYPE "partialinlining" 00027 00028 STATISTIC(NumPartialInlined, "Number of functions partially inlined"); 00029 00030 namespace { 00031 struct PartialInliner : public ModulePass { 00032 void getAnalysisUsage(AnalysisUsage &AU) const override { } 00033 static char ID; // Pass identification, replacement for typeid 00034 PartialInliner() : ModulePass(ID) { 00035 initializePartialInlinerPass(*PassRegistry::getPassRegistry()); 00036 } 00037 00038 bool runOnModule(Module& M) override; 00039 00040 private: 00041 Function* unswitchFunction(Function* F); 00042 }; 00043 } 00044 00045 char PartialInliner::ID = 0; 00046 INITIALIZE_PASS(PartialInliner, "partial-inliner", 00047 "Partial Inliner", false, false) 00048 00049 ModulePass* llvm::createPartialInliningPass() { return new PartialInliner(); } 00050 00051 Function* PartialInliner::unswitchFunction(Function* F) { 00052 // First, verify that this function is an unswitching candidate... 00053 BasicBlock* entryBlock = F->begin(); 00054 BranchInst *BR = dyn_cast<BranchInst>(entryBlock->getTerminator()); 00055 if (!BR || BR->isUnconditional()) 00056 return nullptr; 00057 00058 BasicBlock* returnBlock = nullptr; 00059 BasicBlock* nonReturnBlock = nullptr; 00060 unsigned returnCount = 0; 00061 for (succ_iterator SI = succ_begin(entryBlock), SE = succ_end(entryBlock); 00062 SI != SE; ++SI) 00063 if (isa<ReturnInst>((*SI)->getTerminator())) { 00064 returnBlock = *SI; 00065 returnCount++; 00066 } else 00067 nonReturnBlock = *SI; 00068 00069 if (returnCount != 1) 00070 return nullptr; 00071 00072 // Clone the function, so that we can hack away on it. 00073 ValueToValueMapTy VMap; 00074 Function* duplicateFunction = CloneFunction(F, VMap, 00075 /*ModuleLevelChanges=*/false); 00076 duplicateFunction->setLinkage(GlobalValue::InternalLinkage); 00077 F->getParent()->getFunctionList().push_back(duplicateFunction); 00078 BasicBlock* newEntryBlock = cast<BasicBlock>(VMap[entryBlock]); 00079 BasicBlock* newReturnBlock = cast<BasicBlock>(VMap[returnBlock]); 00080 BasicBlock* newNonReturnBlock = cast<BasicBlock>(VMap[nonReturnBlock]); 00081 00082 // Go ahead and update all uses to the duplicate, so that we can just 00083 // use the inliner functionality when we're done hacking. 00084 F->replaceAllUsesWith(duplicateFunction); 00085 00086 // Special hackery is needed with PHI nodes that have inputs from more than 00087 // one extracted block. For simplicity, just split the PHIs into a two-level 00088 // sequence of PHIs, some of which will go in the extracted region, and some 00089 // of which will go outside. 00090 BasicBlock* preReturn = newReturnBlock; 00091 newReturnBlock = newReturnBlock->splitBasicBlock( 00092 newReturnBlock->getFirstNonPHI()); 00093 BasicBlock::iterator I = preReturn->begin(); 00094 BasicBlock::iterator Ins = newReturnBlock->begin(); 00095 while (I != preReturn->end()) { 00096 PHINode* OldPhi = dyn_cast<PHINode>(I); 00097 if (!OldPhi) break; 00098 00099 PHINode* retPhi = PHINode::Create(OldPhi->getType(), 2, "", Ins); 00100 OldPhi->replaceAllUsesWith(retPhi); 00101 Ins = newReturnBlock->getFirstNonPHI(); 00102 00103 retPhi->addIncoming(I, preReturn); 00104 retPhi->addIncoming(OldPhi->getIncomingValueForBlock(newEntryBlock), 00105 newEntryBlock); 00106 OldPhi->removeIncomingValue(newEntryBlock); 00107 00108 ++I; 00109 } 00110 newEntryBlock->getTerminator()->replaceUsesOfWith(preReturn, newReturnBlock); 00111 00112 // Gather up the blocks that we're going to extract. 00113 std::vector<BasicBlock*> toExtract; 00114 toExtract.push_back(newNonReturnBlock); 00115 for (Function::iterator FI = duplicateFunction->begin(), 00116 FE = duplicateFunction->end(); FI != FE; ++FI) 00117 if (&*FI != newEntryBlock && &*FI != newReturnBlock && 00118 &*FI != newNonReturnBlock) 00119 toExtract.push_back(FI); 00120 00121 // The CodeExtractor needs a dominator tree. 00122 DominatorTree DT; 00123 DT.recalculate(*duplicateFunction); 00124 00125 // Extract the body of the if. 00126 Function* extractedFunction 00127 = CodeExtractor(toExtract, &DT).extractCodeRegion(); 00128 00129 InlineFunctionInfo IFI; 00130 00131 // Inline the top-level if test into all callers. 00132 std::vector<User *> Users(duplicateFunction->user_begin(), 00133 duplicateFunction->user_end()); 00134 for (std::vector<User*>::iterator UI = Users.begin(), UE = Users.end(); 00135 UI != UE; ++UI) 00136 if (CallInst *CI = dyn_cast<CallInst>(*UI)) 00137 InlineFunction(CI, IFI); 00138 else if (InvokeInst *II = dyn_cast<InvokeInst>(*UI)) 00139 InlineFunction(II, IFI); 00140 00141 // Ditch the duplicate, since we're done with it, and rewrite all remaining 00142 // users (function pointers, etc.) back to the original function. 00143 duplicateFunction->replaceAllUsesWith(F); 00144 duplicateFunction->eraseFromParent(); 00145 00146 ++NumPartialInlined; 00147 00148 return extractedFunction; 00149 } 00150 00151 bool PartialInliner::runOnModule(Module& M) { 00152 std::vector<Function*> worklist; 00153 worklist.reserve(M.size()); 00154 for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) 00155 if (!FI->use_empty() && !FI->isDeclaration()) 00156 worklist.push_back(&*FI); 00157 00158 bool changed = false; 00159 while (!worklist.empty()) { 00160 Function* currFunc = worklist.back(); 00161 worklist.pop_back(); 00162 00163 if (currFunc->use_empty()) continue; 00164 00165 bool recursive = false; 00166 for (User *U : currFunc->users()) 00167 if (Instruction* I = dyn_cast<Instruction>(U)) 00168 if (I->getParent()->getParent() == currFunc) { 00169 recursive = true; 00170 break; 00171 } 00172 if (recursive) continue; 00173 00174 00175 if (Function* newFunc = unswitchFunction(currFunc)) { 00176 worklist.push_back(newFunc); 00177 changed = true; 00178 } 00179 00180 } 00181 00182 return changed; 00183 }