1243789Sdim//===------ SimplifyLibCalls.cpp - Library calls simplifier ---------------===// 2243789Sdim// 3243789Sdim// The LLVM Compiler Infrastructure 4243789Sdim// 5243789Sdim// This file is distributed under the University of Illinois Open Source 6243789Sdim// License. See LICENSE.TXT for details. 7243789Sdim// 8243789Sdim//===----------------------------------------------------------------------===// 9243789Sdim// 10243789Sdim// This is a utility pass used for testing the InstructionSimplify analysis. 11243789Sdim// The analysis is applied to every instruction, and if it simplifies then the 12243789Sdim// instruction is replaced by the simplification. If you are looking for a pass 13243789Sdim// that performs serious instruction folding, use the instcombine pass instead. 14243789Sdim// 15243789Sdim//===----------------------------------------------------------------------===// 16243789Sdim 17243789Sdim#include "llvm/Transforms/Utils/SimplifyLibCalls.h" 18252723Sdim#include "llvm/ADT/SmallString.h" 19243789Sdim#include "llvm/ADT/StringMap.h" 20263509Sdim#include "llvm/ADT/Triple.h" 21243789Sdim#include "llvm/Analysis/ValueTracking.h" 22252723Sdim#include "llvm/IR/DataLayout.h" 23252723Sdim#include "llvm/IR/Function.h" 24252723Sdim#include "llvm/IR/IRBuilder.h" 25252723Sdim#include "llvm/IR/IntrinsicInst.h" 26252723Sdim#include "llvm/IR/Intrinsics.h" 27252723Sdim#include "llvm/IR/LLVMContext.h" 28252723Sdim#include "llvm/IR/Module.h" 29252723Sdim#include "llvm/Support/Allocator.h" 30263509Sdim#include "llvm/Support/CommandLine.h" 31243789Sdim#include "llvm/Target/TargetLibraryInfo.h" 32243789Sdim#include "llvm/Transforms/Utils/BuildLibCalls.h" 33243789Sdim 34243789Sdimusing namespace llvm; 35243789Sdim 36263509Sdimstatic cl::opt<bool> 37263509SdimColdErrorCalls("error-reporting-is-cold", cl::init(true), 38263509Sdim cl::Hidden, cl::desc("Treat error-reporting calls as cold")); 39263509Sdim 40243789Sdim/// This class is the abstract base class for the set of optimizations that 41243789Sdim/// corresponds to one library call. 42243789Sdimnamespace { 43243789Sdimclass LibCallOptimization { 44243789Sdimprotected: 45243789Sdim Function *Caller; 46243789Sdim const DataLayout *TD; 47243789Sdim const TargetLibraryInfo *TLI; 48243789Sdim const LibCallSimplifier *LCS; 49243789Sdim LLVMContext* Context; 50243789Sdimpublic: 51243789Sdim LibCallOptimization() { } 52243789Sdim virtual ~LibCallOptimization() {} 53243789Sdim 54243789Sdim /// callOptimizer - This pure virtual method is implemented by base classes to 55243789Sdim /// do various optimizations. If this returns null then no transformation was 56243789Sdim /// performed. If it returns CI, then it transformed the call and CI is to be 57243789Sdim /// deleted. If it returns something else, replace CI with the new value and 58243789Sdim /// delete CI. 59243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) 60243789Sdim =0; 61243789Sdim 62252723Sdim /// ignoreCallingConv - Returns false if this transformation could possibly 63252723Sdim /// change the calling convention. 64252723Sdim virtual bool ignoreCallingConv() { return false; } 65252723Sdim 66243789Sdim Value *optimizeCall(CallInst *CI, const DataLayout *TD, 67243789Sdim const TargetLibraryInfo *TLI, 68243789Sdim const LibCallSimplifier *LCS, IRBuilder<> &B) { 69243789Sdim Caller = CI->getParent()->getParent(); 70243789Sdim this->TD = TD; 71243789Sdim this->TLI = TLI; 72243789Sdim this->LCS = LCS; 73243789Sdim if (CI->getCalledFunction()) 74243789Sdim Context = &CI->getCalledFunction()->getContext(); 75243789Sdim 76243789Sdim // We never change the calling convention. 77252723Sdim if (!ignoreCallingConv() && CI->getCallingConv() != llvm::CallingConv::C) 78243789Sdim return NULL; 79243789Sdim 80243789Sdim return callOptimizer(CI->getCalledFunction(), CI, B); 81243789Sdim } 82243789Sdim}; 83243789Sdim 84243789Sdim//===----------------------------------------------------------------------===// 85243789Sdim// Helper Functions 86243789Sdim//===----------------------------------------------------------------------===// 87243789Sdim 88243789Sdim/// isOnlyUsedInZeroEqualityComparison - Return true if it only matters that the 89243789Sdim/// value is equal or not-equal to zero. 90243789Sdimstatic bool isOnlyUsedInZeroEqualityComparison(Value *V) { 91243789Sdim for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); 92243789Sdim UI != E; ++UI) { 93243789Sdim if (ICmpInst *IC = dyn_cast<ICmpInst>(*UI)) 94243789Sdim if (IC->isEquality()) 95243789Sdim if (Constant *C = dyn_cast<Constant>(IC->getOperand(1))) 96243789Sdim if (C->isNullValue()) 97243789Sdim continue; 98243789Sdim // Unknown instruction. 99243789Sdim return false; 100243789Sdim } 101243789Sdim return true; 102243789Sdim} 103243789Sdim 104243789Sdim/// isOnlyUsedInEqualityComparison - Return true if it is only used in equality 105243789Sdim/// comparisons with With. 106243789Sdimstatic bool isOnlyUsedInEqualityComparison(Value *V, Value *With) { 107243789Sdim for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); 108243789Sdim UI != E; ++UI) { 109243789Sdim if (ICmpInst *IC = dyn_cast<ICmpInst>(*UI)) 110243789Sdim if (IC->isEquality() && IC->getOperand(1) == With) 111243789Sdim continue; 112243789Sdim // Unknown instruction. 113243789Sdim return false; 114243789Sdim } 115243789Sdim return true; 116243789Sdim} 117243789Sdim 118252723Sdimstatic bool callHasFloatingPointArgument(const CallInst *CI) { 119252723Sdim for (CallInst::const_op_iterator it = CI->op_begin(), e = CI->op_end(); 120252723Sdim it != e; ++it) { 121252723Sdim if ((*it)->getType()->isFloatingPointTy()) 122252723Sdim return true; 123252723Sdim } 124252723Sdim return false; 125252723Sdim} 126252723Sdim 127263509Sdim/// \brief Check whether the overloaded unary floating point function 128263509Sdim/// corresponing to \a Ty is available. 129263509Sdimstatic bool hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty, 130263509Sdim LibFunc::Func DoubleFn, LibFunc::Func FloatFn, 131263509Sdim LibFunc::Func LongDoubleFn) { 132263509Sdim switch (Ty->getTypeID()) { 133263509Sdim case Type::FloatTyID: 134263509Sdim return TLI->has(FloatFn); 135263509Sdim case Type::DoubleTyID: 136263509Sdim return TLI->has(DoubleFn); 137263509Sdim default: 138263509Sdim return TLI->has(LongDoubleFn); 139263509Sdim } 140263509Sdim} 141263509Sdim 142243789Sdim//===----------------------------------------------------------------------===// 143243789Sdim// Fortified Library Call Optimizations 144243789Sdim//===----------------------------------------------------------------------===// 145243789Sdim 146243789Sdimstruct FortifiedLibCallOptimization : public LibCallOptimization { 147243789Sdimprotected: 148243789Sdim virtual bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp, 149243789Sdim bool isString) const = 0; 150243789Sdim}; 151243789Sdim 152243789Sdimstruct InstFortifiedLibCallOptimization : public FortifiedLibCallOptimization { 153243789Sdim CallInst *CI; 154243789Sdim 155243789Sdim bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp, bool isString) const { 156243789Sdim if (CI->getArgOperand(SizeCIOp) == CI->getArgOperand(SizeArgOp)) 157243789Sdim return true; 158243789Sdim if (ConstantInt *SizeCI = 159243789Sdim dyn_cast<ConstantInt>(CI->getArgOperand(SizeCIOp))) { 160243789Sdim if (SizeCI->isAllOnesValue()) 161243789Sdim return true; 162243789Sdim if (isString) { 163243789Sdim uint64_t Len = GetStringLength(CI->getArgOperand(SizeArgOp)); 164243789Sdim // If the length is 0 we don't know how long it is and so we can't 165243789Sdim // remove the check. 166243789Sdim if (Len == 0) return false; 167243789Sdim return SizeCI->getZExtValue() >= Len; 168243789Sdim } 169243789Sdim if (ConstantInt *Arg = dyn_cast<ConstantInt>( 170243789Sdim CI->getArgOperand(SizeArgOp))) 171243789Sdim return SizeCI->getZExtValue() >= Arg->getZExtValue(); 172243789Sdim } 173243789Sdim return false; 174243789Sdim } 175243789Sdim}; 176243789Sdim 177243789Sdimstruct MemCpyChkOpt : public InstFortifiedLibCallOptimization { 178243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 179243789Sdim this->CI = CI; 180243789Sdim FunctionType *FT = Callee->getFunctionType(); 181243789Sdim LLVMContext &Context = CI->getParent()->getContext(); 182243789Sdim 183243789Sdim // Check if this has the right signature. 184243789Sdim if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 185243789Sdim !FT->getParamType(0)->isPointerTy() || 186243789Sdim !FT->getParamType(1)->isPointerTy() || 187243789Sdim FT->getParamType(2) != TD->getIntPtrType(Context) || 188243789Sdim FT->getParamType(3) != TD->getIntPtrType(Context)) 189243789Sdim return 0; 190243789Sdim 191243789Sdim if (isFoldable(3, 2, false)) { 192243789Sdim B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), 193243789Sdim CI->getArgOperand(2), 1); 194243789Sdim return CI->getArgOperand(0); 195243789Sdim } 196243789Sdim return 0; 197243789Sdim } 198243789Sdim}; 199243789Sdim 200243789Sdimstruct MemMoveChkOpt : public InstFortifiedLibCallOptimization { 201243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 202243789Sdim this->CI = CI; 203243789Sdim FunctionType *FT = Callee->getFunctionType(); 204243789Sdim LLVMContext &Context = CI->getParent()->getContext(); 205243789Sdim 206243789Sdim // Check if this has the right signature. 207243789Sdim if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 208243789Sdim !FT->getParamType(0)->isPointerTy() || 209243789Sdim !FT->getParamType(1)->isPointerTy() || 210243789Sdim FT->getParamType(2) != TD->getIntPtrType(Context) || 211243789Sdim FT->getParamType(3) != TD->getIntPtrType(Context)) 212243789Sdim return 0; 213243789Sdim 214243789Sdim if (isFoldable(3, 2, false)) { 215243789Sdim B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1), 216243789Sdim CI->getArgOperand(2), 1); 217243789Sdim return CI->getArgOperand(0); 218243789Sdim } 219243789Sdim return 0; 220243789Sdim } 221243789Sdim}; 222243789Sdim 223243789Sdimstruct MemSetChkOpt : public InstFortifiedLibCallOptimization { 224243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 225243789Sdim this->CI = CI; 226243789Sdim FunctionType *FT = Callee->getFunctionType(); 227243789Sdim LLVMContext &Context = CI->getParent()->getContext(); 228243789Sdim 229243789Sdim // Check if this has the right signature. 230243789Sdim if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 231243789Sdim !FT->getParamType(0)->isPointerTy() || 232243789Sdim !FT->getParamType(1)->isIntegerTy() || 233243789Sdim FT->getParamType(2) != TD->getIntPtrType(Context) || 234243789Sdim FT->getParamType(3) != TD->getIntPtrType(Context)) 235243789Sdim return 0; 236243789Sdim 237243789Sdim if (isFoldable(3, 2, false)) { 238243789Sdim Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), 239243789Sdim false); 240243789Sdim B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1); 241243789Sdim return CI->getArgOperand(0); 242243789Sdim } 243243789Sdim return 0; 244243789Sdim } 245243789Sdim}; 246243789Sdim 247243789Sdimstruct StrCpyChkOpt : public InstFortifiedLibCallOptimization { 248243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 249243789Sdim this->CI = CI; 250243789Sdim StringRef Name = Callee->getName(); 251243789Sdim FunctionType *FT = Callee->getFunctionType(); 252243789Sdim LLVMContext &Context = CI->getParent()->getContext(); 253243789Sdim 254243789Sdim // Check if this has the right signature. 255243789Sdim if (FT->getNumParams() != 3 || 256243789Sdim FT->getReturnType() != FT->getParamType(0) || 257243789Sdim FT->getParamType(0) != FT->getParamType(1) || 258243789Sdim FT->getParamType(0) != Type::getInt8PtrTy(Context) || 259243789Sdim FT->getParamType(2) != TD->getIntPtrType(Context)) 260243789Sdim return 0; 261243789Sdim 262243789Sdim Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); 263243789Sdim if (Dst == Src) // __strcpy_chk(x,x) -> x 264243789Sdim return Src; 265243789Sdim 266243789Sdim // If a) we don't have any length information, or b) we know this will 267243789Sdim // fit then just lower to a plain strcpy. Otherwise we'll keep our 268243789Sdim // strcpy_chk call which may fail at runtime if the size is too long. 269243789Sdim // TODO: It might be nice to get a maximum length out of the possible 270243789Sdim // string lengths for varying. 271243789Sdim if (isFoldable(2, 1, true)) { 272243789Sdim Value *Ret = EmitStrCpy(Dst, Src, B, TD, TLI, Name.substr(2, 6)); 273243789Sdim return Ret; 274243789Sdim } else { 275243789Sdim // Maybe we can stil fold __strcpy_chk to __memcpy_chk. 276243789Sdim uint64_t Len = GetStringLength(Src); 277243789Sdim if (Len == 0) return 0; 278243789Sdim 279243789Sdim // This optimization require DataLayout. 280243789Sdim if (!TD) return 0; 281243789Sdim 282243789Sdim Value *Ret = 283243789Sdim EmitMemCpyChk(Dst, Src, 284243789Sdim ConstantInt::get(TD->getIntPtrType(Context), Len), 285243789Sdim CI->getArgOperand(2), B, TD, TLI); 286243789Sdim return Ret; 287243789Sdim } 288243789Sdim return 0; 289243789Sdim } 290243789Sdim}; 291243789Sdim 292243789Sdimstruct StpCpyChkOpt : public InstFortifiedLibCallOptimization { 293243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 294243789Sdim this->CI = CI; 295243789Sdim StringRef Name = Callee->getName(); 296243789Sdim FunctionType *FT = Callee->getFunctionType(); 297243789Sdim LLVMContext &Context = CI->getParent()->getContext(); 298243789Sdim 299243789Sdim // Check if this has the right signature. 300243789Sdim if (FT->getNumParams() != 3 || 301243789Sdim FT->getReturnType() != FT->getParamType(0) || 302243789Sdim FT->getParamType(0) != FT->getParamType(1) || 303243789Sdim FT->getParamType(0) != Type::getInt8PtrTy(Context) || 304243789Sdim FT->getParamType(2) != TD->getIntPtrType(FT->getParamType(0))) 305243789Sdim return 0; 306243789Sdim 307243789Sdim Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); 308243789Sdim if (Dst == Src) { // stpcpy(x,x) -> x+strlen(x) 309243789Sdim Value *StrLen = EmitStrLen(Src, B, TD, TLI); 310243789Sdim return StrLen ? B.CreateInBoundsGEP(Dst, StrLen) : 0; 311243789Sdim } 312243789Sdim 313243789Sdim // If a) we don't have any length information, or b) we know this will 314243789Sdim // fit then just lower to a plain stpcpy. Otherwise we'll keep our 315243789Sdim // stpcpy_chk call which may fail at runtime if the size is too long. 316243789Sdim // TODO: It might be nice to get a maximum length out of the possible 317243789Sdim // string lengths for varying. 318243789Sdim if (isFoldable(2, 1, true)) { 319243789Sdim Value *Ret = EmitStrCpy(Dst, Src, B, TD, TLI, Name.substr(2, 6)); 320243789Sdim return Ret; 321243789Sdim } else { 322243789Sdim // Maybe we can stil fold __stpcpy_chk to __memcpy_chk. 323243789Sdim uint64_t Len = GetStringLength(Src); 324243789Sdim if (Len == 0) return 0; 325243789Sdim 326243789Sdim // This optimization require DataLayout. 327243789Sdim if (!TD) return 0; 328243789Sdim 329243789Sdim Type *PT = FT->getParamType(0); 330243789Sdim Value *LenV = ConstantInt::get(TD->getIntPtrType(PT), Len); 331243789Sdim Value *DstEnd = B.CreateGEP(Dst, 332243789Sdim ConstantInt::get(TD->getIntPtrType(PT), 333243789Sdim Len - 1)); 334243789Sdim if (!EmitMemCpyChk(Dst, Src, LenV, CI->getArgOperand(2), B, TD, TLI)) 335243789Sdim return 0; 336243789Sdim return DstEnd; 337243789Sdim } 338243789Sdim return 0; 339243789Sdim } 340243789Sdim}; 341243789Sdim 342243789Sdimstruct StrNCpyChkOpt : public InstFortifiedLibCallOptimization { 343243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 344243789Sdim this->CI = CI; 345243789Sdim StringRef Name = Callee->getName(); 346243789Sdim FunctionType *FT = Callee->getFunctionType(); 347243789Sdim LLVMContext &Context = CI->getParent()->getContext(); 348243789Sdim 349243789Sdim // Check if this has the right signature. 350243789Sdim if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 351243789Sdim FT->getParamType(0) != FT->getParamType(1) || 352243789Sdim FT->getParamType(0) != Type::getInt8PtrTy(Context) || 353243789Sdim !FT->getParamType(2)->isIntegerTy() || 354243789Sdim FT->getParamType(3) != TD->getIntPtrType(Context)) 355243789Sdim return 0; 356243789Sdim 357243789Sdim if (isFoldable(3, 2, false)) { 358243789Sdim Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1), 359243789Sdim CI->getArgOperand(2), B, TD, TLI, 360243789Sdim Name.substr(2, 7)); 361243789Sdim return Ret; 362243789Sdim } 363243789Sdim return 0; 364243789Sdim } 365243789Sdim}; 366243789Sdim 367243789Sdim//===----------------------------------------------------------------------===// 368243789Sdim// String and Memory Library Call Optimizations 369243789Sdim//===----------------------------------------------------------------------===// 370243789Sdim 371243789Sdimstruct StrCatOpt : public LibCallOptimization { 372243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 373243789Sdim // Verify the "strcat" function prototype. 374243789Sdim FunctionType *FT = Callee->getFunctionType(); 375243789Sdim if (FT->getNumParams() != 2 || 376243789Sdim FT->getReturnType() != B.getInt8PtrTy() || 377243789Sdim FT->getParamType(0) != FT->getReturnType() || 378243789Sdim FT->getParamType(1) != FT->getReturnType()) 379243789Sdim return 0; 380243789Sdim 381243789Sdim // Extract some information from the instruction 382243789Sdim Value *Dst = CI->getArgOperand(0); 383243789Sdim Value *Src = CI->getArgOperand(1); 384243789Sdim 385243789Sdim // See if we can get the length of the input string. 386243789Sdim uint64_t Len = GetStringLength(Src); 387243789Sdim if (Len == 0) return 0; 388243789Sdim --Len; // Unbias length. 389243789Sdim 390243789Sdim // Handle the simple, do-nothing case: strcat(x, "") -> x 391243789Sdim if (Len == 0) 392243789Sdim return Dst; 393243789Sdim 394243789Sdim // These optimizations require DataLayout. 395243789Sdim if (!TD) return 0; 396243789Sdim 397243789Sdim return emitStrLenMemCpy(Src, Dst, Len, B); 398243789Sdim } 399243789Sdim 400243789Sdim Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, 401243789Sdim IRBuilder<> &B) { 402243789Sdim // We need to find the end of the destination string. That's where the 403243789Sdim // memory is to be moved to. We just generate a call to strlen. 404243789Sdim Value *DstLen = EmitStrLen(Dst, B, TD, TLI); 405243789Sdim if (!DstLen) 406243789Sdim return 0; 407243789Sdim 408243789Sdim // Now that we have the destination's length, we must index into the 409243789Sdim // destination's pointer to get the actual memcpy destination (end of 410243789Sdim // the string .. we're concatenating). 411243789Sdim Value *CpyDst = B.CreateGEP(Dst, DstLen, "endptr"); 412243789Sdim 413243789Sdim // We have enough information to now generate the memcpy call to do the 414243789Sdim // concatenation for us. Make a memcpy to copy the nul byte with align = 1. 415243789Sdim B.CreateMemCpy(CpyDst, Src, 416243789Sdim ConstantInt::get(TD->getIntPtrType(*Context), Len + 1), 1); 417243789Sdim return Dst; 418243789Sdim } 419243789Sdim}; 420243789Sdim 421243789Sdimstruct StrNCatOpt : public StrCatOpt { 422243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 423243789Sdim // Verify the "strncat" function prototype. 424243789Sdim FunctionType *FT = Callee->getFunctionType(); 425243789Sdim if (FT->getNumParams() != 3 || 426243789Sdim FT->getReturnType() != B.getInt8PtrTy() || 427243789Sdim FT->getParamType(0) != FT->getReturnType() || 428243789Sdim FT->getParamType(1) != FT->getReturnType() || 429243789Sdim !FT->getParamType(2)->isIntegerTy()) 430243789Sdim return 0; 431243789Sdim 432243789Sdim // Extract some information from the instruction 433243789Sdim Value *Dst = CI->getArgOperand(0); 434243789Sdim Value *Src = CI->getArgOperand(1); 435243789Sdim uint64_t Len; 436243789Sdim 437243789Sdim // We don't do anything if length is not constant 438243789Sdim if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2))) 439243789Sdim Len = LengthArg->getZExtValue(); 440243789Sdim else 441243789Sdim return 0; 442243789Sdim 443243789Sdim // See if we can get the length of the input string. 444243789Sdim uint64_t SrcLen = GetStringLength(Src); 445243789Sdim if (SrcLen == 0) return 0; 446243789Sdim --SrcLen; // Unbias length. 447243789Sdim 448243789Sdim // Handle the simple, do-nothing cases: 449243789Sdim // strncat(x, "", c) -> x 450243789Sdim // strncat(x, c, 0) -> x 451243789Sdim if (SrcLen == 0 || Len == 0) return Dst; 452243789Sdim 453243789Sdim // These optimizations require DataLayout. 454243789Sdim if (!TD) return 0; 455243789Sdim 456243789Sdim // We don't optimize this case 457243789Sdim if (Len < SrcLen) return 0; 458243789Sdim 459243789Sdim // strncat(x, s, c) -> strcat(x, s) 460243789Sdim // s is constant so the strcat can be optimized further 461243789Sdim return emitStrLenMemCpy(Src, Dst, SrcLen, B); 462243789Sdim } 463243789Sdim}; 464243789Sdim 465243789Sdimstruct StrChrOpt : public LibCallOptimization { 466243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 467243789Sdim // Verify the "strchr" function prototype. 468243789Sdim FunctionType *FT = Callee->getFunctionType(); 469243789Sdim if (FT->getNumParams() != 2 || 470243789Sdim FT->getReturnType() != B.getInt8PtrTy() || 471243789Sdim FT->getParamType(0) != FT->getReturnType() || 472243789Sdim !FT->getParamType(1)->isIntegerTy(32)) 473243789Sdim return 0; 474243789Sdim 475243789Sdim Value *SrcStr = CI->getArgOperand(0); 476243789Sdim 477243789Sdim // If the second operand is non-constant, see if we can compute the length 478243789Sdim // of the input string and turn this into memchr. 479243789Sdim ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 480243789Sdim if (CharC == 0) { 481243789Sdim // These optimizations require DataLayout. 482243789Sdim if (!TD) return 0; 483243789Sdim 484243789Sdim uint64_t Len = GetStringLength(SrcStr); 485243789Sdim if (Len == 0 || !FT->getParamType(1)->isIntegerTy(32))// memchr needs i32. 486243789Sdim return 0; 487243789Sdim 488243789Sdim return EmitMemChr(SrcStr, CI->getArgOperand(1), // include nul. 489243789Sdim ConstantInt::get(TD->getIntPtrType(*Context), Len), 490243789Sdim B, TD, TLI); 491243789Sdim } 492243789Sdim 493243789Sdim // Otherwise, the character is a constant, see if the first argument is 494243789Sdim // a string literal. If so, we can constant fold. 495243789Sdim StringRef Str; 496243789Sdim if (!getConstantStringInfo(SrcStr, Str)) 497243789Sdim return 0; 498243789Sdim 499243789Sdim // Compute the offset, make sure to handle the case when we're searching for 500243789Sdim // zero (a weird way to spell strlen). 501263509Sdim size_t I = (0xFF & CharC->getSExtValue()) == 0 ? 502243789Sdim Str.size() : Str.find(CharC->getSExtValue()); 503243789Sdim if (I == StringRef::npos) // Didn't find the char. strchr returns null. 504243789Sdim return Constant::getNullValue(CI->getType()); 505243789Sdim 506243789Sdim // strchr(s+n,c) -> gep(s+n+i,c) 507243789Sdim return B.CreateGEP(SrcStr, B.getInt64(I), "strchr"); 508243789Sdim } 509243789Sdim}; 510243789Sdim 511243789Sdimstruct StrRChrOpt : public LibCallOptimization { 512243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 513243789Sdim // Verify the "strrchr" function prototype. 514243789Sdim FunctionType *FT = Callee->getFunctionType(); 515243789Sdim if (FT->getNumParams() != 2 || 516243789Sdim FT->getReturnType() != B.getInt8PtrTy() || 517243789Sdim FT->getParamType(0) != FT->getReturnType() || 518243789Sdim !FT->getParamType(1)->isIntegerTy(32)) 519243789Sdim return 0; 520243789Sdim 521243789Sdim Value *SrcStr = CI->getArgOperand(0); 522243789Sdim ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 523243789Sdim 524243789Sdim // Cannot fold anything if we're not looking for a constant. 525243789Sdim if (!CharC) 526243789Sdim return 0; 527243789Sdim 528243789Sdim StringRef Str; 529243789Sdim if (!getConstantStringInfo(SrcStr, Str)) { 530243789Sdim // strrchr(s, 0) -> strchr(s, 0) 531243789Sdim if (TD && CharC->isZero()) 532243789Sdim return EmitStrChr(SrcStr, '\0', B, TD, TLI); 533243789Sdim return 0; 534243789Sdim } 535243789Sdim 536243789Sdim // Compute the offset. 537263509Sdim size_t I = (0xFF & CharC->getSExtValue()) == 0 ? 538243789Sdim Str.size() : Str.rfind(CharC->getSExtValue()); 539243789Sdim if (I == StringRef::npos) // Didn't find the char. Return null. 540243789Sdim return Constant::getNullValue(CI->getType()); 541243789Sdim 542243789Sdim // strrchr(s+n,c) -> gep(s+n+i,c) 543243789Sdim return B.CreateGEP(SrcStr, B.getInt64(I), "strrchr"); 544243789Sdim } 545243789Sdim}; 546243789Sdim 547243789Sdimstruct StrCmpOpt : public LibCallOptimization { 548243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 549243789Sdim // Verify the "strcmp" function prototype. 550243789Sdim FunctionType *FT = Callee->getFunctionType(); 551243789Sdim if (FT->getNumParams() != 2 || 552243789Sdim !FT->getReturnType()->isIntegerTy(32) || 553243789Sdim FT->getParamType(0) != FT->getParamType(1) || 554243789Sdim FT->getParamType(0) != B.getInt8PtrTy()) 555243789Sdim return 0; 556243789Sdim 557243789Sdim Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1); 558243789Sdim if (Str1P == Str2P) // strcmp(x,x) -> 0 559243789Sdim return ConstantInt::get(CI->getType(), 0); 560243789Sdim 561243789Sdim StringRef Str1, Str2; 562243789Sdim bool HasStr1 = getConstantStringInfo(Str1P, Str1); 563243789Sdim bool HasStr2 = getConstantStringInfo(Str2P, Str2); 564243789Sdim 565243789Sdim // strcmp(x, y) -> cnst (if both x and y are constant strings) 566243789Sdim if (HasStr1 && HasStr2) 567243789Sdim return ConstantInt::get(CI->getType(), Str1.compare(Str2)); 568243789Sdim 569243789Sdim if (HasStr1 && Str1.empty()) // strcmp("", x) -> -*x 570243789Sdim return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), 571243789Sdim CI->getType())); 572243789Sdim 573243789Sdim if (HasStr2 && Str2.empty()) // strcmp(x,"") -> *x 574243789Sdim return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType()); 575243789Sdim 576243789Sdim // strcmp(P, "x") -> memcmp(P, "x", 2) 577243789Sdim uint64_t Len1 = GetStringLength(Str1P); 578243789Sdim uint64_t Len2 = GetStringLength(Str2P); 579243789Sdim if (Len1 && Len2) { 580243789Sdim // These optimizations require DataLayout. 581243789Sdim if (!TD) return 0; 582243789Sdim 583243789Sdim return EmitMemCmp(Str1P, Str2P, 584243789Sdim ConstantInt::get(TD->getIntPtrType(*Context), 585243789Sdim std::min(Len1, Len2)), B, TD, TLI); 586243789Sdim } 587243789Sdim 588243789Sdim return 0; 589243789Sdim } 590243789Sdim}; 591243789Sdim 592243789Sdimstruct StrNCmpOpt : public LibCallOptimization { 593243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 594243789Sdim // Verify the "strncmp" function prototype. 595243789Sdim FunctionType *FT = Callee->getFunctionType(); 596243789Sdim if (FT->getNumParams() != 3 || 597243789Sdim !FT->getReturnType()->isIntegerTy(32) || 598243789Sdim FT->getParamType(0) != FT->getParamType(1) || 599243789Sdim FT->getParamType(0) != B.getInt8PtrTy() || 600243789Sdim !FT->getParamType(2)->isIntegerTy()) 601243789Sdim return 0; 602243789Sdim 603243789Sdim Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1); 604243789Sdim if (Str1P == Str2P) // strncmp(x,x,n) -> 0 605243789Sdim return ConstantInt::get(CI->getType(), 0); 606243789Sdim 607243789Sdim // Get the length argument if it is constant. 608243789Sdim uint64_t Length; 609243789Sdim if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2))) 610243789Sdim Length = LengthArg->getZExtValue(); 611243789Sdim else 612243789Sdim return 0; 613243789Sdim 614243789Sdim if (Length == 0) // strncmp(x,y,0) -> 0 615243789Sdim return ConstantInt::get(CI->getType(), 0); 616243789Sdim 617243789Sdim if (TD && Length == 1) // strncmp(x,y,1) -> memcmp(x,y,1) 618243789Sdim return EmitMemCmp(Str1P, Str2P, CI->getArgOperand(2), B, TD, TLI); 619243789Sdim 620243789Sdim StringRef Str1, Str2; 621243789Sdim bool HasStr1 = getConstantStringInfo(Str1P, Str1); 622243789Sdim bool HasStr2 = getConstantStringInfo(Str2P, Str2); 623243789Sdim 624243789Sdim // strncmp(x, y) -> cnst (if both x and y are constant strings) 625243789Sdim if (HasStr1 && HasStr2) { 626243789Sdim StringRef SubStr1 = Str1.substr(0, Length); 627243789Sdim StringRef SubStr2 = Str2.substr(0, Length); 628243789Sdim return ConstantInt::get(CI->getType(), SubStr1.compare(SubStr2)); 629243789Sdim } 630243789Sdim 631243789Sdim if (HasStr1 && Str1.empty()) // strncmp("", x, n) -> -*x 632243789Sdim return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), 633243789Sdim CI->getType())); 634243789Sdim 635243789Sdim if (HasStr2 && Str2.empty()) // strncmp(x, "", n) -> *x 636243789Sdim return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType()); 637243789Sdim 638243789Sdim return 0; 639243789Sdim } 640243789Sdim}; 641243789Sdim 642243789Sdimstruct StrCpyOpt : public LibCallOptimization { 643243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 644243789Sdim // Verify the "strcpy" function prototype. 645243789Sdim FunctionType *FT = Callee->getFunctionType(); 646243789Sdim if (FT->getNumParams() != 2 || 647243789Sdim FT->getReturnType() != FT->getParamType(0) || 648243789Sdim FT->getParamType(0) != FT->getParamType(1) || 649243789Sdim FT->getParamType(0) != B.getInt8PtrTy()) 650243789Sdim return 0; 651243789Sdim 652243789Sdim Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); 653243789Sdim if (Dst == Src) // strcpy(x,x) -> x 654243789Sdim return Src; 655243789Sdim 656243789Sdim // These optimizations require DataLayout. 657243789Sdim if (!TD) return 0; 658243789Sdim 659243789Sdim // See if we can get the length of the input string. 660243789Sdim uint64_t Len = GetStringLength(Src); 661243789Sdim if (Len == 0) return 0; 662243789Sdim 663243789Sdim // We have enough information to now generate the memcpy call to do the 664243789Sdim // copy for us. Make a memcpy to copy the nul byte with align = 1. 665243789Sdim B.CreateMemCpy(Dst, Src, 666243789Sdim ConstantInt::get(TD->getIntPtrType(*Context), Len), 1); 667243789Sdim return Dst; 668243789Sdim } 669243789Sdim}; 670243789Sdim 671243789Sdimstruct StpCpyOpt: public LibCallOptimization { 672243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 673243789Sdim // Verify the "stpcpy" function prototype. 674243789Sdim FunctionType *FT = Callee->getFunctionType(); 675243789Sdim if (FT->getNumParams() != 2 || 676243789Sdim FT->getReturnType() != FT->getParamType(0) || 677243789Sdim FT->getParamType(0) != FT->getParamType(1) || 678243789Sdim FT->getParamType(0) != B.getInt8PtrTy()) 679243789Sdim return 0; 680243789Sdim 681243789Sdim // These optimizations require DataLayout. 682243789Sdim if (!TD) return 0; 683243789Sdim 684243789Sdim Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); 685243789Sdim if (Dst == Src) { // stpcpy(x,x) -> x+strlen(x) 686243789Sdim Value *StrLen = EmitStrLen(Src, B, TD, TLI); 687243789Sdim return StrLen ? B.CreateInBoundsGEP(Dst, StrLen) : 0; 688243789Sdim } 689243789Sdim 690243789Sdim // See if we can get the length of the input string. 691243789Sdim uint64_t Len = GetStringLength(Src); 692243789Sdim if (Len == 0) return 0; 693243789Sdim 694243789Sdim Type *PT = FT->getParamType(0); 695243789Sdim Value *LenV = ConstantInt::get(TD->getIntPtrType(PT), Len); 696243789Sdim Value *DstEnd = B.CreateGEP(Dst, 697243789Sdim ConstantInt::get(TD->getIntPtrType(PT), 698243789Sdim Len - 1)); 699243789Sdim 700243789Sdim // We have enough information to now generate the memcpy call to do the 701243789Sdim // copy for us. Make a memcpy to copy the nul byte with align = 1. 702243789Sdim B.CreateMemCpy(Dst, Src, LenV, 1); 703243789Sdim return DstEnd; 704243789Sdim } 705243789Sdim}; 706243789Sdim 707243789Sdimstruct StrNCpyOpt : public LibCallOptimization { 708243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 709243789Sdim FunctionType *FT = Callee->getFunctionType(); 710243789Sdim if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || 711243789Sdim FT->getParamType(0) != FT->getParamType(1) || 712243789Sdim FT->getParamType(0) != B.getInt8PtrTy() || 713243789Sdim !FT->getParamType(2)->isIntegerTy()) 714243789Sdim return 0; 715243789Sdim 716243789Sdim Value *Dst = CI->getArgOperand(0); 717243789Sdim Value *Src = CI->getArgOperand(1); 718243789Sdim Value *LenOp = CI->getArgOperand(2); 719243789Sdim 720243789Sdim // See if we can get the length of the input string. 721243789Sdim uint64_t SrcLen = GetStringLength(Src); 722243789Sdim if (SrcLen == 0) return 0; 723243789Sdim --SrcLen; 724243789Sdim 725243789Sdim if (SrcLen == 0) { 726243789Sdim // strncpy(x, "", y) -> memset(x, '\0', y, 1) 727243789Sdim B.CreateMemSet(Dst, B.getInt8('\0'), LenOp, 1); 728243789Sdim return Dst; 729243789Sdim } 730243789Sdim 731243789Sdim uint64_t Len; 732243789Sdim if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(LenOp)) 733243789Sdim Len = LengthArg->getZExtValue(); 734243789Sdim else 735243789Sdim return 0; 736243789Sdim 737243789Sdim if (Len == 0) return Dst; // strncpy(x, y, 0) -> x 738243789Sdim 739243789Sdim // These optimizations require DataLayout. 740243789Sdim if (!TD) return 0; 741243789Sdim 742243789Sdim // Let strncpy handle the zero padding 743243789Sdim if (Len > SrcLen+1) return 0; 744243789Sdim 745243789Sdim Type *PT = FT->getParamType(0); 746243789Sdim // strncpy(x, s, c) -> memcpy(x, s, c, 1) [s and c are constant] 747243789Sdim B.CreateMemCpy(Dst, Src, 748243789Sdim ConstantInt::get(TD->getIntPtrType(PT), Len), 1); 749243789Sdim 750243789Sdim return Dst; 751243789Sdim } 752243789Sdim}; 753243789Sdim 754243789Sdimstruct StrLenOpt : public LibCallOptimization { 755252723Sdim virtual bool ignoreCallingConv() { return true; } 756243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 757243789Sdim FunctionType *FT = Callee->getFunctionType(); 758243789Sdim if (FT->getNumParams() != 1 || 759243789Sdim FT->getParamType(0) != B.getInt8PtrTy() || 760243789Sdim !FT->getReturnType()->isIntegerTy()) 761243789Sdim return 0; 762243789Sdim 763243789Sdim Value *Src = CI->getArgOperand(0); 764243789Sdim 765243789Sdim // Constant folding: strlen("xyz") -> 3 766243789Sdim if (uint64_t Len = GetStringLength(Src)) 767243789Sdim return ConstantInt::get(CI->getType(), Len-1); 768243789Sdim 769243789Sdim // strlen(x) != 0 --> *x != 0 770243789Sdim // strlen(x) == 0 --> *x == 0 771243789Sdim if (isOnlyUsedInZeroEqualityComparison(CI)) 772243789Sdim return B.CreateZExt(B.CreateLoad(Src, "strlenfirst"), CI->getType()); 773243789Sdim return 0; 774243789Sdim } 775243789Sdim}; 776243789Sdim 777243789Sdimstruct StrPBrkOpt : public LibCallOptimization { 778243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 779243789Sdim FunctionType *FT = Callee->getFunctionType(); 780243789Sdim if (FT->getNumParams() != 2 || 781243789Sdim FT->getParamType(0) != B.getInt8PtrTy() || 782243789Sdim FT->getParamType(1) != FT->getParamType(0) || 783243789Sdim FT->getReturnType() != FT->getParamType(0)) 784243789Sdim return 0; 785243789Sdim 786243789Sdim StringRef S1, S2; 787243789Sdim bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1); 788243789Sdim bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2); 789243789Sdim 790243789Sdim // strpbrk(s, "") -> NULL 791243789Sdim // strpbrk("", s) -> NULL 792243789Sdim if ((HasS1 && S1.empty()) || (HasS2 && S2.empty())) 793243789Sdim return Constant::getNullValue(CI->getType()); 794243789Sdim 795243789Sdim // Constant folding. 796243789Sdim if (HasS1 && HasS2) { 797243789Sdim size_t I = S1.find_first_of(S2); 798263509Sdim if (I == StringRef::npos) // No match. 799243789Sdim return Constant::getNullValue(CI->getType()); 800243789Sdim 801243789Sdim return B.CreateGEP(CI->getArgOperand(0), B.getInt64(I), "strpbrk"); 802243789Sdim } 803243789Sdim 804243789Sdim // strpbrk(s, "a") -> strchr(s, 'a') 805243789Sdim if (TD && HasS2 && S2.size() == 1) 806243789Sdim return EmitStrChr(CI->getArgOperand(0), S2[0], B, TD, TLI); 807243789Sdim 808243789Sdim return 0; 809243789Sdim } 810243789Sdim}; 811243789Sdim 812243789Sdimstruct StrToOpt : public LibCallOptimization { 813243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 814243789Sdim FunctionType *FT = Callee->getFunctionType(); 815243789Sdim if ((FT->getNumParams() != 2 && FT->getNumParams() != 3) || 816243789Sdim !FT->getParamType(0)->isPointerTy() || 817243789Sdim !FT->getParamType(1)->isPointerTy()) 818243789Sdim return 0; 819243789Sdim 820243789Sdim Value *EndPtr = CI->getArgOperand(1); 821243789Sdim if (isa<ConstantPointerNull>(EndPtr)) { 822243789Sdim // With a null EndPtr, this function won't capture the main argument. 823243789Sdim // It would be readonly too, except that it still may write to errno. 824252723Sdim CI->addAttribute(1, Attribute::NoCapture); 825243789Sdim } 826243789Sdim 827243789Sdim return 0; 828243789Sdim } 829243789Sdim}; 830243789Sdim 831243789Sdimstruct StrSpnOpt : public LibCallOptimization { 832243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 833243789Sdim FunctionType *FT = Callee->getFunctionType(); 834243789Sdim if (FT->getNumParams() != 2 || 835243789Sdim FT->getParamType(0) != B.getInt8PtrTy() || 836243789Sdim FT->getParamType(1) != FT->getParamType(0) || 837243789Sdim !FT->getReturnType()->isIntegerTy()) 838243789Sdim return 0; 839243789Sdim 840243789Sdim StringRef S1, S2; 841243789Sdim bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1); 842243789Sdim bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2); 843243789Sdim 844243789Sdim // strspn(s, "") -> 0 845243789Sdim // strspn("", s) -> 0 846243789Sdim if ((HasS1 && S1.empty()) || (HasS2 && S2.empty())) 847243789Sdim return Constant::getNullValue(CI->getType()); 848243789Sdim 849243789Sdim // Constant folding. 850243789Sdim if (HasS1 && HasS2) { 851243789Sdim size_t Pos = S1.find_first_not_of(S2); 852243789Sdim if (Pos == StringRef::npos) Pos = S1.size(); 853243789Sdim return ConstantInt::get(CI->getType(), Pos); 854243789Sdim } 855243789Sdim 856243789Sdim return 0; 857243789Sdim } 858243789Sdim}; 859243789Sdim 860243789Sdimstruct StrCSpnOpt : public LibCallOptimization { 861243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 862243789Sdim FunctionType *FT = Callee->getFunctionType(); 863243789Sdim if (FT->getNumParams() != 2 || 864243789Sdim FT->getParamType(0) != B.getInt8PtrTy() || 865243789Sdim FT->getParamType(1) != FT->getParamType(0) || 866243789Sdim !FT->getReturnType()->isIntegerTy()) 867243789Sdim return 0; 868243789Sdim 869243789Sdim StringRef S1, S2; 870243789Sdim bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1); 871243789Sdim bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2); 872243789Sdim 873243789Sdim // strcspn("", s) -> 0 874243789Sdim if (HasS1 && S1.empty()) 875243789Sdim return Constant::getNullValue(CI->getType()); 876243789Sdim 877243789Sdim // Constant folding. 878243789Sdim if (HasS1 && HasS2) { 879243789Sdim size_t Pos = S1.find_first_of(S2); 880243789Sdim if (Pos == StringRef::npos) Pos = S1.size(); 881243789Sdim return ConstantInt::get(CI->getType(), Pos); 882243789Sdim } 883243789Sdim 884243789Sdim // strcspn(s, "") -> strlen(s) 885243789Sdim if (TD && HasS2 && S2.empty()) 886243789Sdim return EmitStrLen(CI->getArgOperand(0), B, TD, TLI); 887243789Sdim 888243789Sdim return 0; 889243789Sdim } 890243789Sdim}; 891243789Sdim 892243789Sdimstruct StrStrOpt : public LibCallOptimization { 893243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 894243789Sdim FunctionType *FT = Callee->getFunctionType(); 895243789Sdim if (FT->getNumParams() != 2 || 896243789Sdim !FT->getParamType(0)->isPointerTy() || 897243789Sdim !FT->getParamType(1)->isPointerTy() || 898243789Sdim !FT->getReturnType()->isPointerTy()) 899243789Sdim return 0; 900243789Sdim 901243789Sdim // fold strstr(x, x) -> x. 902243789Sdim if (CI->getArgOperand(0) == CI->getArgOperand(1)) 903243789Sdim return B.CreateBitCast(CI->getArgOperand(0), CI->getType()); 904243789Sdim 905243789Sdim // fold strstr(a, b) == a -> strncmp(a, b, strlen(b)) == 0 906243789Sdim if (TD && isOnlyUsedInEqualityComparison(CI, CI->getArgOperand(0))) { 907243789Sdim Value *StrLen = EmitStrLen(CI->getArgOperand(1), B, TD, TLI); 908243789Sdim if (!StrLen) 909243789Sdim return 0; 910243789Sdim Value *StrNCmp = EmitStrNCmp(CI->getArgOperand(0), CI->getArgOperand(1), 911243789Sdim StrLen, B, TD, TLI); 912243789Sdim if (!StrNCmp) 913243789Sdim return 0; 914243789Sdim for (Value::use_iterator UI = CI->use_begin(), UE = CI->use_end(); 915243789Sdim UI != UE; ) { 916243789Sdim ICmpInst *Old = cast<ICmpInst>(*UI++); 917243789Sdim Value *Cmp = B.CreateICmp(Old->getPredicate(), StrNCmp, 918243789Sdim ConstantInt::getNullValue(StrNCmp->getType()), 919243789Sdim "cmp"); 920243789Sdim LCS->replaceAllUsesWith(Old, Cmp); 921243789Sdim } 922243789Sdim return CI; 923243789Sdim } 924243789Sdim 925243789Sdim // See if either input string is a constant string. 926243789Sdim StringRef SearchStr, ToFindStr; 927243789Sdim bool HasStr1 = getConstantStringInfo(CI->getArgOperand(0), SearchStr); 928243789Sdim bool HasStr2 = getConstantStringInfo(CI->getArgOperand(1), ToFindStr); 929243789Sdim 930243789Sdim // fold strstr(x, "") -> x. 931243789Sdim if (HasStr2 && ToFindStr.empty()) 932243789Sdim return B.CreateBitCast(CI->getArgOperand(0), CI->getType()); 933243789Sdim 934243789Sdim // If both strings are known, constant fold it. 935243789Sdim if (HasStr1 && HasStr2) { 936263509Sdim size_t Offset = SearchStr.find(ToFindStr); 937243789Sdim 938243789Sdim if (Offset == StringRef::npos) // strstr("foo", "bar") -> null 939243789Sdim return Constant::getNullValue(CI->getType()); 940243789Sdim 941243789Sdim // strstr("abcd", "bc") -> gep((char*)"abcd", 1) 942243789Sdim Value *Result = CastToCStr(CI->getArgOperand(0), B); 943243789Sdim Result = B.CreateConstInBoundsGEP1_64(Result, Offset, "strstr"); 944243789Sdim return B.CreateBitCast(Result, CI->getType()); 945243789Sdim } 946243789Sdim 947243789Sdim // fold strstr(x, "y") -> strchr(x, 'y'). 948243789Sdim if (HasStr2 && ToFindStr.size() == 1) { 949243789Sdim Value *StrChr= EmitStrChr(CI->getArgOperand(0), ToFindStr[0], B, TD, TLI); 950243789Sdim return StrChr ? B.CreateBitCast(StrChr, CI->getType()) : 0; 951243789Sdim } 952243789Sdim return 0; 953243789Sdim } 954243789Sdim}; 955243789Sdim 956243789Sdimstruct MemCmpOpt : public LibCallOptimization { 957243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 958243789Sdim FunctionType *FT = Callee->getFunctionType(); 959243789Sdim if (FT->getNumParams() != 3 || !FT->getParamType(0)->isPointerTy() || 960243789Sdim !FT->getParamType(1)->isPointerTy() || 961243789Sdim !FT->getReturnType()->isIntegerTy(32)) 962243789Sdim return 0; 963243789Sdim 964243789Sdim Value *LHS = CI->getArgOperand(0), *RHS = CI->getArgOperand(1); 965243789Sdim 966243789Sdim if (LHS == RHS) // memcmp(s,s,x) -> 0 967243789Sdim return Constant::getNullValue(CI->getType()); 968243789Sdim 969243789Sdim // Make sure we have a constant length. 970243789Sdim ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getArgOperand(2)); 971243789Sdim if (!LenC) return 0; 972243789Sdim uint64_t Len = LenC->getZExtValue(); 973243789Sdim 974243789Sdim if (Len == 0) // memcmp(s1,s2,0) -> 0 975243789Sdim return Constant::getNullValue(CI->getType()); 976243789Sdim 977243789Sdim // memcmp(S1,S2,1) -> *(unsigned char*)LHS - *(unsigned char*)RHS 978243789Sdim if (Len == 1) { 979243789Sdim Value *LHSV = B.CreateZExt(B.CreateLoad(CastToCStr(LHS, B), "lhsc"), 980243789Sdim CI->getType(), "lhsv"); 981243789Sdim Value *RHSV = B.CreateZExt(B.CreateLoad(CastToCStr(RHS, B), "rhsc"), 982243789Sdim CI->getType(), "rhsv"); 983243789Sdim return B.CreateSub(LHSV, RHSV, "chardiff"); 984243789Sdim } 985243789Sdim 986243789Sdim // Constant folding: memcmp(x, y, l) -> cnst (all arguments are constant) 987243789Sdim StringRef LHSStr, RHSStr; 988243789Sdim if (getConstantStringInfo(LHS, LHSStr) && 989243789Sdim getConstantStringInfo(RHS, RHSStr)) { 990243789Sdim // Make sure we're not reading out-of-bounds memory. 991243789Sdim if (Len > LHSStr.size() || Len > RHSStr.size()) 992243789Sdim return 0; 993252723Sdim // Fold the memcmp and normalize the result. This way we get consistent 994252723Sdim // results across multiple platforms. 995252723Sdim uint64_t Ret = 0; 996252723Sdim int Cmp = memcmp(LHSStr.data(), RHSStr.data(), Len); 997252723Sdim if (Cmp < 0) 998252723Sdim Ret = -1; 999252723Sdim else if (Cmp > 0) 1000252723Sdim Ret = 1; 1001243789Sdim return ConstantInt::get(CI->getType(), Ret); 1002243789Sdim } 1003243789Sdim 1004243789Sdim return 0; 1005243789Sdim } 1006243789Sdim}; 1007243789Sdim 1008243789Sdimstruct MemCpyOpt : public LibCallOptimization { 1009243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1010243789Sdim // These optimizations require DataLayout. 1011243789Sdim if (!TD) return 0; 1012243789Sdim 1013243789Sdim FunctionType *FT = Callee->getFunctionType(); 1014243789Sdim if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || 1015243789Sdim !FT->getParamType(0)->isPointerTy() || 1016243789Sdim !FT->getParamType(1)->isPointerTy() || 1017243789Sdim FT->getParamType(2) != TD->getIntPtrType(*Context)) 1018243789Sdim return 0; 1019243789Sdim 1020243789Sdim // memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1) 1021243789Sdim B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), 1022243789Sdim CI->getArgOperand(2), 1); 1023243789Sdim return CI->getArgOperand(0); 1024243789Sdim } 1025243789Sdim}; 1026243789Sdim 1027243789Sdimstruct MemMoveOpt : public LibCallOptimization { 1028243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1029243789Sdim // These optimizations require DataLayout. 1030243789Sdim if (!TD) return 0; 1031243789Sdim 1032243789Sdim FunctionType *FT = Callee->getFunctionType(); 1033243789Sdim if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || 1034243789Sdim !FT->getParamType(0)->isPointerTy() || 1035243789Sdim !FT->getParamType(1)->isPointerTy() || 1036243789Sdim FT->getParamType(2) != TD->getIntPtrType(*Context)) 1037243789Sdim return 0; 1038243789Sdim 1039243789Sdim // memmove(x, y, n) -> llvm.memmove(x, y, n, 1) 1040243789Sdim B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1), 1041243789Sdim CI->getArgOperand(2), 1); 1042243789Sdim return CI->getArgOperand(0); 1043243789Sdim } 1044243789Sdim}; 1045243789Sdim 1046243789Sdimstruct MemSetOpt : public LibCallOptimization { 1047243789Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1048243789Sdim // These optimizations require DataLayout. 1049243789Sdim if (!TD) return 0; 1050243789Sdim 1051243789Sdim FunctionType *FT = Callee->getFunctionType(); 1052243789Sdim if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) || 1053243789Sdim !FT->getParamType(0)->isPointerTy() || 1054243789Sdim !FT->getParamType(1)->isIntegerTy() || 1055263509Sdim FT->getParamType(2) != TD->getIntPtrType(FT->getParamType(0))) 1056243789Sdim return 0; 1057243789Sdim 1058243789Sdim // memset(p, v, n) -> llvm.memset(p, v, n, 1) 1059243789Sdim Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), false); 1060243789Sdim B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1); 1061243789Sdim return CI->getArgOperand(0); 1062243789Sdim } 1063243789Sdim}; 1064243789Sdim 1065252723Sdim//===----------------------------------------------------------------------===// 1066252723Sdim// Math Library Optimizations 1067252723Sdim//===----------------------------------------------------------------------===// 1068252723Sdim 1069252723Sdim//===----------------------------------------------------------------------===// 1070252723Sdim// Double -> Float Shrinking Optimizations for Unary Functions like 'floor' 1071252723Sdim 1072252723Sdimstruct UnaryDoubleFPOpt : public LibCallOptimization { 1073252723Sdim bool CheckRetType; 1074252723Sdim UnaryDoubleFPOpt(bool CheckReturnType): CheckRetType(CheckReturnType) {} 1075252723Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1076252723Sdim FunctionType *FT = Callee->getFunctionType(); 1077252723Sdim if (FT->getNumParams() != 1 || !FT->getReturnType()->isDoubleTy() || 1078252723Sdim !FT->getParamType(0)->isDoubleTy()) 1079252723Sdim return 0; 1080252723Sdim 1081252723Sdim if (CheckRetType) { 1082252723Sdim // Check if all the uses for function like 'sin' are converted to float. 1083252723Sdim for (Value::use_iterator UseI = CI->use_begin(); UseI != CI->use_end(); 1084252723Sdim ++UseI) { 1085252723Sdim FPTruncInst *Cast = dyn_cast<FPTruncInst>(*UseI); 1086252723Sdim if (Cast == 0 || !Cast->getType()->isFloatTy()) 1087252723Sdim return 0; 1088252723Sdim } 1089252723Sdim } 1090252723Sdim 1091252723Sdim // If this is something like 'floor((double)floatval)', convert to floorf. 1092252723Sdim FPExtInst *Cast = dyn_cast<FPExtInst>(CI->getArgOperand(0)); 1093252723Sdim if (Cast == 0 || !Cast->getOperand(0)->getType()->isFloatTy()) 1094252723Sdim return 0; 1095252723Sdim 1096252723Sdim // floor((double)floatval) -> (double)floorf(floatval) 1097252723Sdim Value *V = Cast->getOperand(0); 1098252723Sdim V = EmitUnaryFloatFnCall(V, Callee->getName(), B, Callee->getAttributes()); 1099252723Sdim return B.CreateFPExt(V, B.getDoubleTy()); 1100252723Sdim } 1101252723Sdim}; 1102252723Sdim 1103252723Sdimstruct UnsafeFPLibCallOptimization : public LibCallOptimization { 1104252723Sdim bool UnsafeFPShrink; 1105252723Sdim UnsafeFPLibCallOptimization(bool UnsafeFPShrink) { 1106252723Sdim this->UnsafeFPShrink = UnsafeFPShrink; 1107252723Sdim } 1108252723Sdim}; 1109252723Sdim 1110252723Sdimstruct CosOpt : public UnsafeFPLibCallOptimization { 1111252723Sdim CosOpt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {} 1112252723Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1113252723Sdim Value *Ret = NULL; 1114252723Sdim if (UnsafeFPShrink && Callee->getName() == "cos" && 1115252723Sdim TLI->has(LibFunc::cosf)) { 1116252723Sdim UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 1117252723Sdim Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B); 1118252723Sdim } 1119252723Sdim 1120252723Sdim FunctionType *FT = Callee->getFunctionType(); 1121252723Sdim // Just make sure this has 1 argument of FP type, which matches the 1122252723Sdim // result type. 1123252723Sdim if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) || 1124252723Sdim !FT->getParamType(0)->isFloatingPointTy()) 1125252723Sdim return Ret; 1126252723Sdim 1127252723Sdim // cos(-x) -> cos(x) 1128252723Sdim Value *Op1 = CI->getArgOperand(0); 1129252723Sdim if (BinaryOperator::isFNeg(Op1)) { 1130252723Sdim BinaryOperator *BinExpr = cast<BinaryOperator>(Op1); 1131252723Sdim return B.CreateCall(Callee, BinExpr->getOperand(1), "cos"); 1132252723Sdim } 1133252723Sdim return Ret; 1134252723Sdim } 1135252723Sdim}; 1136252723Sdim 1137252723Sdimstruct PowOpt : public UnsafeFPLibCallOptimization { 1138252723Sdim PowOpt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {} 1139252723Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1140252723Sdim Value *Ret = NULL; 1141252723Sdim if (UnsafeFPShrink && Callee->getName() == "pow" && 1142252723Sdim TLI->has(LibFunc::powf)) { 1143252723Sdim UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 1144252723Sdim Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B); 1145252723Sdim } 1146252723Sdim 1147252723Sdim FunctionType *FT = Callee->getFunctionType(); 1148252723Sdim // Just make sure this has 2 arguments of the same FP type, which match the 1149252723Sdim // result type. 1150252723Sdim if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) || 1151252723Sdim FT->getParamType(0) != FT->getParamType(1) || 1152252723Sdim !FT->getParamType(0)->isFloatingPointTy()) 1153252723Sdim return Ret; 1154252723Sdim 1155252723Sdim Value *Op1 = CI->getArgOperand(0), *Op2 = CI->getArgOperand(1); 1156252723Sdim if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1)) { 1157263509Sdim // pow(1.0, x) -> 1.0 1158263509Sdim if (Op1C->isExactlyValue(1.0)) 1159252723Sdim return Op1C; 1160263509Sdim // pow(2.0, x) -> exp2(x) 1161263509Sdim if (Op1C->isExactlyValue(2.0) && 1162263509Sdim hasUnaryFloatFn(TLI, Op1->getType(), LibFunc::exp2, LibFunc::exp2f, 1163263509Sdim LibFunc::exp2l)) 1164252723Sdim return EmitUnaryFloatFnCall(Op2, "exp2", B, Callee->getAttributes()); 1165252723Sdim } 1166252723Sdim 1167252723Sdim ConstantFP *Op2C = dyn_cast<ConstantFP>(Op2); 1168252723Sdim if (Op2C == 0) return Ret; 1169252723Sdim 1170252723Sdim if (Op2C->getValueAPF().isZero()) // pow(x, 0.0) -> 1.0 1171252723Sdim return ConstantFP::get(CI->getType(), 1.0); 1172252723Sdim 1173263509Sdim if (Op2C->isExactlyValue(0.5) && 1174263509Sdim hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::sqrt, LibFunc::sqrtf, 1175263509Sdim LibFunc::sqrtl) && 1176263509Sdim hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::fabs, LibFunc::fabsf, 1177263509Sdim LibFunc::fabsl)) { 1178252723Sdim // Expand pow(x, 0.5) to (x == -infinity ? +infinity : fabs(sqrt(x))). 1179252723Sdim // This is faster than calling pow, and still handles negative zero 1180252723Sdim // and negative infinity correctly. 1181252723Sdim // TODO: In fast-math mode, this could be just sqrt(x). 1182252723Sdim // TODO: In finite-only mode, this could be just fabs(sqrt(x)). 1183252723Sdim Value *Inf = ConstantFP::getInfinity(CI->getType()); 1184252723Sdim Value *NegInf = ConstantFP::getInfinity(CI->getType(), true); 1185252723Sdim Value *Sqrt = EmitUnaryFloatFnCall(Op1, "sqrt", B, 1186252723Sdim Callee->getAttributes()); 1187252723Sdim Value *FAbs = EmitUnaryFloatFnCall(Sqrt, "fabs", B, 1188252723Sdim Callee->getAttributes()); 1189252723Sdim Value *FCmp = B.CreateFCmpOEQ(Op1, NegInf); 1190252723Sdim Value *Sel = B.CreateSelect(FCmp, Inf, FAbs); 1191252723Sdim return Sel; 1192252723Sdim } 1193252723Sdim 1194252723Sdim if (Op2C->isExactlyValue(1.0)) // pow(x, 1.0) -> x 1195252723Sdim return Op1; 1196252723Sdim if (Op2C->isExactlyValue(2.0)) // pow(x, 2.0) -> x*x 1197252723Sdim return B.CreateFMul(Op1, Op1, "pow2"); 1198252723Sdim if (Op2C->isExactlyValue(-1.0)) // pow(x, -1.0) -> 1.0/x 1199252723Sdim return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0), 1200252723Sdim Op1, "powrecip"); 1201252723Sdim return 0; 1202252723Sdim } 1203252723Sdim}; 1204252723Sdim 1205252723Sdimstruct Exp2Opt : public UnsafeFPLibCallOptimization { 1206252723Sdim Exp2Opt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {} 1207252723Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1208252723Sdim Value *Ret = NULL; 1209252723Sdim if (UnsafeFPShrink && Callee->getName() == "exp2" && 1210263509Sdim TLI->has(LibFunc::exp2f)) { 1211252723Sdim UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 1212252723Sdim Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B); 1213252723Sdim } 1214252723Sdim 1215252723Sdim FunctionType *FT = Callee->getFunctionType(); 1216252723Sdim // Just make sure this has 1 argument of FP type, which matches the 1217252723Sdim // result type. 1218252723Sdim if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) || 1219252723Sdim !FT->getParamType(0)->isFloatingPointTy()) 1220252723Sdim return Ret; 1221252723Sdim 1222252723Sdim Value *Op = CI->getArgOperand(0); 1223252723Sdim // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x)) if sizeof(x) <= 32 1224252723Sdim // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < 32 1225252723Sdim Value *LdExpArg = 0; 1226252723Sdim if (SIToFPInst *OpC = dyn_cast<SIToFPInst>(Op)) { 1227252723Sdim if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() <= 32) 1228252723Sdim LdExpArg = B.CreateSExt(OpC->getOperand(0), B.getInt32Ty()); 1229252723Sdim } else if (UIToFPInst *OpC = dyn_cast<UIToFPInst>(Op)) { 1230252723Sdim if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() < 32) 1231252723Sdim LdExpArg = B.CreateZExt(OpC->getOperand(0), B.getInt32Ty()); 1232252723Sdim } 1233252723Sdim 1234252723Sdim if (LdExpArg) { 1235252723Sdim const char *Name; 1236252723Sdim if (Op->getType()->isFloatTy()) 1237252723Sdim Name = "ldexpf"; 1238252723Sdim else if (Op->getType()->isDoubleTy()) 1239252723Sdim Name = "ldexp"; 1240252723Sdim else 1241252723Sdim Name = "ldexpl"; 1242252723Sdim 1243252723Sdim Constant *One = ConstantFP::get(*Context, APFloat(1.0f)); 1244252723Sdim if (!Op->getType()->isFloatTy()) 1245252723Sdim One = ConstantExpr::getFPExtend(One, Op->getType()); 1246252723Sdim 1247252723Sdim Module *M = Caller->getParent(); 1248252723Sdim Value *Callee = M->getOrInsertFunction(Name, Op->getType(), 1249252723Sdim Op->getType(), 1250252723Sdim B.getInt32Ty(), NULL); 1251252723Sdim CallInst *CI = B.CreateCall2(Callee, One, LdExpArg); 1252252723Sdim if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) 1253252723Sdim CI->setCallingConv(F->getCallingConv()); 1254252723Sdim 1255252723Sdim return CI; 1256252723Sdim } 1257252723Sdim return Ret; 1258252723Sdim } 1259252723Sdim}; 1260252723Sdim 1261263509Sdimstruct SinCosPiOpt : public LibCallOptimization { 1262263509Sdim SinCosPiOpt() {} 1263263509Sdim 1264263509Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1265263509Sdim // Make sure the prototype is as expected, otherwise the rest of the 1266263509Sdim // function is probably invalid and likely to abort. 1267263509Sdim if (!isTrigLibCall(CI)) 1268263509Sdim return 0; 1269263509Sdim 1270263509Sdim Value *Arg = CI->getArgOperand(0); 1271263509Sdim SmallVector<CallInst *, 1> SinCalls; 1272263509Sdim SmallVector<CallInst *, 1> CosCalls; 1273263509Sdim SmallVector<CallInst *, 1> SinCosCalls; 1274263509Sdim 1275263509Sdim bool IsFloat = Arg->getType()->isFloatTy(); 1276263509Sdim 1277263509Sdim // Look for all compatible sinpi, cospi and sincospi calls with the same 1278263509Sdim // argument. If there are enough (in some sense) we can make the 1279263509Sdim // substitution. 1280263509Sdim for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end(); 1281263509Sdim UI != UE; ++UI) 1282263509Sdim classifyArgUse(*UI, CI->getParent(), IsFloat, SinCalls, CosCalls, 1283263509Sdim SinCosCalls); 1284263509Sdim 1285263509Sdim // It's only worthwhile if both sinpi and cospi are actually used. 1286263509Sdim if (SinCosCalls.empty() && (SinCalls.empty() || CosCalls.empty())) 1287263509Sdim return 0; 1288263509Sdim 1289263509Sdim Value *Sin, *Cos, *SinCos; 1290263509Sdim insertSinCosCall(B, CI->getCalledFunction(), Arg, IsFloat, Sin, Cos, 1291263509Sdim SinCos); 1292263509Sdim 1293263509Sdim replaceTrigInsts(SinCalls, Sin); 1294263509Sdim replaceTrigInsts(CosCalls, Cos); 1295263509Sdim replaceTrigInsts(SinCosCalls, SinCos); 1296263509Sdim 1297263509Sdim return 0; 1298263509Sdim } 1299263509Sdim 1300263509Sdim bool isTrigLibCall(CallInst *CI) { 1301263509Sdim Function *Callee = CI->getCalledFunction(); 1302263509Sdim FunctionType *FT = Callee->getFunctionType(); 1303263509Sdim 1304263509Sdim // We can only hope to do anything useful if we can ignore things like errno 1305263509Sdim // and floating-point exceptions. 1306263509Sdim bool AttributesSafe = CI->hasFnAttr(Attribute::NoUnwind) && 1307263509Sdim CI->hasFnAttr(Attribute::ReadNone); 1308263509Sdim 1309263509Sdim // Other than that we need float(float) or double(double) 1310263509Sdim return AttributesSafe && FT->getNumParams() == 1 && 1311263509Sdim FT->getReturnType() == FT->getParamType(0) && 1312263509Sdim (FT->getParamType(0)->isFloatTy() || 1313263509Sdim FT->getParamType(0)->isDoubleTy()); 1314263509Sdim } 1315263509Sdim 1316263509Sdim void classifyArgUse(Value *Val, BasicBlock *BB, bool IsFloat, 1317263509Sdim SmallVectorImpl<CallInst *> &SinCalls, 1318263509Sdim SmallVectorImpl<CallInst *> &CosCalls, 1319263509Sdim SmallVectorImpl<CallInst *> &SinCosCalls) { 1320263509Sdim CallInst *CI = dyn_cast<CallInst>(Val); 1321263509Sdim 1322263509Sdim if (!CI) 1323263509Sdim return; 1324263509Sdim 1325263509Sdim Function *Callee = CI->getCalledFunction(); 1326263509Sdim StringRef FuncName = Callee->getName(); 1327263509Sdim LibFunc::Func Func; 1328263509Sdim if (!TLI->getLibFunc(FuncName, Func) || !TLI->has(Func) || 1329263509Sdim !isTrigLibCall(CI)) 1330263509Sdim return; 1331263509Sdim 1332263509Sdim if (IsFloat) { 1333263509Sdim if (Func == LibFunc::sinpif) 1334263509Sdim SinCalls.push_back(CI); 1335263509Sdim else if (Func == LibFunc::cospif) 1336263509Sdim CosCalls.push_back(CI); 1337263509Sdim else if (Func == LibFunc::sincospi_stretf) 1338263509Sdim SinCosCalls.push_back(CI); 1339263509Sdim } else { 1340263509Sdim if (Func == LibFunc::sinpi) 1341263509Sdim SinCalls.push_back(CI); 1342263509Sdim else if (Func == LibFunc::cospi) 1343263509Sdim CosCalls.push_back(CI); 1344263509Sdim else if (Func == LibFunc::sincospi_stret) 1345263509Sdim SinCosCalls.push_back(CI); 1346263509Sdim } 1347263509Sdim } 1348263509Sdim 1349263509Sdim void replaceTrigInsts(SmallVectorImpl<CallInst*> &Calls, Value *Res) { 1350263509Sdim for (SmallVectorImpl<CallInst*>::iterator I = Calls.begin(), 1351263509Sdim E = Calls.end(); 1352263509Sdim I != E; ++I) { 1353263509Sdim LCS->replaceAllUsesWith(*I, Res); 1354263509Sdim } 1355263509Sdim } 1356263509Sdim 1357263509Sdim void insertSinCosCall(IRBuilder<> &B, Function *OrigCallee, Value *Arg, 1358263509Sdim bool UseFloat, Value *&Sin, Value *&Cos, 1359263509Sdim Value *&SinCos) { 1360263509Sdim Type *ArgTy = Arg->getType(); 1361263509Sdim Type *ResTy; 1362263509Sdim StringRef Name; 1363263509Sdim 1364263509Sdim Triple T(OrigCallee->getParent()->getTargetTriple()); 1365263509Sdim if (UseFloat) { 1366263509Sdim Name = "__sincospi_stretf"; 1367263509Sdim 1368263509Sdim assert(T.getArch() != Triple::x86 && "x86 messy and unsupported for now"); 1369263509Sdim // x86_64 can't use {float, float} since that would be returned in both 1370263509Sdim // xmm0 and xmm1, which isn't what a real struct would do. 1371263509Sdim ResTy = T.getArch() == Triple::x86_64 1372263509Sdim ? static_cast<Type *>(VectorType::get(ArgTy, 2)) 1373263509Sdim : static_cast<Type *>(StructType::get(ArgTy, ArgTy, NULL)); 1374263509Sdim } else { 1375263509Sdim Name = "__sincospi_stret"; 1376263509Sdim ResTy = StructType::get(ArgTy, ArgTy, NULL); 1377263509Sdim } 1378263509Sdim 1379263509Sdim Module *M = OrigCallee->getParent(); 1380263509Sdim Value *Callee = M->getOrInsertFunction(Name, OrigCallee->getAttributes(), 1381263509Sdim ResTy, ArgTy, NULL); 1382263509Sdim 1383263509Sdim if (Instruction *ArgInst = dyn_cast<Instruction>(Arg)) { 1384263509Sdim // If the argument is an instruction, it must dominate all uses so put our 1385263509Sdim // sincos call there. 1386263509Sdim BasicBlock::iterator Loc = ArgInst; 1387263509Sdim B.SetInsertPoint(ArgInst->getParent(), ++Loc); 1388263509Sdim } else { 1389263509Sdim // Otherwise (e.g. for a constant) the beginning of the function is as 1390263509Sdim // good a place as any. 1391263509Sdim BasicBlock &EntryBB = B.GetInsertBlock()->getParent()->getEntryBlock(); 1392263509Sdim B.SetInsertPoint(&EntryBB, EntryBB.begin()); 1393263509Sdim } 1394263509Sdim 1395263509Sdim SinCos = B.CreateCall(Callee, Arg, "sincospi"); 1396263509Sdim 1397263509Sdim if (SinCos->getType()->isStructTy()) { 1398263509Sdim Sin = B.CreateExtractValue(SinCos, 0, "sinpi"); 1399263509Sdim Cos = B.CreateExtractValue(SinCos, 1, "cospi"); 1400263509Sdim } else { 1401263509Sdim Sin = B.CreateExtractElement(SinCos, ConstantInt::get(B.getInt32Ty(), 0), 1402263509Sdim "sinpi"); 1403263509Sdim Cos = B.CreateExtractElement(SinCos, ConstantInt::get(B.getInt32Ty(), 1), 1404263509Sdim "cospi"); 1405263509Sdim } 1406263509Sdim } 1407263509Sdim 1408263509Sdim}; 1409263509Sdim 1410252723Sdim//===----------------------------------------------------------------------===// 1411252723Sdim// Integer Library Call Optimizations 1412252723Sdim//===----------------------------------------------------------------------===// 1413252723Sdim 1414252723Sdimstruct FFSOpt : public LibCallOptimization { 1415252723Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1416252723Sdim FunctionType *FT = Callee->getFunctionType(); 1417252723Sdim // Just make sure this has 2 arguments of the same FP type, which match the 1418252723Sdim // result type. 1419252723Sdim if (FT->getNumParams() != 1 || 1420252723Sdim !FT->getReturnType()->isIntegerTy(32) || 1421252723Sdim !FT->getParamType(0)->isIntegerTy()) 1422252723Sdim return 0; 1423252723Sdim 1424252723Sdim Value *Op = CI->getArgOperand(0); 1425252723Sdim 1426252723Sdim // Constant fold. 1427252723Sdim if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) { 1428252723Sdim if (CI->isZero()) // ffs(0) -> 0. 1429252723Sdim return B.getInt32(0); 1430252723Sdim // ffs(c) -> cttz(c)+1 1431252723Sdim return B.getInt32(CI->getValue().countTrailingZeros() + 1); 1432252723Sdim } 1433252723Sdim 1434252723Sdim // ffs(x) -> x != 0 ? (i32)llvm.cttz(x)+1 : 0 1435252723Sdim Type *ArgType = Op->getType(); 1436252723Sdim Value *F = Intrinsic::getDeclaration(Callee->getParent(), 1437252723Sdim Intrinsic::cttz, ArgType); 1438252723Sdim Value *V = B.CreateCall2(F, Op, B.getFalse(), "cttz"); 1439252723Sdim V = B.CreateAdd(V, ConstantInt::get(V->getType(), 1)); 1440252723Sdim V = B.CreateIntCast(V, B.getInt32Ty(), false); 1441252723Sdim 1442252723Sdim Value *Cond = B.CreateICmpNE(Op, Constant::getNullValue(ArgType)); 1443252723Sdim return B.CreateSelect(Cond, V, B.getInt32(0)); 1444252723Sdim } 1445252723Sdim}; 1446252723Sdim 1447252723Sdimstruct AbsOpt : public LibCallOptimization { 1448252723Sdim virtual bool ignoreCallingConv() { return true; } 1449252723Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1450252723Sdim FunctionType *FT = Callee->getFunctionType(); 1451252723Sdim // We require integer(integer) where the types agree. 1452252723Sdim if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() || 1453252723Sdim FT->getParamType(0) != FT->getReturnType()) 1454252723Sdim return 0; 1455252723Sdim 1456252723Sdim // abs(x) -> x >s -1 ? x : -x 1457252723Sdim Value *Op = CI->getArgOperand(0); 1458252723Sdim Value *Pos = B.CreateICmpSGT(Op, Constant::getAllOnesValue(Op->getType()), 1459252723Sdim "ispos"); 1460252723Sdim Value *Neg = B.CreateNeg(Op, "neg"); 1461252723Sdim return B.CreateSelect(Pos, Op, Neg); 1462252723Sdim } 1463252723Sdim}; 1464252723Sdim 1465252723Sdimstruct IsDigitOpt : public LibCallOptimization { 1466252723Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1467252723Sdim FunctionType *FT = Callee->getFunctionType(); 1468252723Sdim // We require integer(i32) 1469252723Sdim if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() || 1470252723Sdim !FT->getParamType(0)->isIntegerTy(32)) 1471252723Sdim return 0; 1472252723Sdim 1473252723Sdim // isdigit(c) -> (c-'0') <u 10 1474252723Sdim Value *Op = CI->getArgOperand(0); 1475252723Sdim Op = B.CreateSub(Op, B.getInt32('0'), "isdigittmp"); 1476252723Sdim Op = B.CreateICmpULT(Op, B.getInt32(10), "isdigit"); 1477252723Sdim return B.CreateZExt(Op, CI->getType()); 1478252723Sdim } 1479252723Sdim}; 1480252723Sdim 1481252723Sdimstruct IsAsciiOpt : public LibCallOptimization { 1482252723Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1483252723Sdim FunctionType *FT = Callee->getFunctionType(); 1484252723Sdim // We require integer(i32) 1485252723Sdim if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() || 1486252723Sdim !FT->getParamType(0)->isIntegerTy(32)) 1487252723Sdim return 0; 1488252723Sdim 1489252723Sdim // isascii(c) -> c <u 128 1490252723Sdim Value *Op = CI->getArgOperand(0); 1491252723Sdim Op = B.CreateICmpULT(Op, B.getInt32(128), "isascii"); 1492252723Sdim return B.CreateZExt(Op, CI->getType()); 1493252723Sdim } 1494252723Sdim}; 1495252723Sdim 1496252723Sdimstruct ToAsciiOpt : public LibCallOptimization { 1497252723Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1498252723Sdim FunctionType *FT = Callee->getFunctionType(); 1499252723Sdim // We require i32(i32) 1500252723Sdim if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) || 1501252723Sdim !FT->getParamType(0)->isIntegerTy(32)) 1502252723Sdim return 0; 1503252723Sdim 1504252723Sdim // toascii(c) -> c & 0x7f 1505252723Sdim return B.CreateAnd(CI->getArgOperand(0), 1506252723Sdim ConstantInt::get(CI->getType(),0x7F)); 1507252723Sdim } 1508252723Sdim}; 1509252723Sdim 1510252723Sdim//===----------------------------------------------------------------------===// 1511252723Sdim// Formatting and IO Library Call Optimizations 1512252723Sdim//===----------------------------------------------------------------------===// 1513252723Sdim 1514263509Sdimstruct ErrorReportingOpt : public LibCallOptimization { 1515263509Sdim ErrorReportingOpt(int S = -1) : StreamArg(S) {} 1516263509Sdim 1517263509Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &) { 1518263509Sdim // Error reporting calls should be cold, mark them as such. 1519263509Sdim // This applies even to non-builtin calls: it is only a hint and applies to 1520263509Sdim // functions that the frontend might not understand as builtins. 1521263509Sdim 1522263509Sdim // This heuristic was suggested in: 1523263509Sdim // Improving Static Branch Prediction in a Compiler 1524263509Sdim // Brian L. Deitrich, Ben-Chung Cheng, Wen-mei W. Hwu 1525263509Sdim // Proceedings of PACT'98, Oct. 1998, IEEE 1526263509Sdim 1527263509Sdim if (!CI->hasFnAttr(Attribute::Cold) && isReportingError(Callee, CI)) { 1528263509Sdim CI->addAttribute(AttributeSet::FunctionIndex, Attribute::Cold); 1529263509Sdim } 1530263509Sdim 1531263509Sdim return 0; 1532263509Sdim } 1533263509Sdim 1534263509Sdimprotected: 1535263509Sdim bool isReportingError(Function *Callee, CallInst *CI) { 1536263509Sdim if (!ColdErrorCalls) 1537263509Sdim return false; 1538263509Sdim 1539263509Sdim if (!Callee || !Callee->isDeclaration()) 1540263509Sdim return false; 1541263509Sdim 1542263509Sdim if (StreamArg < 0) 1543263509Sdim return true; 1544263509Sdim 1545263509Sdim // These functions might be considered cold, but only if their stream 1546263509Sdim // argument is stderr. 1547263509Sdim 1548263509Sdim if (StreamArg >= (int) CI->getNumArgOperands()) 1549263509Sdim return false; 1550263509Sdim LoadInst *LI = dyn_cast<LoadInst>(CI->getArgOperand(StreamArg)); 1551263509Sdim if (!LI) 1552263509Sdim return false; 1553263509Sdim GlobalVariable *GV = dyn_cast<GlobalVariable>(LI->getPointerOperand()); 1554263509Sdim if (!GV || !GV->isDeclaration()) 1555263509Sdim return false; 1556263509Sdim return GV->getName() == "stderr"; 1557263509Sdim } 1558263509Sdim 1559263509Sdim int StreamArg; 1560263509Sdim}; 1561263509Sdim 1562252723Sdimstruct PrintFOpt : public LibCallOptimization { 1563252723Sdim Value *optimizeFixedFormatString(Function *Callee, CallInst *CI, 1564252723Sdim IRBuilder<> &B) { 1565252723Sdim // Check for a fixed format string. 1566252723Sdim StringRef FormatStr; 1567252723Sdim if (!getConstantStringInfo(CI->getArgOperand(0), FormatStr)) 1568252723Sdim return 0; 1569252723Sdim 1570252723Sdim // Empty format string -> noop. 1571252723Sdim if (FormatStr.empty()) // Tolerate printf's declared void. 1572252723Sdim return CI->use_empty() ? (Value*)CI : 1573252723Sdim ConstantInt::get(CI->getType(), 0); 1574252723Sdim 1575252723Sdim // Do not do any of the following transformations if the printf return value 1576252723Sdim // is used, in general the printf return value is not compatible with either 1577252723Sdim // putchar() or puts(). 1578252723Sdim if (!CI->use_empty()) 1579252723Sdim return 0; 1580252723Sdim 1581252723Sdim // printf("x") -> putchar('x'), even for '%'. 1582252723Sdim if (FormatStr.size() == 1) { 1583252723Sdim Value *Res = EmitPutChar(B.getInt32(FormatStr[0]), B, TD, TLI); 1584252723Sdim if (CI->use_empty() || !Res) return Res; 1585252723Sdim return B.CreateIntCast(Res, CI->getType(), true); 1586252723Sdim } 1587252723Sdim 1588252723Sdim // printf("foo\n") --> puts("foo") 1589252723Sdim if (FormatStr[FormatStr.size()-1] == '\n' && 1590263509Sdim FormatStr.find('%') == StringRef::npos) { // No format characters. 1591252723Sdim // Create a string literal with no \n on it. We expect the constant merge 1592252723Sdim // pass to be run after this pass, to merge duplicate strings. 1593252723Sdim FormatStr = FormatStr.drop_back(); 1594252723Sdim Value *GV = B.CreateGlobalString(FormatStr, "str"); 1595252723Sdim Value *NewCI = EmitPutS(GV, B, TD, TLI); 1596252723Sdim return (CI->use_empty() || !NewCI) ? 1597252723Sdim NewCI : 1598252723Sdim ConstantInt::get(CI->getType(), FormatStr.size()+1); 1599252723Sdim } 1600252723Sdim 1601252723Sdim // Optimize specific format strings. 1602252723Sdim // printf("%c", chr) --> putchar(chr) 1603252723Sdim if (FormatStr == "%c" && CI->getNumArgOperands() > 1 && 1604252723Sdim CI->getArgOperand(1)->getType()->isIntegerTy()) { 1605252723Sdim Value *Res = EmitPutChar(CI->getArgOperand(1), B, TD, TLI); 1606252723Sdim 1607252723Sdim if (CI->use_empty() || !Res) return Res; 1608252723Sdim return B.CreateIntCast(Res, CI->getType(), true); 1609252723Sdim } 1610252723Sdim 1611252723Sdim // printf("%s\n", str) --> puts(str) 1612252723Sdim if (FormatStr == "%s\n" && CI->getNumArgOperands() > 1 && 1613252723Sdim CI->getArgOperand(1)->getType()->isPointerTy()) { 1614252723Sdim return EmitPutS(CI->getArgOperand(1), B, TD, TLI); 1615252723Sdim } 1616252723Sdim return 0; 1617252723Sdim } 1618252723Sdim 1619252723Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1620252723Sdim // Require one fixed pointer argument and an integer/void result. 1621252723Sdim FunctionType *FT = Callee->getFunctionType(); 1622252723Sdim if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() || 1623252723Sdim !(FT->getReturnType()->isIntegerTy() || 1624252723Sdim FT->getReturnType()->isVoidTy())) 1625252723Sdim return 0; 1626252723Sdim 1627252723Sdim if (Value *V = optimizeFixedFormatString(Callee, CI, B)) { 1628252723Sdim return V; 1629252723Sdim } 1630252723Sdim 1631252723Sdim // printf(format, ...) -> iprintf(format, ...) if no floating point 1632252723Sdim // arguments. 1633252723Sdim if (TLI->has(LibFunc::iprintf) && !callHasFloatingPointArgument(CI)) { 1634252723Sdim Module *M = B.GetInsertBlock()->getParent()->getParent(); 1635252723Sdim Constant *IPrintFFn = 1636252723Sdim M->getOrInsertFunction("iprintf", FT, Callee->getAttributes()); 1637252723Sdim CallInst *New = cast<CallInst>(CI->clone()); 1638252723Sdim New->setCalledFunction(IPrintFFn); 1639252723Sdim B.Insert(New); 1640252723Sdim return New; 1641252723Sdim } 1642252723Sdim return 0; 1643252723Sdim } 1644252723Sdim}; 1645252723Sdim 1646252723Sdimstruct SPrintFOpt : public LibCallOptimization { 1647252723Sdim Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI, 1648252723Sdim IRBuilder<> &B) { 1649252723Sdim // Check for a fixed format string. 1650252723Sdim StringRef FormatStr; 1651252723Sdim if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr)) 1652252723Sdim return 0; 1653252723Sdim 1654252723Sdim // If we just have a format string (nothing else crazy) transform it. 1655252723Sdim if (CI->getNumArgOperands() == 2) { 1656252723Sdim // Make sure there's no % in the constant array. We could try to handle 1657252723Sdim // %% -> % in the future if we cared. 1658252723Sdim for (unsigned i = 0, e = FormatStr.size(); i != e; ++i) 1659252723Sdim if (FormatStr[i] == '%') 1660252723Sdim return 0; // we found a format specifier, bail out. 1661252723Sdim 1662252723Sdim // These optimizations require DataLayout. 1663252723Sdim if (!TD) return 0; 1664252723Sdim 1665252723Sdim // sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1) 1666252723Sdim B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), 1667252723Sdim ConstantInt::get(TD->getIntPtrType(*Context), // Copy the 1668252723Sdim FormatStr.size() + 1), 1); // nul byte. 1669252723Sdim return ConstantInt::get(CI->getType(), FormatStr.size()); 1670252723Sdim } 1671252723Sdim 1672252723Sdim // The remaining optimizations require the format string to be "%s" or "%c" 1673252723Sdim // and have an extra operand. 1674252723Sdim if (FormatStr.size() != 2 || FormatStr[0] != '%' || 1675252723Sdim CI->getNumArgOperands() < 3) 1676252723Sdim return 0; 1677252723Sdim 1678252723Sdim // Decode the second character of the format string. 1679252723Sdim if (FormatStr[1] == 'c') { 1680252723Sdim // sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0 1681252723Sdim if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return 0; 1682252723Sdim Value *V = B.CreateTrunc(CI->getArgOperand(2), B.getInt8Ty(), "char"); 1683252723Sdim Value *Ptr = CastToCStr(CI->getArgOperand(0), B); 1684252723Sdim B.CreateStore(V, Ptr); 1685252723Sdim Ptr = B.CreateGEP(Ptr, B.getInt32(1), "nul"); 1686252723Sdim B.CreateStore(B.getInt8(0), Ptr); 1687252723Sdim 1688252723Sdim return ConstantInt::get(CI->getType(), 1); 1689252723Sdim } 1690252723Sdim 1691252723Sdim if (FormatStr[1] == 's') { 1692252723Sdim // These optimizations require DataLayout. 1693252723Sdim if (!TD) return 0; 1694252723Sdim 1695252723Sdim // sprintf(dest, "%s", str) -> llvm.memcpy(dest, str, strlen(str)+1, 1) 1696252723Sdim if (!CI->getArgOperand(2)->getType()->isPointerTy()) return 0; 1697252723Sdim 1698252723Sdim Value *Len = EmitStrLen(CI->getArgOperand(2), B, TD, TLI); 1699252723Sdim if (!Len) 1700252723Sdim return 0; 1701252723Sdim Value *IncLen = B.CreateAdd(Len, 1702252723Sdim ConstantInt::get(Len->getType(), 1), 1703252723Sdim "leninc"); 1704252723Sdim B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(2), IncLen, 1); 1705252723Sdim 1706252723Sdim // The sprintf result is the unincremented number of bytes in the string. 1707252723Sdim return B.CreateIntCast(Len, CI->getType(), false); 1708252723Sdim } 1709252723Sdim return 0; 1710252723Sdim } 1711252723Sdim 1712252723Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1713252723Sdim // Require two fixed pointer arguments and an integer result. 1714252723Sdim FunctionType *FT = Callee->getFunctionType(); 1715252723Sdim if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() || 1716252723Sdim !FT->getParamType(1)->isPointerTy() || 1717252723Sdim !FT->getReturnType()->isIntegerTy()) 1718252723Sdim return 0; 1719252723Sdim 1720252723Sdim if (Value *V = OptimizeFixedFormatString(Callee, CI, B)) { 1721252723Sdim return V; 1722252723Sdim } 1723252723Sdim 1724252723Sdim // sprintf(str, format, ...) -> siprintf(str, format, ...) if no floating 1725252723Sdim // point arguments. 1726252723Sdim if (TLI->has(LibFunc::siprintf) && !callHasFloatingPointArgument(CI)) { 1727252723Sdim Module *M = B.GetInsertBlock()->getParent()->getParent(); 1728252723Sdim Constant *SIPrintFFn = 1729252723Sdim M->getOrInsertFunction("siprintf", FT, Callee->getAttributes()); 1730252723Sdim CallInst *New = cast<CallInst>(CI->clone()); 1731252723Sdim New->setCalledFunction(SIPrintFFn); 1732252723Sdim B.Insert(New); 1733252723Sdim return New; 1734252723Sdim } 1735252723Sdim return 0; 1736252723Sdim } 1737252723Sdim}; 1738252723Sdim 1739252723Sdimstruct FPrintFOpt : public LibCallOptimization { 1740252723Sdim Value *optimizeFixedFormatString(Function *Callee, CallInst *CI, 1741252723Sdim IRBuilder<> &B) { 1742263509Sdim ErrorReportingOpt ER(/* StreamArg = */ 0); 1743263509Sdim (void) ER.callOptimizer(Callee, CI, B); 1744263509Sdim 1745252723Sdim // All the optimizations depend on the format string. 1746252723Sdim StringRef FormatStr; 1747252723Sdim if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr)) 1748252723Sdim return 0; 1749252723Sdim 1750252723Sdim // Do not do any of the following transformations if the fprintf return 1751252723Sdim // value is used, in general the fprintf return value is not compatible 1752252723Sdim // with fwrite(), fputc() or fputs(). 1753252723Sdim if (!CI->use_empty()) 1754252723Sdim return 0; 1755252723Sdim 1756252723Sdim // fprintf(F, "foo") --> fwrite("foo", 3, 1, F) 1757252723Sdim if (CI->getNumArgOperands() == 2) { 1758252723Sdim for (unsigned i = 0, e = FormatStr.size(); i != e; ++i) 1759252723Sdim if (FormatStr[i] == '%') // Could handle %% -> % if we cared. 1760252723Sdim return 0; // We found a format specifier. 1761252723Sdim 1762252723Sdim // These optimizations require DataLayout. 1763252723Sdim if (!TD) return 0; 1764252723Sdim 1765252723Sdim return EmitFWrite(CI->getArgOperand(1), 1766252723Sdim ConstantInt::get(TD->getIntPtrType(*Context), 1767252723Sdim FormatStr.size()), 1768252723Sdim CI->getArgOperand(0), B, TD, TLI); 1769252723Sdim } 1770252723Sdim 1771252723Sdim // The remaining optimizations require the format string to be "%s" or "%c" 1772252723Sdim // and have an extra operand. 1773252723Sdim if (FormatStr.size() != 2 || FormatStr[0] != '%' || 1774252723Sdim CI->getNumArgOperands() < 3) 1775252723Sdim return 0; 1776252723Sdim 1777252723Sdim // Decode the second character of the format string. 1778252723Sdim if (FormatStr[1] == 'c') { 1779252723Sdim // fprintf(F, "%c", chr) --> fputc(chr, F) 1780252723Sdim if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return 0; 1781252723Sdim return EmitFPutC(CI->getArgOperand(2), CI->getArgOperand(0), B, TD, TLI); 1782252723Sdim } 1783252723Sdim 1784252723Sdim if (FormatStr[1] == 's') { 1785252723Sdim // fprintf(F, "%s", str) --> fputs(str, F) 1786252723Sdim if (!CI->getArgOperand(2)->getType()->isPointerTy()) 1787252723Sdim return 0; 1788252723Sdim return EmitFPutS(CI->getArgOperand(2), CI->getArgOperand(0), B, TD, TLI); 1789252723Sdim } 1790252723Sdim return 0; 1791252723Sdim } 1792252723Sdim 1793252723Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1794252723Sdim // Require two fixed paramters as pointers and integer result. 1795252723Sdim FunctionType *FT = Callee->getFunctionType(); 1796252723Sdim if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() || 1797252723Sdim !FT->getParamType(1)->isPointerTy() || 1798252723Sdim !FT->getReturnType()->isIntegerTy()) 1799252723Sdim return 0; 1800252723Sdim 1801252723Sdim if (Value *V = optimizeFixedFormatString(Callee, CI, B)) { 1802252723Sdim return V; 1803252723Sdim } 1804252723Sdim 1805252723Sdim // fprintf(stream, format, ...) -> fiprintf(stream, format, ...) if no 1806252723Sdim // floating point arguments. 1807252723Sdim if (TLI->has(LibFunc::fiprintf) && !callHasFloatingPointArgument(CI)) { 1808252723Sdim Module *M = B.GetInsertBlock()->getParent()->getParent(); 1809252723Sdim Constant *FIPrintFFn = 1810252723Sdim M->getOrInsertFunction("fiprintf", FT, Callee->getAttributes()); 1811252723Sdim CallInst *New = cast<CallInst>(CI->clone()); 1812252723Sdim New->setCalledFunction(FIPrintFFn); 1813252723Sdim B.Insert(New); 1814252723Sdim return New; 1815252723Sdim } 1816252723Sdim return 0; 1817252723Sdim } 1818252723Sdim}; 1819252723Sdim 1820252723Sdimstruct FWriteOpt : public LibCallOptimization { 1821252723Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1822263509Sdim ErrorReportingOpt ER(/* StreamArg = */ 3); 1823263509Sdim (void) ER.callOptimizer(Callee, CI, B); 1824263509Sdim 1825252723Sdim // Require a pointer, an integer, an integer, a pointer, returning integer. 1826252723Sdim FunctionType *FT = Callee->getFunctionType(); 1827252723Sdim if (FT->getNumParams() != 4 || !FT->getParamType(0)->isPointerTy() || 1828252723Sdim !FT->getParamType(1)->isIntegerTy() || 1829252723Sdim !FT->getParamType(2)->isIntegerTy() || 1830252723Sdim !FT->getParamType(3)->isPointerTy() || 1831252723Sdim !FT->getReturnType()->isIntegerTy()) 1832252723Sdim return 0; 1833252723Sdim 1834252723Sdim // Get the element size and count. 1835252723Sdim ConstantInt *SizeC = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 1836252723Sdim ConstantInt *CountC = dyn_cast<ConstantInt>(CI->getArgOperand(2)); 1837252723Sdim if (!SizeC || !CountC) return 0; 1838252723Sdim uint64_t Bytes = SizeC->getZExtValue()*CountC->getZExtValue(); 1839252723Sdim 1840252723Sdim // If this is writing zero records, remove the call (it's a noop). 1841252723Sdim if (Bytes == 0) 1842252723Sdim return ConstantInt::get(CI->getType(), 0); 1843252723Sdim 1844252723Sdim // If this is writing one byte, turn it into fputc. 1845252723Sdim // This optimisation is only valid, if the return value is unused. 1846252723Sdim if (Bytes == 1 && CI->use_empty()) { // fwrite(S,1,1,F) -> fputc(S[0],F) 1847252723Sdim Value *Char = B.CreateLoad(CastToCStr(CI->getArgOperand(0), B), "char"); 1848252723Sdim Value *NewCI = EmitFPutC(Char, CI->getArgOperand(3), B, TD, TLI); 1849252723Sdim return NewCI ? ConstantInt::get(CI->getType(), 1) : 0; 1850252723Sdim } 1851252723Sdim 1852252723Sdim return 0; 1853252723Sdim } 1854252723Sdim}; 1855252723Sdim 1856252723Sdimstruct FPutsOpt : public LibCallOptimization { 1857252723Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1858263509Sdim ErrorReportingOpt ER(/* StreamArg = */ 1); 1859263509Sdim (void) ER.callOptimizer(Callee, CI, B); 1860263509Sdim 1861252723Sdim // These optimizations require DataLayout. 1862252723Sdim if (!TD) return 0; 1863252723Sdim 1864252723Sdim // Require two pointers. Also, we can't optimize if return value is used. 1865252723Sdim FunctionType *FT = Callee->getFunctionType(); 1866252723Sdim if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() || 1867252723Sdim !FT->getParamType(1)->isPointerTy() || 1868252723Sdim !CI->use_empty()) 1869252723Sdim return 0; 1870252723Sdim 1871252723Sdim // fputs(s,F) --> fwrite(s,1,strlen(s),F) 1872252723Sdim uint64_t Len = GetStringLength(CI->getArgOperand(0)); 1873252723Sdim if (!Len) return 0; 1874252723Sdim // Known to have no uses (see above). 1875252723Sdim return EmitFWrite(CI->getArgOperand(0), 1876252723Sdim ConstantInt::get(TD->getIntPtrType(*Context), Len-1), 1877252723Sdim CI->getArgOperand(1), B, TD, TLI); 1878252723Sdim } 1879252723Sdim}; 1880252723Sdim 1881252723Sdimstruct PutsOpt : public LibCallOptimization { 1882252723Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1883252723Sdim // Require one fixed pointer argument and an integer/void result. 1884252723Sdim FunctionType *FT = Callee->getFunctionType(); 1885252723Sdim if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() || 1886252723Sdim !(FT->getReturnType()->isIntegerTy() || 1887252723Sdim FT->getReturnType()->isVoidTy())) 1888252723Sdim return 0; 1889252723Sdim 1890252723Sdim // Check for a constant string. 1891252723Sdim StringRef Str; 1892252723Sdim if (!getConstantStringInfo(CI->getArgOperand(0), Str)) 1893252723Sdim return 0; 1894252723Sdim 1895252723Sdim if (Str.empty() && CI->use_empty()) { 1896252723Sdim // puts("") -> putchar('\n') 1897252723Sdim Value *Res = EmitPutChar(B.getInt32('\n'), B, TD, TLI); 1898252723Sdim if (CI->use_empty() || !Res) return Res; 1899252723Sdim return B.CreateIntCast(Res, CI->getType(), true); 1900252723Sdim } 1901252723Sdim 1902252723Sdim return 0; 1903252723Sdim } 1904252723Sdim}; 1905252723Sdim 1906243789Sdim} // End anonymous namespace. 1907243789Sdim 1908243789Sdimnamespace llvm { 1909243789Sdim 1910243789Sdimclass LibCallSimplifierImpl { 1911243789Sdim const DataLayout *TD; 1912243789Sdim const TargetLibraryInfo *TLI; 1913243789Sdim const LibCallSimplifier *LCS; 1914252723Sdim bool UnsafeFPShrink; 1915243789Sdim 1916252723Sdim // Math library call optimizations. 1917252723Sdim CosOpt Cos; 1918252723Sdim PowOpt Pow; 1919252723Sdim Exp2Opt Exp2; 1920243789Sdimpublic: 1921243789Sdim LibCallSimplifierImpl(const DataLayout *TD, const TargetLibraryInfo *TLI, 1922252723Sdim const LibCallSimplifier *LCS, 1923252723Sdim bool UnsafeFPShrink = false) 1924252723Sdim : Cos(UnsafeFPShrink), Pow(UnsafeFPShrink), Exp2(UnsafeFPShrink) { 1925243789Sdim this->TD = TD; 1926243789Sdim this->TLI = TLI; 1927243789Sdim this->LCS = LCS; 1928252723Sdim this->UnsafeFPShrink = UnsafeFPShrink; 1929243789Sdim } 1930243789Sdim 1931243789Sdim Value *optimizeCall(CallInst *CI); 1932252723Sdim LibCallOptimization *lookupOptimization(CallInst *CI); 1933252723Sdim bool hasFloatVersion(StringRef FuncName); 1934243789Sdim}; 1935243789Sdim 1936252723Sdimbool LibCallSimplifierImpl::hasFloatVersion(StringRef FuncName) { 1937252723Sdim LibFunc::Func Func; 1938252723Sdim SmallString<20> FloatFuncName = FuncName; 1939252723Sdim FloatFuncName += 'f'; 1940252723Sdim if (TLI->getLibFunc(FloatFuncName, Func)) 1941252723Sdim return TLI->has(Func); 1942252723Sdim return false; 1943252723Sdim} 1944243789Sdim 1945252723Sdim// Fortified library call optimizations. 1946252723Sdimstatic MemCpyChkOpt MemCpyChk; 1947252723Sdimstatic MemMoveChkOpt MemMoveChk; 1948252723Sdimstatic MemSetChkOpt MemSetChk; 1949252723Sdimstatic StrCpyChkOpt StrCpyChk; 1950252723Sdimstatic StpCpyChkOpt StpCpyChk; 1951252723Sdimstatic StrNCpyChkOpt StrNCpyChk; 1952243789Sdim 1953252723Sdim// String library call optimizations. 1954252723Sdimstatic StrCatOpt StrCat; 1955252723Sdimstatic StrNCatOpt StrNCat; 1956252723Sdimstatic StrChrOpt StrChr; 1957252723Sdimstatic StrRChrOpt StrRChr; 1958252723Sdimstatic StrCmpOpt StrCmp; 1959252723Sdimstatic StrNCmpOpt StrNCmp; 1960252723Sdimstatic StrCpyOpt StrCpy; 1961252723Sdimstatic StpCpyOpt StpCpy; 1962252723Sdimstatic StrNCpyOpt StrNCpy; 1963252723Sdimstatic StrLenOpt StrLen; 1964252723Sdimstatic StrPBrkOpt StrPBrk; 1965252723Sdimstatic StrToOpt StrTo; 1966252723Sdimstatic StrSpnOpt StrSpn; 1967252723Sdimstatic StrCSpnOpt StrCSpn; 1968252723Sdimstatic StrStrOpt StrStr; 1969252723Sdim 1970252723Sdim// Memory library call optimizations. 1971252723Sdimstatic MemCmpOpt MemCmp; 1972252723Sdimstatic MemCpyOpt MemCpy; 1973252723Sdimstatic MemMoveOpt MemMove; 1974252723Sdimstatic MemSetOpt MemSet; 1975252723Sdim 1976252723Sdim// Math library call optimizations. 1977252723Sdimstatic UnaryDoubleFPOpt UnaryDoubleFP(false); 1978252723Sdimstatic UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 1979263509Sdimstatic SinCosPiOpt SinCosPi; 1980252723Sdim 1981252723Sdim // Integer library call optimizations. 1982252723Sdimstatic FFSOpt FFS; 1983252723Sdimstatic AbsOpt Abs; 1984252723Sdimstatic IsDigitOpt IsDigit; 1985252723Sdimstatic IsAsciiOpt IsAscii; 1986252723Sdimstatic ToAsciiOpt ToAscii; 1987252723Sdim 1988252723Sdim// Formatting and IO library call optimizations. 1989263509Sdimstatic ErrorReportingOpt ErrorReporting; 1990263509Sdimstatic ErrorReportingOpt ErrorReporting0(0); 1991263509Sdimstatic ErrorReportingOpt ErrorReporting1(1); 1992252723Sdimstatic PrintFOpt PrintF; 1993252723Sdimstatic SPrintFOpt SPrintF; 1994252723Sdimstatic FPrintFOpt FPrintF; 1995252723Sdimstatic FWriteOpt FWrite; 1996252723Sdimstatic FPutsOpt FPuts; 1997252723Sdimstatic PutsOpt Puts; 1998252723Sdim 1999252723SdimLibCallOptimization *LibCallSimplifierImpl::lookupOptimization(CallInst *CI) { 2000252723Sdim LibFunc::Func Func; 2001252723Sdim Function *Callee = CI->getCalledFunction(); 2002252723Sdim StringRef FuncName = Callee->getName(); 2003252723Sdim 2004252723Sdim // Next check for intrinsics. 2005252723Sdim if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) { 2006252723Sdim switch (II->getIntrinsicID()) { 2007252723Sdim case Intrinsic::pow: 2008252723Sdim return &Pow; 2009252723Sdim case Intrinsic::exp2: 2010252723Sdim return &Exp2; 2011252723Sdim default: 2012252723Sdim return 0; 2013252723Sdim } 2014252723Sdim } 2015252723Sdim 2016252723Sdim // Then check for known library functions. 2017252723Sdim if (TLI->getLibFunc(FuncName, Func) && TLI->has(Func)) { 2018252723Sdim switch (Func) { 2019252723Sdim case LibFunc::strcat: 2020252723Sdim return &StrCat; 2021252723Sdim case LibFunc::strncat: 2022252723Sdim return &StrNCat; 2023252723Sdim case LibFunc::strchr: 2024252723Sdim return &StrChr; 2025252723Sdim case LibFunc::strrchr: 2026252723Sdim return &StrRChr; 2027252723Sdim case LibFunc::strcmp: 2028252723Sdim return &StrCmp; 2029252723Sdim case LibFunc::strncmp: 2030252723Sdim return &StrNCmp; 2031252723Sdim case LibFunc::strcpy: 2032252723Sdim return &StrCpy; 2033252723Sdim case LibFunc::stpcpy: 2034252723Sdim return &StpCpy; 2035252723Sdim case LibFunc::strncpy: 2036252723Sdim return &StrNCpy; 2037252723Sdim case LibFunc::strlen: 2038252723Sdim return &StrLen; 2039252723Sdim case LibFunc::strpbrk: 2040252723Sdim return &StrPBrk; 2041252723Sdim case LibFunc::strtol: 2042252723Sdim case LibFunc::strtod: 2043252723Sdim case LibFunc::strtof: 2044252723Sdim case LibFunc::strtoul: 2045252723Sdim case LibFunc::strtoll: 2046252723Sdim case LibFunc::strtold: 2047252723Sdim case LibFunc::strtoull: 2048252723Sdim return &StrTo; 2049252723Sdim case LibFunc::strspn: 2050252723Sdim return &StrSpn; 2051252723Sdim case LibFunc::strcspn: 2052252723Sdim return &StrCSpn; 2053252723Sdim case LibFunc::strstr: 2054252723Sdim return &StrStr; 2055252723Sdim case LibFunc::memcmp: 2056252723Sdim return &MemCmp; 2057252723Sdim case LibFunc::memcpy: 2058252723Sdim return &MemCpy; 2059252723Sdim case LibFunc::memmove: 2060252723Sdim return &MemMove; 2061252723Sdim case LibFunc::memset: 2062252723Sdim return &MemSet; 2063252723Sdim case LibFunc::cosf: 2064252723Sdim case LibFunc::cos: 2065252723Sdim case LibFunc::cosl: 2066252723Sdim return &Cos; 2067263509Sdim case LibFunc::sinpif: 2068263509Sdim case LibFunc::sinpi: 2069263509Sdim case LibFunc::cospif: 2070263509Sdim case LibFunc::cospi: 2071263509Sdim return &SinCosPi; 2072252723Sdim case LibFunc::powf: 2073252723Sdim case LibFunc::pow: 2074252723Sdim case LibFunc::powl: 2075252723Sdim return &Pow; 2076252723Sdim case LibFunc::exp2l: 2077252723Sdim case LibFunc::exp2: 2078252723Sdim case LibFunc::exp2f: 2079252723Sdim return &Exp2; 2080252723Sdim case LibFunc::ffs: 2081252723Sdim case LibFunc::ffsl: 2082252723Sdim case LibFunc::ffsll: 2083252723Sdim return &FFS; 2084252723Sdim case LibFunc::abs: 2085252723Sdim case LibFunc::labs: 2086252723Sdim case LibFunc::llabs: 2087252723Sdim return &Abs; 2088252723Sdim case LibFunc::isdigit: 2089252723Sdim return &IsDigit; 2090252723Sdim case LibFunc::isascii: 2091252723Sdim return &IsAscii; 2092252723Sdim case LibFunc::toascii: 2093252723Sdim return &ToAscii; 2094252723Sdim case LibFunc::printf: 2095252723Sdim return &PrintF; 2096252723Sdim case LibFunc::sprintf: 2097252723Sdim return &SPrintF; 2098252723Sdim case LibFunc::fprintf: 2099252723Sdim return &FPrintF; 2100252723Sdim case LibFunc::fwrite: 2101252723Sdim return &FWrite; 2102252723Sdim case LibFunc::fputs: 2103252723Sdim return &FPuts; 2104252723Sdim case LibFunc::puts: 2105252723Sdim return &Puts; 2106263509Sdim case LibFunc::perror: 2107263509Sdim return &ErrorReporting; 2108263509Sdim case LibFunc::vfprintf: 2109263509Sdim case LibFunc::fiprintf: 2110263509Sdim return &ErrorReporting0; 2111263509Sdim case LibFunc::fputc: 2112263509Sdim return &ErrorReporting1; 2113252723Sdim case LibFunc::ceil: 2114252723Sdim case LibFunc::fabs: 2115252723Sdim case LibFunc::floor: 2116252723Sdim case LibFunc::rint: 2117252723Sdim case LibFunc::round: 2118252723Sdim case LibFunc::nearbyint: 2119252723Sdim case LibFunc::trunc: 2120252723Sdim if (hasFloatVersion(FuncName)) 2121252723Sdim return &UnaryDoubleFP; 2122252723Sdim return 0; 2123252723Sdim case LibFunc::acos: 2124252723Sdim case LibFunc::acosh: 2125252723Sdim case LibFunc::asin: 2126252723Sdim case LibFunc::asinh: 2127252723Sdim case LibFunc::atan: 2128252723Sdim case LibFunc::atanh: 2129252723Sdim case LibFunc::cbrt: 2130252723Sdim case LibFunc::cosh: 2131252723Sdim case LibFunc::exp: 2132252723Sdim case LibFunc::exp10: 2133252723Sdim case LibFunc::expm1: 2134252723Sdim case LibFunc::log: 2135252723Sdim case LibFunc::log10: 2136252723Sdim case LibFunc::log1p: 2137252723Sdim case LibFunc::log2: 2138252723Sdim case LibFunc::logb: 2139252723Sdim case LibFunc::sin: 2140252723Sdim case LibFunc::sinh: 2141252723Sdim case LibFunc::sqrt: 2142252723Sdim case LibFunc::tan: 2143252723Sdim case LibFunc::tanh: 2144252723Sdim if (UnsafeFPShrink && hasFloatVersion(FuncName)) 2145252723Sdim return &UnsafeUnaryDoubleFP; 2146252723Sdim return 0; 2147252723Sdim case LibFunc::memcpy_chk: 2148252723Sdim return &MemCpyChk; 2149252723Sdim default: 2150252723Sdim return 0; 2151252723Sdim } 2152252723Sdim } 2153252723Sdim 2154252723Sdim // Finally check for fortified library calls. 2155252723Sdim if (FuncName.endswith("_chk")) { 2156252723Sdim if (FuncName == "__memmove_chk") 2157252723Sdim return &MemMoveChk; 2158252723Sdim else if (FuncName == "__memset_chk") 2159252723Sdim return &MemSetChk; 2160252723Sdim else if (FuncName == "__strcpy_chk") 2161252723Sdim return &StrCpyChk; 2162252723Sdim else if (FuncName == "__stpcpy_chk") 2163252723Sdim return &StpCpyChk; 2164252723Sdim else if (FuncName == "__strncpy_chk") 2165252723Sdim return &StrNCpyChk; 2166252723Sdim else if (FuncName == "__stpncpy_chk") 2167252723Sdim return &StrNCpyChk; 2168252723Sdim } 2169252723Sdim 2170252723Sdim return 0; 2171252723Sdim 2172243789Sdim} 2173243789Sdim 2174243789SdimValue *LibCallSimplifierImpl::optimizeCall(CallInst *CI) { 2175252723Sdim LibCallOptimization *LCO = lookupOptimization(CI); 2176243789Sdim if (LCO) { 2177243789Sdim IRBuilder<> Builder(CI); 2178243789Sdim return LCO->optimizeCall(CI, TD, TLI, LCS, Builder); 2179243789Sdim } 2180243789Sdim return 0; 2181243789Sdim} 2182243789Sdim 2183243789SdimLibCallSimplifier::LibCallSimplifier(const DataLayout *TD, 2184252723Sdim const TargetLibraryInfo *TLI, 2185252723Sdim bool UnsafeFPShrink) { 2186252723Sdim Impl = new LibCallSimplifierImpl(TD, TLI, this, UnsafeFPShrink); 2187243789Sdim} 2188243789Sdim 2189243789SdimLibCallSimplifier::~LibCallSimplifier() { 2190243789Sdim delete Impl; 2191243789Sdim} 2192243789Sdim 2193243789SdimValue *LibCallSimplifier::optimizeCall(CallInst *CI) { 2194263509Sdim if (CI->isNoBuiltin()) return 0; 2195243789Sdim return Impl->optimizeCall(CI); 2196243789Sdim} 2197243789Sdim 2198243789Sdimvoid LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) const { 2199243789Sdim I->replaceAllUsesWith(With); 2200243789Sdim I->eraseFromParent(); 2201243789Sdim} 2202243789Sdim 2203243789Sdim} 2204263509Sdim 2205263509Sdim// TODO: 2206263509Sdim// Additional cases that we need to add to this file: 2207263509Sdim// 2208263509Sdim// cbrt: 2209263509Sdim// * cbrt(expN(X)) -> expN(x/3) 2210263509Sdim// * cbrt(sqrt(x)) -> pow(x,1/6) 2211263509Sdim// * cbrt(sqrt(x)) -> pow(x,1/9) 2212263509Sdim// 2213263509Sdim// exp, expf, expl: 2214263509Sdim// * exp(log(x)) -> x 2215263509Sdim// 2216263509Sdim// log, logf, logl: 2217263509Sdim// * log(exp(x)) -> x 2218263509Sdim// * log(x**y) -> y*log(x) 2219263509Sdim// * log(exp(y)) -> y*log(e) 2220263509Sdim// * log(exp2(y)) -> y*log(2) 2221263509Sdim// * log(exp10(y)) -> y*log(10) 2222263509Sdim// * log(sqrt(x)) -> 0.5*log(x) 2223263509Sdim// * log(pow(x,y)) -> y*log(x) 2224263509Sdim// 2225263509Sdim// lround, lroundf, lroundl: 2226263509Sdim// * lround(cnst) -> cnst' 2227263509Sdim// 2228263509Sdim// pow, powf, powl: 2229263509Sdim// * pow(exp(x),y) -> exp(x*y) 2230263509Sdim// * pow(sqrt(x),y) -> pow(x,y*0.5) 2231263509Sdim// * pow(pow(x,y),z)-> pow(x,y*z) 2232263509Sdim// 2233263509Sdim// round, roundf, roundl: 2234263509Sdim// * round(cnst) -> cnst' 2235263509Sdim// 2236263509Sdim// signbit: 2237263509Sdim// * signbit(cnst) -> cnst' 2238263509Sdim// * signbit(nncst) -> 0 (if pstv is a non-negative constant) 2239263509Sdim// 2240263509Sdim// sqrt, sqrtf, sqrtl: 2241263509Sdim// * sqrt(expN(x)) -> expN(x*0.5) 2242263509Sdim// * sqrt(Nroot(x)) -> pow(x,1/(2*N)) 2243263509Sdim// * sqrt(pow(x,y)) -> pow(|x|,y*0.5) 2244263509Sdim// 2245263509Sdim// strchr: 2246263509Sdim// * strchr(p, 0) -> strlen(p) 2247263509Sdim// tan, tanf, tanl: 2248263509Sdim// * tan(atan(x)) -> x 2249263509Sdim// 2250263509Sdim// trunc, truncf, truncl: 2251263509Sdim// * trunc(cnst) -> cnst' 2252263509Sdim// 2253263509Sdim// 2254