blob: fed239eae3690a53490ee45fdcc85296ff2a56e9 [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);
736 if (isa<ConstantPointerNull>(EndPtr))
737 CI->addAttribute(1, Attribute::NoCapture);
738
739 return 0;
740 }
741};
742
743
744//===---------------------------------------===//
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000745// 'memcmp' Optimizations
746
747struct VISIBILITY_HIDDEN MemCmpOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000748 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000749 const FunctionType *FT = Callee->getFunctionType();
750 if (FT->getNumParams() != 3 || !isa<PointerType>(FT->getParamType(0)) ||
751 !isa<PointerType>(FT->getParamType(1)) ||
752 FT->getReturnType() != Type::Int32Ty)
753 return 0;
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000754
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000755 Value *LHS = CI->getOperand(1), *RHS = CI->getOperand(2);
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000756
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000757 if (LHS == RHS) // memcmp(s,s,x) -> 0
758 return Constant::getNullValue(CI->getType());
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000759
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000760 // Make sure we have a constant length.
761 ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getOperand(3));
Chris Lattner56b4f2b2008-05-01 06:39:12 +0000762 if (!LenC) return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000763 uint64_t Len = LenC->getZExtValue();
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000764
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000765 if (Len == 0) // memcmp(s1,s2,0) -> 0
766 return Constant::getNullValue(CI->getType());
767
768 if (Len == 1) { // memcmp(S1,S2,1) -> *LHS - *RHS
769 Value *LHSV = B.CreateLoad(CastToCStr(LHS, B), "lhsv");
770 Value *RHSV = B.CreateLoad(CastToCStr(RHS, B), "rhsv");
771 return B.CreateZExt(B.CreateSub(LHSV, RHSV, "chardiff"), CI->getType());
772 }
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000773
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000774 // memcmp(S1,S2,2) != 0 -> (*(short*)LHS ^ *(short*)RHS) != 0
775 // memcmp(S1,S2,4) != 0 -> (*(int*)LHS ^ *(int*)RHS) != 0
776 if ((Len == 2 || Len == 4) && IsOnlyUsedInZeroEqualityComparison(CI)) {
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000777 const Type *PTy = PointerType::getUnqual(Len == 2 ?
778 Type::Int16Ty : Type::Int32Ty);
779 LHS = B.CreateBitCast(LHS, PTy, "tmp");
780 RHS = B.CreateBitCast(RHS, PTy, "tmp");
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000781 LoadInst *LHSV = B.CreateLoad(LHS, "lhsv");
782 LoadInst *RHSV = B.CreateLoad(RHS, "rhsv");
783 LHSV->setAlignment(1); RHSV->setAlignment(1); // Unaligned loads.
784 return B.CreateZExt(B.CreateXor(LHSV, RHSV, "shortdiff"), CI->getType());
785 }
Duncan Sandsec00fcb2008-05-19 09:27:24 +0000786
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000787 return 0;
788 }
789};
790
791//===---------------------------------------===//
792// 'memcpy' Optimizations
793
794struct VISIBILITY_HIDDEN MemCpyOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000795 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000796 const FunctionType *FT = Callee->getFunctionType();
797 if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
798 !isa<PointerType>(FT->getParamType(0)) ||
799 !isa<PointerType>(FT->getParamType(1)) ||
800 FT->getParamType(2) != TD->getIntPtrType())
801 return 0;
802
803 // memcpy(x, y, n) -> llvm.memcpy(x, y, n, 1)
804 EmitMemCpy(CI->getOperand(1), CI->getOperand(2), CI->getOperand(3), 1, B);
805 return CI->getOperand(1);
806 }
807};
808
Eli Friedmand83ae7d2008-11-30 08:32:11 +0000809//===---------------------------------------===//
810// 'memmove' Optimizations
811
812struct VISIBILITY_HIDDEN MemMoveOpt : public LibCallOptimization {
813 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
814 const FunctionType *FT = Callee->getFunctionType();
815 if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
816 !isa<PointerType>(FT->getParamType(0)) ||
817 !isa<PointerType>(FT->getParamType(1)) ||
818 FT->getParamType(2) != TD->getIntPtrType())
819 return 0;
820
821 // memmove(x, y, n) -> llvm.memmove(x, y, n, 1)
822 Module *M = Caller->getParent();
823 Intrinsic::ID IID = Intrinsic::memmove;
824 const Type *Tys[1];
825 Tys[0] = TD->getIntPtrType();
826 Value *MemMove = Intrinsic::getDeclaration(M, IID, Tys, 1);
827 Value *Dst = CastToCStr(CI->getOperand(1), B);
828 Value *Src = CastToCStr(CI->getOperand(2), B);
829 Value *Size = CI->getOperand(3);
830 Value *Align = ConstantInt::get(Type::Int32Ty, 1);
831 B.CreateCall4(MemMove, Dst, Src, Size, Align);
832 return CI->getOperand(1);
833 }
834};
835
836//===---------------------------------------===//
837// 'memset' Optimizations
838
839struct VISIBILITY_HIDDEN MemSetOpt : public LibCallOptimization {
840 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
841 const FunctionType *FT = Callee->getFunctionType();
842 if (FT->getNumParams() != 3 || FT->getReturnType() != FT->getParamType(0) ||
843 !isa<PointerType>(FT->getParamType(0)) ||
844 FT->getParamType(1) != TD->getIntPtrType() ||
845 FT->getParamType(2) != TD->getIntPtrType())
846 return 0;
847
848 // memset(p, v, n) -> llvm.memset(p, v, n, 1)
849 Module *M = Caller->getParent();
850 Intrinsic::ID IID = Intrinsic::memset;
851 const Type *Tys[1];
852 Tys[0] = TD->getIntPtrType();
853 Value *MemSet = Intrinsic::getDeclaration(M, IID, Tys, 1);
854 Value *Dst = CastToCStr(CI->getOperand(1), B);
855 Value *Val = B.CreateTrunc(CI->getOperand(2), Type::Int8Ty);
856 Value *Size = CI->getOperand(3);
857 Value *Align = ConstantInt::get(Type::Int32Ty, 1);
858 B.CreateCall4(MemSet, Dst, Val, Size, Align);
859 return CI->getOperand(1);
860 }
861};
862
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000863//===----------------------------------------------------------------------===//
864// Math Library Optimizations
865//===----------------------------------------------------------------------===//
866
867//===---------------------------------------===//
868// 'pow*' Optimizations
869
870struct VISIBILITY_HIDDEN PowOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000871 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000872 const FunctionType *FT = Callee->getFunctionType();
873 // Just make sure this has 2 arguments of the same FP type, which match the
874 // result type.
875 if (FT->getNumParams() != 2 || FT->getReturnType() != FT->getParamType(0) ||
876 FT->getParamType(0) != FT->getParamType(1) ||
877 !FT->getParamType(0)->isFloatingPoint())
878 return 0;
879
880 Value *Op1 = CI->getOperand(1), *Op2 = CI->getOperand(2);
881 if (ConstantFP *Op1C = dyn_cast<ConstantFP>(Op1)) {
882 if (Op1C->isExactlyValue(1.0)) // pow(1.0, x) -> 1.0
883 return Op1C;
884 if (Op1C->isExactlyValue(2.0)) // pow(2.0, x) -> exp2(x)
885 return EmitUnaryFloatFnCall(Op2, "exp2", B);
886 }
887
888 ConstantFP *Op2C = dyn_cast<ConstantFP>(Op2);
889 if (Op2C == 0) return 0;
890
891 if (Op2C->getValueAPF().isZero()) // pow(x, 0.0) -> 1.0
892 return ConstantFP::get(CI->getType(), 1.0);
893
894 if (Op2C->isExactlyValue(0.5)) {
895 // FIXME: This is not safe for -0.0 and -inf. This can only be done when
896 // 'unsafe' math optimizations are allowed.
897 // x pow(x, 0.5) sqrt(x)
898 // ---------------------------------------------
899 // -0.0 +0.0 -0.0
900 // -inf +inf NaN
901#if 0
902 // pow(x, 0.5) -> sqrt(x)
903 return B.CreateCall(get_sqrt(), Op1, "sqrt");
904#endif
905 }
906
907 if (Op2C->isExactlyValue(1.0)) // pow(x, 1.0) -> x
908 return Op1;
909 if (Op2C->isExactlyValue(2.0)) // pow(x, 2.0) -> x*x
910 return B.CreateMul(Op1, Op1, "pow2");
911 if (Op2C->isExactlyValue(-1.0)) // pow(x, -1.0) -> 1.0/x
912 return B.CreateFDiv(ConstantFP::get(CI->getType(), 1.0), Op1, "powrecip");
913 return 0;
914 }
915};
916
917//===---------------------------------------===//
Chris Lattnere818f772008-05-02 18:43:35 +0000918// 'exp2' Optimizations
919
920struct VISIBILITY_HIDDEN Exp2Opt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000921 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnere818f772008-05-02 18:43:35 +0000922 const FunctionType *FT = Callee->getFunctionType();
923 // Just make sure this has 1 argument of FP type, which matches the
924 // result type.
925 if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
926 !FT->getParamType(0)->isFloatingPoint())
927 return 0;
928
929 Value *Op = CI->getOperand(1);
930 // Turn exp2(sitofp(x)) -> ldexp(1.0, sext(x)) if sizeof(x) <= 32
931 // Turn exp2(uitofp(x)) -> ldexp(1.0, zext(x)) if sizeof(x) < 32
932 Value *LdExpArg = 0;
933 if (SIToFPInst *OpC = dyn_cast<SIToFPInst>(Op)) {
934 if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() <= 32)
935 LdExpArg = B.CreateSExt(OpC->getOperand(0), Type::Int32Ty, "tmp");
936 } else if (UIToFPInst *OpC = dyn_cast<UIToFPInst>(Op)) {
937 if (OpC->getOperand(0)->getType()->getPrimitiveSizeInBits() < 32)
938 LdExpArg = B.CreateZExt(OpC->getOperand(0), Type::Int32Ty, "tmp");
939 }
940
941 if (LdExpArg) {
942 const char *Name;
943 if (Op->getType() == Type::FloatTy)
944 Name = "ldexpf";
945 else if (Op->getType() == Type::DoubleTy)
946 Name = "ldexp";
947 else
948 Name = "ldexpl";
949
950 Constant *One = ConstantFP::get(APFloat(1.0f));
951 if (Op->getType() != Type::FloatTy)
952 One = ConstantExpr::getFPExtend(One, Op->getType());
953
954 Module *M = Caller->getParent();
955 Value *Callee = M->getOrInsertFunction(Name, Op->getType(),
956 Op->getType(), Type::Int32Ty,NULL);
957 return B.CreateCall2(Callee, One, LdExpArg);
958 }
959 return 0;
960 }
961};
962
963
964//===---------------------------------------===//
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000965// Double -> Float Shrinking Optimizations for Unary Functions like 'floor'
966
967struct VISIBILITY_HIDDEN UnaryDoubleFPOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000968 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000969 const FunctionType *FT = Callee->getFunctionType();
970 if (FT->getNumParams() != 1 || FT->getReturnType() != Type::DoubleTy ||
971 FT->getParamType(0) != Type::DoubleTy)
972 return 0;
973
974 // If this is something like 'floor((double)floatval)', convert to floorf.
975 FPExtInst *Cast = dyn_cast<FPExtInst>(CI->getOperand(1));
976 if (Cast == 0 || Cast->getOperand(0)->getType() != Type::FloatTy)
977 return 0;
978
979 // floor((double)floatval) -> (double)floorf(floatval)
980 Value *V = Cast->getOperand(0);
981 V = EmitUnaryFloatFnCall(V, Callee->getNameStart(), B);
982 return B.CreateFPExt(V, Type::DoubleTy);
983 }
984};
985
986//===----------------------------------------------------------------------===//
987// Integer Optimizations
988//===----------------------------------------------------------------------===//
989
990//===---------------------------------------===//
991// 'ffs*' Optimizations
992
993struct VISIBILITY_HIDDEN FFSOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +0000994 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +0000995 const FunctionType *FT = Callee->getFunctionType();
996 // Just make sure this has 2 arguments of the same FP type, which match the
997 // result type.
998 if (FT->getNumParams() != 1 || FT->getReturnType() != Type::Int32Ty ||
999 !isa<IntegerType>(FT->getParamType(0)))
1000 return 0;
1001
1002 Value *Op = CI->getOperand(1);
1003
1004 // Constant fold.
1005 if (ConstantInt *CI = dyn_cast<ConstantInt>(Op)) {
1006 if (CI->getValue() == 0) // ffs(0) -> 0.
1007 return Constant::getNullValue(CI->getType());
1008 return ConstantInt::get(Type::Int32Ty, // ffs(c) -> cttz(c)+1
1009 CI->getValue().countTrailingZeros()+1);
1010 }
1011
1012 // ffs(x) -> x != 0 ? (i32)llvm.cttz(x)+1 : 0
1013 const Type *ArgType = Op->getType();
1014 Value *F = Intrinsic::getDeclaration(Callee->getParent(),
1015 Intrinsic::cttz, &ArgType, 1);
1016 Value *V = B.CreateCall(F, Op, "cttz");
1017 V = B.CreateAdd(V, ConstantInt::get(Type::Int32Ty, 1), "tmp");
1018 V = B.CreateIntCast(V, Type::Int32Ty, false, "tmp");
1019
1020 Value *Cond = B.CreateICmpNE(Op, Constant::getNullValue(ArgType), "tmp");
1021 return B.CreateSelect(Cond, V, ConstantInt::get(Type::Int32Ty, 0));
1022 }
1023};
1024
1025//===---------------------------------------===//
1026// 'isdigit' Optimizations
1027
1028struct VISIBILITY_HIDDEN IsDigitOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001029 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001030 const FunctionType *FT = Callee->getFunctionType();
1031 // We require integer(i32)
1032 if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) ||
1033 FT->getParamType(0) != Type::Int32Ty)
1034 return 0;
1035
1036 // isdigit(c) -> (c-'0') <u 10
1037 Value *Op = CI->getOperand(1);
1038 Op = B.CreateSub(Op, ConstantInt::get(Type::Int32Ty, '0'), "isdigittmp");
1039 Op = B.CreateICmpULT(Op, ConstantInt::get(Type::Int32Ty, 10), "isdigit");
1040 return B.CreateZExt(Op, CI->getType());
1041 }
1042};
1043
1044//===---------------------------------------===//
1045// 'isascii' Optimizations
1046
1047struct VISIBILITY_HIDDEN IsAsciiOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001048 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001049 const FunctionType *FT = Callee->getFunctionType();
1050 // We require integer(i32)
1051 if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) ||
1052 FT->getParamType(0) != Type::Int32Ty)
1053 return 0;
1054
1055 // isascii(c) -> c <u 128
1056 Value *Op = CI->getOperand(1);
1057 Op = B.CreateICmpULT(Op, ConstantInt::get(Type::Int32Ty, 128), "isascii");
1058 return B.CreateZExt(Op, CI->getType());
1059 }
1060};
Chris Lattner313f0e62008-06-09 08:26:51 +00001061
1062//===---------------------------------------===//
1063// 'abs', 'labs', 'llabs' Optimizations
1064
1065struct VISIBILITY_HIDDEN AbsOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001066 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattner313f0e62008-06-09 08:26:51 +00001067 const FunctionType *FT = Callee->getFunctionType();
1068 // We require integer(integer) where the types agree.
1069 if (FT->getNumParams() != 1 || !isa<IntegerType>(FT->getReturnType()) ||
1070 FT->getParamType(0) != FT->getReturnType())
1071 return 0;
1072
1073 // abs(x) -> x >s -1 ? x : -x
1074 Value *Op = CI->getOperand(1);
1075 Value *Pos = B.CreateICmpSGT(Op,ConstantInt::getAllOnesValue(Op->getType()),
1076 "ispos");
1077 Value *Neg = B.CreateNeg(Op, "neg");
1078 return B.CreateSelect(Pos, Op, Neg);
1079 }
1080};
1081
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001082
1083//===---------------------------------------===//
1084// 'toascii' Optimizations
1085
1086struct VISIBILITY_HIDDEN ToAsciiOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001087 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001088 const FunctionType *FT = Callee->getFunctionType();
1089 // We require i32(i32)
1090 if (FT->getNumParams() != 1 || FT->getReturnType() != FT->getParamType(0) ||
1091 FT->getParamType(0) != Type::Int32Ty)
1092 return 0;
1093
1094 // isascii(c) -> c & 0x7f
1095 return B.CreateAnd(CI->getOperand(1), ConstantInt::get(CI->getType(),0x7F));
1096 }
1097};
1098
1099//===----------------------------------------------------------------------===//
1100// Formatting and IO Optimizations
1101//===----------------------------------------------------------------------===//
1102
1103//===---------------------------------------===//
1104// 'printf' Optimizations
1105
1106struct VISIBILITY_HIDDEN PrintFOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001107 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001108 // Require one fixed pointer argument and an integer/void result.
1109 const FunctionType *FT = Callee->getFunctionType();
1110 if (FT->getNumParams() < 1 || !isa<PointerType>(FT->getParamType(0)) ||
1111 !(isa<IntegerType>(FT->getReturnType()) ||
1112 FT->getReturnType() == Type::VoidTy))
1113 return 0;
1114
1115 // Check for a fixed format string.
1116 std::string FormatStr;
1117 if (!GetConstantStringInfo(CI->getOperand(1), FormatStr))
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001118 return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001119
1120 // Empty format string -> noop.
1121 if (FormatStr.empty()) // Tolerate printf's declared void.
1122 return CI->use_empty() ? (Value*)CI : ConstantInt::get(CI->getType(), 0);
1123
1124 // printf("x") -> putchar('x'), even for '%'.
1125 if (FormatStr.size() == 1) {
1126 EmitPutChar(ConstantInt::get(Type::Int32Ty, FormatStr[0]), B);
1127 return CI->use_empty() ? (Value*)CI : ConstantInt::get(CI->getType(), 1);
1128 }
1129
1130 // printf("foo\n") --> puts("foo")
1131 if (FormatStr[FormatStr.size()-1] == '\n' &&
1132 FormatStr.find('%') == std::string::npos) { // no format characters.
1133 // Create a string literal with no \n on it. We expect the constant merge
1134 // pass to be run after this pass, to merge duplicate strings.
1135 FormatStr.erase(FormatStr.end()-1);
1136 Constant *C = ConstantArray::get(FormatStr, true);
1137 C = new GlobalVariable(C->getType(), true,GlobalVariable::InternalLinkage,
1138 C, "str", Callee->getParent());
1139 EmitPutS(C, B);
1140 return CI->use_empty() ? (Value*)CI :
1141 ConstantInt::get(CI->getType(), FormatStr.size()+1);
1142 }
1143
1144 // Optimize specific format strings.
1145 // printf("%c", chr) --> putchar(*(i8*)dst)
1146 if (FormatStr == "%c" && CI->getNumOperands() > 2 &&
1147 isa<IntegerType>(CI->getOperand(2)->getType())) {
1148 EmitPutChar(CI->getOperand(2), B);
1149 return CI->use_empty() ? (Value*)CI : ConstantInt::get(CI->getType(), 1);
1150 }
1151
1152 // printf("%s\n", str) --> puts(str)
1153 if (FormatStr == "%s\n" && CI->getNumOperands() > 2 &&
1154 isa<PointerType>(CI->getOperand(2)->getType()) &&
1155 CI->use_empty()) {
1156 EmitPutS(CI->getOperand(2), B);
1157 return CI;
1158 }
1159 return 0;
1160 }
1161};
1162
1163//===---------------------------------------===//
1164// 'sprintf' Optimizations
1165
1166struct VISIBILITY_HIDDEN SPrintFOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001167 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001168 // Require two fixed pointer arguments and an integer result.
1169 const FunctionType *FT = Callee->getFunctionType();
1170 if (FT->getNumParams() != 2 || !isa<PointerType>(FT->getParamType(0)) ||
1171 !isa<PointerType>(FT->getParamType(1)) ||
1172 !isa<IntegerType>(FT->getReturnType()))
1173 return 0;
1174
1175 // Check for a fixed format string.
1176 std::string FormatStr;
1177 if (!GetConstantStringInfo(CI->getOperand(2), FormatStr))
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001178 return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001179
1180 // If we just have a format string (nothing else crazy) transform it.
1181 if (CI->getNumOperands() == 3) {
1182 // Make sure there's no % in the constant array. We could try to handle
1183 // %% -> % in the future if we cared.
1184 for (unsigned i = 0, e = FormatStr.size(); i != e; ++i)
1185 if (FormatStr[i] == '%')
1186 return 0; // we found a format specifier, bail out.
1187
1188 // sprintf(str, fmt) -> llvm.memcpy(str, fmt, strlen(fmt)+1, 1)
1189 EmitMemCpy(CI->getOperand(1), CI->getOperand(2), // Copy the nul byte.
1190 ConstantInt::get(TD->getIntPtrType(), FormatStr.size()+1),1,B);
1191 return ConstantInt::get(CI->getType(), FormatStr.size());
1192 }
1193
1194 // The remaining optimizations require the format string to be "%s" or "%c"
1195 // and have an extra operand.
1196 if (FormatStr.size() != 2 || FormatStr[0] != '%' || CI->getNumOperands() <4)
1197 return 0;
1198
1199 // Decode the second character of the format string.
1200 if (FormatStr[1] == 'c') {
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001201 // sprintf(dst, "%c", chr) --> *(i8*)dst = chr; *((i8*)dst+1) = 0
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001202 if (!isa<IntegerType>(CI->getOperand(3)->getType())) return 0;
1203 Value *V = B.CreateTrunc(CI->getOperand(3), Type::Int8Ty, "char");
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001204 Value *Ptr = CastToCStr(CI->getOperand(1), B);
1205 B.CreateStore(V, Ptr);
1206 Ptr = B.CreateGEP(Ptr, ConstantInt::get(Type::Int32Ty, 1), "nul");
1207 B.CreateStore(Constant::getNullValue(Type::Int8Ty), Ptr);
1208
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001209 return ConstantInt::get(CI->getType(), 1);
1210 }
1211
1212 if (FormatStr[1] == 's') {
1213 // sprintf(dest, "%s", str) -> llvm.memcpy(dest, str, strlen(str)+1, 1)
1214 if (!isa<PointerType>(CI->getOperand(3)->getType())) return 0;
1215
1216 Value *Len = EmitStrLen(CI->getOperand(3), B);
1217 Value *IncLen = B.CreateAdd(Len, ConstantInt::get(Len->getType(), 1),
1218 "leninc");
1219 EmitMemCpy(CI->getOperand(1), CI->getOperand(3), IncLen, 1, B);
1220
1221 // The sprintf result is the unincremented number of bytes in the string.
1222 return B.CreateIntCast(Len, CI->getType(), false);
1223 }
1224 return 0;
1225 }
1226};
1227
1228//===---------------------------------------===//
1229// 'fwrite' Optimizations
1230
1231struct VISIBILITY_HIDDEN FWriteOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001232 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001233 // Require a pointer, an integer, an integer, a pointer, returning integer.
1234 const FunctionType *FT = Callee->getFunctionType();
1235 if (FT->getNumParams() != 4 || !isa<PointerType>(FT->getParamType(0)) ||
1236 !isa<IntegerType>(FT->getParamType(1)) ||
1237 !isa<IntegerType>(FT->getParamType(2)) ||
1238 !isa<PointerType>(FT->getParamType(3)) ||
1239 !isa<IntegerType>(FT->getReturnType()))
1240 return 0;
1241
1242 // Get the element size and count.
1243 ConstantInt *SizeC = dyn_cast<ConstantInt>(CI->getOperand(2));
1244 ConstantInt *CountC = dyn_cast<ConstantInt>(CI->getOperand(3));
1245 if (!SizeC || !CountC) return 0;
1246 uint64_t Bytes = SizeC->getZExtValue()*CountC->getZExtValue();
1247
1248 // If this is writing zero records, remove the call (it's a noop).
1249 if (Bytes == 0)
1250 return ConstantInt::get(CI->getType(), 0);
1251
1252 // If this is writing one byte, turn it into fputc.
1253 if (Bytes == 1) { // fwrite(S,1,1,F) -> fputc(S[0],F)
1254 Value *Char = B.CreateLoad(CastToCStr(CI->getOperand(1), B), "char");
1255 EmitFPutC(Char, CI->getOperand(4), B);
1256 return ConstantInt::get(CI->getType(), 1);
1257 }
1258
1259 return 0;
1260 }
1261};
1262
1263//===---------------------------------------===//
1264// 'fputs' Optimizations
1265
1266struct VISIBILITY_HIDDEN FPutsOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001267 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001268 // Require two pointers. Also, we can't optimize if return value is used.
1269 const FunctionType *FT = Callee->getFunctionType();
1270 if (FT->getNumParams() != 2 || !isa<PointerType>(FT->getParamType(0)) ||
1271 !isa<PointerType>(FT->getParamType(1)) ||
1272 !CI->use_empty())
1273 return 0;
1274
1275 // fputs(s,F) --> fwrite(s,1,strlen(s),F)
1276 uint64_t Len = GetStringLength(CI->getOperand(1));
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001277 if (!Len) return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001278 EmitFWrite(CI->getOperand(1), ConstantInt::get(TD->getIntPtrType(), Len-1),
1279 CI->getOperand(2), B);
1280 return CI; // Known to have no uses (see above).
1281 }
1282};
1283
1284//===---------------------------------------===//
1285// 'fprintf' Optimizations
1286
1287struct VISIBILITY_HIDDEN FPrintFOpt : public LibCallOptimization {
Eric Christopher7a61d702008-08-08 19:39:37 +00001288 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001289 // Require two fixed paramters as pointers and integer result.
1290 const FunctionType *FT = Callee->getFunctionType();
1291 if (FT->getNumParams() != 2 || !isa<PointerType>(FT->getParamType(0)) ||
1292 !isa<PointerType>(FT->getParamType(1)) ||
1293 !isa<IntegerType>(FT->getReturnType()))
1294 return 0;
1295
1296 // All the optimizations depend on the format string.
1297 std::string FormatStr;
1298 if (!GetConstantStringInfo(CI->getOperand(2), FormatStr))
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001299 return 0;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001300
1301 // fprintf(F, "foo") --> fwrite("foo", 3, 1, F)
1302 if (CI->getNumOperands() == 3) {
1303 for (unsigned i = 0, e = FormatStr.size(); i != e; ++i)
1304 if (FormatStr[i] == '%') // Could handle %% -> % if we cared.
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001305 return 0; // We found a format specifier.
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001306
1307 EmitFWrite(CI->getOperand(2), ConstantInt::get(TD->getIntPtrType(),
1308 FormatStr.size()),
1309 CI->getOperand(1), B);
1310 return ConstantInt::get(CI->getType(), FormatStr.size());
1311 }
1312
1313 // The remaining optimizations require the format string to be "%s" or "%c"
1314 // and have an extra operand.
1315 if (FormatStr.size() != 2 || FormatStr[0] != '%' || CI->getNumOperands() <4)
1316 return 0;
1317
1318 // Decode the second character of the format string.
1319 if (FormatStr[1] == 'c') {
1320 // fprintf(F, "%c", chr) --> *(i8*)dst = chr
1321 if (!isa<IntegerType>(CI->getOperand(3)->getType())) return 0;
1322 EmitFPutC(CI->getOperand(3), CI->getOperand(1), B);
1323 return ConstantInt::get(CI->getType(), 1);
1324 }
1325
1326 if (FormatStr[1] == 's') {
1327 // fprintf(F, "%s", str) -> fputs(str, F)
1328 if (!isa<PointerType>(CI->getOperand(3)->getType()) || !CI->use_empty())
1329 return 0;
1330 EmitFPutS(CI->getOperand(3), CI->getOperand(1), B);
1331 return CI;
1332 }
1333 return 0;
1334 }
1335};
1336
Bill Wendlingac178222008-05-05 21:37:59 +00001337} // end anonymous namespace.
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001338
1339//===----------------------------------------------------------------------===//
1340// SimplifyLibCalls Pass Implementation
1341//===----------------------------------------------------------------------===//
1342
1343namespace {
1344 /// This pass optimizes well known library functions from libc and libm.
1345 ///
1346 class VISIBILITY_HIDDEN SimplifyLibCalls : public FunctionPass {
1347 StringMap<LibCallOptimization*> Optimizations;
1348 // Miscellaneous LibCall Optimizations
1349 ExitOpt Exit;
1350 // String and Memory LibCall Optimizations
1351 StrCatOpt StrCat; StrChrOpt StrChr; StrCmpOpt StrCmp; StrNCmpOpt StrNCmp;
Nick Lewycky4c498412009-02-13 15:31:46 +00001352 StrCpyOpt StrCpy; StrLenOpt StrLen; StrToOpt StrTo; MemCmpOpt MemCmp;
1353 MemCpyOpt MemCpy; MemMoveOpt MemMove; MemSetOpt MemSet;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001354 // Math Library Optimizations
Chris Lattnere818f772008-05-02 18:43:35 +00001355 PowOpt Pow; Exp2Opt Exp2; UnaryDoubleFPOpt UnaryDoubleFP;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001356 // Integer Optimizations
Chris Lattner313f0e62008-06-09 08:26:51 +00001357 FFSOpt FFS; AbsOpt Abs; IsDigitOpt IsDigit; IsAsciiOpt IsAscii;
1358 ToAsciiOpt ToAscii;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001359 // Formatting and IO Optimizations
1360 SPrintFOpt SPrintF; PrintFOpt PrintF;
1361 FWriteOpt FWrite; FPutsOpt FPuts; FPrintFOpt FPrintF;
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001362
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001363 bool Modified; // This is only used by doInitialization.
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001364 public:
1365 static char ID; // Pass identification
Dan Gohmanae73dc12008-09-04 17:05:41 +00001366 SimplifyLibCalls() : FunctionPass(&ID) {}
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001367
1368 void InitOptimizations();
1369 bool runOnFunction(Function &F);
1370
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001371 void setDoesNotAccessMemory(Function &F);
1372 void setOnlyReadsMemory(Function &F);
1373 void setDoesNotThrow(Function &F);
1374 void setDoesNotCapture(Function &F, unsigned n);
1375 void setDoesNotAlias(Function &F, unsigned n);
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001376 bool doInitialization(Module &M);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001377
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001378 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1379 AU.addRequired<TargetData>();
1380 }
1381 };
1382 char SimplifyLibCalls::ID = 0;
1383} // end anonymous namespace.
1384
1385static RegisterPass<SimplifyLibCalls>
1386X("simplify-libcalls", "Simplify well-known library calls");
1387
1388// Public interface to the Simplify LibCalls pass.
1389FunctionPass *llvm::createSimplifyLibCallsPass() {
1390 return new SimplifyLibCalls();
1391}
1392
1393/// Optimizations - Populate the Optimizations map with all the optimizations
1394/// we know.
1395void SimplifyLibCalls::InitOptimizations() {
1396 // Miscellaneous LibCall Optimizations
1397 Optimizations["exit"] = &Exit;
1398
1399 // String and Memory LibCall Optimizations
1400 Optimizations["strcat"] = &StrCat;
1401 Optimizations["strchr"] = &StrChr;
1402 Optimizations["strcmp"] = &StrCmp;
1403 Optimizations["strncmp"] = &StrNCmp;
1404 Optimizations["strcpy"] = &StrCpy;
1405 Optimizations["strlen"] = &StrLen;
Nick Lewycky4c498412009-02-13 15:31:46 +00001406 Optimizations["strtol"] = &StrTo;
1407 Optimizations["strtod"] = &StrTo;
1408 Optimizations["strtof"] = &StrTo;
1409 Optimizations["strtoul"] = &StrTo;
1410 Optimizations["strtoll"] = &StrTo;
1411 Optimizations["strtold"] = &StrTo;
1412 Optimizations["strtoull"] = &StrTo;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001413 Optimizations["memcmp"] = &MemCmp;
1414 Optimizations["memcpy"] = &MemCpy;
Eli Friedmand83ae7d2008-11-30 08:32:11 +00001415 Optimizations["memmove"] = &MemMove;
1416 Optimizations["memset"] = &MemSet;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001417
1418 // Math Library Optimizations
1419 Optimizations["powf"] = &Pow;
1420 Optimizations["pow"] = &Pow;
1421 Optimizations["powl"] = &Pow;
Dale Johannesen53bfbbc2008-09-04 18:30:46 +00001422 Optimizations["llvm.pow.f32"] = &Pow;
1423 Optimizations["llvm.pow.f64"] = &Pow;
1424 Optimizations["llvm.pow.f80"] = &Pow;
1425 Optimizations["llvm.pow.f128"] = &Pow;
1426 Optimizations["llvm.pow.ppcf128"] = &Pow;
Chris Lattnere818f772008-05-02 18:43:35 +00001427 Optimizations["exp2l"] = &Exp2;
1428 Optimizations["exp2"] = &Exp2;
1429 Optimizations["exp2f"] = &Exp2;
Dale Johannesen53bfbbc2008-09-04 18:30:46 +00001430 Optimizations["llvm.exp2.ppcf128"] = &Exp2;
1431 Optimizations["llvm.exp2.f128"] = &Exp2;
1432 Optimizations["llvm.exp2.f80"] = &Exp2;
1433 Optimizations["llvm.exp2.f64"] = &Exp2;
1434 Optimizations["llvm.exp2.f32"] = &Exp2;
Chris Lattnere818f772008-05-02 18:43:35 +00001435
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001436#ifdef HAVE_FLOORF
1437 Optimizations["floor"] = &UnaryDoubleFP;
1438#endif
1439#ifdef HAVE_CEILF
1440 Optimizations["ceil"] = &UnaryDoubleFP;
1441#endif
1442#ifdef HAVE_ROUNDF
1443 Optimizations["round"] = &UnaryDoubleFP;
1444#endif
1445#ifdef HAVE_RINTF
1446 Optimizations["rint"] = &UnaryDoubleFP;
1447#endif
1448#ifdef HAVE_NEARBYINTF
1449 Optimizations["nearbyint"] = &UnaryDoubleFP;
1450#endif
1451
1452 // Integer Optimizations
1453 Optimizations["ffs"] = &FFS;
1454 Optimizations["ffsl"] = &FFS;
1455 Optimizations["ffsll"] = &FFS;
Chris Lattner313f0e62008-06-09 08:26:51 +00001456 Optimizations["abs"] = &Abs;
1457 Optimizations["labs"] = &Abs;
1458 Optimizations["llabs"] = &Abs;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001459 Optimizations["isdigit"] = &IsDigit;
1460 Optimizations["isascii"] = &IsAscii;
1461 Optimizations["toascii"] = &ToAscii;
1462
1463 // Formatting and IO Optimizations
1464 Optimizations["sprintf"] = &SPrintF;
1465 Optimizations["printf"] = &PrintF;
1466 Optimizations["fwrite"] = &FWrite;
1467 Optimizations["fputs"] = &FPuts;
1468 Optimizations["fprintf"] = &FPrintF;
1469}
1470
1471
1472/// runOnFunction - Top level algorithm.
1473///
1474bool SimplifyLibCalls::runOnFunction(Function &F) {
1475 if (Optimizations.empty())
1476 InitOptimizations();
1477
1478 const TargetData &TD = getAnalysis<TargetData>();
1479
Eric Christopher7a61d702008-08-08 19:39:37 +00001480 IRBuilder<> Builder;
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001481
1482 bool Changed = false;
1483 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
1484 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
1485 // Ignore non-calls.
1486 CallInst *CI = dyn_cast<CallInst>(I++);
1487 if (!CI) continue;
1488
1489 // Ignore indirect calls and calls to non-external functions.
1490 Function *Callee = CI->getCalledFunction();
1491 if (Callee == 0 || !Callee->isDeclaration() ||
1492 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage()))
1493 continue;
1494
1495 // Ignore unknown calls.
1496 const char *CalleeName = Callee->getNameStart();
1497 StringMap<LibCallOptimization*>::iterator OMI =
1498 Optimizations.find(CalleeName, CalleeName+Callee->getNameLen());
1499 if (OMI == Optimizations.end()) continue;
1500
1501 // Set the builder to the instruction after the call.
1502 Builder.SetInsertPoint(BB, I);
1503
1504 // Try to optimize this call.
1505 Value *Result = OMI->second->OptimizeCall(CI, TD, Builder);
1506 if (Result == 0) continue;
1507
Chris Lattner56b4f2b2008-05-01 06:39:12 +00001508 DEBUG(DOUT << "SimplifyLibCalls simplified: " << *CI;
1509 DOUT << " into: " << *Result << "\n");
1510
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00001511 // Something changed!
1512 Changed = true;
1513 ++NumSimplified;
1514
1515 // Inspect the instruction after the call (which was potentially just
1516 // added) next.
1517 I = CI; ++I;
1518
1519 if (CI != Result && !CI->use_empty()) {
1520 CI->replaceAllUsesWith(Result);
1521 if (!Result->hasName())
1522 Result->takeName(CI);
1523 }
1524 CI->eraseFromParent();
1525 }
1526 }
1527 return Changed;
1528}
1529
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001530// Utility methods for doInitialization.
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001531
1532void SimplifyLibCalls::setDoesNotAccessMemory(Function &F) {
1533 if (!F.doesNotAccessMemory()) {
1534 F.setDoesNotAccessMemory();
1535 ++NumAnnotated;
1536 Modified = true;
1537 }
1538}
1539void SimplifyLibCalls::setOnlyReadsMemory(Function &F) {
1540 if (!F.onlyReadsMemory()) {
1541 F.setOnlyReadsMemory();
1542 ++NumAnnotated;
1543 Modified = true;
1544 }
1545}
1546void SimplifyLibCalls::setDoesNotThrow(Function &F) {
1547 if (!F.doesNotThrow()) {
1548 F.setDoesNotThrow();
1549 ++NumAnnotated;
1550 Modified = true;
1551 }
1552}
1553void SimplifyLibCalls::setDoesNotCapture(Function &F, unsigned n) {
1554 if (!F.doesNotCapture(n)) {
1555 F.setDoesNotCapture(n);
1556 ++NumAnnotated;
1557 Modified = true;
1558 }
1559}
1560void SimplifyLibCalls::setDoesNotAlias(Function &F, unsigned n) {
1561 if (!F.doesNotAlias(n)) {
1562 F.setDoesNotAlias(n);
1563 ++NumAnnotated;
1564 Modified = true;
1565 }
1566}
1567
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001568/// doInitialization - Add attributes to well-known functions.
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001569///
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001570bool SimplifyLibCalls::doInitialization(Module &M) {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001571 Modified = false;
1572 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
1573 Function &F = *I;
1574 if (!F.isDeclaration())
1575 continue;
1576
1577 unsigned NameLen = F.getNameLen();
1578 if (!NameLen)
1579 continue;
1580
1581 const FunctionType *FTy = F.getFunctionType();
1582
1583 const char *NameStr = F.getNameStart();
1584 switch (NameStr[0]) {
1585 case 's':
1586 if (NameLen == 6 && !strcmp(NameStr, "strlen")) {
1587 if (FTy->getNumParams() != 1 ||
1588 !isa<PointerType>(FTy->getParamType(0)))
1589 continue;
1590 setOnlyReadsMemory(F);
1591 setDoesNotThrow(F);
1592 setDoesNotCapture(F, 1);
1593 } else if ((NameLen == 6 && !strcmp(NameStr, "strcpy")) ||
1594 (NameLen == 6 && !strcmp(NameStr, "stpcpy")) ||
1595 (NameLen == 6 && !strcmp(NameStr, "strcat")) ||
Nick Lewycky4c498412009-02-13 15:31:46 +00001596 (NameLen == 6 && !strcmp(NameStr, "strtol")) ||
1597 (NameLen == 6 && !strcmp(NameStr, "strtod")) ||
1598 (NameLen == 6 && !strcmp(NameStr, "strtof")) ||
1599 (NameLen == 7 && !strcmp(NameStr, "strtoul")) ||
1600 (NameLen == 7 && !strcmp(NameStr, "strtoll")) ||
1601 (NameLen == 7 && !strcmp(NameStr, "strtold")) ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001602 (NameLen == 7 && !strcmp(NameStr, "strncat")) ||
Nick Lewycky4c498412009-02-13 15:31:46 +00001603 (NameLen == 7 && !strcmp(NameStr, "strncpy")) ||
1604 (NameLen == 8 && !strcmp(NameStr, "strtoull"))) {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001605 if (FTy->getNumParams() < 2 ||
1606 !isa<PointerType>(FTy->getParamType(1)))
1607 continue;
1608 setDoesNotThrow(F);
1609 setDoesNotCapture(F, 2);
1610 } else if (NameLen == 7 && !strcmp(NameStr, "strxfrm")) {
1611 if (FTy->getNumParams() != 3 ||
1612 !isa<PointerType>(FTy->getParamType(0)) ||
1613 !isa<PointerType>(FTy->getParamType(1)))
1614 continue;
1615 setDoesNotThrow(F);
1616 setDoesNotCapture(F, 1);
1617 setDoesNotCapture(F, 2);
1618 } else if ((NameLen == 6 && !strcmp(NameStr, "strcmp")) ||
1619 (NameLen == 6 && !strcmp(NameStr, "strspn")) ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001620 (NameLen == 7 && !strcmp(NameStr, "strncmp")) ||
1621 (NameLen == 7 && !strcmp(NameStr, "strcspn")) ||
1622 (NameLen == 7 && !strcmp(NameStr, "strcoll")) ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001623 (NameLen == 10 && !strcmp(NameStr, "strcasecmp")) ||
1624 (NameLen == 11 && !strcmp(NameStr, "strncasecmp"))) {
1625 if (FTy->getNumParams() < 2 ||
1626 !isa<PointerType>(FTy->getParamType(0)) ||
1627 !isa<PointerType>(FTy->getParamType(1)))
1628 continue;
1629 setOnlyReadsMemory(F);
1630 setDoesNotThrow(F);
1631 setDoesNotCapture(F, 1);
1632 setDoesNotCapture(F, 2);
1633 } else if ((NameLen == 6 && !strcmp(NameStr, "strstr")) ||
1634 (NameLen == 7 && !strcmp(NameStr, "strpbrk"))) {
1635 if (FTy->getNumParams() != 2 ||
1636 !isa<PointerType>(FTy->getParamType(1)))
1637 continue;
1638 setOnlyReadsMemory(F);
1639 setDoesNotThrow(F);
1640 setDoesNotCapture(F, 2);
1641 } else if ((NameLen == 6 && !strcmp(NameStr, "strtok")) ||
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001642 (NameLen == 8 && !strcmp(NameStr, "strtok_r"))) {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001643 if (FTy->getNumParams() < 2 ||
1644 !isa<PointerType>(FTy->getParamType(1)))
1645 continue;
1646 setDoesNotThrow(F);
1647 setDoesNotCapture(F, 2);
1648 } else if ((NameLen == 5 && !strcmp(NameStr, "scanf")) ||
1649 (NameLen == 6 && !strcmp(NameStr, "setbuf")) ||
1650 (NameLen == 7 && !strcmp(NameStr, "setvbuf"))) {
1651 if (FTy->getNumParams() < 1 ||
1652 !isa<PointerType>(FTy->getParamType(0)))
1653 continue;
1654 setDoesNotThrow(F);
1655 setDoesNotCapture(F, 1);
1656 } else if (NameLen == 6 && !strcmp(NameStr, "sscanf")) {
1657 if (FTy->getNumParams() < 2 ||
1658 !isa<PointerType>(FTy->getParamType(0)) ||
1659 !isa<PointerType>(FTy->getParamType(1)))
1660 continue;
1661 setDoesNotThrow(F);
1662 setDoesNotCapture(F, 1);
1663 setDoesNotCapture(F, 2);
Nick Lewycky6cd0c042009-01-05 00:07:50 +00001664 } else if ((NameLen == 6 && !strcmp(NameStr, "strdup")) ||
1665 (NameLen == 7 && !strcmp(NameStr, "strndup"))) {
1666 if (FTy->getNumParams() < 1 ||
1667 !isa<PointerType>(FTy->getReturnType()) ||
1668 !isa<PointerType>(FTy->getParamType(0)))
1669 continue;
1670 setDoesNotThrow(F);
1671 setDoesNotAlias(F, 0);
1672 setDoesNotCapture(F, 1);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001673 } else if (NameLen == 7 && !strcmp(NameStr, "sprintf")) {
1674 if (FTy->getNumParams() != 2 ||
1675 !isa<PointerType>(FTy->getParamType(0)) ||
1676 !isa<PointerType>(FTy->getParamType(1)))
1677 continue;
1678 setDoesNotThrow(F);
1679 setDoesNotCapture(F, 1);
1680 setDoesNotCapture(F, 2);
1681 } else if (NameLen == 8 && !strcmp(NameStr, "snprintf")) {
1682 if (FTy->getNumParams() != 3 ||
1683 !isa<PointerType>(FTy->getParamType(0)) ||
1684 !isa<PointerType>(FTy->getParamType(2)))
1685 continue;
1686 setDoesNotThrow(F);
1687 setDoesNotCapture(F, 1);
1688 setDoesNotCapture(F, 3);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001689 }
1690 break;
1691 case 'm':
1692 if (NameLen == 6 && !strcmp(NameStr, "memcmp")) {
1693 if (FTy->getNumParams() != 3 ||
1694 !isa<PointerType>(FTy->getParamType(0)) ||
1695 !isa<PointerType>(FTy->getParamType(1)))
1696 continue;
1697 setOnlyReadsMemory(F);
1698 setDoesNotThrow(F);
1699 setDoesNotCapture(F, 1);
1700 setDoesNotCapture(F, 2);
1701 } else if ((NameLen == 6 && !strcmp(NameStr, "memchr")) ||
1702 (NameLen == 7 && !strcmp(NameStr, "memrchr"))) {
1703 if (FTy->getNumParams() != 3)
1704 continue;
1705 setOnlyReadsMemory(F);
1706 setDoesNotThrow(F);
1707 } else if ((NameLen == 6 && !strcmp(NameStr, "memcpy")) ||
1708 (NameLen == 7 && !strcmp(NameStr, "memccpy")) ||
1709 (NameLen == 7 && !strcmp(NameStr, "memmove"))) {
1710 if (FTy->getNumParams() < 3 ||
1711 !isa<PointerType>(FTy->getParamType(1)))
1712 continue;
1713 setDoesNotThrow(F);
1714 setDoesNotCapture(F, 2);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001715 } else if (NameLen == 8 && !strcmp(NameStr, "memalign")) {
1716 if (!isa<PointerType>(FTy->getReturnType()))
1717 continue;
1718 setDoesNotAlias(F, 0);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001719 }
1720 break;
1721 case 'r':
1722 if (NameLen == 7 && !strcmp(NameStr, "realloc")) {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001723 if (FTy->getNumParams() != 2 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001724 !isa<PointerType>(FTy->getParamType(0)) ||
1725 !isa<PointerType>(FTy->getReturnType()))
1726 continue;
1727 setDoesNotThrow(F);
1728 setDoesNotAlias(F, 0);
1729 setDoesNotCapture(F, 1);
1730 } else if (NameLen == 4 && !strcmp(NameStr, "read")) {
1731 if (FTy->getNumParams() != 3 ||
1732 !isa<PointerType>(FTy->getParamType(1)))
1733 continue;
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001734 // May throw; "read" is a valid pthread cancellation point.
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001735 setDoesNotCapture(F, 2);
1736 } else if ((NameLen == 5 && !strcmp(NameStr, "rmdir")) ||
1737 (NameLen == 6 && !strcmp(NameStr, "rewind")) ||
1738 (NameLen == 6 && !strcmp(NameStr, "remove"))) {
1739 if (FTy->getNumParams() != 1 ||
1740 !isa<PointerType>(FTy->getParamType(0)))
1741 continue;
1742 setDoesNotThrow(F);
1743 setDoesNotCapture(F, 1);
1744 } else if (NameLen == 6 && !strcmp(NameStr, "rename")) {
1745 if (FTy->getNumParams() != 2 ||
1746 !isa<PointerType>(FTy->getParamType(0)) ||
1747 !isa<PointerType>(FTy->getParamType(1)))
1748 continue;
1749 setDoesNotThrow(F);
1750 setDoesNotCapture(F, 1);
1751 setDoesNotCapture(F, 2);
1752 }
1753 break;
1754 case 'w':
1755 if (NameLen == 5 && !strcmp(NameStr, "write")) {
1756 if (FTy->getNumParams() != 3 ||
1757 !isa<PointerType>(FTy->getParamType(1)))
1758 continue;
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001759 // May throw; "write" is a valid pthread cancellation point.
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001760 setDoesNotCapture(F, 2);
1761 }
1762 break;
1763 case 'b':
1764 if (NameLen == 5 && !strcmp(NameStr, "bcopy")) {
1765 if (FTy->getNumParams() != 3 ||
1766 !isa<PointerType>(FTy->getParamType(0)) ||
1767 !isa<PointerType>(FTy->getParamType(1)))
1768 continue;
1769 setDoesNotThrow(F);
1770 setDoesNotCapture(F, 1);
1771 setDoesNotCapture(F, 2);
1772 } else if (NameLen == 4 && !strcmp(NameStr, "bcmp")) {
1773 if (FTy->getNumParams() != 3 ||
1774 !isa<PointerType>(FTy->getParamType(0)) ||
1775 !isa<PointerType>(FTy->getParamType(1)))
1776 continue;
1777 setDoesNotThrow(F);
1778 setOnlyReadsMemory(F);
1779 setDoesNotCapture(F, 1);
1780 setDoesNotCapture(F, 2);
1781 } else if (NameLen == 5 && !strcmp(NameStr, "bzero")) {
1782 if (FTy->getNumParams() != 2 ||
1783 !isa<PointerType>(FTy->getParamType(0)))
1784 continue;
1785 setDoesNotThrow(F);
1786 setDoesNotCapture(F, 1);
1787 }
1788 break;
1789 case 'c':
1790 if (NameLen == 6 && !strcmp(NameStr, "calloc")) {
1791 if (FTy->getNumParams() != 2 ||
1792 !isa<PointerType>(FTy->getReturnType()))
1793 continue;
1794 setDoesNotThrow(F);
1795 setDoesNotAlias(F, 0);
1796 } else if ((NameLen == 5 && !strcmp(NameStr, "chown")) ||
1797 (NameLen == 8 && !strcmp(NameStr, "clearerr")) ||
1798 (NameLen == 8 && !strcmp(NameStr, "closedir"))) {
1799 if (FTy->getNumParams() == 0 ||
1800 !isa<PointerType>(FTy->getParamType(0)))
1801 continue;
1802 setDoesNotThrow(F);
1803 setDoesNotCapture(F, 1);
1804 }
1805 break;
1806 case 'a':
1807 if ((NameLen == 4 && !strcmp(NameStr, "atoi")) ||
1808 (NameLen == 4 && !strcmp(NameStr, "atol")) ||
1809 (NameLen == 4 && !strcmp(NameStr, "atof")) ||
1810 (NameLen == 5 && !strcmp(NameStr, "atoll"))) {
1811 if (FTy->getNumParams() != 1 ||
1812 !isa<PointerType>(FTy->getParamType(0)))
1813 continue;
1814 setDoesNotThrow(F);
1815 setOnlyReadsMemory(F);
1816 setDoesNotCapture(F, 1);
1817 } else if (NameLen == 6 && !strcmp(NameStr, "access")) {
1818 if (FTy->getNumParams() != 2 ||
1819 !isa<PointerType>(FTy->getParamType(0)))
1820 continue;
1821 setDoesNotThrow(F);
1822 setDoesNotCapture(F, 1);
1823 }
1824 break;
1825 case 'f':
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001826 if (NameLen == 5 && !strcmp(NameStr, "fopen")) {
1827 if (FTy->getNumParams() != 2 ||
1828 !isa<PointerType>(FTy->getReturnType()) ||
1829 !isa<PointerType>(FTy->getParamType(0)) ||
1830 !isa<PointerType>(FTy->getParamType(1)))
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001831 continue;
1832 setDoesNotThrow(F);
1833 setDoesNotAlias(F, 0);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001834 setDoesNotCapture(F, 1);
1835 setDoesNotCapture(F, 2);
1836 } else if (NameLen == 6 && !strcmp(NameStr, "fdopen")) {
1837 if (FTy->getNumParams() != 2 ||
1838 !isa<PointerType>(FTy->getReturnType()) ||
1839 !isa<PointerType>(FTy->getParamType(1)))
1840 continue;
1841 setDoesNotThrow(F);
1842 setDoesNotAlias(F, 0);
1843 setDoesNotCapture(F, 2);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001844 } else if ((NameLen == 4 && !strcmp(NameStr, "feof")) ||
1845 (NameLen == 4 && !strcmp(NameStr, "free")) ||
1846 (NameLen == 5 && !strcmp(NameStr, "fseek")) ||
1847 (NameLen == 5 && !strcmp(NameStr, "ftell")) ||
1848 (NameLen == 5 && !strcmp(NameStr, "fgetc")) ||
1849 (NameLen == 6 && !strcmp(NameStr, "fseeko")) ||
1850 (NameLen == 6 && !strcmp(NameStr, "ftello")) ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001851 (NameLen == 6 && !strcmp(NameStr, "fileno")) ||
1852 (NameLen == 6 && !strcmp(NameStr, "fflush")) ||
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001853 (NameLen == 6 && !strcmp(NameStr, "fclose")) ||
1854 (NameLen == 7 && !strcmp(NameStr, "fsetpos"))) {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001855 if (FTy->getNumParams() == 0 ||
1856 !isa<PointerType>(FTy->getParamType(0)))
1857 continue;
1858 setDoesNotThrow(F);
1859 setDoesNotCapture(F, 1);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001860 } else if (NameLen == 6 && !strcmp(NameStr, "ferror")) {
1861 if (FTy->getNumParams() != 1 ||
1862 !isa<PointerType>(FTy->getParamType(0)))
1863 continue;
1864 setDoesNotThrow(F);
1865 setDoesNotCapture(F, 1);
1866 setOnlyReadsMemory(F);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001867 } else if ((NameLen == 5 && !strcmp(NameStr, "fputc")) ||
1868 (NameLen == 5 && !strcmp(NameStr, "fputs"))) {
1869 if (FTy->getNumParams() != 2 ||
1870 !isa<PointerType>(FTy->getParamType(1)))
1871 continue;
1872 setDoesNotThrow(F);
1873 setDoesNotCapture(F, 2);
1874 } else if (NameLen == 5 && !strcmp(NameStr, "fgets")) {
1875 if (FTy->getNumParams() != 3 ||
1876 !isa<PointerType>(FTy->getParamType(0)) ||
1877 !isa<PointerType>(FTy->getParamType(2)))
1878 continue;
1879 setDoesNotThrow(F);
1880 setDoesNotCapture(F, 3);
1881 } else if ((NameLen == 5 && !strcmp(NameStr, "fread")) ||
1882 (NameLen == 6 && !strcmp(NameStr, "fwrite"))) {
1883 if (FTy->getNumParams() != 4 ||
1884 !isa<PointerType>(FTy->getParamType(0)) ||
1885 !isa<PointerType>(FTy->getParamType(3)))
1886 continue;
1887 setDoesNotThrow(F);
1888 setDoesNotCapture(F, 1);
1889 setDoesNotCapture(F, 4);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001890 } else if (NameLen == 7 && !strcmp(NameStr, "fgetpos")) {
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001891 if (FTy->getNumParams() != 2 ||
1892 !isa<PointerType>(FTy->getParamType(0)) ||
1893 !isa<PointerType>(FTy->getParamType(1)))
1894 continue;
1895 setDoesNotThrow(F);
1896 setDoesNotCapture(F, 1);
1897 setDoesNotCapture(F, 2);
1898 } else if (NameLen == 6 && !strcmp(NameStr, "fscanf")) {
1899 if (FTy->getNumParams() < 2 ||
1900 !isa<PointerType>(FTy->getParamType(0)) ||
1901 !isa<PointerType>(FTy->getParamType(1)))
1902 continue;
1903 setDoesNotThrow(F);
1904 setDoesNotCapture(F, 1);
1905 setDoesNotCapture(F, 2);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001906 } else if (NameLen == 7 && !strcmp(NameStr, "fprintf")) {
1907 if (FTy->getNumParams() != 2 ||
1908 !isa<PointerType>(FTy->getParamType(0)) ||
1909 !isa<PointerType>(FTy->getParamType(1)))
1910 continue;
1911 setDoesNotThrow(F);
1912 setDoesNotCapture(F, 1);
1913 setDoesNotCapture(F, 2);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001914 }
1915 break;
1916 case 'g':
1917 if ((NameLen == 4 && !strcmp(NameStr, "getc")) ||
1918 (NameLen == 10 && !strcmp(NameStr, "getlogin_r"))) {
1919 if (FTy->getNumParams() == 0 ||
1920 !isa<PointerType>(FTy->getParamType(0)))
1921 continue;
1922 setDoesNotThrow(F);
1923 setDoesNotCapture(F, 1);
1924 } else if (NameLen == 6 && !strcmp(NameStr, "getenv")) {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001925 if (FTy->getNumParams() != 1 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001926 !isa<PointerType>(FTy->getParamType(0)))
1927 continue;
1928 setDoesNotThrow(F);
1929 setOnlyReadsMemory(F);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001930 setDoesNotCapture(F, 1);
1931 } else if ((NameLen == 4 && !strcmp(NameStr, "gets")) ||
1932 (NameLen == 7 && !strcmp(NameStr, "getchar"))) {
1933 setDoesNotThrow(F);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001934 }
1935 break;
1936 case 'u':
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001937 if (NameLen == 6 && !strcmp(NameStr, "ungetc")) {
1938 if (FTy->getNumParams() != 2 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001939 !isa<PointerType>(FTy->getParamType(1)))
1940 continue;
1941 setDoesNotThrow(F);
1942 setDoesNotCapture(F, 2);
1943 } else if (NameLen == 6 && !strcmp(NameStr, "unlink")) {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001944 if (FTy->getNumParams() != 1 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001945 !isa<PointerType>(FTy->getParamType(0)))
1946 continue;
1947 setDoesNotThrow(F);
1948 setDoesNotCapture(F, 1);
1949 }
1950 break;
1951 case 'p':
1952 if (NameLen == 4 && !strcmp(NameStr, "putc")) {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001953 if (FTy->getNumParams() != 2 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001954 !isa<PointerType>(FTy->getParamType(1)))
1955 continue;
1956 setDoesNotThrow(F);
1957 setDoesNotCapture(F, 2);
1958 } else if ((NameLen == 4 && !strcmp(NameStr, "puts")) ||
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001959 (NameLen == 6 && !strcmp(NameStr, "printf")) ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001960 (NameLen == 6 && !strcmp(NameStr, "perror"))) {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001961 if (FTy->getNumParams() != 1 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001962 !isa<PointerType>(FTy->getParamType(0)))
1963 continue;
1964 setDoesNotThrow(F);
1965 setDoesNotCapture(F, 1);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001966 } else if ((NameLen == 5 && !strcmp(NameStr, "pread")) ||
1967 (NameLen == 6 && !strcmp(NameStr, "pwrite"))) {
1968 if (FTy->getNumParams() != 4 ||
1969 !isa<PointerType>(FTy->getParamType(1)))
1970 continue;
1971 // May throw; these are valid pthread cancellation points.
1972 setDoesNotCapture(F, 2);
1973 } else if (NameLen == 7 && !strcmp(NameStr, "putchar")) {
1974 setDoesNotThrow(F);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001975 }
1976 break;
1977 case 'v':
1978 if (NameLen == 6 && !strcmp(NameStr, "vscanf")) {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001979 if (FTy->getNumParams() != 2 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001980 !isa<PointerType>(FTy->getParamType(1)))
1981 continue;
1982 setDoesNotThrow(F);
1983 setDoesNotCapture(F, 1);
1984 } else if ((NameLen == 7 && !strcmp(NameStr, "vsscanf")) ||
1985 (NameLen == 7 && !strcmp(NameStr, "vfscanf"))) {
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001986 if (FTy->getNumParams() != 3 ||
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00001987 !isa<PointerType>(FTy->getParamType(1)) ||
1988 !isa<PointerType>(FTy->getParamType(2)))
1989 continue;
1990 setDoesNotThrow(F);
1991 setDoesNotCapture(F, 1);
1992 setDoesNotCapture(F, 2);
Nick Lewycky0b6679d2009-01-18 04:34:36 +00001993 } else if (NameLen == 6 && !strcmp(NameStr, "valloc")) {
1994 if (!isa<PointerType>(FTy->getReturnType()))
1995 continue;
1996 setDoesNotThrow(F);
1997 setDoesNotAlias(F, 0);
1998 } else if (NameLen == 7 && !strcmp(NameStr, "vprintf")) {
1999 if (FTy->getNumParams() != 2 ||
2000 !isa<PointerType>(FTy->getParamType(0)))
2001 continue;
2002 setDoesNotThrow(F);
2003 setDoesNotCapture(F, 1);
2004 } else if ((NameLen == 8 && !strcmp(NameStr, "vfprintf")) ||
2005 (NameLen == 8 && !strcmp(NameStr, "vsprintf"))) {
2006 if (FTy->getNumParams() != 3 ||
2007 !isa<PointerType>(FTy->getParamType(0)) ||
2008 !isa<PointerType>(FTy->getParamType(1)))
2009 continue;
2010 setDoesNotThrow(F);
2011 setDoesNotCapture(F, 1);
2012 setDoesNotCapture(F, 2);
2013 } else if (NameLen == 9 && !strcmp(NameStr, "vsnprintf")) {
2014 if (FTy->getNumParams() != 4 ||
2015 !isa<PointerType>(FTy->getParamType(0)) ||
2016 !isa<PointerType>(FTy->getParamType(2)))
2017 continue;
2018 setDoesNotThrow(F);
2019 setDoesNotCapture(F, 1);
2020 setDoesNotCapture(F, 3);
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002021 }
2022 break;
2023 case 'o':
2024 if (NameLen == 7 && !strcmp(NameStr, "opendir")) {
2025 // The description of fdopendir sounds like opening the same fd
2026 // twice might result in the same DIR* !
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002027 if (!isa<PointerType>(FTy->getReturnType()))
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002028 continue;
2029 setDoesNotThrow(F);
2030 setDoesNotAlias(F, 0);
2031 }
2032 break;
2033 case 't':
2034 if (NameLen == 7 && !strcmp(NameStr, "tmpfile")) {
2035 if (!isa<PointerType>(FTy->getReturnType()))
2036 continue;
2037 setDoesNotThrow(F);
2038 setDoesNotAlias(F, 0);
2039 }
2040 case 'h':
2041 if ((NameLen == 5 && !strcmp(NameStr, "htonl")) ||
2042 (NameLen == 5 && !strcmp(NameStr, "htons"))) {
2043 setDoesNotThrow(F);
2044 setDoesNotAccessMemory(F);
2045 }
2046 break;
2047 case 'n':
2048 if ((NameLen == 5 && !strcmp(NameStr, "ntohl")) ||
2049 (NameLen == 5 && !strcmp(NameStr, "ntohs"))) {
2050 setDoesNotThrow(F);
2051 setDoesNotAccessMemory(F);
2052 }
Nick Lewycky0b6679d2009-01-18 04:34:36 +00002053 case '_':
2054 if ((NameLen == 8 && !strcmp(NameStr, "__strdup")) ||
2055 (NameLen == 9 && !strcmp(NameStr, "__strndup"))) {
2056 if (FTy->getNumParams() < 1 ||
2057 !isa<PointerType>(FTy->getReturnType()) ||
2058 !isa<PointerType>(FTy->getParamType(0)))
2059 continue;
2060 setDoesNotThrow(F);
2061 setDoesNotAlias(F, 0);
2062 setDoesNotCapture(F, 1);
2063 } else if (NameLen == 10 && !strcmp(NameStr, "__strtok_r")) {
2064 if (FTy->getNumParams() != 3 ||
2065 !isa<PointerType>(FTy->getParamType(1)))
2066 continue;
2067 setDoesNotThrow(F);
2068 setDoesNotCapture(F, 2);
2069 } else if (NameLen == 8 && !strcmp(NameStr, "_IO_getc")) {
2070 if (FTy->getNumParams() != 1 ||
2071 !isa<PointerType>(FTy->getParamType(0)))
2072 continue;
2073 setDoesNotThrow(F);
2074 setDoesNotCapture(F, 1);
2075 } else if (NameLen == 8 && !strcmp(NameStr, "_IO_putc")) {
2076 if (FTy->getNumParams() != 2 ||
2077 !isa<PointerType>(FTy->getParamType(1)))
2078 continue;
2079 setDoesNotThrow(F);
2080 setDoesNotCapture(F, 2);
2081 }
2082 case 1:
2083 if (NameLen == 15 && !strcmp(NameStr, "\1__isoc99_scanf")) {
2084 if (FTy->getNumParams() < 1 ||
2085 !isa<PointerType>(FTy->getParamType(0)))
2086 continue;
2087 setDoesNotThrow(F);
2088 setDoesNotCapture(F, 1);
2089 } else if (NameLen == 16 && !strcmp(NameStr, "\1__isoc99_sscanf")) {
2090 if (FTy->getNumParams() < 1 ||
2091 !isa<PointerType>(FTy->getParamType(0)))
2092 continue;
2093 setDoesNotThrow(F);
2094 setDoesNotCapture(F, 1);
2095 setDoesNotCapture(F, 2);
2096 }
Nick Lewycky0f8df9a2009-01-04 20:27:34 +00002097 break;
2098 }
2099 }
2100 return Modified;
2101}
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00002102
2103// TODO:
2104// Additional cases that we need to add to this file:
2105//
2106// cbrt:
2107// * cbrt(expN(X)) -> expN(x/3)
2108// * cbrt(sqrt(x)) -> pow(x,1/6)
2109// * cbrt(sqrt(x)) -> pow(x,1/9)
2110//
2111// cos, cosf, cosl:
2112// * cos(-x) -> cos(x)
2113//
2114// exp, expf, expl:
2115// * exp(log(x)) -> x
2116//
2117// log, logf, logl:
2118// * log(exp(x)) -> x
2119// * log(x**y) -> y*log(x)
2120// * log(exp(y)) -> y*log(e)
2121// * log(exp2(y)) -> y*log(2)
2122// * log(exp10(y)) -> y*log(10)
2123// * log(sqrt(x)) -> 0.5*log(x)
2124// * log(pow(x,y)) -> y*log(x)
2125//
2126// lround, lroundf, lroundl:
2127// * lround(cnst) -> cnst'
2128//
2129// memcmp:
2130// * memcmp(x,y,l) -> cnst
2131// (if all arguments are constant and strlen(x) <= l and strlen(y) <= l)
2132//
Chris Lattnerfd1cbbe2008-05-01 06:25:24 +00002133// pow, powf, powl:
2134// * pow(exp(x),y) -> exp(x*y)
2135// * pow(sqrt(x),y) -> pow(x,y*0.5)
2136// * pow(pow(x,y),z)-> pow(x,y*z)
2137//
2138// puts:
2139// * puts("") -> putchar("\n")
2140//
2141// round, roundf, roundl:
2142// * round(cnst) -> cnst'
2143//
2144// signbit:
2145// * signbit(cnst) -> cnst'
2146// * signbit(nncst) -> 0 (if pstv is a non-negative constant)
2147//
2148// sqrt, sqrtf, sqrtl:
2149// * sqrt(expN(x)) -> expN(x*0.5)
2150// * sqrt(Nroot(x)) -> pow(x,1/(2*N))
2151// * sqrt(pow(x,y)) -> pow(|x|,y*0.5)
2152//
2153// stpcpy:
2154// * stpcpy(str, "literal") ->
2155// llvm.memcpy(str,"literal",strlen("literal")+1,1)
2156// strrchr:
2157// * strrchr(s,c) -> reverse_offset_of_in(c,s)
2158// (if c is a constant integer and s is a constant string)
2159// * strrchr(s1,0) -> strchr(s1,0)
2160//
2161// strncat:
2162// * strncat(x,y,0) -> x
2163// * strncat(x,y,0) -> x (if strlen(y) = 0)
2164// * strncat(x,y,l) -> strcat(x,y) (if y and l are constants an l > strlen(y))
2165//
2166// strncpy:
2167// * strncpy(d,s,0) -> d
2168// * strncpy(d,s,l) -> memcpy(d,s,l,1)
2169// (if s and l are constants)
2170//
2171// strpbrk:
2172// * strpbrk(s,a) -> offset_in_for(s,a)
2173// (if s and a are both constant strings)
2174// * strpbrk(s,"") -> 0
2175// * strpbrk(s,a) -> strchr(s,a[0]) (if a is constant string of length 1)
2176//
2177// strspn, strcspn:
2178// * strspn(s,a) -> const_int (if both args are constant)
2179// * strspn("",a) -> 0
2180// * strspn(s,"") -> 0
2181// * strcspn(s,a) -> const_int (if both args are constant)
2182// * strcspn("",a) -> 0
2183// * strcspn(s,"") -> strlen(a)
2184//
2185// strstr:
2186// * strstr(x,x) -> x
2187// * strstr(s1,s2) -> offset_of_s2_in(s1)
2188// (if s1 and s2 are constant strings)
2189//
2190// tan, tanf, tanl:
2191// * tan(atan(x)) -> x
2192//
2193// trunc, truncf, truncl:
2194// * trunc(cnst) -> cnst'
2195//
2196//