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