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);
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: