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