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