diff options
Diffstat (limited to 'lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp')
-rw-r--r-- | lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp | 179 |
1 files changed, 96 insertions, 83 deletions
diff --git a/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp b/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp index 9f26f78892c65..c4b3e3464f409 100644 --- a/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp +++ b/lib/Transforms/Scalar/PartiallyInlineLibCalls.cpp @@ -13,12 +13,10 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/IR/IRBuilder.h" -#include "llvm/IR/Intrinsics.h" -#include "llvm/Pass.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" @@ -26,85 +24,9 @@ using namespace llvm; #define DEBUG_TYPE "partially-inline-libcalls" -namespace { - class PartiallyInlineLibCalls : public FunctionPass { - public: - static char ID; - - PartiallyInlineLibCalls() : - FunctionPass(ID) { - initializePartiallyInlineLibCallsPass(*PassRegistry::getPassRegistry()); - } - - void getAnalysisUsage(AnalysisUsage &AU) const override; - bool runOnFunction(Function &F) override; - - private: - /// Optimize calls to sqrt. - bool optimizeSQRT(CallInst *Call, Function *CalledFunc, - BasicBlock &CurrBB, Function::iterator &BB); - }; - - char PartiallyInlineLibCalls::ID = 0; -} - -INITIALIZE_PASS(PartiallyInlineLibCalls, "partially-inline-libcalls", - "Partially inline calls to library functions", false, false) - -void PartiallyInlineLibCalls::getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<TargetLibraryInfoWrapperPass>(); - AU.addRequired<TargetTransformInfoWrapperPass>(); - FunctionPass::getAnalysisUsage(AU); -} - -bool PartiallyInlineLibCalls::runOnFunction(Function &F) { - bool Changed = false; - Function::iterator CurrBB; - TargetLibraryInfo *TLI = - &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); - const TargetTransformInfo *TTI = - &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F); - for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE;) { - CurrBB = BB++; - - for (BasicBlock::iterator II = CurrBB->begin(), IE = CurrBB->end(); - II != IE; ++II) { - CallInst *Call = dyn_cast<CallInst>(&*II); - Function *CalledFunc; - - if (!Call || !(CalledFunc = Call->getCalledFunction())) - continue; - - // Skip if function either has local linkage or is not a known library - // function. - LibFunc::Func LibFunc; - if (CalledFunc->hasLocalLinkage() || !CalledFunc->hasName() || - !TLI->getLibFunc(CalledFunc->getName(), LibFunc)) - continue; - - switch (LibFunc) { - case LibFunc::sqrtf: - case LibFunc::sqrt: - if (TTI->haveFastSqrt(Call->getType()) && - optimizeSQRT(Call, CalledFunc, *CurrBB, BB)) - break; - continue; - default: - continue; - } - Changed = true; - break; - } - } - - return Changed; -} - -bool PartiallyInlineLibCalls::optimizeSQRT(CallInst *Call, - Function *CalledFunc, - BasicBlock &CurrBB, - Function::iterator &BB) { +static bool optimizeSQRT(CallInst *Call, Function *CalledFunc, + BasicBlock &CurrBB, Function::iterator &BB) { // There is no need to change the IR, since backend will emit sqrt // instruction if the call has already been marked read-only. if (Call->onlyReadsMemory()) @@ -158,6 +80,97 @@ bool PartiallyInlineLibCalls::optimizeSQRT(CallInst *Call, return true; } +static bool runPartiallyInlineLibCalls(Function &F, TargetLibraryInfo *TLI, + const TargetTransformInfo *TTI) { + bool Changed = false; + + Function::iterator CurrBB; + for (Function::iterator BB = F.begin(), BE = F.end(); BB != BE;) { + CurrBB = BB++; + + for (BasicBlock::iterator II = CurrBB->begin(), IE = CurrBB->end(); + II != IE; ++II) { + CallInst *Call = dyn_cast<CallInst>(&*II); + Function *CalledFunc; + + if (!Call || !(CalledFunc = Call->getCalledFunction())) + continue; + + // Skip if function either has local linkage or is not a known library + // function. + LibFunc::Func LibFunc; + if (CalledFunc->hasLocalLinkage() || !CalledFunc->hasName() || + !TLI->getLibFunc(CalledFunc->getName(), LibFunc)) + continue; + + switch (LibFunc) { + case LibFunc::sqrtf: + case LibFunc::sqrt: + if (TTI->haveFastSqrt(Call->getType()) && + optimizeSQRT(Call, CalledFunc, *CurrBB, BB)) + break; + continue; + default: + continue; + } + + Changed = true; + break; + } + } + + return Changed; +} + +PreservedAnalyses +PartiallyInlineLibCallsPass::run(Function &F, AnalysisManager<Function> &AM) { + auto &TLI = AM.getResult<TargetLibraryAnalysis>(F); + auto &TTI = AM.getResult<TargetIRAnalysis>(F); + if (!runPartiallyInlineLibCalls(F, &TLI, &TTI)) + return PreservedAnalyses::all(); + return PreservedAnalyses::none(); +} + +namespace { +class PartiallyInlineLibCallsLegacyPass : public FunctionPass { +public: + static char ID; + + PartiallyInlineLibCallsLegacyPass() : FunctionPass(ID) { + initializePartiallyInlineLibCallsLegacyPassPass( + *PassRegistry::getPassRegistry()); + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequired<TargetLibraryInfoWrapperPass>(); + AU.addRequired<TargetTransformInfoWrapperPass>(); + FunctionPass::getAnalysisUsage(AU); + } + + bool runOnFunction(Function &F) override { + if (skipFunction(F)) + return false; + + TargetLibraryInfo *TLI = + &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); + const TargetTransformInfo *TTI = + &getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F); + return runPartiallyInlineLibCalls(F, TLI, TTI); + } +}; +} + +char PartiallyInlineLibCallsLegacyPass::ID = 0; +INITIALIZE_PASS_BEGIN(PartiallyInlineLibCallsLegacyPass, + "partially-inline-libcalls", + "Partially inline calls to library functions", false, + false) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) +INITIALIZE_PASS_END(PartiallyInlineLibCallsLegacyPass, + "partially-inline-libcalls", + "Partially inline calls to library functions", false, false) + FunctionPass *llvm::createPartiallyInlineLibCallsPass() { - return new PartiallyInlineLibCalls(); + return new PartiallyInlineLibCallsLegacyPass(); } |