From 6722f5e5b315dfd065573f5910315e631ce93baf Mon Sep 17 00:00:00 2001 From: Ahmed Bougacha Date: Mon, 12 Jan 2015 17:20:06 +0000 Subject: [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 --- llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp | 106 +++++++++++++++---------- 1 file changed, 64 insertions(+), 42 deletions(-) (limited to 'llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp') diff --git a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp index 930f6665770..fd654423f0e 100644 --- a/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -2060,53 +2060,18 @@ bool LibCallSimplifier::hasFloatVersion(StringRef FuncName) { 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(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(CallInst *CI) { 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(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: -- cgit v1.2.3