LLVM API Documentation
00001 //===--- PartiallyInlineLibCalls.cpp - Partially inline libcalls ----------===// 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 tries to partially inline the fast path of well-known library 00011 // functions, such as using square-root instructions for cases where sqrt() 00012 // does not need to set errno. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #include "llvm/Analysis/TargetTransformInfo.h" 00017 #include "llvm/IR/IRBuilder.h" 00018 #include "llvm/IR/Intrinsics.h" 00019 #include "llvm/Pass.h" 00020 #include "llvm/Support/CommandLine.h" 00021 #include "llvm/Target/TargetLibraryInfo.h" 00022 #include "llvm/Transforms/Scalar.h" 00023 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 00024 00025 using namespace llvm; 00026 00027 #define DEBUG_TYPE "partially-inline-libcalls" 00028 00029 namespace { 00030 class PartiallyInlineLibCalls : public FunctionPass { 00031 public: 00032 static char ID; 00033 00034 PartiallyInlineLibCalls() : 00035 FunctionPass(ID) { 00036 initializePartiallyInlineLibCallsPass(*PassRegistry::getPassRegistry()); 00037 } 00038 00039 void getAnalysisUsage(AnalysisUsage &AU) const override; 00040 bool runOnFunction(Function &F) override; 00041 00042 private: 00043 /// Optimize calls to sqrt. 00044 bool optimizeSQRT(CallInst *Call, Function *CalledFunc, 00045 BasicBlock &CurrBB, Function::iterator &BB); 00046 }; 00047 00048 char PartiallyInlineLibCalls::ID = 0; 00049 } 00050 00051 INITIALIZE_PASS(PartiallyInlineLibCalls, "partially-inline-libcalls", 00052 "Partially inline calls to library functions", false, false) 00053 00054 void PartiallyInlineLibCalls::getAnalysisUsage(AnalysisUsage &AU) const { 00055 AU.addRequired<TargetLibraryInfo>(); 00056 AU.addRequired<TargetTransformInfo>(); 00057 FunctionPass::getAnalysisUsage(AU); 00058 } 00059 00060 bool PartiallyInlineLibCalls::runOnFunction(Function &F) { 00061 bool Changed = false; 00062 Function::iterator CurrBB; 00063 TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfo>(); 00064 const TargetTransformInfo *TTI = &getAnalysis<TargetTransformInfo>(); 00065 for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE;) { 00066 CurrBB = BB++; 00067 00068 for (BasicBlock::iterator II = CurrBB->begin(), IE = CurrBB->end(); 00069 II != IE; ++II) { 00070 CallInst *Call = dyn_cast<CallInst>(&*II); 00071 Function *CalledFunc; 00072 00073 if (!Call || !(CalledFunc = Call->getCalledFunction())) 00074 continue; 00075 00076 // Skip if function either has local linkage or is not a known library 00077 // function. 00078 LibFunc::Func LibFunc; 00079 if (CalledFunc->hasLocalLinkage() || !CalledFunc->hasName() || 00080 !TLI->getLibFunc(CalledFunc->getName(), LibFunc)) 00081 continue; 00082 00083 switch (LibFunc) { 00084 case LibFunc::sqrtf: 00085 case LibFunc::sqrt: 00086 if (TTI->haveFastSqrt(Call->getType()) && 00087 optimizeSQRT(Call, CalledFunc, *CurrBB, BB)) 00088 break; 00089 continue; 00090 default: 00091 continue; 00092 } 00093 00094 Changed = true; 00095 break; 00096 } 00097 } 00098 00099 return Changed; 00100 } 00101 00102 bool PartiallyInlineLibCalls::optimizeSQRT(CallInst *Call, 00103 Function *CalledFunc, 00104 BasicBlock &CurrBB, 00105 Function::iterator &BB) { 00106 // There is no need to change the IR, since backend will emit sqrt 00107 // instruction if the call has already been marked read-only. 00108 if (Call->onlyReadsMemory()) 00109 return false; 00110 00111 // The call must have the expected result type. 00112 if (!Call->getType()->isFloatingPointTy()) 00113 return false; 00114 00115 // Do the following transformation: 00116 // 00117 // (before) 00118 // dst = sqrt(src) 00119 // 00120 // (after) 00121 // v0 = sqrt_noreadmem(src) # native sqrt instruction. 00122 // if (v0 is a NaN) 00123 // v1 = sqrt(src) # library call. 00124 // dst = phi(v0, v1) 00125 // 00126 00127 // Move all instructions following Call to newly created block JoinBB. 00128 // Create phi and replace all uses. 00129 BasicBlock *JoinBB = llvm::SplitBlock(&CurrBB, Call->getNextNode(), this); 00130 IRBuilder<> Builder(JoinBB, JoinBB->begin()); 00131 PHINode *Phi = Builder.CreatePHI(Call->getType(), 2); 00132 Call->replaceAllUsesWith(Phi); 00133 00134 // Create basic block LibCallBB and insert a call to library function sqrt. 00135 BasicBlock *LibCallBB = BasicBlock::Create(CurrBB.getContext(), "call.sqrt", 00136 CurrBB.getParent(), JoinBB); 00137 Builder.SetInsertPoint(LibCallBB); 00138 Instruction *LibCall = Call->clone(); 00139 Builder.Insert(LibCall); 00140 Builder.CreateBr(JoinBB); 00141 00142 // Add attribute "readnone" so that backend can use a native sqrt instruction 00143 // for this call. Insert a FP compare instruction and a conditional branch 00144 // at the end of CurrBB. 00145 Call->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone); 00146 CurrBB.getTerminator()->eraseFromParent(); 00147 Builder.SetInsertPoint(&CurrBB); 00148 Value *FCmp = Builder.CreateFCmpOEQ(Call, Call); 00149 Builder.CreateCondBr(FCmp, JoinBB, LibCallBB); 00150 00151 // Add phi operands. 00152 Phi->addIncoming(Call, &CurrBB); 00153 Phi->addIncoming(LibCall, LibCallBB); 00154 00155 BB = JoinBB; 00156 return true; 00157 } 00158 00159 FunctionPass *llvm::createPartiallyInlineLibCallsPass() { 00160 return new PartiallyInlineLibCalls(); 00161 }