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/ADT/STLExtras.h"
21 #include "llvm/ADT/SmallPtrSet.h"
22 #include "llvm/ADT/Statistic.h"
23 #include "llvm/ADT/StringMap.h"
24 #include "llvm/Analysis/ValueTracking.h"
25 #include "llvm/Config/config.h" // FIXME: Shouldn't depend on host!
26 #include "llvm/DataLayout.h"
27 #include "llvm/IRBuilder.h"
28 #include "llvm/LLVMContext.h"
29 #include "llvm/Module.h"
30 #include "llvm/Pass.h"
31 #include "llvm/Support/CommandLine.h"
32 #include "llvm/Support/Debug.h"
33 #include "llvm/Support/raw_ostream.h"
34 #include "llvm/Target/TargetLibraryInfo.h"
35 #include "llvm/Transforms/Utils/BuildLibCalls.h"
38 STATISTIC(NumAnnotated, "Number of attributes added to library functions");
40 //===----------------------------------------------------------------------===//
41 // Optimizer Base Class
42 //===----------------------------------------------------------------------===//
44 /// This class is the abstract base class for the set of optimizations that
45 /// corresponds to one library call.
47 class LibCallOptimization {
51 const TargetLibraryInfo *TLI;
54 LibCallOptimization() { }
55 virtual ~LibCallOptimization() {}
57 /// CallOptimizer - This pure virtual method is implemented by base classes to
58 /// do various optimizations. If this returns null then no transformation was
59 /// performed. If it returns CI, then it transformed the call and CI is to be
60 /// deleted. If it returns something else, replace CI with the new value and
62 virtual Value *CallOptimizer(Function *Callee, CallInst *CI, IRBuilder<> &B)
65 Value *OptimizeCall(CallInst *CI, const DataLayout *TD,
66 const TargetLibraryInfo *TLI, IRBuilder<> &B) {
67 Caller = CI->getParent()->getParent();
70 if (CI->getCalledFunction())
71 Context = &CI->getCalledFunction()->getContext();
73 // We never change the calling convention.
74 if (CI->getCallingConv() != llvm::CallingConv::C)
77 return CallOptimizer(CI->getCalledFunction(), CI, B);
80 } // End anonymous namespace.
83 //===----------------------------------------------------------------------===//
84 // SimplifyLibCalls Pass Implementation
85 //===----------------------------------------------------------------------===//
88 /// This pass optimizes well known library functions from libc and libm.
90 class SimplifyLibCalls : public FunctionPass {
91 TargetLibraryInfo *TLI;
93 StringMap<LibCallOptimization*> Optimizations;
95 bool Modified; // This is only used by doInitialization.
97 static char ID; // Pass identification
98 SimplifyLibCalls() : FunctionPass(ID) {
99 initializeSimplifyLibCallsPass(*PassRegistry::getPassRegistry());
101 void AddOpt(LibFunc::Func F, LibCallOptimization* Opt);
102 void AddOpt(LibFunc::Func F1, LibFunc::Func F2, LibCallOptimization* Opt);
104 void InitOptimizations();
105 bool runOnFunction(Function &F);
107 void setDoesNotAccessMemory(Function &F);
108 void setOnlyReadsMemory(Function &F);
109 void setDoesNotThrow(Function &F);
110 void setDoesNotCapture(Function &F, unsigned n);
111 void setDoesNotAlias(Function &F, unsigned n);
112 bool doInitialization(Module &M);
114 void inferPrototypeAttributes(Function &F);
115 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
116 AU.addRequired<TargetLibraryInfo>();
119 } // end anonymous namespace.
121 char SimplifyLibCalls::ID = 0;
123 INITIALIZE_PASS_BEGIN(SimplifyLibCalls, "simplify-libcalls",
124 "Simplify well-known library calls", false, false)
125 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)
126 INITIALIZE_PASS_END(SimplifyLibCalls, "simplify-libcalls",
127 "Simplify well-known library calls", false, false)
129 // Public interface to the Simplify LibCalls pass.
130 FunctionPass *llvm::createSimplifyLibCallsPass() {
131 return new SimplifyLibCalls();
134 void SimplifyLibCalls::AddOpt(LibFunc::Func F, LibCallOptimization* Opt) {
136 Optimizations[TLI->getName(F)] = Opt;
139 void SimplifyLibCalls::AddOpt(LibFunc::Func F1, LibFunc::Func F2,
140 LibCallOptimization* Opt) {
141 if (TLI->has(F1) && TLI->has(F2))
142 Optimizations[TLI->getName(F1)] = Opt;
145 /// Optimizations - Populate the Optimizations map with all the optimizations
147 void SimplifyLibCalls::InitOptimizations() {
151 /// runOnFunction - Top level algorithm.
153 bool SimplifyLibCalls::runOnFunction(Function &F) {
154 TLI = &getAnalysis<TargetLibraryInfo>();
156 if (Optimizations.empty())
159 const DataLayout *TD = getAnalysisIfAvailable<DataLayout>();
161 IRBuilder<> Builder(F.getContext());
163 bool Changed = false;
164 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
165 for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
167 CallInst *CI = dyn_cast<CallInst>(I++);
170 // Ignore indirect calls and calls to non-external functions.
171 Function *Callee = CI->getCalledFunction();
172 if (Callee == 0 || !Callee->isDeclaration() ||
173 !(Callee->hasExternalLinkage() || Callee->hasDLLImportLinkage()))
176 // Ignore unknown calls.
177 LibCallOptimization *LCO = Optimizations.lookup(Callee->getName());
180 // Set the builder to the instruction after the call.
181 Builder.SetInsertPoint(BB, I);
183 // Use debug location of CI for all new instructions.
184 Builder.SetCurrentDebugLocation(CI->getDebugLoc());
186 // Try to optimize this call.
187 Value *Result = LCO->OptimizeCall(CI, TD, TLI, Builder);
188 if (Result == 0) continue;
190 DEBUG(dbgs() << "SimplifyLibCalls simplified: " << *CI;
191 dbgs() << " into: " << *Result << "\n");
193 // Something changed!
196 // Inspect the instruction after the call (which was potentially just
200 if (CI != Result && !CI->use_empty()) {
201 CI->replaceAllUsesWith(Result);
202 if (!Result->hasName())
203 Result->takeName(CI);
205 CI->eraseFromParent();
211 // Utility methods for doInitialization.
213 void SimplifyLibCalls::setDoesNotAccessMemory(Function &F) {
214 if (!F.doesNotAccessMemory()) {
215 F.setDoesNotAccessMemory();
220 void SimplifyLibCalls::setOnlyReadsMemory(Function &F) {
221 if (!F.onlyReadsMemory()) {
222 F.setOnlyReadsMemory();
227 void SimplifyLibCalls::setDoesNotThrow(Function &F) {
228 if (!F.doesNotThrow()) {
234 void SimplifyLibCalls::setDoesNotCapture(Function &F, unsigned n) {
235 if (!F.doesNotCapture(n)) {
236 F.setDoesNotCapture(n);
241 void SimplifyLibCalls::setDoesNotAlias(Function &F, unsigned n) {
242 if (!F.doesNotAlias(n)) {
243 F.setDoesNotAlias(n);
250 void SimplifyLibCalls::inferPrototypeAttributes(Function &F) {
251 FunctionType *FTy = F.getFunctionType();
253 StringRef Name = F.getName();
256 if (Name == "strlen") {
257 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
259 setOnlyReadsMemory(F);
261 setDoesNotCapture(F, 1);
262 } else if (Name == "strchr" ||
264 if (FTy->getNumParams() != 2 ||
265 !FTy->getParamType(0)->isPointerTy() ||
266 !FTy->getParamType(1)->isIntegerTy())
268 setOnlyReadsMemory(F);
270 } else if (Name == "strcpy" ||
282 Name == "strtoull") {
283 if (FTy->getNumParams() < 2 ||
284 !FTy->getParamType(1)->isPointerTy())
287 setDoesNotCapture(F, 2);
288 } else if (Name == "strxfrm") {
289 if (FTy->getNumParams() != 3 ||
290 !FTy->getParamType(0)->isPointerTy() ||
291 !FTy->getParamType(1)->isPointerTy())
294 setDoesNotCapture(F, 1);
295 setDoesNotCapture(F, 2);
296 } else if (Name == "strcmp" ||
301 Name == "strcasecmp" ||
302 Name == "strncasecmp") {
303 if (FTy->getNumParams() < 2 ||
304 !FTy->getParamType(0)->isPointerTy() ||
305 !FTy->getParamType(1)->isPointerTy())
307 setOnlyReadsMemory(F);
309 setDoesNotCapture(F, 1);
310 setDoesNotCapture(F, 2);
311 } else if (Name == "strstr" ||
313 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
315 setOnlyReadsMemory(F);
317 setDoesNotCapture(F, 2);
318 } else if (Name == "strtok" ||
319 Name == "strtok_r") {
320 if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
323 setDoesNotCapture(F, 2);
324 } else if (Name == "scanf" ||
327 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
330 setDoesNotCapture(F, 1);
331 } else if (Name == "strdup" ||
333 if (FTy->getNumParams() < 1 || !FTy->getReturnType()->isPointerTy() ||
334 !FTy->getParamType(0)->isPointerTy())
337 setDoesNotAlias(F, 0);
338 setDoesNotCapture(F, 1);
339 } else if (Name == "stat" ||
343 if (FTy->getNumParams() < 2 ||
344 !FTy->getParamType(0)->isPointerTy() ||
345 !FTy->getParamType(1)->isPointerTy())
348 setDoesNotCapture(F, 1);
349 setDoesNotCapture(F, 2);
350 } else if (Name == "snprintf") {
351 if (FTy->getNumParams() != 3 ||
352 !FTy->getParamType(0)->isPointerTy() ||
353 !FTy->getParamType(2)->isPointerTy())
356 setDoesNotCapture(F, 1);
357 setDoesNotCapture(F, 3);
358 } else if (Name == "setitimer") {
359 if (FTy->getNumParams() != 3 ||
360 !FTy->getParamType(1)->isPointerTy() ||
361 !FTy->getParamType(2)->isPointerTy())
364 setDoesNotCapture(F, 2);
365 setDoesNotCapture(F, 3);
366 } else if (Name == "system") {
367 if (FTy->getNumParams() != 1 ||
368 !FTy->getParamType(0)->isPointerTy())
370 // May throw; "system" is a valid pthread cancellation point.
371 setDoesNotCapture(F, 1);
375 if (Name == "malloc") {
376 if (FTy->getNumParams() != 1 ||
377 !FTy->getReturnType()->isPointerTy())
380 setDoesNotAlias(F, 0);
381 } else if (Name == "memcmp") {
382 if (FTy->getNumParams() != 3 ||
383 !FTy->getParamType(0)->isPointerTy() ||
384 !FTy->getParamType(1)->isPointerTy())
386 setOnlyReadsMemory(F);
388 setDoesNotCapture(F, 1);
389 setDoesNotCapture(F, 2);
390 } else if (Name == "memchr" ||
392 if (FTy->getNumParams() != 3)
394 setOnlyReadsMemory(F);
396 } else if (Name == "modf" ||
402 if (FTy->getNumParams() < 2 ||
403 !FTy->getParamType(1)->isPointerTy())
406 setDoesNotCapture(F, 2);
407 } else if (Name == "memalign") {
408 if (!FTy->getReturnType()->isPointerTy())
410 setDoesNotAlias(F, 0);
411 } else if (Name == "mkdir" ||
413 if (FTy->getNumParams() == 0 ||
414 !FTy->getParamType(0)->isPointerTy())
417 setDoesNotCapture(F, 1);
421 if (Name == "realloc") {
422 if (FTy->getNumParams() != 2 ||
423 !FTy->getParamType(0)->isPointerTy() ||
424 !FTy->getReturnType()->isPointerTy())
427 setDoesNotAlias(F, 0);
428 setDoesNotCapture(F, 1);
429 } else if (Name == "read") {
430 if (FTy->getNumParams() != 3 ||
431 !FTy->getParamType(1)->isPointerTy())
433 // May throw; "read" is a valid pthread cancellation point.
434 setDoesNotCapture(F, 2);
435 } else if (Name == "rmdir" ||
438 Name == "realpath") {
439 if (FTy->getNumParams() < 1 ||
440 !FTy->getParamType(0)->isPointerTy())
443 setDoesNotCapture(F, 1);
444 } else if (Name == "rename" ||
445 Name == "readlink") {
446 if (FTy->getNumParams() < 2 ||
447 !FTy->getParamType(0)->isPointerTy() ||
448 !FTy->getParamType(1)->isPointerTy())
451 setDoesNotCapture(F, 1);
452 setDoesNotCapture(F, 2);
456 if (Name == "write") {
457 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy())
459 // May throw; "write" is a valid pthread cancellation point.
460 setDoesNotCapture(F, 2);
464 if (Name == "bcopy") {
465 if (FTy->getNumParams() != 3 ||
466 !FTy->getParamType(0)->isPointerTy() ||
467 !FTy->getParamType(1)->isPointerTy())
470 setDoesNotCapture(F, 1);
471 setDoesNotCapture(F, 2);
472 } else if (Name == "bcmp") {
473 if (FTy->getNumParams() != 3 ||
474 !FTy->getParamType(0)->isPointerTy() ||
475 !FTy->getParamType(1)->isPointerTy())
478 setOnlyReadsMemory(F);
479 setDoesNotCapture(F, 1);
480 setDoesNotCapture(F, 2);
481 } else if (Name == "bzero") {
482 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
485 setDoesNotCapture(F, 1);
489 if (Name == "calloc") {
490 if (FTy->getNumParams() != 2 ||
491 !FTy->getReturnType()->isPointerTy())
494 setDoesNotAlias(F, 0);
495 } else if (Name == "chmod" ||
498 Name == "clearerr" ||
499 Name == "closedir") {
500 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
503 setDoesNotCapture(F, 1);
507 if (Name == "atoi" ||
511 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
514 setOnlyReadsMemory(F);
515 setDoesNotCapture(F, 1);
516 } else if (Name == "access") {
517 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
520 setDoesNotCapture(F, 1);
524 if (Name == "fopen") {
525 if (FTy->getNumParams() != 2 ||
526 !FTy->getReturnType()->isPointerTy() ||
527 !FTy->getParamType(0)->isPointerTy() ||
528 !FTy->getParamType(1)->isPointerTy())
531 setDoesNotAlias(F, 0);
532 setDoesNotCapture(F, 1);
533 setDoesNotCapture(F, 2);
534 } else if (Name == "fdopen") {
535 if (FTy->getNumParams() != 2 ||
536 !FTy->getReturnType()->isPointerTy() ||
537 !FTy->getParamType(1)->isPointerTy())
540 setDoesNotAlias(F, 0);
541 setDoesNotCapture(F, 2);
542 } else if (Name == "feof" ||
553 Name == "flockfile" ||
554 Name == "funlockfile" ||
555 Name == "ftrylockfile") {
556 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
559 setDoesNotCapture(F, 1);
560 } else if (Name == "ferror") {
561 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
564 setDoesNotCapture(F, 1);
565 setOnlyReadsMemory(F);
566 } else if (Name == "fputc" ||
571 Name == "fstatvfs") {
572 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
575 setDoesNotCapture(F, 2);
576 } else if (Name == "fgets") {
577 if (FTy->getNumParams() != 3 ||
578 !FTy->getParamType(0)->isPointerTy() ||
579 !FTy->getParamType(2)->isPointerTy())
582 setDoesNotCapture(F, 3);
583 } else if (Name == "fread" ||
585 if (FTy->getNumParams() != 4 ||
586 !FTy->getParamType(0)->isPointerTy() ||
587 !FTy->getParamType(3)->isPointerTy())
590 setDoesNotCapture(F, 1);
591 setDoesNotCapture(F, 4);
592 } else if (Name == "fputs" ||
596 if (FTy->getNumParams() < 2 ||
597 !FTy->getParamType(0)->isPointerTy() ||
598 !FTy->getParamType(1)->isPointerTy())
601 setDoesNotCapture(F, 1);
602 setDoesNotCapture(F, 2);
606 if (Name == "getc" ||
607 Name == "getlogin_r" ||
608 Name == "getc_unlocked") {
609 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
612 setDoesNotCapture(F, 1);
613 } else if (Name == "getenv") {
614 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
617 setOnlyReadsMemory(F);
618 setDoesNotCapture(F, 1);
619 } else if (Name == "gets" ||
622 } else if (Name == "getitimer") {
623 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
626 setDoesNotCapture(F, 2);
627 } else if (Name == "getpwnam") {
628 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
631 setDoesNotCapture(F, 1);
635 if (Name == "ungetc") {
636 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
639 setDoesNotCapture(F, 2);
640 } else if (Name == "uname" ||
642 Name == "unsetenv") {
643 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
646 setDoesNotCapture(F, 1);
647 } else if (Name == "utime" ||
649 if (FTy->getNumParams() != 2 ||
650 !FTy->getParamType(0)->isPointerTy() ||
651 !FTy->getParamType(1)->isPointerTy())
654 setDoesNotCapture(F, 1);
655 setDoesNotCapture(F, 2);
659 if (Name == "putc") {
660 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
663 setDoesNotCapture(F, 2);
664 } else if (Name == "puts" ||
667 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
670 setDoesNotCapture(F, 1);
671 } else if (Name == "pread" ||
673 if (FTy->getNumParams() != 4 || !FTy->getParamType(1)->isPointerTy())
675 // May throw; these are valid pthread cancellation points.
676 setDoesNotCapture(F, 2);
677 } else if (Name == "putchar") {
679 } else if (Name == "popen") {
680 if (FTy->getNumParams() != 2 ||
681 !FTy->getReturnType()->isPointerTy() ||
682 !FTy->getParamType(0)->isPointerTy() ||
683 !FTy->getParamType(1)->isPointerTy())
686 setDoesNotAlias(F, 0);
687 setDoesNotCapture(F, 1);
688 setDoesNotCapture(F, 2);
689 } else if (Name == "pclose") {
690 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
693 setDoesNotCapture(F, 1);
697 if (Name == "vscanf") {
698 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
701 setDoesNotCapture(F, 1);
702 } else if (Name == "vsscanf" ||
704 if (FTy->getNumParams() != 3 ||
705 !FTy->getParamType(1)->isPointerTy() ||
706 !FTy->getParamType(2)->isPointerTy())
709 setDoesNotCapture(F, 1);
710 setDoesNotCapture(F, 2);
711 } else if (Name == "valloc") {
712 if (!FTy->getReturnType()->isPointerTy())
715 setDoesNotAlias(F, 0);
716 } else if (Name == "vprintf") {
717 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
720 setDoesNotCapture(F, 1);
721 } else if (Name == "vfprintf" ||
722 Name == "vsprintf") {
723 if (FTy->getNumParams() != 3 ||
724 !FTy->getParamType(0)->isPointerTy() ||
725 !FTy->getParamType(1)->isPointerTy())
728 setDoesNotCapture(F, 1);
729 setDoesNotCapture(F, 2);
730 } else if (Name == "vsnprintf") {
731 if (FTy->getNumParams() != 4 ||
732 !FTy->getParamType(0)->isPointerTy() ||
733 !FTy->getParamType(2)->isPointerTy())
736 setDoesNotCapture(F, 1);
737 setDoesNotCapture(F, 3);
741 if (Name == "open") {
742 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy())
744 // May throw; "open" is a valid pthread cancellation point.
745 setDoesNotCapture(F, 1);
746 } else if (Name == "opendir") {
747 if (FTy->getNumParams() != 1 ||
748 !FTy->getReturnType()->isPointerTy() ||
749 !FTy->getParamType(0)->isPointerTy())
752 setDoesNotAlias(F, 0);
753 setDoesNotCapture(F, 1);
757 if (Name == "tmpfile") {
758 if (!FTy->getReturnType()->isPointerTy())
761 setDoesNotAlias(F, 0);
762 } else if (Name == "times") {
763 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
766 setDoesNotCapture(F, 1);
770 if (Name == "htonl" ||
773 setDoesNotAccessMemory(F);
777 if (Name == "ntohl" ||
780 setDoesNotAccessMemory(F);
784 if (Name == "lstat") {
785 if (FTy->getNumParams() != 2 ||
786 !FTy->getParamType(0)->isPointerTy() ||
787 !FTy->getParamType(1)->isPointerTy())
790 setDoesNotCapture(F, 1);
791 setDoesNotCapture(F, 2);
792 } else if (Name == "lchown") {
793 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy())
796 setDoesNotCapture(F, 1);
800 if (Name == "qsort") {
801 if (FTy->getNumParams() != 4 || !FTy->getParamType(3)->isPointerTy())
803 // May throw; places call through function pointer.
804 setDoesNotCapture(F, 4);
808 if (Name == "__strdup" ||
809 Name == "__strndup") {
810 if (FTy->getNumParams() < 1 ||
811 !FTy->getReturnType()->isPointerTy() ||
812 !FTy->getParamType(0)->isPointerTy())
815 setDoesNotAlias(F, 0);
816 setDoesNotCapture(F, 1);
817 } else if (Name == "__strtok_r") {
818 if (FTy->getNumParams() != 3 ||
819 !FTy->getParamType(1)->isPointerTy())
822 setDoesNotCapture(F, 2);
823 } else if (Name == "_IO_getc") {
824 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
827 setDoesNotCapture(F, 1);
828 } else if (Name == "_IO_putc") {
829 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
832 setDoesNotCapture(F, 2);
836 if (Name == "\1__isoc99_scanf") {
837 if (FTy->getNumParams() < 1 ||
838 !FTy->getParamType(0)->isPointerTy())
841 setDoesNotCapture(F, 1);
842 } else if (Name == "\1stat64" ||
843 Name == "\1lstat64" ||
844 Name == "\1statvfs64" ||
845 Name == "\1__isoc99_sscanf") {
846 if (FTy->getNumParams() < 1 ||
847 !FTy->getParamType(0)->isPointerTy() ||
848 !FTy->getParamType(1)->isPointerTy())
851 setDoesNotCapture(F, 1);
852 setDoesNotCapture(F, 2);
853 } else if (Name == "\1fopen64") {
854 if (FTy->getNumParams() != 2 ||
855 !FTy->getReturnType()->isPointerTy() ||
856 !FTy->getParamType(0)->isPointerTy() ||
857 !FTy->getParamType(1)->isPointerTy())
860 setDoesNotAlias(F, 0);
861 setDoesNotCapture(F, 1);
862 setDoesNotCapture(F, 2);
863 } else if (Name == "\1fseeko64" ||
864 Name == "\1ftello64") {
865 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
868 setDoesNotCapture(F, 1);
869 } else if (Name == "\1tmpfile64") {
870 if (!FTy->getReturnType()->isPointerTy())
873 setDoesNotAlias(F, 0);
874 } else if (Name == "\1fstat64" ||
875 Name == "\1fstatvfs64") {
876 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
879 setDoesNotCapture(F, 2);
880 } else if (Name == "\1open64") {
881 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy())
883 // May throw; "open" is a valid pthread cancellation point.
884 setDoesNotCapture(F, 1);
890 /// doInitialization - Add attributes to well-known functions.
892 bool SimplifyLibCalls::doInitialization(Module &M) {
894 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
896 if (F.isDeclaration() && F.hasName())
897 inferPrototypeAttributes(F);
903 // Additional cases that we need to add to this file:
906 // * cbrt(expN(X)) -> expN(x/3)
907 // * cbrt(sqrt(x)) -> pow(x,1/6)
908 // * cbrt(sqrt(x)) -> pow(x,1/9)
911 // * exp(log(x)) -> x
914 // * log(exp(x)) -> x
915 // * log(x**y) -> y*log(x)
916 // * log(exp(y)) -> y*log(e)
917 // * log(exp2(y)) -> y*log(2)
918 // * log(exp10(y)) -> y*log(10)
919 // * log(sqrt(x)) -> 0.5*log(x)
920 // * log(pow(x,y)) -> y*log(x)
922 // lround, lroundf, lroundl:
923 // * lround(cnst) -> cnst'
926 // * pow(exp(x),y) -> exp(x*y)
927 // * pow(sqrt(x),y) -> pow(x,y*0.5)
928 // * pow(pow(x,y),z)-> pow(x,y*z)
930 // round, roundf, roundl:
931 // * round(cnst) -> cnst'
934 // * signbit(cnst) -> cnst'
935 // * signbit(nncst) -> 0 (if pstv is a non-negative constant)
937 // sqrt, sqrtf, sqrtl:
938 // * sqrt(expN(x)) -> expN(x*0.5)
939 // * sqrt(Nroot(x)) -> pow(x,1/(2*N))
940 // * sqrt(pow(x,y)) -> pow(|x|,y*0.5)
943 // * strchr(p, 0) -> strlen(p)
945 // * tan(atan(x)) -> x
947 // trunc, truncf, truncl:
948 // * trunc(cnst) -> cnst'