1 //===- Attributes.cpp - Implement AttributesList --------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // \file 10 // This file implements the Attribute, AttributeImpl, AttrBuilder, 11 // AttributeListImpl, and AttributeList classes. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/IR/Attributes.h" 16 #include "AttributeImpl.h" 17 #include "LLVMContextImpl.h" 18 #include "llvm/ADT/ArrayRef.h" 19 #include "llvm/ADT/FoldingSet.h" 20 #include "llvm/ADT/Optional.h" 21 #include "llvm/ADT/STLExtras.h" 22 #include "llvm/ADT/SmallVector.h" 23 #include "llvm/ADT/StringExtras.h" 24 #include "llvm/ADT/StringRef.h" 25 #include "llvm/ADT/Twine.h" 26 #include "llvm/Config/llvm-config.h" 27 #include "llvm/IR/Function.h" 28 #include "llvm/IR/LLVMContext.h" 29 #include "llvm/IR/Type.h" 30 #include "llvm/Support/Compiler.h" 31 #include "llvm/Support/Debug.h" 32 #include "llvm/Support/ErrorHandling.h" 33 #include "llvm/Support/MathExtras.h" 34 #include "llvm/Support/raw_ostream.h" 35 #include <algorithm> 36 #include <cassert> 37 #include <climits> 38 #include <cstddef> 39 #include <cstdint> 40 #include <limits> 41 #include <string> 42 #include <tuple> 43 #include <utility> 44 45 using namespace llvm; 46 47 //===----------------------------------------------------------------------===// 48 // Attribute Construction Methods 49 //===----------------------------------------------------------------------===// 50 51 // allocsize has two integer arguments, but because they're both 32 bits, we can 52 // pack them into one 64-bit value, at the cost of making said value 53 // nonsensical. 54 // 55 // In order to do this, we need to reserve one value of the second (optional) 56 // allocsize argument to signify "not present." 57 static const unsigned AllocSizeNumElemsNotPresent = -1; 58 59 static uint64_t packAllocSizeArgs(unsigned ElemSizeArg, 60 const Optional<unsigned> &NumElemsArg) { 61 assert((!NumElemsArg.hasValue() || 62 *NumElemsArg != AllocSizeNumElemsNotPresent) && 63 "Attempting to pack a reserved value"); 64 65 return uint64_t(ElemSizeArg) << 32 | 66 NumElemsArg.getValueOr(AllocSizeNumElemsNotPresent); 67 } 68 69 static std::pair<unsigned, Optional<unsigned>> 70 unpackAllocSizeArgs(uint64_t Num) { 71 unsigned NumElems = Num & std::numeric_limits<unsigned>::max(); 72 unsigned ElemSizeArg = Num >> 32; 73 74 Optional<unsigned> NumElemsArg; 75 if (NumElems != AllocSizeNumElemsNotPresent) 76 NumElemsArg = NumElems; 77 return std::make_pair(ElemSizeArg, NumElemsArg); 78 } 79 80 Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind, 81 uint64_t Val) { 82 LLVMContextImpl *pImpl = Context.pImpl; 83 FoldingSetNodeID ID; 84 ID.AddInteger(Kind); 85 if (Val) ID.AddInteger(Val); 86 87 void *InsertPoint; 88 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint); 89 90 if (!PA) { 91 // If we didn't find any existing attributes of the same shape then create a 92 // new one and insert it. 93 if (!Val) 94 PA = new EnumAttributeImpl(Kind); 95 else 96 PA = new IntAttributeImpl(Kind, Val); 97 pImpl->AttrsSet.InsertNode(PA, InsertPoint); 98 } 99 100 // Return the Attribute that we found or created. 101 return Attribute(PA); 102 } 103 104 Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) { 105 LLVMContextImpl *pImpl = Context.pImpl; 106 FoldingSetNodeID ID; 107 ID.AddString(Kind); 108 if (!Val.empty()) ID.AddString(Val); 109 110 void *InsertPoint; 111 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint); 112 113 if (!PA) { 114 // If we didn't find any existing attributes of the same shape then create a 115 // new one and insert it. 116 PA = new StringAttributeImpl(Kind, Val); 117 pImpl->AttrsSet.InsertNode(PA, InsertPoint); 118 } 119 120 // Return the Attribute that we found or created. 121 return Attribute(PA); 122 } 123 124 Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind, 125 Type *Ty) { 126 LLVMContextImpl *pImpl = Context.pImpl; 127 FoldingSetNodeID ID; 128 ID.AddInteger(Kind); 129 ID.AddPointer(Ty); 130 131 void *InsertPoint; 132 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint); 133 134 if (!PA) { 135 // If we didn't find any existing attributes of the same shape then create a 136 // new one and insert it. 137 PA = new TypeAttributeImpl(Kind, Ty); 138 pImpl->AttrsSet.InsertNode(PA, InsertPoint); 139 } 140 141 // Return the Attribute that we found or created. 142 return Attribute(PA); 143 } 144 145 Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) { 146 assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); 147 assert(Align <= 0x40000000 && "Alignment too large."); 148 return get(Context, Alignment, Align); 149 } 150 151 Attribute Attribute::getWithStackAlignment(LLVMContext &Context, 152 uint64_t Align) { 153 assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); 154 assert(Align <= 0x100 && "Alignment too large."); 155 return get(Context, StackAlignment, Align); 156 } 157 158 Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context, 159 uint64_t Bytes) { 160 assert(Bytes && "Bytes must be non-zero."); 161 return get(Context, Dereferenceable, Bytes); 162 } 163 164 Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context, 165 uint64_t Bytes) { 166 assert(Bytes && "Bytes must be non-zero."); 167 return get(Context, DereferenceableOrNull, Bytes); 168 } 169 170 Attribute Attribute::getWithByValType(LLVMContext &Context, Type *Ty) { 171 return get(Context, ByVal, Ty); 172 } 173 174 Attribute 175 Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, 176 const Optional<unsigned> &NumElemsArg) { 177 assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) && 178 "Invalid allocsize arguments -- given allocsize(0, 0)"); 179 return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg)); 180 } 181 182 //===----------------------------------------------------------------------===// 183 // Attribute Accessor Methods 184 //===----------------------------------------------------------------------===// 185 186 bool Attribute::isEnumAttribute() const { 187 return pImpl && pImpl->isEnumAttribute(); 188 } 189 190 bool Attribute::isIntAttribute() const { 191 return pImpl && pImpl->isIntAttribute(); 192 } 193 194 bool Attribute::isStringAttribute() const { 195 return pImpl && pImpl->isStringAttribute(); 196 } 197 198 bool Attribute::isTypeAttribute() const { 199 return pImpl && pImpl->isTypeAttribute(); 200 } 201 202 Attribute::AttrKind Attribute::getKindAsEnum() const { 203 if (!pImpl) return None; 204 assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute()) && 205 "Invalid attribute type to get the kind as an enum!"); 206 return pImpl->getKindAsEnum(); 207 } 208 209 uint64_t Attribute::getValueAsInt() const { 210 if (!pImpl) return 0; 211 assert(isIntAttribute() && 212 "Expected the attribute to be an integer attribute!"); 213 return pImpl->getValueAsInt(); 214 } 215 216 StringRef Attribute::getKindAsString() const { 217 if (!pImpl) return {}; 218 assert(isStringAttribute() && 219 "Invalid attribute type to get the kind as a string!"); 220 return pImpl->getKindAsString(); 221 } 222 223 StringRef Attribute::getValueAsString() const { 224 if (!pImpl) return {}; 225 assert(isStringAttribute() && 226 "Invalid attribute type to get the value as a string!"); 227 return pImpl->getValueAsString(); 228 } 229 230 Type *Attribute::getValueAsType() const { 231 if (!pImpl) return {}; 232 assert(isTypeAttribute() && 233 "Invalid attribute type to get the value as a type!"); 234 return pImpl->getValueAsType(); 235 } 236 237 238 bool Attribute::hasAttribute(AttrKind Kind) const { 239 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None); 240 } 241 242 bool Attribute::hasAttribute(StringRef Kind) const { 243 if (!isStringAttribute()) return false; 244 return pImpl && pImpl->hasAttribute(Kind); 245 } 246 247 unsigned Attribute::getAlignment() const { 248 assert(hasAttribute(Attribute::Alignment) && 249 "Trying to get alignment from non-alignment attribute!"); 250 return pImpl->getValueAsInt(); 251 } 252 253 unsigned Attribute::getStackAlignment() const { 254 assert(hasAttribute(Attribute::StackAlignment) && 255 "Trying to get alignment from non-alignment attribute!"); 256 return pImpl->getValueAsInt(); 257 } 258 259 uint64_t Attribute::getDereferenceableBytes() const { 260 assert(hasAttribute(Attribute::Dereferenceable) && 261 "Trying to get dereferenceable bytes from " 262 "non-dereferenceable attribute!"); 263 return pImpl->getValueAsInt(); 264 } 265 266 uint64_t Attribute::getDereferenceableOrNullBytes() const { 267 assert(hasAttribute(Attribute::DereferenceableOrNull) && 268 "Trying to get dereferenceable bytes from " 269 "non-dereferenceable attribute!"); 270 return pImpl->getValueAsInt(); 271 } 272 273 std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const { 274 assert(hasAttribute(Attribute::AllocSize) && 275 "Trying to get allocsize args from non-allocsize attribute"); 276 return unpackAllocSizeArgs(pImpl->getValueAsInt()); 277 } 278 279 std::string Attribute::getAsString(bool InAttrGrp) const { 280 if (!pImpl) return {}; 281 282 if (hasAttribute(Attribute::SanitizeAddress)) 283 return "sanitize_address"; 284 if (hasAttribute(Attribute::SanitizeHWAddress)) 285 return "sanitize_hwaddress"; 286 if (hasAttribute(Attribute::AlwaysInline)) 287 return "alwaysinline"; 288 if (hasAttribute(Attribute::ArgMemOnly)) 289 return "argmemonly"; 290 if (hasAttribute(Attribute::Builtin)) 291 return "builtin"; 292 if (hasAttribute(Attribute::Convergent)) 293 return "convergent"; 294 if (hasAttribute(Attribute::SwiftError)) 295 return "swifterror"; 296 if (hasAttribute(Attribute::SwiftSelf)) 297 return "swiftself"; 298 if (hasAttribute(Attribute::InaccessibleMemOnly)) 299 return "inaccessiblememonly"; 300 if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly)) 301 return "inaccessiblemem_or_argmemonly"; 302 if (hasAttribute(Attribute::InAlloca)) 303 return "inalloca"; 304 if (hasAttribute(Attribute::InlineHint)) 305 return "inlinehint"; 306 if (hasAttribute(Attribute::InReg)) 307 return "inreg"; 308 if (hasAttribute(Attribute::JumpTable)) 309 return "jumptable"; 310 if (hasAttribute(Attribute::MinSize)) 311 return "minsize"; 312 if (hasAttribute(Attribute::Naked)) 313 return "naked"; 314 if (hasAttribute(Attribute::Nest)) 315 return "nest"; 316 if (hasAttribute(Attribute::NoAlias)) 317 return "noalias"; 318 if (hasAttribute(Attribute::NoBuiltin)) 319 return "nobuiltin"; 320 if (hasAttribute(Attribute::NoCapture)) 321 return "nocapture"; 322 if (hasAttribute(Attribute::NoDuplicate)) 323 return "noduplicate"; 324 if (hasAttribute(Attribute::NoFree)) 325 return "nofree"; 326 if (hasAttribute(Attribute::NoImplicitFloat)) 327 return "noimplicitfloat"; 328 if (hasAttribute(Attribute::NoInline)) 329 return "noinline"; 330 if (hasAttribute(Attribute::NonLazyBind)) 331 return "nonlazybind"; 332 if (hasAttribute(Attribute::NonNull)) 333 return "nonnull"; 334 if (hasAttribute(Attribute::NoRedZone)) 335 return "noredzone"; 336 if (hasAttribute(Attribute::NoReturn)) 337 return "noreturn"; 338 if (hasAttribute(Attribute::NoSync)) 339 return "nosync"; 340 if (hasAttribute(Attribute::WillReturn)) 341 return "willreturn"; 342 if (hasAttribute(Attribute::NoCfCheck)) 343 return "nocf_check"; 344 if (hasAttribute(Attribute::NoRecurse)) 345 return "norecurse"; 346 if (hasAttribute(Attribute::NoUnwind)) 347 return "nounwind"; 348 if (hasAttribute(Attribute::OptForFuzzing)) 349 return "optforfuzzing"; 350 if (hasAttribute(Attribute::OptimizeNone)) 351 return "optnone"; 352 if (hasAttribute(Attribute::OptimizeForSize)) 353 return "optsize"; 354 if (hasAttribute(Attribute::ReadNone)) 355 return "readnone"; 356 if (hasAttribute(Attribute::ReadOnly)) 357 return "readonly"; 358 if (hasAttribute(Attribute::WriteOnly)) 359 return "writeonly"; 360 if (hasAttribute(Attribute::Returned)) 361 return "returned"; 362 if (hasAttribute(Attribute::ReturnsTwice)) 363 return "returns_twice"; 364 if (hasAttribute(Attribute::SExt)) 365 return "signext"; 366 if (hasAttribute(Attribute::SpeculativeLoadHardening)) 367 return "speculative_load_hardening"; 368 if (hasAttribute(Attribute::Speculatable)) 369 return "speculatable"; 370 if (hasAttribute(Attribute::StackProtect)) 371 return "ssp"; 372 if (hasAttribute(Attribute::StackProtectReq)) 373 return "sspreq"; 374 if (hasAttribute(Attribute::StackProtectStrong)) 375 return "sspstrong"; 376 if (hasAttribute(Attribute::SafeStack)) 377 return "safestack"; 378 if (hasAttribute(Attribute::ShadowCallStack)) 379 return "shadowcallstack"; 380 if (hasAttribute(Attribute::StrictFP)) 381 return "strictfp"; 382 if (hasAttribute(Attribute::StructRet)) 383 return "sret"; 384 if (hasAttribute(Attribute::SanitizeThread)) 385 return "sanitize_thread"; 386 if (hasAttribute(Attribute::SanitizeMemory)) 387 return "sanitize_memory"; 388 if (hasAttribute(Attribute::UWTable)) 389 return "uwtable"; 390 if (hasAttribute(Attribute::ZExt)) 391 return "zeroext"; 392 if (hasAttribute(Attribute::Cold)) 393 return "cold"; 394 if (hasAttribute(Attribute::ImmArg)) 395 return "immarg"; 396 397 if (hasAttribute(Attribute::ByVal)) { 398 std::string Result; 399 Result += "byval"; 400 if (Type *Ty = getValueAsType()) { 401 raw_string_ostream OS(Result); 402 Result += '('; 403 Ty->print(OS, false, true); 404 OS.flush(); 405 Result += ')'; 406 } 407 return Result; 408 } 409 410 // FIXME: These should be output like this: 411 // 412 // align=4 413 // alignstack=8 414 // 415 if (hasAttribute(Attribute::Alignment)) { 416 std::string Result; 417 Result += "align"; 418 Result += (InAttrGrp) ? "=" : " "; 419 Result += utostr(getValueAsInt()); 420 return Result; 421 } 422 423 auto AttrWithBytesToString = [&](const char *Name) { 424 std::string Result; 425 Result += Name; 426 if (InAttrGrp) { 427 Result += "="; 428 Result += utostr(getValueAsInt()); 429 } else { 430 Result += "("; 431 Result += utostr(getValueAsInt()); 432 Result += ")"; 433 } 434 return Result; 435 }; 436 437 if (hasAttribute(Attribute::StackAlignment)) 438 return AttrWithBytesToString("alignstack"); 439 440 if (hasAttribute(Attribute::Dereferenceable)) 441 return AttrWithBytesToString("dereferenceable"); 442 443 if (hasAttribute(Attribute::DereferenceableOrNull)) 444 return AttrWithBytesToString("dereferenceable_or_null"); 445 446 if (hasAttribute(Attribute::AllocSize)) { 447 unsigned ElemSize; 448 Optional<unsigned> NumElems; 449 std::tie(ElemSize, NumElems) = getAllocSizeArgs(); 450 451 std::string Result = "allocsize("; 452 Result += utostr(ElemSize); 453 if (NumElems.hasValue()) { 454 Result += ','; 455 Result += utostr(*NumElems); 456 } 457 Result += ')'; 458 return Result; 459 } 460 461 // Convert target-dependent attributes to strings of the form: 462 // 463 // "kind" 464 // "kind" = "value" 465 // 466 if (isStringAttribute()) { 467 std::string Result; 468 Result += (Twine('"') + getKindAsString() + Twine('"')).str(); 469 470 std::string AttrVal = pImpl->getValueAsString(); 471 if (AttrVal.empty()) return Result; 472 473 // Since some attribute strings contain special characters that cannot be 474 // printable, those have to be escaped to make the attribute value printable 475 // as is. e.g. "\01__gnu_mcount_nc" 476 { 477 raw_string_ostream OS(Result); 478 OS << "=\""; 479 printEscapedString(AttrVal, OS); 480 OS << "\""; 481 } 482 return Result; 483 } 484 485 llvm_unreachable("Unknown attribute"); 486 } 487 488 bool Attribute::operator<(Attribute A) const { 489 if (!pImpl && !A.pImpl) return false; 490 if (!pImpl) return true; 491 if (!A.pImpl) return false; 492 return *pImpl < *A.pImpl; 493 } 494 495 //===----------------------------------------------------------------------===// 496 // AttributeImpl Definition 497 //===----------------------------------------------------------------------===// 498 499 // Pin the vtables to this file. 500 AttributeImpl::~AttributeImpl() = default; 501 502 void EnumAttributeImpl::anchor() {} 503 504 void IntAttributeImpl::anchor() {} 505 506 void StringAttributeImpl::anchor() {} 507 508 void TypeAttributeImpl::anchor() {} 509 510 bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const { 511 if (isStringAttribute()) return false; 512 return getKindAsEnum() == A; 513 } 514 515 bool AttributeImpl::hasAttribute(StringRef Kind) const { 516 if (!isStringAttribute()) return false; 517 return getKindAsString() == Kind; 518 } 519 520 Attribute::AttrKind AttributeImpl::getKindAsEnum() const { 521 assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute()); 522 return static_cast<const EnumAttributeImpl *>(this)->getEnumKind(); 523 } 524 525 uint64_t AttributeImpl::getValueAsInt() const { 526 assert(isIntAttribute()); 527 return static_cast<const IntAttributeImpl *>(this)->getValue(); 528 } 529 530 StringRef AttributeImpl::getKindAsString() const { 531 assert(isStringAttribute()); 532 return static_cast<const StringAttributeImpl *>(this)->getStringKind(); 533 } 534 535 StringRef AttributeImpl::getValueAsString() const { 536 assert(isStringAttribute()); 537 return static_cast<const StringAttributeImpl *>(this)->getStringValue(); 538 } 539 540 Type *AttributeImpl::getValueAsType() const { 541 assert(isTypeAttribute()); 542 return static_cast<const TypeAttributeImpl *>(this)->getTypeValue(); 543 } 544 545 bool AttributeImpl::operator<(const AttributeImpl &AI) const { 546 // This sorts the attributes with Attribute::AttrKinds coming first (sorted 547 // relative to their enum value) and then strings. 548 if (isEnumAttribute()) { 549 if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum(); 550 if (AI.isIntAttribute()) return true; 551 if (AI.isStringAttribute()) return true; 552 if (AI.isTypeAttribute()) return true; 553 } 554 555 if (isTypeAttribute()) { 556 if (AI.isEnumAttribute()) return false; 557 if (AI.isTypeAttribute()) { 558 assert(getKindAsEnum() != AI.getKindAsEnum() && 559 "Comparison of types would be unstable"); 560 return getKindAsEnum() < AI.getKindAsEnum(); 561 } 562 if (AI.isIntAttribute()) return true; 563 if (AI.isStringAttribute()) return true; 564 } 565 566 if (isIntAttribute()) { 567 if (AI.isEnumAttribute()) return false; 568 if (AI.isTypeAttribute()) return false; 569 if (AI.isIntAttribute()) { 570 if (getKindAsEnum() == AI.getKindAsEnum()) 571 return getValueAsInt() < AI.getValueAsInt(); 572 return getKindAsEnum() < AI.getKindAsEnum(); 573 } 574 if (AI.isStringAttribute()) return true; 575 } 576 577 assert(isStringAttribute()); 578 if (AI.isEnumAttribute()) return false; 579 if (AI.isTypeAttribute()) return false; 580 if (AI.isIntAttribute()) return false; 581 if (getKindAsString() == AI.getKindAsString()) 582 return getValueAsString() < AI.getValueAsString(); 583 return getKindAsString() < AI.getKindAsString(); 584 } 585 586 //===----------------------------------------------------------------------===// 587 // AttributeSet Definition 588 //===----------------------------------------------------------------------===// 589 590 AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) { 591 return AttributeSet(AttributeSetNode::get(C, B)); 592 } 593 594 AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) { 595 return AttributeSet(AttributeSetNode::get(C, Attrs)); 596 } 597 598 AttributeSet AttributeSet::addAttribute(LLVMContext &C, 599 Attribute::AttrKind Kind) const { 600 if (hasAttribute(Kind)) return *this; 601 AttrBuilder B; 602 B.addAttribute(Kind); 603 return addAttributes(C, AttributeSet::get(C, B)); 604 } 605 606 AttributeSet AttributeSet::addAttribute(LLVMContext &C, StringRef Kind, 607 StringRef Value) const { 608 AttrBuilder B; 609 B.addAttribute(Kind, Value); 610 return addAttributes(C, AttributeSet::get(C, B)); 611 } 612 613 AttributeSet AttributeSet::addAttributes(LLVMContext &C, 614 const AttributeSet AS) const { 615 if (!hasAttributes()) 616 return AS; 617 618 if (!AS.hasAttributes()) 619 return *this; 620 621 AttrBuilder B(AS); 622 for (const auto I : *this) 623 B.addAttribute(I); 624 625 return get(C, B); 626 } 627 628 AttributeSet AttributeSet::removeAttribute(LLVMContext &C, 629 Attribute::AttrKind Kind) const { 630 if (!hasAttribute(Kind)) return *this; 631 AttrBuilder B(*this); 632 B.removeAttribute(Kind); 633 return get(C, B); 634 } 635 636 AttributeSet AttributeSet::removeAttribute(LLVMContext &C, 637 StringRef Kind) const { 638 if (!hasAttribute(Kind)) return *this; 639 AttrBuilder B(*this); 640 B.removeAttribute(Kind); 641 return get(C, B); 642 } 643 644 AttributeSet AttributeSet::removeAttributes(LLVMContext &C, 645 const AttrBuilder &Attrs) const { 646 AttrBuilder B(*this); 647 B.remove(Attrs); 648 return get(C, B); 649 } 650 651 unsigned AttributeSet::getNumAttributes() const { 652 return SetNode ? SetNode->getNumAttributes() : 0; 653 } 654 655 bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const { 656 return SetNode ? SetNode->hasAttribute(Kind) : false; 657 } 658 659 bool AttributeSet::hasAttribute(StringRef Kind) const { 660 return SetNode ? SetNode->hasAttribute(Kind) : false; 661 } 662 663 Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const { 664 return SetNode ? SetNode->getAttribute(Kind) : Attribute(); 665 } 666 667 Attribute AttributeSet::getAttribute(StringRef Kind) const { 668 return SetNode ? SetNode->getAttribute(Kind) : Attribute(); 669 } 670 671 unsigned AttributeSet::getAlignment() const { 672 return SetNode ? SetNode->getAlignment() : 0; 673 } 674 675 unsigned AttributeSet::getStackAlignment() const { 676 return SetNode ? SetNode->getStackAlignment() : 0; 677 } 678 679 uint64_t AttributeSet::getDereferenceableBytes() const { 680 return SetNode ? SetNode->getDereferenceableBytes() : 0; 681 } 682 683 uint64_t AttributeSet::getDereferenceableOrNullBytes() const { 684 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0; 685 } 686 687 Type *AttributeSet::getByValType() const { 688 return SetNode ? SetNode->getByValType() : nullptr; 689 } 690 691 std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const { 692 return SetNode ? SetNode->getAllocSizeArgs() 693 : std::pair<unsigned, Optional<unsigned>>(0, 0); 694 } 695 696 std::string AttributeSet::getAsString(bool InAttrGrp) const { 697 return SetNode ? SetNode->getAsString(InAttrGrp) : ""; 698 } 699 700 AttributeSet::iterator AttributeSet::begin() const { 701 return SetNode ? SetNode->begin() : nullptr; 702 } 703 704 AttributeSet::iterator AttributeSet::end() const { 705 return SetNode ? SetNode->end() : nullptr; 706 } 707 708 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 709 LLVM_DUMP_METHOD void AttributeSet::dump() const { 710 dbgs() << "AS =\n"; 711 dbgs() << " { "; 712 dbgs() << getAsString(true) << " }\n"; 713 } 714 #endif 715 716 //===----------------------------------------------------------------------===// 717 // AttributeSetNode Definition 718 //===----------------------------------------------------------------------===// 719 720 AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs) 721 : AvailableAttrs(0), NumAttrs(Attrs.size()) { 722 // There's memory after the node where we can store the entries in. 723 llvm::copy(Attrs, getTrailingObjects<Attribute>()); 724 725 for (const auto I : *this) { 726 if (!I.isStringAttribute()) { 727 AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum(); 728 } 729 } 730 } 731 732 AttributeSetNode *AttributeSetNode::get(LLVMContext &C, 733 ArrayRef<Attribute> Attrs) { 734 if (Attrs.empty()) 735 return nullptr; 736 737 // Otherwise, build a key to look up the existing attributes. 738 LLVMContextImpl *pImpl = C.pImpl; 739 FoldingSetNodeID ID; 740 741 SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end()); 742 llvm::sort(SortedAttrs); 743 744 for (const auto Attr : SortedAttrs) 745 Attr.Profile(ID); 746 747 void *InsertPoint; 748 AttributeSetNode *PA = 749 pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint); 750 751 // If we didn't find any existing attributes of the same shape then create a 752 // new one and insert it. 753 if (!PA) { 754 // Coallocate entries after the AttributeSetNode itself. 755 void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size())); 756 PA = new (Mem) AttributeSetNode(SortedAttrs); 757 pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint); 758 } 759 760 // Return the AttributeSetNode that we found or created. 761 return PA; 762 } 763 764 AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) { 765 // Add target-independent attributes. 766 SmallVector<Attribute, 8> Attrs; 767 for (Attribute::AttrKind Kind = Attribute::None; 768 Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) { 769 if (!B.contains(Kind)) 770 continue; 771 772 Attribute Attr; 773 switch (Kind) { 774 case Attribute::ByVal: 775 Attr = Attribute::getWithByValType(C, B.getByValType()); 776 break; 777 case Attribute::Alignment: 778 Attr = Attribute::getWithAlignment(C, B.getAlignment()); 779 break; 780 case Attribute::StackAlignment: 781 Attr = Attribute::getWithStackAlignment(C, B.getStackAlignment()); 782 break; 783 case Attribute::Dereferenceable: 784 Attr = Attribute::getWithDereferenceableBytes( 785 C, B.getDereferenceableBytes()); 786 break; 787 case Attribute::DereferenceableOrNull: 788 Attr = Attribute::getWithDereferenceableOrNullBytes( 789 C, B.getDereferenceableOrNullBytes()); 790 break; 791 case Attribute::AllocSize: { 792 auto A = B.getAllocSizeArgs(); 793 Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second); 794 break; 795 } 796 default: 797 Attr = Attribute::get(C, Kind); 798 } 799 Attrs.push_back(Attr); 800 } 801 802 // Add target-dependent (string) attributes. 803 for (const auto &TDA : B.td_attrs()) 804 Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second)); 805 806 return get(C, Attrs); 807 } 808 809 bool AttributeSetNode::hasAttribute(StringRef Kind) const { 810 for (const auto I : *this) 811 if (I.hasAttribute(Kind)) 812 return true; 813 return false; 814 } 815 816 Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const { 817 if (hasAttribute(Kind)) { 818 for (const auto I : *this) 819 if (I.hasAttribute(Kind)) 820 return I; 821 } 822 return {}; 823 } 824 825 Attribute AttributeSetNode::getAttribute(StringRef Kind) const { 826 for (const auto I : *this) 827 if (I.hasAttribute(Kind)) 828 return I; 829 return {}; 830 } 831 832 unsigned AttributeSetNode::getAlignment() const { 833 for (const auto I : *this) 834 if (I.hasAttribute(Attribute::Alignment)) 835 return I.getAlignment(); 836 return 0; 837 } 838 839 unsigned AttributeSetNode::getStackAlignment() const { 840 for (const auto I : *this) 841 if (I.hasAttribute(Attribute::StackAlignment)) 842 return I.getStackAlignment(); 843 return 0; 844 } 845 846 Type *AttributeSetNode::getByValType() const { 847 for (const auto I : *this) 848 if (I.hasAttribute(Attribute::ByVal)) 849 return I.getValueAsType(); 850 return 0; 851 } 852 853 uint64_t AttributeSetNode::getDereferenceableBytes() const { 854 for (const auto I : *this) 855 if (I.hasAttribute(Attribute::Dereferenceable)) 856 return I.getDereferenceableBytes(); 857 return 0; 858 } 859 860 uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const { 861 for (const auto I : *this) 862 if (I.hasAttribute(Attribute::DereferenceableOrNull)) 863 return I.getDereferenceableOrNullBytes(); 864 return 0; 865 } 866 867 std::pair<unsigned, Optional<unsigned>> 868 AttributeSetNode::getAllocSizeArgs() const { 869 for (const auto I : *this) 870 if (I.hasAttribute(Attribute::AllocSize)) 871 return I.getAllocSizeArgs(); 872 return std::make_pair(0, 0); 873 } 874 875 std::string AttributeSetNode::getAsString(bool InAttrGrp) const { 876 std::string Str; 877 for (iterator I = begin(), E = end(); I != E; ++I) { 878 if (I != begin()) 879 Str += ' '; 880 Str += I->getAsString(InAttrGrp); 881 } 882 return Str; 883 } 884 885 //===----------------------------------------------------------------------===// 886 // AttributeListImpl Definition 887 //===----------------------------------------------------------------------===// 888 889 /// Map from AttributeList index to the internal array index. Adding one happens 890 /// to work, but it relies on unsigned integer wrapping. MSVC warns about 891 /// unsigned wrapping in constexpr functions, so write out the conditional. LLVM 892 /// folds it to add anyway. 893 static constexpr unsigned attrIdxToArrayIdx(unsigned Index) { 894 return Index == AttributeList::FunctionIndex ? 0 : Index + 1; 895 } 896 897 AttributeListImpl::AttributeListImpl(LLVMContext &C, 898 ArrayRef<AttributeSet> Sets) 899 : AvailableFunctionAttrs(0), Context(C), NumAttrSets(Sets.size()) { 900 assert(!Sets.empty() && "pointless AttributeListImpl"); 901 902 // There's memory after the node where we can store the entries in. 903 llvm::copy(Sets, getTrailingObjects<AttributeSet>()); 904 905 // Initialize AvailableFunctionAttrs summary bitset. 906 static_assert(Attribute::EndAttrKinds <= 907 sizeof(AvailableFunctionAttrs) * CHAR_BIT, 908 "Too many attributes"); 909 static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U, 910 "function should be stored in slot 0"); 911 for (const auto I : Sets[0]) { 912 if (!I.isStringAttribute()) 913 AvailableFunctionAttrs |= 1ULL << I.getKindAsEnum(); 914 } 915 } 916 917 void AttributeListImpl::Profile(FoldingSetNodeID &ID) const { 918 Profile(ID, makeArrayRef(begin(), end())); 919 } 920 921 void AttributeListImpl::Profile(FoldingSetNodeID &ID, 922 ArrayRef<AttributeSet> Sets) { 923 for (const auto &Set : Sets) 924 ID.AddPointer(Set.SetNode); 925 } 926 927 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 928 LLVM_DUMP_METHOD void AttributeListImpl::dump() const { 929 AttributeList(const_cast<AttributeListImpl *>(this)).dump(); 930 } 931 #endif 932 933 //===----------------------------------------------------------------------===// 934 // AttributeList Construction and Mutation Methods 935 //===----------------------------------------------------------------------===// 936 937 AttributeList AttributeList::getImpl(LLVMContext &C, 938 ArrayRef<AttributeSet> AttrSets) { 939 assert(!AttrSets.empty() && "pointless AttributeListImpl"); 940 941 LLVMContextImpl *pImpl = C.pImpl; 942 FoldingSetNodeID ID; 943 AttributeListImpl::Profile(ID, AttrSets); 944 945 void *InsertPoint; 946 AttributeListImpl *PA = 947 pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint); 948 949 // If we didn't find any existing attributes of the same shape then 950 // create a new one and insert it. 951 if (!PA) { 952 // Coallocate entries after the AttributeListImpl itself. 953 void *Mem = ::operator new( 954 AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size())); 955 PA = new (Mem) AttributeListImpl(C, AttrSets); 956 pImpl->AttrsLists.InsertNode(PA, InsertPoint); 957 } 958 959 // Return the AttributesList that we found or created. 960 return AttributeList(PA); 961 } 962 963 AttributeList 964 AttributeList::get(LLVMContext &C, 965 ArrayRef<std::pair<unsigned, Attribute>> Attrs) { 966 // If there are no attributes then return a null AttributesList pointer. 967 if (Attrs.empty()) 968 return {}; 969 970 assert(std::is_sorted(Attrs.begin(), Attrs.end(), 971 [](const std::pair<unsigned, Attribute> &LHS, 972 const std::pair<unsigned, Attribute> &RHS) { 973 return LHS.first < RHS.first; 974 }) && "Misordered Attributes list!"); 975 assert(llvm::none_of(Attrs, 976 [](const std::pair<unsigned, Attribute> &Pair) { 977 return Pair.second.hasAttribute(Attribute::None); 978 }) && 979 "Pointless attribute!"); 980 981 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes 982 // list. 983 SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec; 984 for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(), 985 E = Attrs.end(); I != E; ) { 986 unsigned Index = I->first; 987 SmallVector<Attribute, 4> AttrVec; 988 while (I != E && I->first == Index) { 989 AttrVec.push_back(I->second); 990 ++I; 991 } 992 993 AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec)); 994 } 995 996 return get(C, AttrPairVec); 997 } 998 999 AttributeList 1000 AttributeList::get(LLVMContext &C, 1001 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) { 1002 // If there are no attributes then return a null AttributesList pointer. 1003 if (Attrs.empty()) 1004 return {}; 1005 1006 assert(std::is_sorted(Attrs.begin(), Attrs.end(), 1007 [](const std::pair<unsigned, AttributeSet> &LHS, 1008 const std::pair<unsigned, AttributeSet> &RHS) { 1009 return LHS.first < RHS.first; 1010 }) && 1011 "Misordered Attributes list!"); 1012 assert(llvm::none_of(Attrs, 1013 [](const std::pair<unsigned, AttributeSet> &Pair) { 1014 return !Pair.second.hasAttributes(); 1015 }) && 1016 "Pointless attribute!"); 1017 1018 unsigned MaxIndex = Attrs.back().first; 1019 // If the MaxIndex is FunctionIndex and there are other indices in front 1020 // of it, we need to use the largest of those to get the right size. 1021 if (MaxIndex == FunctionIndex && Attrs.size() > 1) 1022 MaxIndex = Attrs[Attrs.size() - 2].first; 1023 1024 SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1); 1025 for (const auto Pair : Attrs) 1026 AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second; 1027 1028 return getImpl(C, AttrVec); 1029 } 1030 1031 AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs, 1032 AttributeSet RetAttrs, 1033 ArrayRef<AttributeSet> ArgAttrs) { 1034 // Scan from the end to find the last argument with attributes. Most 1035 // arguments don't have attributes, so it's nice if we can have fewer unique 1036 // AttributeListImpls by dropping empty attribute sets at the end of the list. 1037 unsigned NumSets = 0; 1038 for (size_t I = ArgAttrs.size(); I != 0; --I) { 1039 if (ArgAttrs[I - 1].hasAttributes()) { 1040 NumSets = I + 2; 1041 break; 1042 } 1043 } 1044 if (NumSets == 0) { 1045 // Check function and return attributes if we didn't have argument 1046 // attributes. 1047 if (RetAttrs.hasAttributes()) 1048 NumSets = 2; 1049 else if (FnAttrs.hasAttributes()) 1050 NumSets = 1; 1051 } 1052 1053 // If all attribute sets were empty, we can use the empty attribute list. 1054 if (NumSets == 0) 1055 return {}; 1056 1057 SmallVector<AttributeSet, 8> AttrSets; 1058 AttrSets.reserve(NumSets); 1059 // If we have any attributes, we always have function attributes. 1060 AttrSets.push_back(FnAttrs); 1061 if (NumSets > 1) 1062 AttrSets.push_back(RetAttrs); 1063 if (NumSets > 2) { 1064 // Drop the empty argument attribute sets at the end. 1065 ArgAttrs = ArgAttrs.take_front(NumSets - 2); 1066 AttrSets.insert(AttrSets.end(), ArgAttrs.begin(), ArgAttrs.end()); 1067 } 1068 1069 return getImpl(C, AttrSets); 1070 } 1071 1072 AttributeList AttributeList::get(LLVMContext &C, unsigned Index, 1073 const AttrBuilder &B) { 1074 if (!B.hasAttributes()) 1075 return {}; 1076 Index = attrIdxToArrayIdx(Index); 1077 SmallVector<AttributeSet, 8> AttrSets(Index + 1); 1078 AttrSets[Index] = AttributeSet::get(C, B); 1079 return getImpl(C, AttrSets); 1080 } 1081 1082 AttributeList AttributeList::get(LLVMContext &C, unsigned Index, 1083 ArrayRef<Attribute::AttrKind> Kinds) { 1084 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; 1085 for (const auto K : Kinds) 1086 Attrs.emplace_back(Index, Attribute::get(C, K)); 1087 return get(C, Attrs); 1088 } 1089 1090 AttributeList AttributeList::get(LLVMContext &C, unsigned Index, 1091 ArrayRef<StringRef> Kinds) { 1092 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; 1093 for (const auto K : Kinds) 1094 Attrs.emplace_back(Index, Attribute::get(C, K)); 1095 return get(C, Attrs); 1096 } 1097 1098 AttributeList AttributeList::get(LLVMContext &C, 1099 ArrayRef<AttributeList> Attrs) { 1100 if (Attrs.empty()) 1101 return {}; 1102 if (Attrs.size() == 1) 1103 return Attrs[0]; 1104 1105 unsigned MaxSize = 0; 1106 for (const auto List : Attrs) 1107 MaxSize = std::max(MaxSize, List.getNumAttrSets()); 1108 1109 // If every list was empty, there is no point in merging the lists. 1110 if (MaxSize == 0) 1111 return {}; 1112 1113 SmallVector<AttributeSet, 8> NewAttrSets(MaxSize); 1114 for (unsigned I = 0; I < MaxSize; ++I) { 1115 AttrBuilder CurBuilder; 1116 for (const auto List : Attrs) 1117 CurBuilder.merge(List.getAttributes(I - 1)); 1118 NewAttrSets[I] = AttributeSet::get(C, CurBuilder); 1119 } 1120 1121 return getImpl(C, NewAttrSets); 1122 } 1123 1124 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index, 1125 Attribute::AttrKind Kind) const { 1126 if (hasAttribute(Index, Kind)) return *this; 1127 AttrBuilder B; 1128 B.addAttribute(Kind); 1129 return addAttributes(C, Index, B); 1130 } 1131 1132 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index, 1133 StringRef Kind, 1134 StringRef Value) const { 1135 AttrBuilder B; 1136 B.addAttribute(Kind, Value); 1137 return addAttributes(C, Index, B); 1138 } 1139 1140 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index, 1141 Attribute A) const { 1142 AttrBuilder B; 1143 B.addAttribute(A); 1144 return addAttributes(C, Index, B); 1145 } 1146 1147 AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index, 1148 const AttrBuilder &B) const { 1149 if (!B.hasAttributes()) 1150 return *this; 1151 1152 if (!pImpl) 1153 return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}}); 1154 1155 #ifndef NDEBUG 1156 // FIXME it is not obvious how this should work for alignment. For now, say 1157 // we can't change a known alignment. 1158 unsigned OldAlign = getAttributes(Index).getAlignment(); 1159 unsigned NewAlign = B.getAlignment(); 1160 assert((!OldAlign || !NewAlign || OldAlign == NewAlign) && 1161 "Attempt to change alignment!"); 1162 #endif 1163 1164 Index = attrIdxToArrayIdx(Index); 1165 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1166 if (Index >= AttrSets.size()) 1167 AttrSets.resize(Index + 1); 1168 1169 AttrBuilder Merged(AttrSets[Index]); 1170 Merged.merge(B); 1171 AttrSets[Index] = AttributeSet::get(C, Merged); 1172 1173 return getImpl(C, AttrSets); 1174 } 1175 1176 AttributeList AttributeList::addParamAttribute(LLVMContext &C, 1177 ArrayRef<unsigned> ArgNos, 1178 Attribute A) const { 1179 assert(std::is_sorted(ArgNos.begin(), ArgNos.end())); 1180 1181 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1182 unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex); 1183 if (MaxIndex >= AttrSets.size()) 1184 AttrSets.resize(MaxIndex + 1); 1185 1186 for (unsigned ArgNo : ArgNos) { 1187 unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex); 1188 AttrBuilder B(AttrSets[Index]); 1189 B.addAttribute(A); 1190 AttrSets[Index] = AttributeSet::get(C, B); 1191 } 1192 1193 return getImpl(C, AttrSets); 1194 } 1195 1196 AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index, 1197 Attribute::AttrKind Kind) const { 1198 if (!hasAttribute(Index, Kind)) return *this; 1199 1200 Index = attrIdxToArrayIdx(Index); 1201 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1202 assert(Index < AttrSets.size()); 1203 1204 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind); 1205 1206 return getImpl(C, AttrSets); 1207 } 1208 1209 AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index, 1210 StringRef Kind) const { 1211 if (!hasAttribute(Index, Kind)) return *this; 1212 1213 Index = attrIdxToArrayIdx(Index); 1214 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1215 assert(Index < AttrSets.size()); 1216 1217 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind); 1218 1219 return getImpl(C, AttrSets); 1220 } 1221 1222 AttributeList 1223 AttributeList::removeAttributes(LLVMContext &C, unsigned Index, 1224 const AttrBuilder &AttrsToRemove) const { 1225 if (!pImpl) 1226 return {}; 1227 1228 Index = attrIdxToArrayIdx(Index); 1229 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1230 if (Index >= AttrSets.size()) 1231 AttrSets.resize(Index + 1); 1232 1233 AttrSets[Index] = AttrSets[Index].removeAttributes(C, AttrsToRemove); 1234 1235 return getImpl(C, AttrSets); 1236 } 1237 1238 AttributeList AttributeList::removeAttributes(LLVMContext &C, 1239 unsigned WithoutIndex) const { 1240 if (!pImpl) 1241 return {}; 1242 WithoutIndex = attrIdxToArrayIdx(WithoutIndex); 1243 if (WithoutIndex >= getNumAttrSets()) 1244 return *this; 1245 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1246 AttrSets[WithoutIndex] = AttributeSet(); 1247 return getImpl(C, AttrSets); 1248 } 1249 1250 AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C, 1251 unsigned Index, 1252 uint64_t Bytes) const { 1253 AttrBuilder B; 1254 B.addDereferenceableAttr(Bytes); 1255 return addAttributes(C, Index, B); 1256 } 1257 1258 AttributeList 1259 AttributeList::addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index, 1260 uint64_t Bytes) const { 1261 AttrBuilder B; 1262 B.addDereferenceableOrNullAttr(Bytes); 1263 return addAttributes(C, Index, B); 1264 } 1265 1266 AttributeList 1267 AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index, 1268 unsigned ElemSizeArg, 1269 const Optional<unsigned> &NumElemsArg) { 1270 AttrBuilder B; 1271 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg); 1272 return addAttributes(C, Index, B); 1273 } 1274 1275 //===----------------------------------------------------------------------===// 1276 // AttributeList Accessor Methods 1277 //===----------------------------------------------------------------------===// 1278 1279 LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); } 1280 1281 AttributeSet AttributeList::getParamAttributes(unsigned ArgNo) const { 1282 return getAttributes(ArgNo + FirstArgIndex); 1283 } 1284 1285 AttributeSet AttributeList::getRetAttributes() const { 1286 return getAttributes(ReturnIndex); 1287 } 1288 1289 AttributeSet AttributeList::getFnAttributes() const { 1290 return getAttributes(FunctionIndex); 1291 } 1292 1293 bool AttributeList::hasAttribute(unsigned Index, 1294 Attribute::AttrKind Kind) const { 1295 return getAttributes(Index).hasAttribute(Kind); 1296 } 1297 1298 bool AttributeList::hasAttribute(unsigned Index, StringRef Kind) const { 1299 return getAttributes(Index).hasAttribute(Kind); 1300 } 1301 1302 bool AttributeList::hasAttributes(unsigned Index) const { 1303 return getAttributes(Index).hasAttributes(); 1304 } 1305 1306 bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind) const { 1307 return pImpl && pImpl->hasFnAttribute(Kind); 1308 } 1309 1310 bool AttributeList::hasFnAttribute(StringRef Kind) const { 1311 return hasAttribute(AttributeList::FunctionIndex, Kind); 1312 } 1313 1314 bool AttributeList::hasParamAttribute(unsigned ArgNo, 1315 Attribute::AttrKind Kind) const { 1316 return hasAttribute(ArgNo + FirstArgIndex, Kind); 1317 } 1318 1319 bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr, 1320 unsigned *Index) const { 1321 if (!pImpl) return false; 1322 1323 for (unsigned I = index_begin(), E = index_end(); I != E; ++I) { 1324 if (hasAttribute(I, Attr)) { 1325 if (Index) 1326 *Index = I; 1327 return true; 1328 } 1329 } 1330 1331 return false; 1332 } 1333 1334 Attribute AttributeList::getAttribute(unsigned Index, 1335 Attribute::AttrKind Kind) const { 1336 return getAttributes(Index).getAttribute(Kind); 1337 } 1338 1339 Attribute AttributeList::getAttribute(unsigned Index, StringRef Kind) const { 1340 return getAttributes(Index).getAttribute(Kind); 1341 } 1342 1343 unsigned AttributeList::getRetAlignment() const { 1344 return getAttributes(ReturnIndex).getAlignment(); 1345 } 1346 1347 unsigned AttributeList::getParamAlignment(unsigned ArgNo) const { 1348 return getAttributes(ArgNo + FirstArgIndex).getAlignment(); 1349 } 1350 1351 Type *AttributeList::getParamByValType(unsigned Index) const { 1352 return getAttributes(Index+FirstArgIndex).getByValType(); 1353 } 1354 1355 1356 unsigned AttributeList::getStackAlignment(unsigned Index) const { 1357 return getAttributes(Index).getStackAlignment(); 1358 } 1359 1360 uint64_t AttributeList::getDereferenceableBytes(unsigned Index) const { 1361 return getAttributes(Index).getDereferenceableBytes(); 1362 } 1363 1364 uint64_t AttributeList::getDereferenceableOrNullBytes(unsigned Index) const { 1365 return getAttributes(Index).getDereferenceableOrNullBytes(); 1366 } 1367 1368 std::pair<unsigned, Optional<unsigned>> 1369 AttributeList::getAllocSizeArgs(unsigned Index) const { 1370 return getAttributes(Index).getAllocSizeArgs(); 1371 } 1372 1373 std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const { 1374 return getAttributes(Index).getAsString(InAttrGrp); 1375 } 1376 1377 AttributeSet AttributeList::getAttributes(unsigned Index) const { 1378 Index = attrIdxToArrayIdx(Index); 1379 if (!pImpl || Index >= getNumAttrSets()) 1380 return {}; 1381 return pImpl->begin()[Index]; 1382 } 1383 1384 AttributeList::iterator AttributeList::begin() const { 1385 return pImpl ? pImpl->begin() : nullptr; 1386 } 1387 1388 AttributeList::iterator AttributeList::end() const { 1389 return pImpl ? pImpl->end() : nullptr; 1390 } 1391 1392 //===----------------------------------------------------------------------===// 1393 // AttributeList Introspection Methods 1394 //===----------------------------------------------------------------------===// 1395 1396 unsigned AttributeList::getNumAttrSets() const { 1397 return pImpl ? pImpl->NumAttrSets : 0; 1398 } 1399 1400 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1401 LLVM_DUMP_METHOD void AttributeList::dump() const { 1402 dbgs() << "PAL[\n"; 1403 1404 for (unsigned i = index_begin(), e = index_end(); i != e; ++i) { 1405 if (getAttributes(i).hasAttributes()) 1406 dbgs() << " { " << i << " => " << getAsString(i) << " }\n"; 1407 } 1408 1409 dbgs() << "]\n"; 1410 } 1411 #endif 1412 1413 //===----------------------------------------------------------------------===// 1414 // AttrBuilder Method Implementations 1415 //===----------------------------------------------------------------------===// 1416 1417 // FIXME: Remove this ctor, use AttributeSet. 1418 AttrBuilder::AttrBuilder(AttributeList AL, unsigned Index) { 1419 AttributeSet AS = AL.getAttributes(Index); 1420 for (const auto &A : AS) 1421 addAttribute(A); 1422 } 1423 1424 AttrBuilder::AttrBuilder(AttributeSet AS) { 1425 for (const auto &A : AS) 1426 addAttribute(A); 1427 } 1428 1429 void AttrBuilder::clear() { 1430 Attrs.reset(); 1431 TargetDepAttrs.clear(); 1432 Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0; 1433 AllocSizeArgs = 0; 1434 ByValType = nullptr; 1435 } 1436 1437 AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { 1438 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!"); 1439 assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment && 1440 Val != Attribute::Dereferenceable && Val != Attribute::AllocSize && 1441 "Adding integer attribute without adding a value!"); 1442 Attrs[Val] = true; 1443 return *this; 1444 } 1445 1446 AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) { 1447 if (Attr.isStringAttribute()) { 1448 addAttribute(Attr.getKindAsString(), Attr.getValueAsString()); 1449 return *this; 1450 } 1451 1452 Attribute::AttrKind Kind = Attr.getKindAsEnum(); 1453 Attrs[Kind] = true; 1454 1455 if (Kind == Attribute::Alignment) 1456 Alignment = Attr.getAlignment(); 1457 else if (Kind == Attribute::StackAlignment) 1458 StackAlignment = Attr.getStackAlignment(); 1459 else if (Kind == Attribute::ByVal) 1460 ByValType = Attr.getValueAsType(); 1461 else if (Kind == Attribute::Dereferenceable) 1462 DerefBytes = Attr.getDereferenceableBytes(); 1463 else if (Kind == Attribute::DereferenceableOrNull) 1464 DerefOrNullBytes = Attr.getDereferenceableOrNullBytes(); 1465 else if (Kind == Attribute::AllocSize) 1466 AllocSizeArgs = Attr.getValueAsInt(); 1467 return *this; 1468 } 1469 1470 AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) { 1471 TargetDepAttrs[A] = V; 1472 return *this; 1473 } 1474 1475 AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { 1476 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!"); 1477 Attrs[Val] = false; 1478 1479 if (Val == Attribute::Alignment) 1480 Alignment = 0; 1481 else if (Val == Attribute::StackAlignment) 1482 StackAlignment = 0; 1483 else if (Val == Attribute::ByVal) 1484 ByValType = nullptr; 1485 else if (Val == Attribute::Dereferenceable) 1486 DerefBytes = 0; 1487 else if (Val == Attribute::DereferenceableOrNull) 1488 DerefOrNullBytes = 0; 1489 else if (Val == Attribute::AllocSize) 1490 AllocSizeArgs = 0; 1491 1492 return *this; 1493 } 1494 1495 AttrBuilder &AttrBuilder::removeAttributes(AttributeList A, uint64_t Index) { 1496 remove(A.getAttributes(Index)); 1497 return *this; 1498 } 1499 1500 AttrBuilder &AttrBuilder::removeAttribute(StringRef A) { 1501 auto I = TargetDepAttrs.find(A); 1502 if (I != TargetDepAttrs.end()) 1503 TargetDepAttrs.erase(I); 1504 return *this; 1505 } 1506 1507 std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const { 1508 return unpackAllocSizeArgs(AllocSizeArgs); 1509 } 1510 1511 AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) { 1512 if (Align == 0) return *this; 1513 1514 assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); 1515 assert(Align <= 0x40000000 && "Alignment too large."); 1516 1517 Attrs[Attribute::Alignment] = true; 1518 Alignment = Align; 1519 return *this; 1520 } 1521 1522 AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) { 1523 // Default alignment, allow the target to define how to align it. 1524 if (Align == 0) return *this; 1525 1526 assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); 1527 assert(Align <= 0x100 && "Alignment too large."); 1528 1529 Attrs[Attribute::StackAlignment] = true; 1530 StackAlignment = Align; 1531 return *this; 1532 } 1533 1534 AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) { 1535 if (Bytes == 0) return *this; 1536 1537 Attrs[Attribute::Dereferenceable] = true; 1538 DerefBytes = Bytes; 1539 return *this; 1540 } 1541 1542 AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) { 1543 if (Bytes == 0) 1544 return *this; 1545 1546 Attrs[Attribute::DereferenceableOrNull] = true; 1547 DerefOrNullBytes = Bytes; 1548 return *this; 1549 } 1550 1551 AttrBuilder &AttrBuilder::addAllocSizeAttr(unsigned ElemSize, 1552 const Optional<unsigned> &NumElems) { 1553 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems)); 1554 } 1555 1556 AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) { 1557 // (0, 0) is our "not present" value, so we need to check for it here. 1558 assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)"); 1559 1560 Attrs[Attribute::AllocSize] = true; 1561 // Reuse existing machinery to store this as a single 64-bit integer so we can 1562 // save a few bytes over using a pair<unsigned, Optional<unsigned>>. 1563 AllocSizeArgs = RawArgs; 1564 return *this; 1565 } 1566 1567 AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) { 1568 Attrs[Attribute::ByVal] = true; 1569 ByValType = Ty; 1570 return *this; 1571 } 1572 1573 AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { 1574 // FIXME: What if both have alignments, but they don't match?! 1575 if (!Alignment) 1576 Alignment = B.Alignment; 1577 1578 if (!StackAlignment) 1579 StackAlignment = B.StackAlignment; 1580 1581 if (!DerefBytes) 1582 DerefBytes = B.DerefBytes; 1583 1584 if (!DerefOrNullBytes) 1585 DerefOrNullBytes = B.DerefOrNullBytes; 1586 1587 if (!AllocSizeArgs) 1588 AllocSizeArgs = B.AllocSizeArgs; 1589 1590 if (!ByValType) 1591 ByValType = B.ByValType; 1592 1593 Attrs |= B.Attrs; 1594 1595 for (auto I : B.td_attrs()) 1596 TargetDepAttrs[I.first] = I.second; 1597 1598 return *this; 1599 } 1600 1601 AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) { 1602 // FIXME: What if both have alignments, but they don't match?! 1603 if (B.Alignment) 1604 Alignment = 0; 1605 1606 if (B.StackAlignment) 1607 StackAlignment = 0; 1608 1609 if (B.DerefBytes) 1610 DerefBytes = 0; 1611 1612 if (B.DerefOrNullBytes) 1613 DerefOrNullBytes = 0; 1614 1615 if (B.AllocSizeArgs) 1616 AllocSizeArgs = 0; 1617 1618 if (B.ByValType) 1619 ByValType = nullptr; 1620 1621 Attrs &= ~B.Attrs; 1622 1623 for (auto I : B.td_attrs()) 1624 TargetDepAttrs.erase(I.first); 1625 1626 return *this; 1627 } 1628 1629 bool AttrBuilder::overlaps(const AttrBuilder &B) const { 1630 // First check if any of the target independent attributes overlap. 1631 if ((Attrs & B.Attrs).any()) 1632 return true; 1633 1634 // Then check if any target dependent ones do. 1635 for (const auto &I : td_attrs()) 1636 if (B.contains(I.first)) 1637 return true; 1638 1639 return false; 1640 } 1641 1642 bool AttrBuilder::contains(StringRef A) const { 1643 return TargetDepAttrs.find(A) != TargetDepAttrs.end(); 1644 } 1645 1646 bool AttrBuilder::hasAttributes() const { 1647 return !Attrs.none() || !TargetDepAttrs.empty(); 1648 } 1649 1650 bool AttrBuilder::hasAttributes(AttributeList AL, uint64_t Index) const { 1651 AttributeSet AS = AL.getAttributes(Index); 1652 1653 for (const auto Attr : AS) { 1654 if (Attr.isEnumAttribute() || Attr.isIntAttribute()) { 1655 if (contains(Attr.getKindAsEnum())) 1656 return true; 1657 } else { 1658 assert(Attr.isStringAttribute() && "Invalid attribute kind!"); 1659 return contains(Attr.getKindAsString()); 1660 } 1661 } 1662 1663 return false; 1664 } 1665 1666 bool AttrBuilder::hasAlignmentAttr() const { 1667 return Alignment != 0; 1668 } 1669 1670 bool AttrBuilder::operator==(const AttrBuilder &B) { 1671 if (Attrs != B.Attrs) 1672 return false; 1673 1674 for (td_const_iterator I = TargetDepAttrs.begin(), 1675 E = TargetDepAttrs.end(); I != E; ++I) 1676 if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end()) 1677 return false; 1678 1679 return Alignment == B.Alignment && StackAlignment == B.StackAlignment && 1680 DerefBytes == B.DerefBytes && ByValType == B.ByValType; 1681 } 1682 1683 //===----------------------------------------------------------------------===// 1684 // AttributeFuncs Function Defintions 1685 //===----------------------------------------------------------------------===// 1686 1687 /// Which attributes cannot be applied to a type. 1688 AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) { 1689 AttrBuilder Incompatible; 1690 1691 if (!Ty->isIntegerTy()) 1692 // Attribute that only apply to integers. 1693 Incompatible.addAttribute(Attribute::SExt) 1694 .addAttribute(Attribute::ZExt); 1695 1696 if (!Ty->isPointerTy()) 1697 // Attribute that only apply to pointers. 1698 Incompatible.addAttribute(Attribute::ByVal) 1699 .addAttribute(Attribute::Nest) 1700 .addAttribute(Attribute::NoAlias) 1701 .addAttribute(Attribute::NoCapture) 1702 .addAttribute(Attribute::NonNull) 1703 .addDereferenceableAttr(1) // the int here is ignored 1704 .addDereferenceableOrNullAttr(1) // the int here is ignored 1705 .addAttribute(Attribute::ReadNone) 1706 .addAttribute(Attribute::ReadOnly) 1707 .addAttribute(Attribute::StructRet) 1708 .addAttribute(Attribute::InAlloca); 1709 1710 return Incompatible; 1711 } 1712 1713 template<typename AttrClass> 1714 static bool isEqual(const Function &Caller, const Function &Callee) { 1715 return Caller.getFnAttribute(AttrClass::getKind()) == 1716 Callee.getFnAttribute(AttrClass::getKind()); 1717 } 1718 1719 /// Compute the logical AND of the attributes of the caller and the 1720 /// callee. 1721 /// 1722 /// This function sets the caller's attribute to false if the callee's attribute 1723 /// is false. 1724 template<typename AttrClass> 1725 static void setAND(Function &Caller, const Function &Callee) { 1726 if (AttrClass::isSet(Caller, AttrClass::getKind()) && 1727 !AttrClass::isSet(Callee, AttrClass::getKind())) 1728 AttrClass::set(Caller, AttrClass::getKind(), false); 1729 } 1730 1731 /// Compute the logical OR of the attributes of the caller and the 1732 /// callee. 1733 /// 1734 /// This function sets the caller's attribute to true if the callee's attribute 1735 /// is true. 1736 template<typename AttrClass> 1737 static void setOR(Function &Caller, const Function &Callee) { 1738 if (!AttrClass::isSet(Caller, AttrClass::getKind()) && 1739 AttrClass::isSet(Callee, AttrClass::getKind())) 1740 AttrClass::set(Caller, AttrClass::getKind(), true); 1741 } 1742 1743 /// If the inlined function had a higher stack protection level than the 1744 /// calling function, then bump up the caller's stack protection level. 1745 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) { 1746 // If upgrading the SSP attribute, clear out the old SSP Attributes first. 1747 // Having multiple SSP attributes doesn't actually hurt, but it adds useless 1748 // clutter to the IR. 1749 AttrBuilder OldSSPAttr; 1750 OldSSPAttr.addAttribute(Attribute::StackProtect) 1751 .addAttribute(Attribute::StackProtectStrong) 1752 .addAttribute(Attribute::StackProtectReq); 1753 1754 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) { 1755 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr); 1756 Caller.addFnAttr(Attribute::StackProtectReq); 1757 } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) && 1758 !Caller.hasFnAttribute(Attribute::StackProtectReq)) { 1759 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr); 1760 Caller.addFnAttr(Attribute::StackProtectStrong); 1761 } else if (Callee.hasFnAttribute(Attribute::StackProtect) && 1762 !Caller.hasFnAttribute(Attribute::StackProtectReq) && 1763 !Caller.hasFnAttribute(Attribute::StackProtectStrong)) 1764 Caller.addFnAttr(Attribute::StackProtect); 1765 } 1766 1767 /// If the inlined function required stack probes, then ensure that 1768 /// the calling function has those too. 1769 static void adjustCallerStackProbes(Function &Caller, const Function &Callee) { 1770 if (!Caller.hasFnAttribute("probe-stack") && 1771 Callee.hasFnAttribute("probe-stack")) { 1772 Caller.addFnAttr(Callee.getFnAttribute("probe-stack")); 1773 } 1774 } 1775 1776 /// If the inlined function defines the size of guard region 1777 /// on the stack, then ensure that the calling function defines a guard region 1778 /// that is no larger. 1779 static void 1780 adjustCallerStackProbeSize(Function &Caller, const Function &Callee) { 1781 if (Callee.hasFnAttribute("stack-probe-size")) { 1782 uint64_t CalleeStackProbeSize; 1783 Callee.getFnAttribute("stack-probe-size") 1784 .getValueAsString() 1785 .getAsInteger(0, CalleeStackProbeSize); 1786 if (Caller.hasFnAttribute("stack-probe-size")) { 1787 uint64_t CallerStackProbeSize; 1788 Caller.getFnAttribute("stack-probe-size") 1789 .getValueAsString() 1790 .getAsInteger(0, CallerStackProbeSize); 1791 if (CallerStackProbeSize > CalleeStackProbeSize) { 1792 Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size")); 1793 } 1794 } else { 1795 Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size")); 1796 } 1797 } 1798 } 1799 1800 /// If the inlined function defines a min legal vector width, then ensure 1801 /// the calling function has the same or larger min legal vector width. If the 1802 /// caller has the attribute, but the callee doesn't, we need to remove the 1803 /// attribute from the caller since we can't make any guarantees about the 1804 /// caller's requirements. 1805 /// This function is called after the inlining decision has been made so we have 1806 /// to merge the attribute this way. Heuristics that would use 1807 /// min-legal-vector-width to determine inline compatibility would need to be 1808 /// handled as part of inline cost analysis. 1809 static void 1810 adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) { 1811 if (Caller.hasFnAttribute("min-legal-vector-width")) { 1812 if (Callee.hasFnAttribute("min-legal-vector-width")) { 1813 uint64_t CallerVectorWidth; 1814 Caller.getFnAttribute("min-legal-vector-width") 1815 .getValueAsString() 1816 .getAsInteger(0, CallerVectorWidth); 1817 uint64_t CalleeVectorWidth; 1818 Callee.getFnAttribute("min-legal-vector-width") 1819 .getValueAsString() 1820 .getAsInteger(0, CalleeVectorWidth); 1821 if (CallerVectorWidth < CalleeVectorWidth) 1822 Caller.addFnAttr(Callee.getFnAttribute("min-legal-vector-width")); 1823 } else { 1824 // If the callee doesn't have the attribute then we don't know anything 1825 // and must drop the attribute from the caller. 1826 Caller.removeFnAttr("min-legal-vector-width"); 1827 } 1828 } 1829 } 1830 1831 /// If the inlined function has "null-pointer-is-valid=true" attribute, 1832 /// set this attribute in the caller post inlining. 1833 static void 1834 adjustNullPointerValidAttr(Function &Caller, const Function &Callee) { 1835 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) { 1836 Caller.addFnAttr(Callee.getFnAttribute("null-pointer-is-valid")); 1837 } 1838 } 1839 1840 #define GET_ATTR_COMPAT_FUNC 1841 #include "AttributesCompatFunc.inc" 1842 1843 bool AttributeFuncs::areInlineCompatible(const Function &Caller, 1844 const Function &Callee) { 1845 return hasCompatibleFnAttrs(Caller, Callee); 1846 } 1847 1848 void AttributeFuncs::mergeAttributesForInlining(Function &Caller, 1849 const Function &Callee) { 1850 mergeFnAttrs(Caller, Callee); 1851 } 1852