blob: c57991bd9e3427b46d7e8d92788911774f86b361 [file] [log] [blame]
Meador Inge5e890452012-10-13 16:45:24 +00001//===------ 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;
Meador Ingeb69bf6b2012-11-11 03:51:43 +000037 const LibCallSimplifier *LCS;
Meador Inge5e890452012-10-13 16:45:24 +000038 LLVMContext* Context;
39public:
40 LibCallOptimization() { }
41 virtual ~LibCallOptimization() {}
42
43 /// callOptimizer - This pure virtual method is implemented by base classes to
44 /// do various optimizations. If this returns null then no transformation was
45 /// performed. If it returns CI, then it transformed the call and CI is to be
46 /// deleted. If it returns something else, replace CI with the new value and
47 /// delete CI.
48 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)
49 =0;
50
51 Value *optimizeCall(CallInst *CI, const DataLayout *TD,
Meador Ingeb69bf6b2012-11-11 03:51:43 +000052 const TargetLibraryInfo *TLI,
53 const LibCallSimplifier *LCS, IRBuilder<> &B) {
Meador Inge5e890452012-10-13 16:45:24 +000054 Caller = CI->getParent()->getParent();
55 this->TD = TD;
56 this->TLI = TLI;
Meador Ingeb69bf6b2012-11-11 03:51:43 +000057 this->LCS = LCS;
Meador Inge5e890452012-10-13 16:45:24 +000058 if (CI->getCalledFunction())
59 Context = &CI->getCalledFunction()->getContext();
60
61 // We never change the calling convention.
62 if (CI->getCallingConv() != llvm::CallingConv::C)
63 return NULL;
64
65 return callOptimizer(CI->getCalledFunction(), CI, B);
66 }
67};
68
69//===----------------------------------------------------------------------===//
Meador Inge57cfd712012-10-31 03:33:06 +000070// Helper Functions
71//===----------------------------------------------------------------------===//
72
73/// isOnlyUsedInZeroEqualityComparison - Return true if it only matters that the
74/// value is equal or not-equal to zero.
75static bool isOnlyUsedInZeroEqualityComparison(Value *V) {
76 for (Value::use_iterator UI = V->use_begin(), E = V->use_end();
77 UI != E; ++UI) {
78 if (ICmpInst *IC = dyn_cast<ICmpInst>(*UI))
79 if (IC->isEquality())
80 if (Constant *C = dyn_cast<Constant>(IC->getOperand(1)))
81 if (C->isNullValue())
82 continue;
83 // Unknown instruction.
84 return false;
85 }
86 return true;
87}
88
Meador Inge6e1591a2012-11-11 03:51:48 +000089/// isOnlyUsedInEqualityComparison - Return true if it is only used in equality
90/// comparisons with With.
91static bool isOnlyUsedInEqualityComparison(Value *V, Value *With) {
92 for (Value::use_iterator UI = V->use_begin(), E = V->use_end();
93 UI != E; ++UI) {
94 if (ICmpInst *IC = dyn_cast<ICmpInst>(*UI))
95 if (IC->isEquality() && IC->getOperand(1) == With)
96 continue;
97 // Unknown instruction.
98 return false;
99 }
100 return true;
101}
102
Meador Inge57cfd712012-10-31 03:33:06 +0000103//===----------------------------------------------------------------------===//
Meador Inge5e890452012-10-13 16:45:24 +0000104// Fortified Library Call Optimizations
105//===----------------------------------------------------------------------===//
106
107struct FortifiedLibCallOptimization : public LibCallOptimization {
108protected:
109 virtual bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp,
110 bool isString) const = 0;
111};
112
113struct InstFortifiedLibCallOptimization : public FortifiedLibCallOptimization {
114 CallInst *CI;
115
116 bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp, bool isString) const {
117 if (CI->getArgOperand(SizeCIOp) == CI->getArgOperand(SizeArgOp))
118 return true;
119 if (ConstantInt *SizeCI =
120 dyn_cast<ConstantInt>(CI->getArgOperand(SizeCIOp))) {
121 if (SizeCI->isAllOnesValue())
122 return true;
123 if (isString) {
124 uint64_t Len = GetStringLength(CI->getArgOperand(SizeArgOp));
125 // If the length is 0 we don't know how long it is and so we can't
126 // remove the check.
127 if (Len == 0) return false;
128 return SizeCI->getZExtValue() >= Len;
129 }
130 if (ConstantInt *Arg = dyn_cast<ConstantInt>(
131 CI->getArgOperand(SizeArgOp)))
132 return SizeCI->getZExtValue() >= Arg->getZExtValue();
133 }
134 return false;
135 }
136};
137
138struct MemCpyChkOpt : public InstFortifiedLibCallOptimization {
139 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
140 this->CI = CI;
141 FunctionType *FT = Callee->getFunctionType();
Chandler Carruthece6c6b2012-11-01 08:07:29 +0000142 LLVMContext &Context = CI->getParent()->getContext();
Meador Inge5e890452012-10-13 16:45:24 +0000143
144 // Check if this has the right signature.
145 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
146 !FT->getParamType(0)->isPointerTy() ||
147 !FT->getParamType(1)->isPointerTy() ||
Chandler Carruthece6c6b2012-11-01 08:07:29 +0000148 FT->getParamType(2) != TD->getIntPtrType(Context) ||
149 FT->getParamType(3) != TD->getIntPtrType(Context))
Meador Inge5e890452012-10-13 16:45:24 +0000150 return 0;
151
152 if (isFoldable(3, 2, false)) {
153 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
154 CI->getArgOperand(2), 1);
155 return CI->getArgOperand(0);
156 }
157 return 0;
158 }
159};
160
161struct MemMoveChkOpt : public InstFortifiedLibCallOptimization {
162 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
163 this->CI = CI;
164 FunctionType *FT = Callee->getFunctionType();
Chandler Carruthece6c6b2012-11-01 08:07:29 +0000165 LLVMContext &Context = CI->getParent()->getContext();
Meador Inge5e890452012-10-13 16:45:24 +0000166
167 // Check if this has the right signature.
168 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
169 !FT->getParamType(0)->isPointerTy() ||
170 !FT->getParamType(1)->isPointerTy() ||
Chandler Carruthece6c6b2012-11-01 08:07:29 +0000171 FT->getParamType(2) != TD->getIntPtrType(Context) ||
172 FT->getParamType(3) != TD->getIntPtrType(Context))
Meador Inge5e890452012-10-13 16:45:24 +0000173 return 0;
174
175 if (isFoldable(3, 2, false)) {
176 B.CreateMemMove(CI->getArgOperand(0), CI->getArgOperand(1),
177 CI->getArgOperand(2), 1);
178 return CI->getArgOperand(0);
179 }
180 return 0;
181 }
182};
183
184struct MemSetChkOpt : public InstFortifiedLibCallOptimization {
185 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
186 this->CI = CI;
187 FunctionType *FT = Callee->getFunctionType();
Chandler Carruthece6c6b2012-11-01 08:07:29 +0000188 LLVMContext &Context = CI->getParent()->getContext();
Meador Inge5e890452012-10-13 16:45:24 +0000189
190 // Check if this has the right signature.
191 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
192 !FT->getParamType(0)->isPointerTy() ||
193 !FT->getParamType(1)->isIntegerTy() ||
Chandler Carruthece6c6b2012-11-01 08:07:29 +0000194 FT->getParamType(2) != TD->getIntPtrType(Context) ||
195 FT->getParamType(3) != TD->getIntPtrType(Context))
Meador Inge5e890452012-10-13 16:45:24 +0000196 return 0;
197
198 if (isFoldable(3, 2, false)) {
199 Value *Val = B.CreateIntCast(CI->getArgOperand(1), B.getInt8Ty(),
200 false);
201 B.CreateMemSet(CI->getArgOperand(0), Val, CI->getArgOperand(2), 1);
202 return CI->getArgOperand(0);
203 }
204 return 0;
205 }
206};
207
208struct StrCpyChkOpt : public InstFortifiedLibCallOptimization {
209 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
210 this->CI = CI;
211 StringRef Name = Callee->getName();
212 FunctionType *FT = Callee->getFunctionType();
213 LLVMContext &Context = CI->getParent()->getContext();
214
215 // Check if this has the right signature.
216 if (FT->getNumParams() != 3 ||
217 FT->getReturnType() != FT->getParamType(0) ||
218 FT->getParamType(0) != FT->getParamType(1) ||
219 FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
Chandler Carruthece6c6b2012-11-01 08:07:29 +0000220 FT->getParamType(2) != TD->getIntPtrType(Context))
Meador Inge5e890452012-10-13 16:45:24 +0000221 return 0;
222
Meador Inge0c41d572012-10-18 18:12:40 +0000223 Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
224 if (Dst == Src) // __strcpy_chk(x,x) -> x
225 return Src;
226
Meador Inge5e890452012-10-13 16:45:24 +0000227 // If a) we don't have any length information, or b) we know this will
Meador Ingefa9d1372012-10-31 00:20:51 +0000228 // fit then just lower to a plain strcpy. Otherwise we'll keep our
229 // strcpy_chk call which may fail at runtime if the size is too long.
Meador Inge5e890452012-10-13 16:45:24 +0000230 // TODO: It might be nice to get a maximum length out of the possible
231 // string lengths for varying.
232 if (isFoldable(2, 1, true)) {
Meador Inge0c41d572012-10-18 18:12:40 +0000233 Value *Ret = EmitStrCpy(Dst, Src, B, TD, TLI, Name.substr(2, 6));
234 return Ret;
235 } else {
236 // Maybe we can stil fold __strcpy_chk to __memcpy_chk.
237 uint64_t Len = GetStringLength(Src);
238 if (Len == 0) return 0;
239
240 // This optimization require DataLayout.
241 if (!TD) return 0;
242
243 Value *Ret =
244 EmitMemCpyChk(Dst, Src,
Chandler Carruthece6c6b2012-11-01 08:07:29 +0000245 ConstantInt::get(TD->getIntPtrType(Context), Len),
246 CI->getArgOperand(2), B, TD, TLI);
Meador Inge5e890452012-10-13 16:45:24 +0000247 return Ret;
248 }
249 return 0;
250 }
251};
252
Meador Ingefa9d1372012-10-31 00:20:51 +0000253struct StpCpyChkOpt : public InstFortifiedLibCallOptimization {
254 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
255 this->CI = CI;
256 StringRef Name = Callee->getName();
257 FunctionType *FT = Callee->getFunctionType();
258 LLVMContext &Context = CI->getParent()->getContext();
259
260 // Check if this has the right signature.
261 if (FT->getNumParams() != 3 ||
262 FT->getReturnType() != FT->getParamType(0) ||
263 FT->getParamType(0) != FT->getParamType(1) ||
264 FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
265 FT->getParamType(2) != TD->getIntPtrType(FT->getParamType(0)))
266 return 0;
267
268 Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
269 if (Dst == Src) { // stpcpy(x,x) -> x+strlen(x)
270 Value *StrLen = EmitStrLen(Src, B, TD, TLI);
271 return StrLen ? B.CreateInBoundsGEP(Dst, StrLen) : 0;
272 }
273
274 // If a) we don't have any length information, or b) we know this will
275 // fit then just lower to a plain stpcpy. Otherwise we'll keep our
276 // stpcpy_chk call which may fail at runtime if the size is too long.
277 // TODO: It might be nice to get a maximum length out of the possible
278 // string lengths for varying.
279 if (isFoldable(2, 1, true)) {
280 Value *Ret = EmitStrCpy(Dst, Src, B, TD, TLI, Name.substr(2, 6));
281 return Ret;
282 } else {
283 // Maybe we can stil fold __stpcpy_chk to __memcpy_chk.
284 uint64_t Len = GetStringLength(Src);
285 if (Len == 0) return 0;
286
287 // This optimization require DataLayout.
288 if (!TD) return 0;
289
290 Type *PT = FT->getParamType(0);
291 Value *LenV = ConstantInt::get(TD->getIntPtrType(PT), Len);
292 Value *DstEnd = B.CreateGEP(Dst,
293 ConstantInt::get(TD->getIntPtrType(PT),
294 Len - 1));
295 if (!EmitMemCpyChk(Dst, Src, LenV, CI->getArgOperand(2), B, TD, TLI))
296 return 0;
297 return DstEnd;
298 }
299 return 0;
300 }
301};
302
Meador Inge5e890452012-10-13 16:45:24 +0000303struct StrNCpyChkOpt : public InstFortifiedLibCallOptimization {
304 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
305 this->CI = CI;
306 StringRef Name = Callee->getName();
307 FunctionType *FT = Callee->getFunctionType();
308 LLVMContext &Context = CI->getParent()->getContext();
309
310 // Check if this has the right signature.
311 if (FT->getNumParams() != 4 || FT->getReturnType() != FT->getParamType(0) ||
312 FT->getParamType(0) != FT->getParamType(1) ||
313 FT->getParamType(0) != Type::getInt8PtrTy(Context) ||
314 !FT->getParamType(2)->isIntegerTy() ||
Chandler Carruthece6c6b2012-11-01 08:07:29 +0000315 FT->getParamType(3) != TD->getIntPtrType(Context))
Meador Inge5e890452012-10-13 16:45:24 +0000316 return 0;
317
318 if (isFoldable(3, 2, false)) {
319 Value *Ret = EmitStrNCpy(CI->getArgOperand(0), CI->getArgOperand(1),
320 CI->getArgOperand(2), B, TD, TLI,
321 Name.substr(2, 7));
322 return Ret;
323 }
324 return 0;
325 }
326};
327
Meador Inge73d8a582012-10-13 16:45:32 +0000328//===----------------------------------------------------------------------===//
329// String and Memory Library Call Optimizations
330//===----------------------------------------------------------------------===//
331
332struct StrCatOpt : public LibCallOptimization {
333 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
334 // Verify the "strcat" function prototype.
335 FunctionType *FT = Callee->getFunctionType();
336 if (FT->getNumParams() != 2 ||
337 FT->getReturnType() != B.getInt8PtrTy() ||
338 FT->getParamType(0) != FT->getReturnType() ||
339 FT->getParamType(1) != FT->getReturnType())
340 return 0;
341
342 // Extract some information from the instruction
343 Value *Dst = CI->getArgOperand(0);
344 Value *Src = CI->getArgOperand(1);
345
346 // See if we can get the length of the input string.
347 uint64_t Len = GetStringLength(Src);
348 if (Len == 0) return 0;
349 --Len; // Unbias length.
350
351 // Handle the simple, do-nothing case: strcat(x, "") -> x
352 if (Len == 0)
353 return Dst;
354
355 // These optimizations require DataLayout.
356 if (!TD) return 0;
357
358 return emitStrLenMemCpy(Src, Dst, Len, B);
359 }
360
361 Value *emitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len,
362 IRBuilder<> &B) {
363 // We need to find the end of the destination string. That's where the
364 // memory is to be moved to. We just generate a call to strlen.
365 Value *DstLen = EmitStrLen(Dst, B, TD, TLI);
366 if (!DstLen)
367 return 0;
368
369 // Now that we have the destination's length, we must index into the
370 // destination's pointer to get the actual memcpy destination (end of
371 // the string .. we're concatenating).
372 Value *CpyDst = B.CreateGEP(Dst, DstLen, "endptr");
373
374 // We have enough information to now generate the memcpy call to do the
375 // concatenation for us. Make a memcpy to copy the nul byte with align = 1.
376 B.CreateMemCpy(CpyDst, Src,
Chandler Carruthece6c6b2012-11-01 08:07:29 +0000377 ConstantInt::get(TD->getIntPtrType(*Context), Len + 1), 1);
Meador Inge73d8a582012-10-13 16:45:32 +0000378 return Dst;
379 }
380};
381
382struct StrNCatOpt : public StrCatOpt {
383 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
384 // Verify the "strncat" function prototype.
385 FunctionType *FT = Callee->getFunctionType();
386 if (FT->getNumParams() != 3 ||
387 FT->getReturnType() != B.getInt8PtrTy() ||
388 FT->getParamType(0) != FT->getReturnType() ||
389 FT->getParamType(1) != FT->getReturnType() ||
390 !FT->getParamType(2)->isIntegerTy())
391 return 0;
392
393 // Extract some information from the instruction
394 Value *Dst = CI->getArgOperand(0);
395 Value *Src = CI->getArgOperand(1);
396 uint64_t Len;
397
398 // We don't do anything if length is not constant
399 if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)))
400 Len = LengthArg->getZExtValue();
401 else
402 return 0;
403
404 // See if we can get the length of the input string.
405 uint64_t SrcLen = GetStringLength(Src);
406 if (SrcLen == 0) return 0;
407 --SrcLen; // Unbias length.
408
409 // Handle the simple, do-nothing cases:
410 // strncat(x, "", c) -> x
411 // strncat(x, c, 0) -> x
412 if (SrcLen == 0 || Len == 0) return Dst;
413
414 // These optimizations require DataLayout.
415 if (!TD) return 0;
416
417 // We don't optimize this case
418 if (Len < SrcLen) return 0;
419
420 // strncat(x, s, c) -> strcat(x, s)
421 // s is constant so the strcat can be optimized further
422 return emitStrLenMemCpy(Src, Dst, SrcLen, B);
423 }
424};
425
Meador Inge186f8d92012-10-13 16:45:37 +0000426struct StrChrOpt : public LibCallOptimization {
427 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
428 // Verify the "strchr" function prototype.
429 FunctionType *FT = Callee->getFunctionType();
430 if (FT->getNumParams() != 2 ||
431 FT->getReturnType() != B.getInt8PtrTy() ||
432 FT->getParamType(0) != FT->getReturnType() ||
433 !FT->getParamType(1)->isIntegerTy(32))
434 return 0;
435
436 Value *SrcStr = CI->getArgOperand(0);
437
438 // If the second operand is non-constant, see if we can compute the length
439 // of the input string and turn this into memchr.
440 ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1));
441 if (CharC == 0) {
442 // These optimizations require DataLayout.
443 if (!TD) return 0;
444
445 uint64_t Len = GetStringLength(SrcStr);
446 if (Len == 0 || !FT->getParamType(1)->isIntegerTy(32))// memchr needs i32.
447 return 0;
448
449 return EmitMemChr(SrcStr, CI->getArgOperand(1), // include nul.
Chandler Carruthece6c6b2012-11-01 08:07:29 +0000450 ConstantInt::get(TD->getIntPtrType(*Context), Len),
Meador Inge186f8d92012-10-13 16:45:37 +0000451 B, TD, TLI);
452 }
453
454 // Otherwise, the character is a constant, see if the first argument is
455 // a string literal. If so, we can constant fold.
456 StringRef Str;
457 if (!getConstantStringInfo(SrcStr, Str))
458 return 0;
459
460 // Compute the offset, make sure to handle the case when we're searching for
461 // zero (a weird way to spell strlen).
462 size_t I = CharC->getSExtValue() == 0 ?
463 Str.size() : Str.find(CharC->getSExtValue());
464 if (I == StringRef::npos) // Didn't find the char. strchr returns null.
465 return Constant::getNullValue(CI->getType());
466
467 // strchr(s+n,c) -> gep(s+n+i,c)
468 return B.CreateGEP(SrcStr, B.getInt64(I), "strchr");
469 }
470};
471
472struct StrRChrOpt : public LibCallOptimization {
473 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
474 // Verify the "strrchr" function prototype.
475 FunctionType *FT = Callee->getFunctionType();
476 if (FT->getNumParams() != 2 ||
477 FT->getReturnType() != B.getInt8PtrTy() ||
478 FT->getParamType(0) != FT->getReturnType() ||
479 !FT->getParamType(1)->isIntegerTy(32))
480 return 0;
481
482 Value *SrcStr = CI->getArgOperand(0);
483 ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getArgOperand(1));
484
485 // Cannot fold anything if we're not looking for a constant.
486 if (!CharC)
487 return 0;
488
489 StringRef Str;
490 if (!getConstantStringInfo(SrcStr, Str)) {
491 // strrchr(s, 0) -> strchr(s, 0)
492 if (TD && CharC->isZero())
493 return EmitStrChr(SrcStr, '\0', B, TD, TLI);
494 return 0;
495 }
496
497 // Compute the offset.
498 size_t I = CharC->getSExtValue() == 0 ?
499 Str.size() : Str.rfind(CharC->getSExtValue());
500 if (I == StringRef::npos) // Didn't find the char. Return null.
501 return Constant::getNullValue(CI->getType());
502
503 // strrchr(s+n,c) -> gep(s+n+i,c)
504 return B.CreateGEP(SrcStr, B.getInt64(I), "strrchr");
505 }
506};
507
Meador Ingea239c2e2012-10-15 03:47:37 +0000508struct StrCmpOpt : public LibCallOptimization {
509 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
510 // Verify the "strcmp" function prototype.
511 FunctionType *FT = Callee->getFunctionType();
512 if (FT->getNumParams() != 2 ||
513 !FT->getReturnType()->isIntegerTy(32) ||
514 FT->getParamType(0) != FT->getParamType(1) ||
515 FT->getParamType(0) != B.getInt8PtrTy())
516 return 0;
517
518 Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1);
519 if (Str1P == Str2P) // strcmp(x,x) -> 0
520 return ConstantInt::get(CI->getType(), 0);
521
522 StringRef Str1, Str2;
523 bool HasStr1 = getConstantStringInfo(Str1P, Str1);
524 bool HasStr2 = getConstantStringInfo(Str2P, Str2);
525
526 // strcmp(x, y) -> cnst (if both x and y are constant strings)
527 if (HasStr1 && HasStr2)
528 return ConstantInt::get(CI->getType(), Str1.compare(Str2));
529
530 if (HasStr1 && Str1.empty()) // strcmp("", x) -> -*x
531 return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"),
532 CI->getType()));
533
534 if (HasStr2 && Str2.empty()) // strcmp(x,"") -> *x
535 return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType());
536
537 // strcmp(P, "x") -> memcmp(P, "x", 2)
538 uint64_t Len1 = GetStringLength(Str1P);
539 uint64_t Len2 = GetStringLength(Str2P);
540 if (Len1 && Len2) {
541 // These optimizations require DataLayout.
542 if (!TD) return 0;
543
544 return EmitMemCmp(Str1P, Str2P,
Chandler Carruthece6c6b2012-11-01 08:07:29 +0000545 ConstantInt::get(TD->getIntPtrType(*Context),
Meador Ingea239c2e2012-10-15 03:47:37 +0000546 std::min(Len1, Len2)), B, TD, TLI);
547 }
548
549 return 0;
550 }
551};
552
553struct StrNCmpOpt : public LibCallOptimization {
554 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
555 // Verify the "strncmp" function prototype.
556 FunctionType *FT = Callee->getFunctionType();
557 if (FT->getNumParams() != 3 ||
558 !FT->getReturnType()->isIntegerTy(32) ||
559 FT->getParamType(0) != FT->getParamType(1) ||
560 FT->getParamType(0) != B.getInt8PtrTy() ||
561 !FT->getParamType(2)->isIntegerTy())
562 return 0;
563
564 Value *Str1P = CI->getArgOperand(0), *Str2P = CI->getArgOperand(1);
565 if (Str1P == Str2P) // strncmp(x,x,n) -> 0
566 return ConstantInt::get(CI->getType(), 0);
567
568 // Get the length argument if it is constant.
569 uint64_t Length;
570 if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getArgOperand(2)))
571 Length = LengthArg->getZExtValue();
572 else
573 return 0;
574
575 if (Length == 0) // strncmp(x,y,0) -> 0
576 return ConstantInt::get(CI->getType(), 0);
577
578 if (TD && Length == 1) // strncmp(x,y,1) -> memcmp(x,y,1)
579 return EmitMemCmp(Str1P, Str2P, CI->getArgOperand(2), B, TD, TLI);
580
581 StringRef Str1, Str2;
582 bool HasStr1 = getConstantStringInfo(Str1P, Str1);
583 bool HasStr2 = getConstantStringInfo(Str2P, Str2);
584
585 // strncmp(x, y) -> cnst (if both x and y are constant strings)
586 if (HasStr1 && HasStr2) {
587 StringRef SubStr1 = Str1.substr(0, Length);
588 StringRef SubStr2 = Str2.substr(0, Length);
589 return ConstantInt::get(CI->getType(), SubStr1.compare(SubStr2));
590 }
591
592 if (HasStr1 && Str1.empty()) // strncmp("", x, n) -> -*x
593 return B.CreateNeg(B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"),
594 CI->getType()));
595
596 if (HasStr2 && Str2.empty()) // strncmp(x, "", n) -> *x
597 return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType());
598
599 return 0;
600 }
601};
602
Meador Inge0c41d572012-10-18 18:12:40 +0000603struct StrCpyOpt : public LibCallOptimization {
604 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
605 // Verify the "strcpy" function prototype.
606 FunctionType *FT = Callee->getFunctionType();
607 if (FT->getNumParams() != 2 ||
608 FT->getReturnType() != FT->getParamType(0) ||
609 FT->getParamType(0) != FT->getParamType(1) ||
610 FT->getParamType(0) != B.getInt8PtrTy())
611 return 0;
612
613 Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
614 if (Dst == Src) // strcpy(x,x) -> x
615 return Src;
616
617 // These optimizations require DataLayout.
618 if (!TD) return 0;
619
620 // See if we can get the length of the input string.
621 uint64_t Len = GetStringLength(Src);
622 if (Len == 0) return 0;
623
624 // We have enough information to now generate the memcpy call to do the
625 // copy for us. Make a memcpy to copy the nul byte with align = 1.
626 B.CreateMemCpy(Dst, Src,
Chandler Carruthece6c6b2012-11-01 08:07:29 +0000627 ConstantInt::get(TD->getIntPtrType(*Context), Len), 1);
Meador Inge0c41d572012-10-18 18:12:40 +0000628 return Dst;
629 }
630};
631
Meador Ingee6d781f2012-10-31 00:20:56 +0000632struct StpCpyOpt: public LibCallOptimization {
633 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
634 // Verify the "stpcpy" function prototype.
635 FunctionType *FT = Callee->getFunctionType();
636 if (FT->getNumParams() != 2 ||
637 FT->getReturnType() != FT->getParamType(0) ||
638 FT->getParamType(0) != FT->getParamType(1) ||
639 FT->getParamType(0) != B.getInt8PtrTy())
640 return 0;
641
642 // These optimizations require DataLayout.
643 if (!TD) return 0;
644
645 Value *Dst = CI->getArgOperand(0), *Src = CI->getArgOperand(1);
646 if (Dst == Src) { // stpcpy(x,x) -> x+strlen(x)
647 Value *StrLen = EmitStrLen(Src, B, TD, TLI);
648 return StrLen ? B.CreateInBoundsGEP(Dst, StrLen) : 0;
649 }
650
651 // See if we can get the length of the input string.
652 uint64_t Len = GetStringLength(Src);
653 if (Len == 0) return 0;
654
655 Type *PT = FT->getParamType(0);
656 Value *LenV = ConstantInt::get(TD->getIntPtrType(PT), Len);
657 Value *DstEnd = B.CreateGEP(Dst,
658 ConstantInt::get(TD->getIntPtrType(PT),
659 Len - 1));
660
661 // We have enough information to now generate the memcpy call to do the
662 // copy for us. Make a memcpy to copy the nul byte with align = 1.
663 B.CreateMemCpy(Dst, Src, LenV, 1);
664 return DstEnd;
665 }
666};
667
Meador Ingea0885fb2012-10-31 03:33:00 +0000668struct StrNCpyOpt : public LibCallOptimization {
669 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
670 FunctionType *FT = Callee->getFunctionType();
671 if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
672 FT->getParamType(0) != FT->getParamType(1) ||
673 FT->getParamType(0) != B.getInt8PtrTy() ||
674 !FT->getParamType(2)->isIntegerTy())
675 return 0;
676
677 Value *Dst = CI->getArgOperand(0);
678 Value *Src = CI->getArgOperand(1);
679 Value *LenOp = CI->getArgOperand(2);
680
681 // See if we can get the length of the input string.
682 uint64_t SrcLen = GetStringLength(Src);
683 if (SrcLen == 0) return 0;
684 --SrcLen;
685
686 if (SrcLen == 0) {
687 // strncpy(x, "", y) -> memset(x, '\0', y, 1)
688 B.CreateMemSet(Dst, B.getInt8('\0'), LenOp, 1);
689 return Dst;
690 }
691
692 uint64_t Len;
693 if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(LenOp))
694 Len = LengthArg->getZExtValue();
695 else
696 return 0;
697
698 if (Len == 0) return Dst; // strncpy(x, y, 0) -> x
699
700 // These optimizations require DataLayout.
701 if (!TD) return 0;
702
703 // Let strncpy handle the zero padding
704 if (Len > SrcLen+1) return 0;
705
706 Type *PT = FT->getParamType(0);
707 // strncpy(x, s, c) -> memcpy(x, s, c, 1) [s and c are constant]
708 B.CreateMemCpy(Dst, Src,
709 ConstantInt::get(TD->getIntPtrType(PT), Len), 1);
710
711 return Dst;
712 }
713};
714
Meador Inge57cfd712012-10-31 03:33:06 +0000715struct StrLenOpt : public LibCallOptimization {
716 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
717 FunctionType *FT = Callee->getFunctionType();
718 if (FT->getNumParams() != 1 ||
719 FT->getParamType(0) != B.getInt8PtrTy() ||
720 !FT->getReturnType()->isIntegerTy())
721 return 0;
722
723 Value *Src = CI->getArgOperand(0);
724
725 // Constant folding: strlen("xyz") -> 3
726 if (uint64_t Len = GetStringLength(Src))
727 return ConstantInt::get(CI->getType(), Len-1);
728
729 // strlen(x) != 0 --> *x != 0
730 // strlen(x) == 0 --> *x == 0
731 if (isOnlyUsedInZeroEqualityComparison(CI))
732 return B.CreateZExt(B.CreateLoad(Src, "strlenfirst"), CI->getType());
733 return 0;
734 }
735};
736
Meador Inge08684d12012-10-31 04:29:58 +0000737struct StrPBrkOpt : public LibCallOptimization {
738 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
739 FunctionType *FT = Callee->getFunctionType();
740 if (FT->getNumParams() != 2 ||
741 FT->getParamType(0) != B.getInt8PtrTy() ||
742 FT->getParamType(1) != FT->getParamType(0) ||
743 FT->getReturnType() != FT->getParamType(0))
744 return 0;
745
746 StringRef S1, S2;
747 bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1);
748 bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2);
749
750 // strpbrk(s, "") -> NULL
751 // strpbrk("", s) -> NULL
752 if ((HasS1 && S1.empty()) || (HasS2 && S2.empty()))
753 return Constant::getNullValue(CI->getType());
754
755 // Constant folding.
756 if (HasS1 && HasS2) {
757 size_t I = S1.find_first_of(S2);
758 if (I == std::string::npos) // No match.
759 return Constant::getNullValue(CI->getType());
760
761 return B.CreateGEP(CI->getArgOperand(0), B.getInt64(I), "strpbrk");
762 }
763
764 // strpbrk(s, "a") -> strchr(s, 'a')
765 if (TD && HasS2 && S2.size() == 1)
766 return EmitStrChr(CI->getArgOperand(0), S2[0], B, TD, TLI);
767
768 return 0;
769 }
770};
771
Meador Ingee0f1dca2012-10-31 14:58:26 +0000772struct StrToOpt : public LibCallOptimization {
773 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
774 FunctionType *FT = Callee->getFunctionType();
775 if ((FT->getNumParams() != 2 && FT->getNumParams() != 3) ||
776 !FT->getParamType(0)->isPointerTy() ||
777 !FT->getParamType(1)->isPointerTy())
778 return 0;
779
780 Value *EndPtr = CI->getArgOperand(1);
781 if (isa<ConstantPointerNull>(EndPtr)) {
782 // With a null EndPtr, this function won't capture the main argument.
783 // It would be readonly too, except that it still may write to errno.
784 CI->addAttribute(1, Attributes::get(Callee->getContext(),
785 Attributes::NoCapture));
786 }
787
788 return 0;
789 }
790};
791
Meador Inge7629de32012-11-08 01:33:50 +0000792struct StrSpnOpt : public LibCallOptimization {
793 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
794 FunctionType *FT = Callee->getFunctionType();
795 if (FT->getNumParams() != 2 ||
796 FT->getParamType(0) != B.getInt8PtrTy() ||
797 FT->getParamType(1) != FT->getParamType(0) ||
798 !FT->getReturnType()->isIntegerTy())
799 return 0;
800
801 StringRef S1, S2;
802 bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1);
803 bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2);
804
805 // strspn(s, "") -> 0
806 // strspn("", s) -> 0
807 if ((HasS1 && S1.empty()) || (HasS2 && S2.empty()))
808 return Constant::getNullValue(CI->getType());
809
810 // Constant folding.
811 if (HasS1 && HasS2) {
812 size_t Pos = S1.find_first_not_of(S2);
813 if (Pos == StringRef::npos) Pos = S1.size();
814 return ConstantInt::get(CI->getType(), Pos);
815 }
816
817 return 0;
818 }
819};
820
Meador Inge5464ee72012-11-10 15:16:48 +0000821struct StrCSpnOpt : public LibCallOptimization {
822 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
823 FunctionType *FT = Callee->getFunctionType();
824 if (FT->getNumParams() != 2 ||
825 FT->getParamType(0) != B.getInt8PtrTy() ||
826 FT->getParamType(1) != FT->getParamType(0) ||
827 !FT->getReturnType()->isIntegerTy())
828 return 0;
829
830 StringRef S1, S2;
831 bool HasS1 = getConstantStringInfo(CI->getArgOperand(0), S1);
832 bool HasS2 = getConstantStringInfo(CI->getArgOperand(1), S2);
833
834 // strcspn("", s) -> 0
835 if (HasS1 && S1.empty())
836 return Constant::getNullValue(CI->getType());
837
838 // Constant folding.
839 if (HasS1 && HasS2) {
840 size_t Pos = S1.find_first_of(S2);
841 if (Pos == StringRef::npos) Pos = S1.size();
842 return ConstantInt::get(CI->getType(), Pos);
843 }
844
845 // strcspn(s, "") -> strlen(s)
846 if (TD && HasS2 && S2.empty())
847 return EmitStrLen(CI->getArgOperand(0), B, TD, TLI);
848
849 return 0;
850 }
851};
852
Meador Inge6e1591a2012-11-11 03:51:48 +0000853struct StrStrOpt : public LibCallOptimization {
854 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
855 FunctionType *FT = Callee->getFunctionType();
856 if (FT->getNumParams() != 2 ||
857 !FT->getParamType(0)->isPointerTy() ||
858 !FT->getParamType(1)->isPointerTy() ||
859 !FT->getReturnType()->isPointerTy())
860 return 0;
861
862 // fold strstr(x, x) -> x.
863 if (CI->getArgOperand(0) == CI->getArgOperand(1))
864 return B.CreateBitCast(CI->getArgOperand(0), CI->getType());
865
866 // fold strstr(a, b) == a -> strncmp(a, b, strlen(b)) == 0
867 if (TD && isOnlyUsedInEqualityComparison(CI, CI->getArgOperand(0))) {
868 Value *StrLen = EmitStrLen(CI->getArgOperand(1), B, TD, TLI);
869 if (!StrLen)
870 return 0;
871 Value *StrNCmp = EmitStrNCmp(CI->getArgOperand(0), CI->getArgOperand(1),
872 StrLen, B, TD, TLI);
873 if (!StrNCmp)
874 return 0;
875 for (Value::use_iterator UI = CI->use_begin(), UE = CI->use_end();
876 UI != UE; ) {
877 ICmpInst *Old = cast<ICmpInst>(*UI++);
878 Value *Cmp = B.CreateICmp(Old->getPredicate(), StrNCmp,
879 ConstantInt::getNullValue(StrNCmp->getType()),
880 "cmp");
881 LCS->replaceAllUsesWith(Old, Cmp);
882 }
883 return CI;
884 }
885
886 // See if either input string is a constant string.
887 StringRef SearchStr, ToFindStr;
888 bool HasStr1 = getConstantStringInfo(CI->getArgOperand(0), SearchStr);
889 bool HasStr2 = getConstantStringInfo(CI->getArgOperand(1), ToFindStr);
890
891 // fold strstr(x, "") -> x.
892 if (HasStr2 && ToFindStr.empty())
893 return B.CreateBitCast(CI->getArgOperand(0), CI->getType());
894
895 // If both strings are known, constant fold it.
896 if (HasStr1 && HasStr2) {
897 std::string::size_type Offset = SearchStr.find(ToFindStr);
898
899 if (Offset == StringRef::npos) // strstr("foo", "bar") -> null
900 return Constant::getNullValue(CI->getType());
901
902 // strstr("abcd", "bc") -> gep((char*)"abcd", 1)
903 Value *Result = CastToCStr(CI->getArgOperand(0), B);
904 Result = B.CreateConstInBoundsGEP1_64(Result, Offset, "strstr");
905 return B.CreateBitCast(Result, CI->getType());
906 }
907
908 // fold strstr(x, "y") -> strchr(x, 'y').
909 if (HasStr2 && ToFindStr.size() == 1) {
910 Value *StrChr= EmitStrChr(CI->getArgOperand(0), ToFindStr[0], B, TD, TLI);
911 return StrChr ? B.CreateBitCast(StrChr, CI->getType()) : 0;
912 }
913 return 0;
914 }
915};
916
Meador Ingebb51ec82012-11-11 05:11:20 +0000917struct MemCmpOpt : public LibCallOptimization {
918 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
919 FunctionType *FT = Callee->getFunctionType();
920 if (FT->getNumParams() != 3 || !FT->getParamType(0)->isPointerTy() ||
921 !FT->getParamType(1)->isPointerTy() ||
922 !FT->getReturnType()->isIntegerTy(32))
923 return 0;
924
925 Value *LHS = CI->getArgOperand(0), *RHS = CI->getArgOperand(1);
926
927 if (LHS == RHS) // memcmp(s,s,x) -> 0
928 return Constant::getNullValue(CI->getType());
929
930 // Make sure we have a constant length.
931 ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getArgOperand(2));
932 if (!LenC) return 0;
933 uint64_t Len = LenC->getZExtValue();
934
935 if (Len == 0) // memcmp(s1,s2,0) -> 0
936 return Constant::getNullValue(CI->getType());
937
938 // memcmp(S1,S2,1) -> *(unsigned char*)LHS - *(unsigned char*)RHS
939 if (Len == 1) {
940 Value *LHSV = B.CreateZExt(B.CreateLoad(CastToCStr(LHS, B), "lhsc"),
941 CI->getType(), "lhsv");
942 Value *RHSV = B.CreateZExt(B.CreateLoad(CastToCStr(RHS, B), "rhsc"),
943 CI->getType(), "rhsv");
944 return B.CreateSub(LHSV, RHSV, "chardiff");
945 }
946
947 // Constant folding: memcmp(x, y, l) -> cnst (all arguments are constant)
948 StringRef LHSStr, RHSStr;
949 if (getConstantStringInfo(LHS, LHSStr) &&
950 getConstantStringInfo(RHS, RHSStr)) {
951 // Make sure we're not reading out-of-bounds memory.
952 if (Len > LHSStr.size() || Len > RHSStr.size())
953 return 0;
954 uint64_t Ret = memcmp(LHSStr.data(), RHSStr.data(), Len);
955 return ConstantInt::get(CI->getType(), Ret);
956 }
957
958 return 0;
959 }
960};
961
Meador Inge11b04b42012-11-11 05:54:34 +0000962struct MemCpyOpt : public LibCallOptimization {
963 virtual Value *callOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
964 // These optimizations require DataLayout.
965 if (!TD) return 0;
966
967 FunctionType *FT = Callee->getFunctionType();
968 if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
969 !FT->getParamType(0)->isPointerTy() ||
970 !FT->getParamType(1)->isPointerTy() ||
971 FT->getParamType(2) != TD->getIntPtrType(*Context))
972 return 0;
973
974 // memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1)
975 B.CreateMemCpy(CI->getArgOperand(0), CI->getArgOperand(1),
976 CI->getArgOperand(2), 1);
977 return CI->getArgOperand(0);
978 }
979};
980
Meador Inge5e890452012-10-13 16:45:24 +0000981} // End anonymous namespace.
982
983namespace llvm {
984
985class LibCallSimplifierImpl {
Meador Inge5e890452012-10-13 16:45:24 +0000986 const DataLayout *TD;
987 const TargetLibraryInfo *TLI;
Meador Ingeb69bf6b2012-11-11 03:51:43 +0000988 const LibCallSimplifier *LCS;
Meador Inge5e890452012-10-13 16:45:24 +0000989 StringMap<LibCallOptimization*> Optimizations;
990
991 // Fortified library call optimizations.
992 MemCpyChkOpt MemCpyChk;
993 MemMoveChkOpt MemMoveChk;
994 MemSetChkOpt MemSetChk;
995 StrCpyChkOpt StrCpyChk;
Meador Ingefa9d1372012-10-31 00:20:51 +0000996 StpCpyChkOpt StpCpyChk;
Meador Inge5e890452012-10-13 16:45:24 +0000997 StrNCpyChkOpt StrNCpyChk;
998
Meador Ingebb51ec82012-11-11 05:11:20 +0000999 // String library call optimizations.
Meador Inge73d8a582012-10-13 16:45:32 +00001000 StrCatOpt StrCat;
1001 StrNCatOpt StrNCat;
Meador Inge186f8d92012-10-13 16:45:37 +00001002 StrChrOpt StrChr;
1003 StrRChrOpt StrRChr;
Meador Ingea239c2e2012-10-15 03:47:37 +00001004 StrCmpOpt StrCmp;
1005 StrNCmpOpt StrNCmp;
Meador Inge0c41d572012-10-18 18:12:40 +00001006 StrCpyOpt StrCpy;
Meador Ingee6d781f2012-10-31 00:20:56 +00001007 StpCpyOpt StpCpy;
Meador Ingea0885fb2012-10-31 03:33:00 +00001008 StrNCpyOpt StrNCpy;
Meador Inge57cfd712012-10-31 03:33:06 +00001009 StrLenOpt StrLen;
Meador Inge08684d12012-10-31 04:29:58 +00001010 StrPBrkOpt StrPBrk;
Meador Ingee0f1dca2012-10-31 14:58:26 +00001011 StrToOpt StrTo;
Meador Inge7629de32012-11-08 01:33:50 +00001012 StrSpnOpt StrSpn;
Meador Inge5464ee72012-11-10 15:16:48 +00001013 StrCSpnOpt StrCSpn;
Meador Inge6e1591a2012-11-11 03:51:48 +00001014 StrStrOpt StrStr;
Meador Inge73d8a582012-10-13 16:45:32 +00001015
Meador Ingebb51ec82012-11-11 05:11:20 +00001016 // Memory library call optimizations.
1017 MemCmpOpt MemCmp;
Meador Inge11b04b42012-11-11 05:54:34 +00001018 MemCpyOpt MemCpy;
Meador Ingebb51ec82012-11-11 05:11:20 +00001019
Meador Inge5e890452012-10-13 16:45:24 +00001020 void initOptimizations();
Meador Ingee29c8802012-11-10 03:11:10 +00001021 void addOpt(LibFunc::Func F, LibCallOptimization* Opt);
Meador Inge5e890452012-10-13 16:45:24 +00001022public:
Meador Ingeb69bf6b2012-11-11 03:51:43 +00001023 LibCallSimplifierImpl(const DataLayout *TD, const TargetLibraryInfo *TLI,
1024 const LibCallSimplifier *LCS) {
Meador Inge5e890452012-10-13 16:45:24 +00001025 this->TD = TD;
1026 this->TLI = TLI;
Meador Ingeb69bf6b2012-11-11 03:51:43 +00001027 this->LCS = LCS;
Meador Inge5e890452012-10-13 16:45:24 +00001028 }
1029
1030 Value *optimizeCall(CallInst *CI);
1031};
1032
1033void LibCallSimplifierImpl::initOptimizations() {
1034 // Fortified library call optimizations.
1035 Optimizations["__memcpy_chk"] = &MemCpyChk;
1036 Optimizations["__memmove_chk"] = &MemMoveChk;
1037 Optimizations["__memset_chk"] = &MemSetChk;
1038 Optimizations["__strcpy_chk"] = &StrCpyChk;
Meador Ingefa9d1372012-10-31 00:20:51 +00001039 Optimizations["__stpcpy_chk"] = &StpCpyChk;
Meador Inge5e890452012-10-13 16:45:24 +00001040 Optimizations["__strncpy_chk"] = &StrNCpyChk;
1041 Optimizations["__stpncpy_chk"] = &StrNCpyChk;
Meador Inge73d8a582012-10-13 16:45:32 +00001042
Meador Ingebb51ec82012-11-11 05:11:20 +00001043 // String library call optimizations.
Meador Ingee29c8802012-11-10 03:11:10 +00001044 addOpt(LibFunc::strcat, &StrCat);
1045 addOpt(LibFunc::strncat, &StrNCat);
1046 addOpt(LibFunc::strchr, &StrChr);
1047 addOpt(LibFunc::strrchr, &StrRChr);
1048 addOpt(LibFunc::strcmp, &StrCmp);
1049 addOpt(LibFunc::strncmp, &StrNCmp);
1050 addOpt(LibFunc::strcpy, &StrCpy);
1051 addOpt(LibFunc::stpcpy, &StpCpy);
1052 addOpt(LibFunc::strncpy, &StrNCpy);
1053 addOpt(LibFunc::strlen, &StrLen);
1054 addOpt(LibFunc::strpbrk, &StrPBrk);
1055 addOpt(LibFunc::strtol, &StrTo);
1056 addOpt(LibFunc::strtod, &StrTo);
1057 addOpt(LibFunc::strtof, &StrTo);
1058 addOpt(LibFunc::strtoul, &StrTo);
1059 addOpt(LibFunc::strtoll, &StrTo);
1060 addOpt(LibFunc::strtold, &StrTo);
1061 addOpt(LibFunc::strtoull, &StrTo);
1062 addOpt(LibFunc::strspn, &StrSpn);
Meador Inge5464ee72012-11-10 15:16:48 +00001063 addOpt(LibFunc::strcspn, &StrCSpn);
Meador Inge6e1591a2012-11-11 03:51:48 +00001064 addOpt(LibFunc::strstr, &StrStr);
Meador Ingebb51ec82012-11-11 05:11:20 +00001065
1066 // Memory library call optimizations.
1067 addOpt(LibFunc::memcmp, &MemCmp);
Meador Inge11b04b42012-11-11 05:54:34 +00001068 addOpt(LibFunc::memcpy, &MemCpy);
Meador Inge5e890452012-10-13 16:45:24 +00001069}
1070
1071Value *LibCallSimplifierImpl::optimizeCall(CallInst *CI) {
1072 if (Optimizations.empty())
1073 initOptimizations();
1074
1075 Function *Callee = CI->getCalledFunction();
1076 LibCallOptimization *LCO = Optimizations.lookup(Callee->getName());
1077 if (LCO) {
1078 IRBuilder<> Builder(CI);
Meador Ingeb69bf6b2012-11-11 03:51:43 +00001079 return LCO->optimizeCall(CI, TD, TLI, LCS, Builder);
Meador Inge5e890452012-10-13 16:45:24 +00001080 }
1081 return 0;
1082}
1083
Meador Ingee29c8802012-11-10 03:11:10 +00001084void LibCallSimplifierImpl::addOpt(LibFunc::Func F, LibCallOptimization* Opt) {
1085 if (TLI->has(F))
1086 Optimizations[TLI->getName(F)] = Opt;
1087}
1088
Meador Inge5e890452012-10-13 16:45:24 +00001089LibCallSimplifier::LibCallSimplifier(const DataLayout *TD,
1090 const TargetLibraryInfo *TLI) {
Meador Ingeb69bf6b2012-11-11 03:51:43 +00001091 Impl = new LibCallSimplifierImpl(TD, TLI, this);
Meador Inge5e890452012-10-13 16:45:24 +00001092}
1093
1094LibCallSimplifier::~LibCallSimplifier() {
1095 delete Impl;
1096}
1097
1098Value *LibCallSimplifier::optimizeCall(CallInst *CI) {
1099 return Impl->optimizeCall(CI);
1100}
1101
Meador Ingeb69bf6b2012-11-11 03:51:43 +00001102void LibCallSimplifier::replaceAllUsesWith(Instruction *I, Value *With) const {
1103 I->replaceAllUsesWith(With);
1104 I->eraseFromParent();
1105}
1106
Meador Inge5e890452012-10-13 16:45:24 +00001107}