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