[SimplifyLibCalls] Factor out str/mem libcall optimizations.

Put them in a separate function, so we can reuse them to further
simplify fortified libcalls as well.

Differential Revision: http://reviews.llvm.org/D6540

llvm-svn: 225639
This commit is contained in:
Ahmed Bougacha 2015-01-12 17:20:06 +00:00
parent b7d8afb6c5
commit 6722f5e5b3
2 changed files with 68 additions and 44 deletions

View File

@ -84,6 +84,8 @@ private:
Value *optimizeMemCpy(CallInst *CI, IRBuilder<> &B);
Value *optimizeMemMove(CallInst *CI, IRBuilder<> &B);
Value *optimizeMemSet(CallInst *CI, IRBuilder<> &B);
// Wrapper for all String/Memory Library Call Optimizations
Value *optimizeStringMemoryLibCall(CallInst *CI, IRBuilder<> &B);
// Math Library Optimizations
Value *optimizeUnaryDoubleFP(CallInst *CI, IRBuilder<> &B, bool CheckRetType);

View File

@ -2060,6 +2060,70 @@ bool LibCallSimplifier::hasFloatVersion(StringRef FuncName) {
return false;
}
Value *LibCallSimplifier::optimizeStringMemoryLibCall(CallInst *CI,
IRBuilder<> &Builder) {
LibFunc::Func Func;
Function *Callee = CI->getCalledFunction();
StringRef FuncName = Callee->getName();
// Check for string/memory library functions.
if (TLI->getLibFunc(FuncName, Func) && TLI->has(Func)) {
// Make sure we never change the calling convention.
assert((ignoreCallingConv(Func) ||
CI->getCallingConv() == llvm::CallingConv::C) &&
"Optimizing string/memory libcall would change the calling convention");
switch (Func) {
case LibFunc::strcat:
return optimizeStrCat(CI, Builder);
case LibFunc::strncat:
return optimizeStrNCat(CI, Builder);
case LibFunc::strchr:
return optimizeStrChr(CI, Builder);
case LibFunc::strrchr:
return optimizeStrRChr(CI, Builder);
case LibFunc::strcmp:
return optimizeStrCmp(CI, Builder);
case LibFunc::strncmp:
return optimizeStrNCmp(CI, Builder);
case LibFunc::strcpy:
return optimizeStrCpy(CI, Builder);
case LibFunc::stpcpy:
return optimizeStpCpy(CI, Builder);
case LibFunc::strncpy:
return optimizeStrNCpy(CI, Builder);
case LibFunc::strlen:
return optimizeStrLen(CI, Builder);
case LibFunc::strpbrk:
return optimizeStrPBrk(CI, Builder);
case LibFunc::strtol:
case LibFunc::strtod:
case LibFunc::strtof:
case LibFunc::strtoul:
case LibFunc::strtoll:
case LibFunc::strtold:
case LibFunc::strtoull:
return optimizeStrTo(CI, Builder);
case LibFunc::strspn:
return optimizeStrSpn(CI, Builder);
case LibFunc::strcspn:
return optimizeStrCSpn(CI, Builder);
case LibFunc::strstr:
return optimizeStrStr(CI, Builder);
case LibFunc::memcmp:
return optimizeMemCmp(CI, Builder);
case LibFunc::memcpy:
return optimizeMemCpy(CI, Builder);
case LibFunc::memmove:
return optimizeMemMove(CI, Builder);
case LibFunc::memset:
return optimizeMemSet(CI, Builder);
default:
break;
}
}
return nullptr;
}
Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
if (CI->isNoBuiltin())
return nullptr;
@ -2107,51 +2171,9 @@ Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
// We never change the calling convention.
if (!ignoreCallingConv(Func) && !isCallingConvC)
return nullptr;
if (Value *V = optimizeStringMemoryLibCall(CI, Builder))
return V;
switch (Func) {
case LibFunc::strcat:
return optimizeStrCat(CI, Builder);
case LibFunc::strncat:
return optimizeStrNCat(CI, Builder);
case LibFunc::strchr:
return optimizeStrChr(CI, Builder);
case LibFunc::strrchr:
return optimizeStrRChr(CI, Builder);
case LibFunc::strcmp:
return optimizeStrCmp(CI, Builder);
case LibFunc::strncmp:
return optimizeStrNCmp(CI, Builder);
case LibFunc::strcpy:
return optimizeStrCpy(CI, Builder);
case LibFunc::stpcpy:
return optimizeStpCpy(CI, Builder);
case LibFunc::strncpy:
return optimizeStrNCpy(CI, Builder);
case LibFunc::strlen:
return optimizeStrLen(CI, Builder);
case LibFunc::strpbrk:
return optimizeStrPBrk(CI, Builder);
case LibFunc::strtol:
case LibFunc::strtod:
case LibFunc::strtof:
case LibFunc::strtoul:
case LibFunc::strtoll:
case LibFunc::strtold:
case LibFunc::strtoull:
return optimizeStrTo(CI, Builder);
case LibFunc::strspn:
return optimizeStrSpn(CI, Builder);
case LibFunc::strcspn:
return optimizeStrCSpn(CI, Builder);
case LibFunc::strstr:
return optimizeStrStr(CI, Builder);
case LibFunc::memcmp:
return optimizeMemCmp(CI, Builder);
case LibFunc::memcpy:
return optimizeMemCpy(CI, Builder);
case LibFunc::memmove:
return optimizeMemMove(CI, Builder);
case LibFunc::memset:
return optimizeMemSet(CI, Builder);
case LibFunc::cosf:
case LibFunc::cos:
case LibFunc::cosl: