1 //===- 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/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" 19 using namespace llvm; 20 21 #define DEBUG_TYPE "inferattrs" 22 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"); 31 32 static bool setDoesNotAccessMemory(Function &F) { 33 if (F.doesNotAccessMemory()) 34 return false; 35 F.setDoesNotAccessMemory(); 36 ++NumReadNone; 37 return true; 38 } 39 40 static bool setOnlyReadsMemory(Function &F) { 41 if (F.onlyReadsMemory()) 42 return false; 43 F.setOnlyReadsMemory(); 44 ++NumReadOnly; 45 return true; 46 } 47 48 static bool setOnlyAccessesArgMemory(Function &F) { 49 if (F.onlyAccessesArgMemory()) 50 return false; 51 F.setOnlyAccessesArgMemory (); 52 ++NumArgMemOnly; 53 return true; 54 } 55 56 57 static bool setDoesNotThrow(Function &F) { 58 if (F.doesNotThrow()) 59 return false; 60 F.setDoesNotThrow(); 61 ++NumNoUnwind; 62 return true; 63 } 64 65 static 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 73 static 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 81 static 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 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)) 94 return false; 95 F.addAttribute(n, Attribute::NonNull); 96 ++NumNonNull; 97 return true; 98 } 99 100 /// 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. 104 static 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; 115 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 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) 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 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))) 921 return false; 922 923 Changed |= setOnlyAccessesArgMemory(F); 924 Changed |= setOnlyReadsMemory(F, 2); 925 return Changed; 926 927 // int __nvvm_reflect(const char *) 928 case LibFunc::nvvm_reflect: 929 if (FTy->getNumParams() != 1 || !isa<PointerType>(FTy->getParamType(0))) 930 return false; 931 932 Changed |= setDoesNotAccessMemory(F); 933 Changed |= setDoesNotThrow(F); 934 return Changed; 935 936 default: 937 // FIXME: It'd be really nice to cover all the library functions we're 938 // aware of here. 939 return false; 940 } 941 } 942 943 static bool inferAllPrototypeAttributes(Module &M, 944 const TargetLibraryInfo &TLI) { 945 bool Changed = false; 946 947 for (Function &F : M.functions()) 948 // We only infer things using the prototype if the definition isn't around 949 // to analyze directly. 950 if (F.isDeclaration()) 951 Changed |= inferPrototypeAttributes(F, TLI); 952 953 return Changed; 954 } 955 956 PreservedAnalyses InferFunctionAttrsPass::run(Module &M, 957 AnalysisManager<Module> &AM) { 958 auto &TLI = AM.getResult<TargetLibraryAnalysis>(M); 959 960 if (!inferAllPrototypeAttributes(M, TLI)) 961 // If we didn't infer anything, preserve all analyses. 962 return PreservedAnalyses::all(); 963 964 // Otherwise, we may have changed fundamental function attributes, so clear 965 // out all the passes. 966 return PreservedAnalyses::none(); 967 } 968 969 namespace { 970 struct InferFunctionAttrsLegacyPass : public ModulePass { 971 static char ID; // Pass identification, replacement for typeid 972 InferFunctionAttrsLegacyPass() : ModulePass(ID) { 973 initializeInferFunctionAttrsLegacyPassPass( 974 *PassRegistry::getPassRegistry()); 975 } 976 977 void getAnalysisUsage(AnalysisUsage &AU) const override { 978 AU.addRequired<TargetLibraryInfoWrapperPass>(); 979 } 980 981 bool runOnModule(Module &M) override { 982 auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); 983 return inferAllPrototypeAttributes(M, TLI); 984 } 985 }; 986 } 987 988 char InferFunctionAttrsLegacyPass::ID = 0; 989 INITIALIZE_PASS_BEGIN(InferFunctionAttrsLegacyPass, "inferattrs", 990 "Infer set function attributes", false, false) 991 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 992 INITIALIZE_PASS_END(InferFunctionAttrsLegacyPass, "inferattrs", 993 "Infer set function attributes", false, false) 994 995 Pass *llvm::createInferFunctionAttrsLegacyPass() { 996 return new InferFunctionAttrsLegacyPass(); 997 } 998