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" 18249423Sdim#include "llvm/ADT/SmallString.h" 19243789Sdim#include "llvm/ADT/StringMap.h" 20263508Sdim#include "llvm/ADT/Triple.h" 21243789Sdim#include "llvm/Analysis/ValueTracking.h" 22249423Sdim#include "llvm/IR/DataLayout.h" 23249423Sdim#include "llvm/IR/Function.h" 24249423Sdim#include "llvm/IR/IRBuilder.h" 25249423Sdim#include "llvm/IR/IntrinsicInst.h" 26249423Sdim#include "llvm/IR/Intrinsics.h" 27249423Sdim#include "llvm/IR/LLVMContext.h" 28249423Sdim#include "llvm/IR/Module.h" 29249423Sdim#include "llvm/Support/Allocator.h" 30263508Sdim#include "llvm/Support/CommandLine.h" 31243789Sdim#include "llvm/Target/TargetLibraryInfo.h" 32243789Sdim#include "llvm/Transforms/Utils/BuildLibCalls.h" 33243789Sdim 34243789Sdimusing namespace llvm; 35243789Sdim 36263508Sdimstatic cl::opt<bool> 37263508SdimColdErrorCalls("error-reporting-is-cold", cl::init(true), 38263508Sdim cl::Hidden, cl::desc("Treat error-reporting calls as cold")); 39263508Sdim 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 62249423Sdim /// ignoreCallingConv - Returns false if this transformation could possibly 63249423Sdim /// change the calling convention. 64249423Sdim virtual bool ignoreCallingConv() { return false; } 65249423Sdim 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. 77249423Sdim 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 118249423Sdimstatic bool callHasFloatingPointArgument(const CallInst *CI) { 119249423Sdim for (CallInst::const_op_iterator it = CI->op_begin(), e = CI->op_end(); 120249423Sdim it != e; ++it) { 121249423Sdim if ((*it)->getType()->isFloatingPointTy()) 122249423Sdim return true; 123249423Sdim } 124249423Sdim return false; 125249423Sdim} 126249423Sdim 127263508Sdim/// \brief Check whether the overloaded unary floating point function 128263508Sdim/// corresponing to \a Ty is available. 129263508Sdimstatic bool hasUnaryFloatFn(const TargetLibraryInfo *TLI, Type *Ty, 130263508Sdim LibFunc::Func DoubleFn, LibFunc::Func FloatFn, 131263508Sdim LibFunc::Func LongDoubleFn) { 132263508Sdim switch (Ty->getTypeID()) { 133263508Sdim case Type::FloatTyID: 134263508Sdim return TLI->has(FloatFn); 135263508Sdim case Type::DoubleTyID: 136263508Sdim return TLI->has(DoubleFn); 137263508Sdim default: 138263508Sdim return TLI->has(LongDoubleFn); 139263508Sdim } 140263508Sdim} 141263508Sdim 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). 501263508Sdim 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. 537263508Sdim 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 { 755249423Sdim 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); 798263508Sdim 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. 824249423Sdim 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) { 936263508Sdim 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; 993249423Sdim // Fold the memcmp and normalize the result. This way we get consistent 994249423Sdim // results across multiple platforms. 995249423Sdim uint64_t Ret = 0; 996249423Sdim int Cmp = memcmp(LHSStr.data(), RHSStr.data(), Len); 997249423Sdim if (Cmp < 0) 998249423Sdim Ret = -1; 999249423Sdim else if (Cmp > 0) 1000249423Sdim 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() || 1055263508Sdim 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 1065249423Sdim//===----------------------------------------------------------------------===// 1066249423Sdim// Math Library Optimizations 1067249423Sdim//===----------------------------------------------------------------------===// 1068249423Sdim 1069249423Sdim//===----------------------------------------------------------------------===// 1070249423Sdim// Double -> Float Shrinking Optimizations for Unary Functions like 'floor' 1071249423Sdim 1072249423Sdimstruct UnaryDoubleFPOpt : public LibCallOptimization { 1073249423Sdim bool CheckRetType; 1074249423Sdim UnaryDoubleFPOpt(bool CheckReturnType): CheckRetType(CheckReturnType) {} 1075249423Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1076249423Sdim FunctionType *FT = Callee->getFunctionType(); 1077249423Sdim if (FT->getNumParams() != 1 || !FT->getReturnType()->isDoubleTy() || 1078249423Sdim !FT->getParamType(0)->isDoubleTy()) 1079249423Sdim return 0; 1080249423Sdim 1081249423Sdim if (CheckRetType) { 1082249423Sdim // Check if all the uses for function like 'sin' are converted to float. 1083249423Sdim for (Value::use_iterator UseI = CI->use_begin(); UseI != CI->use_end(); 1084249423Sdim ++UseI) { 1085249423Sdim FPTruncInst *Cast = dyn_cast<FPTruncInst>(*UseI); 1086249423Sdim if (Cast == 0 || !Cast->getType()->isFloatTy()) 1087249423Sdim return 0; 1088249423Sdim } 1089249423Sdim } 1090249423Sdim 1091249423Sdim // If this is something like 'floor((double)floatval)', convert to floorf. 1092249423Sdim FPExtInst *Cast = dyn_cast<FPExtInst>(CI->getArgOperand(0)); 1093249423Sdim if (Cast == 0 || !Cast->getOperand(0)->getType()->isFloatTy()) 1094249423Sdim return 0; 1095249423Sdim 1096249423Sdim // floor((double)floatval) -> (double)floorf(floatval) 1097249423Sdim Value *V = Cast->getOperand(0); 1098249423Sdim V = EmitUnaryFloatFnCall(V, Callee->getName(), B, Callee->getAttributes()); 1099249423Sdim return B.CreateFPExt(V, B.getDoubleTy()); 1100249423Sdim } 1101249423Sdim}; 1102249423Sdim 1103249423Sdimstruct UnsafeFPLibCallOptimization : public LibCallOptimization { 1104249423Sdim bool UnsafeFPShrink; 1105249423Sdim UnsafeFPLibCallOptimization(bool UnsafeFPShrink) { 1106249423Sdim this->UnsafeFPShrink = UnsafeFPShrink; 1107249423Sdim } 1108249423Sdim}; 1109249423Sdim 1110249423Sdimstruct CosOpt : public UnsafeFPLibCallOptimization { 1111249423Sdim CosOpt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {} 1112249423Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1113249423Sdim Value *Ret = NULL; 1114249423Sdim if (UnsafeFPShrink && Callee->getName() == "cos" && 1115249423Sdim TLI->has(LibFunc::cosf)) { 1116249423Sdim UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 1117249423Sdim Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B); 1118249423Sdim } 1119249423Sdim 1120249423Sdim FunctionType *FT = Callee->getFunctionType(); 1121249423Sdim // Just make sure this has 1 argument of FP type, which matches the 1122249423Sdim // result type. 1123249423Sdim if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) || 1124249423Sdim !FT->getParamType(0)->isFloatingPointTy()) 1125249423Sdim return Ret; 1126249423Sdim 1127249423Sdim // cos(-x) -> cos(x) 1128249423Sdim Value *Op1 = CI->getArgOperand(0); 1129249423Sdim if (BinaryOperator::isFNeg(Op1)) { 1130249423Sdim BinaryOperator *BinExpr = cast<BinaryOperator>(Op1); 1131249423Sdim return B.CreateCall(Callee, BinExpr->getOperand(1), "cos"); 1132249423Sdim } 1133249423Sdim return Ret; 1134249423Sdim } 1135249423Sdim}; 1136249423Sdim 1137249423Sdimstruct PowOpt : public UnsafeFPLibCallOptimization { 1138249423Sdim PowOpt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {} 1139249423Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1140249423Sdim Value *Ret = NULL; 1141249423Sdim if (UnsafeFPShrink && Callee->getName() == "pow" && 1142249423Sdim TLI->has(LibFunc::powf)) { 1143249423Sdim UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 1144249423Sdim Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B); 1145249423Sdim } 1146249423Sdim 1147249423Sdim FunctionType *FT = Callee->getFunctionType(); 1148249423Sdim // Just make sure this has 2 arguments of the same FP type, which match the 1149249423Sdim // result type. 1150249423Sdim if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) || 1151249423Sdim FT->getParamType(0) != FT->getParamType(1) || 1152249423Sdim !FT->getParamType(0)->isFloatingPointTy()) 1153249423Sdim return Ret; 1154249423Sdim 1155249423Sdim Value *Op1 = CI->getArgOperand(0), *Op2 = CI->getArgOperand(1); 1156249423Sdim if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1)) { 1157263508Sdim // pow(1.0, x) -> 1.0 1158263508Sdim if (Op1C->isExactlyValue(1.0)) 1159249423Sdim return Op1C; 1160263508Sdim // pow(2.0, x) -> exp2(x) 1161263508Sdim if (Op1C->isExactlyValue(2.0) && 1162263508Sdim hasUnaryFloatFn(TLI, Op1->getType(), LibFunc::exp2, LibFunc::exp2f, 1163263508Sdim LibFunc::exp2l)) 1164249423Sdim return EmitUnaryFloatFnCall(Op2, "exp2", B, Callee->getAttributes()); 1165249423Sdim } 1166249423Sdim 1167249423Sdim ConstantFP *Op2C = dyn_cast<ConstantFP>(Op2); 1168249423Sdim if (Op2C == 0) return Ret; 1169249423Sdim 1170249423Sdim if (Op2C->getValueAPF().isZero()) // pow(x, 0.0) -> 1.0 1171249423Sdim return ConstantFP::get(CI->getType(), 1.0); 1172249423Sdim 1173263508Sdim if (Op2C->isExactlyValue(0.5) && 1174263508Sdim hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::sqrt, LibFunc::sqrtf, 1175263508Sdim LibFunc::sqrtl) && 1176263508Sdim hasUnaryFloatFn(TLI, Op2->getType(), LibFunc::fabs, LibFunc::fabsf, 1177263508Sdim LibFunc::fabsl)) { 1178249423Sdim // Expand pow(x, 0.5) to (x == -infinity ? +infinity : fabs(sqrt(x))). 1179249423Sdim // This is faster than calling pow, and still handles negative zero 1180249423Sdim // and negative infinity correctly. 1181249423Sdim // TODO: In fast-math mode, this could be just sqrt(x). 1182249423Sdim // TODO: In finite-only mode, this could be just fabs(sqrt(x)). 1183249423Sdim Value *Inf = ConstantFP::getInfinity(CI->getType()); 1184249423Sdim Value *NegInf = ConstantFP::getInfinity(CI->getType(), true); 1185249423Sdim Value *Sqrt = EmitUnaryFloatFnCall(Op1, "sqrt", B, 1186249423Sdim Callee->getAttributes()); 1187249423Sdim Value *FAbs = EmitUnaryFloatFnCall(Sqrt, "fabs", B, 1188249423Sdim Callee->getAttributes()); 1189249423Sdim Value *FCmp = B.CreateFCmpOEQ(Op1, NegInf); 1190249423Sdim Value *Sel = B.CreateSelect(FCmp, Inf, FAbs); 1191249423Sdim return Sel; 1192249423Sdim } 1193249423Sdim 1194249423Sdim if (Op2C->isExactlyValue(1.0)) // pow(x, 1.0) -> x 1195249423Sdim return Op1; 1196249423Sdim if (Op2C->isExactlyValue(2.0)) // pow(x, 2.0) -> x*x 1197249423Sdim return B.CreateFMul(Op1, Op1, "pow2"); 1198249423Sdim if (Op2C->isExactlyValue(-1.0)) // pow(x, -1.0) -> 1.0/x 1199249423Sdim return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0), 1200249423Sdim Op1, "powrecip"); 1201249423Sdim return 0; 1202249423Sdim } 1203249423Sdim}; 1204249423Sdim 1205249423Sdimstruct Exp2Opt : public UnsafeFPLibCallOptimization { 1206249423Sdim Exp2Opt(bool UnsafeFPShrink) : UnsafeFPLibCallOptimization(UnsafeFPShrink) {} 1207249423Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1208249423Sdim Value *Ret = NULL; 1209249423Sdim if (UnsafeFPShrink && Callee->getName() == "exp2" && 1210263508Sdim TLI->has(LibFunc::exp2f)) { 1211249423Sdim UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 1212249423Sdim Ret = UnsafeUnaryDoubleFP.callOptimizer(Callee, CI, B); 1213249423Sdim } 1214249423Sdim 1215249423Sdim FunctionType *FT = Callee->getFunctionType(); 1216249423Sdim // Just make sure this has 1 argument of FP type, which matches the 1217249423Sdim // result type. 1218249423Sdim if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) || 1219249423Sdim !FT->getParamType(0)->isFloatingPointTy()) 1220249423Sdim return Ret; 1221249423Sdim 1222249423Sdim Value *Op = CI->getArgOperand(0); 1223249423Sdim // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x)) if sizeof(x) <= 32 1224249423Sdim // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < 32 1225249423Sdim Value *LdExpArg = 0; 1226249423Sdim if (SIToFPInst *OpC = dyn_cast<SIToFPInst>(Op)) { 1227249423Sdim if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() <= 32) 1228249423Sdim LdExpArg = B.CreateSExt(OpC->getOperand(0), B.getInt32Ty()); 1229249423Sdim } else if (UIToFPInst *OpC = dyn_cast<UIToFPInst>(Op)) { 1230249423Sdim if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() < 32) 1231249423Sdim LdExpArg = B.CreateZExt(OpC->getOperand(0), B.getInt32Ty()); 1232249423Sdim } 1233249423Sdim 1234249423Sdim if (LdExpArg) { 1235249423Sdim const char *Name; 1236249423Sdim if (Op->getType()->isFloatTy()) 1237249423Sdim Name = "ldexpf"; 1238249423Sdim else if (Op->getType()->isDoubleTy()) 1239249423Sdim Name = "ldexp"; 1240249423Sdim else 1241249423Sdim Name = "ldexpl"; 1242249423Sdim 1243249423Sdim Constant *One = ConstantFP::get(*Context, APFloat(1.0f)); 1244249423Sdim if (!Op->getType()->isFloatTy()) 1245249423Sdim One = ConstantExpr::getFPExtend(One, Op->getType()); 1246249423Sdim 1247249423Sdim Module *M = Caller->getParent(); 1248249423Sdim Value *Callee = M->getOrInsertFunction(Name, Op->getType(), 1249249423Sdim Op->getType(), 1250249423Sdim B.getInt32Ty(), NULL); 1251249423Sdim CallInst *CI = B.CreateCall2(Callee, One, LdExpArg); 1252249423Sdim if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) 1253249423Sdim CI->setCallingConv(F->getCallingConv()); 1254249423Sdim 1255249423Sdim return CI; 1256249423Sdim } 1257249423Sdim return Ret; 1258249423Sdim } 1259249423Sdim}; 1260249423Sdim 1261263508Sdimstruct SinCosPiOpt : public LibCallOptimization { 1262263508Sdim SinCosPiOpt() {} 1263263508Sdim 1264263508Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1265263508Sdim // Make sure the prototype is as expected, otherwise the rest of the 1266263508Sdim // function is probably invalid and likely to abort. 1267263508Sdim if (!isTrigLibCall(CI)) 1268263508Sdim return 0; 1269263508Sdim 1270263508Sdim Value *Arg = CI->getArgOperand(0); 1271263508Sdim SmallVector<CallInst *, 1> SinCalls; 1272263508Sdim SmallVector<CallInst *, 1> CosCalls; 1273263508Sdim SmallVector<CallInst *, 1> SinCosCalls; 1274263508Sdim 1275263508Sdim bool IsFloat = Arg->getType()->isFloatTy(); 1276263508Sdim 1277263508Sdim // Look for all compatible sinpi, cospi and sincospi calls with the same 1278263508Sdim // argument. If there are enough (in some sense) we can make the 1279263508Sdim // substitution. 1280263508Sdim for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end(); 1281263508Sdim UI != UE; ++UI) 1282263508Sdim classifyArgUse(*UI, CI->getParent(), IsFloat, SinCalls, CosCalls, 1283263508Sdim SinCosCalls); 1284263508Sdim 1285263508Sdim // It's only worthwhile if both sinpi and cospi are actually used. 1286263508Sdim if (SinCosCalls.empty() && (SinCalls.empty() || CosCalls.empty())) 1287263508Sdim return 0; 1288263508Sdim 1289263508Sdim Value *Sin, *Cos, *SinCos; 1290263508Sdim insertSinCosCall(B, CI->getCalledFunction(), Arg, IsFloat, Sin, Cos, 1291263508Sdim SinCos); 1292263508Sdim 1293263508Sdim replaceTrigInsts(SinCalls, Sin); 1294263508Sdim replaceTrigInsts(CosCalls, Cos); 1295263508Sdim replaceTrigInsts(SinCosCalls, SinCos); 1296263508Sdim 1297263508Sdim return 0; 1298263508Sdim } 1299263508Sdim 1300263508Sdim bool isTrigLibCall(CallInst *CI) { 1301263508Sdim Function *Callee = CI->getCalledFunction(); 1302263508Sdim FunctionType *FT = Callee->getFunctionType(); 1303263508Sdim 1304263508Sdim // We can only hope to do anything useful if we can ignore things like errno 1305263508Sdim // and floating-point exceptions. 1306263508Sdim bool AttributesSafe = CI->hasFnAttr(Attribute::NoUnwind) && 1307263508Sdim CI->hasFnAttr(Attribute::ReadNone); 1308263508Sdim 1309263508Sdim // Other than that we need float(float) or double(double) 1310263508Sdim return AttributesSafe && FT->getNumParams() == 1 && 1311263508Sdim FT->getReturnType() == FT->getParamType(0) && 1312263508Sdim (FT->getParamType(0)->isFloatTy() || 1313263508Sdim FT->getParamType(0)->isDoubleTy()); 1314263508Sdim } 1315263508Sdim 1316263508Sdim void classifyArgUse(Value *Val, BasicBlock *BB, bool IsFloat, 1317263508Sdim SmallVectorImpl<CallInst *> &SinCalls, 1318263508Sdim SmallVectorImpl<CallInst *> &CosCalls, 1319263508Sdim SmallVectorImpl<CallInst *> &SinCosCalls) { 1320263508Sdim CallInst *CI = dyn_cast<CallInst>(Val); 1321263508Sdim 1322263508Sdim if (!CI) 1323263508Sdim return; 1324263508Sdim 1325263508Sdim Function *Callee = CI->getCalledFunction(); 1326263508Sdim StringRef FuncName = Callee->getName(); 1327263508Sdim LibFunc::Func Func; 1328263508Sdim if (!TLI->getLibFunc(FuncName, Func) || !TLI->has(Func) || 1329263508Sdim !isTrigLibCall(CI)) 1330263508Sdim return; 1331263508Sdim 1332263508Sdim if (IsFloat) { 1333263508Sdim if (Func == LibFunc::sinpif) 1334263508Sdim SinCalls.push_back(CI); 1335263508Sdim else if (Func == LibFunc::cospif) 1336263508Sdim CosCalls.push_back(CI); 1337263508Sdim else if (Func == LibFunc::sincospi_stretf) 1338263508Sdim SinCosCalls.push_back(CI); 1339263508Sdim } else { 1340263508Sdim if (Func == LibFunc::sinpi) 1341263508Sdim SinCalls.push_back(CI); 1342263508Sdim else if (Func == LibFunc::cospi) 1343263508Sdim CosCalls.push_back(CI); 1344263508Sdim else if (Func == LibFunc::sincospi_stret) 1345263508Sdim SinCosCalls.push_back(CI); 1346263508Sdim } 1347263508Sdim } 1348263508Sdim 1349263508Sdim void replaceTrigInsts(SmallVectorImpl<CallInst*> &Calls, Value *Res) { 1350263508Sdim for (SmallVectorImpl<CallInst*>::iterator I = Calls.begin(), 1351263508Sdim E = Calls.end(); 1352263508Sdim I != E; ++I) { 1353263508Sdim LCS->replaceAllUsesWith(*I, Res); 1354263508Sdim } 1355263508Sdim } 1356263508Sdim 1357263508Sdim void insertSinCosCall(IRBuilder<> &B, Function *OrigCallee, Value *Arg, 1358263508Sdim bool UseFloat, Value *&Sin, Value *&Cos, 1359263508Sdim Value *&SinCos) { 1360263508Sdim Type *ArgTy = Arg->getType(); 1361263508Sdim Type *ResTy; 1362263508Sdim StringRef Name; 1363263508Sdim 1364263508Sdim Triple T(OrigCallee->getParent()->getTargetTriple()); 1365263508Sdim if (UseFloat) { 1366263508Sdim Name = "__sincospi_stretf"; 1367263508Sdim 1368263508Sdim assert(T.getArch() != Triple::x86 && "x86 messy and unsupported for now"); 1369263508Sdim // x86_64 can't use {float, float} since that would be returned in both 1370263508Sdim // xmm0 and xmm1, which isn't what a real struct would do. 1371263508Sdim ResTy = T.getArch() == Triple::x86_64 1372263508Sdim ? static_cast<Type *>(VectorType::get(ArgTy, 2)) 1373263508Sdim : static_cast<Type *>(StructType::get(ArgTy, ArgTy, NULL)); 1374263508Sdim } else { 1375263508Sdim Name = "__sincospi_stret"; 1376263508Sdim ResTy = StructType::get(ArgTy, ArgTy, NULL); 1377263508Sdim } 1378263508Sdim 1379263508Sdim Module *M = OrigCallee->getParent(); 1380263508Sdim Value *Callee = M->getOrInsertFunction(Name, OrigCallee->getAttributes(), 1381263508Sdim ResTy, ArgTy, NULL); 1382263508Sdim 1383263508Sdim if (Instruction *ArgInst = dyn_cast<Instruction>(Arg)) { 1384263508Sdim // If the argument is an instruction, it must dominate all uses so put our 1385263508Sdim // sincos call there. 1386263508Sdim BasicBlock::iterator Loc = ArgInst; 1387263508Sdim B.SetInsertPoint(ArgInst->getParent(), ++Loc); 1388263508Sdim } else { 1389263508Sdim // Otherwise (e.g. for a constant) the beginning of the function is as 1390263508Sdim // good a place as any. 1391263508Sdim BasicBlock &EntryBB = B.GetInsertBlock()->getParent()->getEntryBlock(); 1392263508Sdim B.SetInsertPoint(&EntryBB, EntryBB.begin()); 1393263508Sdim } 1394263508Sdim 1395263508Sdim SinCos = B.CreateCall(Callee, Arg, "sincospi"); 1396263508Sdim 1397263508Sdim if (SinCos->getType()->isStructTy()) { 1398263508Sdim Sin = B.CreateExtractValue(SinCos, 0, "sinpi"); 1399263508Sdim Cos = B.CreateExtractValue(SinCos, 1, "cospi"); 1400263508Sdim } else { 1401263508Sdim Sin = B.CreateExtractElement(SinCos, ConstantInt::get(B.getInt32Ty(), 0), 1402263508Sdim "sinpi"); 1403263508Sdim Cos = B.CreateExtractElement(SinCos, ConstantInt::get(B.getInt32Ty(), 1), 1404263508Sdim "cospi"); 1405263508Sdim } 1406263508Sdim } 1407263508Sdim 1408263508Sdim}; 1409263508Sdim 1410249423Sdim//===----------------------------------------------------------------------===// 1411249423Sdim// Integer Library Call Optimizations 1412249423Sdim//===----------------------------------------------------------------------===// 1413249423Sdim 1414249423Sdimstruct FFSOpt : public LibCallOptimization { 1415249423Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1416249423Sdim FunctionType *FT = Callee->getFunctionType(); 1417249423Sdim // Just make sure this has 2 arguments of the same FP type, which match the 1418249423Sdim // result type. 1419249423Sdim if (FT->getNumParams() != 1 || 1420249423Sdim !FT->getReturnType()->isIntegerTy(32) || 1421249423Sdim !FT->getParamType(0)->isIntegerTy()) 1422249423Sdim return 0; 1423249423Sdim 1424249423Sdim Value *Op = CI->getArgOperand(0); 1425249423Sdim 1426249423Sdim // Constant fold. 1427249423Sdim if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) { 1428249423Sdim if (CI->isZero()) // ffs(0) -> 0. 1429249423Sdim return B.getInt32(0); 1430249423Sdim // ffs(c) -> cttz(c)+1 1431249423Sdim return B.getInt32(CI->getValue().countTrailingZeros() + 1); 1432249423Sdim } 1433249423Sdim 1434249423Sdim // ffs(x) -> x != 0 ? (i32)llvm.cttz(x)+1 : 0 1435249423Sdim Type *ArgType = Op->getType(); 1436249423Sdim Value *F = Intrinsic::getDeclaration(Callee->getParent(), 1437249423Sdim Intrinsic::cttz, ArgType); 1438249423Sdim Value *V = B.CreateCall2(F, Op, B.getFalse(), "cttz"); 1439249423Sdim V = B.CreateAdd(V, ConstantInt::get(V->getType(), 1)); 1440249423Sdim V = B.CreateIntCast(V, B.getInt32Ty(), false); 1441249423Sdim 1442249423Sdim Value *Cond = B.CreateICmpNE(Op, Constant::getNullValue(ArgType)); 1443249423Sdim return B.CreateSelect(Cond, V, B.getInt32(0)); 1444249423Sdim } 1445249423Sdim}; 1446249423Sdim 1447249423Sdimstruct AbsOpt : public LibCallOptimization { 1448249423Sdim virtual bool ignoreCallingConv() { return true; } 1449249423Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1450249423Sdim FunctionType *FT = Callee->getFunctionType(); 1451249423Sdim // We require integer(integer) where the types agree. 1452249423Sdim if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() || 1453249423Sdim FT->getParamType(0) != FT->getReturnType()) 1454249423Sdim return 0; 1455249423Sdim 1456249423Sdim // abs(x) -> x >s -1 ? x : -x 1457249423Sdim Value *Op = CI->getArgOperand(0); 1458249423Sdim Value *Pos = B.CreateICmpSGT(Op, Constant::getAllOnesValue(Op->getType()), 1459249423Sdim "ispos"); 1460249423Sdim Value *Neg = B.CreateNeg(Op, "neg"); 1461249423Sdim return B.CreateSelect(Pos, Op, Neg); 1462249423Sdim } 1463249423Sdim}; 1464249423Sdim 1465249423Sdimstruct IsDigitOpt : public LibCallOptimization { 1466249423Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1467249423Sdim FunctionType *FT = Callee->getFunctionType(); 1468249423Sdim // We require integer(i32) 1469249423Sdim if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() || 1470249423Sdim !FT->getParamType(0)->isIntegerTy(32)) 1471249423Sdim return 0; 1472249423Sdim 1473249423Sdim // isdigit(c) -> (c-'0') <u 10 1474249423Sdim Value *Op = CI->getArgOperand(0); 1475249423Sdim Op = B.CreateSub(Op, B.getInt32('0'), "isdigittmp"); 1476249423Sdim Op = B.CreateICmpULT(Op, B.getInt32(10), "isdigit"); 1477249423Sdim return B.CreateZExt(Op, CI->getType()); 1478249423Sdim } 1479249423Sdim}; 1480249423Sdim 1481249423Sdimstruct IsAsciiOpt : public LibCallOptimization { 1482249423Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1483249423Sdim FunctionType *FT = Callee->getFunctionType(); 1484249423Sdim // We require integer(i32) 1485249423Sdim if (FT->getNumParams() != 1 || !FT->getReturnType()->isIntegerTy() || 1486249423Sdim !FT->getParamType(0)->isIntegerTy(32)) 1487249423Sdim return 0; 1488249423Sdim 1489249423Sdim // isascii(c) -> c <u 128 1490249423Sdim Value *Op = CI->getArgOperand(0); 1491249423Sdim Op = B.CreateICmpULT(Op, B.getInt32(128), "isascii"); 1492249423Sdim return B.CreateZExt(Op, CI->getType()); 1493249423Sdim } 1494249423Sdim}; 1495249423Sdim 1496249423Sdimstruct ToAsciiOpt : public LibCallOptimization { 1497249423Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1498249423Sdim FunctionType *FT = Callee->getFunctionType(); 1499249423Sdim // We require i32(i32) 1500249423Sdim if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) || 1501249423Sdim !FT->getParamType(0)->isIntegerTy(32)) 1502249423Sdim return 0; 1503249423Sdim 1504249423Sdim // toascii(c) -> c & 0x7f 1505249423Sdim return B.CreateAnd(CI->getArgOperand(0), 1506249423Sdim ConstantInt::get(CI->getType(),0x7F)); 1507249423Sdim } 1508249423Sdim}; 1509249423Sdim 1510249423Sdim//===----------------------------------------------------------------------===// 1511249423Sdim// Formatting and IO Library Call Optimizations 1512249423Sdim//===----------------------------------------------------------------------===// 1513249423Sdim 1514263508Sdimstruct ErrorReportingOpt : public LibCallOptimization { 1515263508Sdim ErrorReportingOpt(int S = -1) : StreamArg(S) {} 1516263508Sdim 1517263508Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &) { 1518263508Sdim // Error reporting calls should be cold, mark them as such. 1519263508Sdim // This applies even to non-builtin calls: it is only a hint and applies to 1520263508Sdim // functions that the frontend might not understand as builtins. 1521263508Sdim 1522263508Sdim // This heuristic was suggested in: 1523263508Sdim // Improving Static Branch Prediction in a Compiler 1524263508Sdim // Brian L. Deitrich, Ben-Chung Cheng, Wen-mei W. Hwu 1525263508Sdim // Proceedings of PACT'98, Oct. 1998, IEEE 1526263508Sdim 1527263508Sdim if (!CI->hasFnAttr(Attribute::Cold) && isReportingError(Callee, CI)) { 1528263508Sdim CI->addAttribute(AttributeSet::FunctionIndex, Attribute::Cold); 1529263508Sdim } 1530263508Sdim 1531263508Sdim return 0; 1532263508Sdim } 1533263508Sdim 1534263508Sdimprotected: 1535263508Sdim bool isReportingError(Function *Callee, CallInst *CI) { 1536263508Sdim if (!ColdErrorCalls) 1537263508Sdim return false; 1538263508Sdim 1539263508Sdim if (!Callee || !Callee->isDeclaration()) 1540263508Sdim return false; 1541263508Sdim 1542263508Sdim if (StreamArg < 0) 1543263508Sdim return true; 1544263508Sdim 1545263508Sdim // These functions might be considered cold, but only if their stream 1546263508Sdim // argument is stderr. 1547263508Sdim 1548263508Sdim if (StreamArg >= (int) CI->getNumArgOperands()) 1549263508Sdim return false; 1550263508Sdim LoadInst *LI = dyn_cast<LoadInst>(CI->getArgOperand(StreamArg)); 1551263508Sdim if (!LI) 1552263508Sdim return false; 1553263508Sdim GlobalVariable *GV = dyn_cast<GlobalVariable>(LI->getPointerOperand()); 1554263508Sdim if (!GV || !GV->isDeclaration()) 1555263508Sdim return false; 1556263508Sdim return GV->getName() == "stderr"; 1557263508Sdim } 1558263508Sdim 1559263508Sdim int StreamArg; 1560263508Sdim}; 1561263508Sdim 1562249423Sdimstruct PrintFOpt : public LibCallOptimization { 1563249423Sdim Value *optimizeFixedFormatString(Function *Callee, CallInst *CI, 1564249423Sdim IRBuilder<> &B) { 1565249423Sdim // Check for a fixed format string. 1566249423Sdim StringRef FormatStr; 1567249423Sdim if (!getConstantStringInfo(CI->getArgOperand(0), FormatStr)) 1568249423Sdim return 0; 1569249423Sdim 1570249423Sdim // Empty format string -> noop. 1571249423Sdim if (FormatStr.empty()) // Tolerate printf's declared void. 1572249423Sdim return CI->use_empty() ? (Value*)CI : 1573249423Sdim ConstantInt::get(CI->getType(), 0); 1574249423Sdim 1575249423Sdim // Do not do any of the following transformations if the printf return value 1576249423Sdim // is used, in general the printf return value is not compatible with either 1577249423Sdim // putchar() or puts(). 1578249423Sdim if (!CI->use_empty()) 1579249423Sdim return 0; 1580249423Sdim 1581249423Sdim // printf("x") -> putchar('x'), even for '%'. 1582249423Sdim if (FormatStr.size() == 1) { 1583249423Sdim Value *Res = EmitPutChar(B.getInt32(FormatStr[0]), B, TD, TLI); 1584249423Sdim if (CI->use_empty() || !Res) return Res; 1585249423Sdim return B.CreateIntCast(Res, CI->getType(), true); 1586249423Sdim } 1587249423Sdim 1588249423Sdim // printf("foo\n") --> puts("foo") 1589249423Sdim if (FormatStr[FormatStr.size()-1] == '\n' && 1590263508Sdim FormatStr.find('%') == StringRef::npos) { // No format characters. 1591249423Sdim // Create a string literal with no \n on it. We expect the constant merge 1592249423Sdim // pass to be run after this pass, to merge duplicate strings. 1593249423Sdim FormatStr = FormatStr.drop_back(); 1594249423Sdim Value *GV = B.CreateGlobalString(FormatStr, "str"); 1595249423Sdim Value *NewCI = EmitPutS(GV, B, TD, TLI); 1596249423Sdim return (CI->use_empty() || !NewCI) ? 1597249423Sdim NewCI : 1598249423Sdim ConstantInt::get(CI->getType(), FormatStr.size()+1); 1599249423Sdim } 1600249423Sdim 1601249423Sdim // Optimize specific format strings. 1602249423Sdim // printf("%c", chr) --> putchar(chr) 1603249423Sdim if (FormatStr == "%c" && CI->getNumArgOperands() > 1 && 1604249423Sdim CI->getArgOperand(1)->getType()->isIntegerTy()) { 1605249423Sdim Value *Res = EmitPutChar(CI->getArgOperand(1), B, TD, TLI); 1606249423Sdim 1607249423Sdim if (CI->use_empty() || !Res) return Res; 1608249423Sdim return B.CreateIntCast(Res, CI->getType(), true); 1609249423Sdim } 1610249423Sdim 1611249423Sdim // printf("%s\n", str) --> puts(str) 1612249423Sdim if (FormatStr == "%s\n" && CI->getNumArgOperands() > 1 && 1613249423Sdim CI->getArgOperand(1)->getType()->isPointerTy()) { 1614249423Sdim return EmitPutS(CI->getArgOperand(1), B, TD, TLI); 1615249423Sdim } 1616249423Sdim return 0; 1617249423Sdim } 1618249423Sdim 1619249423Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1620249423Sdim // Require one fixed pointer argument and an integer/void result. 1621249423Sdim FunctionType *FT = Callee->getFunctionType(); 1622249423Sdim if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() || 1623249423Sdim !(FT->getReturnType()->isIntegerTy() || 1624249423Sdim FT->getReturnType()->isVoidTy())) 1625249423Sdim return 0; 1626249423Sdim 1627249423Sdim if (Value *V = optimizeFixedFormatString(Callee, CI, B)) { 1628249423Sdim return V; 1629249423Sdim } 1630249423Sdim 1631249423Sdim // printf(format, ...) -> iprintf(format, ...) if no floating point 1632249423Sdim // arguments. 1633249423Sdim if (TLI->has(LibFunc::iprintf) && !callHasFloatingPointArgument(CI)) { 1634249423Sdim Module *M = B.GetInsertBlock()->getParent()->getParent(); 1635249423Sdim Constant *IPrintFFn = 1636249423Sdim M->getOrInsertFunction("iprintf", FT, Callee->getAttributes()); 1637249423Sdim CallInst *New = cast<CallInst>(CI->clone()); 1638249423Sdim New->setCalledFunction(IPrintFFn); 1639249423Sdim B.Insert(New); 1640249423Sdim return New; 1641249423Sdim } 1642249423Sdim return 0; 1643249423Sdim } 1644249423Sdim}; 1645249423Sdim 1646249423Sdimstruct SPrintFOpt : public LibCallOptimization { 1647249423Sdim Value *OptimizeFixedFormatString(Function *Callee, CallInst *CI, 1648249423Sdim IRBuilder<> &B) { 1649249423Sdim // Check for a fixed format string. 1650249423Sdim StringRef FormatStr; 1651249423Sdim if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr)) 1652249423Sdim return 0; 1653249423Sdim 1654249423Sdim // If we just have a format string (nothing else crazy) transform it. 1655249423Sdim if (CI->getNumArgOperands() == 2) { 1656249423Sdim // Make sure there's no % in the constant array. We could try to handle 1657249423Sdim // %% -> % in the future if we cared. 1658249423Sdim for (unsigned i = 0, e = FormatStr.size(); i != e; ++i) 1659249423Sdim if (FormatStr[i] == '%') 1660249423Sdim return 0; // we found a format specifier, bail out. 1661249423Sdim 1662249423Sdim // These optimizations require DataLayout. 1663249423Sdim if (!TD) return 0; 1664249423Sdim 1665249423Sdim // sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1) 1666249423Sdim B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), 1667249423Sdim ConstantInt::get(TD->getIntPtrType(*Context), // Copy the 1668249423Sdim FormatStr.size() + 1), 1); // nul byte. 1669249423Sdim return ConstantInt::get(CI->getType(), FormatStr.size()); 1670249423Sdim } 1671249423Sdim 1672249423Sdim // The remaining optimizations require the format string to be "%s" or "%c" 1673249423Sdim // and have an extra operand. 1674249423Sdim if (FormatStr.size() != 2 || FormatStr[0] != '%' || 1675249423Sdim CI->getNumArgOperands() < 3) 1676249423Sdim return 0; 1677249423Sdim 1678249423Sdim // Decode the second character of the format string. 1679249423Sdim if (FormatStr[1] == 'c') { 1680249423Sdim // sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0 1681249423Sdim if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return 0; 1682249423Sdim Value *V = B.CreateTrunc(CI->getArgOperand(2), B.getInt8Ty(), "char"); 1683249423Sdim Value *Ptr = CastToCStr(CI->getArgOperand(0), B); 1684249423Sdim B.CreateStore(V, Ptr); 1685249423Sdim Ptr = B.CreateGEP(Ptr, B.getInt32(1), "nul"); 1686249423Sdim B.CreateStore(B.getInt8(0), Ptr); 1687249423Sdim 1688249423Sdim return ConstantInt::get(CI->getType(), 1); 1689249423Sdim } 1690249423Sdim 1691249423Sdim if (FormatStr[1] == 's') { 1692249423Sdim // These optimizations require DataLayout. 1693249423Sdim if (!TD) return 0; 1694249423Sdim 1695249423Sdim // sprintf(dest, "%s", str) -> llvm.memcpy(dest, str, strlen(str)+1, 1) 1696249423Sdim if (!CI->getArgOperand(2)->getType()->isPointerTy()) return 0; 1697249423Sdim 1698249423Sdim Value *Len = EmitStrLen(CI->getArgOperand(2), B, TD, TLI); 1699249423Sdim if (!Len) 1700249423Sdim return 0; 1701249423Sdim Value *IncLen = B.CreateAdd(Len, 1702249423Sdim ConstantInt::get(Len->getType(), 1), 1703249423Sdim "leninc"); 1704249423Sdim B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(2), IncLen, 1); 1705249423Sdim 1706249423Sdim // The sprintf result is the unincremented number of bytes in the string. 1707249423Sdim return B.CreateIntCast(Len, CI->getType(), false); 1708249423Sdim } 1709249423Sdim return 0; 1710249423Sdim } 1711249423Sdim 1712249423Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1713249423Sdim // Require two fixed pointer arguments and an integer result. 1714249423Sdim FunctionType *FT = Callee->getFunctionType(); 1715249423Sdim if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() || 1716249423Sdim !FT->getParamType(1)->isPointerTy() || 1717249423Sdim !FT->getReturnType()->isIntegerTy()) 1718249423Sdim return 0; 1719249423Sdim 1720249423Sdim if (Value *V = OptimizeFixedFormatString(Callee, CI, B)) { 1721249423Sdim return V; 1722249423Sdim } 1723249423Sdim 1724249423Sdim // sprintf(str, format, ...) -> siprintf(str, format, ...) if no floating 1725249423Sdim // point arguments. 1726249423Sdim if (TLI->has(LibFunc::siprintf) && !callHasFloatingPointArgument(CI)) { 1727249423Sdim Module *M = B.GetInsertBlock()->getParent()->getParent(); 1728249423Sdim Constant *SIPrintFFn = 1729249423Sdim M->getOrInsertFunction("siprintf", FT, Callee->getAttributes()); 1730249423Sdim CallInst *New = cast<CallInst>(CI->clone()); 1731249423Sdim New->setCalledFunction(SIPrintFFn); 1732249423Sdim B.Insert(New); 1733249423Sdim return New; 1734249423Sdim } 1735249423Sdim return 0; 1736249423Sdim } 1737249423Sdim}; 1738249423Sdim 1739249423Sdimstruct FPrintFOpt : public LibCallOptimization { 1740249423Sdim Value *optimizeFixedFormatString(Function *Callee, CallInst *CI, 1741249423Sdim IRBuilder<> &B) { 1742263508Sdim ErrorReportingOpt ER(/* StreamArg = */ 0); 1743263508Sdim (void) ER.callOptimizer(Callee, CI, B); 1744263508Sdim 1745249423Sdim // All the optimizations depend on the format string. 1746249423Sdim StringRef FormatStr; 1747249423Sdim if (!getConstantStringInfo(CI->getArgOperand(1), FormatStr)) 1748249423Sdim return 0; 1749249423Sdim 1750251662Sdim // Do not do any of the following transformations if the fprintf return 1751251662Sdim // value is used, in general the fprintf return value is not compatible 1752251662Sdim // with fwrite(), fputc() or fputs(). 1753251662Sdim if (!CI->use_empty()) 1754251662Sdim return 0; 1755251662Sdim 1756249423Sdim // fprintf(F, "foo") --> fwrite("foo", 3, 1, F) 1757249423Sdim if (CI->getNumArgOperands() == 2) { 1758249423Sdim for (unsigned i = 0, e = FormatStr.size(); i != e; ++i) 1759249423Sdim if (FormatStr[i] == '%') // Could handle %% -> % if we cared. 1760249423Sdim return 0; // We found a format specifier. 1761249423Sdim 1762249423Sdim // These optimizations require DataLayout. 1763249423Sdim if (!TD) return 0; 1764249423Sdim 1765251662Sdim return EmitFWrite(CI->getArgOperand(1), 1766251662Sdim ConstantInt::get(TD->getIntPtrType(*Context), 1767251662Sdim FormatStr.size()), 1768251662Sdim CI->getArgOperand(0), B, TD, TLI); 1769249423Sdim } 1770249423Sdim 1771249423Sdim // The remaining optimizations require the format string to be "%s" or "%c" 1772249423Sdim // and have an extra operand. 1773249423Sdim if (FormatStr.size() != 2 || FormatStr[0] != '%' || 1774249423Sdim CI->getNumArgOperands() < 3) 1775249423Sdim return 0; 1776249423Sdim 1777249423Sdim // Decode the second character of the format string. 1778249423Sdim if (FormatStr[1] == 'c') { 1779249423Sdim // fprintf(F, "%c", chr) --> fputc(chr, F) 1780249423Sdim if (!CI->getArgOperand(2)->getType()->isIntegerTy()) return 0; 1781251662Sdim return EmitFPutC(CI->getArgOperand(2), CI->getArgOperand(0), B, TD, TLI); 1782249423Sdim } 1783249423Sdim 1784249423Sdim if (FormatStr[1] == 's') { 1785249423Sdim // fprintf(F, "%s", str) --> fputs(str, F) 1786251662Sdim if (!CI->getArgOperand(2)->getType()->isPointerTy()) 1787249423Sdim return 0; 1788249423Sdim return EmitFPutS(CI->getArgOperand(2), CI->getArgOperand(0), B, TD, TLI); 1789249423Sdim } 1790249423Sdim return 0; 1791249423Sdim } 1792249423Sdim 1793249423Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1794249423Sdim // Require two fixed paramters as pointers and integer result. 1795249423Sdim FunctionType *FT = Callee->getFunctionType(); 1796249423Sdim if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() || 1797249423Sdim !FT->getParamType(1)->isPointerTy() || 1798249423Sdim !FT->getReturnType()->isIntegerTy()) 1799249423Sdim return 0; 1800249423Sdim 1801249423Sdim if (Value *V = optimizeFixedFormatString(Callee, CI, B)) { 1802249423Sdim return V; 1803249423Sdim } 1804249423Sdim 1805249423Sdim // fprintf(stream, format, ...) -> fiprintf(stream, format, ...) if no 1806249423Sdim // floating point arguments. 1807249423Sdim if (TLI->has(LibFunc::fiprintf) && !callHasFloatingPointArgument(CI)) { 1808249423Sdim Module *M = B.GetInsertBlock()->getParent()->getParent(); 1809249423Sdim Constant *FIPrintFFn = 1810249423Sdim M->getOrInsertFunction("fiprintf", FT, Callee->getAttributes()); 1811249423Sdim CallInst *New = cast<CallInst>(CI->clone()); 1812249423Sdim New->setCalledFunction(FIPrintFFn); 1813249423Sdim B.Insert(New); 1814249423Sdim return New; 1815249423Sdim } 1816249423Sdim return 0; 1817249423Sdim } 1818249423Sdim}; 1819249423Sdim 1820249423Sdimstruct FWriteOpt : public LibCallOptimization { 1821249423Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1822263508Sdim ErrorReportingOpt ER(/* StreamArg = */ 3); 1823263508Sdim (void) ER.callOptimizer(Callee, CI, B); 1824263508Sdim 1825249423Sdim // Require a pointer, an integer, an integer, a pointer, returning integer. 1826249423Sdim FunctionType *FT = Callee->getFunctionType(); 1827249423Sdim if (FT->getNumParams() != 4 || !FT->getParamType(0)->isPointerTy() || 1828249423Sdim !FT->getParamType(1)->isIntegerTy() || 1829249423Sdim !FT->getParamType(2)->isIntegerTy() || 1830249423Sdim !FT->getParamType(3)->isPointerTy() || 1831249423Sdim !FT->getReturnType()->isIntegerTy()) 1832249423Sdim return 0; 1833249423Sdim 1834249423Sdim // Get the element size and count. 1835249423Sdim ConstantInt *SizeC = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 1836249423Sdim ConstantInt *CountC = dyn_cast<ConstantInt>(CI->getArgOperand(2)); 1837249423Sdim if (!SizeC || !CountC) return 0; 1838249423Sdim uint64_t Bytes = SizeC->getZExtValue()*CountC->getZExtValue(); 1839249423Sdim 1840249423Sdim // If this is writing zero records, remove the call (it's a noop). 1841249423Sdim if (Bytes == 0) 1842249423Sdim return ConstantInt::get(CI->getType(), 0); 1843249423Sdim 1844249423Sdim // If this is writing one byte, turn it into fputc. 1845249423Sdim // This optimisation is only valid, if the return value is unused. 1846249423Sdim if (Bytes == 1 && CI->use_empty()) { // fwrite(S,1,1,F) -> fputc(S[0],F) 1847249423Sdim Value *Char = B.CreateLoad(CastToCStr(CI->getArgOperand(0), B), "char"); 1848249423Sdim Value *NewCI = EmitFPutC(Char, CI->getArgOperand(3), B, TD, TLI); 1849249423Sdim return NewCI ? ConstantInt::get(CI->getType(), 1) : 0; 1850249423Sdim } 1851249423Sdim 1852249423Sdim return 0; 1853249423Sdim } 1854249423Sdim}; 1855249423Sdim 1856249423Sdimstruct FPutsOpt : public LibCallOptimization { 1857249423Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1858263508Sdim ErrorReportingOpt ER(/* StreamArg = */ 1); 1859263508Sdim (void) ER.callOptimizer(Callee, CI, B); 1860263508Sdim 1861249423Sdim // These optimizations require DataLayout. 1862249423Sdim if (!TD) return 0; 1863249423Sdim 1864249423Sdim // Require two pointers. Also, we can't optimize if return value is used. 1865249423Sdim FunctionType *FT = Callee->getFunctionType(); 1866249423Sdim if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() || 1867249423Sdim !FT->getParamType(1)->isPointerTy() || 1868249423Sdim !CI->use_empty()) 1869249423Sdim return 0; 1870249423Sdim 1871249423Sdim // fputs(s,F) --> fwrite(s,1,strlen(s),F) 1872249423Sdim uint64_t Len = GetStringLength(CI->getArgOperand(0)); 1873249423Sdim if (!Len) return 0; 1874249423Sdim // Known to have no uses (see above). 1875249423Sdim return EmitFWrite(CI->getArgOperand(0), 1876249423Sdim ConstantInt::get(TD->getIntPtrType(*Context), Len-1), 1877249423Sdim CI->getArgOperand(1), B, TD, TLI); 1878249423Sdim } 1879249423Sdim}; 1880249423Sdim 1881249423Sdimstruct PutsOpt : public LibCallOptimization { 1882249423Sdim virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 1883249423Sdim // Require one fixed pointer argument and an integer/void result. 1884249423Sdim FunctionType *FT = Callee->getFunctionType(); 1885249423Sdim if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() || 1886249423Sdim !(FT->getReturnType()->isIntegerTy() || 1887249423Sdim FT->getReturnType()->isVoidTy())) 1888249423Sdim return 0; 1889249423Sdim 1890249423Sdim // Check for a constant string. 1891249423Sdim StringRef Str; 1892249423Sdim if (!getConstantStringInfo(CI->getArgOperand(0), Str)) 1893249423Sdim return 0; 1894249423Sdim 1895249423Sdim if (Str.empty() && CI->use_empty()) { 1896249423Sdim // puts("") -> putchar('\n') 1897249423Sdim Value *Res = EmitPutChar(B.getInt32('\n'), B, TD, TLI); 1898249423Sdim if (CI->use_empty() || !Res) return Res; 1899249423Sdim return B.CreateIntCast(Res, CI->getType(), true); 1900249423Sdim } 1901249423Sdim 1902249423Sdim return 0; 1903249423Sdim } 1904249423Sdim}; 1905249423Sdim 1906243789Sdim} // End anonymous namespace. 1907243789Sdim 1908243789Sdimnamespace llvm { 1909243789Sdim 1910243789Sdimclass LibCallSimplifierImpl { 1911243789Sdim const DataLayout *TD; 1912243789Sdim const TargetLibraryInfo *TLI; 1913243789Sdim const LibCallSimplifier *LCS; 1914249423Sdim bool UnsafeFPShrink; 1915243789Sdim 1916249423Sdim // Math library call optimizations. 1917249423Sdim CosOpt Cos; 1918249423Sdim PowOpt Pow; 1919249423Sdim Exp2Opt Exp2; 1920243789Sdimpublic: 1921243789Sdim LibCallSimplifierImpl(const DataLayout *TD, const TargetLibraryInfo *TLI, 1922249423Sdim const LibCallSimplifier *LCS, 1923249423Sdim bool UnsafeFPShrink = false) 1924249423Sdim : Cos(UnsafeFPShrink), Pow(UnsafeFPShrink), Exp2(UnsafeFPShrink) { 1925243789Sdim this->TD = TD; 1926243789Sdim this->TLI = TLI; 1927243789Sdim this->LCS = LCS; 1928249423Sdim this->UnsafeFPShrink = UnsafeFPShrink; 1929243789Sdim } 1930243789Sdim 1931243789Sdim Value *optimizeCall(CallInst *CI); 1932249423Sdim LibCallOptimization *lookupOptimization(CallInst *CI); 1933249423Sdim bool hasFloatVersion(StringRef FuncName); 1934243789Sdim}; 1935243789Sdim 1936249423Sdimbool LibCallSimplifierImpl::hasFloatVersion(StringRef FuncName) { 1937249423Sdim LibFunc::Func Func; 1938249423Sdim SmallString<20> FloatFuncName = FuncName; 1939249423Sdim FloatFuncName += 'f'; 1940249423Sdim if (TLI->getLibFunc(FloatFuncName, Func)) 1941249423Sdim return TLI->has(Func); 1942249423Sdim return false; 1943249423Sdim} 1944243789Sdim 1945249423Sdim// Fortified library call optimizations. 1946249423Sdimstatic MemCpyChkOpt MemCpyChk; 1947249423Sdimstatic MemMoveChkOpt MemMoveChk; 1948249423Sdimstatic MemSetChkOpt MemSetChk; 1949249423Sdimstatic StrCpyChkOpt StrCpyChk; 1950249423Sdimstatic StpCpyChkOpt StpCpyChk; 1951249423Sdimstatic StrNCpyChkOpt StrNCpyChk; 1952243789Sdim 1953249423Sdim// String library call optimizations. 1954249423Sdimstatic StrCatOpt StrCat; 1955249423Sdimstatic StrNCatOpt StrNCat; 1956249423Sdimstatic StrChrOpt StrChr; 1957249423Sdimstatic StrRChrOpt StrRChr; 1958249423Sdimstatic StrCmpOpt StrCmp; 1959249423Sdimstatic StrNCmpOpt StrNCmp; 1960249423Sdimstatic StrCpyOpt StrCpy; 1961249423Sdimstatic StpCpyOpt StpCpy; 1962249423Sdimstatic StrNCpyOpt StrNCpy; 1963249423Sdimstatic StrLenOpt StrLen; 1964249423Sdimstatic StrPBrkOpt StrPBrk; 1965249423Sdimstatic StrToOpt StrTo; 1966249423Sdimstatic StrSpnOpt StrSpn; 1967249423Sdimstatic StrCSpnOpt StrCSpn; 1968249423Sdimstatic StrStrOpt StrStr; 1969249423Sdim 1970249423Sdim// Memory library call optimizations. 1971249423Sdimstatic MemCmpOpt MemCmp; 1972249423Sdimstatic MemCpyOpt MemCpy; 1973249423Sdimstatic MemMoveOpt MemMove; 1974249423Sdimstatic MemSetOpt MemSet; 1975249423Sdim 1976249423Sdim// Math library call optimizations. 1977249423Sdimstatic UnaryDoubleFPOpt UnaryDoubleFP(false); 1978249423Sdimstatic UnaryDoubleFPOpt UnsafeUnaryDoubleFP(true); 1979263508Sdimstatic SinCosPiOpt SinCosPi; 1980249423Sdim 1981249423Sdim // Integer library call optimizations. 1982249423Sdimstatic FFSOpt FFS; 1983249423Sdimstatic AbsOpt Abs; 1984249423Sdimstatic IsDigitOpt IsDigit; 1985249423Sdimstatic IsAsciiOpt IsAscii; 1986249423Sdimstatic ToAsciiOpt ToAscii; 1987249423Sdim 1988249423Sdim// Formatting and IO library call optimizations. 1989263508Sdimstatic ErrorReportingOpt ErrorReporting; 1990263508Sdimstatic ErrorReportingOpt ErrorReporting0(0); 1991263508Sdimstatic ErrorReportingOpt ErrorReporting1(1); 1992249423Sdimstatic PrintFOpt PrintF; 1993249423Sdimstatic SPrintFOpt SPrintF; 1994249423Sdimstatic FPrintFOpt FPrintF; 1995249423Sdimstatic FWriteOpt FWrite; 1996249423Sdimstatic FPutsOpt FPuts; 1997249423Sdimstatic PutsOpt Puts; 1998249423Sdim 1999249423SdimLibCallOptimization *LibCallSimplifierImpl::lookupOptimization(CallInst *CI) { 2000249423Sdim LibFunc::Func Func; 2001249423Sdim Function *Callee = CI->getCalledFunction(); 2002249423Sdim StringRef FuncName = Callee->getName(); 2003249423Sdim 2004249423Sdim // Next check for intrinsics. 2005249423Sdim if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) { 2006249423Sdim switch (II->getIntrinsicID()) { 2007249423Sdim case Intrinsic::pow: 2008249423Sdim return &Pow; 2009249423Sdim case Intrinsic::exp2: 2010249423Sdim return &Exp2; 2011249423Sdim default: 2012249423Sdim return 0; 2013249423Sdim } 2014249423Sdim } 2015249423Sdim 2016249423Sdim // Then check for known library functions. 2017249423Sdim if (TLI->getLibFunc(FuncName, Func) && TLI->has(Func)) { 2018249423Sdim switch (Func) { 2019249423Sdim case LibFunc::strcat: 2020249423Sdim return &StrCat; 2021249423Sdim case LibFunc::strncat: 2022249423Sdim return &StrNCat; 2023249423Sdim case LibFunc::strchr: 2024249423Sdim return &StrChr; 2025249423Sdim case LibFunc::strrchr: 2026249423Sdim return &StrRChr; 2027249423Sdim case LibFunc::strcmp: 2028249423Sdim return &StrCmp; 2029249423Sdim case LibFunc::strncmp: 2030249423Sdim return &StrNCmp; 2031249423Sdim case LibFunc::strcpy: 2032249423Sdim return &StrCpy; 2033249423Sdim case LibFunc::stpcpy: 2034249423Sdim return &StpCpy; 2035249423Sdim case LibFunc::strncpy: 2036249423Sdim return &StrNCpy; 2037249423Sdim case LibFunc::strlen: 2038249423Sdim return &StrLen; 2039249423Sdim case LibFunc::strpbrk: 2040249423Sdim return &StrPBrk; 2041249423Sdim case LibFunc::strtol: 2042249423Sdim case LibFunc::strtod: 2043249423Sdim case LibFunc::strtof: 2044249423Sdim case LibFunc::strtoul: 2045249423Sdim case LibFunc::strtoll: 2046249423Sdim case LibFunc::strtold: 2047249423Sdim case LibFunc::strtoull: 2048249423Sdim return &StrTo; 2049249423Sdim case LibFunc::strspn: 2050249423Sdim return &StrSpn; 2051249423Sdim case LibFunc::strcspn: 2052249423Sdim return &StrCSpn; 2053249423Sdim case LibFunc::strstr: 2054249423Sdim return &StrStr; 2055249423Sdim case LibFunc::memcmp: 2056249423Sdim return &MemCmp; 2057249423Sdim case LibFunc::memcpy: 2058249423Sdim return &MemCpy; 2059249423Sdim case LibFunc::memmove: 2060249423Sdim return &MemMove; 2061249423Sdim case LibFunc::memset: 2062249423Sdim return &MemSet; 2063249423Sdim case LibFunc::cosf: 2064249423Sdim case LibFunc::cos: 2065249423Sdim case LibFunc::cosl: 2066249423Sdim return &Cos; 2067263508Sdim case LibFunc::sinpif: 2068263508Sdim case LibFunc::sinpi: 2069263508Sdim case LibFunc::cospif: 2070263508Sdim case LibFunc::cospi: 2071263508Sdim return &SinCosPi; 2072249423Sdim case LibFunc::powf: 2073249423Sdim case LibFunc::pow: 2074249423Sdim case LibFunc::powl: 2075249423Sdim return &Pow; 2076249423Sdim case LibFunc::exp2l: 2077249423Sdim case LibFunc::exp2: 2078249423Sdim case LibFunc::exp2f: 2079249423Sdim return &Exp2; 2080249423Sdim case LibFunc::ffs: 2081249423Sdim case LibFunc::ffsl: 2082249423Sdim case LibFunc::ffsll: 2083249423Sdim return &FFS; 2084249423Sdim case LibFunc::abs: 2085249423Sdim case LibFunc::labs: 2086249423Sdim case LibFunc::llabs: 2087249423Sdim return &Abs; 2088249423Sdim case LibFunc::isdigit: 2089249423Sdim return &IsDigit; 2090249423Sdim case LibFunc::isascii: 2091249423Sdim return &IsAscii; 2092249423Sdim case LibFunc::toascii: 2093249423Sdim return &ToAscii; 2094249423Sdim case LibFunc::printf: 2095249423Sdim return &PrintF; 2096249423Sdim case LibFunc::sprintf: 2097249423Sdim return &SPrintF; 2098249423Sdim case LibFunc::fprintf: 2099249423Sdim return &FPrintF; 2100249423Sdim case LibFunc::fwrite: 2101249423Sdim return &FWrite; 2102249423Sdim case LibFunc::fputs: 2103249423Sdim return &FPuts; 2104249423Sdim case LibFunc::puts: 2105249423Sdim return &Puts; 2106263508Sdim case LibFunc::perror: 2107263508Sdim return &ErrorReporting; 2108263508Sdim case LibFunc::vfprintf: 2109263508Sdim case LibFunc::fiprintf: 2110263508Sdim return &ErrorReporting0; 2111263508Sdim case LibFunc::fputc: 2112263508Sdim return &ErrorReporting1; 2113249423Sdim case LibFunc::ceil: 2114249423Sdim case LibFunc::fabs: 2115249423Sdim case LibFunc::floor: 2116249423Sdim case LibFunc::rint: 2117249423Sdim case LibFunc::round: 2118249423Sdim case LibFunc::nearbyint: 2119249423Sdim case LibFunc::trunc: 2120249423Sdim if (hasFloatVersion(FuncName)) 2121249423Sdim return &UnaryDoubleFP; 2122249423Sdim return 0; 2123249423Sdim case LibFunc::acos: 2124249423Sdim case LibFunc::acosh: 2125249423Sdim case LibFunc::asin: 2126249423Sdim case LibFunc::asinh: 2127249423Sdim case LibFunc::atan: 2128249423Sdim case LibFunc::atanh: 2129249423Sdim case LibFunc::cbrt: 2130249423Sdim case LibFunc::cosh: 2131249423Sdim case LibFunc::exp: 2132249423Sdim case LibFunc::exp10: 2133249423Sdim case LibFunc::expm1: 2134249423Sdim case LibFunc::log: 2135249423Sdim case LibFunc::log10: 2136249423Sdim case LibFunc::log1p: 2137249423Sdim case LibFunc::log2: 2138249423Sdim case LibFunc::logb: 2139249423Sdim case LibFunc::sin: 2140249423Sdim case LibFunc::sinh: 2141249423Sdim case LibFunc::sqrt: 2142249423Sdim case LibFunc::tan: 2143249423Sdim case LibFunc::tanh: 2144249423Sdim if (UnsafeFPShrink && hasFloatVersion(FuncName)) 2145249423Sdim return &UnsafeUnaryDoubleFP; 2146249423Sdim return 0; 2147249423Sdim case LibFunc::memcpy_chk: 2148249423Sdim return &MemCpyChk; 2149249423Sdim default: 2150249423Sdim return 0; 2151249423Sdim } 2152249423Sdim } 2153249423Sdim 2154249423Sdim // Finally check for fortified library calls. 2155249423Sdim if (FuncName.endswith("_chk")) { 2156249423Sdim if (FuncName == "__memmove_chk") 2157249423Sdim return &MemMoveChk; 2158249423Sdim else if (FuncName == "__memset_chk") 2159249423Sdim return &MemSetChk; 2160249423Sdim else if (FuncName == "__strcpy_chk") 2161249423Sdim return &StrCpyChk; 2162249423Sdim else if (FuncName == "__stpcpy_chk") 2163249423Sdim return &StpCpyChk; 2164249423Sdim else if (FuncName == "__strncpy_chk") 2165249423Sdim return &StrNCpyChk; 2166249423Sdim else if (FuncName == "__stpncpy_chk") 2167249423Sdim return &StrNCpyChk; 2168249423Sdim } 2169249423Sdim 2170249423Sdim return 0; 2171249423Sdim 2172243789Sdim} 2173243789Sdim 2174243789SdimValue *LibCallSimplifierImpl::optimizeCall(CallInst *CI) { 2175249423Sdim 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, 2184249423Sdim const TargetLibraryInfo *TLI, 2185249423Sdim bool UnsafeFPShrink) { 2186249423Sdim Impl = new LibCallSimplifierImpl(TD, TLI, this, UnsafeFPShrink); 2187243789Sdim} 2188243789Sdim 2189243789SdimLibCallSimplifier::~LibCallSimplifier() { 2190243789Sdim delete Impl; 2191243789Sdim} 2192243789Sdim 2193243789SdimValue *LibCallSimplifier::optimizeCall(CallInst *CI) { 2194263508Sdim 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} 2204263508Sdim 2205263508Sdim// TODO: 2206263508Sdim// Additional cases that we need to add to this file: 2207263508Sdim// 2208263508Sdim// cbrt: 2209263508Sdim// * cbrt(expN(X)) -> expN(x/3) 2210263508Sdim// * cbrt(sqrt(x)) -> pow(x,1/6) 2211263508Sdim// * cbrt(sqrt(x)) -> pow(x,1/9) 2212263508Sdim// 2213263508Sdim// exp, expf, expl: 2214263508Sdim// * exp(log(x)) -> x 2215263508Sdim// 2216263508Sdim// log, logf, logl: 2217263508Sdim// * log(exp(x)) -> x 2218263508Sdim// * log(x**y) -> y*log(x) 2219263508Sdim// * log(exp(y)) -> y*log(e) 2220263508Sdim// * log(exp2(y)) -> y*log(2) 2221263508Sdim// * log(exp10(y)) -> y*log(10) 2222263508Sdim// * log(sqrt(x)) -> 0.5*log(x) 2223263508Sdim// * log(pow(x,y)) -> y*log(x) 2224263508Sdim// 2225263508Sdim// lround, lroundf, lroundl: 2226263508Sdim// * lround(cnst) -> cnst' 2227263508Sdim// 2228263508Sdim// pow, powf, powl: 2229263508Sdim// * pow(exp(x),y) -> exp(x*y) 2230263508Sdim// * pow(sqrt(x),y) -> pow(x,y*0.5) 2231263508Sdim// * pow(pow(x,y),z)-> pow(x,y*z) 2232263508Sdim// 2233263508Sdim// round, roundf, roundl: 2234263508Sdim// * round(cnst) -> cnst' 2235263508Sdim// 2236263508Sdim// signbit: 2237263508Sdim// * signbit(cnst) -> cnst' 2238263508Sdim// * signbit(nncst) -> 0 (if pstv is a non-negative constant) 2239263508Sdim// 2240263508Sdim// sqrt, sqrtf, sqrtl: 2241263508Sdim// * sqrt(expN(x)) -> expN(x*0.5) 2242263508Sdim// * sqrt(Nroot(x)) -> pow(x,1/(2*N)) 2243263508Sdim// * sqrt(pow(x,y)) -> pow(|x|,y*0.5) 2244263508Sdim// 2245263508Sdim// strchr: 2246263508Sdim// * strchr(p, 0) -> strlen(p) 2247263508Sdim// tan, tanf, tanl: 2248263508Sdim// * tan(atan(x)) -> x 2249263508Sdim// 2250263508Sdim// trunc, truncf, truncl: 2251263508Sdim// * trunc(cnst) -> cnst' 2252263508Sdim// 2253263508Sdim// 2254