diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2008-11-30 08:32:11 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2008-11-30 08:32:11 +0000 |
commit | 09bc6109455ef105f6a2d88c90904a817157eb61 (patch) | |
tree | 98eed9b37ea82052c29b1059a08f8e545996040e /llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp | |
parent | e9ef170d4af016243029942fde8c9e25128a168a (diff) | |
download | bcm5719-llvm-09bc6109455ef105f6a2d88c90904a817157eb61.tar.gz bcm5719-llvm-09bc6109455ef105f6a2d88c90904a817157eb61.zip |
Optimize memmove and memset into the LLVM builtins. Note that these
only show up in code from front-ends besides llvm-gcc, like clang.
llvm-svn: 60287
Diffstat (limited to 'llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp index 89527477a80..07c8d94860c 100644 --- a/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Scalar/SimplifyLibCalls.cpp @@ -707,6 +707,60 @@ struct VISIBILITY_HIDDEN MemCpyOpt : public LibCallOptimization { } }; +//===---------------------------------------===// +// 'memmove' Optimizations + +struct VISIBILITY_HIDDEN MemMoveOpt : public LibCallOptimization { + virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { + const FunctionType *FT = Callee->getFunctionType(); + if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || + !isa<PointerType>(FT->getParamType(0)) || + !isa<PointerType>(FT->getParamType(1)) || + FT->getParamType(2) != TD->getIntPtrType()) + return 0; + + // memmove(x, y, n) -> llvm.memmove(x, y, n, 1) + Module *M = Caller->getParent(); + Intrinsic::ID IID = Intrinsic::memmove; + const Type *Tys[1]; + Tys[0] = TD->getIntPtrType(); + Value *MemMove = Intrinsic::getDeclaration(M, IID, Tys, 1); + Value *Dst = CastToCStr(CI->getOperand(1), B); + Value *Src = CastToCStr(CI->getOperand(2), B); + Value *Size = CI->getOperand(3); + Value *Align = ConstantInt::get(Type::Int32Ty, 1); + B.CreateCall4(MemMove, Dst, Src, Size, Align); + return CI->getOperand(1); + } +}; + +//===---------------------------------------===// +// 'memset' Optimizations + +struct VISIBILITY_HIDDEN MemSetOpt : public LibCallOptimization { + virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { + const FunctionType *FT = Callee->getFunctionType(); + if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || + !isa<PointerType>(FT->getParamType(0)) || + FT->getParamType(1) != TD->getIntPtrType() || + FT->getParamType(2) != TD->getIntPtrType()) + return 0; + + // memset(p, v, n) -> llvm.memset(p, v, n, 1) + Module *M = Caller->getParent(); + Intrinsic::ID IID = Intrinsic::memset; + const Type *Tys[1]; + Tys[0] = TD->getIntPtrType(); + Value *MemSet = Intrinsic::getDeclaration(M, IID, Tys, 1); + Value *Dst = CastToCStr(CI->getOperand(1), B); + Value *Val = B.CreateTrunc(CI->getOperand(2), Type::Int8Ty); + Value *Size = CI->getOperand(3); + Value *Align = ConstantInt::get(Type::Int32Ty, 1); + B.CreateCall4(MemSet, Dst, Val, Size, Align); + return CI->getOperand(1); + } +}; + //===----------------------------------------------------------------------===// // Math Library Optimizations //===----------------------------------------------------------------------===// @@ -1197,6 +1251,7 @@ namespace { // String and Memory LibCall Optimizations StrCatOpt StrCat; StrChrOpt StrChr; StrCmpOpt StrCmp; StrNCmpOpt StrNCmp; StrCpyOpt StrCpy; StrLenOpt StrLen; MemCmpOpt MemCmp; MemCpyOpt MemCpy; + MemMoveOpt MemMove; MemSetOpt MemSet; // Math Library Optimizations PowOpt Pow; Exp2Opt Exp2; UnaryDoubleFPOpt UnaryDoubleFP; // Integer Optimizations @@ -1242,6 +1297,8 @@ void SimplifyLibCalls::InitOptimizations() { Optimizations["strlen"] = &StrLen; Optimizations["memcmp"] = &MemCmp; Optimizations["memcpy"] = &MemCpy; + Optimizations["memmove"] = &MemMove; + Optimizations["memset"] = &MemSet; // Math Library Optimizations Optimizations["powf"] = &Pow; @@ -1386,10 +1443,6 @@ bool SimplifyLibCalls::runOnFunction(Function &F) { // * memcmp(x,y,l) -> cnst // (if all arguments are constant and strlen(x) <= l and strlen(y) <= l) // -// memmove: -// * memmove(d,s,l,a) -> memcpy(d,s,l,a) -// (if s is a global constant array) -// // pow, powf, powl: // * pow(exp(x),y) -> exp(x*y) // * pow(sqrt(x),y) -> pow(x,y*0.5) |