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/Analysis/MemoryBuiltins.h"
14 #include "llvm/IR/Function.h"
15 #include "llvm/IR/LLVMContext.h"
16 #include "llvm/IR/Module.h"
17 #include "llvm/Support/Debug.h"
18 #include "llvm/Support/raw_ostream.h"
21 #define DEBUG_TYPE "inferattrs"
23 STATISTIC(NumReadNone, "Number of functions inferred as readnone");
24 STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
25 STATISTIC(NumArgMemOnly, "Number of functions inferred as argmemonly");
26 STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
27 STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
28 STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
29 STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");
30 STATISTIC(NumNonNull, "Number of function returns inferred as nonnull returns");
32 static bool setDoesNotAccessMemory(Function &F) {
33 if (F.doesNotAccessMemory())
35 F.setDoesNotAccessMemory();
40 static bool setOnlyReadsMemory(Function &F) {
41 if (F.onlyReadsMemory())
43 F.setOnlyReadsMemory();
48 static bool setOnlyAccessesArgMemory(Function &F) {
49 if (F.onlyAccessesArgMemory())
51 F.setOnlyAccessesArgMemory ();
57 static bool setDoesNotThrow(Function &F) {
65 static bool setDoesNotCapture(Function &F, unsigned n) {
66 if (F.doesNotCapture(n))
68 F.setDoesNotCapture(n);
73 static bool setOnlyReadsMemory(Function &F, unsigned n) {
74 if (F.onlyReadsMemory(n))
76 F.setOnlyReadsMemory(n);
81 static bool setDoesNotAlias(Function &F, unsigned n) {
82 if (F.doesNotAlias(n))
89 static bool setNonNull(Function &F, unsigned n) {
90 assert((n != AttributeSet::ReturnIndex ||
91 F.getReturnType()->isPointerTy()) &&
92 "nonnull applies only to pointers");
93 if (F.getAttributes().hasAttribute(n, Attribute::NonNull))
95 F.addAttribute(n, Attribute::NonNull);
100 /// Analyze the name and prototype of the given function and set any applicable
103 /// Returns true if any attributes were set and false otherwise.
104 static bool inferPrototypeAttributes(Function &F,
105 const TargetLibraryInfo &TLI) {
106 if (F.hasFnAttribute(Attribute::OptimizeNone))
109 FunctionType *FTy = F.getFunctionType();
110 LibFunc::Func TheLibFunc;
111 if (!(TLI.getLibFunc(F.getName(), TheLibFunc) && TLI.has(TheLibFunc)))
114 bool Changed = false;
115 switch (TheLibFunc) {
116 case LibFunc::strlen:
117 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
119 Changed |= setOnlyReadsMemory(F);
120 Changed |= setDoesNotThrow(F);
121 Changed |= setDoesNotCapture(F, 1);
123 case LibFunc::strchr:
124 case LibFunc::strrchr:
125 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
126 !FTy->getParamType(1)->isIntegerTy())
128 Changed |= setOnlyReadsMemory(F);
129 Changed |= setDoesNotThrow(F);
131 case LibFunc::strtol:
132 case LibFunc::strtod:
133 case LibFunc::strtof:
134 case LibFunc::strtoul:
135 case LibFunc::strtoll:
136 case LibFunc::strtold:
137 case LibFunc::strtoull:
138 if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
140 Changed |= setDoesNotThrow(F);
141 Changed |= setDoesNotCapture(F, 2);
142 Changed |= setOnlyReadsMemory(F, 1);
144 case LibFunc::strcpy:
145 case LibFunc::stpcpy:
146 case LibFunc::strcat:
147 case LibFunc::strncat:
148 case LibFunc::strncpy:
149 case LibFunc::stpncpy:
150 if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
152 Changed |= setDoesNotThrow(F);
153 Changed |= setDoesNotCapture(F, 2);
154 Changed |= setOnlyReadsMemory(F, 2);
156 case LibFunc::strxfrm:
157 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
158 !FTy->getParamType(1)->isPointerTy())
160 Changed |= setDoesNotThrow(F);
161 Changed |= setDoesNotCapture(F, 1);
162 Changed |= setDoesNotCapture(F, 2);
163 Changed |= setOnlyReadsMemory(F, 2);
165 case LibFunc::strcmp: // 0,1
166 case LibFunc::strspn: // 0,1
167 case LibFunc::strncmp: // 0,1
168 case LibFunc::strcspn: // 0,1
169 case LibFunc::strcoll: // 0,1
170 case LibFunc::strcasecmp: // 0,1
171 case LibFunc::strncasecmp: //
172 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
173 !FTy->getParamType(1)->isPointerTy())
175 Changed |= setOnlyReadsMemory(F);
176 Changed |= setDoesNotThrow(F);
177 Changed |= setDoesNotCapture(F, 1);
178 Changed |= setDoesNotCapture(F, 2);
180 case LibFunc::strstr:
181 case LibFunc::strpbrk:
182 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
184 Changed |= setOnlyReadsMemory(F);
185 Changed |= setDoesNotThrow(F);
186 Changed |= setDoesNotCapture(F, 2);
188 case LibFunc::strtok:
189 case LibFunc::strtok_r:
190 if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
192 Changed |= setDoesNotThrow(F);
193 Changed |= setDoesNotCapture(F, 2);
194 Changed |= setOnlyReadsMemory(F, 2);
197 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
199 Changed |= setDoesNotThrow(F);
200 Changed |= setDoesNotCapture(F, 1);
201 Changed |= setOnlyReadsMemory(F, 1);
203 case LibFunc::setbuf:
204 case LibFunc::setvbuf:
205 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
207 Changed |= setDoesNotThrow(F);
208 Changed |= setDoesNotCapture(F, 1);
210 case LibFunc::strdup:
211 case LibFunc::strndup:
212 if (FTy->getNumParams() < 1 || !FTy->getReturnType()->isPointerTy() ||
213 !FTy->getParamType(0)->isPointerTy())
215 Changed |= setDoesNotThrow(F);
216 Changed |= setDoesNotAlias(F, 0);
217 Changed |= setDoesNotCapture(F, 1);
218 Changed |= setOnlyReadsMemory(F, 1);
221 case LibFunc::statvfs:
222 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
223 !FTy->getParamType(1)->isPointerTy())
225 Changed |= setDoesNotThrow(F);
226 Changed |= setDoesNotCapture(F, 1);
227 Changed |= setDoesNotCapture(F, 2);
228 Changed |= setOnlyReadsMemory(F, 1);
230 case LibFunc::sscanf:
231 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
232 !FTy->getParamType(1)->isPointerTy())
234 Changed |= setDoesNotThrow(F);
235 Changed |= setDoesNotCapture(F, 1);
236 Changed |= setDoesNotCapture(F, 2);
237 Changed |= setOnlyReadsMemory(F, 1);
238 Changed |= setOnlyReadsMemory(F, 2);
240 case LibFunc::sprintf:
241 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
242 !FTy->getParamType(1)->isPointerTy())
244 Changed |= setDoesNotThrow(F);
245 Changed |= setDoesNotCapture(F, 1);
246 Changed |= setDoesNotCapture(F, 2);
247 Changed |= setOnlyReadsMemory(F, 2);
249 case LibFunc::snprintf:
250 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
251 !FTy->getParamType(2)->isPointerTy())
253 Changed |= setDoesNotThrow(F);
254 Changed |= setDoesNotCapture(F, 1);
255 Changed |= setDoesNotCapture(F, 3);
256 Changed |= setOnlyReadsMemory(F, 3);
258 case LibFunc::setitimer:
259 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy() ||
260 !FTy->getParamType(2)->isPointerTy())
262 Changed |= setDoesNotThrow(F);
263 Changed |= setDoesNotCapture(F, 2);
264 Changed |= setDoesNotCapture(F, 3);
265 Changed |= setOnlyReadsMemory(F, 2);
267 case LibFunc::system:
268 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
270 // May throw; "system" is a valid pthread cancellation point.
271 Changed |= setDoesNotCapture(F, 1);
272 Changed |= setOnlyReadsMemory(F, 1);
274 case LibFunc::malloc:
275 if (FTy->getNumParams() != 1 || !FTy->getReturnType()->isPointerTy())
277 Changed |= setDoesNotThrow(F);
278 Changed |= setDoesNotAlias(F, 0);
280 case LibFunc::memcmp:
281 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
282 !FTy->getParamType(1)->isPointerTy())
284 Changed |= setOnlyReadsMemory(F);
285 Changed |= setDoesNotThrow(F);
286 Changed |= setDoesNotCapture(F, 1);
287 Changed |= setDoesNotCapture(F, 2);
289 case LibFunc::memchr:
290 case LibFunc::memrchr:
291 if (FTy->getNumParams() != 3)
293 Changed |= setOnlyReadsMemory(F);
294 Changed |= setDoesNotThrow(F);
299 if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
301 Changed |= setDoesNotThrow(F);
302 Changed |= setDoesNotCapture(F, 2);
304 case LibFunc::memcpy:
305 case LibFunc::memccpy:
306 case LibFunc::memmove:
307 if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
309 Changed |= setDoesNotThrow(F);
310 Changed |= setDoesNotCapture(F, 2);
311 Changed |= setOnlyReadsMemory(F, 2);
313 case LibFunc::memalign:
314 if (!FTy->getReturnType()->isPointerTy())
316 Changed |= setDoesNotAlias(F, 0);
319 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
321 Changed |= setDoesNotThrow(F);
322 Changed |= setDoesNotCapture(F, 1);
323 Changed |= setOnlyReadsMemory(F, 1);
325 case LibFunc::mktime:
326 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
328 Changed |= setDoesNotThrow(F);
329 Changed |= setDoesNotCapture(F, 1);
331 case LibFunc::realloc:
332 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
333 !FTy->getReturnType()->isPointerTy())
335 Changed |= setDoesNotThrow(F);
336 Changed |= setDoesNotAlias(F, 0);
337 Changed |= setDoesNotCapture(F, 1);
340 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy())
342 // May throw; "read" is a valid pthread cancellation point.
343 Changed |= setDoesNotCapture(F, 2);
345 case LibFunc::rewind:
346 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
348 Changed |= setDoesNotThrow(F);
349 Changed |= setDoesNotCapture(F, 1);
352 case LibFunc::remove:
353 case LibFunc::realpath:
354 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
356 Changed |= setDoesNotThrow(F);
357 Changed |= setDoesNotCapture(F, 1);
358 Changed |= setOnlyReadsMemory(F, 1);
360 case LibFunc::rename:
361 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
362 !FTy->getParamType(1)->isPointerTy())
364 Changed |= setDoesNotThrow(F);
365 Changed |= setDoesNotCapture(F, 1);
366 Changed |= setDoesNotCapture(F, 2);
367 Changed |= setOnlyReadsMemory(F, 1);
368 Changed |= setOnlyReadsMemory(F, 2);
370 case LibFunc::readlink:
371 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
372 !FTy->getParamType(1)->isPointerTy())
374 Changed |= setDoesNotThrow(F);
375 Changed |= setDoesNotCapture(F, 1);
376 Changed |= setDoesNotCapture(F, 2);
377 Changed |= setOnlyReadsMemory(F, 1);
380 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy())
382 // May throw; "write" is a valid pthread cancellation point.
383 Changed |= setDoesNotCapture(F, 2);
384 Changed |= setOnlyReadsMemory(F, 2);
387 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
388 !FTy->getParamType(1)->isPointerTy())
390 Changed |= setDoesNotThrow(F);
391 Changed |= setDoesNotCapture(F, 1);
392 Changed |= setDoesNotCapture(F, 2);
393 Changed |= setOnlyReadsMemory(F, 1);
396 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
397 !FTy->getParamType(1)->isPointerTy())
399 Changed |= setDoesNotThrow(F);
400 Changed |= setOnlyReadsMemory(F);
401 Changed |= setDoesNotCapture(F, 1);
402 Changed |= setDoesNotCapture(F, 2);
405 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
407 Changed |= setDoesNotThrow(F);
408 Changed |= setDoesNotCapture(F, 1);
410 case LibFunc::calloc:
411 if (FTy->getNumParams() != 2 || !FTy->getReturnType()->isPointerTy())
413 Changed |= setDoesNotThrow(F);
414 Changed |= setDoesNotAlias(F, 0);
418 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
420 Changed |= setDoesNotThrow(F);
421 Changed |= setDoesNotCapture(F, 1);
422 Changed |= setOnlyReadsMemory(F, 1);
424 case LibFunc::ctermid:
425 case LibFunc::clearerr:
426 case LibFunc::closedir:
427 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
429 Changed |= setDoesNotThrow(F);
430 Changed |= setDoesNotCapture(F, 1);
436 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
438 Changed |= setDoesNotThrow(F);
439 Changed |= setOnlyReadsMemory(F);
440 Changed |= setDoesNotCapture(F, 1);
442 case LibFunc::access:
443 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
445 Changed |= setDoesNotThrow(F);
446 Changed |= setDoesNotCapture(F, 1);
447 Changed |= setOnlyReadsMemory(F, 1);
450 if (FTy->getNumParams() != 2 || !FTy->getReturnType()->isPointerTy() ||
451 !FTy->getParamType(0)->isPointerTy() ||
452 !FTy->getParamType(1)->isPointerTy())
454 Changed |= setDoesNotThrow(F);
455 Changed |= setDoesNotAlias(F, 0);
456 Changed |= setDoesNotCapture(F, 1);
457 Changed |= setDoesNotCapture(F, 2);
458 Changed |= setOnlyReadsMemory(F, 1);
459 Changed |= setOnlyReadsMemory(F, 2);
461 case LibFunc::fdopen:
462 if (FTy->getNumParams() != 2 || !FTy->getReturnType()->isPointerTy() ||
463 !FTy->getParamType(1)->isPointerTy())
465 Changed |= setDoesNotThrow(F);
466 Changed |= setDoesNotAlias(F, 0);
467 Changed |= setDoesNotCapture(F, 2);
468 Changed |= setOnlyReadsMemory(F, 2);
475 case LibFunc::fseeko:
476 case LibFunc::ftello:
477 case LibFunc::fileno:
478 case LibFunc::fflush:
479 case LibFunc::fclose:
480 case LibFunc::fsetpos:
481 case LibFunc::flockfile:
482 case LibFunc::funlockfile:
483 case LibFunc::ftrylockfile:
484 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
486 Changed |= setDoesNotThrow(F);
487 Changed |= setDoesNotCapture(F, 1);
489 case LibFunc::ferror:
490 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
492 Changed |= setDoesNotThrow(F);
493 Changed |= setDoesNotCapture(F, 1);
494 Changed |= setOnlyReadsMemory(F);
499 case LibFunc::frexpf:
500 case LibFunc::frexpl:
501 case LibFunc::fstatvfs:
502 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
504 Changed |= setDoesNotThrow(F);
505 Changed |= setDoesNotCapture(F, 2);
508 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
509 !FTy->getParamType(2)->isPointerTy())
511 Changed |= setDoesNotThrow(F);
512 Changed |= setDoesNotCapture(F, 3);
515 if (FTy->getNumParams() != 4 || !FTy->getParamType(0)->isPointerTy() ||
516 !FTy->getParamType(3)->isPointerTy())
518 Changed |= setDoesNotThrow(F);
519 Changed |= setDoesNotCapture(F, 1);
520 Changed |= setDoesNotCapture(F, 4);
522 case LibFunc::fwrite:
523 if (FTy->getNumParams() != 4 || !FTy->getParamType(0)->isPointerTy() ||
524 !FTy->getParamType(3)->isPointerTy())
526 Changed |= setDoesNotThrow(F);
527 Changed |= setDoesNotCapture(F, 1);
528 Changed |= setDoesNotCapture(F, 4);
531 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
532 !FTy->getParamType(1)->isPointerTy())
534 Changed |= setDoesNotThrow(F);
535 Changed |= setDoesNotCapture(F, 1);
536 Changed |= setDoesNotCapture(F, 2);
537 Changed |= setOnlyReadsMemory(F, 1);
539 case LibFunc::fscanf:
540 case LibFunc::fprintf:
541 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
542 !FTy->getParamType(1)->isPointerTy())
544 Changed |= setDoesNotThrow(F);
545 Changed |= setDoesNotCapture(F, 1);
546 Changed |= setDoesNotCapture(F, 2);
547 Changed |= setOnlyReadsMemory(F, 2);
549 case LibFunc::fgetpos:
550 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
551 !FTy->getParamType(1)->isPointerTy())
553 Changed |= setDoesNotThrow(F);
554 Changed |= setDoesNotCapture(F, 1);
555 Changed |= setDoesNotCapture(F, 2);
558 case LibFunc::getlogin_r:
559 case LibFunc::getc_unlocked:
560 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
562 Changed |= setDoesNotThrow(F);
563 Changed |= setDoesNotCapture(F, 1);
565 case LibFunc::getenv:
566 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
568 Changed |= setDoesNotThrow(F);
569 Changed |= setOnlyReadsMemory(F);
570 Changed |= setDoesNotCapture(F, 1);
573 case LibFunc::getchar:
574 Changed |= setDoesNotThrow(F);
576 case LibFunc::getitimer:
577 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
579 Changed |= setDoesNotThrow(F);
580 Changed |= setDoesNotCapture(F, 2);
582 case LibFunc::getpwnam:
583 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
585 Changed |= setDoesNotThrow(F);
586 Changed |= setDoesNotCapture(F, 1);
587 Changed |= setOnlyReadsMemory(F, 1);
589 case LibFunc::ungetc:
590 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
592 Changed |= setDoesNotThrow(F);
593 Changed |= setDoesNotCapture(F, 2);
596 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
598 Changed |= setDoesNotThrow(F);
599 Changed |= setDoesNotCapture(F, 1);
601 case LibFunc::unlink:
602 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
604 Changed |= setDoesNotThrow(F);
605 Changed |= setDoesNotCapture(F, 1);
606 Changed |= setOnlyReadsMemory(F, 1);
608 case LibFunc::unsetenv:
609 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
611 Changed |= setDoesNotThrow(F);
612 Changed |= setDoesNotCapture(F, 1);
613 Changed |= setOnlyReadsMemory(F, 1);
616 case LibFunc::utimes:
617 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
618 !FTy->getParamType(1)->isPointerTy())
620 Changed |= setDoesNotThrow(F);
621 Changed |= setDoesNotCapture(F, 1);
622 Changed |= setDoesNotCapture(F, 2);
623 Changed |= setOnlyReadsMemory(F, 1);
624 Changed |= setOnlyReadsMemory(F, 2);
627 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
629 Changed |= setDoesNotThrow(F);
630 Changed |= setDoesNotCapture(F, 2);
633 case LibFunc::printf:
634 case LibFunc::perror:
635 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
637 Changed |= setDoesNotThrow(F);
638 Changed |= setDoesNotCapture(F, 1);
639 Changed |= setOnlyReadsMemory(F, 1);
642 if (FTy->getNumParams() != 4 || !FTy->getParamType(1)->isPointerTy())
644 // May throw; "pread" is a valid pthread cancellation point.
645 Changed |= setDoesNotCapture(F, 2);
647 case LibFunc::pwrite:
648 if (FTy->getNumParams() != 4 || !FTy->getParamType(1)->isPointerTy())
650 // May throw; "pwrite" is a valid pthread cancellation point.
651 Changed |= setDoesNotCapture(F, 2);
652 Changed |= setOnlyReadsMemory(F, 2);
654 case LibFunc::putchar:
655 Changed |= setDoesNotThrow(F);
658 if (FTy->getNumParams() != 2 || !FTy->getReturnType()->isPointerTy() ||
659 !FTy->getParamType(0)->isPointerTy() ||
660 !FTy->getParamType(1)->isPointerTy())
662 Changed |= setDoesNotThrow(F);
663 Changed |= setDoesNotAlias(F, 0);
664 Changed |= setDoesNotCapture(F, 1);
665 Changed |= setDoesNotCapture(F, 2);
666 Changed |= setOnlyReadsMemory(F, 1);
667 Changed |= setOnlyReadsMemory(F, 2);
669 case LibFunc::pclose:
670 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
672 Changed |= setDoesNotThrow(F);
673 Changed |= setDoesNotCapture(F, 1);
675 case LibFunc::vscanf:
676 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
678 Changed |= setDoesNotThrow(F);
679 Changed |= setDoesNotCapture(F, 1);
680 Changed |= setOnlyReadsMemory(F, 1);
682 case LibFunc::vsscanf:
683 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy() ||
684 !FTy->getParamType(2)->isPointerTy())
686 Changed |= setDoesNotThrow(F);
687 Changed |= setDoesNotCapture(F, 1);
688 Changed |= setDoesNotCapture(F, 2);
689 Changed |= setOnlyReadsMemory(F, 1);
690 Changed |= setOnlyReadsMemory(F, 2);
692 case LibFunc::vfscanf:
693 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy() ||
694 !FTy->getParamType(2)->isPointerTy())
696 Changed |= setDoesNotThrow(F);
697 Changed |= setDoesNotCapture(F, 1);
698 Changed |= setDoesNotCapture(F, 2);
699 Changed |= setOnlyReadsMemory(F, 2);
701 case LibFunc::valloc:
702 if (!FTy->getReturnType()->isPointerTy())
704 Changed |= setDoesNotThrow(F);
705 Changed |= setDoesNotAlias(F, 0);
707 case LibFunc::vprintf:
708 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
710 Changed |= setDoesNotThrow(F);
711 Changed |= setDoesNotCapture(F, 1);
712 Changed |= setOnlyReadsMemory(F, 1);
714 case LibFunc::vfprintf:
715 case LibFunc::vsprintf:
716 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
717 !FTy->getParamType(1)->isPointerTy())
719 Changed |= setDoesNotThrow(F);
720 Changed |= setDoesNotCapture(F, 1);
721 Changed |= setDoesNotCapture(F, 2);
722 Changed |= setOnlyReadsMemory(F, 2);
724 case LibFunc::vsnprintf:
725 if (FTy->getNumParams() != 4 || !FTy->getParamType(0)->isPointerTy() ||
726 !FTy->getParamType(2)->isPointerTy())
728 Changed |= setDoesNotThrow(F);
729 Changed |= setDoesNotCapture(F, 1);
730 Changed |= setDoesNotCapture(F, 3);
731 Changed |= setOnlyReadsMemory(F, 3);
734 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy())
736 // May throw; "open" is a valid pthread cancellation point.
737 Changed |= setDoesNotCapture(F, 1);
738 Changed |= setOnlyReadsMemory(F, 1);
740 case LibFunc::opendir:
741 if (FTy->getNumParams() != 1 || !FTy->getReturnType()->isPointerTy() ||
742 !FTy->getParamType(0)->isPointerTy())
744 Changed |= setDoesNotThrow(F);
745 Changed |= setDoesNotAlias(F, 0);
746 Changed |= setDoesNotCapture(F, 1);
747 Changed |= setOnlyReadsMemory(F, 1);
749 case LibFunc::tmpfile:
750 if (!FTy->getReturnType()->isPointerTy())
752 Changed |= setDoesNotThrow(F);
753 Changed |= setDoesNotAlias(F, 0);
756 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
758 Changed |= setDoesNotThrow(F);
759 Changed |= setDoesNotCapture(F, 1);
765 Changed |= setDoesNotThrow(F);
766 Changed |= setDoesNotAccessMemory(F);
769 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
770 !FTy->getParamType(1)->isPointerTy())
772 Changed |= setDoesNotThrow(F);
773 Changed |= setDoesNotCapture(F, 1);
774 Changed |= setDoesNotCapture(F, 2);
775 Changed |= setOnlyReadsMemory(F, 1);
777 case LibFunc::lchown:
778 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy())
780 Changed |= setDoesNotThrow(F);
781 Changed |= setDoesNotCapture(F, 1);
782 Changed |= setOnlyReadsMemory(F, 1);
785 if (FTy->getNumParams() != 4 || !FTy->getParamType(3)->isPointerTy())
787 // May throw; places call through function pointer.
788 Changed |= setDoesNotCapture(F, 4);
790 case LibFunc::dunder_strdup:
791 case LibFunc::dunder_strndup:
792 if (FTy->getNumParams() < 1 || !FTy->getReturnType()->isPointerTy() ||
793 !FTy->getParamType(0)->isPointerTy())
795 Changed |= setDoesNotThrow(F);
796 Changed |= setDoesNotAlias(F, 0);
797 Changed |= setDoesNotCapture(F, 1);
798 Changed |= setOnlyReadsMemory(F, 1);
800 case LibFunc::dunder_strtok_r:
801 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy())
803 Changed |= setDoesNotThrow(F);
804 Changed |= setDoesNotCapture(F, 2);
805 Changed |= setOnlyReadsMemory(F, 2);
807 case LibFunc::under_IO_getc:
808 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
810 Changed |= setDoesNotThrow(F);
811 Changed |= setDoesNotCapture(F, 1);
813 case LibFunc::under_IO_putc:
814 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
816 Changed |= setDoesNotThrow(F);
817 Changed |= setDoesNotCapture(F, 2);
819 case LibFunc::dunder_isoc99_scanf:
820 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
822 Changed |= setDoesNotThrow(F);
823 Changed |= setDoesNotCapture(F, 1);
824 Changed |= setOnlyReadsMemory(F, 1);
826 case LibFunc::stat64:
827 case LibFunc::lstat64:
828 case LibFunc::statvfs64:
829 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy() ||
830 !FTy->getParamType(1)->isPointerTy())
832 Changed |= setDoesNotThrow(F);
833 Changed |= setDoesNotCapture(F, 1);
834 Changed |= setDoesNotCapture(F, 2);
835 Changed |= setOnlyReadsMemory(F, 1);
837 case LibFunc::dunder_isoc99_sscanf:
838 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy() ||
839 !FTy->getParamType(1)->isPointerTy())
841 Changed |= setDoesNotThrow(F);
842 Changed |= setDoesNotCapture(F, 1);
843 Changed |= setDoesNotCapture(F, 2);
844 Changed |= setOnlyReadsMemory(F, 1);
845 Changed |= setOnlyReadsMemory(F, 2);
847 case LibFunc::fopen64:
848 if (FTy->getNumParams() != 2 || !FTy->getReturnType()->isPointerTy() ||
849 !FTy->getParamType(0)->isPointerTy() ||
850 !FTy->getParamType(1)->isPointerTy())
852 Changed |= setDoesNotThrow(F);
853 Changed |= setDoesNotAlias(F, 0);
854 Changed |= setDoesNotCapture(F, 1);
855 Changed |= setDoesNotCapture(F, 2);
856 Changed |= setOnlyReadsMemory(F, 1);
857 Changed |= setOnlyReadsMemory(F, 2);
859 case LibFunc::fseeko64:
860 case LibFunc::ftello64:
861 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
863 Changed |= setDoesNotThrow(F);
864 Changed |= setDoesNotCapture(F, 1);
866 case LibFunc::tmpfile64:
867 if (!FTy->getReturnType()->isPointerTy())
869 Changed |= setDoesNotThrow(F);
870 Changed |= setDoesNotAlias(F, 0);
872 case LibFunc::fstat64:
873 case LibFunc::fstatvfs64:
874 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
876 Changed |= setDoesNotThrow(F);
877 Changed |= setDoesNotCapture(F, 2);
879 case LibFunc::open64:
880 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy())
882 // May throw; "open" is a valid pthread cancellation point.
883 Changed |= setDoesNotCapture(F, 1);
884 Changed |= setOnlyReadsMemory(F, 1);
886 case LibFunc::gettimeofday:
887 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
888 !FTy->getParamType(1)->isPointerTy())
890 // Currently some platforms have the restrict keyword on the arguments to
891 // gettimeofday. To be conservative, do not add noalias to gettimeofday's
893 Changed |= setDoesNotThrow(F);
894 Changed |= setDoesNotCapture(F, 1);
895 Changed |= setDoesNotCapture(F, 2);
898 case LibFunc::Znwj: // new(unsigned int)
899 case LibFunc::Znwm: // new(unsigned long)
900 case LibFunc::Znaj: // new[](unsigned int)
901 case LibFunc::Znam: // new[](unsigned long)
902 case LibFunc::msvc_new_int: // new(unsigned int)
903 case LibFunc::msvc_new_longlong: // new(unsigned long long)
904 case LibFunc::msvc_new_array_int: // new[](unsigned int)
905 case LibFunc::msvc_new_array_longlong: // new[](unsigned long long)
906 if (FTy->getNumParams() != 1)
908 // Operator new always returns a nonnull noalias pointer
909 Changed |= setNonNull(F, AttributeSet::ReturnIndex);
910 Changed |= setDoesNotAlias(F, AttributeSet::ReturnIndex);
913 //TODO: add LibFunc entries for:
914 //case LibFunc::memset_pattern4:
915 //case LibFunc::memset_pattern8:
916 case LibFunc::memset_pattern16:
917 if (FTy->isVarArg() || FTy->getNumParams() != 3 ||
918 !isa<PointerType>(FTy->getParamType(0)) ||
919 !isa<PointerType>(FTy->getParamType(1)) ||
920 !isa<IntegerType>(FTy->getParamType(2)))
923 Changed |= setOnlyAccessesArgMemory(F);
924 Changed |= setOnlyReadsMemory(F, 2);
928 // FIXME: It'd be really nice to cover all the library functions we're
934 static bool inferAllPrototypeAttributes(Module &M,
935 const TargetLibraryInfo &TLI) {
936 bool Changed = false;
938 for (Function &F : M.functions())
939 // We only infer things using the prototype if the definition isn't around
940 // to analyze directly.
941 if (F.isDeclaration())
942 Changed |= inferPrototypeAttributes(F, TLI);
947 PreservedAnalyses InferFunctionAttrsPass::run(Module &M,
948 AnalysisManager<Module> *AM) {
949 auto &TLI = AM->getResult<TargetLibraryAnalysis>(M);
951 if (!inferAllPrototypeAttributes(M, TLI))
952 // If we didn't infer anything, preserve all analyses.
953 return PreservedAnalyses::all();
955 // Otherwise, we may have changed fundamental function attributes, so clear
956 // out all the passes.
957 return PreservedAnalyses::none();
961 struct InferFunctionAttrsLegacyPass : public ModulePass {
962 static char ID; // Pass identification, replacement for typeid
963 InferFunctionAttrsLegacyPass() : ModulePass(ID) {
964 initializeInferFunctionAttrsLegacyPassPass(
965 *PassRegistry::getPassRegistry());
968 void getAnalysisUsage(AnalysisUsage &AU) const override {
969 AU.addRequired<TargetLibraryInfoWrapperPass>();
972 bool runOnModule(Module &M) override {
973 auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
974 return inferAllPrototypeAttributes(M, TLI);
979 char InferFunctionAttrsLegacyPass::ID = 0;
980 INITIALIZE_PASS_BEGIN(InferFunctionAttrsLegacyPass, "inferattrs",
981 "Infer set function attributes", false, false)
982 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
983 INITIALIZE_PASS_END(InferFunctionAttrsLegacyPass, "inferattrs",
984 "Infer set function attributes", false, false)
986 Pass *llvm::createInferFunctionAttrsLegacyPass() {
987 return new InferFunctionAttrsLegacyPass();