SimplifyLibCalls.cpp revision b3394f56416df855f860a82e1f2222bcf476ac27
1//===------ SimplifyLibCalls.cpp - Library calls simplifier ---------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This is a utility pass used for testing the InstructionSimplify analysis. 11// The analysis is applied to every instruction, and if it simplifies then the 12// instruction is replaced by the simplification. If you are looking for a pass 13// that performs serious instruction folding, use the instcombine pass instead. 14// 15//===----------------------------------------------------------------------===// 16 17#include "llvm/Transforms/Utils/SimplifyLibCalls.h" 18#include "llvm/DataLayout.h" 19#include "llvm/ADT/StringMap.h" 20#include "llvm/Analysis/ValueTracking.h" 21#include "llvm/Function.h" 22#include "llvm/IRBuilder.h" 23#include "llvm/LLVMContext.h" 24#include "llvm/Target/TargetLibraryInfo.h" 25#include "llvm/Transforms/Utils/BuildLibCalls.h" 26 27using namespace llvm; 28 29/// This class is the abstract base class for the set of optimizations that 30/// corresponds to one library call. 31namespace { 32class LibCallOptimization { 33protected: 34 Function *Caller; 35 const DataLayout *TD; 36 const TargetLibraryInfo *TLI; 37 LLVMContext* Context; 38public: 39 LibCallOptimization() { } 40 virtual ~LibCallOptimization() {} 41 42 /// callOptimizer - This pure virtual method is implemented by base classes to 43 /// do various optimizations. If this returns null then no transformation was 44 /// performed. If it returns CI, then it transformed the call and CI is to be 45 /// deleted. If it returns something else, replace CI with the new value and 46 /// delete CI. 47 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) 48 =0; 49 50 Value *optimizeCall(CallInst *CI, const DataLayout *TD, 51 const TargetLibraryInfo *TLI, IRBuilder<> &B) { 52 Caller = CI->getParent()->getParent(); 53 this->TD = TD; 54 this->TLI = TLI; 55 if (CI->getCalledFunction()) 56 Context = &CI->getCalledFunction()->getContext(); 57 58 // We never change the calling convention. 59 if (CI->getCallingConv() != llvm::CallingConv::C) 60 return NULL; 61 62 return callOptimizer(CI->getCalledFunction(), CI, B); 63 } 64}; 65 66//===----------------------------------------------------------------------===// 67// Fortified Library Call Optimizations 68//===----------------------------------------------------------------------===// 69 70struct FortifiedLibCallOptimization : public LibCallOptimization { 71protected: 72 virtual bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp, 73 bool isString) const = 0; 74}; 75 76struct InstFortifiedLibCallOptimization : public FortifiedLibCallOptimization { 77 CallInst *CI; 78 79 bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp, bool isString) const { 80 if (CI->getArgOperand(SizeCIOp) == CI->getArgOperand(SizeArgOp)) 81 return true; 82 if (ConstantInt *SizeCI = 83 dyn_cast<ConstantInt>(CI->getArgOperand(SizeCIOp))) { 84 if (SizeCI->isAllOnesValue()) 85 return true; 86 if (isString) { 87 uint64_t Len = GetStringLength(CI->getArgOperand(SizeArgOp)); 88 // If the length is 0 we don't know how long it is and so we can't 89 // remove the check. 90 if (Len == 0) return false; 91 return SizeCI->getZExtValue() >= Len; 92 } 93 if (ConstantInt *Arg = dyn_cast<ConstantInt>( 94 CI->getArgOperand(SizeArgOp))) 95 return SizeCI->getZExtValue() >= Arg->getZExtValue(); 96 } 97 return false; 98 } 99}; 100 101struct MemCpyChkOpt : public InstFortifiedLibCallOptimization { 102 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 103 this->CI = CI; 104 FunctionType *FT = Callee->getFunctionType(); 105 LLVMContext &Context = CI->getParent()->getContext(); 106 107 // Check if this has the right signature. 108 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 109 !FT->getParamType(0)->isPointerTy() || 110 !FT->getParamType(1)->isPointerTy() || 111 FT->getParamType(2) != TD->getIntPtrType(Context) || 112 FT->getParamType(3) != TD->getIntPtrType(Context)) 113 return 0; 114 115 if (isFoldable(3, 2, false)) { 116 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), 117 CI->getArgOperand(2), 1); 118 return CI->getArgOperand(0); 119 } 120 return 0; 121 } 122}; 123 124struct MemMoveChkOpt : public InstFortifiedLibCallOptimization { 125 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 126 this->CI = CI; 127 FunctionType *FT = Callee->getFunctionType(); 128 LLVMContext &Context = CI->getParent()->getContext(); 129 130 // Check if this has the right signature. 131 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 132 !FT->getParamType(0)->isPointerTy() || 133 !FT->getParamType(1)->isPointerTy() || 134 FT->getParamType(2) != TD->getIntPtrType(Context) || 135 FT->getParamType(3) != TD->getIntPtrType(Context)) 136 return 0; 137 138 if (isFoldable(3, 2, false)) { 139 B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1), 140 CI->getArgOperand(2), 1); 141 return CI->getArgOperand(0); 142 } 143 return 0; 144 } 145}; 146 147struct MemSetChkOpt : public InstFortifiedLibCallOptimization { 148 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 149 this->CI = CI; 150 FunctionType *FT = Callee->getFunctionType(); 151 LLVMContext &Context = CI->getParent()->getContext(); 152 153 // Check if this has the right signature. 154 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 155 !FT->getParamType(0)->isPointerTy() || 156 !FT->getParamType(1)->isIntegerTy() || 157 FT->getParamType(2) != TD->getIntPtrType(Context) || 158 FT->getParamType(3) != TD->getIntPtrType(Context)) 159 return 0; 160 161 if (isFoldable(3, 2, false)) { 162 Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), 163 false); 164 B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1); 165 return CI->getArgOperand(0); 166 } 167 return 0; 168 } 169}; 170 171struct StrCpyChkOpt : public InstFortifiedLibCallOptimization { 172 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 173 this->CI = CI; 174 StringRef Name = Callee->getName(); 175 FunctionType *FT = Callee->getFunctionType(); 176 LLVMContext &Context = CI->getParent()->getContext(); 177 178 // Check if this has the right signature. 179 if (FT->getNumParams() != 3 || 180 FT->getReturnType() != FT->getParamType(0) || 181 FT->getParamType(0) != FT->getParamType(1) || 182 FT->getParamType(0) != Type::getInt8PtrTy(Context) || 183 FT->getParamType(2) != TD->getIntPtrType(Context)) 184 return 0; 185 186 Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); 187 if (Dst == Src) // __strcpy_chk(x,x) -> x 188 return Src; 189 190 // If a) we don't have any length information, or b) we know this will 191 // fit then just lower to a plain st[rp]cpy. Otherwise we'll keep our 192 // st[rp]cpy_chk call which may fail at runtime if the size is too long. 193 // TODO: It might be nice to get a maximum length out of the possible 194 // string lengths for varying. 195 if (isFoldable(2, 1, true)) { 196 Value *Ret = EmitStrCpy(Dst, Src, B, TD, TLI, Name.substr(2, 6)); 197 return Ret; 198 } else { 199 // Maybe we can stil fold __strcpy_chk to __memcpy_chk. 200 uint64_t Len = GetStringLength(Src); 201 if (Len == 0) return 0; 202 203 // This optimization require DataLayout. 204 if (!TD) return 0; 205 206 Value *Ret = 207 EmitMemCpyChk(Dst, Src, 208 ConstantInt::get(TD->getIntPtrType(Context), Len), 209 CI->getArgOperand(2), B, TD, TLI); 210 return Ret; 211 } 212 return 0; 213 } 214}; 215 216struct StrNCpyChkOpt : public InstFortifiedLibCallOptimization { 217 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 218 this->CI = CI; 219 StringRef Name = Callee->getName(); 220 FunctionType *FT = Callee->getFunctionType(); 221 LLVMContext &Context = CI->getParent()->getContext(); 222 223 // Check if this has the right signature. 224 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 225 FT->getParamType(0) != FT->getParamType(1) || 226 FT->getParamType(0) != Type::getInt8PtrTy(Context) || 227 !FT->getParamType(2)->isIntegerTy() || 228 FT->getParamType(3) != TD->getIntPtrType(Context)) 229 return 0; 230 231 if (isFoldable(3, 2, false)) { 232 Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1), 233 CI->getArgOperand(2), B, TD, TLI, 234 Name.substr(2, 7)); 235 return Ret; 236 } 237 return 0; 238 } 239}; 240 241//===----------------------------------------------------------------------===// 242// String and Memory Library Call Optimizations 243//===----------------------------------------------------------------------===// 244 245struct StrCatOpt : public LibCallOptimization { 246 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 247 // Verify the "strcat" function prototype. 248 FunctionType *FT = Callee->getFunctionType(); 249 if (FT->getNumParams() != 2 || 250 FT->getReturnType() != B.getInt8PtrTy() || 251 FT->getParamType(0) != FT->getReturnType() || 252 FT->getParamType(1) != FT->getReturnType()) 253 return 0; 254 255 // Extract some information from the instruction 256 Value *Dst = CI->getArgOperand(0); 257 Value *Src = CI->getArgOperand(1); 258 259 // See if we can get the length of the input string. 260 uint64_t Len = GetStringLength(Src); 261 if (Len == 0) return 0; 262 --Len; // Unbias length. 263 264 // Handle the simple, do-nothing case: strcat(x, "") -> x 265 if (Len == 0) 266 return Dst; 267 268 // These optimizations require DataLayout. 269 if (!TD) return 0; 270 271 return emitStrLenMemCpy(Src, Dst, Len, B); 272 } 273 274 Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, 275 IRBuilder<> &B) { 276 // We need to find the end of the destination string. That's where the 277 // memory is to be moved to. We just generate a call to strlen. 278 Value *DstLen = EmitStrLen(Dst, B, TD, TLI); 279 if (!DstLen) 280 return 0; 281 282 // Now that we have the destination's length, we must index into the 283 // destination's pointer to get the actual memcpy destination (end of 284 // the string .. we're concatenating). 285 Value *CpyDst = B.CreateGEP(Dst, DstLen, "endptr"); 286 287 // We have enough information to now generate the memcpy call to do the 288 // concatenation for us. Make a memcpy to copy the nul byte with align = 1. 289 B.CreateMemCpy(CpyDst, Src, 290 ConstantInt::get(TD->getIntPtrType(*Context), Len + 1), 1); 291 return Dst; 292 } 293}; 294 295struct StrNCatOpt : public StrCatOpt { 296 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 297 // Verify the "strncat" function prototype. 298 FunctionType *FT = Callee->getFunctionType(); 299 if (FT->getNumParams() != 3 || 300 FT->getReturnType() != B.getInt8PtrTy() || 301 FT->getParamType(0) != FT->getReturnType() || 302 FT->getParamType(1) != FT->getReturnType() || 303 !FT->getParamType(2)->isIntegerTy()) 304 return 0; 305 306 // Extract some information from the instruction 307 Value *Dst = CI->getArgOperand(0); 308 Value *Src = CI->getArgOperand(1); 309 uint64_t Len; 310 311 // We don't do anything if length is not constant 312 if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2))) 313 Len = LengthArg->getZExtValue(); 314 else 315 return 0; 316 317 // See if we can get the length of the input string. 318 uint64_t SrcLen = GetStringLength(Src); 319 if (SrcLen == 0) return 0; 320 --SrcLen; // Unbias length. 321 322 // Handle the simple, do-nothing cases: 323 // strncat(x, "", c) -> x 324 // strncat(x, c, 0) -> x 325 if (SrcLen == 0 || Len == 0) return Dst; 326 327 // These optimizations require DataLayout. 328 if (!TD) return 0; 329 330 // We don't optimize this case 331 if (Len < SrcLen) return 0; 332 333 // strncat(x, s, c) -> strcat(x, s) 334 // s is constant so the strcat can be optimized further 335 return emitStrLenMemCpy(Src, Dst, SrcLen, B); 336 } 337}; 338 339struct StrChrOpt : public LibCallOptimization { 340 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 341 // Verify the "strchr" function prototype. 342 FunctionType *FT = Callee->getFunctionType(); 343 if (FT->getNumParams() != 2 || 344 FT->getReturnType() != B.getInt8PtrTy() || 345 FT->getParamType(0) != FT->getReturnType() || 346 !FT->getParamType(1)->isIntegerTy(32)) 347 return 0; 348 349 Value *SrcStr = CI->getArgOperand(0); 350 351 // If the second operand is non-constant, see if we can compute the length 352 // of the input string and turn this into memchr. 353 ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 354 if (CharC == 0) { 355 // These optimizations require DataLayout. 356 if (!TD) return 0; 357 358 uint64_t Len = GetStringLength(SrcStr); 359 if (Len == 0 || !FT->getParamType(1)->isIntegerTy(32))// memchr needs i32. 360 return 0; 361 362 return EmitMemChr(SrcStr, CI->getArgOperand(1), // include nul. 363 ConstantInt::get(TD->getIntPtrType(*Context), Len), 364 B, TD, TLI); 365 } 366 367 // Otherwise, the character is a constant, see if the first argument is 368 // a string literal. If so, we can constant fold. 369 StringRef Str; 370 if (!getConstantStringInfo(SrcStr, Str)) 371 return 0; 372 373 // Compute the offset, make sure to handle the case when we're searching for 374 // zero (a weird way to spell strlen). 375 size_t I = CharC->getSExtValue() == 0 ? 376 Str.size() : Str.find(CharC->getSExtValue()); 377 if (I == StringRef::npos) // Didn't find the char. strchr returns null. 378 return Constant::getNullValue(CI->getType()); 379 380 // strchr(s+n,c) -> gep(s+n+i,c) 381 return B.CreateGEP(SrcStr, B.getInt64(I), "strchr"); 382 } 383}; 384 385struct StrRChrOpt : public LibCallOptimization { 386 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 387 // Verify the "strrchr" function prototype. 388 FunctionType *FT = Callee->getFunctionType(); 389 if (FT->getNumParams() != 2 || 390 FT->getReturnType() != B.getInt8PtrTy() || 391 FT->getParamType(0) != FT->getReturnType() || 392 !FT->getParamType(1)->isIntegerTy(32)) 393 return 0; 394 395 Value *SrcStr = CI->getArgOperand(0); 396 ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 397 398 // Cannot fold anything if we're not looking for a constant. 399 if (!CharC) 400 return 0; 401 402 StringRef Str; 403 if (!getConstantStringInfo(SrcStr, Str)) { 404 // strrchr(s, 0) -> strchr(s, 0) 405 if (TD && CharC->isZero()) 406 return EmitStrChr(SrcStr, '\0', B, TD, TLI); 407 return 0; 408 } 409 410 // Compute the offset. 411 size_t I = CharC->getSExtValue() == 0 ? 412 Str.size() : Str.rfind(CharC->getSExtValue()); 413 if (I == StringRef::npos) // Didn't find the char. Return null. 414 return Constant::getNullValue(CI->getType()); 415 416 // strrchr(s+n,c) -> gep(s+n+i,c) 417 return B.CreateGEP(SrcStr, B.getInt64(I), "strrchr"); 418 } 419}; 420 421struct StrCmpOpt : public LibCallOptimization { 422 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 423 // Verify the "strcmp" function prototype. 424 FunctionType *FT = Callee->getFunctionType(); 425 if (FT->getNumParams() != 2 || 426 !FT->getReturnType()->isIntegerTy(32) || 427 FT->getParamType(0) != FT->getParamType(1) || 428 FT->getParamType(0) != B.getInt8PtrTy()) 429 return 0; 430 431 Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1); 432 if (Str1P == Str2P) // strcmp(x,x) -> 0 433 return ConstantInt::get(CI->getType(), 0); 434 435 StringRef Str1, Str2; 436 bool HasStr1 = getConstantStringInfo(Str1P, Str1); 437 bool HasStr2 = getConstantStringInfo(Str2P, Str2); 438 439 // strcmp(x, y) -> cnst (if both x and y are constant strings) 440 if (HasStr1 && HasStr2) 441 return ConstantInt::get(CI->getType(), Str1.compare(Str2)); 442 443 if (HasStr1 && Str1.empty()) // strcmp("", x) -> -*x 444 return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), 445 CI->getType())); 446 447 if (HasStr2 && Str2.empty()) // strcmp(x,"") -> *x 448 return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType()); 449 450 // strcmp(P, "x") -> memcmp(P, "x", 2) 451 uint64_t Len1 = GetStringLength(Str1P); 452 uint64_t Len2 = GetStringLength(Str2P); 453 if (Len1 && Len2) { 454 // These optimizations require DataLayout. 455 if (!TD) return 0; 456 457 return EmitMemCmp(Str1P, Str2P, 458 ConstantInt::get(TD->getIntPtrType(*Context), 459 std::min(Len1, Len2)), B, TD, TLI); 460 } 461 462 return 0; 463 } 464}; 465 466struct StrNCmpOpt : public LibCallOptimization { 467 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 468 // Verify the "strncmp" function prototype. 469 FunctionType *FT = Callee->getFunctionType(); 470 if (FT->getNumParams() != 3 || 471 !FT->getReturnType()->isIntegerTy(32) || 472 FT->getParamType(0) != FT->getParamType(1) || 473 FT->getParamType(0) != B.getInt8PtrTy() || 474 !FT->getParamType(2)->isIntegerTy()) 475 return 0; 476 477 Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1); 478 if (Str1P == Str2P) // strncmp(x,x,n) -> 0 479 return ConstantInt::get(CI->getType(), 0); 480 481 // Get the length argument if it is constant. 482 uint64_t Length; 483 if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2))) 484 Length = LengthArg->getZExtValue(); 485 else 486 return 0; 487 488 if (Length == 0) // strncmp(x,y,0) -> 0 489 return ConstantInt::get(CI->getType(), 0); 490 491 if (TD && Length == 1) // strncmp(x,y,1) -> memcmp(x,y,1) 492 return EmitMemCmp(Str1P, Str2P, CI->getArgOperand(2), B, TD, TLI); 493 494 StringRef Str1, Str2; 495 bool HasStr1 = getConstantStringInfo(Str1P, Str1); 496 bool HasStr2 = getConstantStringInfo(Str2P, Str2); 497 498 // strncmp(x, y) -> cnst (if both x and y are constant strings) 499 if (HasStr1 && HasStr2) { 500 StringRef SubStr1 = Str1.substr(0, Length); 501 StringRef SubStr2 = Str2.substr(0, Length); 502 return ConstantInt::get(CI->getType(), SubStr1.compare(SubStr2)); 503 } 504 505 if (HasStr1 && Str1.empty()) // strncmp("", x, n) -> -*x 506 return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), 507 CI->getType())); 508 509 if (HasStr2 && Str2.empty()) // strncmp(x, "", n) -> *x 510 return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType()); 511 512 return 0; 513 } 514}; 515 516struct StrCpyOpt : public LibCallOptimization { 517 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 518 // Verify the "strcpy" function prototype. 519 FunctionType *FT = Callee->getFunctionType(); 520 if (FT->getNumParams() != 2 || 521 FT->getReturnType() != FT->getParamType(0) || 522 FT->getParamType(0) != FT->getParamType(1) || 523 FT->getParamType(0) != B.getInt8PtrTy()) 524 return 0; 525 526 Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); 527 if (Dst == Src) // strcpy(x,x) -> x 528 return Src; 529 530 // These optimizations require DataLayout. 531 if (!TD) return 0; 532 533 // See if we can get the length of the input string. 534 uint64_t Len = GetStringLength(Src); 535 if (Len == 0) return 0; 536 537 // We have enough information to now generate the memcpy call to do the 538 // copy for us. Make a memcpy to copy the nul byte with align = 1. 539 B.CreateMemCpy(Dst, Src, 540 ConstantInt::get(TD->getIntPtrType(*Context), Len), 1); 541 return Dst; 542 } 543}; 544 545} // End anonymous namespace. 546 547namespace llvm { 548 549class LibCallSimplifierImpl { 550 const DataLayout *TD; 551 const TargetLibraryInfo *TLI; 552 StringMap<LibCallOptimization*> Optimizations; 553 554 // Fortified library call optimizations. 555 MemCpyChkOpt MemCpyChk; 556 MemMoveChkOpt MemMoveChk; 557 MemSetChkOpt MemSetChk; 558 StrCpyChkOpt StrCpyChk; 559 StrNCpyChkOpt StrNCpyChk; 560 561 // String and memory library call optimizations. 562 StrCatOpt StrCat; 563 StrNCatOpt StrNCat; 564 StrChrOpt StrChr; 565 StrRChrOpt StrRChr; 566 StrCmpOpt StrCmp; 567 StrNCmpOpt StrNCmp; 568 StrCpyOpt StrCpy; 569 570 void initOptimizations(); 571public: 572 LibCallSimplifierImpl(const DataLayout *TD, const TargetLibraryInfo *TLI) { 573 this->TD = TD; 574 this->TLI = TLI; 575 } 576 577 Value *optimizeCall(CallInst *CI); 578}; 579 580void LibCallSimplifierImpl::initOptimizations() { 581 // Fortified library call optimizations. 582 Optimizations["__memcpy_chk"] = &MemCpyChk; 583 Optimizations["__memmove_chk"] = &MemMoveChk; 584 Optimizations["__memset_chk"] = &MemSetChk; 585 Optimizations["__strcpy_chk"] = &StrCpyChk; 586 Optimizations["__stpcpy_chk"] = &StrCpyChk; 587 Optimizations["__strncpy_chk"] = &StrNCpyChk; 588 Optimizations["__stpncpy_chk"] = &StrNCpyChk; 589 590 // String and memory library call optimizations. 591 Optimizations["strcat"] = &StrCat; 592 Optimizations["strncat"] = &StrNCat; 593 Optimizations["strchr"] = &StrChr; 594 Optimizations["strrchr"] = &StrRChr; 595 Optimizations["strcmp"] = &StrCmp; 596 Optimizations["strncmp"] = &StrNCmp; 597 Optimizations["strcpy"] = &StrCpy; 598} 599 600Value *LibCallSimplifierImpl::optimizeCall(CallInst *CI) { 601 if (Optimizations.empty()) 602 initOptimizations(); 603 604 Function *Callee = CI->getCalledFunction(); 605 LibCallOptimization *LCO = Optimizations.lookup(Callee->getName()); 606 if (LCO) { 607 IRBuilder<> Builder(CI); 608 return LCO->optimizeCall(CI, TD, TLI, Builder); 609 } 610 return 0; 611} 612 613LibCallSimplifier::LibCallSimplifier(const DataLayout *TD, 614 const TargetLibraryInfo *TLI) { 615 Impl = new LibCallSimplifierImpl(TD, TLI); 616} 617 618LibCallSimplifier::~LibCallSimplifier() { 619 delete Impl; 620} 621 622Value *LibCallSimplifier::optimizeCall(CallInst *CI) { 623 return Impl->optimizeCall(CI); 624} 625 626} 627