blob: c199f301a99eefd229dcbdb8a5352dfb261672b4 [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"
23#include "llvm/Module.h"
24#include "llvm/Pass.h"
25#include "llvm/Support/IRBuilder.h"
Evan Cheng0ff39b32008-06-30 07:31:25 +000026#include "llvm/Analysis/ValueTracking.h"
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000027#include "llvm/Target/TargetData.h"
28#include "llvm/ADT/SmallPtrSet.h"
29#include "llvm/ADT/StringMap.h"
30#include "llvm/ADT/Statistic.h"
31#include "llvm/Support/Compiler.h"
Chris Lattner56b4f2b2008-05-01 06:39:12 +000032#include "llvm/Support/Debug.h"
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000033#include "llvm/Config/config.h"
34using namespace llvm;
35
36STATISTIC(NumSimplified, "Number of library calls simplified");
Nick Lewycky0f8df9a2009-01-04 20:27:34 +000037STATISTIC(NumAnnotated, "Number of attributes added to library functions");
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000038
39//===----------------------------------------------------------------------===//
40// Optimizer Base Class
41//===----------------------------------------------------------------------===//
42
43/// This class is the abstract base class for the set of optimizations that
44/// corresponds to one library call.
45namespace {
46class VISIBILITY_HIDDEN LibCallOptimization {
47protected:
48 Function *Caller;
49 const TargetData *TD;
50public:
51 LibCallOptimization() { }
52 virtual ~LibCallOptimization() {}
53
54 /// CallOptimizer - This pure virtual method is implemented by base classes to
55 /// do various optimizations. If this returns null then no transformation was
56 /// performed. If it returns CI, then it transformed the call and CI is to be
57 /// deleted. If it returns something else, replace CI with the new value and
58 /// delete CI.
Eric Christopher7a61d702008-08-08 19:39:37 +000059 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)
60 =0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000061
Eric Christopher7a61d702008-08-08 19:39:37 +000062 Value *OptimizeCall(CallInst *CI, const TargetData &TD, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000063 Caller = CI->getParent()->getParent();
64 this->TD = &TD;
65 return CallOptimizer(CI->getCalledFunction(), CI, B);
66 }
67
68 /// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
Eric Christopher7a61d702008-08-08 19:39:37 +000069 Value *CastToCStr(Value *V, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000070
71 /// EmitStrLen - Emit a call to the strlen function to the builder, for the
72 /// specified pointer. Ptr is required to be some pointer type, and the
73 /// return value has 'intptr_t' type.
Eric Christopher7a61d702008-08-08 19:39:37 +000074 Value *EmitStrLen(Value *Ptr, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000075
76 /// EmitMemCpy - Emit a call to the memcpy function to the builder. This
77 /// always expects that the size has type 'intptr_t' and Dst/Src are pointers.
78 Value *EmitMemCpy(Value *Dst, Value *Src, Value *Len,
Eric Christopher7a61d702008-08-08 19:39:37 +000079 unsigned Align, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000080
81 /// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
82 /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
Eric Christopher7a61d702008-08-08 19:39:37 +000083 Value *EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B);
Nick Lewycky13a09e22008-12-21 00:19:21 +000084
85 /// EmitMemCmp - Emit a call to the memcmp function.
86 Value *EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B);
87
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000088 /// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
89 /// 'floor'). This function is known to take a single of type matching 'Op'
90 /// and returns one value with the same type. If 'Op' is a long double, 'l'
91 /// is added as the suffix of name, if 'Op' is a float, we add a 'f' suffix.
Eric Christopher7a61d702008-08-08 19:39:37 +000092 Value *EmitUnaryFloatFnCall(Value *Op, const char *Name, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000093
94 /// EmitPutChar - Emit a call to the putchar function. This assumes that Char
95 /// is an integer.
Eric Christopher7a61d702008-08-08 19:39:37 +000096 void EmitPutChar(Value *Char, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +000097
98 /// EmitPutS - Emit a call to the puts function. This assumes that Str is
99 /// some pointer.
Eric Christopher7a61d702008-08-08 19:39:37 +0000100 void EmitPutS(Value *Str, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000101
102 /// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
103 /// an i32, and File is a pointer to FILE.
Eric Christopher7a61d702008-08-08 19:39:37 +0000104 void EmitFPutC(Value *Char, Value *File, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000105
106 /// EmitFPutS - Emit a call to the puts function. Str is required to be a
107 /// pointer and File is a pointer to FILE.
Eric Christopher7a61d702008-08-08 19:39:37 +0000108 void EmitFPutS(Value *Str, Value *File, IRBuilder<> &B);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000109
110 /// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
111 /// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
Eric Christopher7a61d702008-08-08 19:39:37 +0000112 void EmitFWrite(Value *Ptr, Value *Size, Value *File, IRBuilder<> &B);
Nick Lewycky13a09e22008-12-21 00:19:21 +0000113
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000114};
115} // End anonymous namespace.
116
117/// CastToCStr - Return V if it is an i8*, otherwise cast it to i8*.
Eric Christopher7a61d702008-08-08 19:39:37 +0000118Value *LibCallOptimization::CastToCStr(Value *V, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000119 return B.CreateBitCast(V, PointerType::getUnqual(Type::Int8Ty), "cstr");
120}
121
122/// EmitStrLen - Emit a call to the strlen function to the builder, for the
123/// specified pointer. This always returns an integer value of size intptr_t.
Eric Christopher7a61d702008-08-08 19:39:37 +0000124Value *LibCallOptimization::EmitStrLen(Value *Ptr, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000125 Module *M = Caller->getParent();
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000126 AttributeWithIndex AWI[2];
127 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
128 AWI[1] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
129 Attribute::NoUnwind);
130
131 Constant *StrLen =M->getOrInsertFunction("strlen", AttrListPtr::get(AWI, 2),
132 TD->getIntPtrType(),
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000133 PointerType::getUnqual(Type::Int8Ty),
134 NULL);
135 return B.CreateCall(StrLen, CastToCStr(Ptr, B), "strlen");
136}
137
138/// EmitMemCpy - Emit a call to the memcpy function to the builder. This always
139/// expects that the size has type 'intptr_t' and Dst/Src are pointers.
140Value *LibCallOptimization::EmitMemCpy(Value *Dst, Value *Src, Value *Len,
Eric Christopher7a61d702008-08-08 19:39:37 +0000141 unsigned Align, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000142 Module *M = Caller->getParent();
Chris Lattner824b9582008-11-21 16:42:48 +0000143 Intrinsic::ID IID = Intrinsic::memcpy;
144 const Type *Tys[1];
145 Tys[0] = Len->getType();
146 Value *MemCpy = Intrinsic::getDeclaration(M, IID, Tys, 1);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000147 return B.CreateCall4(MemCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Len,
148 ConstantInt::get(Type::Int32Ty, Align));
149}
150
151/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is
152/// a pointer, Val is an i32 value, and Len is an 'intptr_t' value.
153Value *LibCallOptimization::EmitMemChr(Value *Ptr, Value *Val,
Eric Christopher7a61d702008-08-08 19:39:37 +0000154 Value *Len, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000155 Module *M = Caller->getParent();
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000156 AttributeWithIndex AWI;
157 AWI = AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind);
158
159 Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(&AWI, 1),
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000160 PointerType::getUnqual(Type::Int8Ty),
161 PointerType::getUnqual(Type::Int8Ty),
162 Type::Int32Ty, TD->getIntPtrType(),
163 NULL);
164 return B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr");
165}
166
Nick Lewycky13a09e22008-12-21 00:19:21 +0000167/// EmitMemCmp - Emit a call to the memcmp function.
168Value *LibCallOptimization::EmitMemCmp(Value *Ptr1, Value *Ptr2,
169 Value *Len, IRBuilder<> &B) {
170 Module *M = Caller->getParent();
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000171 AttributeWithIndex AWI[3];
172 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
173 AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture);
174 AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly |
175 Attribute::NoUnwind);
176
177 Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI, 3),
Nick Lewycky13a09e22008-12-21 00:19:21 +0000178 Type::Int32Ty,
179 PointerType::getUnqual(Type::Int8Ty),
180 PointerType::getUnqual(Type::Int8Ty),
181 TD->getIntPtrType(), NULL);
182 return B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B),
183 Len, "memcmp");
184}
185
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000186/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g.
187/// 'floor'). This function is known to take a single of type matching 'Op' and
188/// returns one value with the same type. If 'Op' is a long double, 'l' is
189/// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix.
190Value *LibCallOptimization::EmitUnaryFloatFnCall(Value *Op, const char *Name,
Eric Christopher7a61d702008-08-08 19:39:37 +0000191 IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000192 char NameBuffer[20];
193 if (Op->getType() != Type::DoubleTy) {
194 // If we need to add a suffix, copy into NameBuffer.
195 unsigned NameLen = strlen(Name);
196 assert(NameLen < sizeof(NameBuffer)-2);
197 memcpy(NameBuffer, Name, NameLen);
198 if (Op->getType() == Type::FloatTy)
199 NameBuffer[NameLen] = 'f'; // floorf
200 else
201 NameBuffer[NameLen] = 'l'; // floorl
202 NameBuffer[NameLen+1] = 0;
203 Name = NameBuffer;
204 }
205
206 Module *M = Caller->getParent();
207 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
208 Op->getType(), NULL);
209 return B.CreateCall(Callee, Op, Name);
210}
211
212/// EmitPutChar - Emit a call to the putchar function. This assumes that Char
213/// is an integer.
Eric Christopher7a61d702008-08-08 19:39:37 +0000214void LibCallOptimization::EmitPutChar(Value *Char, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000215 Module *M = Caller->getParent();
216 Value *F = M->getOrInsertFunction("putchar", Type::Int32Ty,
217 Type::Int32Ty, NULL);
218 B.CreateCall(F, B.CreateIntCast(Char, Type::Int32Ty, "chari"), "putchar");
219}
220
221/// EmitPutS - Emit a call to the puts function. This assumes that Str is
222/// some pointer.
Eric Christopher7a61d702008-08-08 19:39:37 +0000223void LibCallOptimization::EmitPutS(Value *Str, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000224 Module *M = Caller->getParent();
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000225 AttributeWithIndex AWI[2];
226 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
227 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
228
229 Value *F = M->getOrInsertFunction("puts", AttrListPtr::get(AWI, 2),
230 Type::Int32Ty,
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000231 PointerType::getUnqual(Type::Int8Ty), NULL);
232 B.CreateCall(F, CastToCStr(Str, B), "puts");
233}
234
235/// EmitFPutC - Emit a call to the fputc function. This assumes that Char is
236/// an integer and File is a pointer to FILE.
Eric Christopher7a61d702008-08-08 19:39:37 +0000237void LibCallOptimization::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000238 Module *M = Caller->getParent();
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000239 AttributeWithIndex AWI[2];
240 AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
241 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
242 Constant *F;
243 if (isa<PointerType>(File->getType()))
244 F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI, 2), Type::Int32Ty,
245 Type::Int32Ty, File->getType(), NULL);
246
247 else
248 F = M->getOrInsertFunction("fputc", Type::Int32Ty, Type::Int32Ty,
249 File->getType(), NULL);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000250 Char = B.CreateIntCast(Char, Type::Int32Ty, "chari");
251 B.CreateCall2(F, Char, File, "fputc");
252}
253
254/// EmitFPutS - Emit a call to the puts function. Str is required to be a
255/// pointer and File is a pointer to FILE.
Eric Christopher7a61d702008-08-08 19:39:37 +0000256void LibCallOptimization::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000257 Module *M = Caller->getParent();
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000258 AttributeWithIndex AWI[2];
259 AWI[0] = AttributeWithIndex::get(2, Attribute::NoCapture);
260 AWI[1] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
261 Constant *F;
262 if (isa<PointerType>(File->getType()))
263 F = M->getOrInsertFunction("fputs", AttrListPtr::get(AWI, 2), Type::Int32Ty,
264 PointerType::getUnqual(Type::Int8Ty),
265 File->getType(), NULL);
266 else
267 F = M->getOrInsertFunction("fputs", Type::Int32Ty,
268 PointerType::getUnqual(Type::Int8Ty),
269 File->getType(), NULL);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000270 B.CreateCall2(F, CastToCStr(Str, B), File, "fputs");
271}
272
273/// EmitFWrite - Emit a call to the fwrite function. This assumes that Ptr is
274/// a pointer, Size is an 'intptr_t', and File is a pointer to FILE.
275void LibCallOptimization::EmitFWrite(Value *Ptr, Value *Size, Value *File,
Eric Christopher7a61d702008-08-08 19:39:37 +0000276 IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000277 Module *M = Caller->getParent();
Nick Lewycky6cd0c042009-01-05 00:07:50 +0000278 AttributeWithIndex AWI[3];
279 AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture);
280 AWI[1] = AttributeWithIndex::get(4, Attribute::NoCapture);
281 AWI[2] = AttributeWithIndex::get(~0u, Attribute::NoUnwind);
282 Constant *F;
283 if (isa<PointerType>(File->getType()))
284 F = M->getOrInsertFunction("fwrite", AttrListPtr::get(AWI, 3),
285 TD->getIntPtrType(),
286 PointerType::getUnqual(Type::Int8Ty),
287 TD->getIntPtrType(), TD->getIntPtrType(),
288 File->getType(), NULL);
289 else
290 F = M->getOrInsertFunction("fwrite", TD->getIntPtrType(),
291 PointerType::getUnqual(Type::Int8Ty),
292 TD->getIntPtrType(), TD->getIntPtrType(),
293 File->getType(), NULL);
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000294 B.CreateCall4(F, CastToCStr(Ptr, B), Size,
295 ConstantInt::get(TD->getIntPtrType(), 1), File);
296}
297
298//===----------------------------------------------------------------------===//
299// Helper Functions
300//===----------------------------------------------------------------------===//
301
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000302/// GetStringLengthH - If we can compute the length of the string pointed to by
303/// the specified pointer, return 'len+1'. If we can't, return 0.
304static uint64_t GetStringLengthH(Value *V, SmallPtrSet<PHINode*, 32> &PHIs) {
305 // Look through noop bitcast instructions.
306 if (BitCastInst *BCI = dyn_cast<BitCastInst>(V))
307 return GetStringLengthH(BCI->getOperand(0), PHIs);
308
309 // If this is a PHI node, there are two cases: either we have already seen it
310 // or we haven't.
311 if (PHINode *PN = dyn_cast<PHINode>(V)) {
312 if (!PHIs.insert(PN))
313 return ~0ULL; // already in the set.
314
315 // If it was new, see if all the input strings are the same length.
316 uint64_t LenSoFar = ~0ULL;
317 for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
318 uint64_t Len = GetStringLengthH(PN->getIncomingValue(i), PHIs);
319 if (Len == 0) return 0; // Unknown length -> unknown.
320
321 if (Len == ~0ULL) continue;
322
323 if (Len != LenSoFar && LenSoFar != ~0ULL)
324 return 0; // Disagree -> unknown.
325 LenSoFar = Len;
326 }
327
328 // Success, all agree.
329 return LenSoFar;
330 }
331
332 // strlen(select(c,x,y)) -> strlen(x) ^ strlen(y)
333 if (SelectInst *SI = dyn_cast<SelectInst>(V)) {
334 uint64_t Len1 = GetStringLengthH(SI->getTrueValue(), PHIs);
335 if (Len1 == 0) return 0;
336 uint64_t Len2 = GetStringLengthH(SI->getFalseValue(), PHIs);
337 if (Len2 == 0) return 0;
338 if (Len1 == ~0ULL) return Len2;
339 if (Len2 == ~0ULL) return Len1;
340 if (Len1 != Len2) return 0;
341 return Len1;
342 }
343
344 // If the value is not a GEP instruction nor a constant expression with a
345 // GEP instruction, then return unknown.
346 User *GEP = 0;
347 if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) {
348 GEP = GEPI;
349 } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
350 if (CE->getOpcode() != Instruction::GetElementPtr)
351 return 0;
352 GEP = CE;
353 } else {
354 return 0;
355 }
356
357 // Make sure the GEP has exactly three arguments.
358 if (GEP->getNumOperands() != 3)
359 return 0;
360
361 // Check to make sure that the first operand of the GEP is an integer and
362 // has value 0 so that we are sure we're indexing into the initializer.
363 if (ConstantInt *Idx = dyn_cast<ConstantInt>(GEP->getOperand(1))) {
364 if (!Idx->isZero())
365 return 0;
366 } else
367 return 0;
368
369 // If the second index isn't a ConstantInt, then this is a variable index
370 // into the array. If this occurs, we can't say anything meaningful about
371 // the string.
372 uint64_t StartIdx = 0;
373 if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2)))
374 StartIdx = CI->getZExtValue();
375 else
376 return 0;
377
378 // The GEP instruction, constant or instruction, must reference a global
379 // variable that is a constant and is initialized. The referenced constant
380 // initializer is the array that we'll use for optimization.
381 GlobalVariable* GV = dyn_cast<GlobalVariable>(GEP->getOperand(0));
382 if (!GV || !GV->isConstant() || !GV->hasInitializer())
383 return 0;
384 Constant *GlobalInit = GV->getInitializer();
385
386 // Handle the ConstantAggregateZero case, which is a degenerate case. The
387 // initializer is constant zero so the length of the string must be zero.
388 if (isa<ConstantAggregateZero>(GlobalInit))
389 return 1; // Len = 0 offset by 1.
390
391 // Must be a Constant Array
392 ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
393 if (!Array || Array->getType()->getElementType() != Type::Int8Ty)
394 return false;
395
396 // Get the number of elements in the array
397 uint64_t NumElts = Array->getType()->getNumElements();
398
399 // Traverse the constant array from StartIdx (derived above) which is
400 // the place the GEP refers to in the array.
401 for (unsigned i = StartIdx; i != NumElts; ++i) {
402 Constant *Elt = Array->getOperand(i);
403 ConstantInt *CI = dyn_cast<ConstantInt>(Elt);
404 if (!CI) // This array isn't suitable, non-int initializer.
405 return 0;
406 if (CI->isZero())
407 return i-StartIdx+1; // We found end of string, success!
408 }
409
410 return 0; // The array isn't null terminated, conservatively return 'unknown'.
411}
412
413/// GetStringLength - If we can compute the length of the string pointed to by
414/// the specified pointer, return 'len+1'. If we can't, return 0.
415static uint64_t GetStringLength(Value *V) {
416 if (!isa<PointerType>(V->getType())) return 0;
417
418 SmallPtrSet<PHINode*, 32> PHIs;
419 uint64_t Len = GetStringLengthH(V, PHIs);
420 // If Len is ~0ULL, we had an infinite phi cycle: this is dead code, so return
421 // an empty string as a length.
422 return Len == ~0ULL ? 1 : Len;
423}
424
425/// IsOnlyUsedInZeroEqualityComparison - Return true if it only matters that the
426/// value is equal or not-equal to zero.
427static bool IsOnlyUsedInZeroEqualityComparison(Value *V) {
428 for (Value::use_iterator UI = V->use_begin(), E = V->use_end();
429 UI != E; ++UI) {
430 if (ICmpInst *IC = dyn_cast<ICmpInst>(*UI))
431 if (IC->isEquality())
432 if (Constant *C = dyn_cast<Constant>(IC->getOperand(1)))
433 if (C->isNullValue())
434 continue;
435 // Unknown instruction.
436 return false;
437 }
438 return true;
439}
440
441//===----------------------------------------------------------------------===//
442// Miscellaneous LibCall Optimizations
443//===----------------------------------------------------------------------===//
444
Bill Wendlingac178222008-05-05 21:37:59 +0000445namespace {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000446//===---------------------------------------===//
447// 'exit' Optimizations
448
449/// ExitOpt - int main() { exit(4); } --> int main() { return 4; }
450struct VISIBILITY_HIDDEN ExitOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000451 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000452 // Verify we have a reasonable prototype for exit.
453 if (Callee->arg_size() == 0 || !CI->use_empty())
454 return 0;
455
456 // Verify the caller is main, and that the result type of main matches the
457 // argument type of exit.
458 if (!Caller->isName("main") || !Caller->hasExternalLinkage() ||
459 Caller->getReturnType() != CI->getOperand(1)->getType())
460 return 0;
461
462 TerminatorInst *OldTI = CI->getParent()->getTerminator();
463
464 // Create the return after the call.
465 ReturnInst *RI = B.CreateRet(CI->getOperand(1));
466
467 // Drop all successor phi node entries.
468 for (unsigned i = 0, e = OldTI->getNumSuccessors(); i != e; ++i)
469 OldTI->getSuccessor(i)->removePredecessor(CI->getParent());
470
471 // Erase all instructions from after our return instruction until the end of
472 // the block.
473 BasicBlock::iterator FirstDead = RI; ++FirstDead;
474 CI->getParent()->getInstList().erase(FirstDead, CI->getParent()->end());
475 return CI;
476 }
477};
478
479//===----------------------------------------------------------------------===//
480// String and Memory LibCall Optimizations
481//===----------------------------------------------------------------------===//
482
483//===---------------------------------------===//
484// 'strcat' Optimizations
485
486struct VISIBILITY_HIDDEN StrCatOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000487 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000488 // Verify the "strcat" function prototype.
489 const FunctionType *FT = Callee->getFunctionType();
490 if (FT->getNumParams() != 2 ||
491 FT->getReturnType() != PointerType::getUnqual(Type::Int8Ty) ||
492 FT->getParamType(0) != FT->getReturnType() ||
493 FT->getParamType(1) != FT->getReturnType())
494 return 0;
495
496 // Extract some information from the instruction
497 Value *Dst = CI->getOperand(1);
498 Value *Src = CI->getOperand(2);
499
500 // See if we can get the length of the input string.
501 uint64_t Len = GetStringLength(Src);
Chris Lattner56b4f2b2008-05-01 06:39:12 +0000502 if (Len == 0) return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000503 --Len; // Unbias length.
504
505 // Handle the simple, do-nothing case: strcat(x, "") -> x
506 if (Len == 0)
507 return Dst;
508
509 // We need to find the end of the destination string. That's where the
510 // memory is to be moved to. We just generate a call to strlen.
511 Value *DstLen = EmitStrLen(Dst, B);
512
513 // Now that we have the destination's length, we must index into the
514 // destination's pointer to get the actual memcpy destination (end of
515 // the string .. we're concatenating).
516 Dst = B.CreateGEP(Dst, DstLen, "endptr");
517
518 // We have enough information to now generate the memcpy call to do the
519 // concatenation for us. Make a memcpy to copy the nul byte with align = 1.
520 EmitMemCpy(Dst, Src, ConstantInt::get(TD->getIntPtrType(), Len+1), 1, B);
521 return Dst;
522 }
523};
524
525//===---------------------------------------===//
526// 'strchr' Optimizations
527
528struct VISIBILITY_HIDDEN StrChrOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000529 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000530 // Verify the "strchr" function prototype.
531 const FunctionType *FT = Callee->getFunctionType();
532 if (FT->getNumParams() != 2 ||
533 FT->getReturnType() != PointerType::getUnqual(Type::Int8Ty) ||
534 FT->getParamType(0) != FT->getReturnType())
535 return 0;
536
537 Value *SrcStr = CI->getOperand(1);
538
539 // If the second operand is non-constant, see if we can compute the length
540 // of the input string and turn this into memchr.
541 ConstantInt *CharC = dyn_cast<ConstantInt>(CI->getOperand(2));
542 if (CharC == 0) {
543 uint64_t Len = GetStringLength(SrcStr);
544 if (Len == 0 || FT->getParamType(1) != Type::Int32Ty) // memchr needs i32.
545 return 0;
546
547 return EmitMemChr(SrcStr, CI->getOperand(2), // include nul.
548 ConstantInt::get(TD->getIntPtrType(), Len), B);
549 }
550
551 // Otherwise, the character is a constant, see if the first argument is
552 // a string literal. If so, we can constant fold.
553 std::string Str;
554 if (!GetConstantStringInfo(SrcStr, Str))
Chris Lattner56b4f2b2008-05-01 06:39:12 +0000555 return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000556
557 // strchr can find the nul character.
558 Str += '\0';
559 char CharValue = CharC->getSExtValue();
560
561 // Compute the offset.
562 uint64_t i = 0;
563 while (1) {
564 if (i == Str.size()) // Didn't find the char. strchr returns null.
565 return Constant::getNullValue(CI->getType());
566 // Did we find our match?
567 if (Str[i] == CharValue)
568 break;
569 ++i;
570 }
571
572 // strchr(s+n,c) -> gep(s+n+i,c)
573 Value *Idx = ConstantInt::get(Type::Int64Ty, i);
574 return B.CreateGEP(SrcStr, Idx, "strchr");
575 }
576};
577
578//===---------------------------------------===//
579// 'strcmp' Optimizations
580
581struct VISIBILITY_HIDDEN StrCmpOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000582 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000583 // Verify the "strcmp" function prototype.
584 const FunctionType *FT = Callee->getFunctionType();
585 if (FT->getNumParams() != 2 || FT->getReturnType() != Type::Int32Ty ||
586 FT->getParamType(0) != FT->getParamType(1) ||
587 FT->getParamType(0) != PointerType::getUnqual(Type::Int8Ty))
588 return 0;
589
590 Value *Str1P = CI->getOperand(1), *Str2P = CI->getOperand(2);
591 if (Str1P == Str2P) // strcmp(x,x) -> 0
592 return ConstantInt::get(CI->getType(), 0);
593
594 std::string Str1, Str2;
595 bool HasStr1 = GetConstantStringInfo(Str1P, Str1);
596 bool HasStr2 = GetConstantStringInfo(Str2P, Str2);
597
598 if (HasStr1 && Str1.empty()) // strcmp("", x) -> *x
599 return B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), CI->getType());
600
601 if (HasStr2 && Str2.empty()) // strcmp(x,"") -> *x
602 return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType());
603
604 // strcmp(x, y) -> cnst (if both x and y are constant strings)
605 if (HasStr1 && HasStr2)
606 return ConstantInt::get(CI->getType(), strcmp(Str1.c_str(),Str2.c_str()));
Nick Lewycky13a09e22008-12-21 00:19:21 +0000607
608 // strcmp(P, "x") -> memcmp(P, "x", 2)
609 uint64_t Len1 = GetStringLength(Str1P);
610 uint64_t Len2 = GetStringLength(Str2P);
611 if (Len1 || Len2) {
612 // Choose the smallest Len excluding 0 which means 'unknown'.
613 if (!Len1 || (Len2 && Len2 < Len1))
614 Len1 = Len2;
615 return EmitMemCmp(Str1P, Str2P,
616 ConstantInt::get(TD->getIntPtrType(), Len1), B);
617 }
618
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000619 return 0;
620 }
621};
622
623//===---------------------------------------===//
624// 'strncmp' Optimizations
625
626struct VISIBILITY_HIDDEN StrNCmpOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000627 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000628 // Verify the "strncmp" function prototype.
629 const FunctionType *FT = Callee->getFunctionType();
630 if (FT->getNumParams() != 3 || FT->getReturnType() != Type::Int32Ty ||
631 FT->getParamType(0) != FT->getParamType(1) ||
632 FT->getParamType(0) != PointerType::getUnqual(Type::Int8Ty) ||
633 !isa<IntegerType>(FT->getParamType(2)))
634 return 0;
635
636 Value *Str1P = CI->getOperand(1), *Str2P = CI->getOperand(2);
637 if (Str1P == Str2P) // strncmp(x,x,n) -> 0
638 return ConstantInt::get(CI->getType(), 0);
639
640 // Get the length argument if it is constant.
641 uint64_t Length;
642 if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getOperand(3)))
643 Length = LengthArg->getZExtValue();
644 else
645 return 0;
646
647 if (Length == 0) // strncmp(x,y,0) -> 0
648 return ConstantInt::get(CI->getType(), 0);
649
650 std::string Str1, Str2;
651 bool HasStr1 = GetConstantStringInfo(Str1P, Str1);
652 bool HasStr2 = GetConstantStringInfo(Str2P, Str2);
653
654 if (HasStr1 && Str1.empty()) // strncmp("", x, n) -> *x
655 return B.CreateZExt(B.CreateLoad(Str2P, "strcmpload"), CI->getType());
656
657 if (HasStr2 && Str2.empty()) // strncmp(x, "", n) -> *x
658 return B.CreateZExt(B.CreateLoad(Str1P, "strcmpload"), CI->getType());
659
660 // strncmp(x, y) -> cnst (if both x and y are constant strings)
661 if (HasStr1 && HasStr2)
662 return ConstantInt::get(CI->getType(),
663 strncmp(Str1.c_str(), Str2.c_str(), Length));
664 return 0;
665 }
666};
667
668
669//===---------------------------------------===//
670// 'strcpy' Optimizations
671
672struct VISIBILITY_HIDDEN StrCpyOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000673 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000674 // Verify the "strcpy" function prototype.
675 const FunctionType *FT = Callee->getFunctionType();
676 if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) ||
677 FT->getParamType(0) != FT->getParamType(1) ||
678 FT->getParamType(0) != PointerType::getUnqual(Type::Int8Ty))
679 return 0;
680
681 Value *Dst = CI->getOperand(1), *Src = CI->getOperand(2);
682 if (Dst == Src) // strcpy(x,x) -> x
683 return Src;
684
685 // See if we can get the length of the input string.
686 uint64_t Len = GetStringLength(Src);
Chris Lattner56b4f2b2008-05-01 06:39:12 +0000687 if (Len == 0) return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000688
689 // We have enough information to now generate the memcpy call to do the
690 // concatenation for us. Make a memcpy to copy the nul byte with align = 1.
691 EmitMemCpy(Dst, Src, ConstantInt::get(TD->getIntPtrType(), Len), 1, B);
692 return Dst;
693 }
694};
695
696
697
698//===---------------------------------------===//
699// 'strlen' Optimizations
700
701struct VISIBILITY_HIDDEN StrLenOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000702 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000703 const FunctionType *FT = Callee->getFunctionType();
704 if (FT->getNumParams() != 1 ||
705 FT->getParamType(0) != PointerType::getUnqual(Type::Int8Ty) ||
706 !isa<IntegerType>(FT->getReturnType()))
707 return 0;
708
709 Value *Src = CI->getOperand(1);
710
711 // Constant folding: strlen("xyz") -> 3
712 if (uint64_t Len = GetStringLength(Src))
713 return ConstantInt::get(CI->getType(), Len-1);
714
715 // Handle strlen(p) != 0.
716 if (!IsOnlyUsedInZeroEqualityComparison(CI)) return 0;
717
718 // strlen(x) != 0 --> *x != 0
719 // strlen(x) == 0 --> *x == 0
720 return B.CreateZExt(B.CreateLoad(Src, "strlenfirst"), CI->getType());
721 }
722};
723
724//===---------------------------------------===//
Nick Lewycky4c498412009-02-13 15:31:46 +0000725// 'strto*' Optimizations
726
727struct VISIBILITY_HIDDEN StrToOpt : public LibCallOptimization {
728 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
729 const FunctionType *FT = Callee->getFunctionType();
730 if ((FT->getNumParams() != 2 && FT->getNumParams() != 3) ||
731 !isa<PointerType>(FT->getParamType(0)) ||
732 !isa<PointerType>(FT->getParamType(1)))
733 return 0;
734
735 Value *EndPtr = CI->getOperand(2);
Nick Lewycky02b6a6a2009-02-13 17:08:33 +0000736 if (isa<ConstantPointerNull>(EndPtr)) {
737 CI->setOnlyReadsMemory();
Nick Lewycky4c498412009-02-13 15:31:46 +0000738 CI->addAttribute(1, Attribute::NoCapture);
Nick Lewycky02b6a6a2009-02-13 17:08:33 +0000739 }
Nick Lewycky4c498412009-02-13 15:31:46 +0000740
741 return 0;
742 }
743};
744
745
746//===---------------------------------------===//
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000747// 'memcmp' Optimizations
748
749struct VISIBILITY_HIDDEN MemCmpOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000750 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000751 const FunctionType *FT = Callee->getFunctionType();
752 if (FT->getNumParams() != 3 || !isa<PointerType>(FT->getParamType(0)) ||
753 !isa<PointerType>(FT->getParamType(1)) ||
754 FT->getReturnType() != Type::Int32Ty)
755 return 0;
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000756
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000757 Value *LHS = CI->getOperand(1), *RHS = CI->getOperand(2);
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000758
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000759 if (LHS == RHS) // memcmp(s,s,x) -> 0
760 return Constant::getNullValue(CI->getType());
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000761
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000762 // Make sure we have a constant length.
763 ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getOperand(3));
Chris Lattner56b4f2b2008-05-01 06:39:12 +0000764 if (!LenC) return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000765 uint64_t Len = LenC->getZExtValue();
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000766
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000767 if (Len == 0) // memcmp(s1,s2,0) -> 0
768 return Constant::getNullValue(CI->getType());
769
770 if (Len == 1) { // memcmp(S1,S2,1) -> *LHS - *RHS
771 Value *LHSV = B.CreateLoad(CastToCStr(LHS, B), "lhsv");
772 Value *RHSV = B.CreateLoad(CastToCStr(RHS, B), "rhsv");
773 return B.CreateZExt(B.CreateSub(LHSV, RHSV, "chardiff"), CI->getType());
774 }
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000775
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000776 // memcmp(S1,S2,2) != 0 -> (*(short*)LHS ^ *(short*)RHS) != 0
777 // memcmp(S1,S2,4) != 0 -> (*(int*)LHS ^ *(int*)RHS) != 0
778 if ((Len == 2 || Len == 4) && IsOnlyUsedInZeroEqualityComparison(CI)) {
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000779 const Type *PTy = PointerType::getUnqual(Len == 2 ?
780 Type::Int16Ty : Type::Int32Ty);
781 LHS = B.CreateBitCast(LHS, PTy, "tmp");
782 RHS = B.CreateBitCast(RHS, PTy, "tmp");
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000783 LoadInst *LHSV = B.CreateLoad(LHS, "lhsv");
784 LoadInst *RHSV = B.CreateLoad(RHS, "rhsv");
785 LHSV->setAlignment(1); RHSV->setAlignment(1); // Unaligned loads.
786 return B.CreateZExt(B.CreateXor(LHSV, RHSV, "shortdiff"), CI->getType());
787 }
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000788
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000789 return 0;
790 }
791};
792
793//===---------------------------------------===//
794// 'memcpy' Optimizations
795
796struct VISIBILITY_HIDDEN MemCpyOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000797 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000798 const FunctionType *FT = Callee->getFunctionType();
799 if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
800 !isa<PointerType>(FT->getParamType(0)) ||
801 !isa<PointerType>(FT->getParamType(1)) ||
802 FT->getParamType(2) != TD->getIntPtrType())
803 return 0;
804
805 // memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1)
806 EmitMemCpy(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3), 1, B);
807 return CI->getOperand(1);
808 }
809};
810
Eli Friedmand83ae7d2008-11-30 08:32:11 +0000811//===---------------------------------------===//
812// 'memmove' Optimizations
813
814struct VISIBILITY_HIDDEN MemMoveOpt : public LibCallOptimization {
815 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
816 const FunctionType *FT = Callee->getFunctionType();
817 if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
818 !isa<PointerType>(FT->getParamType(0)) ||
819 !isa<PointerType>(FT->getParamType(1)) ||
820 FT->getParamType(2) != TD->getIntPtrType())
821 return 0;
822
823 // memmove(x, y, n) -> llvm.memmove(x, y, n, 1)
824 Module *M = Caller->getParent();
825 Intrinsic::ID IID = Intrinsic::memmove;
826 const Type *Tys[1];
827 Tys[0] = TD->getIntPtrType();
828 Value *MemMove = Intrinsic::getDeclaration(M, IID, Tys, 1);
829 Value *Dst = CastToCStr(CI->getOperand(1), B);
830 Value *Src = CastToCStr(CI->getOperand(2), B);
831 Value *Size = CI->getOperand(3);
832 Value *Align = ConstantInt::get(Type::Int32Ty, 1);
833 B.CreateCall4(MemMove, Dst, Src, Size, Align);
834 return CI->getOperand(1);
835 }
836};
837
838//===---------------------------------------===//
839// 'memset' Optimizations
840
841struct VISIBILITY_HIDDEN MemSetOpt : public LibCallOptimization {
842 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
843 const FunctionType *FT = Callee->getFunctionType();
844 if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
845 !isa<PointerType>(FT->getParamType(0)) ||
846 FT->getParamType(1) != TD->getIntPtrType() ||
847 FT->getParamType(2) != TD->getIntPtrType())
848 return 0;
849
850 // memset(p, v, n) -> llvm.memset(p, v, n, 1)
851 Module *M = Caller->getParent();
852 Intrinsic::ID IID = Intrinsic::memset;
853 const Type *Tys[1];
854 Tys[0] = TD->getIntPtrType();
855 Value *MemSet = Intrinsic::getDeclaration(M, IID, Tys, 1);
856 Value *Dst = CastToCStr(CI->getOperand(1), B);
857 Value *Val = B.CreateTrunc(CI->getOperand(2), Type::Int8Ty);
858 Value *Size = CI->getOperand(3);
859 Value *Align = ConstantInt::get(Type::Int32Ty, 1);
860 B.CreateCall4(MemSet, Dst, Val, Size, Align);
861 return CI->getOperand(1);
862 }
863};
864
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000865//===----------------------------------------------------------------------===//
866// Math Library Optimizations
867//===----------------------------------------------------------------------===//
868
869//===---------------------------------------===//
870// 'pow*' Optimizations
871
872struct VISIBILITY_HIDDEN PowOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000873 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000874 const FunctionType *FT = Callee->getFunctionType();
875 // Just make sure this has 2 arguments of the same FP type, which match the
876 // result type.
877 if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) ||
878 FT->getParamType(0) != FT->getParamType(1) ||
879 !FT->getParamType(0)->isFloatingPoint())
880 return 0;
881
882 Value *Op1 = CI->getOperand(1), *Op2 = CI->getOperand(2);
883 if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1)) {
884 if (Op1C->isExactlyValue(1.0)) // pow(1.0, x) -> 1.0
885 return Op1C;
886 if (Op1C->isExactlyValue(2.0)) // pow(2.0, x) -> exp2(x)
887 return EmitUnaryFloatFnCall(Op2, "exp2", B);
888 }
889
890 ConstantFP *Op2C = dyn_cast<ConstantFP>(Op2);
891 if (Op2C == 0) return 0;
892
893 if (Op2C->getValueAPF().isZero()) // pow(x, 0.0) -> 1.0
894 return ConstantFP::get(CI->getType(), 1.0);
895
896 if (Op2C->isExactlyValue(0.5)) {
897 // FIXME: This is not safe for -0.0 and -inf. This can only be done when
898 // 'unsafe' math optimizations are allowed.
899 // x pow(x, 0.5) sqrt(x)
900 // ---------------------------------------------
901 // -0.0 +0.0 -0.0
902 // -inf +inf NaN
903#if 0
904 // pow(x, 0.5) -> sqrt(x)
905 return B.CreateCall(get_sqrt(), Op1, "sqrt");
906#endif
907 }
908
909 if (Op2C->isExactlyValue(1.0)) // pow(x, 1.0) -> x
910 return Op1;
911 if (Op2C->isExactlyValue(2.0)) // pow(x, 2.0) -> x*x
912 return B.CreateMul(Op1, Op1, "pow2");
913 if (Op2C->isExactlyValue(-1.0)) // pow(x, -1.0) -> 1.0/x
914 return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0), Op1, "powrecip");
915 return 0;
916 }
917};
918
919//===---------------------------------------===//
Chris Lattnere818f772008-05-02 18:43:35 +0000920// 'exp2' Optimizations
921
922struct VISIBILITY_HIDDEN Exp2Opt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000923 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnere818f772008-05-02 18:43:35 +0000924 const FunctionType *FT = Callee->getFunctionType();
925 // Just make sure this has 1 argument of FP type, which matches the
926 // result type.
927 if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
928 !FT->getParamType(0)->isFloatingPoint())
929 return 0;
930
931 Value *Op = CI->getOperand(1);
932 // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x)) if sizeof(x) <= 32
933 // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < 32
934 Value *LdExpArg = 0;
935 if (SIToFPInst *OpC = dyn_cast<SIToFPInst>(Op)) {
936 if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() <= 32)
937 LdExpArg = B.CreateSExt(OpC->getOperand(0), Type::Int32Ty, "tmp");
938 } else if (UIToFPInst *OpC = dyn_cast<UIToFPInst>(Op)) {
939 if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() < 32)
940 LdExpArg = B.CreateZExt(OpC->getOperand(0), Type::Int32Ty, "tmp");
941 }
942
943 if (LdExpArg) {
944 const char *Name;
945 if (Op->getType() == Type::FloatTy)
946 Name = "ldexpf";
947 else if (Op->getType() == Type::DoubleTy)
948 Name = "ldexp";
949 else
950 Name = "ldexpl";
951
952 Constant *One = ConstantFP::get(APFloat(1.0f));
953 if (Op->getType() != Type::FloatTy)
954 One = ConstantExpr::getFPExtend(One, Op->getType());
955
956 Module *M = Caller->getParent();
957 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
958 Op->getType(), Type::Int32Ty,NULL);
959 return B.CreateCall2(Callee, One, LdExpArg);
960 }
961 return 0;
962 }
963};
964
965
966//===---------------------------------------===//
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000967// Double -> Float Shrinking Optimizations for Unary Functions like 'floor'
968
969struct VISIBILITY_HIDDEN UnaryDoubleFPOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000970 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000971 const FunctionType *FT = Callee->getFunctionType();
972 if (FT->getNumParams() != 1 || FT->getReturnType() != Type::DoubleTy ||
973 FT->getParamType(0) != Type::DoubleTy)
974 return 0;
975
976 // If this is something like 'floor((double)floatval)', convert to floorf.
977 FPExtInst *Cast = dyn_cast<FPExtInst>(CI->getOperand(1));
978 if (Cast == 0 || Cast->getOperand(0)->getType() != Type::FloatTy)
979 return 0;
980
981 // floor((double)floatval) -> (double)floorf(floatval)
982 Value *V = Cast->getOperand(0);
983 V = EmitUnaryFloatFnCall(V, Callee->getNameStart(), B);
984 return B.CreateFPExt(V, Type::DoubleTy);
985 }
986};
987
988//===----------------------------------------------------------------------===//
989// Integer Optimizations
990//===----------------------------------------------------------------------===//
991
992//===---------------------------------------===//
993// 'ffs*' Optimizations
994
995struct VISIBILITY_HIDDEN FFSOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000996 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000997 const FunctionType *FT = Callee->getFunctionType();
998 // Just make sure this has 2 arguments of the same FP type, which match the
999 // result type.
1000 if (FT->getNumParams() != 1 || FT->getReturnType() != Type::Int32Ty ||
1001 !isa<IntegerType>(FT->getParamType(0)))
1002 return 0;
1003
1004 Value *Op = CI->getOperand(1);
1005
1006 // Constant fold.
1007 if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
1008 if (CI->getValue() == 0) // ffs(0) -> 0.
1009 return Constant::getNullValue(CI->getType());
1010 return ConstantInt::get(Type::Int32Ty, // ffs(c) -> cttz(c)+1
1011 CI->getValue().countTrailingZeros()+1);
1012 }
1013
1014 // ffs(x) -> x != 0 ? (i32)llvm.cttz(x)+1 : 0
1015 const Type *ArgType = Op->getType();
1016 Value *F = Intrinsic::getDeclaration(Callee->getParent(),
1017 Intrinsic::cttz, &ArgType, 1);
1018 Value *V = B.CreateCall(F, Op, "cttz");
1019 V = B.CreateAdd(V, ConstantInt::get(Type::Int32Ty, 1), "tmp");
1020 V = B.CreateIntCast(V, Type::Int32Ty, false, "tmp");
1021
1022 Value *Cond = B.CreateICmpNE(Op, Constant::getNullValue(ArgType), "tmp");
1023 return B.CreateSelect(Cond, V, ConstantInt::get(Type::Int32Ty, 0));
1024 }
1025};
1026
1027//===---------------------------------------===//
1028// 'isdigit' Optimizations
1029
1030struct VISIBILITY_HIDDEN IsDigitOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001031 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001032 const FunctionType *FT = Callee->getFunctionType();
1033 // We require integer(i32)
1034 if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) ||
1035 FT->getParamType(0) != Type::Int32Ty)
1036 return 0;
1037
1038 // isdigit(c) -> (c-'0') <u 10
1039 Value *Op = CI->getOperand(1);
1040 Op = B.CreateSub(Op, ConstantInt::get(Type::Int32Ty, '0'), "isdigittmp");
1041 Op = B.CreateICmpULT(Op, ConstantInt::get(Type::Int32Ty, 10), "isdigit");
1042 return B.CreateZExt(Op, CI->getType());
1043 }
1044};
1045
1046//===---------------------------------------===//
1047// 'isascii' Optimizations
1048
1049struct VISIBILITY_HIDDEN IsAsciiOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001050 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001051 const FunctionType *FT = Callee->getFunctionType();
1052 // We require integer(i32)
1053 if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) ||
1054 FT->getParamType(0) != Type::Int32Ty)
1055 return 0;
1056
1057 // isascii(c) -> c <u 128
1058 Value *Op = CI->getOperand(1);
1059 Op = B.CreateICmpULT(Op, ConstantInt::get(Type::Int32Ty, 128), "isascii");
1060 return B.CreateZExt(Op, CI->getType());
1061 }
1062};
Chris Lattner313f0e62008-06-09 08:26:51 +00001063
1064//===---------------------------------------===//
1065// 'abs', 'labs', 'llabs' Optimizations
1066
1067struct VISIBILITY_HIDDEN AbsOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001068 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattner313f0e62008-06-09 08:26:51 +00001069 const FunctionType *FT = Callee->getFunctionType();
1070 // We require integer(integer) where the types agree.
1071 if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) ||
1072 FT->getParamType(0) != FT->getReturnType())
1073 return 0;
1074
1075 // abs(x) -> x >s -1 ? x : -x
1076 Value *Op = CI->getOperand(1);
1077 Value *Pos = B.CreateICmpSGT(Op,ConstantInt::getAllOnesValue(Op->getType()),
1078 "ispos");
1079 Value *Neg = B.CreateNeg(Op, "neg");
1080 return B.CreateSelect(Pos, Op, Neg);
1081 }
1082};
1083
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001084
1085//===---------------------------------------===//
1086// 'toascii' Optimizations
1087
1088struct VISIBILITY_HIDDEN ToAsciiOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001089 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001090 const FunctionType *FT = Callee->getFunctionType();
1091 // We require i32(i32)
1092 if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
1093 FT->getParamType(0) != Type::Int32Ty)
1094 return 0;
1095
1096 // isascii(c) -> c & 0x7f
1097 return B.CreateAnd(CI->getOperand(1), ConstantInt::get(CI->getType(),0x7F));
1098 }
1099};
1100
1101//===----------------------------------------------------------------------===//
1102// Formatting and IO Optimizations
1103//===----------------------------------------------------------------------===//
1104
1105//===---------------------------------------===//
1106// 'printf' Optimizations
1107
1108struct VISIBILITY_HIDDEN PrintFOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001109 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001110 // Require one fixed pointer argument and an integer/void result.
1111 const FunctionType *FT = Callee->getFunctionType();
1112 if (FT->getNumParams() < 1 || !isa<PointerType>(FT->getParamType(0)) ||
1113 !(isa<IntegerType>(FT->getReturnType()) ||
1114 FT->getReturnType() == Type::VoidTy))
1115 return 0;
1116
1117 // Check for a fixed format string.
1118 std::string FormatStr;
1119 if (!GetConstantStringInfo(CI->getOperand(1), FormatStr))
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001120 return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001121
1122 // Empty format string -> noop.
1123 if (FormatStr.empty()) // Tolerate printf's declared void.
1124 return CI->use_empty() ? (Value*)CI : ConstantInt::get(CI->getType(), 0);
1125
1126 // printf("x") -> putchar('x'), even for '%'.
1127 if (FormatStr.size() == 1) {
1128 EmitPutChar(ConstantInt::get(Type::Int32Ty, FormatStr[0]), B);
1129 return CI->use_empty() ? (Value*)CI : ConstantInt::get(CI->getType(), 1);
1130 }
1131
1132 // printf("foo\n") --> puts("foo")
1133 if (FormatStr[FormatStr.size()-1] == '\n' &&
1134 FormatStr.find('%') == std::string::npos) { // no format characters.
1135 // Create a string literal with no \n on it. We expect the constant merge
1136 // pass to be run after this pass, to merge duplicate strings.
1137 FormatStr.erase(FormatStr.end()-1);
1138 Constant *C = ConstantArray::get(FormatStr, true);
1139 C = new GlobalVariable(C->getType(), true,GlobalVariable::InternalLinkage,
1140 C, "str", Callee->getParent());
1141 EmitPutS(C, B);
1142 return CI->use_empty() ? (Value*)CI :
1143 ConstantInt::get(CI->getType(), FormatStr.size()+1);
1144 }
1145
1146 // Optimize specific format strings.
1147 // printf("%c", chr) --> putchar(*(i8*)dst)
1148 if (FormatStr == "%c" && CI->getNumOperands() > 2 &&
1149 isa<IntegerType>(CI->getOperand(2)->getType())) {
1150 EmitPutChar(CI->getOperand(2), B);
1151 return CI->use_empty() ? (Value*)CI : ConstantInt::get(CI->getType(), 1);
1152 }
1153
1154 // printf("%s\n", str) --> puts(str)
1155 if (FormatStr == "%s\n" && CI->getNumOperands() > 2 &&
1156 isa<PointerType>(CI->getOperand(2)->getType()) &&
1157 CI->use_empty()) {
1158 EmitPutS(CI->getOperand(2), B);
1159 return CI;
1160 }
1161 return 0;
1162 }
1163};
1164
1165//===---------------------------------------===//
1166// 'sprintf' Optimizations
1167
1168struct VISIBILITY_HIDDEN SPrintFOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001169 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001170 // Require two fixed pointer arguments and an integer result.
1171 const FunctionType *FT = Callee->getFunctionType();
1172 if (FT->getNumParams() != 2 || !isa<PointerType>(FT->getParamType(0)) ||
1173 !isa<PointerType>(FT->getParamType(1)) ||
1174 !isa<IntegerType>(FT->getReturnType()))
1175 return 0;
1176
1177 // Check for a fixed format string.
1178 std::string FormatStr;
1179 if (!GetConstantStringInfo(CI->getOperand(2), FormatStr))
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001180 return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001181
1182 // If we just have a format string (nothing else crazy) transform it.
1183 if (CI->getNumOperands() == 3) {
1184 // Make sure there's no % in the constant array. We could try to handle
1185 // %% -> % in the future if we cared.
1186 for (unsigned i = 0, e = FormatStr.size(); i != e; ++i)
1187 if (FormatStr[i] == '%')
1188 return 0; // we found a format specifier, bail out.
1189
1190 // sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1)
1191 EmitMemCpy(CI->getOperand(1), CI->getOperand(2), // Copy the nul byte.
1192 ConstantInt::get(TD->getIntPtrType(), FormatStr.size()+1),1,B);
1193 return ConstantInt::get(CI->getType(), FormatStr.size());
1194 }
1195
1196 // The remaining optimizations require the format string to be "%s" or "%c"
1197 // and have an extra operand.
1198 if (FormatStr.size() != 2 || FormatStr[0] != '%' || CI->getNumOperands() <4)
1199 return 0;
1200
1201 // Decode the second character of the format string.
1202 if (FormatStr[1] == 'c') {
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001203 // sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001204 if (!isa<IntegerType>(CI->getOperand(3)->getType())) return 0;
1205 Value *V = B.CreateTrunc(CI->getOperand(3), Type::Int8Ty, "char");
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001206 Value *Ptr = CastToCStr(CI->getOperand(1), B);
1207 B.CreateStore(V, Ptr);
1208 Ptr = B.CreateGEP(Ptr, ConstantInt::get(Type::Int32Ty, 1), "nul");
1209 B.CreateStore(Constant::getNullValue(Type::Int8Ty), Ptr);
1210
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001211 return ConstantInt::get(CI->getType(), 1);
1212 }
1213
1214 if (FormatStr[1] == 's') {
1215 // sprintf(dest, "%s", str) -> llvm.memcpy(dest, str, strlen(str)+1, 1)
1216 if (!isa<PointerType>(CI->getOperand(3)->getType())) return 0;
1217
1218 Value *Len = EmitStrLen(CI->getOperand(3), B);
1219 Value *IncLen = B.CreateAdd(Len, ConstantInt::get(Len->getType(), 1),
1220 "leninc");
1221 EmitMemCpy(CI->getOperand(1), CI->getOperand(3), IncLen, 1, B);
1222
1223 // The sprintf result is the unincremented number of bytes in the string.
1224 return B.CreateIntCast(Len, CI->getType(), false);
1225 }
1226 return 0;
1227 }
1228};
1229
1230//===---------------------------------------===//
1231// 'fwrite' Optimizations
1232
1233struct VISIBILITY_HIDDEN FWriteOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001234 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001235 // Require a pointer, an integer, an integer, a pointer, returning integer.
1236 const FunctionType *FT = Callee->getFunctionType();
1237 if (FT->getNumParams() != 4 || !isa<PointerType>(FT->getParamType(0)) ||
1238 !isa<IntegerType>(FT->getParamType(1)) ||
1239 !isa<IntegerType>(FT->getParamType(2)) ||
1240 !isa<PointerType>(FT->getParamType(3)) ||
1241 !isa<IntegerType>(FT->getReturnType()))
1242 return 0;
1243
1244 // Get the element size and count.
1245 ConstantInt *SizeC = dyn_cast<ConstantInt>(CI->getOperand(2));
1246 ConstantInt *CountC = dyn_cast<ConstantInt>(CI->getOperand(3));
1247 if (!SizeC || !CountC) return 0;
1248 uint64_t Bytes = SizeC->getZExtValue()*CountC->getZExtValue();
1249
1250 // If this is writing zero records, remove the call (it's a noop).
1251 if (Bytes == 0)
1252 return ConstantInt::get(CI->getType(), 0);
1253
1254 // If this is writing one byte, turn it into fputc.
1255 if (Bytes == 1) { // fwrite(S,1,1,F) -> fputc(S[0],F)
1256 Value *Char = B.CreateLoad(CastToCStr(CI->getOperand(1), B), "char");
1257 EmitFPutC(Char, CI->getOperand(4), B);
1258 return ConstantInt::get(CI->getType(), 1);
1259 }
1260
1261 return 0;
1262 }
1263};
1264
1265//===---------------------------------------===//
1266// 'fputs' Optimizations
1267
1268struct VISIBILITY_HIDDEN FPutsOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001269 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001270 // Require two pointers. Also, we can't optimize if return value is used.
1271 const FunctionType *FT = Callee->getFunctionType();
1272 if (FT->getNumParams() != 2 || !isa<PointerType>(FT->getParamType(0)) ||
1273 !isa<PointerType>(FT->getParamType(1)) ||
1274 !CI->use_empty())
1275 return 0;
1276
1277 // fputs(s,F) --> fwrite(s,1,strlen(s),F)
1278 uint64_t Len = GetStringLength(CI->getOperand(1));
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001279 if (!Len) return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001280 EmitFWrite(CI->getOperand(1), ConstantInt::get(TD->getIntPtrType(), Len-1),
1281 CI->getOperand(2), B);
1282 return CI; // Known to have no uses (see above).
1283 }
1284};
1285
1286//===---------------------------------------===//
1287// 'fprintf' Optimizations
1288
1289struct VISIBILITY_HIDDEN FPrintFOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001290 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001291 // Require two fixed paramters as pointers and integer result.
1292 const FunctionType *FT = Callee->getFunctionType();
1293 if (FT->getNumParams() != 2 || !isa<PointerType>(FT->getParamType(0)) ||
1294 !isa<PointerType>(FT->getParamType(1)) ||
1295 !isa<IntegerType>(FT->getReturnType()))
1296 return 0;
1297
1298 // All the optimizations depend on the format string.
1299 std::string FormatStr;
1300 if (!GetConstantStringInfo(CI->getOperand(2), FormatStr))
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001301 return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001302
1303 // fprintf(F, "foo") --> fwrite("foo", 3, 1, F)
1304 if (CI->getNumOperands() == 3) {
1305 for (unsigned i = 0, e = FormatStr.size(); i != e; ++i)
1306 if (FormatStr[i] == '%') // Could handle %% -> % if we cared.
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001307 return 0; // We found a format specifier.
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001308
1309 EmitFWrite(CI->getOperand(2), ConstantInt::get(TD->getIntPtrType(),
1310 FormatStr.size()),
1311 CI->getOperand(1), B);
1312 return ConstantInt::get(CI->getType(), FormatStr.size());
1313 }
1314
1315 // The remaining optimizations require the format string to be "%s" or "%c"
1316 // and have an extra operand.
1317 if (FormatStr.size() != 2 || FormatStr[0] != '%' || CI->getNumOperands() <4)
1318 return 0;
1319
1320 // Decode the second character of the format string.
1321 if (FormatStr[1] == 'c') {
1322 // fprintf(F, "%c", chr) --> *(i8*)dst = chr
1323 if (!isa<IntegerType>(CI->getOperand(3)->getType())) return 0;
1324 EmitFPutC(CI->getOperand(3), CI->getOperand(1), B);
1325 return ConstantInt::get(CI->getType(), 1);
1326 }
1327
1328 if (FormatStr[1] == 's') {
1329 // fprintf(F, "%s", str) -> fputs(str, F)
1330 if (!isa<PointerType>(CI->getOperand(3)->getType()) || !CI->use_empty())
1331 return 0;
1332 EmitFPutS(CI->getOperand(3), CI->getOperand(1), B);
1333 return CI;
1334 }
1335 return 0;
1336 }
1337};
1338
Bill Wendlingac178222008-05-05 21:37:59 +00001339} // end anonymous namespace.
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001340
1341//===----------------------------------------------------------------------===//
1342// SimplifyLibCalls Pass Implementation
1343//===----------------------------------------------------------------------===//
1344
1345namespace {
1346 /// This pass optimizes well known library functions from libc and libm.
1347 ///
1348 class VISIBILITY_HIDDEN SimplifyLibCalls : public FunctionPass {
1349 StringMap<LibCallOptimization*> Optimizations;
1350 // Miscellaneous LibCall Optimizations
1351 ExitOpt Exit;
1352 // String and Memory LibCall Optimizations
1353 StrCatOpt StrCat; StrChrOpt StrChr; StrCmpOpt StrCmp; StrNCmpOpt StrNCmp;
Nick Lewycky4c498412009-02-13 15:31:46 +00001354 StrCpyOpt StrCpy; StrLenOpt StrLen; StrToOpt StrTo; MemCmpOpt MemCmp;
1355 MemCpyOpt MemCpy; MemMoveOpt MemMove; MemSetOpt MemSet;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001356 // Math Library Optimizations
Chris Lattnere818f772008-05-02 18:43:35 +00001357 PowOpt Pow; Exp2Opt Exp2; UnaryDoubleFPOpt UnaryDoubleFP;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001358 // Integer Optimizations
Chris Lattner313f0e62008-06-09 08:26:51 +00001359 FFSOpt FFS; AbsOpt Abs; IsDigitOpt IsDigit; IsAsciiOpt IsAscii;
1360 ToAsciiOpt ToAscii;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001361 // Formatting and IO Optimizations
1362 SPrintFOpt SPrintF; PrintFOpt PrintF;
1363 FWriteOpt FWrite; FPutsOpt FPuts; FPrintFOpt FPrintF;
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001364
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001365 bool Modified; // This is only used by doInitialization.
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001366 public:
1367 static char ID; // Pass identification
Dan Gohmanae73dc12008-09-04 17:05:41 +00001368 SimplifyLibCalls() : FunctionPass(&ID) {}
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001369
1370 void InitOptimizations();
1371 bool runOnFunction(Function &F);
1372
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001373 void setDoesNotAccessMemory(Function &F);
1374 void setOnlyReadsMemory(Function &F);
1375 void setDoesNotThrow(Function &F);
1376 void setDoesNotCapture(Function &F, unsigned n);
1377 void setDoesNotAlias(Function &F, unsigned n);
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001378 bool doInitialization(Module &M);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001379
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001380 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1381 AU.addRequired<TargetData>();
1382 }
1383 };
1384 char SimplifyLibCalls::ID = 0;
1385} // end anonymous namespace.
1386
1387static RegisterPass<SimplifyLibCalls>
1388X("simplify-libcalls", "Simplify well-known library calls");
1389
1390// Public interface to the Simplify LibCalls pass.
1391FunctionPass *llvm::createSimplifyLibCallsPass() {
1392 return new SimplifyLibCalls();
1393}
1394
1395/// Optimizations - Populate the Optimizations map with all the optimizations
1396/// we know.
1397void SimplifyLibCalls::InitOptimizations() {
1398 // Miscellaneous LibCall Optimizations
1399 Optimizations["exit"] = &Exit;
1400
1401 // String and Memory LibCall Optimizations
1402 Optimizations["strcat"] = &StrCat;
1403 Optimizations["strchr"] = &StrChr;
1404 Optimizations["strcmp"] = &StrCmp;
1405 Optimizations["strncmp"] = &StrNCmp;
1406 Optimizations["strcpy"] = &StrCpy;
1407 Optimizations["strlen"] = &StrLen;
Nick Lewycky4c498412009-02-13 15:31:46 +00001408 Optimizations["strtol"] = &StrTo;
1409 Optimizations["strtod"] = &StrTo;
1410 Optimizations["strtof"] = &StrTo;
1411 Optimizations["strtoul"] = &StrTo;
1412 Optimizations["strtoll"] = &StrTo;
1413 Optimizations["strtold"] = &StrTo;
1414 Optimizations["strtoull"] = &StrTo;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001415 Optimizations["memcmp"] = &MemCmp;
1416 Optimizations["memcpy"] = &MemCpy;
Eli Friedmand83ae7d2008-11-30 08:32:11 +00001417 Optimizations["memmove"] = &MemMove;
1418 Optimizations["memset"] = &MemSet;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001419
1420 // Math Library Optimizations
1421 Optimizations["powf"] = &Pow;
1422 Optimizations["pow"] = &Pow;
1423 Optimizations["powl"] = &Pow;
Dale Johannesen53bfbbc2008-09-04 18:30:46 +00001424 Optimizations["llvm.pow.f32"] = &Pow;
1425 Optimizations["llvm.pow.f64"] = &Pow;
1426 Optimizations["llvm.pow.f80"] = &Pow;
1427 Optimizations["llvm.pow.f128"] = &Pow;
1428 Optimizations["llvm.pow.ppcf128"] = &Pow;
Chris Lattnere818f772008-05-02 18:43:35 +00001429 Optimizations["exp2l"] = &Exp2;
1430 Optimizations["exp2"] = &Exp2;
1431 Optimizations["exp2f"] = &Exp2;
Dale Johannesen53bfbbc2008-09-04 18:30:46 +00001432 Optimizations["llvm.exp2.ppcf128"] = &Exp2;
1433 Optimizations["llvm.exp2.f128"] = &Exp2;
1434 Optimizations["llvm.exp2.f80"] = &Exp2;
1435 Optimizations["llvm.exp2.f64"] = &Exp2;
1436 Optimizations["llvm.exp2.f32"] = &Exp2;
Chris Lattnere818f772008-05-02 18:43:35 +00001437
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001438#ifdef HAVE_FLOORF
1439 Optimizations["floor"] = &UnaryDoubleFP;
1440#endif
1441#ifdef HAVE_CEILF
1442 Optimizations["ceil"] = &UnaryDoubleFP;
1443#endif
1444#ifdef HAVE_ROUNDF
1445 Optimizations["round"] = &UnaryDoubleFP;
1446#endif
1447#ifdef HAVE_RINTF
1448 Optimizations["rint"] = &UnaryDoubleFP;
1449#endif
1450#ifdef HAVE_NEARBYINTF
1451 Optimizations["nearbyint"] = &UnaryDoubleFP;
1452#endif
1453
1454 // Integer Optimizations
1455 Optimizations["ffs"] = &FFS;
1456 Optimizations["ffsl"] = &FFS;
1457 Optimizations["ffsll"] = &FFS;
Chris Lattner313f0e62008-06-09 08:26:51 +00001458 Optimizations["abs"] = &Abs;
1459 Optimizations["labs"] = &Abs;
1460 Optimizations["llabs"] = &Abs;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001461 Optimizations["isdigit"] = &IsDigit;
1462 Optimizations["isascii"] = &IsAscii;
1463 Optimizations["toascii"] = &ToAscii;
1464
1465 // Formatting and IO Optimizations
1466 Optimizations["sprintf"] = &SPrintF;
1467 Optimizations["printf"] = &PrintF;
1468 Optimizations["fwrite"] = &FWrite;
1469 Optimizations["fputs"] = &FPuts;
1470 Optimizations["fprintf"] = &FPrintF;
1471}
1472
1473
1474/// runOnFunction - Top level algorithm.
1475///
1476bool SimplifyLibCalls::runOnFunction(Function &F) {
1477 if (Optimizations.empty())
1478 InitOptimizations();
1479
1480 const TargetData &TD = getAnalysis<TargetData>();
1481
Eric Christopher7a61d702008-08-08 19:39:37 +00001482 IRBuilder<> Builder;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001483
1484 bool Changed = false;
1485 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
1486 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
1487 // Ignore non-calls.
1488 CallInst *CI = dyn_cast<CallInst>(I++);
1489 if (!CI) continue;
1490
1491 // Ignore indirect calls and calls to non-external functions.
1492 Function *Callee = CI->getCalledFunction();
1493 if (Callee == 0 || !Callee->isDeclaration() ||
1494 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage()))
1495 continue;
1496
1497 // Ignore unknown calls.
1498 const char *CalleeName = Callee->getNameStart();
1499 StringMap<LibCallOptimization*>::iterator OMI =
1500 Optimizations.find(CalleeName, CalleeName+Callee->getNameLen());
1501 if (OMI == Optimizations.end()) continue;
1502
1503 // Set the builder to the instruction after the call.
1504 Builder.SetInsertPoint(BB, I);
1505
1506 // Try to optimize this call.
1507 Value *Result = OMI->second->OptimizeCall(CI, TD, Builder);
1508 if (Result == 0) continue;
1509
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001510 DEBUG(DOUT << "SimplifyLibCalls simplified: " << *CI;
1511 DOUT << " into: " << *Result << "\n");
1512
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001513 // Something changed!
1514 Changed = true;
1515 ++NumSimplified;
1516
1517 // Inspect the instruction after the call (which was potentially just
1518 // added) next.
1519 I = CI; ++I;
1520
1521 if (CI != Result && !CI->use_empty()) {
1522 CI->replaceAllUsesWith(Result);
1523 if (!Result->hasName())
1524 Result->takeName(CI);
1525 }
1526 CI->eraseFromParent();
1527 }
1528 }
1529 return Changed;
1530}
1531
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001532// Utility methods for doInitialization.
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001533
1534void SimplifyLibCalls::setDoesNotAccessMemory(Function &F) {
1535 if (!F.doesNotAccessMemory()) {
1536 F.setDoesNotAccessMemory();
1537 ++NumAnnotated;
1538 Modified = true;
1539 }
1540}
1541void SimplifyLibCalls::setOnlyReadsMemory(Function &F) {
1542 if (!F.onlyReadsMemory()) {
1543 F.setOnlyReadsMemory();
1544 ++NumAnnotated;
1545 Modified = true;
1546 }
1547}
1548void SimplifyLibCalls::setDoesNotThrow(Function &F) {
1549 if (!F.doesNotThrow()) {
1550 F.setDoesNotThrow();
1551 ++NumAnnotated;
1552 Modified = true;
1553 }
1554}
1555void SimplifyLibCalls::setDoesNotCapture(Function &F, unsigned n) {
1556 if (!F.doesNotCapture(n)) {
1557 F.setDoesNotCapture(n);
1558 ++NumAnnotated;
1559 Modified = true;
1560 }
1561}
1562void SimplifyLibCalls::setDoesNotAlias(Function &F, unsigned n) {
1563 if (!F.doesNotAlias(n)) {
1564 F.setDoesNotAlias(n);
1565 ++NumAnnotated;
1566 Modified = true;
1567 }
1568}
1569
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001570/// doInitialization - Add attributes to well-known functions.
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001571///
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001572bool SimplifyLibCalls::doInitialization(Module &M) {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001573 Modified = false;
1574 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
1575 Function &F = *I;
1576 if (!F.isDeclaration())
1577 continue;
1578
1579 unsigned NameLen = F.getNameLen();
1580 if (!NameLen)
1581 continue;
1582
1583 const FunctionType *FTy = F.getFunctionType();
1584
1585 const char *NameStr = F.getNameStart();
1586 switch (NameStr[0]) {
1587 case 's':
1588 if (NameLen == 6 && !strcmp(NameStr, "strlen")) {
1589 if (FTy->getNumParams() != 1 ||
1590 !isa<PointerType>(FTy->getParamType(0)))
1591 continue;
1592 setOnlyReadsMemory(F);
1593 setDoesNotThrow(F);
1594 setDoesNotCapture(F, 1);
1595 } else if ((NameLen == 6 && !strcmp(NameStr, "strcpy")) ||
1596 (NameLen == 6 && !strcmp(NameStr, "stpcpy")) ||
1597 (NameLen == 6 && !strcmp(NameStr, "strcat")) ||
Nick Lewycky4c498412009-02-13 15:31:46 +00001598 (NameLen == 6 && !strcmp(NameStr, "strtol")) ||
1599 (NameLen == 6 && !strcmp(NameStr, "strtod")) ||
1600 (NameLen == 6 && !strcmp(NameStr, "strtof")) ||
1601 (NameLen == 7 && !strcmp(NameStr, "strtoul")) ||
1602 (NameLen == 7 && !strcmp(NameStr, "strtoll")) ||
1603 (NameLen == 7 && !strcmp(NameStr, "strtold")) ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001604 (NameLen == 7 && !strcmp(NameStr, "strncat")) ||
Nick Lewycky4c498412009-02-13 15:31:46 +00001605 (NameLen == 7 && !strcmp(NameStr, "strncpy")) ||
1606 (NameLen == 8 && !strcmp(NameStr, "strtoull"))) {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001607 if (FTy->getNumParams() < 2 ||
1608 !isa<PointerType>(FTy->getParamType(1)))
1609 continue;
1610 setDoesNotThrow(F);
1611 setDoesNotCapture(F, 2);
1612 } else if (NameLen == 7 && !strcmp(NameStr, "strxfrm")) {
1613 if (FTy->getNumParams() != 3 ||
1614 !isa<PointerType>(FTy->getParamType(0)) ||
1615 !isa<PointerType>(FTy->getParamType(1)))
1616 continue;
1617 setDoesNotThrow(F);
1618 setDoesNotCapture(F, 1);
1619 setDoesNotCapture(F, 2);
1620 } else if ((NameLen == 6 && !strcmp(NameStr, "strcmp")) ||
1621 (NameLen == 6 && !strcmp(NameStr, "strspn")) ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001622 (NameLen == 7 && !strcmp(NameStr, "strncmp")) ||
1623 (NameLen == 7 && !strcmp(NameStr, "strcspn")) ||
1624 (NameLen == 7 && !strcmp(NameStr, "strcoll")) ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001625 (NameLen == 10 && !strcmp(NameStr, "strcasecmp")) ||
1626 (NameLen == 11 && !strcmp(NameStr, "strncasecmp"))) {
1627 if (FTy->getNumParams() < 2 ||
1628 !isa<PointerType>(FTy->getParamType(0)) ||
1629 !isa<PointerType>(FTy->getParamType(1)))
1630 continue;
1631 setOnlyReadsMemory(F);
1632 setDoesNotThrow(F);
1633 setDoesNotCapture(F, 1);
1634 setDoesNotCapture(F, 2);
1635 } else if ((NameLen == 6 && !strcmp(NameStr, "strstr")) ||
1636 (NameLen == 7 && !strcmp(NameStr, "strpbrk"))) {
1637 if (FTy->getNumParams() != 2 ||
1638 !isa<PointerType>(FTy->getParamType(1)))
1639 continue;
1640 setOnlyReadsMemory(F);
1641 setDoesNotThrow(F);
1642 setDoesNotCapture(F, 2);
1643 } else if ((NameLen == 6 && !strcmp(NameStr, "strtok")) ||
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001644 (NameLen == 8 && !strcmp(NameStr, "strtok_r"))) {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001645 if (FTy->getNumParams() < 2 ||
1646 !isa<PointerType>(FTy->getParamType(1)))
1647 continue;
1648 setDoesNotThrow(F);
1649 setDoesNotCapture(F, 2);
1650 } else if ((NameLen == 5 && !strcmp(NameStr, "scanf")) ||
1651 (NameLen == 6 && !strcmp(NameStr, "setbuf")) ||
1652 (NameLen == 7 && !strcmp(NameStr, "setvbuf"))) {
1653 if (FTy->getNumParams() < 1 ||
1654 !isa<PointerType>(FTy->getParamType(0)))
1655 continue;
1656 setDoesNotThrow(F);
1657 setDoesNotCapture(F, 1);
1658 } else if (NameLen == 6 && !strcmp(NameStr, "sscanf")) {
1659 if (FTy->getNumParams() < 2 ||
1660 !isa<PointerType>(FTy->getParamType(0)) ||
1661 !isa<PointerType>(FTy->getParamType(1)))
1662 continue;
1663 setDoesNotThrow(F);
1664 setDoesNotCapture(F, 1);
1665 setDoesNotCapture(F, 2);
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001666 } else if ((NameLen == 6 && !strcmp(NameStr, "strdup")) ||
1667 (NameLen == 7 && !strcmp(NameStr, "strndup"))) {
1668 if (FTy->getNumParams() < 1 ||
1669 !isa<PointerType>(FTy->getReturnType()) ||
1670 !isa<PointerType>(FTy->getParamType(0)))
1671 continue;
1672 setDoesNotThrow(F);
1673 setDoesNotAlias(F, 0);
1674 setDoesNotCapture(F, 1);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001675 } else if (NameLen == 7 && !strcmp(NameStr, "sprintf")) {
1676 if (FTy->getNumParams() != 2 ||
1677 !isa<PointerType>(FTy->getParamType(0)) ||
1678 !isa<PointerType>(FTy->getParamType(1)))
1679 continue;
1680 setDoesNotThrow(F);
1681 setDoesNotCapture(F, 1);
1682 setDoesNotCapture(F, 2);
1683 } else if (NameLen == 8 && !strcmp(NameStr, "snprintf")) {
1684 if (FTy->getNumParams() != 3 ||
1685 !isa<PointerType>(FTy->getParamType(0)) ||
1686 !isa<PointerType>(FTy->getParamType(2)))
1687 continue;
1688 setDoesNotThrow(F);
1689 setDoesNotCapture(F, 1);
1690 setDoesNotCapture(F, 3);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001691 }
1692 break;
1693 case 'm':
1694 if (NameLen == 6 && !strcmp(NameStr, "memcmp")) {
1695 if (FTy->getNumParams() != 3 ||
1696 !isa<PointerType>(FTy->getParamType(0)) ||
1697 !isa<PointerType>(FTy->getParamType(1)))
1698 continue;
1699 setOnlyReadsMemory(F);
1700 setDoesNotThrow(F);
1701 setDoesNotCapture(F, 1);
1702 setDoesNotCapture(F, 2);
1703 } else if ((NameLen == 6 && !strcmp(NameStr, "memchr")) ||
1704 (NameLen == 7 && !strcmp(NameStr, "memrchr"))) {
1705 if (FTy->getNumParams() != 3)
1706 continue;
1707 setOnlyReadsMemory(F);
1708 setDoesNotThrow(F);
1709 } else if ((NameLen == 6 && !strcmp(NameStr, "memcpy")) ||
1710 (NameLen == 7 && !strcmp(NameStr, "memccpy")) ||
1711 (NameLen == 7 && !strcmp(NameStr, "memmove"))) {
1712 if (FTy->getNumParams() < 3 ||
1713 !isa<PointerType>(FTy->getParamType(1)))
1714 continue;
1715 setDoesNotThrow(F);
1716 setDoesNotCapture(F, 2);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001717 } else if (NameLen == 8 && !strcmp(NameStr, "memalign")) {
1718 if (!isa<PointerType>(FTy->getReturnType()))
1719 continue;
1720 setDoesNotAlias(F, 0);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001721 }
1722 break;
1723 case 'r':
1724 if (NameLen == 7 && !strcmp(NameStr, "realloc")) {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001725 if (FTy->getNumParams() != 2 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001726 !isa<PointerType>(FTy->getParamType(0)) ||
1727 !isa<PointerType>(FTy->getReturnType()))
1728 continue;
1729 setDoesNotThrow(F);
1730 setDoesNotAlias(F, 0);
1731 setDoesNotCapture(F, 1);
1732 } else if (NameLen == 4 && !strcmp(NameStr, "read")) {
1733 if (FTy->getNumParams() != 3 ||
1734 !isa<PointerType>(FTy->getParamType(1)))
1735 continue;
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001736 // May throw; "read" is a valid pthread cancellation point.
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001737 setDoesNotCapture(F, 2);
1738 } else if ((NameLen == 5 && !strcmp(NameStr, "rmdir")) ||
1739 (NameLen == 6 && !strcmp(NameStr, "rewind")) ||
1740 (NameLen == 6 && !strcmp(NameStr, "remove"))) {
1741 if (FTy->getNumParams() != 1 ||
1742 !isa<PointerType>(FTy->getParamType(0)))
1743 continue;
1744 setDoesNotThrow(F);
1745 setDoesNotCapture(F, 1);
1746 } else if (NameLen == 6 && !strcmp(NameStr, "rename")) {
1747 if (FTy->getNumParams() != 2 ||
1748 !isa<PointerType>(FTy->getParamType(0)) ||
1749 !isa<PointerType>(FTy->getParamType(1)))
1750 continue;
1751 setDoesNotThrow(F);
1752 setDoesNotCapture(F, 1);
1753 setDoesNotCapture(F, 2);
1754 }
1755 break;
1756 case 'w':
1757 if (NameLen == 5 && !strcmp(NameStr, "write")) {
1758 if (FTy->getNumParams() != 3 ||
1759 !isa<PointerType>(FTy->getParamType(1)))
1760 continue;
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001761 // May throw; "write" is a valid pthread cancellation point.
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001762 setDoesNotCapture(F, 2);
1763 }
1764 break;
1765 case 'b':
1766 if (NameLen == 5 && !strcmp(NameStr, "bcopy")) {
1767 if (FTy->getNumParams() != 3 ||
1768 !isa<PointerType>(FTy->getParamType(0)) ||
1769 !isa<PointerType>(FTy->getParamType(1)))
1770 continue;
1771 setDoesNotThrow(F);
1772 setDoesNotCapture(F, 1);
1773 setDoesNotCapture(F, 2);
1774 } else if (NameLen == 4 && !strcmp(NameStr, "bcmp")) {
1775 if (FTy->getNumParams() != 3 ||
1776 !isa<PointerType>(FTy->getParamType(0)) ||
1777 !isa<PointerType>(FTy->getParamType(1)))
1778 continue;
1779 setDoesNotThrow(F);
1780 setOnlyReadsMemory(F);
1781 setDoesNotCapture(F, 1);
1782 setDoesNotCapture(F, 2);
1783 } else if (NameLen == 5 && !strcmp(NameStr, "bzero")) {
1784 if (FTy->getNumParams() != 2 ||
1785 !isa<PointerType>(FTy->getParamType(0)))
1786 continue;
1787 setDoesNotThrow(F);
1788 setDoesNotCapture(F, 1);
1789 }
1790 break;
1791 case 'c':
1792 if (NameLen == 6 && !strcmp(NameStr, "calloc")) {
1793 if (FTy->getNumParams() != 2 ||
1794 !isa<PointerType>(FTy->getReturnType()))
1795 continue;
1796 setDoesNotThrow(F);
1797 setDoesNotAlias(F, 0);
1798 } else if ((NameLen == 5 && !strcmp(NameStr, "chown")) ||
1799 (NameLen == 8 && !strcmp(NameStr, "clearerr")) ||
1800 (NameLen == 8 && !strcmp(NameStr, "closedir"))) {
1801 if (FTy->getNumParams() == 0 ||
1802 !isa<PointerType>(FTy->getParamType(0)))
1803 continue;
1804 setDoesNotThrow(F);
1805 setDoesNotCapture(F, 1);
1806 }
1807 break;
1808 case 'a':
1809 if ((NameLen == 4 && !strcmp(NameStr, "atoi")) ||
1810 (NameLen == 4 && !strcmp(NameStr, "atol")) ||
1811 (NameLen == 4 && !strcmp(NameStr, "atof")) ||
1812 (NameLen == 5 && !strcmp(NameStr, "atoll"))) {
1813 if (FTy->getNumParams() != 1 ||
1814 !isa<PointerType>(FTy->getParamType(0)))
1815 continue;
1816 setDoesNotThrow(F);
1817 setOnlyReadsMemory(F);
1818 setDoesNotCapture(F, 1);
1819 } else if (NameLen == 6 && !strcmp(NameStr, "access")) {
1820 if (FTy->getNumParams() != 2 ||
1821 !isa<PointerType>(FTy->getParamType(0)))
1822 continue;
1823 setDoesNotThrow(F);
1824 setDoesNotCapture(F, 1);
1825 }
1826 break;
1827 case 'f':
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001828 if (NameLen == 5 && !strcmp(NameStr, "fopen")) {
1829 if (FTy->getNumParams() != 2 ||
1830 !isa<PointerType>(FTy->getReturnType()) ||
1831 !isa<PointerType>(FTy->getParamType(0)) ||
1832 !isa<PointerType>(FTy->getParamType(1)))
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001833 continue;
1834 setDoesNotThrow(F);
1835 setDoesNotAlias(F, 0);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001836 setDoesNotCapture(F, 1);
1837 setDoesNotCapture(F, 2);
1838 } else if (NameLen == 6 && !strcmp(NameStr, "fdopen")) {
1839 if (FTy->getNumParams() != 2 ||
1840 !isa<PointerType>(FTy->getReturnType()) ||
1841 !isa<PointerType>(FTy->getParamType(1)))
1842 continue;
1843 setDoesNotThrow(F);
1844 setDoesNotAlias(F, 0);
1845 setDoesNotCapture(F, 2);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001846 } else if ((NameLen == 4 && !strcmp(NameStr, "feof")) ||
1847 (NameLen == 4 && !strcmp(NameStr, "free")) ||
1848 (NameLen == 5 && !strcmp(NameStr, "fseek")) ||
1849 (NameLen == 5 && !strcmp(NameStr, "ftell")) ||
1850 (NameLen == 5 && !strcmp(NameStr, "fgetc")) ||
1851 (NameLen == 6 && !strcmp(NameStr, "fseeko")) ||
1852 (NameLen == 6 && !strcmp(NameStr, "ftello")) ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001853 (NameLen == 6 && !strcmp(NameStr, "fileno")) ||
1854 (NameLen == 6 && !strcmp(NameStr, "fflush")) ||
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001855 (NameLen == 6 && !strcmp(NameStr, "fclose")) ||
1856 (NameLen == 7 && !strcmp(NameStr, "fsetpos"))) {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001857 if (FTy->getNumParams() == 0 ||
1858 !isa<PointerType>(FTy->getParamType(0)))
1859 continue;
1860 setDoesNotThrow(F);
1861 setDoesNotCapture(F, 1);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001862 } else if (NameLen == 6 && !strcmp(NameStr, "ferror")) {
1863 if (FTy->getNumParams() != 1 ||
1864 !isa<PointerType>(FTy->getParamType(0)))
1865 continue;
1866 setDoesNotThrow(F);
1867 setDoesNotCapture(F, 1);
1868 setOnlyReadsMemory(F);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001869 } else if ((NameLen == 5 && !strcmp(NameStr, "fputc")) ||
1870 (NameLen == 5 && !strcmp(NameStr, "fputs"))) {
1871 if (FTy->getNumParams() != 2 ||
1872 !isa<PointerType>(FTy->getParamType(1)))
1873 continue;
1874 setDoesNotThrow(F);
1875 setDoesNotCapture(F, 2);
1876 } else if (NameLen == 5 && !strcmp(NameStr, "fgets")) {
1877 if (FTy->getNumParams() != 3 ||
1878 !isa<PointerType>(FTy->getParamType(0)) ||
1879 !isa<PointerType>(FTy->getParamType(2)))
1880 continue;
1881 setDoesNotThrow(F);
1882 setDoesNotCapture(F, 3);
1883 } else if ((NameLen == 5 && !strcmp(NameStr, "fread")) ||
1884 (NameLen == 6 && !strcmp(NameStr, "fwrite"))) {
1885 if (FTy->getNumParams() != 4 ||
1886 !isa<PointerType>(FTy->getParamType(0)) ||
1887 !isa<PointerType>(FTy->getParamType(3)))
1888 continue;
1889 setDoesNotThrow(F);
1890 setDoesNotCapture(F, 1);
1891 setDoesNotCapture(F, 4);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001892 } else if (NameLen == 7 && !strcmp(NameStr, "fgetpos")) {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001893 if (FTy->getNumParams() != 2 ||
1894 !isa<PointerType>(FTy->getParamType(0)) ||
1895 !isa<PointerType>(FTy->getParamType(1)))
1896 continue;
1897 setDoesNotThrow(F);
1898 setDoesNotCapture(F, 1);
1899 setDoesNotCapture(F, 2);
1900 } else if (NameLen == 6 && !strcmp(NameStr, "fscanf")) {
1901 if (FTy->getNumParams() < 2 ||
1902 !isa<PointerType>(FTy->getParamType(0)) ||
1903 !isa<PointerType>(FTy->getParamType(1)))
1904 continue;
1905 setDoesNotThrow(F);
1906 setDoesNotCapture(F, 1);
1907 setDoesNotCapture(F, 2);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001908 } else if (NameLen == 7 && !strcmp(NameStr, "fprintf")) {
1909 if (FTy->getNumParams() != 2 ||
1910 !isa<PointerType>(FTy->getParamType(0)) ||
1911 !isa<PointerType>(FTy->getParamType(1)))
1912 continue;
1913 setDoesNotThrow(F);
1914 setDoesNotCapture(F, 1);
1915 setDoesNotCapture(F, 2);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001916 }
1917 break;
1918 case 'g':
1919 if ((NameLen == 4 && !strcmp(NameStr, "getc")) ||
1920 (NameLen == 10 && !strcmp(NameStr, "getlogin_r"))) {
1921 if (FTy->getNumParams() == 0 ||
1922 !isa<PointerType>(FTy->getParamType(0)))
1923 continue;
1924 setDoesNotThrow(F);
1925 setDoesNotCapture(F, 1);
1926 } else if (NameLen == 6 && !strcmp(NameStr, "getenv")) {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001927 if (FTy->getNumParams() != 1 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001928 !isa<PointerType>(FTy->getParamType(0)))
1929 continue;
1930 setDoesNotThrow(F);
1931 setOnlyReadsMemory(F);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001932 setDoesNotCapture(F, 1);
1933 } else if ((NameLen == 4 && !strcmp(NameStr, "gets")) ||
1934 (NameLen == 7 && !strcmp(NameStr, "getchar"))) {
1935 setDoesNotThrow(F);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001936 }
1937 break;
1938 case 'u':
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001939 if (NameLen == 6 && !strcmp(NameStr, "ungetc")) {
1940 if (FTy->getNumParams() != 2 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001941 !isa<PointerType>(FTy->getParamType(1)))
1942 continue;
1943 setDoesNotThrow(F);
1944 setDoesNotCapture(F, 2);
1945 } else if (NameLen == 6 && !strcmp(NameStr, "unlink")) {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001946 if (FTy->getNumParams() != 1 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001947 !isa<PointerType>(FTy->getParamType(0)))
1948 continue;
1949 setDoesNotThrow(F);
1950 setDoesNotCapture(F, 1);
1951 }
1952 break;
1953 case 'p':
1954 if (NameLen == 4 && !strcmp(NameStr, "putc")) {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001955 if (FTy->getNumParams() != 2 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001956 !isa<PointerType>(FTy->getParamType(1)))
1957 continue;
1958 setDoesNotThrow(F);
1959 setDoesNotCapture(F, 2);
1960 } else if ((NameLen == 4 && !strcmp(NameStr, "puts")) ||
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001961 (NameLen == 6 && !strcmp(NameStr, "printf")) ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001962 (NameLen == 6 && !strcmp(NameStr, "perror"))) {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001963 if (FTy->getNumParams() != 1 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001964 !isa<PointerType>(FTy->getParamType(0)))
1965 continue;
1966 setDoesNotThrow(F);
1967 setDoesNotCapture(F, 1);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001968 } else if ((NameLen == 5 && !strcmp(NameStr, "pread")) ||
1969 (NameLen == 6 && !strcmp(NameStr, "pwrite"))) {
1970 if (FTy->getNumParams() != 4 ||
1971 !isa<PointerType>(FTy->getParamType(1)))
1972 continue;
1973 // May throw; these are valid pthread cancellation points.
1974 setDoesNotCapture(F, 2);
1975 } else if (NameLen == 7 && !strcmp(NameStr, "putchar")) {
1976 setDoesNotThrow(F);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001977 }
1978 break;
1979 case 'v':
1980 if (NameLen == 6 && !strcmp(NameStr, "vscanf")) {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001981 if (FTy->getNumParams() != 2 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001982 !isa<PointerType>(FTy->getParamType(1)))
1983 continue;
1984 setDoesNotThrow(F);
1985 setDoesNotCapture(F, 1);
1986 } else if ((NameLen == 7 && !strcmp(NameStr, "vsscanf")) ||
1987 (NameLen == 7 && !strcmp(NameStr, "vfscanf"))) {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001988 if (FTy->getNumParams() != 3 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001989 !isa<PointerType>(FTy->getParamType(1)) ||
1990 !isa<PointerType>(FTy->getParamType(2)))
1991 continue;
1992 setDoesNotThrow(F);
1993 setDoesNotCapture(F, 1);
1994 setDoesNotCapture(F, 2);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001995 } else if (NameLen == 6 && !strcmp(NameStr, "valloc")) {
1996 if (!isa<PointerType>(FTy->getReturnType()))
1997 continue;
1998 setDoesNotThrow(F);
1999 setDoesNotAlias(F, 0);
2000 } else if (NameLen == 7 && !strcmp(NameStr, "vprintf")) {
2001 if (FTy->getNumParams() != 2 ||
2002 !isa<PointerType>(FTy->getParamType(0)))
2003 continue;
2004 setDoesNotThrow(F);
2005 setDoesNotCapture(F, 1);
2006 } else if ((NameLen == 8 && !strcmp(NameStr, "vfprintf")) ||
2007 (NameLen == 8 && !strcmp(NameStr, "vsprintf"))) {
2008 if (FTy->getNumParams() != 3 ||
2009 !isa<PointerType>(FTy->getParamType(0)) ||
2010 !isa<PointerType>(FTy->getParamType(1)))
2011 continue;
2012 setDoesNotThrow(F);
2013 setDoesNotCapture(F, 1);
2014 setDoesNotCapture(F, 2);
2015 } else if (NameLen == 9 && !strcmp(NameStr, "vsnprintf")) {
2016 if (FTy->getNumParams() != 4 ||
2017 !isa<PointerType>(FTy->getParamType(0)) ||
2018 !isa<PointerType>(FTy->getParamType(2)))
2019 continue;
2020 setDoesNotThrow(F);
2021 setDoesNotCapture(F, 1);
2022 setDoesNotCapture(F, 3);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002023 }
2024 break;
2025 case 'o':
2026 if (NameLen == 7 && !strcmp(NameStr, "opendir")) {
2027 // The description of fdopendir sounds like opening the same fd
2028 // twice might result in the same DIR* !
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002029 if (!isa<PointerType>(FTy->getReturnType()))
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002030 continue;
2031 setDoesNotThrow(F);
2032 setDoesNotAlias(F, 0);
2033 }
2034 break;
2035 case 't':
2036 if (NameLen == 7 && !strcmp(NameStr, "tmpfile")) {
2037 if (!isa<PointerType>(FTy->getReturnType()))
2038 continue;
2039 setDoesNotThrow(F);
2040 setDoesNotAlias(F, 0);
2041 }
2042 case 'h':
2043 if ((NameLen == 5 && !strcmp(NameStr, "htonl")) ||
2044 (NameLen == 5 && !strcmp(NameStr, "htons"))) {
2045 setDoesNotThrow(F);
2046 setDoesNotAccessMemory(F);
2047 }
2048 break;
2049 case 'n':
2050 if ((NameLen == 5 && !strcmp(NameStr, "ntohl")) ||
2051 (NameLen == 5 && !strcmp(NameStr, "ntohs"))) {
2052 setDoesNotThrow(F);
2053 setDoesNotAccessMemory(F);
2054 }
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002055 case '_':
2056 if ((NameLen == 8 && !strcmp(NameStr, "__strdup")) ||
2057 (NameLen == 9 && !strcmp(NameStr, "__strndup"))) {
2058 if (FTy->getNumParams() < 1 ||
2059 !isa<PointerType>(FTy->getReturnType()) ||
2060 !isa<PointerType>(FTy->getParamType(0)))
2061 continue;
2062 setDoesNotThrow(F);
2063 setDoesNotAlias(F, 0);
2064 setDoesNotCapture(F, 1);
2065 } else if (NameLen == 10 && !strcmp(NameStr, "__strtok_r")) {
2066 if (FTy->getNumParams() != 3 ||
2067 !isa<PointerType>(FTy->getParamType(1)))
2068 continue;
2069 setDoesNotThrow(F);
2070 setDoesNotCapture(F, 2);
2071 } else if (NameLen == 8 && !strcmp(NameStr, "_IO_getc")) {
2072 if (FTy->getNumParams() != 1 ||
2073 !isa<PointerType>(FTy->getParamType(0)))
2074 continue;
2075 setDoesNotThrow(F);
2076 setDoesNotCapture(F, 1);
2077 } else if (NameLen == 8 && !strcmp(NameStr, "_IO_putc")) {
2078 if (FTy->getNumParams() != 2 ||
2079 !isa<PointerType>(FTy->getParamType(1)))
2080 continue;
2081 setDoesNotThrow(F);
2082 setDoesNotCapture(F, 2);
2083 }
2084 case 1:
2085 if (NameLen == 15 && !strcmp(NameStr, "\1__isoc99_scanf")) {
2086 if (FTy->getNumParams() < 1 ||
2087 !isa<PointerType>(FTy->getParamType(0)))
2088 continue;
2089 setDoesNotThrow(F);
2090 setDoesNotCapture(F, 1);
2091 } else if (NameLen == 16 && !strcmp(NameStr, "\1__isoc99_sscanf")) {
2092 if (FTy->getNumParams() < 1 ||
2093 !isa<PointerType>(FTy->getParamType(0)))
2094 continue;
2095 setDoesNotThrow(F);
2096 setDoesNotCapture(F, 1);
2097 setDoesNotCapture(F, 2);
2098 }
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002099 break;
2100 }
2101 }
2102 return Modified;
2103}
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00002104
2105// TODO:
2106// Additional cases that we need to add to this file:
2107//
2108// cbrt:
2109// * cbrt(expN(X)) -> expN(x/3)
2110// * cbrt(sqrt(x)) -> pow(x,1/6)
2111// * cbrt(sqrt(x)) -> pow(x,1/9)
2112//
2113// cos, cosf, cosl:
2114// * cos(-x) -> cos(x)
2115//
2116// exp, expf, expl:
2117// * exp(log(x)) -> x
2118//
2119// log, logf, logl:
2120// * log(exp(x)) -> x
2121// * log(x**y) -> y*log(x)
2122// * log(exp(y)) -> y*log(e)
2123// * log(exp2(y)) -> y*log(2)
2124// * log(exp10(y)) -> y*log(10)
2125// * log(sqrt(x)) -> 0.5*log(x)
2126// * log(pow(x,y)) -> y*log(x)
2127//
2128// lround, lroundf, lroundl:
2129// * lround(cnst) -> cnst'
2130//
2131// memcmp:
2132// * memcmp(x,y,l) -> cnst
2133// (if all arguments are constant and strlen(x) <= l and strlen(y) <= l)
2134//
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00002135// pow, powf, powl:
2136// * pow(exp(x),y) -> exp(x*y)
2137// * pow(sqrt(x),y) -> pow(x,y*0.5)
2138// * pow(pow(x,y),z)-> pow(x,y*z)
2139//
2140// puts:
2141// * puts("") -> putchar("\n")
2142//
2143// round, roundf, roundl:
2144// * round(cnst) -> cnst'
2145//
2146// signbit:
2147// * signbit(cnst) -> cnst'
2148// * signbit(nncst) -> 0 (if pstv is a non-negative constant)
2149//
2150// sqrt, sqrtf, sqrtl:
2151// * sqrt(expN(x)) -> expN(x*0.5)
2152// * sqrt(Nroot(x)) -> pow(x,1/(2*N))
2153// * sqrt(pow(x,y)) -> pow(|x|,y*0.5)
2154//
2155// stpcpy:
2156// * stpcpy(str, "literal") ->
2157// llvm.memcpy(str,"literal",strlen("literal")+1,1)
2158// strrchr:
2159// * strrchr(s,c) -> reverse_offset_of_in(c,s)
2160// (if c is a constant integer and s is a constant string)
2161// * strrchr(s1,0) -> strchr(s1,0)
2162//
2163// strncat:
2164// * strncat(x,y,0) -> x
2165// * strncat(x,y,0) -> x (if strlen(y) = 0)
2166// * strncat(x,y,l) -> strcat(x,y) (if y and l are constants an l > strlen(y))
2167//
2168// strncpy:
2169// * strncpy(d,s,0) -> d
2170// * strncpy(d,s,l) -> memcpy(d,s,l,1)
2171// (if s and l are constants)
2172//
2173// strpbrk:
2174// * strpbrk(s,a) -> offset_in_for(s,a)
2175// (if s and a are both constant strings)
2176// * strpbrk(s,"") -> 0
2177// * strpbrk(s,a) -> strchr(s,a[0]) (if a is constant string of length 1)
2178//
2179// strspn, strcspn:
2180// * strspn(s,a) -> const_int (if both args are constant)
2181// * strspn("",a) -> 0
2182// * strspn(s,"") -> 0
2183// * strcspn(s,a) -> const_int (if both args are constant)
2184// * strcspn("",a) -> 0
2185// * strcspn(s,"") -> strlen(a)
2186//
2187// strstr:
2188// * strstr(x,x) -> x
2189// * strstr(s1,s2) -> offset_of_s2_in(s1)
2190// (if s1 and s2 are constant strings)
2191//
2192// tan, tanf, tanl:
2193// * tan(atan(x)) -> x
2194//
2195// trunc, truncf, truncl:
2196// * trunc(cnst) -> cnst'
2197//
2198//