1 //===- SimplifyLibCalls.cpp - Optimize specific well-known library calls --===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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). Any optimization that takes the very simple form
13 // "replace call to library function with simpler code that provides the same
14 // result" belongs in this file.
16 //===----------------------------------------------------------------------===//
18 #define DEBUG_TYPE "simplify-libcalls"
19 #include "llvm/Transforms/Scalar.h"
20 #include "llvm/Transforms/Utils/BuildLibCalls.h"
21 #include "llvm/IRBuilder.h"
22 #include "llvm/LLVMContext.h"
23 #include "llvm/Module.h"
24 #include "llvm/Pass.h"
25 #include "llvm/ADT/STLExtras.h"
26 #include "llvm/ADT/SmallPtrSet.h"
27 #include "llvm/ADT/Statistic.h"
28 #include "llvm/ADT/StringMap.h"
29 #include "llvm/Analysis/ValueTracking.h"
30 #include "llvm/Support/CommandLine.h"
31 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/raw_ostream.h"
33 #include "llvm/DataLayout.h"
34 #include "llvm/Target/TargetLibraryInfo.h"
35 #include "llvm/Config/config.h" // FIXME: Shouldn't depend on host!
38 STATISTIC(NumSimplified, "Number of library calls simplified");
39 STATISTIC(NumAnnotated, "Number of attributes added to library functions");
41 //===----------------------------------------------------------------------===//
42 // Optimizer Base Class
43 //===----------------------------------------------------------------------===//
45 /// This class is the abstract base class for the set of optimizations that
46 /// corresponds to one library call.
48 class LibCallOptimization {
52 const TargetLibraryInfo *TLI;
55 LibCallOptimization() { }
56 virtual ~LibCallOptimization() {}
58 /// CallOptimizer - This pure virtual method is implemented by base classes to
59 /// do various optimizations. If this returns null then no transformation was
60 /// performed. If it returns CI, then it transformed the call and CI is to be
61 /// deleted. If it returns something else, replace CI with the new value and
63 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)
66 Value *OptimizeCall(CallInst *CI, const DataLayout *TD,
67 const TargetLibraryInfo *TLI, IRBuilder<> &B) {
68 Caller = CI->getParent()->getParent();
71 if (CI->getCalledFunction())
72 Context = &CI->getCalledFunction()->getContext();
74 // We never change the calling convention.
75 if (CI->getCallingConv() != llvm::CallingConv::C)
78 return CallOptimizer(CI->getCalledFunction(), CI, B);
81 } // End anonymous namespace.
85 //===----------------------------------------------------------------------===//
86 // Formatting and IO Optimizations
87 //===----------------------------------------------------------------------===//
89 //===---------------------------------------===//
90 // 'fputs' Optimizations
92 struct FPutsOpt : public LibCallOptimization {
93 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
94 // These optimizations require DataLayout.
97 // Require two pointers. Also, we can't optimize if return value is used.
98 FunctionType *FT = Callee->getFunctionType();
99 if (FT->getNumParams() != 2 || !FT->getParamType(0)->isPointerTy() ||
100 !FT->getParamType(1)->isPointerTy() ||
104 // fputs(s,F) --> fwrite(s,1,strlen(s),F)
105 uint64_t Len = GetStringLength(CI->getArgOperand(0));
107 // Known to have no uses (see above).
108 return EmitFWrite(CI->getArgOperand(0),
109 ConstantInt::get(TD->getIntPtrType(*Context), Len-1),
110 CI->getArgOperand(1), B, TD, TLI);
114 //===---------------------------------------===//
115 // 'puts' Optimizations
117 struct PutsOpt : public LibCallOptimization {
118 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B) {
119 // Require one fixed pointer argument and an integer/void result.
120 FunctionType *FT = Callee->getFunctionType();
121 if (FT->getNumParams() < 1 || !FT->getParamType(0)->isPointerTy() ||
122 !(FT->getReturnType()->isIntegerTy() ||
123 FT->getReturnType()->isVoidTy()))
126 // Check for a constant string.
128 if (!getConstantStringInfo(CI->getArgOperand(0), Str))
131 if (Str.empty() && CI->use_empty()) {
132 // puts("") -> putchar('\n')
133 Value *Res = EmitPutChar(B.getInt32('\n'), B, TD, TLI);
134 if (CI->use_empty() || !Res) return Res;
135 return B.CreateIntCast(Res, CI->getType(), true);
142 } // end anonymous namespace.
144 //===----------------------------------------------------------------------===//
145 // SimplifyLibCalls Pass Implementation
146 //===----------------------------------------------------------------------===//
149 /// This pass optimizes well known library functions from libc and libm.
151 class SimplifyLibCalls : public FunctionPass {
152 TargetLibraryInfo *TLI;
154 StringMap<LibCallOptimization*> Optimizations;
155 // Formatting and IO Optimizations
159 bool Modified; // This is only used by doInitialization.
161 static char ID; // Pass identification
162 SimplifyLibCalls() : FunctionPass(ID) {
163 initializeSimplifyLibCallsPass(*PassRegistry::getPassRegistry());
165 void AddOpt(LibFunc::Func F, LibCallOptimization* Opt);
166 void AddOpt(LibFunc::Func F1, LibFunc::Func F2, LibCallOptimization* Opt);
168 void InitOptimizations();
169 bool runOnFunction(Function &F);
171 void setDoesNotAccessMemory(Function &F);
172 void setOnlyReadsMemory(Function &F);
173 void setDoesNotThrow(Function &F);
174 void setDoesNotCapture(Function &F, unsigned n);
175 void setDoesNotAlias(Function &F, unsigned n);
176 bool doInitialization(Module &M);
178 void inferPrototypeAttributes(Function &F);
179 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
180 AU.addRequired<TargetLibraryInfo>();
183 } // end anonymous namespace.
185 char SimplifyLibCalls::ID = 0;
187 INITIALIZE_PASS_BEGIN(SimplifyLibCalls, "simplify-libcalls",
188 "Simplify well-known library calls", false, false)
189 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)
190 INITIALIZE_PASS_END(SimplifyLibCalls, "simplify-libcalls",
191 "Simplify well-known library calls", false, false)
193 // Public interface to the Simplify LibCalls pass.
194 FunctionPass *llvm::createSimplifyLibCallsPass() {
195 return new SimplifyLibCalls();
198 void SimplifyLibCalls::AddOpt(LibFunc::Func F, LibCallOptimization* Opt) {
200 Optimizations[TLI->getName(F)] = Opt;
203 void SimplifyLibCalls::AddOpt(LibFunc::Func F1, LibFunc::Func F2,
204 LibCallOptimization* Opt) {
205 if (TLI->has(F1) && TLI->has(F2))
206 Optimizations[TLI->getName(F1)] = Opt;
209 /// Optimizations - Populate the Optimizations map with all the optimizations
211 void SimplifyLibCalls::InitOptimizations() {
212 // Formatting and IO Optimizations
213 AddOpt(LibFunc::fputs, &FPuts);
214 Optimizations["puts"] = &Puts;
218 /// runOnFunction - Top level algorithm.
220 bool SimplifyLibCalls::runOnFunction(Function &F) {
221 TLI = &getAnalysis<TargetLibraryInfo>();
223 if (Optimizations.empty())
226 const DataLayout *TD = getAnalysisIfAvailable<DataLayout>();
228 IRBuilder<> Builder(F.getContext());
230 bool Changed = false;
231 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
232 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
234 CallInst *CI = dyn_cast<CallInst>(I++);
237 // Ignore indirect calls and calls to non-external functions.
238 Function *Callee = CI->getCalledFunction();
239 if (Callee == 0 || !Callee->isDeclaration() ||
240 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage()))
243 // Ignore unknown calls.
244 LibCallOptimization *LCO = Optimizations.lookup(Callee->getName());
247 // Set the builder to the instruction after the call.
248 Builder.SetInsertPoint(BB, I);
250 // Use debug location of CI for all new instructions.
251 Builder.SetCurrentDebugLocation(CI->getDebugLoc());
253 // Try to optimize this call.
254 Value *Result = LCO->OptimizeCall(CI, TD, TLI, Builder);
255 if (Result == 0) continue;
257 DEBUG(dbgs() << "SimplifyLibCalls simplified: " << *CI;
258 dbgs() << " into: " << *Result << "\n");
260 // Something changed!
264 // Inspect the instruction after the call (which was potentially just
268 if (CI != Result && !CI->use_empty()) {
269 CI->replaceAllUsesWith(Result);
270 if (!Result->hasName())
271 Result->takeName(CI);
273 CI->eraseFromParent();
279 // Utility methods for doInitialization.
281 void SimplifyLibCalls::setDoesNotAccessMemory(Function &F) {
282 if (!F.doesNotAccessMemory()) {
283 F.setDoesNotAccessMemory();
288 void SimplifyLibCalls::setOnlyReadsMemory(Function &F) {
289 if (!F.onlyReadsMemory()) {
290 F.setOnlyReadsMemory();
295 void SimplifyLibCalls::setDoesNotThrow(Function &F) {
296 if (!F.doesNotThrow()) {
302 void SimplifyLibCalls::setDoesNotCapture(Function &F, unsigned n) {
303 if (!F.doesNotCapture(n)) {
304 F.setDoesNotCapture(n);
309 void SimplifyLibCalls::setDoesNotAlias(Function &F, unsigned n) {
310 if (!F.doesNotAlias(n)) {
311 F.setDoesNotAlias(n);
318 void SimplifyLibCalls::inferPrototypeAttributes(Function &F) {
319 FunctionType *FTy = F.getFunctionType();
321 StringRef Name = F.getName();
324 if (Name == "strlen") {
325 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
327 setOnlyReadsMemory(F);
329 setDoesNotCapture(F, 1);
330 } else if (Name == "strchr" ||
332 if (FTy->getNumParams() != 2 ||
333 !FTy->getParamType(0)->isPointerTy() ||
334 !FTy->getParamType(1)->isIntegerTy())
336 setOnlyReadsMemory(F);
338 } else if (Name == "strcpy" ||
350 Name == "strtoull") {
351 if (FTy->getNumParams() < 2 ||
352 !FTy->getParamType(1)->isPointerTy())
355 setDoesNotCapture(F, 2);
356 } else if (Name == "strxfrm") {
357 if (FTy->getNumParams() != 3 ||
358 !FTy->getParamType(0)->isPointerTy() ||
359 !FTy->getParamType(1)->isPointerTy())
362 setDoesNotCapture(F, 1);
363 setDoesNotCapture(F, 2);
364 } else if (Name == "strcmp" ||
369 Name == "strcasecmp" ||
370 Name == "strncasecmp") {
371 if (FTy->getNumParams() < 2 ||
372 !FTy->getParamType(0)->isPointerTy() ||
373 !FTy->getParamType(1)->isPointerTy())
375 setOnlyReadsMemory(F);
377 setDoesNotCapture(F, 1);
378 setDoesNotCapture(F, 2);
379 } else if (Name == "strstr" ||
381 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
383 setOnlyReadsMemory(F);
385 setDoesNotCapture(F, 2);
386 } else if (Name == "strtok" ||
387 Name == "strtok_r") {
388 if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
391 setDoesNotCapture(F, 2);
392 } else if (Name == "scanf" ||
395 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
398 setDoesNotCapture(F, 1);
399 } else if (Name == "strdup" ||
401 if (FTy->getNumParams() < 1 || !FTy->getReturnType()->isPointerTy() ||
402 !FTy->getParamType(0)->isPointerTy())
405 setDoesNotAlias(F, 0);
406 setDoesNotCapture(F, 1);
407 } else if (Name == "stat" ||
411 if (FTy->getNumParams() < 2 ||
412 !FTy->getParamType(0)->isPointerTy() ||
413 !FTy->getParamType(1)->isPointerTy())
416 setDoesNotCapture(F, 1);
417 setDoesNotCapture(F, 2);
418 } else if (Name == "snprintf") {
419 if (FTy->getNumParams() != 3 ||
420 !FTy->getParamType(0)->isPointerTy() ||
421 !FTy->getParamType(2)->isPointerTy())
424 setDoesNotCapture(F, 1);
425 setDoesNotCapture(F, 3);
426 } else if (Name == "setitimer") {
427 if (FTy->getNumParams() != 3 ||
428 !FTy->getParamType(1)->isPointerTy() ||
429 !FTy->getParamType(2)->isPointerTy())
432 setDoesNotCapture(F, 2);
433 setDoesNotCapture(F, 3);
434 } else if (Name == "system") {
435 if (FTy->getNumParams() != 1 ||
436 !FTy->getParamType(0)->isPointerTy())
438 // May throw; "system" is a valid pthread cancellation point.
439 setDoesNotCapture(F, 1);
443 if (Name == "malloc") {
444 if (FTy->getNumParams() != 1 ||
445 !FTy->getReturnType()->isPointerTy())
448 setDoesNotAlias(F, 0);
449 } else if (Name == "memcmp") {
450 if (FTy->getNumParams() != 3 ||
451 !FTy->getParamType(0)->isPointerTy() ||
452 !FTy->getParamType(1)->isPointerTy())
454 setOnlyReadsMemory(F);
456 setDoesNotCapture(F, 1);
457 setDoesNotCapture(F, 2);
458 } else if (Name == "memchr" ||
460 if (FTy->getNumParams() != 3)
462 setOnlyReadsMemory(F);
464 } else if (Name == "modf" ||
470 if (FTy->getNumParams() < 2 ||
471 !FTy->getParamType(1)->isPointerTy())
474 setDoesNotCapture(F, 2);
475 } else if (Name == "memalign") {
476 if (!FTy->getReturnType()->isPointerTy())
478 setDoesNotAlias(F, 0);
479 } else if (Name == "mkdir" ||
481 if (FTy->getNumParams() == 0 ||
482 !FTy->getParamType(0)->isPointerTy())
485 setDoesNotCapture(F, 1);
489 if (Name == "realloc") {
490 if (FTy->getNumParams() != 2 ||
491 !FTy->getParamType(0)->isPointerTy() ||
492 !FTy->getReturnType()->isPointerTy())
495 setDoesNotAlias(F, 0);
496 setDoesNotCapture(F, 1);
497 } else if (Name == "read") {
498 if (FTy->getNumParams() != 3 ||
499 !FTy->getParamType(1)->isPointerTy())
501 // May throw; "read" is a valid pthread cancellation point.
502 setDoesNotCapture(F, 2);
503 } else if (Name == "rmdir" ||
506 Name == "realpath") {
507 if (FTy->getNumParams() < 1 ||
508 !FTy->getParamType(0)->isPointerTy())
511 setDoesNotCapture(F, 1);
512 } else if (Name == "rename" ||
513 Name == "readlink") {
514 if (FTy->getNumParams() < 2 ||
515 !FTy->getParamType(0)->isPointerTy() ||
516 !FTy->getParamType(1)->isPointerTy())
519 setDoesNotCapture(F, 1);
520 setDoesNotCapture(F, 2);
524 if (Name == "write") {
525 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy())
527 // May throw; "write" is a valid pthread cancellation point.
528 setDoesNotCapture(F, 2);
532 if (Name == "bcopy") {
533 if (FTy->getNumParams() != 3 ||
534 !FTy->getParamType(0)->isPointerTy() ||
535 !FTy->getParamType(1)->isPointerTy())
538 setDoesNotCapture(F, 1);
539 setDoesNotCapture(F, 2);
540 } else if (Name == "bcmp") {
541 if (FTy->getNumParams() != 3 ||
542 !FTy->getParamType(0)->isPointerTy() ||
543 !FTy->getParamType(1)->isPointerTy())
546 setOnlyReadsMemory(F);
547 setDoesNotCapture(F, 1);
548 setDoesNotCapture(F, 2);
549 } else if (Name == "bzero") {
550 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
553 setDoesNotCapture(F, 1);
557 if (Name == "calloc") {
558 if (FTy->getNumParams() != 2 ||
559 !FTy->getReturnType()->isPointerTy())
562 setDoesNotAlias(F, 0);
563 } else if (Name == "chmod" ||
566 Name == "clearerr" ||
567 Name == "closedir") {
568 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
571 setDoesNotCapture(F, 1);
575 if (Name == "atoi" ||
579 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
582 setOnlyReadsMemory(F);
583 setDoesNotCapture(F, 1);
584 } else if (Name == "access") {
585 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
588 setDoesNotCapture(F, 1);
592 if (Name == "fopen") {
593 if (FTy->getNumParams() != 2 ||
594 !FTy->getReturnType()->isPointerTy() ||
595 !FTy->getParamType(0)->isPointerTy() ||
596 !FTy->getParamType(1)->isPointerTy())
599 setDoesNotAlias(F, 0);
600 setDoesNotCapture(F, 1);
601 setDoesNotCapture(F, 2);
602 } else if (Name == "fdopen") {
603 if (FTy->getNumParams() != 2 ||
604 !FTy->getReturnType()->isPointerTy() ||
605 !FTy->getParamType(1)->isPointerTy())
608 setDoesNotAlias(F, 0);
609 setDoesNotCapture(F, 2);
610 } else if (Name == "feof" ||
621 Name == "flockfile" ||
622 Name == "funlockfile" ||
623 Name == "ftrylockfile") {
624 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
627 setDoesNotCapture(F, 1);
628 } else if (Name == "ferror") {
629 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
632 setDoesNotCapture(F, 1);
633 setOnlyReadsMemory(F);
634 } else if (Name == "fputc" ||
639 Name == "fstatvfs") {
640 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
643 setDoesNotCapture(F, 2);
644 } else if (Name == "fgets") {
645 if (FTy->getNumParams() != 3 ||
646 !FTy->getParamType(0)->isPointerTy() ||
647 !FTy->getParamType(2)->isPointerTy())
650 setDoesNotCapture(F, 3);
651 } else if (Name == "fread" ||
653 if (FTy->getNumParams() != 4 ||
654 !FTy->getParamType(0)->isPointerTy() ||
655 !FTy->getParamType(3)->isPointerTy())
658 setDoesNotCapture(F, 1);
659 setDoesNotCapture(F, 4);
660 } else if (Name == "fputs" ||
664 if (FTy->getNumParams() < 2 ||
665 !FTy->getParamType(0)->isPointerTy() ||
666 !FTy->getParamType(1)->isPointerTy())
669 setDoesNotCapture(F, 1);
670 setDoesNotCapture(F, 2);
674 if (Name == "getc" ||
675 Name == "getlogin_r" ||
676 Name == "getc_unlocked") {
677 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
680 setDoesNotCapture(F, 1);
681 } else if (Name == "getenv") {
682 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
685 setOnlyReadsMemory(F);
686 setDoesNotCapture(F, 1);
687 } else if (Name == "gets" ||
690 } else if (Name == "getitimer") {
691 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
694 setDoesNotCapture(F, 2);
695 } else if (Name == "getpwnam") {
696 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
699 setDoesNotCapture(F, 1);
703 if (Name == "ungetc") {
704 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
707 setDoesNotCapture(F, 2);
708 } else if (Name == "uname" ||
710 Name == "unsetenv") {
711 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
714 setDoesNotCapture(F, 1);
715 } else if (Name == "utime" ||
717 if (FTy->getNumParams() != 2 ||
718 !FTy->getParamType(0)->isPointerTy() ||
719 !FTy->getParamType(1)->isPointerTy())
722 setDoesNotCapture(F, 1);
723 setDoesNotCapture(F, 2);
727 if (Name == "putc") {
728 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
731 setDoesNotCapture(F, 2);
732 } else if (Name == "puts" ||
735 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
738 setDoesNotCapture(F, 1);
739 } else if (Name == "pread" ||
741 if (FTy->getNumParams() != 4 || !FTy->getParamType(1)->isPointerTy())
743 // May throw; these are valid pthread cancellation points.
744 setDoesNotCapture(F, 2);
745 } else if (Name == "putchar") {
747 } else if (Name == "popen") {
748 if (FTy->getNumParams() != 2 ||
749 !FTy->getReturnType()->isPointerTy() ||
750 !FTy->getParamType(0)->isPointerTy() ||
751 !FTy->getParamType(1)->isPointerTy())
754 setDoesNotAlias(F, 0);
755 setDoesNotCapture(F, 1);
756 setDoesNotCapture(F, 2);
757 } else if (Name == "pclose") {
758 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
761 setDoesNotCapture(F, 1);
765 if (Name == "vscanf") {
766 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
769 setDoesNotCapture(F, 1);
770 } else if (Name == "vsscanf" ||
772 if (FTy->getNumParams() != 3 ||
773 !FTy->getParamType(1)->isPointerTy() ||
774 !FTy->getParamType(2)->isPointerTy())
777 setDoesNotCapture(F, 1);
778 setDoesNotCapture(F, 2);
779 } else if (Name == "valloc") {
780 if (!FTy->getReturnType()->isPointerTy())
783 setDoesNotAlias(F, 0);
784 } else if (Name == "vprintf") {
785 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
788 setDoesNotCapture(F, 1);
789 } else if (Name == "vfprintf" ||
790 Name == "vsprintf") {
791 if (FTy->getNumParams() != 3 ||
792 !FTy->getParamType(0)->isPointerTy() ||
793 !FTy->getParamType(1)->isPointerTy())
796 setDoesNotCapture(F, 1);
797 setDoesNotCapture(F, 2);
798 } else if (Name == "vsnprintf") {
799 if (FTy->getNumParams() != 4 ||
800 !FTy->getParamType(0)->isPointerTy() ||
801 !FTy->getParamType(2)->isPointerTy())
804 setDoesNotCapture(F, 1);
805 setDoesNotCapture(F, 3);
809 if (Name == "open") {
810 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy())
812 // May throw; "open" is a valid pthread cancellation point.
813 setDoesNotCapture(F, 1);
814 } else if (Name == "opendir") {
815 if (FTy->getNumParams() != 1 ||
816 !FTy->getReturnType()->isPointerTy() ||
817 !FTy->getParamType(0)->isPointerTy())
820 setDoesNotAlias(F, 0);
821 setDoesNotCapture(F, 1);
825 if (Name == "tmpfile") {
826 if (!FTy->getReturnType()->isPointerTy())
829 setDoesNotAlias(F, 0);
830 } else if (Name == "times") {
831 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
834 setDoesNotCapture(F, 1);
838 if (Name == "htonl" ||
841 setDoesNotAccessMemory(F);
845 if (Name == "ntohl" ||
848 setDoesNotAccessMemory(F);
852 if (Name == "lstat") {
853 if (FTy->getNumParams() != 2 ||
854 !FTy->getParamType(0)->isPointerTy() ||
855 !FTy->getParamType(1)->isPointerTy())
858 setDoesNotCapture(F, 1);
859 setDoesNotCapture(F, 2);
860 } else if (Name == "lchown") {
861 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy())
864 setDoesNotCapture(F, 1);
868 if (Name == "qsort") {
869 if (FTy->getNumParams() != 4 || !FTy->getParamType(3)->isPointerTy())
871 // May throw; places call through function pointer.
872 setDoesNotCapture(F, 4);
876 if (Name == "__strdup" ||
877 Name == "__strndup") {
878 if (FTy->getNumParams() < 1 ||
879 !FTy->getReturnType()->isPointerTy() ||
880 !FTy->getParamType(0)->isPointerTy())
883 setDoesNotAlias(F, 0);
884 setDoesNotCapture(F, 1);
885 } else if (Name == "__strtok_r") {
886 if (FTy->getNumParams() != 3 ||
887 !FTy->getParamType(1)->isPointerTy())
890 setDoesNotCapture(F, 2);
891 } else if (Name == "_IO_getc") {
892 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
895 setDoesNotCapture(F, 1);
896 } else if (Name == "_IO_putc") {
897 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
900 setDoesNotCapture(F, 2);
904 if (Name == "\1__isoc99_scanf") {
905 if (FTy->getNumParams() < 1 ||
906 !FTy->getParamType(0)->isPointerTy())
909 setDoesNotCapture(F, 1);
910 } else if (Name == "\1stat64" ||
911 Name == "\1lstat64" ||
912 Name == "\1statvfs64" ||
913 Name == "\1__isoc99_sscanf") {
914 if (FTy->getNumParams() < 1 ||
915 !FTy->getParamType(0)->isPointerTy() ||
916 !FTy->getParamType(1)->isPointerTy())
919 setDoesNotCapture(F, 1);
920 setDoesNotCapture(F, 2);
921 } else if (Name == "\1fopen64") {
922 if (FTy->getNumParams() != 2 ||
923 !FTy->getReturnType()->isPointerTy() ||
924 !FTy->getParamType(0)->isPointerTy() ||
925 !FTy->getParamType(1)->isPointerTy())
928 setDoesNotAlias(F, 0);
929 setDoesNotCapture(F, 1);
930 setDoesNotCapture(F, 2);
931 } else if (Name == "\1fseeko64" ||
932 Name == "\1ftello64") {
933 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
936 setDoesNotCapture(F, 1);
937 } else if (Name == "\1tmpfile64") {
938 if (!FTy->getReturnType()->isPointerTy())
941 setDoesNotAlias(F, 0);
942 } else if (Name == "\1fstat64" ||
943 Name == "\1fstatvfs64") {
944 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
947 setDoesNotCapture(F, 2);
948 } else if (Name == "\1open64") {
949 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy())
951 // May throw; "open" is a valid pthread cancellation point.
952 setDoesNotCapture(F, 1);
958 /// doInitialization - Add attributes to well-known functions.
960 bool SimplifyLibCalls::doInitialization(Module &M) {
962 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
964 if (F.isDeclaration() && F.hasName())
965 inferPrototypeAttributes(F);
971 // Additional cases that we need to add to this file:
974 // * cbrt(expN(X)) -> expN(x/3)
975 // * cbrt(sqrt(x)) -> pow(x,1/6)
976 // * cbrt(sqrt(x)) -> pow(x,1/9)
979 // * exp(log(x)) -> x
982 // * log(exp(x)) -> x
983 // * log(x**y) -> y*log(x)
984 // * log(exp(y)) -> y*log(e)
985 // * log(exp2(y)) -> y*log(2)
986 // * log(exp10(y)) -> y*log(10)
987 // * log(sqrt(x)) -> 0.5*log(x)
988 // * log(pow(x,y)) -> y*log(x)
990 // lround, lroundf, lroundl:
991 // * lround(cnst) -> cnst'
994 // * pow(exp(x),y) -> exp(x*y)
995 // * pow(sqrt(x),y) -> pow(x,y*0.5)
996 // * pow(pow(x,y),z)-> pow(x,y*z)
998 // round, roundf, roundl:
999 // * round(cnst) -> cnst'
1002 // * signbit(cnst) -> cnst'
1003 // * signbit(nncst) -> 0 (if pstv is a non-negative constant)
1005 // sqrt, sqrtf, sqrtl:
1006 // * sqrt(expN(x)) -> expN(x*0.5)
1007 // * sqrt(Nroot(x)) -> pow(x,1/(2*N))
1008 // * sqrt(pow(x,y)) -> pow(|x|,y*0.5)
1011 // * strchr(p, 0) -> strlen(p)
1013 // * tan(atan(x)) -> x
1015 // trunc, truncf, truncl:
1016 // * trunc(cnst) -> cnst'