[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
diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
index 930f666..fd65442 100644
--- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp
@@ -2060,6 +2060,70 @@
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 @@
// 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: