[llvm] r225639 - [SimplifyLibCalls] Factor out str/mem libcall optimizations.
Ahmed Bougacha
ahmed.bougacha at gmail.com
Mon Jan 12 09:20:07 PST 2015
Author: ab
Date: Mon Jan 12 11:20:06 2015
New Revision: 225639
URL: http://llvm.org/viewvc/llvm-project?rev=225639&view=rev
Log:
[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
Modified:
llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
Modified: llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h?rev=225639&r1=225638&r2=225639&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/SimplifyLibCalls.h Mon Jan 12 11:20:06 2015
@@ -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);
Modified: llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp?rev=225639&r1=225638&r2=225639&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyLibCalls.cpp Mon Jan 12 11:20:06 2015
@@ -2060,53 +2060,18 @@ bool LibCallSimplifier::hasFloatVersion(
return false;
}
-Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
- if (CI->isNoBuiltin())
- return nullptr;
-
+Value *LibCallSimplifier::optimizeStringMemoryLibCall(CallInst *CI,
+ IRBuilder<> &Builder) {
LibFunc::Func Func;
Function *Callee = CI->getCalledFunction();
StringRef FuncName = Callee->getName();
- IRBuilder<> Builder(CI);
- bool isCallingConvC = CI->getCallingConv() == llvm::CallingConv::C;
-
- // Command-line parameter overrides function attribute.
- if (EnableUnsafeFPShrink.getNumOccurrences() > 0)
- UnsafeFPShrink = EnableUnsafeFPShrink;
- else if (Callee->hasFnAttribute("unsafe-fp-math")) {
- // FIXME: This is the same problem as described in optimizeSqrt().
- // If calls gain access to IR-level FMF, then use that instead of a
- // function attribute.
-
- // Check for unsafe-fp-math = true.
- Attribute Attr = Callee->getFnAttribute("unsafe-fp-math");
- if (Attr.getValueAsString() == "true")
- UnsafeFPShrink = true;
- }
-
- // First, check for intrinsics.
- if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
- if (!isCallingConvC)
- return nullptr;
- switch (II->getIntrinsicID()) {
- case Intrinsic::pow:
- return optimizePow(CI, Builder);
- case Intrinsic::exp2:
- return optimizeExp2(CI, Builder);
- case Intrinsic::fabs:
- return optimizeFabs(CI, Builder);
- case Intrinsic::sqrt:
- return optimizeSqrt(CI, Builder);
- default:
- return nullptr;
- }
- }
- // Then check for known library functions.
+ // Check for string/memory library functions.
if (TLI->getLibFunc(FuncName, Func) && TLI->has(Func)) {
- // We never change the calling convention.
- if (!ignoreCallingConv(Func) && !isCallingConvC)
- return nullptr;
+ // 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);
@@ -2152,6 +2117,63 @@ Value *LibCallSimplifier::optimizeCall(C
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;
+
+ LibFunc::Func Func;
+ Function *Callee = CI->getCalledFunction();
+ StringRef FuncName = Callee->getName();
+ IRBuilder<> Builder(CI);
+ bool isCallingConvC = CI->getCallingConv() == llvm::CallingConv::C;
+
+ // Command-line parameter overrides function attribute.
+ if (EnableUnsafeFPShrink.getNumOccurrences() > 0)
+ UnsafeFPShrink = EnableUnsafeFPShrink;
+ else if (Callee->hasFnAttribute("unsafe-fp-math")) {
+ // FIXME: This is the same problem as described in optimizeSqrt().
+ // If calls gain access to IR-level FMF, then use that instead of a
+ // function attribute.
+
+ // Check for unsafe-fp-math = true.
+ Attribute Attr = Callee->getFnAttribute("unsafe-fp-math");
+ if (Attr.getValueAsString() == "true")
+ UnsafeFPShrink = true;
+ }
+
+ // First, check for intrinsics.
+ if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
+ if (!isCallingConvC)
+ return nullptr;
+ switch (II->getIntrinsicID()) {
+ case Intrinsic::pow:
+ return optimizePow(CI, Builder);
+ case Intrinsic::exp2:
+ return optimizeExp2(CI, Builder);
+ case Intrinsic::fabs:
+ return optimizeFabs(CI, Builder);
+ case Intrinsic::sqrt:
+ return optimizeSqrt(CI, Builder);
+ default:
+ return nullptr;
+ }
+ }
+
+ // Then check for known library functions.
+ if (TLI->getLibFunc(FuncName, Func) && TLI->has(Func)) {
+ // We never change the calling convention.
+ if (!ignoreCallingConv(Func) && !isCallingConvC)
+ return nullptr;
+ if (Value *V = optimizeStringMemoryLibCall(CI, Builder))
+ return V;
+ switch (Func) {
case LibFunc::cosf:
case LibFunc::cos:
case LibFunc::cosl:
More information about the llvm-commits
mailing list