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 27 using namespace llvm; 28 29 /// This class is the abstract base class for the set of optimizations that 30 /// corresponds to one library call. 31 namespace { 32 class LibCallOptimization { 33 protected: 34 Function *Caller; 35 const DataLayout *TD; 36 const TargetLibraryInfo *TLI; 37 LLVMContext* Context; 38 public: 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 70 struct FortifiedLibCallOptimization : public LibCallOptimization { 71 protected: 72 virtual bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp, 73 bool isString) const = 0; 74 }; 75 76 struct 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 101 struct MemCpyChkOpt : public InstFortifiedLibCallOptimization { 102 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 103 this->CI = CI; 104 FunctionType *FT = Callee->getFunctionType(); 105 106 // Check if this has the right signature. 107 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 108 !FT->getParamType(0)->isPointerTy() || 109 !FT->getParamType(1)->isPointerTy() || 110 FT->getParamType(2) != TD->getIntPtrType(FT->getParamType(0)) || 111 FT->getParamType(3) != TD->getIntPtrType(FT->getParamType(1))) 112 return 0; 113 114 if (isFoldable(3, 2, false)) { 115 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1), 116 CI->getArgOperand(2), 1); 117 return CI->getArgOperand(0); 118 } 119 return 0; 120 } 121 }; 122 123 struct MemMoveChkOpt : public InstFortifiedLibCallOptimization { 124 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 125 this->CI = CI; 126 FunctionType *FT = Callee->getFunctionType(); 127 128 // Check if this has the right signature. 129 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 130 !FT->getParamType(0)->isPointerTy() || 131 !FT->getParamType(1)->isPointerTy() || 132 FT->getParamType(2) != TD->getIntPtrType(FT->getParamType(0)) || 133 FT->getParamType(3) != TD->getIntPtrType(FT->getParamType(1))) 134 return 0; 135 136 if (isFoldable(3, 2, false)) { 137 B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1), 138 CI->getArgOperand(2), 1); 139 return CI->getArgOperand(0); 140 } 141 return 0; 142 } 143 }; 144 145 struct MemSetChkOpt : public InstFortifiedLibCallOptimization { 146 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 147 this->CI = CI; 148 FunctionType *FT = Callee->getFunctionType(); 149 150 // Check if this has the right signature. 151 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 152 !FT->getParamType(0)->isPointerTy() || 153 !FT->getParamType(1)->isIntegerTy() || 154 FT->getParamType(2) != TD->getIntPtrType(FT->getParamType(0)) || 155 FT->getParamType(3) != TD->getIntPtrType(FT->getParamType(0))) 156 return 0; 157 158 if (isFoldable(3, 2, false)) { 159 Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(), 160 false); 161 B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1); 162 return CI->getArgOperand(0); 163 } 164 return 0; 165 } 166 }; 167 168 struct StrCpyChkOpt : public InstFortifiedLibCallOptimization { 169 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 170 this->CI = CI; 171 StringRef Name = Callee->getName(); 172 FunctionType *FT = Callee->getFunctionType(); 173 LLVMContext &Context = CI->getParent()->getContext(); 174 175 // Check if this has the right signature. 176 if (FT->getNumParams() != 3 || 177 FT->getReturnType() != FT->getParamType(0) || 178 FT->getParamType(0) != FT->getParamType(1) || 179 FT->getParamType(0) != Type::getInt8PtrTy(Context) || 180 FT->getParamType(2) != TD->getIntPtrType(FT->getParamType(0))) 181 return 0; 182 183 Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1); 184 if (Dst == Src) // __strcpy_chk(x,x) -> x 185 return Src; 186 187 // If a) we don't have any length information, or b) we know this will 188 // fit then just lower to a plain st[rp]cpy. Otherwise we'll keep our 189 // st[rp]cpy_chk call which may fail at runtime if the size is too long. 190 // TODO: It might be nice to get a maximum length out of the possible 191 // string lengths for varying. 192 if (isFoldable(2, 1, true)) { 193 Value *Ret = EmitStrCpy(Dst, Src, B, TD, TLI, Name.substr(2, 6)); 194 return Ret; 195 } else { 196 // Maybe we can stil fold __strcpy_chk to __memcpy_chk. 197 uint64_t Len = GetStringLength(Src); 198 if (Len == 0) return 0; 199 200 // This optimization require DataLayout. 201 if (!TD) return 0; 202 203 Value *Ret = 204 EmitMemCpyChk(Dst, Src, 205 ConstantInt::get(TD->getIntPtrType(Dst->getType()), 206 Len), CI->getArgOperand(2), B, TD, TLI); 207 return Ret; 208 } 209 return 0; 210 } 211 }; 212 213 struct StrNCpyChkOpt : public InstFortifiedLibCallOptimization { 214 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 215 this->CI = CI; 216 StringRef Name = Callee->getName(); 217 FunctionType *FT = Callee->getFunctionType(); 218 LLVMContext &Context = CI->getParent()->getContext(); 219 220 // Check if this has the right signature. 221 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) || 222 FT->getParamType(0) != FT->getParamType(1) || 223 FT->getParamType(0) != Type::getInt8PtrTy(Context) || 224 !FT->getParamType(2)->isIntegerTy() || 225 FT->getParamType(3) != TD->getIntPtrType(FT->getParamType(0))) 226 return 0; 227 228 if (isFoldable(3, 2, false)) { 229 Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1), 230 CI->getArgOperand(2), B, TD, TLI, 231 Name.substr(2, 7)); 232 return Ret; 233 } 234 return 0; 235 } 236 }; 237 238 //===----------------------------------------------------------------------===// 239 // String and Memory Library Call Optimizations 240 //===----------------------------------------------------------------------===// 241 242 struct StrCatOpt : public LibCallOptimization { 243 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 244 // Verify the "strcat" function prototype. 245 FunctionType *FT = Callee->getFunctionType(); 246 if (FT->getNumParams() != 2 || 247 FT->getReturnType() != B.getInt8PtrTy() || 248 FT->getParamType(0) != FT->getReturnType() || 249 FT->getParamType(1) != FT->getReturnType()) 250 return 0; 251 252 // Extract some information from the instruction 253 Value *Dst = CI->getArgOperand(0); 254 Value *Src = CI->getArgOperand(1); 255 256 // See if we can get the length of the input string. 257 uint64_t Len = GetStringLength(Src); 258 if (Len == 0) return 0; 259 --Len; // Unbias length. 260 261 // Handle the simple, do-nothing case: strcat(x, "") -> x 262 if (Len == 0) 263 return Dst; 264 265 // These optimizations require DataLayout. 266 if (!TD) return 0; 267 268 return emitStrLenMemCpy(Src, Dst, Len, B); 269 } 270 271 Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, 272 IRBuilder<> &B) { 273 // We need to find the end of the destination string. That's where the 274 // memory is to be moved to. We just generate a call to strlen. 275 Value *DstLen = EmitStrLen(Dst, B, TD, TLI); 276 if (!DstLen) 277 return 0; 278 279 // Now that we have the destination's length, we must index into the 280 // destination's pointer to get the actual memcpy destination (end of 281 // the string .. we're concatenating). 282 Value *CpyDst = B.CreateGEP(Dst, DstLen, "endptr"); 283 284 // We have enough information to now generate the memcpy call to do the 285 // concatenation for us. Make a memcpy to copy the nul byte with align = 1. 286 B.CreateMemCpy(CpyDst, Src, 287 ConstantInt::get(TD->getIntPtrType(Src->getType()), 288 Len + 1), 1); 289 return Dst; 290 } 291 }; 292 293 struct StrNCatOpt : public StrCatOpt { 294 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 295 // Verify the "strncat" function prototype. 296 FunctionType *FT = Callee->getFunctionType(); 297 if (FT->getNumParams() != 3 || 298 FT->getReturnType() != B.getInt8PtrTy() || 299 FT->getParamType(0) != FT->getReturnType() || 300 FT->getParamType(1) != FT->getReturnType() || 301 !FT->getParamType(2)->isIntegerTy()) 302 return 0; 303 304 // Extract some information from the instruction 305 Value *Dst = CI->getArgOperand(0); 306 Value *Src = CI->getArgOperand(1); 307 uint64_t Len; 308 309 // We don't do anything if length is not constant 310 if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2))) 311 Len = LengthArg->getZExtValue(); 312 else 313 return 0; 314 315 // See if we can get the length of the input string. 316 uint64_t SrcLen = GetStringLength(Src); 317 if (SrcLen == 0) return 0; 318 --SrcLen; // Unbias length. 319 320 // Handle the simple, do-nothing cases: 321 // strncat(x, "", c) -> x 322 // strncat(x, c, 0) -> x 323 if (SrcLen == 0 || Len == 0) return Dst; 324 325 // These optimizations require DataLayout. 326 if (!TD) return 0; 327 328 // We don't optimize this case 329 if (Len < SrcLen) return 0; 330 331 // strncat(x, s, c) -> strcat(x, s) 332 // s is constant so the strcat can be optimized further 333 return emitStrLenMemCpy(Src, Dst, SrcLen, B); 334 } 335 }; 336 337 struct StrChrOpt : public LibCallOptimization { 338 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 339 // Verify the "strchr" function prototype. 340 FunctionType *FT = Callee->getFunctionType(); 341 if (FT->getNumParams() != 2 || 342 FT->getReturnType() != B.getInt8PtrTy() || 343 FT->getParamType(0) != FT->getReturnType() || 344 !FT->getParamType(1)->isIntegerTy(32)) 345 return 0; 346 347 Value *SrcStr = CI->getArgOperand(0); 348 349 // If the second operand is non-constant, see if we can compute the length 350 // of the input string and turn this into memchr. 351 ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 352 if (CharC == 0) { 353 // These optimizations require DataLayout. 354 if (!TD) return 0; 355 356 uint64_t Len = GetStringLength(SrcStr); 357 if (Len == 0 || !FT->getParamType(1)->isIntegerTy(32))// memchr needs i32. 358 return 0; 359 360 Type *PT = FT->getParamType(0); 361 return EmitMemChr(SrcStr, CI->getArgOperand(1), // include nul. 362 ConstantInt::get(TD->getIntPtrType(PT), Len), 363 B, TD, TLI); 364 } 365 366 // Otherwise, the character is a constant, see if the first argument is 367 // a string literal. If so, we can constant fold. 368 StringRef Str; 369 if (!getConstantStringInfo(SrcStr, Str)) 370 return 0; 371 372 // Compute the offset, make sure to handle the case when we're searching for 373 // zero (a weird way to spell strlen). 374 size_t I = CharC->getSExtValue() == 0 ? 375 Str.size() : Str.find(CharC->getSExtValue()); 376 if (I == StringRef::npos) // Didn't find the char. strchr returns null. 377 return Constant::getNullValue(CI->getType()); 378 379 // strchr(s+n,c) -> gep(s+n+i,c) 380 return B.CreateGEP(SrcStr, B.getInt64(I), "strchr"); 381 } 382 }; 383 384 struct StrRChrOpt : public LibCallOptimization { 385 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 386 // Verify the "strrchr" function prototype. 387 FunctionType *FT = Callee->getFunctionType(); 388 if (FT->getNumParams() != 2 || 389 FT->getReturnType() != B.getInt8PtrTy() || 390 FT->getParamType(0) != FT->getReturnType() || 391 !FT->getParamType(1)->isIntegerTy(32)) 392 return 0; 393 394 Value *SrcStr = CI->getArgOperand(0); 395 ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1)); 396 397 // Cannot fold anything if we're not looking for a constant. 398 if (!CharC) 399 return 0; 400 401 StringRef Str; 402 if (!getConstantStringInfo(SrcStr, Str)) { 403 // strrchr(s, 0) -> strchr(s, 0) 404 if (TD && CharC->isZero()) 405 return EmitStrChr(SrcStr, '\0', B, TD, TLI); 406 return 0; 407 } 408 409 // Compute the offset. 410 size_t I = CharC->getSExtValue() == 0 ? 411 Str.size() : Str.rfind(CharC->getSExtValue()); 412 if (I == StringRef::npos) // Didn't find the char. Return null. 413 return Constant::getNullValue(CI->getType()); 414 415 // strrchr(s+n,c) -> gep(s+n+i,c) 416 return B.CreateGEP(SrcStr, B.getInt64(I), "strrchr"); 417 } 418 }; 419 420 struct StrCmpOpt : public LibCallOptimization { 421 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) { 422 // Verify the "strcmp" function prototype. 423 FunctionType *FT = Callee->getFunctionType(); 424 if (FT->getNumParams() != 2 || 425 !FT->getReturnType()->isIntegerTy(32) || 426 FT->getParamType(0) != FT->getParamType(1) || 427 FT->getParamType(0) != B.getInt8PtrTy()) 428 return 0; 429 430 Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1); 431 if (Str1P == Str2P) // strcmp(x,x) -> 0 432 return ConstantInt::get(CI->getType(), 0); 433 434 StringRef Str1, Str2; 435 bool HasStr1 = getConstantStringInfo(Str1P, Str1); 436 bool HasStr2 = getConstantStringInfo(Str2P, Str2); 437 438 // strcmp(x, y) -> cnst (if both x and y are constant strings) 439 if (HasStr1 && HasStr2) 440 return ConstantInt::get(CI->getType(), Str1.compare(Str2)); 441 442 if (HasStr1 && Str1.empty()) // strcmp("", x) -> -*x 443 return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), 444 CI->getType())); 445 446 if (HasStr2 && Str2.empty()) // strcmp(x,"") -> *x 447 return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType()); 448 449 // strcmp(P, "x") -> memcmp(P, "x", 2) 450 uint64_t Len1 = GetStringLength(Str1P); 451 uint64_t Len2 = GetStringLength(Str2P); 452 if (Len1 && Len2) { 453 // These optimizations require DataLayout. 454 if (!TD) return 0; 455 456 Type *PT = FT->getParamType(0); 457 return EmitMemCmp(Str1P, Str2P, 458 ConstantInt::get(TD->getIntPtrType(PT), 459 std::min(Len1, Len2)), B, TD, TLI); 460 } 461 462 return 0; 463 } 464 }; 465 466 struct 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 516 struct 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(Dst->getType()), Len), 1); 541 return Dst; 542 } 543 }; 544 545 } // End anonymous namespace. 546 547 namespace llvm { 548 549 class 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(); 571 public: 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 580 void 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 600 Value *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 613 LibCallSimplifier::LibCallSimplifier(const DataLayout *TD, 614 const TargetLibraryInfo *TLI) { 615 Impl = new LibCallSimplifierImpl(TD, TLI); 616 } 617 618 LibCallSimplifier::~LibCallSimplifier() { 619 delete Impl; 620 } 621 622 Value *LibCallSimplifier::optimizeCall(CallInst *CI) { 623 return Impl->optimizeCall(CI); 624 } 625 626 } 627