blob: d02c861a294817e97308e5a0e226fd047a98df5f [file] [log] [blame]
Chandler Carruth3a040e62015-12-27 08:41:34 +00001//===- InferFunctionAttrs.cpp - Infer implicit function attributes --------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#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"
18using namespace llvm;
19
20#define DEBUG_TYPE "inferattrs"
21
22STATISTIC(NumReadNone, "Number of functions inferred as readnone");
23STATISTIC(NumReadOnly, "Number of functions inferred as readonly");
24STATISTIC(NumNoUnwind, "Number of functions inferred as nounwind");
25STATISTIC(NumNoCapture, "Number of arguments inferred as nocapture");
26STATISTIC(NumReadOnlyArg, "Number of arguments inferred as readonly");
27STATISTIC(NumNoAlias, "Number of function returns inferred as noalias");
28
29static bool setDoesNotAccessMemory(Function &F) {
30 if (F.doesNotAccessMemory())
31 return false;
32 F.setDoesNotAccessMemory();
33 ++NumReadNone;
34 return true;
35}
36
37static bool setOnlyReadsMemory(Function &F) {
38 if (F.onlyReadsMemory())
39 return false;
40 F.setOnlyReadsMemory();
41 ++NumReadOnly;
42 return true;
43}
44
45static bool setDoesNotThrow(Function &F) {
46 if (F.doesNotThrow())
47 return false;
48 F.setDoesNotThrow();
49 ++NumNoUnwind;
50 return true;
51}
52
53static bool setDoesNotCapture(Function &F, unsigned n) {
54 if (F.doesNotCapture(n))
55 return false;
56 F.setDoesNotCapture(n);
57 ++NumNoCapture;
58 return true;
59}
60
61static bool setOnlyReadsMemory(Function &F, unsigned n) {
62 if (F.onlyReadsMemory(n))
63 return false;
64 F.setOnlyReadsMemory(n);
65 ++NumReadOnlyArg;
66 return true;
67}
68
69static bool setDoesNotAlias(Function &F, unsigned n) {
70 if (F.doesNotAlias(n))
71 return false;
72 F.setDoesNotAlias(n);
73 ++NumNoAlias;
74 return true;
75}
76
77/// Analyze the name and prototype of the given function and set any applicable
78/// attributes.
79///
80/// Returns true if any attributes were set and false otherwise.
81static bool inferPrototypeAttributes(Function &F,
82 const TargetLibraryInfo &TLI) {
83 if (F.hasFnAttribute(Attribute::OptimizeNone))
84 return false;
85
86 FunctionType *FTy = F.getFunctionType();
87 LibFunc::Func TheLibFunc;
88 if (!(TLI.getLibFunc(F.getName(), TheLibFunc) && TLI.has(TheLibFunc)))
89 return false;
90
91 bool Changed = false;
92
93 switch (TheLibFunc) {
94 case LibFunc::strlen:
95 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
96 return false;
97 Changed |= setOnlyReadsMemory(F);
98 Changed |= setDoesNotThrow(F);
99 Changed |= setDoesNotCapture(F, 1);
100 return Changed;
101 case LibFunc::strchr:
102 case LibFunc::strrchr:
103 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
104 !FTy->getParamType(1)->isIntegerTy())
105 return false;
106 Changed |= setOnlyReadsMemory(F);
107 Changed |= setDoesNotThrow(F);
108 return Changed;
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())
117 return false;
118 Changed |= setDoesNotThrow(F);
119 Changed |= setDoesNotCapture(F, 2);
120 Changed |= setOnlyReadsMemory(F, 1);
121 return Changed;
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())
129 return false;
130 Changed |= setDoesNotThrow(F);
131 Changed |= setDoesNotCapture(F, 2);
132 Changed |= setOnlyReadsMemory(F, 2);
133 return Changed;
134 case LibFunc::strxfrm:
135 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
136 !FTy->getParamType(1)->isPointerTy())
137 return false;
138 Changed |= setDoesNotThrow(F);
139 Changed |= setDoesNotCapture(F, 1);
140 Changed |= setDoesNotCapture(F, 2);
141 Changed |= setOnlyReadsMemory(F, 2);
142 return Changed;
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())
152 return false;
153 Changed |= setOnlyReadsMemory(F);
154 Changed |= setDoesNotThrow(F);
155 Changed |= setDoesNotCapture(F, 1);
156 Changed |= setDoesNotCapture(F, 2);
157 return Changed;
158 case LibFunc::strstr:
159 case LibFunc::strpbrk:
160 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
161 return false;
162 Changed |= setOnlyReadsMemory(F);
163 Changed |= setDoesNotThrow(F);
164 Changed |= setDoesNotCapture(F, 2);
165 return Changed;
166 case LibFunc::strtok:
167 case LibFunc::strtok_r:
168 if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
169 return false;
170 Changed |= setDoesNotThrow(F);
171 Changed |= setDoesNotCapture(F, 2);
172 Changed |= setOnlyReadsMemory(F, 2);
173 return Changed;
174 case LibFunc::scanf:
175 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
176 return false;
177 Changed |= setDoesNotThrow(F);
178 Changed |= setDoesNotCapture(F, 1);
179 Changed |= setOnlyReadsMemory(F, 1);
180 return Changed;
181 case LibFunc::setbuf:
182 case LibFunc::setvbuf:
183 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
184 return false;
185 Changed |= setDoesNotThrow(F);
186 Changed |= setDoesNotCapture(F, 1);
187 return Changed;
188 case LibFunc::strdup:
189 case LibFunc::strndup:
190 if (FTy->getNumParams() < 1 || !FTy->getReturnType()->isPointerTy() ||
191 !FTy->getParamType(0)->isPointerTy())
192 return false;
193 Changed |= setDoesNotThrow(F);
194 Changed |= setDoesNotAlias(F, 0);
195 Changed |= setDoesNotCapture(F, 1);
196 Changed |= setOnlyReadsMemory(F, 1);
197 return Changed;
198 case LibFunc::stat:
199 case LibFunc::statvfs:
200 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
201 !FTy->getParamType(1)->isPointerTy())
202 return false;
203 Changed |= setDoesNotThrow(F);
204 Changed |= setDoesNotCapture(F, 1);
205 Changed |= setDoesNotCapture(F, 2);
206 Changed |= setOnlyReadsMemory(F, 1);
207 return Changed;
208 case LibFunc::sscanf:
209 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
210 !FTy->getParamType(1)->isPointerTy())
211 return false;
212 Changed |= setDoesNotThrow(F);
213 Changed |= setDoesNotCapture(F, 1);
214 Changed |= setDoesNotCapture(F, 2);
215 Changed |= setOnlyReadsMemory(F, 1);
216 Changed |= setOnlyReadsMemory(F, 2);
217 return Changed;
218 case LibFunc::sprintf:
219 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
220 !FTy->getParamType(1)->isPointerTy())
221 return false;
222 Changed |= setDoesNotThrow(F);
223 Changed |= setDoesNotCapture(F, 1);
224 Changed |= setDoesNotCapture(F, 2);
225 Changed |= setOnlyReadsMemory(F, 2);
226 return Changed;
227 case LibFunc::snprintf:
228 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
229 !FTy->getParamType(2)->isPointerTy())
230 return false;
231 Changed |= setDoesNotThrow(F);
232 Changed |= setDoesNotCapture(F, 1);
233 Changed |= setDoesNotCapture(F, 3);
234 Changed |= setOnlyReadsMemory(F, 3);
235 return Changed;
236 case LibFunc::setitimer:
237 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy() ||
238 !FTy->getParamType(2)->isPointerTy())
239 return false;
240 Changed |= setDoesNotThrow(F);
241 Changed |= setDoesNotCapture(F, 2);
242 Changed |= setDoesNotCapture(F, 3);
243 Changed |= setOnlyReadsMemory(F, 2);
244 return Changed;
245 case LibFunc::system:
246 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
247 return false;
248 // May throw; "system" is a valid pthread cancellation point.
249 Changed |= setDoesNotCapture(F, 1);
250 Changed |= setOnlyReadsMemory(F, 1);
251 return Changed;
252 case LibFunc::malloc:
253 if (FTy->getNumParams() != 1 || !FTy->getReturnType()->isPointerTy())
254 return false;
255 Changed |= setDoesNotThrow(F);
256 Changed |= setDoesNotAlias(F, 0);
257 return Changed;
258 case LibFunc::memcmp:
259 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
260 !FTy->getParamType(1)->isPointerTy())
261 return false;
262 Changed |= setOnlyReadsMemory(F);
263 Changed |= setDoesNotThrow(F);
264 Changed |= setDoesNotCapture(F, 1);
265 Changed |= setDoesNotCapture(F, 2);
266 return Changed;
267 case LibFunc::memchr:
268 case LibFunc::memrchr:
269 if (FTy->getNumParams() != 3)
270 return false;
271 Changed |= setOnlyReadsMemory(F);
272 Changed |= setDoesNotThrow(F);
273 return Changed;
274 case LibFunc::modf:
275 case LibFunc::modff:
276 case LibFunc::modfl:
277 if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
278 return false;
279 Changed |= setDoesNotThrow(F);
280 Changed |= setDoesNotCapture(F, 2);
281 return Changed;
282 case LibFunc::memcpy:
283 case LibFunc::memccpy:
284 case LibFunc::memmove:
285 if (FTy->getNumParams() < 2 || !FTy->getParamType(1)->isPointerTy())
286 return false;
287 Changed |= setDoesNotThrow(F);
288 Changed |= setDoesNotCapture(F, 2);
289 Changed |= setOnlyReadsMemory(F, 2);
290 return Changed;
291 case LibFunc::memalign:
292 if (!FTy->getReturnType()->isPointerTy())
293 return false;
294 Changed |= setDoesNotAlias(F, 0);
295 return Changed;
296 case LibFunc::mkdir:
297 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
298 return false;
299 Changed |= setDoesNotThrow(F);
300 Changed |= setDoesNotCapture(F, 1);
301 Changed |= setOnlyReadsMemory(F, 1);
302 return Changed;
303 case LibFunc::mktime:
304 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
305 return false;
306 Changed |= setDoesNotThrow(F);
307 Changed |= setDoesNotCapture(F, 1);
308 return Changed;
309 case LibFunc::realloc:
310 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
311 !FTy->getReturnType()->isPointerTy())
312 return false;
313 Changed |= setDoesNotThrow(F);
314 Changed |= setDoesNotAlias(F, 0);
315 Changed |= setDoesNotCapture(F, 1);
316 return Changed;
317 case LibFunc::read:
318 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy())
319 return false;
320 // May throw; "read" is a valid pthread cancellation point.
321 Changed |= setDoesNotCapture(F, 2);
322 return Changed;
323 case LibFunc::rewind:
324 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
325 return false;
326 Changed |= setDoesNotThrow(F);
327 Changed |= setDoesNotCapture(F, 1);
328 return Changed;
329 case LibFunc::rmdir:
330 case LibFunc::remove:
331 case LibFunc::realpath:
332 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
333 return false;
334 Changed |= setDoesNotThrow(F);
335 Changed |= setDoesNotCapture(F, 1);
336 Changed |= setOnlyReadsMemory(F, 1);
337 return Changed;
338 case LibFunc::rename:
339 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
340 !FTy->getParamType(1)->isPointerTy())
341 return false;
342 Changed |= setDoesNotThrow(F);
343 Changed |= setDoesNotCapture(F, 1);
344 Changed |= setDoesNotCapture(F, 2);
345 Changed |= setOnlyReadsMemory(F, 1);
346 Changed |= setOnlyReadsMemory(F, 2);
347 return Changed;
348 case LibFunc::readlink:
349 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
350 !FTy->getParamType(1)->isPointerTy())
351 return false;
352 Changed |= setDoesNotThrow(F);
353 Changed |= setDoesNotCapture(F, 1);
354 Changed |= setDoesNotCapture(F, 2);
355 Changed |= setOnlyReadsMemory(F, 1);
356 return Changed;
357 case LibFunc::write:
358 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy())
359 return false;
360 // May throw; "write" is a valid pthread cancellation point.
361 Changed |= setDoesNotCapture(F, 2);
362 Changed |= setOnlyReadsMemory(F, 2);
363 return Changed;
364 case LibFunc::bcopy:
365 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
366 !FTy->getParamType(1)->isPointerTy())
367 return false;
368 Changed |= setDoesNotThrow(F);
369 Changed |= setDoesNotCapture(F, 1);
370 Changed |= setDoesNotCapture(F, 2);
371 Changed |= setOnlyReadsMemory(F, 1);
372 return Changed;
373 case LibFunc::bcmp:
374 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
375 !FTy->getParamType(1)->isPointerTy())
376 return false;
377 Changed |= setDoesNotThrow(F);
378 Changed |= setOnlyReadsMemory(F);
379 Changed |= setDoesNotCapture(F, 1);
380 Changed |= setDoesNotCapture(F, 2);
381 return Changed;
382 case LibFunc::bzero:
383 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
384 return false;
385 Changed |= setDoesNotThrow(F);
386 Changed |= setDoesNotCapture(F, 1);
387 return Changed;
388 case LibFunc::calloc:
389 if (FTy->getNumParams() != 2 || !FTy->getReturnType()->isPointerTy())
390 return false;
391 Changed |= setDoesNotThrow(F);
392 Changed |= setDoesNotAlias(F, 0);
393 return Changed;
394 case LibFunc::chmod:
395 case LibFunc::chown:
396 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
397 return false;
398 Changed |= setDoesNotThrow(F);
399 Changed |= setDoesNotCapture(F, 1);
400 Changed |= setOnlyReadsMemory(F, 1);
401 return Changed;
402 case LibFunc::ctermid:
403 case LibFunc::clearerr:
404 case LibFunc::closedir:
405 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
406 return false;
407 Changed |= setDoesNotThrow(F);
408 Changed |= setDoesNotCapture(F, 1);
409 return Changed;
410 case LibFunc::atoi:
411 case LibFunc::atol:
412 case LibFunc::atof:
413 case LibFunc::atoll:
414 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
415 return false;
416 Changed |= setDoesNotThrow(F);
417 Changed |= setOnlyReadsMemory(F);
418 Changed |= setDoesNotCapture(F, 1);
419 return Changed;
420 case LibFunc::access:
421 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
422 return false;
423 Changed |= setDoesNotThrow(F);
424 Changed |= setDoesNotCapture(F, 1);
425 Changed |= setOnlyReadsMemory(F, 1);
426 return Changed;
427 case LibFunc::fopen:
428 if (FTy->getNumParams() != 2 || !FTy->getReturnType()->isPointerTy() ||
429 !FTy->getParamType(0)->isPointerTy() ||
430 !FTy->getParamType(1)->isPointerTy())
431 return false;
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);
438 return Changed;
439 case LibFunc::fdopen:
440 if (FTy->getNumParams() != 2 || !FTy->getReturnType()->isPointerTy() ||
441 !FTy->getParamType(1)->isPointerTy())
442 return false;
443 Changed |= setDoesNotThrow(F);
444 Changed |= setDoesNotAlias(F, 0);
445 Changed |= setDoesNotCapture(F, 2);
446 Changed |= setOnlyReadsMemory(F, 2);
447 return Changed;
448 case LibFunc::feof:
449 case LibFunc::free:
450 case LibFunc::fseek:
451 case LibFunc::ftell:
452 case LibFunc::fgetc:
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())
463 return false;
464 Changed |= setDoesNotThrow(F);
465 Changed |= setDoesNotCapture(F, 1);
466 return Changed;
467 case LibFunc::ferror:
468 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
469 return false;
470 Changed |= setDoesNotThrow(F);
471 Changed |= setDoesNotCapture(F, 1);
472 Changed |= setOnlyReadsMemory(F);
473 return Changed;
474 case LibFunc::fputc:
475 case LibFunc::fstat:
476 case LibFunc::frexp:
477 case LibFunc::frexpf:
478 case LibFunc::frexpl:
479 case LibFunc::fstatvfs:
480 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
481 return false;
482 Changed |= setDoesNotThrow(F);
483 Changed |= setDoesNotCapture(F, 2);
484 return Changed;
485 case LibFunc::fgets:
486 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
487 !FTy->getParamType(2)->isPointerTy())
488 return false;
489 Changed |= setDoesNotThrow(F);
490 Changed |= setDoesNotCapture(F, 3);
491 return Changed;
492 case LibFunc::fread:
493 if (FTy->getNumParams() != 4 || !FTy->getParamType(0)->isPointerTy() ||
494 !FTy->getParamType(3)->isPointerTy())
495 return false;
496 Changed |= setDoesNotThrow(F);
497 Changed |= setDoesNotCapture(F, 1);
498 Changed |= setDoesNotCapture(F, 4);
499 return Changed;
500 case LibFunc::fwrite:
501 if (FTy->getNumParams() != 4 || !FTy->getParamType(0)->isPointerTy() ||
502 !FTy->getParamType(3)->isPointerTy())
503 return false;
504 Changed |= setDoesNotThrow(F);
505 Changed |= setDoesNotCapture(F, 1);
506 Changed |= setDoesNotCapture(F, 4);
507 return Changed;
508 case LibFunc::fputs:
509 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
510 !FTy->getParamType(1)->isPointerTy())
511 return false;
512 Changed |= setDoesNotThrow(F);
513 Changed |= setDoesNotCapture(F, 1);
514 Changed |= setDoesNotCapture(F, 2);
515 Changed |= setOnlyReadsMemory(F, 1);
516 return Changed;
517 case LibFunc::fscanf:
518 case LibFunc::fprintf:
519 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
520 !FTy->getParamType(1)->isPointerTy())
521 return false;
522 Changed |= setDoesNotThrow(F);
523 Changed |= setDoesNotCapture(F, 1);
524 Changed |= setDoesNotCapture(F, 2);
525 Changed |= setOnlyReadsMemory(F, 2);
526 return Changed;
527 case LibFunc::fgetpos:
528 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy() ||
529 !FTy->getParamType(1)->isPointerTy())
530 return false;
531 Changed |= setDoesNotThrow(F);
532 Changed |= setDoesNotCapture(F, 1);
533 Changed |= setDoesNotCapture(F, 2);
534 return Changed;
535 case LibFunc::getc:
536 case LibFunc::getlogin_r:
537 case LibFunc::getc_unlocked:
538 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
539 return false;
540 Changed |= setDoesNotThrow(F);
541 Changed |= setDoesNotCapture(F, 1);
542 return Changed;
543 case LibFunc::getenv:
544 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
545 return false;
546 Changed |= setDoesNotThrow(F);
547 Changed |= setOnlyReadsMemory(F);
548 Changed |= setDoesNotCapture(F, 1);
549 return Changed;
550 case LibFunc::gets:
551 case LibFunc::getchar:
552 Changed |= setDoesNotThrow(F);
553 return Changed;
554 case LibFunc::getitimer:
555 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
556 return false;
557 Changed |= setDoesNotThrow(F);
558 Changed |= setDoesNotCapture(F, 2);
559 return Changed;
560 case LibFunc::getpwnam:
561 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
562 return false;
563 Changed |= setDoesNotThrow(F);
564 Changed |= setDoesNotCapture(F, 1);
565 Changed |= setOnlyReadsMemory(F, 1);
566 return Changed;
567 case LibFunc::ungetc:
568 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
569 return false;
570 Changed |= setDoesNotThrow(F);
571 Changed |= setDoesNotCapture(F, 2);
572 return Changed;
573 case LibFunc::uname:
574 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
575 return false;
576 Changed |= setDoesNotThrow(F);
577 Changed |= setDoesNotCapture(F, 1);
578 return Changed;
579 case LibFunc::unlink:
580 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
581 return false;
582 Changed |= setDoesNotThrow(F);
583 Changed |= setDoesNotCapture(F, 1);
584 Changed |= setOnlyReadsMemory(F, 1);
585 return Changed;
586 case LibFunc::unsetenv:
587 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
588 return false;
589 Changed |= setDoesNotThrow(F);
590 Changed |= setDoesNotCapture(F, 1);
591 Changed |= setOnlyReadsMemory(F, 1);
592 return Changed;
593 case LibFunc::utime:
594 case LibFunc::utimes:
595 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
596 !FTy->getParamType(1)->isPointerTy())
597 return false;
598 Changed |= setDoesNotThrow(F);
599 Changed |= setDoesNotCapture(F, 1);
600 Changed |= setDoesNotCapture(F, 2);
601 Changed |= setOnlyReadsMemory(F, 1);
602 Changed |= setOnlyReadsMemory(F, 2);
603 return Changed;
604 case LibFunc::putc:
605 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
606 return false;
607 Changed |= setDoesNotThrow(F);
608 Changed |= setDoesNotCapture(F, 2);
609 return Changed;
610 case LibFunc::puts:
611 case LibFunc::printf:
612 case LibFunc::perror:
613 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
614 return false;
615 Changed |= setDoesNotThrow(F);
616 Changed |= setDoesNotCapture(F, 1);
617 Changed |= setOnlyReadsMemory(F, 1);
618 return Changed;
619 case LibFunc::pread:
620 if (FTy->getNumParams() != 4 || !FTy->getParamType(1)->isPointerTy())
621 return false;
622 // May throw; "pread" is a valid pthread cancellation point.
623 Changed |= setDoesNotCapture(F, 2);
624 return Changed;
625 case LibFunc::pwrite:
626 if (FTy->getNumParams() != 4 || !FTy->getParamType(1)->isPointerTy())
627 return false;
628 // May throw; "pwrite" is a valid pthread cancellation point.
629 Changed |= setDoesNotCapture(F, 2);
630 Changed |= setOnlyReadsMemory(F, 2);
631 return Changed;
632 case LibFunc::putchar:
633 Changed |= setDoesNotThrow(F);
634 return Changed;
635 case LibFunc::popen:
636 if (FTy->getNumParams() != 2 || !FTy->getReturnType()->isPointerTy() ||
637 !FTy->getParamType(0)->isPointerTy() ||
638 !FTy->getParamType(1)->isPointerTy())
639 return false;
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);
646 return Changed;
647 case LibFunc::pclose:
648 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
649 return false;
650 Changed |= setDoesNotThrow(F);
651 Changed |= setDoesNotCapture(F, 1);
652 return Changed;
653 case LibFunc::vscanf:
654 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
655 return false;
656 Changed |= setDoesNotThrow(F);
657 Changed |= setDoesNotCapture(F, 1);
658 Changed |= setOnlyReadsMemory(F, 1);
659 return Changed;
660 case LibFunc::vsscanf:
661 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy() ||
662 !FTy->getParamType(2)->isPointerTy())
663 return false;
664 Changed |= setDoesNotThrow(F);
665 Changed |= setDoesNotCapture(F, 1);
666 Changed |= setDoesNotCapture(F, 2);
667 Changed |= setOnlyReadsMemory(F, 1);
668 Changed |= setOnlyReadsMemory(F, 2);
669 return Changed;
670 case LibFunc::vfscanf:
671 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy() ||
672 !FTy->getParamType(2)->isPointerTy())
673 return false;
674 Changed |= setDoesNotThrow(F);
675 Changed |= setDoesNotCapture(F, 1);
676 Changed |= setDoesNotCapture(F, 2);
677 Changed |= setOnlyReadsMemory(F, 2);
678 return Changed;
679 case LibFunc::valloc:
680 if (!FTy->getReturnType()->isPointerTy())
681 return false;
682 Changed |= setDoesNotThrow(F);
683 Changed |= setDoesNotAlias(F, 0);
684 return Changed;
685 case LibFunc::vprintf:
686 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy())
687 return false;
688 Changed |= setDoesNotThrow(F);
689 Changed |= setDoesNotCapture(F, 1);
690 Changed |= setOnlyReadsMemory(F, 1);
691 return Changed;
692 case LibFunc::vfprintf:
693 case LibFunc::vsprintf:
694 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy() ||
695 !FTy->getParamType(1)->isPointerTy())
696 return false;
697 Changed |= setDoesNotThrow(F);
698 Changed |= setDoesNotCapture(F, 1);
699 Changed |= setDoesNotCapture(F, 2);
700 Changed |= setOnlyReadsMemory(F, 2);
701 return Changed;
702 case LibFunc::vsnprintf:
703 if (FTy->getNumParams() != 4 || !FTy->getParamType(0)->isPointerTy() ||
704 !FTy->getParamType(2)->isPointerTy())
705 return false;
706 Changed |= setDoesNotThrow(F);
707 Changed |= setDoesNotCapture(F, 1);
708 Changed |= setDoesNotCapture(F, 3);
709 Changed |= setOnlyReadsMemory(F, 3);
710 return Changed;
711 case LibFunc::open:
712 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy())
713 return false;
714 // May throw; "open" is a valid pthread cancellation point.
715 Changed |= setDoesNotCapture(F, 1);
716 Changed |= setOnlyReadsMemory(F, 1);
717 return Changed;
718 case LibFunc::opendir:
719 if (FTy->getNumParams() != 1 || !FTy->getReturnType()->isPointerTy() ||
720 !FTy->getParamType(0)->isPointerTy())
721 return false;
722 Changed |= setDoesNotThrow(F);
723 Changed |= setDoesNotAlias(F, 0);
724 Changed |= setDoesNotCapture(F, 1);
725 Changed |= setOnlyReadsMemory(F, 1);
726 return Changed;
727 case LibFunc::tmpfile:
728 if (!FTy->getReturnType()->isPointerTy())
729 return false;
730 Changed |= setDoesNotThrow(F);
731 Changed |= setDoesNotAlias(F, 0);
732 return Changed;
733 case LibFunc::times:
734 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
735 return false;
736 Changed |= setDoesNotThrow(F);
737 Changed |= setDoesNotCapture(F, 1);
738 return Changed;
739 case LibFunc::htonl:
740 case LibFunc::htons:
741 case LibFunc::ntohl:
742 case LibFunc::ntohs:
743 Changed |= setDoesNotThrow(F);
744 Changed |= setDoesNotAccessMemory(F);
745 return Changed;
746 case LibFunc::lstat:
747 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
748 !FTy->getParamType(1)->isPointerTy())
749 return false;
750 Changed |= setDoesNotThrow(F);
751 Changed |= setDoesNotCapture(F, 1);
752 Changed |= setDoesNotCapture(F, 2);
753 Changed |= setOnlyReadsMemory(F, 1);
754 return Changed;
755 case LibFunc::lchown:
756 if (FTy->getNumParams() != 3 || !FTy->getParamType(0)->isPointerTy())
757 return false;
758 Changed |= setDoesNotThrow(F);
759 Changed |= setDoesNotCapture(F, 1);
760 Changed |= setOnlyReadsMemory(F, 1);
761 return Changed;
762 case LibFunc::qsort:
763 if (FTy->getNumParams() != 4 || !FTy->getParamType(3)->isPointerTy())
764 return false;
765 // May throw; places call through function pointer.
766 Changed |= setDoesNotCapture(F, 4);
767 return Changed;
768 case LibFunc::dunder_strdup:
769 case LibFunc::dunder_strndup:
770 if (FTy->getNumParams() < 1 || !FTy->getReturnType()->isPointerTy() ||
771 !FTy->getParamType(0)->isPointerTy())
772 return false;
773 Changed |= setDoesNotThrow(F);
774 Changed |= setDoesNotAlias(F, 0);
775 Changed |= setDoesNotCapture(F, 1);
776 Changed |= setOnlyReadsMemory(F, 1);
777 return Changed;
778 case LibFunc::dunder_strtok_r:
779 if (FTy->getNumParams() != 3 || !FTy->getParamType(1)->isPointerTy())
780 return false;
781 Changed |= setDoesNotThrow(F);
782 Changed |= setDoesNotCapture(F, 2);
783 Changed |= setOnlyReadsMemory(F, 2);
784 return Changed;
785 case LibFunc::under_IO_getc:
786 if (FTy->getNumParams() != 1 || !FTy->getParamType(0)->isPointerTy())
787 return false;
788 Changed |= setDoesNotThrow(F);
789 Changed |= setDoesNotCapture(F, 1);
790 return Changed;
791 case LibFunc::under_IO_putc:
792 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
793 return false;
794 Changed |= setDoesNotThrow(F);
795 Changed |= setDoesNotCapture(F, 2);
796 return Changed;
797 case LibFunc::dunder_isoc99_scanf:
798 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy())
799 return false;
800 Changed |= setDoesNotThrow(F);
801 Changed |= setDoesNotCapture(F, 1);
802 Changed |= setOnlyReadsMemory(F, 1);
803 return Changed;
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())
809 return false;
810 Changed |= setDoesNotThrow(F);
811 Changed |= setDoesNotCapture(F, 1);
812 Changed |= setDoesNotCapture(F, 2);
813 Changed |= setOnlyReadsMemory(F, 1);
814 return Changed;
815 case LibFunc::dunder_isoc99_sscanf:
816 if (FTy->getNumParams() < 1 || !FTy->getParamType(0)->isPointerTy() ||
817 !FTy->getParamType(1)->isPointerTy())
818 return false;
819 Changed |= setDoesNotThrow(F);
820 Changed |= setDoesNotCapture(F, 1);
821 Changed |= setDoesNotCapture(F, 2);
822 Changed |= setOnlyReadsMemory(F, 1);
823 Changed |= setOnlyReadsMemory(F, 2);
824 return Changed;
825 case LibFunc::fopen64:
826 if (FTy->getNumParams() != 2 || !FTy->getReturnType()->isPointerTy() ||
827 !FTy->getParamType(0)->isPointerTy() ||
828 !FTy->getParamType(1)->isPointerTy())
829 return false;
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);
836 return Changed;
837 case LibFunc::fseeko64:
838 case LibFunc::ftello64:
839 if (FTy->getNumParams() == 0 || !FTy->getParamType(0)->isPointerTy())
840 return false;
841 Changed |= setDoesNotThrow(F);
842 Changed |= setDoesNotCapture(F, 1);
843 return Changed;
844 case LibFunc::tmpfile64:
845 if (!FTy->getReturnType()->isPointerTy())
846 return false;
847 Changed |= setDoesNotThrow(F);
848 Changed |= setDoesNotAlias(F, 0);
849 return Changed;
850 case LibFunc::fstat64:
851 case LibFunc::fstatvfs64:
852 if (FTy->getNumParams() != 2 || !FTy->getParamType(1)->isPointerTy())
853 return false;
854 Changed |= setDoesNotThrow(F);
855 Changed |= setDoesNotCapture(F, 2);
856 return Changed;
857 case LibFunc::open64:
858 if (FTy->getNumParams() < 2 || !FTy->getParamType(0)->isPointerTy())
859 return false;
860 // May throw; "open" is a valid pthread cancellation point.
861 Changed |= setDoesNotCapture(F, 1);
862 Changed |= setOnlyReadsMemory(F, 1);
863 return Changed;
864 case LibFunc::gettimeofday:
865 if (FTy->getNumParams() != 2 || !FTy->getParamType(0)->isPointerTy() ||
866 !FTy->getParamType(1)->isPointerTy())
867 return false;
868 // Currently some platforms have the restrict keyword on the arguments to
869 // gettimeofday. To be conservative, do not add noalias to gettimeofday's
870 // arguments.
871 Changed |= setDoesNotThrow(F);
872 Changed |= setDoesNotCapture(F, 1);
873 Changed |= setDoesNotCapture(F, 2);
874 return Changed;
875
876 default:
877 // FIXME: It'd be really nice to cover all the library functions we're
878 // aware of here.
879 return false;
880 }
881}
882
883static bool inferAllPrototypeAttributes(Module &M,
884 const TargetLibraryInfo &TLI) {
885 bool Changed = false;
886
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);
892
893 return Changed;
894}
895
896PreservedAnalyses InferFunctionAttrsPass::run(Module &M,
897 AnalysisManager<Module> *AM) {
898 auto &TLI = AM->getResult<TargetLibraryAnalysis>(M);
899
900 if (!inferAllPrototypeAttributes(M, TLI))
901 // If we didn't infer anything, preserve all analyses.
902 return PreservedAnalyses::all();
903
904 // Otherwise, we may have changed fundamental function attributes, so clear
905 // out all the passes.
906 return PreservedAnalyses::none();
907}
908
909namespace {
910struct InferFunctionAttrsLegacyPass : public ModulePass {
911 static char ID; // Pass identification, replacement for typeid
912 InferFunctionAttrsLegacyPass() : ModulePass(ID) {
913 initializeInferFunctionAttrsLegacyPassPass(
914 *PassRegistry::getPassRegistry());
915 }
916
917 void getAnalysisUsage(AnalysisUsage &AU) const override {
918 AU.addRequired<TargetLibraryInfoWrapperPass>();
919 }
920
921 bool runOnModule(Module &M) override {
922 auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
923 return inferAllPrototypeAttributes(M, TLI);
924 }
925};
926}
927
928char InferFunctionAttrsLegacyPass::ID = 0;
929INITIALIZE_PASS_BEGIN(InferFunctionAttrsLegacyPass, "inferattrs",
930 "Infer set function attributes", false, false)
931INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
932INITIALIZE_PASS_END(InferFunctionAttrsLegacyPass, "inferattrs",
933 "Infer set function attributes", false, false)
934
935Pass *llvm::createInferFunctionAttrsLegacyPass() {
936 return new InferFunctionAttrsLegacyPass();
937}