Implement new LibCallSimplifier class
[oota-llvm.git] / lib / Transforms / Utils / SimplifyLibCalls.cpp
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     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
124 struct 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
147 struct 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
171 struct 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     // If a) we don't have any length information, or b) we know this will
187     // fit then just lower to a plain st[rp]cpy. Otherwise we'll keep our
188     // st[rp]cpy_chk call which may fail at runtime if the size is too long.
189     // TODO: It might be nice to get a maximum length out of the possible
190     // string lengths for varying.
191     if (isFoldable(2, 1, true)) {
192       Value *Ret = EmitStrCpy(CI->getArgOperand(0), CI->getArgOperand(1), B, TD,
193                               TLI, Name.substr(2, 6));
194       return Ret;
195     }
196     return 0;
197   }
198 };
199
200 struct StrNCpyChkOpt : public InstFortifiedLibCallOptimization {
201   virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
202     this->CI = CI;
203     StringRef Name = Callee->getName();
204     FunctionType *FT = Callee->getFunctionType();
205     LLVMContext &Context = CI->getParent()->getContext();
206
207     // Check if this has the right signature.
208     if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
209         FT->getParamType(0) != FT->getParamType(1) ||
210         FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
211         !FT->getParamType(2)->isIntegerTy() ||
212         FT->getParamType(3) != TD->getIntPtrType(Context))
213       return 0;
214
215     if (isFoldable(3, 2, false)) {
216       Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1),
217                                CI->getArgOperand(2), B, TD, TLI,
218                                Name.substr(2, 7));
219       return Ret;
220     }
221     return 0;
222   }
223 };
224
225 } // End anonymous namespace.
226
227 namespace llvm {
228
229 class LibCallSimplifierImpl {
230   LibCallSimplifier *Simplifier;
231   const DataLayout *TD;
232   const TargetLibraryInfo *TLI;
233   StringMap<LibCallOptimization*> Optimizations;
234
235   // Fortified library call optimizations.
236   MemCpyChkOpt MemCpyChk;
237   MemMoveChkOpt MemMoveChk;
238   MemSetChkOpt MemSetChk;
239   StrCpyChkOpt StrCpyChk;
240   StrNCpyChkOpt StrNCpyChk;
241
242   void initOptimizations();
243 public:
244   LibCallSimplifierImpl(const DataLayout *TD, const TargetLibraryInfo *TLI) {
245     this->TD = TD;
246     this->TLI = TLI;
247   }
248
249   Value *optimizeCall(CallInst *CI);
250 };
251
252 void LibCallSimplifierImpl::initOptimizations() {
253   // Fortified library call optimizations.
254   Optimizations["__memcpy_chk"] = &MemCpyChk;
255   Optimizations["__memmove_chk"] = &MemMoveChk;
256   Optimizations["__memset_chk"] = &MemSetChk;
257   Optimizations["__strcpy_chk"] = &StrCpyChk;
258   Optimizations["__stpcpy_chk"] = &StrCpyChk;
259   Optimizations["__strncpy_chk"] = &StrNCpyChk;
260   Optimizations["__stpncpy_chk"] = &StrNCpyChk;
261 }
262
263 Value *LibCallSimplifierImpl::optimizeCall(CallInst *CI) {
264   if (Optimizations.empty())
265     initOptimizations();
266
267   Function *Callee = CI->getCalledFunction();
268   LibCallOptimization *LCO = Optimizations.lookup(Callee->getName());
269   if (LCO) {
270     IRBuilder<> Builder(CI);
271     return LCO->optimizeCall(CI, TD, TLI, Builder);
272   }
273   return 0;
274 }
275
276 LibCallSimplifier::LibCallSimplifier(const DataLayout *TD,
277                                      const TargetLibraryInfo *TLI) {
278   Impl = new LibCallSimplifierImpl(TD, TLI);
279 }
280
281 LibCallSimplifier::~LibCallSimplifier() {
282   delete Impl;
283 }
284
285 Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
286   return Impl->optimizeCall(CI);
287 }
288
289 }