summaryrefslogtreecommitdiff
path: root/lib/Transforms/Scalar/SimplifyLibCalls.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/Scalar/SimplifyLibCalls.cpp')
-rw-r--r--lib/Transforms/Scalar/SimplifyLibCalls.cpp247
1 files changed, 0 insertions, 247 deletions
diff --git a/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/lib/Transforms/Scalar/SimplifyLibCalls.cpp
deleted file mode 100644
index 3514e6c2aa..0000000000
--- a/lib/Transforms/Scalar/SimplifyLibCalls.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-//===- SimplifyLibCalls.cpp - Optimize specific well-known library calls --===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a simple pass that applies a variety of small
-// optimizations for calls to specific well-known function calls (e.g. runtime
-// library functions). Any optimization that takes the very simple form
-// "replace call to library function with simpler code that provides the same
-// result" belongs in this file.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "simplify-libcalls"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/Config/config.h" // FIXME: Shouldn't depend on host!
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetLibraryInfo.h"
-#include "llvm/Transforms/Utils/BuildLibCalls.h"
-using namespace llvm;
-
-
-//===----------------------------------------------------------------------===//
-// Optimizer Base Class
-//===----------------------------------------------------------------------===//
-
-/// This class is the abstract base class for the set of optimizations that
-/// corresponds to one library call.
-namespace {
-class LibCallOptimization {
-protected:
- Function *Caller;
- const DataLayout *TD;
- const TargetLibraryInfo *TLI;
- LLVMContext* Context;
-public:
- LibCallOptimization() { }
- virtual ~LibCallOptimization() {}
-
- /// CallOptimizer - This pure virtual method is implemented by base classes to
- /// do various optimizations. If this returns null then no transformation was
- /// performed. If it returns CI, then it transformed the call and CI is to be
- /// deleted. If it returns something else, replace CI with the new value and
- /// delete CI.
- virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)
- =0;
-
- Value *OptimizeCall(CallInst *CI, const DataLayout *TD,
- const TargetLibraryInfo *TLI, IRBuilder<> &B) {
- Caller = CI->getParent()->getParent();
- this->TD = TD;
- this->TLI = TLI;
- if (CI->getCalledFunction())
- Context = &CI->getCalledFunction()->getContext();
-
- // We never change the calling convention.
- if (CI->getCallingConv() != llvm::CallingConv::C)
- return NULL;
-
- return CallOptimizer(CI->getCalledFunction(), CI, B);
- }
-};
-} // End anonymous namespace.
-
-
-//===----------------------------------------------------------------------===//
-// SimplifyLibCalls Pass Implementation
-//===----------------------------------------------------------------------===//
-
-namespace {
- /// This pass optimizes well known library functions from libc and libm.
- ///
- class SimplifyLibCalls : public FunctionPass {
- TargetLibraryInfo *TLI;
-
- StringMap<LibCallOptimization*> Optimizations;
- public:
- static char ID; // Pass identification
- SimplifyLibCalls() : FunctionPass(ID) {
- initializeSimplifyLibCallsPass(*PassRegistry::getPassRegistry());
- }
- void AddOpt(LibFunc::Func F, LibCallOptimization* Opt);
- void AddOpt(LibFunc::Func F1, LibFunc::Func F2, LibCallOptimization* Opt);
-
- void InitOptimizations();
- bool runOnFunction(Function &F);
-
- virtual void getAnalysisUsage(AnalysisUsage &AU) const {
- AU.addRequired<TargetLibraryInfo>();
- }
- };
-} // end anonymous namespace.
-
-char SimplifyLibCalls::ID = 0;
-
-INITIALIZE_PASS_BEGIN(SimplifyLibCalls, "simplify-libcalls",
- "Simplify well-known library calls", false, false)
-INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)
-INITIALIZE_PASS_END(SimplifyLibCalls, "simplify-libcalls",
- "Simplify well-known library calls", false, false)
-
-// Public interface to the Simplify LibCalls pass.
-FunctionPass *llvm::createSimplifyLibCallsPass() {
- return new SimplifyLibCalls();
-}
-
-void SimplifyLibCalls::AddOpt(LibFunc::Func F, LibCallOptimization* Opt) {
- if (TLI->has(F))
- Optimizations[TLI->getName(F)] = Opt;
-}
-
-void SimplifyLibCalls::AddOpt(LibFunc::Func F1, LibFunc::Func F2,
- LibCallOptimization* Opt) {
- if (TLI->has(F1) && TLI->has(F2))
- Optimizations[TLI->getName(F1)] = Opt;
-}
-
-/// Optimizations - Populate the Optimizations map with all the optimizations
-/// we know.
-void SimplifyLibCalls::InitOptimizations() {
-}
-
-
-/// runOnFunction - Top level algorithm.
-///
-bool SimplifyLibCalls::runOnFunction(Function &F) {
- TLI = &getAnalysis<TargetLibraryInfo>();
-
- if (Optimizations.empty())
- InitOptimizations();
-
- const DataLayout *TD = getAnalysisIfAvailable<DataLayout>();
-
- IRBuilder<> Builder(F.getContext());
-
- bool Changed = false;
- for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
- for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
- // Ignore non-calls.
- CallInst *CI = dyn_cast<CallInst>(I++);
- if (!CI || CI->hasFnAttr(Attribute::NoBuiltin)) continue;
-
- // Ignore indirect calls and calls to non-external functions.
- Function *Callee = CI->getCalledFunction();
- if (Callee == 0 || !Callee->isDeclaration() ||
- !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage()))
- continue;
-
- // Ignore unknown calls.
- LibCallOptimization *LCO = Optimizations.lookup(Callee->getName());
- if (!LCO) continue;
-
- // Set the builder to the instruction after the call.
- Builder.SetInsertPoint(BB, I);
-
- // Use debug location of CI for all new instructions.
- Builder.SetCurrentDebugLocation(CI->getDebugLoc());
-
- // Try to optimize this call.
- Value *Result = LCO->OptimizeCall(CI, TD, TLI, Builder);
- if (Result == 0) continue;
-
- DEBUG(dbgs() << "SimplifyLibCalls simplified: " << *CI;
- dbgs() << " into: " << *Result << "\n");
-
- // Something changed!
- Changed = true;
-
- // Inspect the instruction after the call (which was potentially just
- // added) next.
- I = CI; ++I;
-
- if (CI != Result && !CI->use_empty()) {
- CI->replaceAllUsesWith(Result);
- if (!Result->hasName())
- Result->takeName(CI);
- }
- CI->eraseFromParent();
- }
- }
- return Changed;
-}
-
-// TODO:
-// Additional cases that we need to add to this file:
-//
-// cbrt:
-// * cbrt(expN(X)) -> expN(x/3)
-// * cbrt(sqrt(x)) -> pow(x,1/6)
-// * cbrt(sqrt(x)) -> pow(x,1/9)
-//
-// exp, expf, expl:
-// * exp(log(x)) -> x
-//
-// log, logf, logl:
-// * log(exp(x)) -> x
-// * log(x**y) -> y*log(x)
-// * log(exp(y)) -> y*log(e)
-// * log(exp2(y)) -> y*log(2)
-// * log(exp10(y)) -> y*log(10)
-// * log(sqrt(x)) -> 0.5*log(x)
-// * log(pow(x,y)) -> y*log(x)
-//
-// lround, lroundf, lroundl:
-// * lround(cnst) -> cnst'
-//
-// pow, powf, powl:
-// * pow(exp(x),y) -> exp(x*y)
-// * pow(sqrt(x),y) -> pow(x,y*0.5)
-// * pow(pow(x,y),z)-> pow(x,y*z)
-//
-// round, roundf, roundl:
-// * round(cnst) -> cnst'
-//
-// signbit:
-// * signbit(cnst) -> cnst'
-// * signbit(nncst) -> 0 (if pstv is a non-negative constant)
-//
-// sqrt, sqrtf, sqrtl:
-// * sqrt(expN(x)) -> expN(x*0.5)
-// * sqrt(Nroot(x)) -> pow(x,1/(2*N))
-// * sqrt(pow(x,y)) -> pow(|x|,y*0.5)
-//
-// strchr:
-// * strchr(p, 0) -> strlen(p)
-// tan, tanf, tanl:
-// * tan(atan(x)) -> x
-//
-// trunc, truncf, truncl:
-// * trunc(cnst) -> cnst'
-//
-//