blob: 64013d538f682df3ccd19a8c98dfc3c4cddd0d89 [file] [log] [blame]
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001//===- SimplifyLibCalls.cpp - Optimize specific well-known library calls --===//
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 file implements a simple pass that applies a variety of small
11// optimizations for calls to specific well-known function calls (e.g. runtime
12// library functions). For example, a call to the function "exit(3)" that
13// occurs within the main() function can be transformed into a simple "return 3"
14// instruction. Any optimization that takes this form (replace call to library
15// function with simpler code that provides the same result) belongs in this
16// file.
17//
18//===----------------------------------------------------------------------===//
19
20#define DEBUG_TYPE "simplify-libcalls"
21#include "llvm/Transforms/Scalar.h"
22#include "llvm/Intrinsics.h"
Owen Andersonfa5cbd62009-07-03 19:42:02 +000023#include "llvm/LLVMContext.h"
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000024#include "llvm/Module.h"
25#include "llvm/Pass.h"
26#include "llvm/Support/IRBuilder.h"
Evan Cheng0ff39b32008-06-30 07:31:25 +000027#include "llvm/Analysis/ValueTracking.h"
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000028#include "llvm/Target/TargetData.h"
29#include "llvm/ADT/SmallPtrSet.h"
30#include "llvm/ADT/StringMap.h"
31#include "llvm/ADT/Statistic.h"
Daniel Dunbar473955f2009-07-29 22:00:43 +000032#include "llvm/ADT/STLExtras.h"
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000033#include "llvm/Support/Compiler.h"
Chris Lattner56b4f2b2008-05-01 06:39:12 +000034#include "llvm/Support/Debug.h"
Daniel Dunbarf0443c12009-07-26 08:34:35 +000035#include "llvm/Support/raw_ostream.h"
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000036#include "llvm/Config/config.h"
37using namespace llvm;
38
39STATISTIC(NumSimplified, "Number of library calls simplified");
Nick Lewycky0f8df9a2009-01-04 20:27:34 +000040STATISTIC(NumAnnotated, "Number of attributes added to library functions");
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000041
42//===----------------------------------------------------------------------===//
43// Optimizer Base Class
44//===----------------------------------------------------------------------===//
45
46/// This class is the abstract base class for the set of optimizations that
47/// corresponds to one library call.
48namespace {
49class VISIBILITY_HIDDEN LibCallOptimization {
50protected:
51 Function *Caller;
52 const TargetData *TD;
Owen Andersonfa5cbd62009-07-03 19:42:02 +000053 LLVMContext* Context;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000054public:
55 LibCallOptimization() { }
56 virtual ~LibCallOptimization() {}
57
58 /// CallOptimizer - This pure virtual method is implemented by base classes to
59 /// do various optimizations. If this returns null then no transformation was
60 /// performed. If it returns CI, then it transformed the call and CI is to be
61 /// deleted. If it returns something else, replace CI with the new value and
62 /// delete CI.
Eric Christopher7a61d702008-08-08 19:39:37 +000063 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)
64 =0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000065
Eric Christopher7a61d702008-08-08 19:39:37 +000066 Value *OptimizeCall(CallInst *CI, const TargetData &TD, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000067 Caller = CI->getParent()->getParent();
68 this->TD = &TD;
Owen Andersonfa5cbd62009-07-03 19:42:02 +000069 if (CI->getCalledFunction())
Owen Andersone922c022009-07-22 00:24:57 +000070 Context = &CI->getCalledFunction()->getContext();
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000071 return CallOptimizer(CI->getCalledFunction(), CI, B);
72 }
73
74 /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
Eric Christopher7a61d702008-08-08 19:39:37 +000075 Value *CastToCStr(Value *V, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000076
77 /// EmitStrLen - Emit a call to the strlen function to the builder, for the
78 /// specified pointer. Ptr is required to be some pointer type, and the
79 /// return value has 'intptr_t' type.
Eric Christopher7a61d702008-08-08 19:39:37 +000080 Value *EmitStrLen(Value *Ptr, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000081
82 /// EmitMemCpy - Emit a call to the memcpy function to the builder. This
83 /// always expects that the size has type 'intptr_t' and Dst/Src are pointers.
84 Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len,
Eric Christopher7a61d702008-08-08 19:39:37 +000085 unsigned Align, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000086
87 /// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
88 /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
Eric Christopher7a61d702008-08-08 19:39:37 +000089 Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B);
Nick Lewycky13a09e22008-12-21 00:19:21 +000090
91 /// EmitMemCmp - Emit a call to the memcmp function.
92 Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B);
93
Chris Lattnerf5b6bc72009-04-12 05:06:39 +000094 /// EmitMemSet - Emit a call to the memset function
95 Value *EmitMemSet(Value *Dst, Value *Val, Value *Len, IRBuilder<> &B);
96
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000097 /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
98 /// 'floor'). This function is known to take a single of type matching 'Op'
99 /// and returns one value with the same type. If 'Op' is a long double, 'l'
100 /// is added as the suffix of name, if 'Op' is a float, we add a 'f' suffix.
Eric Christopher7a61d702008-08-08 19:39:37 +0000101 Value *EmitUnaryFloatFnCall(Value *Op, const char *Name, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000102
103 /// EmitPutChar - Emit a call to the putchar function. This assumes that Char
104 /// is an integer.
Eric Christopher7a61d702008-08-08 19:39:37 +0000105 void EmitPutChar(Value *Char, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000106
107 /// EmitPutS - Emit a call to the puts function. This assumes that Str is
108 /// some pointer.
Eric Christopher7a61d702008-08-08 19:39:37 +0000109 void EmitPutS(Value *Str, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000110
111 /// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
112 /// an i32, and File is a pointer to FILE.
Eric Christopher7a61d702008-08-08 19:39:37 +0000113 void EmitFPutC(Value *Char, Value *File, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000114
115 /// EmitFPutS - Emit a call to the puts function. Str is required to be a
116 /// pointer and File is a pointer to FILE.
Eric Christopher7a61d702008-08-08 19:39:37 +0000117 void EmitFPutS(Value *Str, Value *File, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000118
119 /// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
120 /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
Eric Christopher7a61d702008-08-08 19:39:37 +0000121 void EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B);
Nick Lewycky13a09e22008-12-21 00:19:21 +0000122
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000123};
124} // End anonymous namespace.
125
126/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
Eric Christopher7a61d702008-08-08 19:39:37 +0000127Value *LibCallOptimization::CastToCStr(Value *V, IRBuilder<> &B) {
Owen Andersonfa5cbd62009-07-03 19:42:02 +0000128 return
Owen Anderson1d0be152009-08-13 21:58:54 +0000129 B.CreateBitCast(V, PointerType::getUnqual(Type::getInt8Ty(*Context)), "cstr");
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000130}
131
132/// EmitStrLen - Emit a call to the strlen function to the builder, for the
133/// specified pointer. This always returns an integer value of size intptr_t.
Eric Christopher7a61d702008-08-08 19:39:37 +0000134Value *LibCallOptimization::EmitStrLen(Value *Ptr, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000135 Module *M = Caller->getParent();
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000136 AttributeWithIndex AWI[2];
137 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
138 AWI[1] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
139 Attribute::NoUnwind);
140
141 Constant *StrLen =M->getOrInsertFunction("strlen", AttrListPtr::get(AWI, 2),
Owen Anderson1d0be152009-08-13 21:58:54 +0000142 TD->getIntPtrType(*Context),
143 PointerType::getUnqual(Type::getInt8Ty(*Context)),
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000144 NULL);
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +0000145 CallInst *CI = B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen");
146 if (const Function *F = dyn_cast<Function>(StrLen->stripPointerCasts()))
147 CI->setCallingConv(F->getCallingConv());
148
149 return CI;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000150}
151
152/// EmitMemCpy - Emit a call to the memcpy function to the builder. This always
153/// expects that the size has type 'intptr_t' and Dst/Src are pointers.
154Value *LibCallOptimization::EmitMemCpy(Value *Dst, Value *Src, Value *Len,
Eric Christopher7a61d702008-08-08 19:39:37 +0000155 unsigned Align, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000156 Module *M = Caller->getParent();
Chris Lattner824b9582008-11-21 16:42:48 +0000157 Intrinsic::ID IID = Intrinsic::memcpy;
158 const Type *Tys[1];
159 Tys[0] = Len->getType();
160 Value *MemCpy = Intrinsic::getDeclaration(M, IID, Tys, 1);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000161 return B.CreateCall4(MemCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Len,
Owen Anderson1d0be152009-08-13 21:58:54 +0000162 ConstantInt::get(Type::getInt32Ty(*Context), Align));
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000163}
164
165/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
166/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
167Value *LibCallOptimization::EmitMemChr(Value *Ptr, Value *Val,
Eric Christopher7a61d702008-08-08 19:39:37 +0000168 Value *Len, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000169 Module *M = Caller->getParent();
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000170 AttributeWithIndex AWI;
171 AWI = AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
172
173 Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(&AWI, 1),
Owen Anderson1d0be152009-08-13 21:58:54 +0000174 PointerType::getUnqual(Type::getInt8Ty(*Context)),
175 PointerType::getUnqual(Type::getInt8Ty(*Context)),
176 Type::getInt32Ty(*Context), TD->getIntPtrType(*Context),
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000177 NULL);
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +0000178 CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr");
179
180 if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts()))
181 CI->setCallingConv(F->getCallingConv());
182
183 return CI;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000184}
185
Nick Lewycky13a09e22008-12-21 00:19:21 +0000186/// EmitMemCmp - Emit a call to the memcmp function.
187Value *LibCallOptimization::EmitMemCmp(Value *Ptr1, Value *Ptr2,
188 Value *Len, IRBuilder<> &B) {
189 Module *M = Caller->getParent();
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000190 AttributeWithIndex AWI[3];
191 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
192 AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
193 AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
194 Attribute::NoUnwind);
195
196 Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI, 3),
Owen Anderson1d0be152009-08-13 21:58:54 +0000197 Type::getInt32Ty(*Context),
198 PointerType::getUnqual(Type::getInt8Ty(*Context)),
199 PointerType::getUnqual(Type::getInt8Ty(*Context)),
200 TD->getIntPtrType(*Context), NULL);
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +0000201 CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B),
202 Len, "memcmp");
203
204 if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts()))
205 CI->setCallingConv(F->getCallingConv());
206
207 return CI;
Nick Lewycky13a09e22008-12-21 00:19:21 +0000208}
209
Chris Lattnerf5b6bc72009-04-12 05:06:39 +0000210/// EmitMemSet - Emit a call to the memset function
211Value *LibCallOptimization::EmitMemSet(Value *Dst, Value *Val,
212 Value *Len, IRBuilder<> &B) {
213 Module *M = Caller->getParent();
214 Intrinsic::ID IID = Intrinsic::memset;
215 const Type *Tys[1];
216 Tys[0] = Len->getType();
217 Value *MemSet = Intrinsic::getDeclaration(M, IID, Tys, 1);
Owen Anderson1d0be152009-08-13 21:58:54 +0000218 Value *Align = ConstantInt::get(Type::getInt32Ty(*Context), 1);
Chris Lattnerf5b6bc72009-04-12 05:06:39 +0000219 return B.CreateCall4(MemSet, CastToCStr(Dst, B), Val, Len, Align);
220}
221
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000222/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
223/// 'floor'). This function is known to take a single of type matching 'Op' and
224/// returns one value with the same type. If 'Op' is a long double, 'l' is
225/// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix.
226Value *LibCallOptimization::EmitUnaryFloatFnCall(Value *Op, const char *Name,
Eric Christopher7a61d702008-08-08 19:39:37 +0000227 IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000228 char NameBuffer[20];
Owen Anderson1d0be152009-08-13 21:58:54 +0000229 if (Op->getType() != Type::getDoubleTy(*Context)) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000230 // If we need to add a suffix, copy into NameBuffer.
231 unsigned NameLen = strlen(Name);
232 assert(NameLen < sizeof(NameBuffer)-2);
233 memcpy(NameBuffer, Name, NameLen);
Owen Anderson1d0be152009-08-13 21:58:54 +0000234 if (Op->getType() == Type::getFloatTy(*Context))
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000235 NameBuffer[NameLen] = 'f'; // floorf
236 else
237 NameBuffer[NameLen] = 'l'; // floorl
238 NameBuffer[NameLen+1] = 0;
239 Name = NameBuffer;
240 }
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +0000241
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000242 Module *M = Caller->getParent();
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +0000243 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000244 Op->getType(), NULL);
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +0000245 CallInst *CI = B.CreateCall(Callee, Op, Name);
246
247 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
248 CI->setCallingConv(F->getCallingConv());
249
250 return CI;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000251}
252
253/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
254/// is an integer.
Eric Christopher7a61d702008-08-08 19:39:37 +0000255void LibCallOptimization::EmitPutChar(Value *Char, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000256 Module *M = Caller->getParent();
Owen Anderson1d0be152009-08-13 21:58:54 +0000257 Value *PutChar = M->getOrInsertFunction("putchar", Type::getInt32Ty(*Context),
258 Type::getInt32Ty(*Context), NULL);
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +0000259 CallInst *CI = B.CreateCall(PutChar,
Owen Anderson1d0be152009-08-13 21:58:54 +0000260 B.CreateIntCast(Char, Type::getInt32Ty(*Context), "chari"),
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +0000261 "putchar");
262
263 if (const Function *F = dyn_cast<Function>(PutChar->stripPointerCasts()))
264 CI->setCallingConv(F->getCallingConv());
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000265}
266
267/// EmitPutS - Emit a call to the puts function. This assumes that Str is
268/// some pointer.
Eric Christopher7a61d702008-08-08 19:39:37 +0000269void LibCallOptimization::EmitPutS(Value *Str, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000270 Module *M = Caller->getParent();
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000271 AttributeWithIndex AWI[2];
272 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
273 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
274
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +0000275 Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI, 2),
Owen Anderson1d0be152009-08-13 21:58:54 +0000276 Type::getInt32Ty(*Context),
277 PointerType::getUnqual(Type::getInt8Ty(*Context)),
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +0000278 NULL);
279 CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts");
280 if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts()))
281 CI->setCallingConv(F->getCallingConv());
282
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000283}
284
285/// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
286/// an integer and File is a pointer to FILE.
Eric Christopher7a61d702008-08-08 19:39:37 +0000287void LibCallOptimization::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000288 Module *M = Caller->getParent();
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000289 AttributeWithIndex AWI[2];
290 AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
291 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
292 Constant *F;
293 if (isa<PointerType>(File->getType()))
Owen Anderson1d0be152009-08-13 21:58:54 +0000294 F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI, 2), Type::getInt32Ty(*Context),
295 Type::getInt32Ty(*Context), File->getType(), NULL);
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000296 else
Owen Anderson1d0be152009-08-13 21:58:54 +0000297 F = M->getOrInsertFunction("fputc", Type::getInt32Ty(*Context), Type::getInt32Ty(*Context),
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000298 File->getType(), NULL);
Owen Anderson1d0be152009-08-13 21:58:54 +0000299 Char = B.CreateIntCast(Char, Type::getInt32Ty(*Context), "chari");
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +0000300 CallInst *CI = B.CreateCall2(F, Char, File, "fputc");
301
302 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
303 CI->setCallingConv(Fn->getCallingConv());
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000304}
305
306/// EmitFPutS - Emit a call to the puts function. Str is required to be a
307/// pointer and File is a pointer to FILE.
Eric Christopher7a61d702008-08-08 19:39:37 +0000308void LibCallOptimization::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000309 Module *M = Caller->getParent();
Nick Lewycky225f7472009-02-15 22:47:25 +0000310 AttributeWithIndex AWI[3];
311 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
312 AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
313 AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000314 Constant *F;
315 if (isa<PointerType>(File->getType()))
Owen Anderson1d0be152009-08-13 21:58:54 +0000316 F = M->getOrInsertFunction("fputs", AttrListPtr::get(AWI, 3), Type::getInt32Ty(*Context),
317 PointerType::getUnqual(Type::getInt8Ty(*Context)),
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000318 File->getType(), NULL);
319 else
Owen Anderson1d0be152009-08-13 21:58:54 +0000320 F = M->getOrInsertFunction("fputs", Type::getInt32Ty(*Context),
321 PointerType::getUnqual(Type::getInt8Ty(*Context)),
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000322 File->getType(), NULL);
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +0000323 CallInst *CI = B.CreateCall2(F, CastToCStr(Str, B), File, "fputs");
324
325 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
326 CI->setCallingConv(Fn->getCallingConv());
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000327}
328
329/// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
330/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
331void LibCallOptimization::EmitFWrite(Value *Ptr, Value *Size, Value *File,
Eric Christopher7a61d702008-08-08 19:39:37 +0000332 IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000333 Module *M = Caller->getParent();
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000334 AttributeWithIndex AWI[3];
335 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
336 AWI[1] = AttributeWithIndex::get(4, Attribute::NoCapture);
337 AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
338 Constant *F;
339 if (isa<PointerType>(File->getType()))
340 F = M->getOrInsertFunction("fwrite", AttrListPtr::get(AWI, 3),
Owen Anderson1d0be152009-08-13 21:58:54 +0000341 TD->getIntPtrType(*Context),
342 PointerType::getUnqual(Type::getInt8Ty(*Context)),
343 TD->getIntPtrType(*Context), TD->getIntPtrType(*Context),
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000344 File->getType(), NULL);
345 else
Owen Anderson1d0be152009-08-13 21:58:54 +0000346 F = M->getOrInsertFunction("fwrite", TD->getIntPtrType(*Context),
347 PointerType::getUnqual(Type::getInt8Ty(*Context)),
348 TD->getIntPtrType(*Context), TD->getIntPtrType(*Context),
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000349 File->getType(), NULL);
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +0000350 CallInst *CI = B.CreateCall4(F, CastToCStr(Ptr, B), Size,
Owen Anderson1d0be152009-08-13 21:58:54 +0000351 ConstantInt::get(TD->getIntPtrType(*Context), 1), File);
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +0000352
353 if (const Function *Fn = dyn_cast<Function>(F->stripPointerCasts()))
354 CI->setCallingConv(Fn->getCallingConv());
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000355}
356
357//===----------------------------------------------------------------------===//
358// Helper Functions
359//===----------------------------------------------------------------------===//
360
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000361/// GetStringLengthH - If we can compute the length of the string pointed to by
362/// the specified pointer, return 'len+1'. If we can't, return 0.
363static uint64_t GetStringLengthH(Value *V, SmallPtrSet<PHINode*, 32> &PHIs) {
364 // Look through noop bitcast instructions.
365 if (BitCastInst *BCI = dyn_cast<BitCastInst>(V))
366 return GetStringLengthH(BCI->getOperand(0), PHIs);
367
368 // If this is a PHI node, there are two cases: either we have already seen it
369 // or we haven't.
370 if (PHINode *PN = dyn_cast<PHINode>(V)) {
371 if (!PHIs.insert(PN))
372 return ~0ULL; // already in the set.
373
374 // If it was new, see if all the input strings are the same length.
375 uint64_t LenSoFar = ~0ULL;
376 for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
377 uint64_t Len = GetStringLengthH(PN->getIncomingValue(i), PHIs);
378 if (Len == 0) return 0; // Unknown length -> unknown.
379
380 if (Len == ~0ULL) continue;
381
382 if (Len != LenSoFar && LenSoFar != ~0ULL)
383 return 0; // Disagree -> unknown.
384 LenSoFar = Len;
385 }
386
387 // Success, all agree.
388 return LenSoFar;
389 }
390
391 // strlen(select(c,x,y)) -> strlen(x) ^ strlen(y)
392 if (SelectInst *SI = dyn_cast<SelectInst>(V)) {
393 uint64_t Len1 = GetStringLengthH(SI->getTrueValue(), PHIs);
394 if (Len1 == 0) return 0;
395 uint64_t Len2 = GetStringLengthH(SI->getFalseValue(), PHIs);
396 if (Len2 == 0) return 0;
397 if (Len1 == ~0ULL) return Len2;
398 if (Len2 == ~0ULL) return Len1;
399 if (Len1 != Len2) return 0;
400 return Len1;
401 }
402
403 // If the value is not a GEP instruction nor a constant expression with a
404 // GEP instruction, then return unknown.
405 User *GEP = 0;
406 if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) {
407 GEP = GEPI;
408 } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
409 if (CE->getOpcode() != Instruction::GetElementPtr)
410 return 0;
411 GEP = CE;
412 } else {
413 return 0;
414 }
415
416 // Make sure the GEP has exactly three arguments.
417 if (GEP->getNumOperands() != 3)
418 return 0;
419
420 // Check to make sure that the first operand of the GEP is an integer and
421 // has value 0 so that we are sure we're indexing into the initializer.
422 if (ConstantInt *Idx = dyn_cast<ConstantInt>(GEP->getOperand(1))) {
423 if (!Idx->isZero())
424 return 0;
425 } else
426 return 0;
427
428 // If the second index isn't a ConstantInt, then this is a variable index
429 // into the array. If this occurs, we can't say anything meaningful about
430 // the string.
431 uint64_t StartIdx = 0;
432 if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2)))
433 StartIdx = CI->getZExtValue();
434 else
435 return 0;
436
437 // The GEP instruction, constant or instruction, must reference a global
438 // variable that is a constant and is initialized. The referenced constant
439 // initializer is the array that we'll use for optimization.
440 GlobalVariable* GV = dyn_cast<GlobalVariable>(GEP->getOperand(0));
441 if (!GV || !GV->isConstant() || !GV->hasInitializer())
442 return 0;
443 Constant *GlobalInit = GV->getInitializer();
444
445 // Handle the ConstantAggregateZero case, which is a degenerate case. The
446 // initializer is constant zero so the length of the string must be zero.
447 if (isa<ConstantAggregateZero>(GlobalInit))
448 return 1; // Len = 0 offset by 1.
449
450 // Must be a Constant Array
451 ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
Owen Anderson1d0be152009-08-13 21:58:54 +0000452 if (!Array ||
453 Array->getType()->getElementType() != Type::getInt8Ty(V->getContext()))
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000454 return false;
455
456 // Get the number of elements in the array
457 uint64_t NumElts = Array->getType()->getNumElements();
458
459 // Traverse the constant array from StartIdx (derived above) which is
460 // the place the GEP refers to in the array.
461 for (unsigned i = StartIdx; i != NumElts; ++i) {
462 Constant *Elt = Array->getOperand(i);
463 ConstantInt *CI = dyn_cast<ConstantInt>(Elt);
464 if (!CI) // This array isn't suitable, non-int initializer.
465 return 0;
466 if (CI->isZero())
467 return i-StartIdx+1; // We found end of string, success!
468 }
469
470 return 0; // The array isn't null terminated, conservatively return 'unknown'.
471}
472
473/// GetStringLength - If we can compute the length of the string pointed to by
474/// the specified pointer, return 'len+1'. If we can't, return 0.
475static uint64_t GetStringLength(Value *V) {
476 if (!isa<PointerType>(V->getType())) return 0;
477
478 SmallPtrSet<PHINode*, 32> PHIs;
479 uint64_t Len = GetStringLengthH(V, PHIs);
480 // If Len is ~0ULL, we had an infinite phi cycle: this is dead code, so return
481 // an empty string as a length.
482 return Len == ~0ULL ? 1 : Len;
483}
484
485/// IsOnlyUsedInZeroEqualityComparison - Return true if it only matters that the
486/// value is equal or not-equal to zero.
487static bool IsOnlyUsedInZeroEqualityComparison(Value *V) {
488 for (Value::use_iterator UI = V->use_begin(), E = V->use_end();
489 UI != E; ++UI) {
490 if (ICmpInst *IC = dyn_cast<ICmpInst>(*UI))
491 if (IC->isEquality())
492 if (Constant *C = dyn_cast<Constant>(IC->getOperand(1)))
493 if (C->isNullValue())
494 continue;
495 // Unknown instruction.
496 return false;
497 }
498 return true;
499}
500
501//===----------------------------------------------------------------------===//
502// Miscellaneous LibCall Optimizations
503//===----------------------------------------------------------------------===//
504
Bill Wendlingac178222008-05-05 21:37:59 +0000505namespace {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000506//===---------------------------------------===//
507// 'exit' Optimizations
508
509/// ExitOpt - int main() { exit(4); } --> int main() { return 4; }
510struct VISIBILITY_HIDDEN ExitOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000511 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000512 // Verify we have a reasonable prototype for exit.
513 if (Callee->arg_size() == 0 || !CI->use_empty())
514 return 0;
515
516 // Verify the caller is main, and that the result type of main matches the
517 // argument type of exit.
Daniel Dunbar03d76512009-07-25 23:55:21 +0000518 if (Caller->getName() != "main" || !Caller->hasExternalLinkage() ||
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000519 Caller->getReturnType() != CI->getOperand(1)->getType())
520 return 0;
521
522 TerminatorInst *OldTI = CI->getParent()->getTerminator();
Daniel Dunbar473955f2009-07-29 22:00:43 +0000523
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000524 // Drop all successor phi node entries.
525 for (unsigned i = 0, e = OldTI->getNumSuccessors(); i != e; ++i)
526 OldTI->getSuccessor(i)->removePredecessor(CI->getParent());
Nick Lewycky0efa9212009-07-29 05:17:50 +0000527
Daniel Dunbar473955f2009-07-29 22:00:43 +0000528 // Remove all instructions after the exit.
529 BasicBlock::iterator Dead = CI, E = OldTI; ++Dead;
530 while (Dead != E) {
531 BasicBlock::iterator Next = next(Dead);
Owen Anderson1d0be152009-08-13 21:58:54 +0000532 if (Dead->getType() != Type::getVoidTy(*Context))
Daniel Dunbar473955f2009-07-29 22:00:43 +0000533 Dead->replaceAllUsesWith(UndefValue::get(Dead->getType()));
534 Dead->eraseFromParent();
535 Dead = Next;
536 }
537
538 // Insert a return instruction.
539 OldTI->eraseFromParent();
540 B.SetInsertPoint(B.GetInsertBlock());
Nick Lewycky0efa9212009-07-29 05:17:50 +0000541 B.CreateRet(CI->getOperand(1));
542
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000543 return CI;
544 }
545};
546
547//===----------------------------------------------------------------------===//
548// String and Memory LibCall Optimizations
549//===----------------------------------------------------------------------===//
550
551//===---------------------------------------===//
552// 'strcat' Optimizations
553
554struct VISIBILITY_HIDDEN StrCatOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000555 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000556 // Verify the "strcat" function prototype.
557 const FunctionType *FT = Callee->getFunctionType();
558 if (FT->getNumParams() != 2 ||
Owen Anderson1d0be152009-08-13 21:58:54 +0000559 FT->getReturnType() != PointerType::getUnqual(Type::getInt8Ty(*Context)) ||
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000560 FT->getParamType(0) != FT->getReturnType() ||
561 FT->getParamType(1) != FT->getReturnType())
562 return 0;
563
564 // Extract some information from the instruction
565 Value *Dst = CI->getOperand(1);
566 Value *Src = CI->getOperand(2);
567
568 // See if we can get the length of the input string.
569 uint64_t Len = GetStringLength(Src);
Chris Lattner56b4f2b2008-05-01 06:39:12 +0000570 if (Len == 0) return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000571 --Len; // Unbias length.
572
573 // Handle the simple, do-nothing case: strcat(x, "") -> x
574 if (Len == 0)
575 return Dst;
576
Chris Lattnerf5b6bc72009-04-12 05:06:39 +0000577 EmitStrLenMemCpy(Src, Dst, Len, B);
578 return Dst;
579 }
580
581 void EmitStrLenMemCpy(Value *Src, Value *Dst, uint64_t Len, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000582 // We need to find the end of the destination string. That's where the
583 // memory is to be moved to. We just generate a call to strlen.
584 Value *DstLen = EmitStrLen(Dst, B);
585
586 // Now that we have the destination's length, we must index into the
587 // destination's pointer to get the actual memcpy destination (end of
588 // the string .. we're concatenating).
Ed Schoutenb5e0a962009-04-06 13:06:48 +0000589 Value *CpyDst = B.CreateGEP(Dst, DstLen, "endptr");
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000590
591 // We have enough information to now generate the memcpy call to do the
592 // concatenation for us. Make a memcpy to copy the nul byte with align = 1.
Owen Andersonfa5cbd62009-07-03 19:42:02 +0000593 EmitMemCpy(CpyDst, Src,
Owen Anderson1d0be152009-08-13 21:58:54 +0000594 ConstantInt::get(TD->getIntPtrType(*Context), Len+1), 1, B);
Chris Lattnerf5b6bc72009-04-12 05:06:39 +0000595 }
596};
597
598//===---------------------------------------===//
599// 'strncat' Optimizations
600
601struct VISIBILITY_HIDDEN StrNCatOpt : public StrCatOpt {
602 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
603 // Verify the "strncat" function prototype.
604 const FunctionType *FT = Callee->getFunctionType();
605 if (FT->getNumParams() != 3 ||
Owen Anderson1d0be152009-08-13 21:58:54 +0000606 FT->getReturnType() != PointerType::getUnqual(Type::getInt8Ty(*Context)) ||
Chris Lattnerf5b6bc72009-04-12 05:06:39 +0000607 FT->getParamType(0) != FT->getReturnType() ||
608 FT->getParamType(1) != FT->getReturnType() ||
609 !isa<IntegerType>(FT->getParamType(2)))
610 return 0;
611
612 // Extract some information from the instruction
613 Value *Dst = CI->getOperand(1);
614 Value *Src = CI->getOperand(2);
615 uint64_t Len;
616
617 // We don't do anything if length is not constant
618 if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getOperand(3)))
619 Len = LengthArg->getZExtValue();
620 else
621 return 0;
622
623 // See if we can get the length of the input string.
624 uint64_t SrcLen = GetStringLength(Src);
625 if (SrcLen == 0) return 0;
626 --SrcLen; // Unbias length.
627
628 // Handle the simple, do-nothing cases:
629 // strncat(x, "", c) -> x
630 // strncat(x, c, 0) -> x
631 if (SrcLen == 0 || Len == 0) return Dst;
632
633 // We don't optimize this case
634 if (Len < SrcLen) return 0;
635
636 // strncat(x, s, c) -> strcat(x, s)
637 // s is constant so the strcat can be optimized further
Chris Lattner5db4cdf2009-04-12 18:22:33 +0000638 EmitStrLenMemCpy(Src, Dst, SrcLen, B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000639 return Dst;
640 }
641};
642
643//===---------------------------------------===//
644// 'strchr' Optimizations
645
646struct VISIBILITY_HIDDEN StrChrOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000647 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000648 // Verify the "strchr" function prototype.
649 const FunctionType *FT = Callee->getFunctionType();
650 if (FT->getNumParams() != 2 ||
Owen Anderson1d0be152009-08-13 21:58:54 +0000651 FT->getReturnType() != PointerType::getUnqual(Type::getInt8Ty(*Context)) ||
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000652 FT->getParamType(0) != FT->getReturnType())
653 return 0;
654
655 Value *SrcStr = CI->getOperand(1);
656
657 // If the second operand is non-constant, see if we can compute the length
658 // of the input string and turn this into memchr.
659 ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getOperand(2));
660 if (CharC == 0) {
661 uint64_t Len = GetStringLength(SrcStr);
Owen Anderson1d0be152009-08-13 21:58:54 +0000662 if (Len == 0 || FT->getParamType(1) != Type::getInt32Ty(*Context)) // memchr needs i32.
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000663 return 0;
664
665 return EmitMemChr(SrcStr, CI->getOperand(2), // include nul.
Owen Anderson1d0be152009-08-13 21:58:54 +0000666 ConstantInt::get(TD->getIntPtrType(*Context), Len), B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000667 }
668
669 // Otherwise, the character is a constant, see if the first argument is
670 // a string literal. If so, we can constant fold.
Bill Wendling0582ae92009-03-13 04:39:26 +0000671 std::string Str;
672 if (!GetConstantStringInfo(SrcStr, Str))
Chris Lattner56b4f2b2008-05-01 06:39:12 +0000673 return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000674
675 // strchr can find the nul character.
676 Str += '\0';
677 char CharValue = CharC->getSExtValue();
678
679 // Compute the offset.
680 uint64_t i = 0;
681 while (1) {
682 if (i == Str.size()) // Didn't find the char. strchr returns null.
Owen Andersona7235ea2009-07-31 20:28:14 +0000683 return Constant::getNullValue(CI->getType());
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000684 // Did we find our match?
685 if (Str[i] == CharValue)
686 break;
687 ++i;
688 }
689
690 // strchr(s+n,c) -> gep(s+n+i,c)
Owen Anderson1d0be152009-08-13 21:58:54 +0000691 Value *Idx = ConstantInt::get(Type::getInt64Ty(*Context), i);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000692 return B.CreateGEP(SrcStr, Idx, "strchr");
693 }
694};
695
696//===---------------------------------------===//
697// 'strcmp' Optimizations
698
699struct VISIBILITY_HIDDEN StrCmpOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000700 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000701 // Verify the "strcmp" function prototype.
702 const FunctionType *FT = Callee->getFunctionType();
Owen Anderson1d0be152009-08-13 21:58:54 +0000703 if (FT->getNumParams() != 2 || FT->getReturnType() != Type::getInt32Ty(*Context) ||
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000704 FT->getParamType(0) != FT->getParamType(1) ||
Owen Anderson1d0be152009-08-13 21:58:54 +0000705 FT->getParamType(0) != PointerType::getUnqual(Type::getInt8Ty(*Context)))
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000706 return 0;
707
708 Value *Str1P = CI->getOperand(1), *Str2P = CI->getOperand(2);
709 if (Str1P == Str2P) // strcmp(x,x) -> 0
Owen Andersoneed707b2009-07-24 23:12:02 +0000710 return ConstantInt::get(CI->getType(), 0);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000711
Bill Wendling0582ae92009-03-13 04:39:26 +0000712 std::string Str1, Str2;
713 bool HasStr1 = GetConstantStringInfo(Str1P, Str1);
714 bool HasStr2 = GetConstantStringInfo(Str2P, Str2);
715
716 if (HasStr1 && Str1.empty()) // strcmp("", x) -> *x
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000717 return B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), CI->getType());
718
Bill Wendling0582ae92009-03-13 04:39:26 +0000719 if (HasStr2 && Str2.empty()) // strcmp(x,"") -> *x
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000720 return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType());
721
722 // strcmp(x, y) -> cnst (if both x and y are constant strings)
Bill Wendling0582ae92009-03-13 04:39:26 +0000723 if (HasStr1 && HasStr2)
Owen Andersoneed707b2009-07-24 23:12:02 +0000724 return ConstantInt::get(CI->getType(),
Owen Andersonfa5cbd62009-07-03 19:42:02 +0000725 strcmp(Str1.c_str(),Str2.c_str()));
Nick Lewycky13a09e22008-12-21 00:19:21 +0000726
727 // strcmp(P, "x") -> memcmp(P, "x", 2)
728 uint64_t Len1 = GetStringLength(Str1P);
729 uint64_t Len2 = GetStringLength(Str2P);
Chris Lattner849832c2009-06-19 04:17:36 +0000730 if (Len1 && Len2) {
Nick Lewycky13a09e22008-12-21 00:19:21 +0000731 return EmitMemCmp(Str1P, Str2P,
Owen Anderson1d0be152009-08-13 21:58:54 +0000732 ConstantInt::get(TD->getIntPtrType(*Context),
Chris Lattner849832c2009-06-19 04:17:36 +0000733 std::min(Len1, Len2)), B);
Nick Lewycky13a09e22008-12-21 00:19:21 +0000734 }
735
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000736 return 0;
737 }
738};
739
740//===---------------------------------------===//
741// 'strncmp' Optimizations
742
743struct VISIBILITY_HIDDEN StrNCmpOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000744 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000745 // Verify the "strncmp" function prototype.
746 const FunctionType *FT = Callee->getFunctionType();
Owen Anderson1d0be152009-08-13 21:58:54 +0000747 if (FT->getNumParams() != 3 || FT->getReturnType() != Type::getInt32Ty(*Context) ||
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000748 FT->getParamType(0) != FT->getParamType(1) ||
Owen Anderson1d0be152009-08-13 21:58:54 +0000749 FT->getParamType(0) != PointerType::getUnqual(Type::getInt8Ty(*Context)) ||
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000750 !isa<IntegerType>(FT->getParamType(2)))
751 return 0;
752
753 Value *Str1P = CI->getOperand(1), *Str2P = CI->getOperand(2);
754 if (Str1P == Str2P) // strncmp(x,x,n) -> 0
Owen Andersoneed707b2009-07-24 23:12:02 +0000755 return ConstantInt::get(CI->getType(), 0);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000756
757 // Get the length argument if it is constant.
758 uint64_t Length;
759 if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getOperand(3)))
760 Length = LengthArg->getZExtValue();
761 else
762 return 0;
763
764 if (Length == 0) // strncmp(x,y,0) -> 0
Owen Andersoneed707b2009-07-24 23:12:02 +0000765 return ConstantInt::get(CI->getType(), 0);
Bill Wendling0582ae92009-03-13 04:39:26 +0000766
767 std::string Str1, Str2;
768 bool HasStr1 = GetConstantStringInfo(Str1P, Str1);
769 bool HasStr2 = GetConstantStringInfo(Str2P, Str2);
770
771 if (HasStr1 && Str1.empty()) // strncmp("", x, n) -> *x
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000772 return B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), CI->getType());
773
Bill Wendling0582ae92009-03-13 04:39:26 +0000774 if (HasStr2 && Str2.empty()) // strncmp(x, "", n) -> *x
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000775 return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType());
776
777 // strncmp(x, y) -> cnst (if both x and y are constant strings)
Bill Wendling0582ae92009-03-13 04:39:26 +0000778 if (HasStr1 && HasStr2)
Owen Andersoneed707b2009-07-24 23:12:02 +0000779 return ConstantInt::get(CI->getType(),
Bill Wendling0582ae92009-03-13 04:39:26 +0000780 strncmp(Str1.c_str(), Str2.c_str(), Length));
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000781 return 0;
782 }
783};
784
785
786//===---------------------------------------===//
787// 'strcpy' Optimizations
788
789struct VISIBILITY_HIDDEN StrCpyOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000790 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000791 // Verify the "strcpy" function prototype.
792 const FunctionType *FT = Callee->getFunctionType();
793 if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) ||
794 FT->getParamType(0) != FT->getParamType(1) ||
Owen Anderson1d0be152009-08-13 21:58:54 +0000795 FT->getParamType(0) != PointerType::getUnqual(Type::getInt8Ty(*Context)))
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000796 return 0;
797
798 Value *Dst = CI->getOperand(1), *Src = CI->getOperand(2);
799 if (Dst == Src) // strcpy(x,x) -> x
800 return Src;
801
802 // See if we can get the length of the input string.
803 uint64_t Len = GetStringLength(Src);
Chris Lattner56b4f2b2008-05-01 06:39:12 +0000804 if (Len == 0) return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000805
806 // We have enough information to now generate the memcpy call to do the
807 // concatenation for us. Make a memcpy to copy the nul byte with align = 1.
Owen Andersonfa5cbd62009-07-03 19:42:02 +0000808 EmitMemCpy(Dst, Src,
Owen Anderson1d0be152009-08-13 21:58:54 +0000809 ConstantInt::get(TD->getIntPtrType(*Context), Len), 1, B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000810 return Dst;
811 }
812};
813
Chris Lattnerf5b6bc72009-04-12 05:06:39 +0000814//===---------------------------------------===//
815// 'strncpy' Optimizations
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000816
Chris Lattnerf5b6bc72009-04-12 05:06:39 +0000817struct VISIBILITY_HIDDEN StrNCpyOpt : public LibCallOptimization {
818 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
819 const FunctionType *FT = Callee->getFunctionType();
820 if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
821 FT->getParamType(0) != FT->getParamType(1) ||
Owen Anderson1d0be152009-08-13 21:58:54 +0000822 FT->getParamType(0) != PointerType::getUnqual(Type::getInt8Ty(*Context)) ||
Chris Lattnerf5b6bc72009-04-12 05:06:39 +0000823 !isa<IntegerType>(FT->getParamType(2)))
824 return 0;
825
826 Value *Dst = CI->getOperand(1);
827 Value *Src = CI->getOperand(2);
828 Value *LenOp = CI->getOperand(3);
829
830 // See if we can get the length of the input string.
831 uint64_t SrcLen = GetStringLength(Src);
832 if (SrcLen == 0) return 0;
833 --SrcLen;
834
835 if (SrcLen == 0) {
836 // strncpy(x, "", y) -> memset(x, '\0', y, 1)
Owen Anderson1d0be152009-08-13 21:58:54 +0000837 EmitMemSet(Dst, ConstantInt::get(Type::getInt8Ty(*Context), '\0'), LenOp, B);
Chris Lattnerf5b6bc72009-04-12 05:06:39 +0000838 return Dst;
839 }
840
841 uint64_t Len;
842 if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(LenOp))
843 Len = LengthArg->getZExtValue();
844 else
845 return 0;
846
847 if (Len == 0) return Dst; // strncpy(x, y, 0) -> x
848
849 // Let strncpy handle the zero padding
850 if (Len > SrcLen+1) return 0;
851
852 // strncpy(x, s, c) -> memcpy(x, s, c, 1) [s and c are constant]
Owen Andersonfa5cbd62009-07-03 19:42:02 +0000853 EmitMemCpy(Dst, Src,
Owen Anderson1d0be152009-08-13 21:58:54 +0000854 ConstantInt::get(TD->getIntPtrType(*Context), Len), 1, B);
Chris Lattnerf5b6bc72009-04-12 05:06:39 +0000855
856 return Dst;
857 }
858};
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000859
860//===---------------------------------------===//
861// 'strlen' Optimizations
862
863struct VISIBILITY_HIDDEN StrLenOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000864 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000865 const FunctionType *FT = Callee->getFunctionType();
866 if (FT->getNumParams() != 1 ||
Owen Anderson1d0be152009-08-13 21:58:54 +0000867 FT->getParamType(0) != PointerType::getUnqual(Type::getInt8Ty(*Context)) ||
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000868 !isa<IntegerType>(FT->getReturnType()))
869 return 0;
870
871 Value *Src = CI->getOperand(1);
872
873 // Constant folding: strlen("xyz") -> 3
874 if (uint64_t Len = GetStringLength(Src))
Owen Andersoneed707b2009-07-24 23:12:02 +0000875 return ConstantInt::get(CI->getType(), Len-1);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000876
877 // Handle strlen(p) != 0.
878 if (!IsOnlyUsedInZeroEqualityComparison(CI)) return 0;
879
880 // strlen(x) != 0 --> *x != 0
881 // strlen(x) == 0 --> *x == 0
882 return B.CreateZExt(B.CreateLoad(Src, "strlenfirst"), CI->getType());
883 }
884};
885
886//===---------------------------------------===//
Nick Lewycky4c498412009-02-13 15:31:46 +0000887// 'strto*' Optimizations
888
889struct VISIBILITY_HIDDEN StrToOpt : public LibCallOptimization {
890 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
891 const FunctionType *FT = Callee->getFunctionType();
892 if ((FT->getNumParams() != 2 && FT->getNumParams() != 3) ||
893 !isa<PointerType>(FT->getParamType(0)) ||
894 !isa<PointerType>(FT->getParamType(1)))
895 return 0;
896
897 Value *EndPtr = CI->getOperand(2);
Nick Lewycky02b6a6a2009-02-13 17:08:33 +0000898 if (isa<ConstantPointerNull>(EndPtr)) {
899 CI->setOnlyReadsMemory();
Nick Lewycky4c498412009-02-13 15:31:46 +0000900 CI->addAttribute(1, Attribute::NoCapture);
Nick Lewycky02b6a6a2009-02-13 17:08:33 +0000901 }
Nick Lewycky4c498412009-02-13 15:31:46 +0000902
903 return 0;
904 }
905};
906
907
908//===---------------------------------------===//
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000909// 'memcmp' Optimizations
910
911struct VISIBILITY_HIDDEN MemCmpOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000912 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000913 const FunctionType *FT = Callee->getFunctionType();
914 if (FT->getNumParams() != 3 || !isa<PointerType>(FT->getParamType(0)) ||
915 !isa<PointerType>(FT->getParamType(1)) ||
Owen Anderson1d0be152009-08-13 21:58:54 +0000916 FT->getReturnType() != Type::getInt32Ty(*Context))
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000917 return 0;
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000918
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000919 Value *LHS = CI->getOperand(1), *RHS = CI->getOperand(2);
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000920
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000921 if (LHS == RHS) // memcmp(s,s,x) -> 0
Owen Andersona7235ea2009-07-31 20:28:14 +0000922 return Constant::getNullValue(CI->getType());
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000923
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000924 // Make sure we have a constant length.
925 ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getOperand(3));
Chris Lattner56b4f2b2008-05-01 06:39:12 +0000926 if (!LenC) return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000927 uint64_t Len = LenC->getZExtValue();
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000928
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000929 if (Len == 0) // memcmp(s1,s2,0) -> 0
Owen Andersona7235ea2009-07-31 20:28:14 +0000930 return Constant::getNullValue(CI->getType());
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000931
932 if (Len == 1) { // memcmp(S1,S2,1) -> *LHS - *RHS
933 Value *LHSV = B.CreateLoad(CastToCStr(LHS, B), "lhsv");
934 Value *RHSV = B.CreateLoad(CastToCStr(RHS, B), "rhsv");
Chris Lattner0e98e4d2009-05-30 18:43:04 +0000935 return B.CreateSExt(B.CreateSub(LHSV, RHSV, "chardiff"), CI->getType());
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000936 }
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000937
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000938 // memcmp(S1,S2,2) != 0 -> (*(short*)LHS ^ *(short*)RHS) != 0
939 // memcmp(S1,S2,4) != 0 -> (*(int*)LHS ^ *(int*)RHS) != 0
940 if ((Len == 2 || Len == 4) && IsOnlyUsedInZeroEqualityComparison(CI)) {
Owen Andersondebcb012009-07-29 22:17:13 +0000941 const Type *PTy = PointerType::getUnqual(Len == 2 ?
Owen Anderson1d0be152009-08-13 21:58:54 +0000942 Type::getInt16Ty(*Context) : Type::getInt32Ty(*Context));
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000943 LHS = B.CreateBitCast(LHS, PTy, "tmp");
944 RHS = B.CreateBitCast(RHS, PTy, "tmp");
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000945 LoadInst *LHSV = B.CreateLoad(LHS, "lhsv");
946 LoadInst *RHSV = B.CreateLoad(RHS, "rhsv");
947 LHSV->setAlignment(1); RHSV->setAlignment(1); // Unaligned loads.
948 return B.CreateZExt(B.CreateXor(LHSV, RHSV, "shortdiff"), CI->getType());
949 }
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000950
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000951 return 0;
952 }
953};
954
955//===---------------------------------------===//
956// 'memcpy' Optimizations
957
958struct VISIBILITY_HIDDEN MemCpyOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000959 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000960 const FunctionType *FT = Callee->getFunctionType();
961 if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
962 !isa<PointerType>(FT->getParamType(0)) ||
963 !isa<PointerType>(FT->getParamType(1)) ||
Owen Anderson1d0be152009-08-13 21:58:54 +0000964 FT->getParamType(2) != TD->getIntPtrType(*Context))
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000965 return 0;
966
967 // memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1)
968 EmitMemCpy(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3), 1, B);
969 return CI->getOperand(1);
970 }
971};
972
Eli Friedmand83ae7d2008-11-30 08:32:11 +0000973//===---------------------------------------===//
974// 'memmove' Optimizations
975
976struct VISIBILITY_HIDDEN MemMoveOpt : public LibCallOptimization {
977 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
978 const FunctionType *FT = Callee->getFunctionType();
979 if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
980 !isa<PointerType>(FT->getParamType(0)) ||
981 !isa<PointerType>(FT->getParamType(1)) ||
Owen Anderson1d0be152009-08-13 21:58:54 +0000982 FT->getParamType(2) != TD->getIntPtrType(*Context))
Eli Friedmand83ae7d2008-11-30 08:32:11 +0000983 return 0;
984
985 // memmove(x, y, n) -> llvm.memmove(x, y, n, 1)
986 Module *M = Caller->getParent();
987 Intrinsic::ID IID = Intrinsic::memmove;
988 const Type *Tys[1];
Owen Anderson1d0be152009-08-13 21:58:54 +0000989 Tys[0] = TD->getIntPtrType(*Context);
Eli Friedmand83ae7d2008-11-30 08:32:11 +0000990 Value *MemMove = Intrinsic::getDeclaration(M, IID, Tys, 1);
991 Value *Dst = CastToCStr(CI->getOperand(1), B);
992 Value *Src = CastToCStr(CI->getOperand(2), B);
993 Value *Size = CI->getOperand(3);
Owen Anderson1d0be152009-08-13 21:58:54 +0000994 Value *Align = ConstantInt::get(Type::getInt32Ty(*Context), 1);
Eli Friedmand83ae7d2008-11-30 08:32:11 +0000995 B.CreateCall4(MemMove, Dst, Src, Size, Align);
996 return CI->getOperand(1);
997 }
998};
999
1000//===---------------------------------------===//
1001// 'memset' Optimizations
1002
1003struct VISIBILITY_HIDDEN MemSetOpt : public LibCallOptimization {
1004 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
1005 const FunctionType *FT = Callee->getFunctionType();
1006 if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
1007 !isa<PointerType>(FT->getParamType(0)) ||
Eli Friedman62bb4132009-07-18 08:34:51 +00001008 !isa<IntegerType>(FT->getParamType(1)) ||
Owen Anderson1d0be152009-08-13 21:58:54 +00001009 FT->getParamType(2) != TD->getIntPtrType(*Context))
Eli Friedmand83ae7d2008-11-30 08:32:11 +00001010 return 0;
1011
1012 // memset(p, v, n) -> llvm.memset(p, v, n, 1)
Owen Anderson1d0be152009-08-13 21:58:54 +00001013 Value *Val = B.CreateIntCast(CI->getOperand(2), Type::getInt8Ty(*Context), false);
Chris Lattnerf5b6bc72009-04-12 05:06:39 +00001014 EmitMemSet(CI->getOperand(1), Val, CI->getOperand(3), B);
Eli Friedmand83ae7d2008-11-30 08:32:11 +00001015 return CI->getOperand(1);
1016 }
1017};
1018
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001019//===----------------------------------------------------------------------===//
1020// Math Library Optimizations
1021//===----------------------------------------------------------------------===//
1022
1023//===---------------------------------------===//
1024// 'pow*' Optimizations
1025
1026struct VISIBILITY_HIDDEN PowOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001027 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001028 const FunctionType *FT = Callee->getFunctionType();
1029 // Just make sure this has 2 arguments of the same FP type, which match the
1030 // result type.
1031 if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) ||
1032 FT->getParamType(0) != FT->getParamType(1) ||
1033 !FT->getParamType(0)->isFloatingPoint())
1034 return 0;
1035
1036 Value *Op1 = CI->getOperand(1), *Op2 = CI->getOperand(2);
1037 if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1)) {
1038 if (Op1C->isExactlyValue(1.0)) // pow(1.0, x) -> 1.0
1039 return Op1C;
1040 if (Op1C->isExactlyValue(2.0)) // pow(2.0, x) -> exp2(x)
1041 return EmitUnaryFloatFnCall(Op2, "exp2", B);
1042 }
1043
1044 ConstantFP *Op2C = dyn_cast<ConstantFP>(Op2);
1045 if (Op2C == 0) return 0;
1046
1047 if (Op2C->getValueAPF().isZero()) // pow(x, 0.0) -> 1.0
Owen Anderson6f83c9c2009-07-27 20:59:43 +00001048 return ConstantFP::get(CI->getType(), 1.0);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001049
1050 if (Op2C->isExactlyValue(0.5)) {
1051 // FIXME: This is not safe for -0.0 and -inf. This can only be done when
1052 // 'unsafe' math optimizations are allowed.
1053 // x pow(x, 0.5) sqrt(x)
1054 // ---------------------------------------------
1055 // -0.0 +0.0 -0.0
1056 // -inf +inf NaN
1057#if 0
1058 // pow(x, 0.5) -> sqrt(x)
1059 return B.CreateCall(get_sqrt(), Op1, "sqrt");
1060#endif
1061 }
1062
1063 if (Op2C->isExactlyValue(1.0)) // pow(x, 1.0) -> x
1064 return Op1;
1065 if (Op2C->isExactlyValue(2.0)) // pow(x, 2.0) -> x*x
Dan Gohmanae3a0be2009-06-04 22:49:04 +00001066 return B.CreateFMul(Op1, Op1, "pow2");
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001067 if (Op2C->isExactlyValue(-1.0)) // pow(x, -1.0) -> 1.0/x
Owen Anderson6f83c9c2009-07-27 20:59:43 +00001068 return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0),
Owen Andersonfa5cbd62009-07-03 19:42:02 +00001069 Op1, "powrecip");
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001070 return 0;
1071 }
1072};
1073
1074//===---------------------------------------===//
Chris Lattnere818f772008-05-02 18:43:35 +00001075// 'exp2' Optimizations
1076
1077struct VISIBILITY_HIDDEN Exp2Opt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001078 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnere818f772008-05-02 18:43:35 +00001079 const FunctionType *FT = Callee->getFunctionType();
1080 // Just make sure this has 1 argument of FP type, which matches the
1081 // result type.
1082 if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
1083 !FT->getParamType(0)->isFloatingPoint())
1084 return 0;
1085
1086 Value *Op = CI->getOperand(1);
1087 // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x)) if sizeof(x) <= 32
1088 // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < 32
1089 Value *LdExpArg = 0;
1090 if (SIToFPInst *OpC = dyn_cast<SIToFPInst>(Op)) {
1091 if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() <= 32)
Owen Anderson1d0be152009-08-13 21:58:54 +00001092 LdExpArg = B.CreateSExt(OpC->getOperand(0), Type::getInt32Ty(*Context), "tmp");
Chris Lattnere818f772008-05-02 18:43:35 +00001093 } else if (UIToFPInst *OpC = dyn_cast<UIToFPInst>(Op)) {
1094 if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() < 32)
Owen Anderson1d0be152009-08-13 21:58:54 +00001095 LdExpArg = B.CreateZExt(OpC->getOperand(0), Type::getInt32Ty(*Context), "tmp");
Chris Lattnere818f772008-05-02 18:43:35 +00001096 }
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +00001097
Chris Lattnere818f772008-05-02 18:43:35 +00001098 if (LdExpArg) {
1099 const char *Name;
Owen Anderson1d0be152009-08-13 21:58:54 +00001100 if (Op->getType() == Type::getFloatTy(*Context))
Chris Lattnere818f772008-05-02 18:43:35 +00001101 Name = "ldexpf";
Owen Anderson1d0be152009-08-13 21:58:54 +00001102 else if (Op->getType() == Type::getDoubleTy(*Context))
Chris Lattnere818f772008-05-02 18:43:35 +00001103 Name = "ldexp";
1104 else
1105 Name = "ldexpl";
1106
Owen Anderson6f83c9c2009-07-27 20:59:43 +00001107 Constant *One = ConstantFP::get(*Context, APFloat(1.0f));
Owen Anderson1d0be152009-08-13 21:58:54 +00001108 if (Op->getType() != Type::getFloatTy(*Context))
Owen Andersonbaf3c402009-07-29 18:55:55 +00001109 One = ConstantExpr::getFPExtend(One, Op->getType());
Chris Lattnere818f772008-05-02 18:43:35 +00001110
1111 Module *M = Caller->getParent();
1112 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
Owen Anderson1d0be152009-08-13 21:58:54 +00001113 Op->getType(), Type::getInt32Ty(*Context),NULL);
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +00001114 CallInst *CI = B.CreateCall2(Callee, One, LdExpArg);
1115 if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts()))
1116 CI->setCallingConv(F->getCallingConv());
1117
1118 return CI;
Chris Lattnere818f772008-05-02 18:43:35 +00001119 }
1120 return 0;
1121 }
1122};
Chris Lattnere818f772008-05-02 18:43:35 +00001123
1124//===---------------------------------------===//
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001125// Double -> Float Shrinking Optimizations for Unary Functions like 'floor'
1126
1127struct VISIBILITY_HIDDEN UnaryDoubleFPOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001128 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001129 const FunctionType *FT = Callee->getFunctionType();
Owen Anderson1d0be152009-08-13 21:58:54 +00001130 if (FT->getNumParams() != 1 || FT->getReturnType() != Type::getDoubleTy(*Context) ||
1131 FT->getParamType(0) != Type::getDoubleTy(*Context))
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001132 return 0;
Anton Korobeynikov9547cdf2009-06-18 20:05:31 +00001133
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001134 // If this is something like 'floor((double)floatval)', convert to floorf.
1135 FPExtInst *Cast = dyn_cast<FPExtInst>(CI->getOperand(1));
Owen Anderson1d0be152009-08-13 21:58:54 +00001136 if (Cast == 0 || Cast->getOperand(0)->getType() != Type::getFloatTy(*Context))
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001137 return 0;
1138
1139 // floor((double)floatval) -> (double)floorf(floatval)
1140 Value *V = Cast->getOperand(0);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001141 V = EmitUnaryFloatFnCall(V, Callee->getName().data(), B);
Owen Anderson1d0be152009-08-13 21:58:54 +00001142 return B.CreateFPExt(V, Type::getDoubleTy(*Context));
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001143 }
1144};
1145
1146//===----------------------------------------------------------------------===//
1147// Integer Optimizations
1148//===----------------------------------------------------------------------===//
1149
1150//===---------------------------------------===//
1151// 'ffs*' Optimizations
1152
1153struct VISIBILITY_HIDDEN FFSOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001154 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001155 const FunctionType *FT = Callee->getFunctionType();
1156 // Just make sure this has 2 arguments of the same FP type, which match the
1157 // result type.
Owen Anderson1d0be152009-08-13 21:58:54 +00001158 if (FT->getNumParams() != 1 || FT->getReturnType() != Type::getInt32Ty(*Context) ||
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001159 !isa<IntegerType>(FT->getParamType(0)))
1160 return 0;
1161
1162 Value *Op = CI->getOperand(1);
1163
1164 // Constant fold.
1165 if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
1166 if (CI->getValue() == 0) // ffs(0) -> 0.
Owen Andersona7235ea2009-07-31 20:28:14 +00001167 return Constant::getNullValue(CI->getType());
Owen Anderson1d0be152009-08-13 21:58:54 +00001168 return ConstantInt::get(Type::getInt32Ty(*Context), // ffs(c) -> cttz(c)+1
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001169 CI->getValue().countTrailingZeros()+1);
1170 }
1171
1172 // ffs(x) -> x != 0 ? (i32)llvm.cttz(x)+1 : 0
1173 const Type *ArgType = Op->getType();
1174 Value *F = Intrinsic::getDeclaration(Callee->getParent(),
1175 Intrinsic::cttz, &ArgType, 1);
1176 Value *V = B.CreateCall(F, Op, "cttz");
Owen Andersoneed707b2009-07-24 23:12:02 +00001177 V = B.CreateAdd(V, ConstantInt::get(V->getType(), 1), "tmp");
Owen Anderson1d0be152009-08-13 21:58:54 +00001178 V = B.CreateIntCast(V, Type::getInt32Ty(*Context), false, "tmp");
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001179
Owen Andersona7235ea2009-07-31 20:28:14 +00001180 Value *Cond = B.CreateICmpNE(Op, Constant::getNullValue(ArgType), "tmp");
Owen Anderson1d0be152009-08-13 21:58:54 +00001181 return B.CreateSelect(Cond, V, ConstantInt::get(Type::getInt32Ty(*Context), 0));
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001182 }
1183};
1184
1185//===---------------------------------------===//
1186// 'isdigit' Optimizations
1187
1188struct VISIBILITY_HIDDEN IsDigitOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001189 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001190 const FunctionType *FT = Callee->getFunctionType();
1191 // We require integer(i32)
1192 if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) ||
Owen Anderson1d0be152009-08-13 21:58:54 +00001193 FT->getParamType(0) != Type::getInt32Ty(*Context))
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001194 return 0;
1195
1196 // isdigit(c) -> (c-'0') <u 10
1197 Value *Op = CI->getOperand(1);
Owen Anderson1d0be152009-08-13 21:58:54 +00001198 Op = B.CreateSub(Op, ConstantInt::get(Type::getInt32Ty(*Context), '0'),
Owen Andersonfa5cbd62009-07-03 19:42:02 +00001199 "isdigittmp");
Owen Anderson1d0be152009-08-13 21:58:54 +00001200 Op = B.CreateICmpULT(Op, ConstantInt::get(Type::getInt32Ty(*Context), 10),
Owen Andersonfa5cbd62009-07-03 19:42:02 +00001201 "isdigit");
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001202 return B.CreateZExt(Op, CI->getType());
1203 }
1204};
1205
1206//===---------------------------------------===//
1207// 'isascii' Optimizations
1208
1209struct VISIBILITY_HIDDEN IsAsciiOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001210 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001211 const FunctionType *FT = Callee->getFunctionType();
1212 // We require integer(i32)
1213 if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) ||
Owen Anderson1d0be152009-08-13 21:58:54 +00001214 FT->getParamType(0) != Type::getInt32Ty(*Context))
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001215 return 0;
1216
1217 // isascii(c) -> c <u 128
1218 Value *Op = CI->getOperand(1);
Owen Anderson1d0be152009-08-13 21:58:54 +00001219 Op = B.CreateICmpULT(Op, ConstantInt::get(Type::getInt32Ty(*Context), 128),
Owen Andersonfa5cbd62009-07-03 19:42:02 +00001220 "isascii");
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001221 return B.CreateZExt(Op, CI->getType());
1222 }
1223};
Chris Lattner313f0e62008-06-09 08:26:51 +00001224
1225//===---------------------------------------===//
1226// 'abs', 'labs', 'llabs' Optimizations
1227
1228struct VISIBILITY_HIDDEN AbsOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001229 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattner313f0e62008-06-09 08:26:51 +00001230 const FunctionType *FT = Callee->getFunctionType();
1231 // We require integer(integer) where the types agree.
1232 if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) ||
1233 FT->getParamType(0) != FT->getReturnType())
1234 return 0;
1235
1236 // abs(x) -> x >s -1 ? x : -x
1237 Value *Op = CI->getOperand(1);
Owen Andersonfa5cbd62009-07-03 19:42:02 +00001238 Value *Pos = B.CreateICmpSGT(Op,
Owen Andersona7235ea2009-07-31 20:28:14 +00001239 Constant::getAllOnesValue(Op->getType()),
Chris Lattner313f0e62008-06-09 08:26:51 +00001240 "ispos");
1241 Value *Neg = B.CreateNeg(Op, "neg");
1242 return B.CreateSelect(Pos, Op, Neg);
1243 }
1244};
1245
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001246
1247//===---------------------------------------===//
1248// 'toascii' Optimizations
1249
1250struct VISIBILITY_HIDDEN ToAsciiOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001251 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001252 const FunctionType *FT = Callee->getFunctionType();
1253 // We require i32(i32)
1254 if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
Owen Anderson1d0be152009-08-13 21:58:54 +00001255 FT->getParamType(0) != Type::getInt32Ty(*Context))
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001256 return 0;
1257
1258 // isascii(c) -> c & 0x7f
Owen Andersonfa5cbd62009-07-03 19:42:02 +00001259 return B.CreateAnd(CI->getOperand(1),
Owen Andersoneed707b2009-07-24 23:12:02 +00001260 ConstantInt::get(CI->getType(),0x7F));
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001261 }
1262};
1263
1264//===----------------------------------------------------------------------===//
1265// Formatting and IO Optimizations
1266//===----------------------------------------------------------------------===//
1267
1268//===---------------------------------------===//
1269// 'printf' Optimizations
1270
1271struct VISIBILITY_HIDDEN PrintFOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001272 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001273 // Require one fixed pointer argument and an integer/void result.
1274 const FunctionType *FT = Callee->getFunctionType();
1275 if (FT->getNumParams() < 1 || !isa<PointerType>(FT->getParamType(0)) ||
1276 !(isa<IntegerType>(FT->getReturnType()) ||
Owen Anderson1d0be152009-08-13 21:58:54 +00001277 FT->getReturnType() == Type::getVoidTy(*Context)))
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001278 return 0;
1279
1280 // Check for a fixed format string.
Bill Wendling0582ae92009-03-13 04:39:26 +00001281 std::string FormatStr;
1282 if (!GetConstantStringInfo(CI->getOperand(1), FormatStr))
1283 return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001284
1285 // Empty format string -> noop.
1286 if (FormatStr.empty()) // Tolerate printf's declared void.
Owen Andersonfa5cbd62009-07-03 19:42:02 +00001287 return CI->use_empty() ? (Value*)CI :
Owen Andersoneed707b2009-07-24 23:12:02 +00001288 ConstantInt::get(CI->getType(), 0);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001289
1290 // printf("x") -> putchar('x'), even for '%'.
1291 if (FormatStr.size() == 1) {
Owen Anderson1d0be152009-08-13 21:58:54 +00001292 EmitPutChar(ConstantInt::get(Type::getInt32Ty(*Context), FormatStr[0]), B);
Owen Andersonfa5cbd62009-07-03 19:42:02 +00001293 return CI->use_empty() ? (Value*)CI :
Owen Andersoneed707b2009-07-24 23:12:02 +00001294 ConstantInt::get(CI->getType(), 1);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001295 }
1296
1297 // printf("foo\n") --> puts("foo")
1298 if (FormatStr[FormatStr.size()-1] == '\n' &&
1299 FormatStr.find('%') == std::string::npos) { // no format characters.
1300 // Create a string literal with no \n on it. We expect the constant merge
1301 // pass to be run after this pass, to merge duplicate strings.
1302 FormatStr.erase(FormatStr.end()-1);
Owen Anderson1d0be152009-08-13 21:58:54 +00001303 Constant *C = ConstantArray::get(*Context, FormatStr, true);
Owen Andersone9b11b42009-07-08 19:03:57 +00001304 C = new GlobalVariable(*Callee->getParent(), C->getType(), true,
1305 GlobalVariable::InternalLinkage, C, "str");
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001306 EmitPutS(C, B);
1307 return CI->use_empty() ? (Value*)CI :
Owen Andersoneed707b2009-07-24 23:12:02 +00001308 ConstantInt::get(CI->getType(), FormatStr.size()+1);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001309 }
1310
1311 // Optimize specific format strings.
1312 // printf("%c", chr) --> putchar(*(i8*)dst)
1313 if (FormatStr == "%c" && CI->getNumOperands() > 2 &&
1314 isa<IntegerType>(CI->getOperand(2)->getType())) {
1315 EmitPutChar(CI->getOperand(2), B);
Owen Andersonfa5cbd62009-07-03 19:42:02 +00001316 return CI->use_empty() ? (Value*)CI :
Owen Andersoneed707b2009-07-24 23:12:02 +00001317 ConstantInt::get(CI->getType(), 1);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001318 }
1319
1320 // printf("%s\n", str) --> puts(str)
1321 if (FormatStr == "%s\n" && CI->getNumOperands() > 2 &&
1322 isa<PointerType>(CI->getOperand(2)->getType()) &&
1323 CI->use_empty()) {
1324 EmitPutS(CI->getOperand(2), B);
1325 return CI;
1326 }
1327 return 0;
1328 }
1329};
1330
1331//===---------------------------------------===//
1332// 'sprintf' Optimizations
1333
1334struct VISIBILITY_HIDDEN SPrintFOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001335 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001336 // Require two fixed pointer arguments and an integer result.
1337 const FunctionType *FT = Callee->getFunctionType();
1338 if (FT->getNumParams() != 2 || !isa<PointerType>(FT->getParamType(0)) ||
1339 !isa<PointerType>(FT->getParamType(1)) ||
1340 !isa<IntegerType>(FT->getReturnType()))
1341 return 0;
1342
1343 // Check for a fixed format string.
Bill Wendling0582ae92009-03-13 04:39:26 +00001344 std::string FormatStr;
1345 if (!GetConstantStringInfo(CI->getOperand(2), FormatStr))
1346 return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001347
1348 // If we just have a format string (nothing else crazy) transform it.
1349 if (CI->getNumOperands() == 3) {
1350 // Make sure there's no % in the constant array. We could try to handle
1351 // %% -> % in the future if we cared.
1352 for (unsigned i = 0, e = FormatStr.size(); i != e; ++i)
1353 if (FormatStr[i] == '%')
1354 return 0; // we found a format specifier, bail out.
1355
1356 // sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1)
1357 EmitMemCpy(CI->getOperand(1), CI->getOperand(2), // Copy the nul byte.
Owen Anderson1d0be152009-08-13 21:58:54 +00001358 ConstantInt::get(TD->getIntPtrType(*Context), FormatStr.size()+1),1,B);
Owen Andersoneed707b2009-07-24 23:12:02 +00001359 return ConstantInt::get(CI->getType(), FormatStr.size());
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001360 }
1361
1362 // The remaining optimizations require the format string to be "%s" or "%c"
1363 // and have an extra operand.
1364 if (FormatStr.size() != 2 || FormatStr[0] != '%' || CI->getNumOperands() <4)
1365 return 0;
1366
1367 // Decode the second character of the format string.
1368 if (FormatStr[1] == 'c') {
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001369 // sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001370 if (!isa<IntegerType>(CI->getOperand(3)->getType())) return 0;
Owen Anderson1d0be152009-08-13 21:58:54 +00001371 Value *V = B.CreateTrunc(CI->getOperand(3), Type::getInt8Ty(*Context), "char");
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001372 Value *Ptr = CastToCStr(CI->getOperand(1), B);
1373 B.CreateStore(V, Ptr);
Owen Anderson1d0be152009-08-13 21:58:54 +00001374 Ptr = B.CreateGEP(Ptr, ConstantInt::get(Type::getInt32Ty(*Context), 1), "nul");
1375 B.CreateStore(Constant::getNullValue(Type::getInt8Ty(*Context)), Ptr);
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001376
Owen Andersoneed707b2009-07-24 23:12:02 +00001377 return ConstantInt::get(CI->getType(), 1);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001378 }
1379
1380 if (FormatStr[1] == 's') {
1381 // sprintf(dest, "%s", str) -> llvm.memcpy(dest, str, strlen(str)+1, 1)
1382 if (!isa<PointerType>(CI->getOperand(3)->getType())) return 0;
1383
1384 Value *Len = EmitStrLen(CI->getOperand(3), B);
Owen Andersonfa5cbd62009-07-03 19:42:02 +00001385 Value *IncLen = B.CreateAdd(Len,
Owen Andersoneed707b2009-07-24 23:12:02 +00001386 ConstantInt::get(Len->getType(), 1),
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001387 "leninc");
1388 EmitMemCpy(CI->getOperand(1), CI->getOperand(3), IncLen, 1, B);
1389
1390 // The sprintf result is the unincremented number of bytes in the string.
1391 return B.CreateIntCast(Len, CI->getType(), false);
1392 }
1393 return 0;
1394 }
1395};
1396
1397//===---------------------------------------===//
1398// 'fwrite' Optimizations
1399
1400struct VISIBILITY_HIDDEN FWriteOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001401 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001402 // Require a pointer, an integer, an integer, a pointer, returning integer.
1403 const FunctionType *FT = Callee->getFunctionType();
1404 if (FT->getNumParams() != 4 || !isa<PointerType>(FT->getParamType(0)) ||
1405 !isa<IntegerType>(FT->getParamType(1)) ||
1406 !isa<IntegerType>(FT->getParamType(2)) ||
1407 !isa<PointerType>(FT->getParamType(3)) ||
1408 !isa<IntegerType>(FT->getReturnType()))
1409 return 0;
1410
1411 // Get the element size and count.
1412 ConstantInt *SizeC = dyn_cast<ConstantInt>(CI->getOperand(2));
1413 ConstantInt *CountC = dyn_cast<ConstantInt>(CI->getOperand(3));
1414 if (!SizeC || !CountC) return 0;
1415 uint64_t Bytes = SizeC->getZExtValue()*CountC->getZExtValue();
1416
1417 // If this is writing zero records, remove the call (it's a noop).
1418 if (Bytes == 0)
Owen Andersoneed707b2009-07-24 23:12:02 +00001419 return ConstantInt::get(CI->getType(), 0);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001420
1421 // If this is writing one byte, turn it into fputc.
1422 if (Bytes == 1) { // fwrite(S,1,1,F) -> fputc(S[0],F)
1423 Value *Char = B.CreateLoad(CastToCStr(CI->getOperand(1), B), "char");
1424 EmitFPutC(Char, CI->getOperand(4), B);
Owen Andersoneed707b2009-07-24 23:12:02 +00001425 return ConstantInt::get(CI->getType(), 1);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001426 }
1427
1428 return 0;
1429 }
1430};
1431
1432//===---------------------------------------===//
1433// 'fputs' Optimizations
1434
1435struct VISIBILITY_HIDDEN FPutsOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001436 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001437 // Require two pointers. Also, we can't optimize if return value is used.
1438 const FunctionType *FT = Callee->getFunctionType();
1439 if (FT->getNumParams() != 2 || !isa<PointerType>(FT->getParamType(0)) ||
1440 !isa<PointerType>(FT->getParamType(1)) ||
1441 !CI->use_empty())
1442 return 0;
1443
1444 // fputs(s,F) --> fwrite(s,1,strlen(s),F)
1445 uint64_t Len = GetStringLength(CI->getOperand(1));
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001446 if (!Len) return 0;
Owen Andersonfa5cbd62009-07-03 19:42:02 +00001447 EmitFWrite(CI->getOperand(1),
Owen Anderson1d0be152009-08-13 21:58:54 +00001448 ConstantInt::get(TD->getIntPtrType(*Context), Len-1),
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001449 CI->getOperand(2), B);
1450 return CI; // Known to have no uses (see above).
1451 }
1452};
1453
1454//===---------------------------------------===//
1455// 'fprintf' Optimizations
1456
1457struct VISIBILITY_HIDDEN FPrintFOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001458 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001459 // Require two fixed paramters as pointers and integer result.
1460 const FunctionType *FT = Callee->getFunctionType();
1461 if (FT->getNumParams() != 2 || !isa<PointerType>(FT->getParamType(0)) ||
1462 !isa<PointerType>(FT->getParamType(1)) ||
1463 !isa<IntegerType>(FT->getReturnType()))
1464 return 0;
1465
1466 // All the optimizations depend on the format string.
Bill Wendling0582ae92009-03-13 04:39:26 +00001467 std::string FormatStr;
1468 if (!GetConstantStringInfo(CI->getOperand(2), FormatStr))
1469 return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001470
1471 // fprintf(F, "foo") --> fwrite("foo", 3, 1, F)
1472 if (CI->getNumOperands() == 3) {
1473 for (unsigned i = 0, e = FormatStr.size(); i != e; ++i)
1474 if (FormatStr[i] == '%') // Could handle %% -> % if we cared.
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001475 return 0; // We found a format specifier.
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001476
Owen Anderson1d0be152009-08-13 21:58:54 +00001477 EmitFWrite(CI->getOperand(2), ConstantInt::get(TD->getIntPtrType(*Context),
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001478 FormatStr.size()),
1479 CI->getOperand(1), B);
Owen Andersoneed707b2009-07-24 23:12:02 +00001480 return ConstantInt::get(CI->getType(), FormatStr.size());
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001481 }
1482
1483 // The remaining optimizations require the format string to be "%s" or "%c"
1484 // and have an extra operand.
1485 if (FormatStr.size() != 2 || FormatStr[0] != '%' || CI->getNumOperands() <4)
1486 return 0;
1487
1488 // Decode the second character of the format string.
1489 if (FormatStr[1] == 'c') {
1490 // fprintf(F, "%c", chr) --> *(i8*)dst = chr
1491 if (!isa<IntegerType>(CI->getOperand(3)->getType())) return 0;
1492 EmitFPutC(CI->getOperand(3), CI->getOperand(1), B);
Owen Andersoneed707b2009-07-24 23:12:02 +00001493 return ConstantInt::get(CI->getType(), 1);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001494 }
1495
1496 if (FormatStr[1] == 's') {
1497 // fprintf(F, "%s", str) -> fputs(str, F)
1498 if (!isa<PointerType>(CI->getOperand(3)->getType()) || !CI->use_empty())
1499 return 0;
1500 EmitFPutS(CI->getOperand(3), CI->getOperand(1), B);
1501 return CI;
1502 }
1503 return 0;
1504 }
1505};
1506
Bill Wendlingac178222008-05-05 21:37:59 +00001507} // end anonymous namespace.
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001508
1509//===----------------------------------------------------------------------===//
1510// SimplifyLibCalls Pass Implementation
1511//===----------------------------------------------------------------------===//
1512
1513namespace {
1514 /// This pass optimizes well known library functions from libc and libm.
1515 ///
1516 class VISIBILITY_HIDDEN SimplifyLibCalls : public FunctionPass {
1517 StringMap<LibCallOptimization*> Optimizations;
1518 // Miscellaneous LibCall Optimizations
1519 ExitOpt Exit;
1520 // String and Memory LibCall Optimizations
Chris Lattnerf5b6bc72009-04-12 05:06:39 +00001521 StrCatOpt StrCat; StrNCatOpt StrNCat; StrChrOpt StrChr; StrCmpOpt StrCmp;
1522 StrNCmpOpt StrNCmp; StrCpyOpt StrCpy; StrNCpyOpt StrNCpy; StrLenOpt StrLen;
1523 StrToOpt StrTo; MemCmpOpt MemCmp; MemCpyOpt MemCpy; MemMoveOpt MemMove;
1524 MemSetOpt MemSet;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001525 // Math Library Optimizations
Chris Lattnere818f772008-05-02 18:43:35 +00001526 PowOpt Pow; Exp2Opt Exp2; UnaryDoubleFPOpt UnaryDoubleFP;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001527 // Integer Optimizations
Chris Lattner313f0e62008-06-09 08:26:51 +00001528 FFSOpt FFS; AbsOpt Abs; IsDigitOpt IsDigit; IsAsciiOpt IsAscii;
1529 ToAsciiOpt ToAscii;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001530 // Formatting and IO Optimizations
1531 SPrintFOpt SPrintF; PrintFOpt PrintF;
1532 FWriteOpt FWrite; FPutsOpt FPuts; FPrintFOpt FPrintF;
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001533
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001534 bool Modified; // This is only used by doInitialization.
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001535 public:
1536 static char ID; // Pass identification
Dan Gohmanae73dc12008-09-04 17:05:41 +00001537 SimplifyLibCalls() : FunctionPass(&ID) {}
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001538
1539 void InitOptimizations();
1540 bool runOnFunction(Function &F);
1541
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001542 void setDoesNotAccessMemory(Function &F);
1543 void setOnlyReadsMemory(Function &F);
1544 void setDoesNotThrow(Function &F);
1545 void setDoesNotCapture(Function &F, unsigned n);
1546 void setDoesNotAlias(Function &F, unsigned n);
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001547 bool doInitialization(Module &M);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001548
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001549 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1550 AU.addRequired<TargetData>();
1551 }
1552 };
1553 char SimplifyLibCalls::ID = 0;
1554} // end anonymous namespace.
1555
1556static RegisterPass<SimplifyLibCalls>
1557X("simplify-libcalls", "Simplify well-known library calls");
1558
1559// Public interface to the Simplify LibCalls pass.
1560FunctionPass *llvm::createSimplifyLibCallsPass() {
1561 return new SimplifyLibCalls();
1562}
1563
1564/// Optimizations - Populate the Optimizations map with all the optimizations
1565/// we know.
1566void SimplifyLibCalls::InitOptimizations() {
1567 // Miscellaneous LibCall Optimizations
1568 Optimizations["exit"] = &Exit;
1569
1570 // String and Memory LibCall Optimizations
1571 Optimizations["strcat"] = &StrCat;
Chris Lattnerf5b6bc72009-04-12 05:06:39 +00001572 Optimizations["strncat"] = &StrNCat;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001573 Optimizations["strchr"] = &StrChr;
1574 Optimizations["strcmp"] = &StrCmp;
1575 Optimizations["strncmp"] = &StrNCmp;
1576 Optimizations["strcpy"] = &StrCpy;
Chris Lattnerf5b6bc72009-04-12 05:06:39 +00001577 Optimizations["strncpy"] = &StrNCpy;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001578 Optimizations["strlen"] = &StrLen;
Nick Lewycky4c498412009-02-13 15:31:46 +00001579 Optimizations["strtol"] = &StrTo;
1580 Optimizations["strtod"] = &StrTo;
1581 Optimizations["strtof"] = &StrTo;
1582 Optimizations["strtoul"] = &StrTo;
1583 Optimizations["strtoll"] = &StrTo;
1584 Optimizations["strtold"] = &StrTo;
1585 Optimizations["strtoull"] = &StrTo;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001586 Optimizations["memcmp"] = &MemCmp;
1587 Optimizations["memcpy"] = &MemCpy;
Eli Friedmand83ae7d2008-11-30 08:32:11 +00001588 Optimizations["memmove"] = &MemMove;
1589 Optimizations["memset"] = &MemSet;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001590
1591 // Math Library Optimizations
1592 Optimizations["powf"] = &Pow;
1593 Optimizations["pow"] = &Pow;
1594 Optimizations["powl"] = &Pow;
Dale Johannesen53bfbbc2008-09-04 18:30:46 +00001595 Optimizations["llvm.pow.f32"] = &Pow;
1596 Optimizations["llvm.pow.f64"] = &Pow;
1597 Optimizations["llvm.pow.f80"] = &Pow;
1598 Optimizations["llvm.pow.f128"] = &Pow;
1599 Optimizations["llvm.pow.ppcf128"] = &Pow;
Chris Lattnere818f772008-05-02 18:43:35 +00001600 Optimizations["exp2l"] = &Exp2;
1601 Optimizations["exp2"] = &Exp2;
1602 Optimizations["exp2f"] = &Exp2;
Dale Johannesen53bfbbc2008-09-04 18:30:46 +00001603 Optimizations["llvm.exp2.ppcf128"] = &Exp2;
1604 Optimizations["llvm.exp2.f128"] = &Exp2;
1605 Optimizations["llvm.exp2.f80"] = &Exp2;
1606 Optimizations["llvm.exp2.f64"] = &Exp2;
1607 Optimizations["llvm.exp2.f32"] = &Exp2;
Chris Lattnere818f772008-05-02 18:43:35 +00001608
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001609#ifdef HAVE_FLOORF
1610 Optimizations["floor"] = &UnaryDoubleFP;
1611#endif
1612#ifdef HAVE_CEILF
1613 Optimizations["ceil"] = &UnaryDoubleFP;
1614#endif
1615#ifdef HAVE_ROUNDF
1616 Optimizations["round"] = &UnaryDoubleFP;
1617#endif
1618#ifdef HAVE_RINTF
1619 Optimizations["rint"] = &UnaryDoubleFP;
1620#endif
1621#ifdef HAVE_NEARBYINTF
1622 Optimizations["nearbyint"] = &UnaryDoubleFP;
1623#endif
1624
1625 // Integer Optimizations
1626 Optimizations["ffs"] = &FFS;
1627 Optimizations["ffsl"] = &FFS;
1628 Optimizations["ffsll"] = &FFS;
Chris Lattner313f0e62008-06-09 08:26:51 +00001629 Optimizations["abs"] = &Abs;
1630 Optimizations["labs"] = &Abs;
1631 Optimizations["llabs"] = &Abs;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001632 Optimizations["isdigit"] = &IsDigit;
1633 Optimizations["isascii"] = &IsAscii;
1634 Optimizations["toascii"] = &ToAscii;
1635
1636 // Formatting and IO Optimizations
1637 Optimizations["sprintf"] = &SPrintF;
1638 Optimizations["printf"] = &PrintF;
1639 Optimizations["fwrite"] = &FWrite;
1640 Optimizations["fputs"] = &FPuts;
1641 Optimizations["fprintf"] = &FPrintF;
1642}
1643
1644
1645/// runOnFunction - Top level algorithm.
1646///
1647bool SimplifyLibCalls::runOnFunction(Function &F) {
1648 if (Optimizations.empty())
1649 InitOptimizations();
1650
1651 const TargetData &TD = getAnalysis<TargetData>();
1652
Owen Andersone922c022009-07-22 00:24:57 +00001653 IRBuilder<> Builder(F.getContext());
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001654
1655 bool Changed = false;
1656 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
1657 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
1658 // Ignore non-calls.
1659 CallInst *CI = dyn_cast<CallInst>(I++);
1660 if (!CI) continue;
1661
1662 // Ignore indirect calls and calls to non-external functions.
1663 Function *Callee = CI->getCalledFunction();
1664 if (Callee == 0 || !Callee->isDeclaration() ||
1665 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage()))
1666 continue;
1667
1668 // Ignore unknown calls.
Daniel Dunbarf0443c12009-07-26 08:34:35 +00001669 LibCallOptimization *LCO = Optimizations.lookup(Callee->getName());
1670 if (!LCO) continue;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001671
1672 // Set the builder to the instruction after the call.
1673 Builder.SetInsertPoint(BB, I);
1674
1675 // Try to optimize this call.
Daniel Dunbarf0443c12009-07-26 08:34:35 +00001676 Value *Result = LCO->OptimizeCall(CI, TD, Builder);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001677 if (Result == 0) continue;
1678
Daniel Dunbarf0443c12009-07-26 08:34:35 +00001679 DEBUG(errs() << "SimplifyLibCalls simplified: " << *CI;
1680 errs() << " into: " << *Result << "\n");
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001681
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001682 // Something changed!
1683 Changed = true;
1684 ++NumSimplified;
1685
1686 // Inspect the instruction after the call (which was potentially just
1687 // added) next.
1688 I = CI; ++I;
1689
1690 if (CI != Result && !CI->use_empty()) {
1691 CI->replaceAllUsesWith(Result);
1692 if (!Result->hasName())
1693 Result->takeName(CI);
1694 }
1695 CI->eraseFromParent();
1696 }
1697 }
1698 return Changed;
1699}
1700
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001701// Utility methods for doInitialization.
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001702
1703void SimplifyLibCalls::setDoesNotAccessMemory(Function &F) {
1704 if (!F.doesNotAccessMemory()) {
1705 F.setDoesNotAccessMemory();
1706 ++NumAnnotated;
1707 Modified = true;
1708 }
1709}
1710void SimplifyLibCalls::setOnlyReadsMemory(Function &F) {
1711 if (!F.onlyReadsMemory()) {
1712 F.setOnlyReadsMemory();
1713 ++NumAnnotated;
1714 Modified = true;
1715 }
1716}
1717void SimplifyLibCalls::setDoesNotThrow(Function &F) {
1718 if (!F.doesNotThrow()) {
1719 F.setDoesNotThrow();
1720 ++NumAnnotated;
1721 Modified = true;
1722 }
1723}
1724void SimplifyLibCalls::setDoesNotCapture(Function &F, unsigned n) {
1725 if (!F.doesNotCapture(n)) {
1726 F.setDoesNotCapture(n);
1727 ++NumAnnotated;
1728 Modified = true;
1729 }
1730}
1731void SimplifyLibCalls::setDoesNotAlias(Function &F, unsigned n) {
1732 if (!F.doesNotAlias(n)) {
1733 F.setDoesNotAlias(n);
1734 ++NumAnnotated;
1735 Modified = true;
1736 }
1737}
1738
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001739/// doInitialization - Add attributes to well-known functions.
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001740///
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001741bool SimplifyLibCalls::doInitialization(Module &M) {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001742 Modified = false;
1743 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
1744 Function &F = *I;
1745 if (!F.isDeclaration())
1746 continue;
1747
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001748 if (!F.hasName())
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001749 continue;
1750
1751 const FunctionType *FTy = F.getFunctionType();
1752
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001753 StringRef Name = F.getName();
1754 switch (Name[0]) {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001755 case 's':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001756 if (Name == "strlen") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001757 if (FTy->getNumParams() != 1 ||
1758 !isa<PointerType>(FTy->getParamType(0)))
1759 continue;
1760 setOnlyReadsMemory(F);
1761 setDoesNotThrow(F);
1762 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001763 } else if (Name == "strcpy" ||
1764 Name == "stpcpy" ||
1765 Name == "strcat" ||
1766 Name == "strtol" ||
1767 Name == "strtod" ||
1768 Name == "strtof" ||
1769 Name == "strtoul" ||
1770 Name == "strtoll" ||
1771 Name == "strtold" ||
1772 Name == "strncat" ||
1773 Name == "strncpy" ||
1774 Name == "strtoull") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001775 if (FTy->getNumParams() < 2 ||
1776 !isa<PointerType>(FTy->getParamType(1)))
1777 continue;
1778 setDoesNotThrow(F);
1779 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001780 } else if (Name == "strxfrm") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001781 if (FTy->getNumParams() != 3 ||
1782 !isa<PointerType>(FTy->getParamType(0)) ||
1783 !isa<PointerType>(FTy->getParamType(1)))
1784 continue;
1785 setDoesNotThrow(F);
1786 setDoesNotCapture(F, 1);
1787 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001788 } else if (Name == "strcmp" ||
1789 Name == "strspn" ||
1790 Name == "strncmp" ||
1791 Name ==" strcspn" ||
1792 Name == "strcoll" ||
1793 Name == "strcasecmp" ||
1794 Name == "strncasecmp") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001795 if (FTy->getNumParams() < 2 ||
1796 !isa<PointerType>(FTy->getParamType(0)) ||
1797 !isa<PointerType>(FTy->getParamType(1)))
1798 continue;
1799 setOnlyReadsMemory(F);
1800 setDoesNotThrow(F);
1801 setDoesNotCapture(F, 1);
1802 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001803 } else if (Name == "strstr" ||
1804 Name == "strpbrk") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001805 if (FTy->getNumParams() != 2 ||
1806 !isa<PointerType>(FTy->getParamType(1)))
1807 continue;
1808 setOnlyReadsMemory(F);
1809 setDoesNotThrow(F);
1810 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001811 } else if (Name == "strtok" ||
1812 Name == "strtok_r") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001813 if (FTy->getNumParams() < 2 ||
1814 !isa<PointerType>(FTy->getParamType(1)))
1815 continue;
1816 setDoesNotThrow(F);
1817 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001818 } else if (Name == "scanf" ||
1819 Name == "setbuf" ||
1820 Name == "setvbuf") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001821 if (FTy->getNumParams() < 1 ||
1822 !isa<PointerType>(FTy->getParamType(0)))
1823 continue;
1824 setDoesNotThrow(F);
1825 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001826 } else if (Name == "strdup" ||
1827 Name == "strndup") {
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001828 if (FTy->getNumParams() < 1 ||
1829 !isa<PointerType>(FTy->getReturnType()) ||
1830 !isa<PointerType>(FTy->getParamType(0)))
1831 continue;
1832 setDoesNotThrow(F);
1833 setDoesNotAlias(F, 0);
1834 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001835 } else if (Name == "stat" ||
1836 Name == "sscanf" ||
1837 Name == "sprintf" ||
1838 Name == "statvfs") {
Nick Lewycky225f7472009-02-15 22:47:25 +00001839 if (FTy->getNumParams() < 2 ||
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001840 !isa<PointerType>(FTy->getParamType(0)) ||
1841 !isa<PointerType>(FTy->getParamType(1)))
1842 continue;
1843 setDoesNotThrow(F);
1844 setDoesNotCapture(F, 1);
1845 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001846 } else if (Name == "snprintf") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001847 if (FTy->getNumParams() != 3 ||
1848 !isa<PointerType>(FTy->getParamType(0)) ||
1849 !isa<PointerType>(FTy->getParamType(2)))
1850 continue;
1851 setDoesNotThrow(F);
1852 setDoesNotCapture(F, 1);
1853 setDoesNotCapture(F, 3);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001854 } else if (Name == "setitimer") {
Nick Lewycky225f7472009-02-15 22:47:25 +00001855 if (FTy->getNumParams() != 3 ||
1856 !isa<PointerType>(FTy->getParamType(1)) ||
1857 !isa<PointerType>(FTy->getParamType(2)))
1858 continue;
1859 setDoesNotThrow(F);
1860 setDoesNotCapture(F, 2);
1861 setDoesNotCapture(F, 3);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001862 } else if (Name == "system") {
Nick Lewycky225f7472009-02-15 22:47:25 +00001863 if (FTy->getNumParams() != 1 ||
1864 !isa<PointerType>(FTy->getParamType(0)))
1865 continue;
1866 // May throw; "system" is a valid pthread cancellation point.
1867 setDoesNotCapture(F, 1);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001868 }
1869 break;
1870 case 'm':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001871 if (Name == "memcmp") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001872 if (FTy->getNumParams() != 3 ||
1873 !isa<PointerType>(FTy->getParamType(0)) ||
1874 !isa<PointerType>(FTy->getParamType(1)))
1875 continue;
1876 setOnlyReadsMemory(F);
1877 setDoesNotThrow(F);
1878 setDoesNotCapture(F, 1);
1879 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001880 } else if (Name == "memchr" ||
1881 Name == "memrchr") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001882 if (FTy->getNumParams() != 3)
1883 continue;
1884 setOnlyReadsMemory(F);
1885 setDoesNotThrow(F);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001886 } else if (Name == "modf" ||
1887 Name == "modff" ||
1888 Name == "modfl" ||
1889 Name == "memcpy" ||
1890 Name == "memccpy" ||
1891 Name == "memmove") {
Nick Lewycky225f7472009-02-15 22:47:25 +00001892 if (FTy->getNumParams() < 2 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001893 !isa<PointerType>(FTy->getParamType(1)))
1894 continue;
1895 setDoesNotThrow(F);
1896 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001897 } else if (Name == "memalign") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001898 if (!isa<PointerType>(FTy->getReturnType()))
1899 continue;
1900 setDoesNotAlias(F, 0);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001901 } else if (Name == "mkdir" ||
1902 Name == "mktime") {
Nick Lewycky225f7472009-02-15 22:47:25 +00001903 if (FTy->getNumParams() == 0 ||
1904 !isa<PointerType>(FTy->getParamType(0)))
1905 continue;
1906 setDoesNotThrow(F);
1907 setDoesNotCapture(F, 1);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001908 }
1909 break;
1910 case 'r':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001911 if (Name == "realloc") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001912 if (FTy->getNumParams() != 2 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001913 !isa<PointerType>(FTy->getParamType(0)) ||
1914 !isa<PointerType>(FTy->getReturnType()))
1915 continue;
1916 setDoesNotThrow(F);
1917 setDoesNotAlias(F, 0);
1918 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001919 } else if (Name == "read") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001920 if (FTy->getNumParams() != 3 ||
1921 !isa<PointerType>(FTy->getParamType(1)))
1922 continue;
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001923 // May throw; "read" is a valid pthread cancellation point.
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001924 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001925 } else if (Name == "rmdir" ||
1926 Name == "rewind" ||
1927 Name == "remove" ||
1928 Name == "realpath") {
Nick Lewycky225f7472009-02-15 22:47:25 +00001929 if (FTy->getNumParams() < 1 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001930 !isa<PointerType>(FTy->getParamType(0)))
1931 continue;
1932 setDoesNotThrow(F);
1933 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001934 } else if (Name == "rename" ||
1935 Name == "readlink") {
Nick Lewycky225f7472009-02-15 22:47:25 +00001936 if (FTy->getNumParams() < 2 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001937 !isa<PointerType>(FTy->getParamType(0)) ||
1938 !isa<PointerType>(FTy->getParamType(1)))
1939 continue;
1940 setDoesNotThrow(F);
1941 setDoesNotCapture(F, 1);
1942 setDoesNotCapture(F, 2);
1943 }
1944 break;
1945 case 'w':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001946 if (Name == "write") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001947 if (FTy->getNumParams() != 3 ||
1948 !isa<PointerType>(FTy->getParamType(1)))
1949 continue;
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001950 // May throw; "write" is a valid pthread cancellation point.
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001951 setDoesNotCapture(F, 2);
1952 }
1953 break;
1954 case 'b':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001955 if (Name == "bcopy") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001956 if (FTy->getNumParams() != 3 ||
1957 !isa<PointerType>(FTy->getParamType(0)) ||
1958 !isa<PointerType>(FTy->getParamType(1)))
1959 continue;
1960 setDoesNotThrow(F);
1961 setDoesNotCapture(F, 1);
1962 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001963 } else if (Name == "bcmp") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001964 if (FTy->getNumParams() != 3 ||
1965 !isa<PointerType>(FTy->getParamType(0)) ||
1966 !isa<PointerType>(FTy->getParamType(1)))
1967 continue;
1968 setDoesNotThrow(F);
1969 setOnlyReadsMemory(F);
1970 setDoesNotCapture(F, 1);
1971 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001972 } else if (Name == "bzero") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001973 if (FTy->getNumParams() != 2 ||
1974 !isa<PointerType>(FTy->getParamType(0)))
1975 continue;
1976 setDoesNotThrow(F);
1977 setDoesNotCapture(F, 1);
1978 }
1979 break;
1980 case 'c':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001981 if (Name == "calloc") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001982 if (FTy->getNumParams() != 2 ||
1983 !isa<PointerType>(FTy->getReturnType()))
1984 continue;
1985 setDoesNotThrow(F);
1986 setDoesNotAlias(F, 0);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00001987 } else if (Name == "chmod" ||
1988 Name == "chown" ||
1989 Name == "ctermid" ||
1990 Name == "clearerr" ||
1991 Name == "closedir") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001992 if (FTy->getNumParams() == 0 ||
1993 !isa<PointerType>(FTy->getParamType(0)))
1994 continue;
1995 setDoesNotThrow(F);
1996 setDoesNotCapture(F, 1);
1997 }
1998 break;
1999 case 'a':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002000 if (Name == "atoi" ||
2001 Name == "atol" ||
2002 Name == "atof" ||
2003 Name == "atoll") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002004 if (FTy->getNumParams() != 1 ||
2005 !isa<PointerType>(FTy->getParamType(0)))
2006 continue;
2007 setDoesNotThrow(F);
2008 setOnlyReadsMemory(F);
2009 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002010 } else if (Name == "access") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002011 if (FTy->getNumParams() != 2 ||
2012 !isa<PointerType>(FTy->getParamType(0)))
2013 continue;
2014 setDoesNotThrow(F);
2015 setDoesNotCapture(F, 1);
2016 }
2017 break;
2018 case 'f':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002019 if (Name == "fopen") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002020 if (FTy->getNumParams() != 2 ||
2021 !isa<PointerType>(FTy->getReturnType()) ||
2022 !isa<PointerType>(FTy->getParamType(0)) ||
2023 !isa<PointerType>(FTy->getParamType(1)))
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002024 continue;
2025 setDoesNotThrow(F);
2026 setDoesNotAlias(F, 0);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002027 setDoesNotCapture(F, 1);
2028 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002029 } else if (Name == "fdopen") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002030 if (FTy->getNumParams() != 2 ||
2031 !isa<PointerType>(FTy->getReturnType()) ||
2032 !isa<PointerType>(FTy->getParamType(1)))
2033 continue;
2034 setDoesNotThrow(F);
2035 setDoesNotAlias(F, 0);
2036 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002037 } else if (Name == "feof" ||
2038 Name == "free" ||
2039 Name == "fseek" ||
2040 Name == "ftell" ||
2041 Name == "fgetc" ||
2042 Name == "fseeko" ||
2043 Name == "ftello" ||
2044 Name == "fileno" ||
2045 Name == "fflush" ||
2046 Name == "fclose" ||
2047 Name == "fsetpos" ||
2048 Name == "flockfile" ||
2049 Name == "funlockfile" ||
2050 Name == "ftrylockfile") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002051 if (FTy->getNumParams() == 0 ||
2052 !isa<PointerType>(FTy->getParamType(0)))
2053 continue;
2054 setDoesNotThrow(F);
2055 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002056 } else if (Name == "ferror") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002057 if (FTy->getNumParams() != 1 ||
2058 !isa<PointerType>(FTy->getParamType(0)))
2059 continue;
2060 setDoesNotThrow(F);
2061 setDoesNotCapture(F, 1);
2062 setOnlyReadsMemory(F);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002063 } else if (Name == "fputc" ||
2064 Name == "fstat" ||
2065 Name == "frexp" ||
2066 Name == "frexpf" ||
2067 Name == "frexpl" ||
2068 Name == "fstatvfs") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002069 if (FTy->getNumParams() != 2 ||
2070 !isa<PointerType>(FTy->getParamType(1)))
2071 continue;
2072 setDoesNotThrow(F);
2073 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002074 } else if (Name == "fgets") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002075 if (FTy->getNumParams() != 3 ||
2076 !isa<PointerType>(FTy->getParamType(0)) ||
2077 !isa<PointerType>(FTy->getParamType(2)))
2078 continue;
2079 setDoesNotThrow(F);
2080 setDoesNotCapture(F, 3);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002081 } else if (Name == "fread" ||
2082 Name == "fwrite") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002083 if (FTy->getNumParams() != 4 ||
2084 !isa<PointerType>(FTy->getParamType(0)) ||
2085 !isa<PointerType>(FTy->getParamType(3)))
2086 continue;
2087 setDoesNotThrow(F);
2088 setDoesNotCapture(F, 1);
2089 setDoesNotCapture(F, 4);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002090 } else if (Name == "fputs" ||
2091 Name == "fscanf" ||
2092 Name == "fprintf" ||
2093 Name == "fgetpos") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002094 if (FTy->getNumParams() < 2 ||
2095 !isa<PointerType>(FTy->getParamType(0)) ||
2096 !isa<PointerType>(FTy->getParamType(1)))
2097 continue;
2098 setDoesNotThrow(F);
2099 setDoesNotCapture(F, 1);
2100 setDoesNotCapture(F, 2);
2101 }
2102 break;
2103 case 'g':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002104 if (Name == "getc" ||
2105 Name == "getlogin_r" ||
2106 Name == "getc_unlocked") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002107 if (FTy->getNumParams() == 0 ||
2108 !isa<PointerType>(FTy->getParamType(0)))
2109 continue;
2110 setDoesNotThrow(F);
2111 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002112 } else if (Name == "getenv") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002113 if (FTy->getNumParams() != 1 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002114 !isa<PointerType>(FTy->getParamType(0)))
2115 continue;
2116 setDoesNotThrow(F);
2117 setOnlyReadsMemory(F);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002118 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002119 } else if (Name == "gets" ||
2120 Name == "getchar") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002121 setDoesNotThrow(F);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002122 } else if (Name == "getitimer") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002123 if (FTy->getNumParams() != 2 ||
2124 !isa<PointerType>(FTy->getParamType(1)))
2125 continue;
2126 setDoesNotThrow(F);
2127 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002128 } else if (Name == "getpwnam") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002129 if (FTy->getNumParams() != 1 ||
2130 !isa<PointerType>(FTy->getParamType(0)))
2131 continue;
2132 setDoesNotThrow(F);
2133 setDoesNotCapture(F, 1);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002134 }
2135 break;
2136 case 'u':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002137 if (Name == "ungetc") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002138 if (FTy->getNumParams() != 2 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002139 !isa<PointerType>(FTy->getParamType(1)))
2140 continue;
2141 setDoesNotThrow(F);
2142 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002143 } else if (Name == "uname" ||
2144 Name == "unlink" ||
2145 Name == "unsetenv") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002146 if (FTy->getNumParams() != 1 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002147 !isa<PointerType>(FTy->getParamType(0)))
2148 continue;
2149 setDoesNotThrow(F);
2150 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002151 } else if (Name == "utime" ||
2152 Name == "utimes") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002153 if (FTy->getNumParams() != 2 ||
2154 !isa<PointerType>(FTy->getParamType(0)) ||
2155 !isa<PointerType>(FTy->getParamType(1)))
2156 continue;
2157 setDoesNotThrow(F);
2158 setDoesNotCapture(F, 1);
2159 setDoesNotCapture(F, 2);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002160 }
2161 break;
2162 case 'p':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002163 if (Name == "putc") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002164 if (FTy->getNumParams() != 2 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002165 !isa<PointerType>(FTy->getParamType(1)))
2166 continue;
2167 setDoesNotThrow(F);
2168 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002169 } else if (Name == "puts" ||
2170 Name == "printf" ||
2171 Name == "perror") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002172 if (FTy->getNumParams() != 1 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002173 !isa<PointerType>(FTy->getParamType(0)))
2174 continue;
2175 setDoesNotThrow(F);
2176 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002177 } else if (Name == "pread" ||
2178 Name == "pwrite") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002179 if (FTy->getNumParams() != 4 ||
2180 !isa<PointerType>(FTy->getParamType(1)))
2181 continue;
2182 // May throw; these are valid pthread cancellation points.
2183 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002184 } else if (Name == "putchar") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002185 setDoesNotThrow(F);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002186 } else if (Name == "popen") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002187 if (FTy->getNumParams() != 2 ||
2188 !isa<PointerType>(FTy->getReturnType()) ||
2189 !isa<PointerType>(FTy->getParamType(0)) ||
2190 !isa<PointerType>(FTy->getParamType(1)))
2191 continue;
2192 setDoesNotThrow(F);
2193 setDoesNotAlias(F, 0);
2194 setDoesNotCapture(F, 1);
2195 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002196 } else if (Name == "pclose") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002197 if (FTy->getNumParams() != 1 ||
2198 !isa<PointerType>(FTy->getParamType(0)))
2199 continue;
2200 setDoesNotThrow(F);
2201 setDoesNotCapture(F, 1);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002202 }
2203 break;
2204 case 'v':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002205 if (Name == "vscanf") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002206 if (FTy->getNumParams() != 2 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002207 !isa<PointerType>(FTy->getParamType(1)))
2208 continue;
2209 setDoesNotThrow(F);
2210 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002211 } else if (Name == "vsscanf" ||
2212 Name == "vfscanf") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002213 if (FTy->getNumParams() != 3 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002214 !isa<PointerType>(FTy->getParamType(1)) ||
2215 !isa<PointerType>(FTy->getParamType(2)))
2216 continue;
2217 setDoesNotThrow(F);
2218 setDoesNotCapture(F, 1);
2219 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002220 } else if (Name == "valloc") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002221 if (!isa<PointerType>(FTy->getReturnType()))
2222 continue;
2223 setDoesNotThrow(F);
2224 setDoesNotAlias(F, 0);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002225 } else if (Name == "vprintf") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002226 if (FTy->getNumParams() != 2 ||
2227 !isa<PointerType>(FTy->getParamType(0)))
2228 continue;
2229 setDoesNotThrow(F);
2230 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002231 } else if (Name == "vfprintf" ||
2232 Name == "vsprintf") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002233 if (FTy->getNumParams() != 3 ||
2234 !isa<PointerType>(FTy->getParamType(0)) ||
2235 !isa<PointerType>(FTy->getParamType(1)))
2236 continue;
2237 setDoesNotThrow(F);
2238 setDoesNotCapture(F, 1);
2239 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002240 } else if (Name == "vsnprintf") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002241 if (FTy->getNumParams() != 4 ||
2242 !isa<PointerType>(FTy->getParamType(0)) ||
2243 !isa<PointerType>(FTy->getParamType(2)))
2244 continue;
2245 setDoesNotThrow(F);
2246 setDoesNotCapture(F, 1);
2247 setDoesNotCapture(F, 3);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002248 }
2249 break;
2250 case 'o':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002251 if (Name == "open") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002252 if (FTy->getNumParams() < 2 ||
2253 !isa<PointerType>(FTy->getParamType(0)))
2254 continue;
2255 // May throw; "open" is a valid pthread cancellation point.
2256 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002257 } else if (Name == "opendir") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002258 if (FTy->getNumParams() != 1 ||
2259 !isa<PointerType>(FTy->getReturnType()) ||
2260 !isa<PointerType>(FTy->getParamType(0)))
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002261 continue;
2262 setDoesNotThrow(F);
2263 setDoesNotAlias(F, 0);
Nick Lewycky225f7472009-02-15 22:47:25 +00002264 setDoesNotCapture(F, 1);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002265 }
2266 break;
2267 case 't':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002268 if (Name == "tmpfile") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002269 if (!isa<PointerType>(FTy->getReturnType()))
2270 continue;
2271 setDoesNotThrow(F);
2272 setDoesNotAlias(F, 0);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002273 } else if (Name == "times") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002274 if (FTy->getNumParams() != 1 ||
2275 !isa<PointerType>(FTy->getParamType(0)))
2276 continue;
2277 setDoesNotThrow(F);
2278 setDoesNotCapture(F, 1);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002279 }
Nick Lewycky225f7472009-02-15 22:47:25 +00002280 break;
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002281 case 'h':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002282 if (Name == "htonl" ||
2283 Name == "htons") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002284 setDoesNotThrow(F);
2285 setDoesNotAccessMemory(F);
2286 }
2287 break;
2288 case 'n':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002289 if (Name == "ntohl" ||
2290 Name == "ntohs") {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002291 setDoesNotThrow(F);
2292 setDoesNotAccessMemory(F);
2293 }
Nick Lewycky225f7472009-02-15 22:47:25 +00002294 break;
2295 case 'l':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002296 if (Name == "lstat") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002297 if (FTy->getNumParams() != 2 ||
2298 !isa<PointerType>(FTy->getParamType(0)) ||
2299 !isa<PointerType>(FTy->getParamType(1)))
2300 continue;
2301 setDoesNotThrow(F);
2302 setDoesNotCapture(F, 1);
2303 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002304 } else if (Name == "lchown") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002305 if (FTy->getNumParams() != 3 ||
2306 !isa<PointerType>(FTy->getParamType(0)))
2307 continue;
2308 setDoesNotThrow(F);
2309 setDoesNotCapture(F, 1);
2310 }
2311 break;
2312 case 'q':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002313 if (Name == "qsort") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002314 if (FTy->getNumParams() != 4 ||
2315 !isa<PointerType>(FTy->getParamType(3)))
2316 continue;
2317 // May throw; places call through function pointer.
2318 setDoesNotCapture(F, 4);
2319 }
2320 break;
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002321 case '_':
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002322 if (Name == "__strdup" ||
2323 Name == "__strndup") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002324 if (FTy->getNumParams() < 1 ||
2325 !isa<PointerType>(FTy->getReturnType()) ||
2326 !isa<PointerType>(FTy->getParamType(0)))
2327 continue;
2328 setDoesNotThrow(F);
2329 setDoesNotAlias(F, 0);
2330 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002331 } else if (Name == "__strtok_r") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002332 if (FTy->getNumParams() != 3 ||
2333 !isa<PointerType>(FTy->getParamType(1)))
2334 continue;
2335 setDoesNotThrow(F);
2336 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002337 } else if (Name == "_IO_getc") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002338 if (FTy->getNumParams() != 1 ||
2339 !isa<PointerType>(FTy->getParamType(0)))
2340 continue;
2341 setDoesNotThrow(F);
2342 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002343 } else if (Name == "_IO_putc") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002344 if (FTy->getNumParams() != 2 ||
2345 !isa<PointerType>(FTy->getParamType(1)))
2346 continue;
2347 setDoesNotThrow(F);
2348 setDoesNotCapture(F, 2);
2349 }
Nick Lewycky225f7472009-02-15 22:47:25 +00002350 break;
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002351 case 1:
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002352 if (Name == "\1__isoc99_scanf") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002353 if (FTy->getNumParams() < 1 ||
2354 !isa<PointerType>(FTy->getParamType(0)))
2355 continue;
2356 setDoesNotThrow(F);
2357 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002358 } else if (Name == "\1stat64" ||
2359 Name == "\1lstat64" ||
2360 Name == "\1statvfs64" ||
2361 Name == "\1__isoc99_sscanf") {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002362 if (FTy->getNumParams() < 1 ||
Nick Lewycky225f7472009-02-15 22:47:25 +00002363 !isa<PointerType>(FTy->getParamType(0)) ||
2364 !isa<PointerType>(FTy->getParamType(1)))
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002365 continue;
2366 setDoesNotThrow(F);
2367 setDoesNotCapture(F, 1);
2368 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002369 } else if (Name == "\1fopen64") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002370 if (FTy->getNumParams() != 2 ||
2371 !isa<PointerType>(FTy->getReturnType()) ||
2372 !isa<PointerType>(FTy->getParamType(0)) ||
2373 !isa<PointerType>(FTy->getParamType(1)))
2374 continue;
2375 setDoesNotThrow(F);
2376 setDoesNotAlias(F, 0);
2377 setDoesNotCapture(F, 1);
2378 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002379 } else if (Name == "\1fseeko64" ||
2380 Name == "\1ftello64") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002381 if (FTy->getNumParams() == 0 ||
2382 !isa<PointerType>(FTy->getParamType(0)))
2383 continue;
2384 setDoesNotThrow(F);
2385 setDoesNotCapture(F, 1);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002386 } else if (Name == "\1tmpfile64") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002387 if (!isa<PointerType>(FTy->getReturnType()))
2388 continue;
2389 setDoesNotThrow(F);
2390 setDoesNotAlias(F, 0);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002391 } else if (Name == "\1fstat64" ||
2392 Name == "\1fstatvfs64") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002393 if (FTy->getNumParams() != 2 ||
2394 !isa<PointerType>(FTy->getParamType(1)))
2395 continue;
2396 setDoesNotThrow(F);
2397 setDoesNotCapture(F, 2);
Daniel Dunbar93b67e42009-07-26 07:49:05 +00002398 } else if (Name == "\1open64") {
Nick Lewycky225f7472009-02-15 22:47:25 +00002399 if (FTy->getNumParams() < 2 ||
2400 !isa<PointerType>(FTy->getParamType(0)))
2401 continue;
2402 // May throw; "open" is a valid pthread cancellation point.
2403 setDoesNotCapture(F, 1);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002404 }
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002405 break;
2406 }
2407 }
2408 return Modified;
2409}
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00002410
2411// TODO:
2412// Additional cases that we need to add to this file:
2413//
2414// cbrt:
2415// * cbrt(expN(X)) -> expN(x/3)
2416// * cbrt(sqrt(x)) -> pow(x,1/6)
2417// * cbrt(sqrt(x)) -> pow(x,1/9)
2418//
2419// cos, cosf, cosl:
2420// * cos(-x) -> cos(x)
2421//
2422// exp, expf, expl:
2423// * exp(log(x)) -> x
2424//
2425// log, logf, logl:
2426// * log(exp(x)) -> x
2427// * log(x**y) -> y*log(x)
2428// * log(exp(y)) -> y*log(e)
2429// * log(exp2(y)) -> y*log(2)
2430// * log(exp10(y)) -> y*log(10)
2431// * log(sqrt(x)) -> 0.5*log(x)
2432// * log(pow(x,y)) -> y*log(x)
2433//
2434// lround, lroundf, lroundl:
2435// * lround(cnst) -> cnst'
2436//
2437// memcmp:
2438// * memcmp(x,y,l) -> cnst
2439// (if all arguments are constant and strlen(x) <= l and strlen(y) <= l)
2440//
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00002441// pow, powf, powl:
2442// * pow(exp(x),y) -> exp(x*y)
2443// * pow(sqrt(x),y) -> pow(x,y*0.5)
2444// * pow(pow(x,y),z)-> pow(x,y*z)
2445//
2446// puts:
2447// * puts("") -> putchar("\n")
2448//
2449// round, roundf, roundl:
2450// * round(cnst) -> cnst'
2451//
2452// signbit:
2453// * signbit(cnst) -> cnst'
2454// * signbit(nncst) -> 0 (if pstv is a non-negative constant)
2455//
2456// sqrt, sqrtf, sqrtl:
2457// * sqrt(expN(x)) -> expN(x*0.5)
2458// * sqrt(Nroot(x)) -> pow(x,1/(2*N))
2459// * sqrt(pow(x,y)) -> pow(|x|,y*0.5)
2460//
2461// stpcpy:
2462// * stpcpy(str, "literal") ->
2463// llvm.memcpy(str,"literal",strlen("literal")+1,1)
2464// strrchr:
2465// * strrchr(s,c) -> reverse_offset_of_in(c,s)
2466// (if c is a constant integer and s is a constant string)
2467// * strrchr(s1,0) -> strchr(s1,0)
2468//
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00002469// strpbrk:
2470// * strpbrk(s,a) -> offset_in_for(s,a)
2471// (if s and a are both constant strings)
2472// * strpbrk(s,"") -> 0
2473// * strpbrk(s,a) -> strchr(s,a[0]) (if a is constant string of length 1)
2474//
2475// strspn, strcspn:
2476// * strspn(s,a) -> const_int (if both args are constant)
2477// * strspn("",a) -> 0
2478// * strspn(s,"") -> 0
2479// * strcspn(s,a) -> const_int (if both args are constant)
2480// * strcspn("",a) -> 0
2481// * strcspn(s,"") -> strlen(a)
2482//
2483// strstr:
2484// * strstr(x,x) -> x
2485// * strstr(s1,s2) -> offset_of_s2_in(s1)
2486// (if s1 and s2 are constant strings)
2487//
2488// tan, tanf, tanl:
2489// * tan(atan(x)) -> x
2490//
2491// trunc, truncf, truncl:
2492// * trunc(cnst) -> cnst'
2493//
2494//