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