1 //===- InferFunctionAttrs.cpp - Infer implicit function attributes --------===//
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 #include "llvm/Transforms/IPO/InferFunctionAttrs.h"
11 #include "llvm/ADT/Statistic.h"
12 #include "llvm/Analysis/TargetLibraryInfo.h"
13 #include "llvm/IR/Function.h"
14 #include "llvm/IR/LLVMContext.h"
15 #include "llvm/IR/Module.h"
16 #include "llvm/Support/Debug.h"
17 #include "llvm/Support/raw_ostream.h"
20 #define DEBUG_TYPE "inferattrs"
22 STATISTIC(NumReadNone, "Number of functions inferred as readnone");
23 STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
24 STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
25 STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
26 STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
27 STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");
29 static bool setDoesNotAccessMemory(Function &F) {
30 if (F.doesNotAccessMemory())
32 F.setDoesNotAccessMemory();
37 static bool setOnlyReadsMemory(Function &F) {
38 if (F.onlyReadsMemory())
40 F.setOnlyReadsMemory();
45 static bool setDoesNotThrow(Function &F) {
53 static bool setDoesNotCapture(Function &F, unsigned n) {
54 if (F.doesNotCapture(n))
56 F.setDoesNotCapture(n);
61 static bool setOnlyReadsMemory(Function &F, unsigned n) {
62 if (F.onlyReadsMemory(n))
64 F.setOnlyReadsMemory(n);
69 static bool setDoesNotAlias(Function &F, unsigned n) {
70 if (F.doesNotAlias(n))
77 /// Analyze the name and prototype of the given function and set any applicable
80 /// Returns true if any attributes were set and false otherwise.
81 static bool inferPrototypeAttributes(Function &F,
82 const TargetLibraryInfo &TLI) {
83 if (F.hasFnAttribute(Attribute::OptimizeNone))
86 FunctionType *FTy = F.getFunctionType();
87 LibFunc::Func TheLibFunc;
88 if (!(TLI.getLibFunc(F.getName(), TheLibFunc) && TLI.has(TheLibFunc)))
95 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
97 Changed |= setOnlyReadsMemory(F);
98 Changed |= setDoesNotThrow(F);
99 Changed |= setDoesNotCapture(F, 1);
101 case LibFunc::strchr:
102 case LibFunc::strrchr:
103 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
104 !FTy->getParamType(1)->isIntegerTy())
106 Changed |= setOnlyReadsMemory(F);
107 Changed |= setDoesNotThrow(F);
109 case LibFunc::strtol:
110 case LibFunc::strtod:
111 case LibFunc::strtof:
112 case LibFunc::strtoul:
113 case LibFunc::strtoll:
114 case LibFunc::strtold:
115 case LibFunc::strtoull:
116 if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
118 Changed |= setDoesNotThrow(F);
119 Changed |= setDoesNotCapture(F, 2);
120 Changed |= setOnlyReadsMemory(F, 1);
122 case LibFunc::strcpy:
123 case LibFunc::stpcpy:
124 case LibFunc::strcat:
125 case LibFunc::strncat:
126 case LibFunc::strncpy:
127 case LibFunc::stpncpy:
128 if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
130 Changed |= setDoesNotThrow(F);
131 Changed |= setDoesNotCapture(F, 2);
132 Changed |= setOnlyReadsMemory(F, 2);
134 case LibFunc::strxfrm:
135 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
136 !FTy->getParamType(1)->isPointerTy())
138 Changed |= setDoesNotThrow(F);
139 Changed |= setDoesNotCapture(F, 1);
140 Changed |= setDoesNotCapture(F, 2);
141 Changed |= setOnlyReadsMemory(F, 2);
143 case LibFunc::strcmp: // 0,1
144 case LibFunc::strspn: // 0,1
145 case LibFunc::strncmp: // 0,1
146 case LibFunc::strcspn: // 0,1
147 case LibFunc::strcoll: // 0,1
148 case LibFunc::strcasecmp: // 0,1
149 case LibFunc::strncasecmp: //
150 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
151 !FTy->getParamType(1)->isPointerTy())
153 Changed |= setOnlyReadsMemory(F);
154 Changed |= setDoesNotThrow(F);
155 Changed |= setDoesNotCapture(F, 1);
156 Changed |= setDoesNotCapture(F, 2);
158 case LibFunc::strstr:
159 case LibFunc::strpbrk:
160 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
162 Changed |= setOnlyReadsMemory(F);
163 Changed |= setDoesNotThrow(F);
164 Changed |= setDoesNotCapture(F, 2);
166 case LibFunc::strtok:
167 case LibFunc::strtok_r:
168 if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
170 Changed |= setDoesNotThrow(F);
171 Changed |= setDoesNotCapture(F, 2);
172 Changed |= setOnlyReadsMemory(F, 2);
175 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
177 Changed |= setDoesNotThrow(F);
178 Changed |= setDoesNotCapture(F, 1);
179 Changed |= setOnlyReadsMemory(F, 1);
181 case LibFunc::setbuf:
182 case LibFunc::setvbuf:
183 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
185 Changed |= setDoesNotThrow(F);
186 Changed |= setDoesNotCapture(F, 1);
188 case LibFunc::strdup:
189 case LibFunc::strndup:
190 if (FTy->getNumParams() < 1 || !FTy->getReturnType()->isPointerTy() ||
191 !FTy->getParamType(0)->isPointerTy())
193 Changed |= setDoesNotThrow(F);
194 Changed |= setDoesNotAlias(F, 0);
195 Changed |= setDoesNotCapture(F, 1);
196 Changed |= setOnlyReadsMemory(F, 1);
199 case LibFunc::statvfs:
200 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
201 !FTy->getParamType(1)->isPointerTy())
203 Changed |= setDoesNotThrow(F);
204 Changed |= setDoesNotCapture(F, 1);
205 Changed |= setDoesNotCapture(F, 2);
206 Changed |= setOnlyReadsMemory(F, 1);
208 case LibFunc::sscanf:
209 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
210 !FTy->getParamType(1)->isPointerTy())
212 Changed |= setDoesNotThrow(F);
213 Changed |= setDoesNotCapture(F, 1);
214 Changed |= setDoesNotCapture(F, 2);
215 Changed |= setOnlyReadsMemory(F, 1);
216 Changed |= setOnlyReadsMemory(F, 2);
218 case LibFunc::sprintf:
219 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
220 !FTy->getParamType(1)->isPointerTy())
222 Changed |= setDoesNotThrow(F);
223 Changed |= setDoesNotCapture(F, 1);
224 Changed |= setDoesNotCapture(F, 2);
225 Changed |= setOnlyReadsMemory(F, 2);
227 case LibFunc::snprintf:
228 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
229 !FTy->getParamType(2)->isPointerTy())
231 Changed |= setDoesNotThrow(F);
232 Changed |= setDoesNotCapture(F, 1);
233 Changed |= setDoesNotCapture(F, 3);
234 Changed |= setOnlyReadsMemory(F, 3);
236 case LibFunc::setitimer:
237 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy() ||
238 !FTy->getParamType(2)->isPointerTy())
240 Changed |= setDoesNotThrow(F);
241 Changed |= setDoesNotCapture(F, 2);
242 Changed |= setDoesNotCapture(F, 3);
243 Changed |= setOnlyReadsMemory(F, 2);
245 case LibFunc::system:
246 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
248 // May throw; "system" is a valid pthread cancellation point.
249 Changed |= setDoesNotCapture(F, 1);
250 Changed |= setOnlyReadsMemory(F, 1);
252 case LibFunc::malloc:
253 if (FTy->getNumParams() != 1 || !FTy->getReturnType()->isPointerTy())
255 Changed |= setDoesNotThrow(F);
256 Changed |= setDoesNotAlias(F, 0);
258 case LibFunc::memcmp:
259 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
260 !FTy->getParamType(1)->isPointerTy())
262 Changed |= setOnlyReadsMemory(F);
263 Changed |= setDoesNotThrow(F);
264 Changed |= setDoesNotCapture(F, 1);
265 Changed |= setDoesNotCapture(F, 2);
267 case LibFunc::memchr:
268 case LibFunc::memrchr:
269 if (FTy->getNumParams() != 3)
271 Changed |= setOnlyReadsMemory(F);
272 Changed |= setDoesNotThrow(F);
277 if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
279 Changed |= setDoesNotThrow(F);
280 Changed |= setDoesNotCapture(F, 2);
282 case LibFunc::memcpy:
283 case LibFunc::memccpy:
284 case LibFunc::memmove:
285 if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
287 Changed |= setDoesNotThrow(F);
288 Changed |= setDoesNotCapture(F, 2);
289 Changed |= setOnlyReadsMemory(F, 2);
291 case LibFunc::memalign:
292 if (!FTy->getReturnType()->isPointerTy())
294 Changed |= setDoesNotAlias(F, 0);
297 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
299 Changed |= setDoesNotThrow(F);
300 Changed |= setDoesNotCapture(F, 1);
301 Changed |= setOnlyReadsMemory(F, 1);
303 case LibFunc::mktime:
304 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
306 Changed |= setDoesNotThrow(F);
307 Changed |= setDoesNotCapture(F, 1);
309 case LibFunc::realloc:
310 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
311 !FTy->getReturnType()->isPointerTy())
313 Changed |= setDoesNotThrow(F);
314 Changed |= setDoesNotAlias(F, 0);
315 Changed |= setDoesNotCapture(F, 1);
318 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy())
320 // May throw; "read" is a valid pthread cancellation point.
321 Changed |= setDoesNotCapture(F, 2);
323 case LibFunc::rewind:
324 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
326 Changed |= setDoesNotThrow(F);
327 Changed |= setDoesNotCapture(F, 1);
330 case LibFunc::remove:
331 case LibFunc::realpath:
332 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
334 Changed |= setDoesNotThrow(F);
335 Changed |= setDoesNotCapture(F, 1);
336 Changed |= setOnlyReadsMemory(F, 1);
338 case LibFunc::rename:
339 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
340 !FTy->getParamType(1)->isPointerTy())
342 Changed |= setDoesNotThrow(F);
343 Changed |= setDoesNotCapture(F, 1);
344 Changed |= setDoesNotCapture(F, 2);
345 Changed |= setOnlyReadsMemory(F, 1);
346 Changed |= setOnlyReadsMemory(F, 2);
348 case LibFunc::readlink:
349 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
350 !FTy->getParamType(1)->isPointerTy())
352 Changed |= setDoesNotThrow(F);
353 Changed |= setDoesNotCapture(F, 1);
354 Changed |= setDoesNotCapture(F, 2);
355 Changed |= setOnlyReadsMemory(F, 1);
358 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy())
360 // May throw; "write" is a valid pthread cancellation point.
361 Changed |= setDoesNotCapture(F, 2);
362 Changed |= setOnlyReadsMemory(F, 2);
365 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
366 !FTy->getParamType(1)->isPointerTy())
368 Changed |= setDoesNotThrow(F);
369 Changed |= setDoesNotCapture(F, 1);
370 Changed |= setDoesNotCapture(F, 2);
371 Changed |= setOnlyReadsMemory(F, 1);
374 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
375 !FTy->getParamType(1)->isPointerTy())
377 Changed |= setDoesNotThrow(F);
378 Changed |= setOnlyReadsMemory(F);
379 Changed |= setDoesNotCapture(F, 1);
380 Changed |= setDoesNotCapture(F, 2);
383 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
385 Changed |= setDoesNotThrow(F);
386 Changed |= setDoesNotCapture(F, 1);
388 case LibFunc::calloc:
389 if (FTy->getNumParams() != 2 || !FTy->getReturnType()->isPointerTy())
391 Changed |= setDoesNotThrow(F);
392 Changed |= setDoesNotAlias(F, 0);
396 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
398 Changed |= setDoesNotThrow(F);
399 Changed |= setDoesNotCapture(F, 1);
400 Changed |= setOnlyReadsMemory(F, 1);
402 case LibFunc::ctermid:
403 case LibFunc::clearerr:
404 case LibFunc::closedir:
405 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
407 Changed |= setDoesNotThrow(F);
408 Changed |= setDoesNotCapture(F, 1);
414 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
416 Changed |= setDoesNotThrow(F);
417 Changed |= setOnlyReadsMemory(F);
418 Changed |= setDoesNotCapture(F, 1);
420 case LibFunc::access:
421 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
423 Changed |= setDoesNotThrow(F);
424 Changed |= setDoesNotCapture(F, 1);
425 Changed |= setOnlyReadsMemory(F, 1);
428 if (FTy->getNumParams() != 2 || !FTy->getReturnType()->isPointerTy() ||
429 !FTy->getParamType(0)->isPointerTy() ||
430 !FTy->getParamType(1)->isPointerTy())
432 Changed |= setDoesNotThrow(F);
433 Changed |= setDoesNotAlias(F, 0);
434 Changed |= setDoesNotCapture(F, 1);
435 Changed |= setDoesNotCapture(F, 2);
436 Changed |= setOnlyReadsMemory(F, 1);
437 Changed |= setOnlyReadsMemory(F, 2);
439 case LibFunc::fdopen:
440 if (FTy->getNumParams() != 2 || !FTy->getReturnType()->isPointerTy() ||
441 !FTy->getParamType(1)->isPointerTy())
443 Changed |= setDoesNotThrow(F);
444 Changed |= setDoesNotAlias(F, 0);
445 Changed |= setDoesNotCapture(F, 2);
446 Changed |= setOnlyReadsMemory(F, 2);
453 case LibFunc::fseeko:
454 case LibFunc::ftello:
455 case LibFunc::fileno:
456 case LibFunc::fflush:
457 case LibFunc::fclose:
458 case LibFunc::fsetpos:
459 case LibFunc::flockfile:
460 case LibFunc::funlockfile:
461 case LibFunc::ftrylockfile:
462 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
464 Changed |= setDoesNotThrow(F);
465 Changed |= setDoesNotCapture(F, 1);
467 case LibFunc::ferror:
468 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
470 Changed |= setDoesNotThrow(F);
471 Changed |= setDoesNotCapture(F, 1);
472 Changed |= setOnlyReadsMemory(F);
477 case LibFunc::frexpf:
478 case LibFunc::frexpl:
479 case LibFunc::fstatvfs:
480 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
482 Changed |= setDoesNotThrow(F);
483 Changed |= setDoesNotCapture(F, 2);
486 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
487 !FTy->getParamType(2)->isPointerTy())
489 Changed |= setDoesNotThrow(F);
490 Changed |= setDoesNotCapture(F, 3);
493 if (FTy->getNumParams() != 4 || !FTy->getParamType(0)->isPointerTy() ||
494 !FTy->getParamType(3)->isPointerTy())
496 Changed |= setDoesNotThrow(F);
497 Changed |= setDoesNotCapture(F, 1);
498 Changed |= setDoesNotCapture(F, 4);
500 case LibFunc::fwrite:
501 if (FTy->getNumParams() != 4 || !FTy->getParamType(0)->isPointerTy() ||
502 !FTy->getParamType(3)->isPointerTy())
504 Changed |= setDoesNotThrow(F);
505 Changed |= setDoesNotCapture(F, 1);
506 Changed |= setDoesNotCapture(F, 4);
509 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
510 !FTy->getParamType(1)->isPointerTy())
512 Changed |= setDoesNotThrow(F);
513 Changed |= setDoesNotCapture(F, 1);
514 Changed |= setDoesNotCapture(F, 2);
515 Changed |= setOnlyReadsMemory(F, 1);
517 case LibFunc::fscanf:
518 case LibFunc::fprintf:
519 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
520 !FTy->getParamType(1)->isPointerTy())
522 Changed |= setDoesNotThrow(F);
523 Changed |= setDoesNotCapture(F, 1);
524 Changed |= setDoesNotCapture(F, 2);
525 Changed |= setOnlyReadsMemory(F, 2);
527 case LibFunc::fgetpos:
528 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
529 !FTy->getParamType(1)->isPointerTy())
531 Changed |= setDoesNotThrow(F);
532 Changed |= setDoesNotCapture(F, 1);
533 Changed |= setDoesNotCapture(F, 2);
536 case LibFunc::getlogin_r:
537 case LibFunc::getc_unlocked:
538 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
540 Changed |= setDoesNotThrow(F);
541 Changed |= setDoesNotCapture(F, 1);
543 case LibFunc::getenv:
544 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
546 Changed |= setDoesNotThrow(F);
547 Changed |= setOnlyReadsMemory(F);
548 Changed |= setDoesNotCapture(F, 1);
551 case LibFunc::getchar:
552 Changed |= setDoesNotThrow(F);
554 case LibFunc::getitimer:
555 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
557 Changed |= setDoesNotThrow(F);
558 Changed |= setDoesNotCapture(F, 2);
560 case LibFunc::getpwnam:
561 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
563 Changed |= setDoesNotThrow(F);
564 Changed |= setDoesNotCapture(F, 1);
565 Changed |= setOnlyReadsMemory(F, 1);
567 case LibFunc::ungetc:
568 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
570 Changed |= setDoesNotThrow(F);
571 Changed |= setDoesNotCapture(F, 2);
574 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
576 Changed |= setDoesNotThrow(F);
577 Changed |= setDoesNotCapture(F, 1);
579 case LibFunc::unlink:
580 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
582 Changed |= setDoesNotThrow(F);
583 Changed |= setDoesNotCapture(F, 1);
584 Changed |= setOnlyReadsMemory(F, 1);
586 case LibFunc::unsetenv:
587 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
589 Changed |= setDoesNotThrow(F);
590 Changed |= setDoesNotCapture(F, 1);
591 Changed |= setOnlyReadsMemory(F, 1);
594 case LibFunc::utimes:
595 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
596 !FTy->getParamType(1)->isPointerTy())
598 Changed |= setDoesNotThrow(F);
599 Changed |= setDoesNotCapture(F, 1);
600 Changed |= setDoesNotCapture(F, 2);
601 Changed |= setOnlyReadsMemory(F, 1);
602 Changed |= setOnlyReadsMemory(F, 2);
605 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
607 Changed |= setDoesNotThrow(F);
608 Changed |= setDoesNotCapture(F, 2);
611 case LibFunc::printf:
612 case LibFunc::perror:
613 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
615 Changed |= setDoesNotThrow(F);
616 Changed |= setDoesNotCapture(F, 1);
617 Changed |= setOnlyReadsMemory(F, 1);
620 if (FTy->getNumParams() != 4 || !FTy->getParamType(1)->isPointerTy())
622 // May throw; "pread" is a valid pthread cancellation point.
623 Changed |= setDoesNotCapture(F, 2);
625 case LibFunc::pwrite:
626 if (FTy->getNumParams() != 4 || !FTy->getParamType(1)->isPointerTy())
628 // May throw; "pwrite" is a valid pthread cancellation point.
629 Changed |= setDoesNotCapture(F, 2);
630 Changed |= setOnlyReadsMemory(F, 2);
632 case LibFunc::putchar:
633 Changed |= setDoesNotThrow(F);
636 if (FTy->getNumParams() != 2 || !FTy->getReturnType()->isPointerTy() ||
637 !FTy->getParamType(0)->isPointerTy() ||
638 !FTy->getParamType(1)->isPointerTy())
640 Changed |= setDoesNotThrow(F);
641 Changed |= setDoesNotAlias(F, 0);
642 Changed |= setDoesNotCapture(F, 1);
643 Changed |= setDoesNotCapture(F, 2);
644 Changed |= setOnlyReadsMemory(F, 1);
645 Changed |= setOnlyReadsMemory(F, 2);
647 case LibFunc::pclose:
648 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
650 Changed |= setDoesNotThrow(F);
651 Changed |= setDoesNotCapture(F, 1);
653 case LibFunc::vscanf:
654 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
656 Changed |= setDoesNotThrow(F);
657 Changed |= setDoesNotCapture(F, 1);
658 Changed |= setOnlyReadsMemory(F, 1);
660 case LibFunc::vsscanf:
661 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy() ||
662 !FTy->getParamType(2)->isPointerTy())
664 Changed |= setDoesNotThrow(F);
665 Changed |= setDoesNotCapture(F, 1);
666 Changed |= setDoesNotCapture(F, 2);
667 Changed |= setOnlyReadsMemory(F, 1);
668 Changed |= setOnlyReadsMemory(F, 2);
670 case LibFunc::vfscanf:
671 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy() ||
672 !FTy->getParamType(2)->isPointerTy())
674 Changed |= setDoesNotThrow(F);
675 Changed |= setDoesNotCapture(F, 1);
676 Changed |= setDoesNotCapture(F, 2);
677 Changed |= setOnlyReadsMemory(F, 2);
679 case LibFunc::valloc:
680 if (!FTy->getReturnType()->isPointerTy())
682 Changed |= setDoesNotThrow(F);
683 Changed |= setDoesNotAlias(F, 0);
685 case LibFunc::vprintf:
686 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
688 Changed |= setDoesNotThrow(F);
689 Changed |= setDoesNotCapture(F, 1);
690 Changed |= setOnlyReadsMemory(F, 1);
692 case LibFunc::vfprintf:
693 case LibFunc::vsprintf:
694 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
695 !FTy->getParamType(1)->isPointerTy())
697 Changed |= setDoesNotThrow(F);
698 Changed |= setDoesNotCapture(F, 1);
699 Changed |= setDoesNotCapture(F, 2);
700 Changed |= setOnlyReadsMemory(F, 2);
702 case LibFunc::vsnprintf:
703 if (FTy->getNumParams() != 4 || !FTy->getParamType(0)->isPointerTy() ||
704 !FTy->getParamType(2)->isPointerTy())
706 Changed |= setDoesNotThrow(F);
707 Changed |= setDoesNotCapture(F, 1);
708 Changed |= setDoesNotCapture(F, 3);
709 Changed |= setOnlyReadsMemory(F, 3);
712 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy())
714 // May throw; "open" is a valid pthread cancellation point.
715 Changed |= setDoesNotCapture(F, 1);
716 Changed |= setOnlyReadsMemory(F, 1);
718 case LibFunc::opendir:
719 if (FTy->getNumParams() != 1 || !FTy->getReturnType()->isPointerTy() ||
720 !FTy->getParamType(0)->isPointerTy())
722 Changed |= setDoesNotThrow(F);
723 Changed |= setDoesNotAlias(F, 0);
724 Changed |= setDoesNotCapture(F, 1);
725 Changed |= setOnlyReadsMemory(F, 1);
727 case LibFunc::tmpfile:
728 if (!FTy->getReturnType()->isPointerTy())
730 Changed |= setDoesNotThrow(F);
731 Changed |= setDoesNotAlias(F, 0);
734 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
736 Changed |= setDoesNotThrow(F);
737 Changed |= setDoesNotCapture(F, 1);
743 Changed |= setDoesNotThrow(F);
744 Changed |= setDoesNotAccessMemory(F);
747 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
748 !FTy->getParamType(1)->isPointerTy())
750 Changed |= setDoesNotThrow(F);
751 Changed |= setDoesNotCapture(F, 1);
752 Changed |= setDoesNotCapture(F, 2);
753 Changed |= setOnlyReadsMemory(F, 1);
755 case LibFunc::lchown:
756 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy())
758 Changed |= setDoesNotThrow(F);
759 Changed |= setDoesNotCapture(F, 1);
760 Changed |= setOnlyReadsMemory(F, 1);
763 if (FTy->getNumParams() != 4 || !FTy->getParamType(3)->isPointerTy())
765 // May throw; places call through function pointer.
766 Changed |= setDoesNotCapture(F, 4);
768 case LibFunc::dunder_strdup:
769 case LibFunc::dunder_strndup:
770 if (FTy->getNumParams() < 1 || !FTy->getReturnType()->isPointerTy() ||
771 !FTy->getParamType(0)->isPointerTy())
773 Changed |= setDoesNotThrow(F);
774 Changed |= setDoesNotAlias(F, 0);
775 Changed |= setDoesNotCapture(F, 1);
776 Changed |= setOnlyReadsMemory(F, 1);
778 case LibFunc::dunder_strtok_r:
779 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy())
781 Changed |= setDoesNotThrow(F);
782 Changed |= setDoesNotCapture(F, 2);
783 Changed |= setOnlyReadsMemory(F, 2);
785 case LibFunc::under_IO_getc:
786 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
788 Changed |= setDoesNotThrow(F);
789 Changed |= setDoesNotCapture(F, 1);
791 case LibFunc::under_IO_putc:
792 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
794 Changed |= setDoesNotThrow(F);
795 Changed |= setDoesNotCapture(F, 2);
797 case LibFunc::dunder_isoc99_scanf:
798 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
800 Changed |= setDoesNotThrow(F);
801 Changed |= setDoesNotCapture(F, 1);
802 Changed |= setOnlyReadsMemory(F, 1);
804 case LibFunc::stat64:
805 case LibFunc::lstat64:
806 case LibFunc::statvfs64:
807 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy() ||
808 !FTy->getParamType(1)->isPointerTy())
810 Changed |= setDoesNotThrow(F);
811 Changed |= setDoesNotCapture(F, 1);
812 Changed |= setDoesNotCapture(F, 2);
813 Changed |= setOnlyReadsMemory(F, 1);
815 case LibFunc::dunder_isoc99_sscanf:
816 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy() ||
817 !FTy->getParamType(1)->isPointerTy())
819 Changed |= setDoesNotThrow(F);
820 Changed |= setDoesNotCapture(F, 1);
821 Changed |= setDoesNotCapture(F, 2);
822 Changed |= setOnlyReadsMemory(F, 1);
823 Changed |= setOnlyReadsMemory(F, 2);
825 case LibFunc::fopen64:
826 if (FTy->getNumParams() != 2 || !FTy->getReturnType()->isPointerTy() ||
827 !FTy->getParamType(0)->isPointerTy() ||
828 !FTy->getParamType(1)->isPointerTy())
830 Changed |= setDoesNotThrow(F);
831 Changed |= setDoesNotAlias(F, 0);
832 Changed |= setDoesNotCapture(F, 1);
833 Changed |= setDoesNotCapture(F, 2);
834 Changed |= setOnlyReadsMemory(F, 1);
835 Changed |= setOnlyReadsMemory(F, 2);
837 case LibFunc::fseeko64:
838 case LibFunc::ftello64:
839 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
841 Changed |= setDoesNotThrow(F);
842 Changed |= setDoesNotCapture(F, 1);
844 case LibFunc::tmpfile64:
845 if (!FTy->getReturnType()->isPointerTy())
847 Changed |= setDoesNotThrow(F);
848 Changed |= setDoesNotAlias(F, 0);
850 case LibFunc::fstat64:
851 case LibFunc::fstatvfs64:
852 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
854 Changed |= setDoesNotThrow(F);
855 Changed |= setDoesNotCapture(F, 2);
857 case LibFunc::open64:
858 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy())
860 // May throw; "open" is a valid pthread cancellation point.
861 Changed |= setDoesNotCapture(F, 1);
862 Changed |= setOnlyReadsMemory(F, 1);
864 case LibFunc::gettimeofday:
865 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
866 !FTy->getParamType(1)->isPointerTy())
868 // Currently some platforms have the restrict keyword on the arguments to
869 // gettimeofday. To be conservative, do not add noalias to gettimeofday's
871 Changed |= setDoesNotThrow(F);
872 Changed |= setDoesNotCapture(F, 1);
873 Changed |= setDoesNotCapture(F, 2);
877 // FIXME: It'd be really nice to cover all the library functions we're
883 static bool inferAllPrototypeAttributes(Module &M,
884 const TargetLibraryInfo &TLI) {
885 bool Changed = false;
887 for (Function &F : M.functions())
888 // We only infer things using the prototype if the definition isn't around
889 // to analyze directly.
890 if (F.isDeclaration())
891 Changed |= inferPrototypeAttributes(F, TLI);
896 PreservedAnalyses InferFunctionAttrsPass::run(Module &M,
897 AnalysisManager<Module> *AM) {
898 auto &TLI = AM->getResult<TargetLibraryAnalysis>(M);
900 if (!inferAllPrototypeAttributes(M, TLI))
901 // If we didn't infer anything, preserve all analyses.
902 return PreservedAnalyses::all();
904 // Otherwise, we may have changed fundamental function attributes, so clear
905 // out all the passes.
906 return PreservedAnalyses::none();
910 struct InferFunctionAttrsLegacyPass : public ModulePass {
911 static char ID; // Pass identification, replacement for typeid
912 InferFunctionAttrsLegacyPass() : ModulePass(ID) {
913 initializeInferFunctionAttrsLegacyPassPass(
914 *PassRegistry::getPassRegistry());
917 void getAnalysisUsage(AnalysisUsage &AU) const override {
918 AU.addRequired<TargetLibraryInfoWrapperPass>();
921 bool runOnModule(Module &M) override {
922 auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
923 return inferAllPrototypeAttributes(M, TLI);
928 char InferFunctionAttrsLegacyPass::ID = 0;
929 INITIALIZE_PASS_BEGIN(InferFunctionAttrsLegacyPass, "inferattrs",
930 "Infer set function attributes", false, false)
931 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
932 INITIALIZE_PASS_END(InferFunctionAttrsLegacyPass, "inferattrs",
933 "Infer set function attributes", false, false)
935 Pass *llvm::createInferFunctionAttrsLegacyPass() {
936 return new InferFunctionAttrsLegacyPass();