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