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 B.remove(Attrs); 787 return get(C, B); 788 } 789 790 unsigned AttributeSet::getNumAttributes() const { 791 return SetNode ? SetNode->getNumAttributes() : 0; 792 } 793 794 bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const { 795 return SetNode ? SetNode->hasAttribute(Kind) : false; 796 } 797 798 bool AttributeSet::hasAttribute(StringRef Kind) const { 799 return SetNode ? SetNode->hasAttribute(Kind) : false; 800 } 801 802 Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const { 803 return SetNode ? SetNode->getAttribute(Kind) : Attribute(); 804 } 805 806 Attribute AttributeSet::getAttribute(StringRef Kind) const { 807 return SetNode ? SetNode->getAttribute(Kind) : Attribute(); 808 } 809 810 MaybeAlign AttributeSet::getAlignment() const { 811 return SetNode ? SetNode->getAlignment() : None; 812 } 813 814 MaybeAlign AttributeSet::getStackAlignment() const { 815 return SetNode ? SetNode->getStackAlignment() : None; 816 } 817 818 uint64_t AttributeSet::getDereferenceableBytes() const { 819 return SetNode ? SetNode->getDereferenceableBytes() : 0; 820 } 821 822 uint64_t AttributeSet::getDereferenceableOrNullBytes() const { 823 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0; 824 } 825 826 Type *AttributeSet::getByRefType() const { 827 return SetNode ? SetNode->getByRefType() : nullptr; 828 } 829 830 Type *AttributeSet::getByValType() const { 831 return SetNode ? SetNode->getByValType() : nullptr; 832 } 833 834 Type *AttributeSet::getStructRetType() const { 835 return SetNode ? SetNode->getStructRetType() : nullptr; 836 } 837 838 Type *AttributeSet::getPreallocatedType() const { 839 return SetNode ? SetNode->getPreallocatedType() : nullptr; 840 } 841 842 Type *AttributeSet::getInAllocaType() const { 843 return SetNode ? SetNode->getInAllocaType() : nullptr; 844 } 845 846 std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const { 847 return SetNode ? SetNode->getAllocSizeArgs() 848 : std::pair<unsigned, Optional<unsigned>>(0, 0); 849 } 850 851 std::pair<unsigned, unsigned> AttributeSet::getVScaleRangeArgs() const { 852 return SetNode ? SetNode->getVScaleRangeArgs() 853 : std::pair<unsigned, unsigned>(0, 0); 854 } 855 856 std::string AttributeSet::getAsString(bool InAttrGrp) const { 857 return SetNode ? SetNode->getAsString(InAttrGrp) : ""; 858 } 859 860 bool AttributeSet::hasParentContext(LLVMContext &C) const { 861 assert(hasAttributes() && "empty AttributeSet doesn't refer to any context"); 862 FoldingSetNodeID ID; 863 SetNode->Profile(ID); 864 void *Unused; 865 return C.pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, Unused) == SetNode; 866 } 867 868 AttributeSet::iterator AttributeSet::begin() const { 869 return SetNode ? SetNode->begin() : nullptr; 870 } 871 872 AttributeSet::iterator AttributeSet::end() const { 873 return SetNode ? SetNode->end() : nullptr; 874 } 875 876 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 877 LLVM_DUMP_METHOD void AttributeSet::dump() const { 878 dbgs() << "AS =\n"; 879 dbgs() << " { "; 880 dbgs() << getAsString(true) << " }\n"; 881 } 882 #endif 883 884 //===----------------------------------------------------------------------===// 885 // AttributeSetNode Definition 886 //===----------------------------------------------------------------------===// 887 888 AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs) 889 : NumAttrs(Attrs.size()) { 890 // There's memory after the node where we can store the entries in. 891 llvm::copy(Attrs, getTrailingObjects<Attribute>()); 892 893 for (const auto &I : *this) { 894 if (I.isStringAttribute()) 895 StringAttrs.insert({ I.getKindAsString(), I }); 896 else 897 AvailableAttrs.addAttribute(I.getKindAsEnum()); 898 } 899 } 900 901 AttributeSetNode *AttributeSetNode::get(LLVMContext &C, 902 ArrayRef<Attribute> Attrs) { 903 SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end()); 904 llvm::sort(SortedAttrs); 905 return getSorted(C, SortedAttrs); 906 } 907 908 AttributeSetNode *AttributeSetNode::getSorted(LLVMContext &C, 909 ArrayRef<Attribute> SortedAttrs) { 910 if (SortedAttrs.empty()) 911 return nullptr; 912 913 // Build a key to look up the existing attributes. 914 LLVMContextImpl *pImpl = C.pImpl; 915 FoldingSetNodeID ID; 916 917 assert(llvm::is_sorted(SortedAttrs) && "Expected sorted attributes!"); 918 for (const auto &Attr : SortedAttrs) 919 Attr.Profile(ID); 920 921 void *InsertPoint; 922 AttributeSetNode *PA = 923 pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint); 924 925 // If we didn't find any existing attributes of the same shape then create a 926 // new one and insert it. 927 if (!PA) { 928 // Coallocate entries after the AttributeSetNode itself. 929 void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size())); 930 PA = new (Mem) AttributeSetNode(SortedAttrs); 931 pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint); 932 } 933 934 // Return the AttributeSetNode that we found or created. 935 return PA; 936 } 937 938 AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) { 939 // Add target-independent attributes. 940 SmallVector<Attribute, 8> Attrs; 941 for (Attribute::AttrKind Kind = Attribute::None; 942 Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) { 943 if (!B.contains(Kind)) 944 continue; 945 946 Attribute Attr; 947 switch (Kind) { 948 case Attribute::ByVal: 949 Attr = Attribute::getWithByValType(C, B.getByValType()); 950 break; 951 case Attribute::StructRet: 952 Attr = Attribute::getWithStructRetType(C, B.getStructRetType()); 953 break; 954 case Attribute::ByRef: 955 Attr = Attribute::getWithByRefType(C, B.getByRefType()); 956 break; 957 case Attribute::Preallocated: 958 Attr = Attribute::getWithPreallocatedType(C, B.getPreallocatedType()); 959 break; 960 case Attribute::InAlloca: 961 Attr = Attribute::getWithInAllocaType(C, B.getInAllocaType()); 962 break; 963 case Attribute::Alignment: 964 assert(B.getAlignment() && "Alignment must be set"); 965 Attr = Attribute::getWithAlignment(C, *B.getAlignment()); 966 break; 967 case Attribute::StackAlignment: 968 assert(B.getStackAlignment() && "StackAlignment must be set"); 969 Attr = Attribute::getWithStackAlignment(C, *B.getStackAlignment()); 970 break; 971 case Attribute::Dereferenceable: 972 Attr = Attribute::getWithDereferenceableBytes( 973 C, B.getDereferenceableBytes()); 974 break; 975 case Attribute::DereferenceableOrNull: 976 Attr = Attribute::getWithDereferenceableOrNullBytes( 977 C, B.getDereferenceableOrNullBytes()); 978 break; 979 case Attribute::AllocSize: { 980 auto A = B.getAllocSizeArgs(); 981 Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second); 982 break; 983 } 984 case Attribute::VScaleRange: { 985 auto A = B.getVScaleRangeArgs(); 986 Attr = Attribute::getWithVScaleRangeArgs(C, A.first, A.second); 987 break; 988 } 989 default: 990 Attr = Attribute::get(C, Kind); 991 } 992 Attrs.push_back(Attr); 993 } 994 995 // Add target-dependent (string) attributes. 996 for (const auto &TDA : B.td_attrs()) 997 Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second)); 998 999 return getSorted(C, Attrs); 1000 } 1001 1002 bool AttributeSetNode::hasAttribute(StringRef Kind) const { 1003 return StringAttrs.count(Kind); 1004 } 1005 1006 Optional<Attribute> 1007 AttributeSetNode::findEnumAttribute(Attribute::AttrKind Kind) const { 1008 // Do a quick presence check. 1009 if (!hasAttribute(Kind)) 1010 return None; 1011 1012 // Attributes in a set are sorted by enum value, followed by string 1013 // attributes. Binary search the one we want. 1014 const Attribute *I = 1015 std::lower_bound(begin(), end() - StringAttrs.size(), Kind, 1016 [](Attribute A, Attribute::AttrKind Kind) { 1017 return A.getKindAsEnum() < Kind; 1018 }); 1019 assert(I != end() && I->hasAttribute(Kind) && "Presence check failed?"); 1020 return *I; 1021 } 1022 1023 Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const { 1024 if (auto A = findEnumAttribute(Kind)) 1025 return *A; 1026 return {}; 1027 } 1028 1029 Attribute AttributeSetNode::getAttribute(StringRef Kind) const { 1030 return StringAttrs.lookup(Kind); 1031 } 1032 1033 MaybeAlign AttributeSetNode::getAlignment() const { 1034 if (auto A = findEnumAttribute(Attribute::Alignment)) 1035 return A->getAlignment(); 1036 return None; 1037 } 1038 1039 MaybeAlign AttributeSetNode::getStackAlignment() const { 1040 if (auto A = findEnumAttribute(Attribute::StackAlignment)) 1041 return A->getStackAlignment(); 1042 return None; 1043 } 1044 1045 Type *AttributeSetNode::getByValType() const { 1046 if (auto A = findEnumAttribute(Attribute::ByVal)) 1047 return A->getValueAsType(); 1048 return nullptr; 1049 } 1050 1051 Type *AttributeSetNode::getStructRetType() const { 1052 if (auto A = findEnumAttribute(Attribute::StructRet)) 1053 return A->getValueAsType(); 1054 return nullptr; 1055 } 1056 1057 Type *AttributeSetNode::getByRefType() const { 1058 if (auto A = findEnumAttribute(Attribute::ByRef)) 1059 return A->getValueAsType(); 1060 return nullptr; 1061 } 1062 1063 Type *AttributeSetNode::getPreallocatedType() const { 1064 if (auto A = findEnumAttribute(Attribute::Preallocated)) 1065 return A->getValueAsType(); 1066 return nullptr; 1067 } 1068 1069 Type *AttributeSetNode::getInAllocaType() const { 1070 if (auto A = findEnumAttribute(Attribute::InAlloca)) 1071 return A->getValueAsType(); 1072 return nullptr; 1073 } 1074 1075 uint64_t AttributeSetNode::getDereferenceableBytes() const { 1076 if (auto A = findEnumAttribute(Attribute::Dereferenceable)) 1077 return A->getDereferenceableBytes(); 1078 return 0; 1079 } 1080 1081 uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const { 1082 if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull)) 1083 return A->getDereferenceableOrNullBytes(); 1084 return 0; 1085 } 1086 1087 std::pair<unsigned, Optional<unsigned>> 1088 AttributeSetNode::getAllocSizeArgs() const { 1089 if (auto A = findEnumAttribute(Attribute::AllocSize)) 1090 return A->getAllocSizeArgs(); 1091 return std::make_pair(0, 0); 1092 } 1093 1094 std::pair<unsigned, unsigned> AttributeSetNode::getVScaleRangeArgs() const { 1095 if (auto A = findEnumAttribute(Attribute::VScaleRange)) 1096 return A->getVScaleRangeArgs(); 1097 return std::make_pair(0, 0); 1098 } 1099 1100 std::string AttributeSetNode::getAsString(bool InAttrGrp) const { 1101 std::string Str; 1102 for (iterator I = begin(), E = end(); I != E; ++I) { 1103 if (I != begin()) 1104 Str += ' '; 1105 Str += I->getAsString(InAttrGrp); 1106 } 1107 return Str; 1108 } 1109 1110 //===----------------------------------------------------------------------===// 1111 // AttributeListImpl Definition 1112 //===----------------------------------------------------------------------===// 1113 1114 /// Map from AttributeList index to the internal array index. Adding one happens 1115 /// to work, because -1 wraps around to 0. 1116 static unsigned attrIdxToArrayIdx(unsigned Index) { 1117 return Index + 1; 1118 } 1119 1120 AttributeListImpl::AttributeListImpl(ArrayRef<AttributeSet> Sets) 1121 : NumAttrSets(Sets.size()) { 1122 assert(!Sets.empty() && "pointless AttributeListImpl"); 1123 1124 // There's memory after the node where we can store the entries in. 1125 llvm::copy(Sets, getTrailingObjects<AttributeSet>()); 1126 1127 // Initialize AvailableFunctionAttrs and AvailableSomewhereAttrs 1128 // summary bitsets. 1129 for (const auto &I : Sets[attrIdxToArrayIdx(AttributeList::FunctionIndex)]) 1130 if (!I.isStringAttribute()) 1131 AvailableFunctionAttrs.addAttribute(I.getKindAsEnum()); 1132 1133 for (const auto &Set : Sets) 1134 for (const auto &I : Set) 1135 if (!I.isStringAttribute()) 1136 AvailableSomewhereAttrs.addAttribute(I.getKindAsEnum()); 1137 } 1138 1139 void AttributeListImpl::Profile(FoldingSetNodeID &ID) const { 1140 Profile(ID, makeArrayRef(begin(), end())); 1141 } 1142 1143 void AttributeListImpl::Profile(FoldingSetNodeID &ID, 1144 ArrayRef<AttributeSet> Sets) { 1145 for (const auto &Set : Sets) 1146 ID.AddPointer(Set.SetNode); 1147 } 1148 1149 bool AttributeListImpl::hasAttrSomewhere(Attribute::AttrKind Kind, 1150 unsigned *Index) const { 1151 if (!AvailableSomewhereAttrs.hasAttribute(Kind)) 1152 return false; 1153 1154 if (Index) { 1155 for (unsigned I = 0, E = NumAttrSets; I != E; ++I) { 1156 if (begin()[I].hasAttribute(Kind)) { 1157 *Index = I - 1; 1158 break; 1159 } 1160 } 1161 } 1162 1163 return true; 1164 } 1165 1166 1167 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1168 LLVM_DUMP_METHOD void AttributeListImpl::dump() const { 1169 AttributeList(const_cast<AttributeListImpl *>(this)).dump(); 1170 } 1171 #endif 1172 1173 //===----------------------------------------------------------------------===// 1174 // AttributeList Construction and Mutation Methods 1175 //===----------------------------------------------------------------------===// 1176 1177 AttributeList AttributeList::getImpl(LLVMContext &C, 1178 ArrayRef<AttributeSet> AttrSets) { 1179 assert(!AttrSets.empty() && "pointless AttributeListImpl"); 1180 1181 LLVMContextImpl *pImpl = C.pImpl; 1182 FoldingSetNodeID ID; 1183 AttributeListImpl::Profile(ID, AttrSets); 1184 1185 void *InsertPoint; 1186 AttributeListImpl *PA = 1187 pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint); 1188 1189 // If we didn't find any existing attributes of the same shape then 1190 // create a new one and insert it. 1191 if (!PA) { 1192 // Coallocate entries after the AttributeListImpl itself. 1193 void *Mem = pImpl->Alloc.Allocate( 1194 AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()), 1195 alignof(AttributeListImpl)); 1196 PA = new (Mem) AttributeListImpl(AttrSets); 1197 pImpl->AttrsLists.InsertNode(PA, InsertPoint); 1198 } 1199 1200 // Return the AttributesList that we found or created. 1201 return AttributeList(PA); 1202 } 1203 1204 AttributeList 1205 AttributeList::get(LLVMContext &C, 1206 ArrayRef<std::pair<unsigned, Attribute>> Attrs) { 1207 // If there are no attributes then return a null AttributesList pointer. 1208 if (Attrs.empty()) 1209 return {}; 1210 1211 assert(llvm::is_sorted(Attrs, 1212 [](const std::pair<unsigned, Attribute> &LHS, 1213 const std::pair<unsigned, Attribute> &RHS) { 1214 return LHS.first < RHS.first; 1215 }) && 1216 "Misordered Attributes list!"); 1217 assert(llvm::all_of(Attrs, 1218 [](const std::pair<unsigned, Attribute> &Pair) { 1219 return Pair.second.isValid(); 1220 }) && 1221 "Pointless attribute!"); 1222 1223 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes 1224 // list. 1225 SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec; 1226 for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(), 1227 E = Attrs.end(); I != E; ) { 1228 unsigned Index = I->first; 1229 SmallVector<Attribute, 4> AttrVec; 1230 while (I != E && I->first == Index) { 1231 AttrVec.push_back(I->second); 1232 ++I; 1233 } 1234 1235 AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec)); 1236 } 1237 1238 return get(C, AttrPairVec); 1239 } 1240 1241 AttributeList 1242 AttributeList::get(LLVMContext &C, 1243 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) { 1244 // If there are no attributes then return a null AttributesList pointer. 1245 if (Attrs.empty()) 1246 return {}; 1247 1248 assert(llvm::is_sorted(Attrs, 1249 [](const std::pair<unsigned, AttributeSet> &LHS, 1250 const std::pair<unsigned, AttributeSet> &RHS) { 1251 return LHS.first < RHS.first; 1252 }) && 1253 "Misordered Attributes list!"); 1254 assert(llvm::none_of(Attrs, 1255 [](const std::pair<unsigned, AttributeSet> &Pair) { 1256 return !Pair.second.hasAttributes(); 1257 }) && 1258 "Pointless attribute!"); 1259 1260 unsigned MaxIndex = Attrs.back().first; 1261 // If the MaxIndex is FunctionIndex and there are other indices in front 1262 // of it, we need to use the largest of those to get the right size. 1263 if (MaxIndex == FunctionIndex && Attrs.size() > 1) 1264 MaxIndex = Attrs[Attrs.size() - 2].first; 1265 1266 SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1); 1267 for (const auto &Pair : Attrs) 1268 AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second; 1269 1270 return getImpl(C, AttrVec); 1271 } 1272 1273 AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs, 1274 AttributeSet RetAttrs, 1275 ArrayRef<AttributeSet> ArgAttrs) { 1276 // Scan from the end to find the last argument with attributes. Most 1277 // arguments don't have attributes, so it's nice if we can have fewer unique 1278 // AttributeListImpls by dropping empty attribute sets at the end of the list. 1279 unsigned NumSets = 0; 1280 for (size_t I = ArgAttrs.size(); I != 0; --I) { 1281 if (ArgAttrs[I - 1].hasAttributes()) { 1282 NumSets = I + 2; 1283 break; 1284 } 1285 } 1286 if (NumSets == 0) { 1287 // Check function and return attributes if we didn't have argument 1288 // attributes. 1289 if (RetAttrs.hasAttributes()) 1290 NumSets = 2; 1291 else if (FnAttrs.hasAttributes()) 1292 NumSets = 1; 1293 } 1294 1295 // If all attribute sets were empty, we can use the empty attribute list. 1296 if (NumSets == 0) 1297 return {}; 1298 1299 SmallVector<AttributeSet, 8> AttrSets; 1300 AttrSets.reserve(NumSets); 1301 // If we have any attributes, we always have function attributes. 1302 AttrSets.push_back(FnAttrs); 1303 if (NumSets > 1) 1304 AttrSets.push_back(RetAttrs); 1305 if (NumSets > 2) { 1306 // Drop the empty argument attribute sets at the end. 1307 ArgAttrs = ArgAttrs.take_front(NumSets - 2); 1308 llvm::append_range(AttrSets, ArgAttrs); 1309 } 1310 1311 return getImpl(C, AttrSets); 1312 } 1313 1314 AttributeList AttributeList::get(LLVMContext &C, unsigned Index, 1315 const AttrBuilder &B) { 1316 if (!B.hasAttributes()) 1317 return {}; 1318 Index = attrIdxToArrayIdx(Index); 1319 SmallVector<AttributeSet, 8> AttrSets(Index + 1); 1320 AttrSets[Index] = AttributeSet::get(C, B); 1321 return getImpl(C, AttrSets); 1322 } 1323 1324 AttributeList AttributeList::get(LLVMContext &C, unsigned Index, 1325 ArrayRef<Attribute::AttrKind> Kinds) { 1326 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; 1327 for (const auto K : Kinds) 1328 Attrs.emplace_back(Index, Attribute::get(C, K)); 1329 return get(C, Attrs); 1330 } 1331 1332 AttributeList AttributeList::get(LLVMContext &C, unsigned Index, 1333 ArrayRef<Attribute::AttrKind> Kinds, 1334 ArrayRef<uint64_t> Values) { 1335 assert(Kinds.size() == Values.size() && "Mismatched attribute values."); 1336 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; 1337 auto VI = Values.begin(); 1338 for (const auto K : Kinds) 1339 Attrs.emplace_back(Index, Attribute::get(C, K, *VI++)); 1340 return get(C, Attrs); 1341 } 1342 1343 AttributeList AttributeList::get(LLVMContext &C, unsigned Index, 1344 ArrayRef<StringRef> Kinds) { 1345 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; 1346 for (const auto &K : Kinds) 1347 Attrs.emplace_back(Index, Attribute::get(C, K)); 1348 return get(C, Attrs); 1349 } 1350 1351 AttributeList AttributeList::get(LLVMContext &C, 1352 ArrayRef<AttributeList> Attrs) { 1353 if (Attrs.empty()) 1354 return {}; 1355 if (Attrs.size() == 1) 1356 return Attrs[0]; 1357 1358 unsigned MaxSize = 0; 1359 for (const auto &List : Attrs) 1360 MaxSize = std::max(MaxSize, List.getNumAttrSets()); 1361 1362 // If every list was empty, there is no point in merging the lists. 1363 if (MaxSize == 0) 1364 return {}; 1365 1366 SmallVector<AttributeSet, 8> NewAttrSets(MaxSize); 1367 for (unsigned I = 0; I < MaxSize; ++I) { 1368 AttrBuilder CurBuilder; 1369 for (const auto &List : Attrs) 1370 CurBuilder.merge(List.getAttributes(I - 1)); 1371 NewAttrSets[I] = AttributeSet::get(C, CurBuilder); 1372 } 1373 1374 return getImpl(C, NewAttrSets); 1375 } 1376 1377 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index, 1378 Attribute::AttrKind Kind) const { 1379 if (hasAttribute(Index, Kind)) return *this; 1380 AttributeSet Attrs = getAttributes(Index); 1381 // TODO: Insert at correct position and avoid sort. 1382 SmallVector<Attribute, 8> NewAttrs(Attrs.begin(), Attrs.end()); 1383 NewAttrs.push_back(Attribute::get(C, Kind)); 1384 return setAttributes(C, Index, AttributeSet::get(C, NewAttrs)); 1385 } 1386 1387 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index, 1388 StringRef Kind, 1389 StringRef Value) const { 1390 AttrBuilder B; 1391 B.addAttribute(Kind, Value); 1392 return addAttributes(C, Index, B); 1393 } 1394 1395 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index, 1396 Attribute A) const { 1397 AttrBuilder B; 1398 B.addAttribute(A); 1399 return addAttributes(C, Index, B); 1400 } 1401 1402 AttributeList AttributeList::setAttributes(LLVMContext &C, unsigned Index, 1403 AttributeSet Attrs) const { 1404 Index = attrIdxToArrayIdx(Index); 1405 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1406 if (Index >= AttrSets.size()) 1407 AttrSets.resize(Index + 1); 1408 AttrSets[Index] = Attrs; 1409 return AttributeList::getImpl(C, AttrSets); 1410 } 1411 1412 AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index, 1413 const AttrBuilder &B) const { 1414 if (!B.hasAttributes()) 1415 return *this; 1416 1417 if (!pImpl) 1418 return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}}); 1419 1420 #ifndef NDEBUG 1421 // FIXME it is not obvious how this should work for alignment. For now, say 1422 // we can't change a known alignment. 1423 const MaybeAlign OldAlign = getAttributes(Index).getAlignment(); 1424 const MaybeAlign NewAlign = B.getAlignment(); 1425 assert((!OldAlign || !NewAlign || OldAlign == NewAlign) && 1426 "Attempt to change alignment!"); 1427 #endif 1428 1429 AttrBuilder Merged(getAttributes(Index)); 1430 Merged.merge(B); 1431 return setAttributes(C, Index, AttributeSet::get(C, Merged)); 1432 } 1433 1434 AttributeList AttributeList::addParamAttribute(LLVMContext &C, 1435 ArrayRef<unsigned> ArgNos, 1436 Attribute A) const { 1437 assert(llvm::is_sorted(ArgNos)); 1438 1439 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1440 unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex); 1441 if (MaxIndex >= AttrSets.size()) 1442 AttrSets.resize(MaxIndex + 1); 1443 1444 for (unsigned ArgNo : ArgNos) { 1445 unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex); 1446 AttrBuilder B(AttrSets[Index]); 1447 B.addAttribute(A); 1448 AttrSets[Index] = AttributeSet::get(C, B); 1449 } 1450 1451 return getImpl(C, AttrSets); 1452 } 1453 1454 AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index, 1455 Attribute::AttrKind Kind) const { 1456 if (!hasAttribute(Index, Kind)) return *this; 1457 1458 Index = attrIdxToArrayIdx(Index); 1459 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1460 assert(Index < AttrSets.size()); 1461 1462 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind); 1463 1464 return getImpl(C, AttrSets); 1465 } 1466 1467 AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index, 1468 StringRef Kind) const { 1469 if (!hasAttribute(Index, Kind)) return *this; 1470 1471 Index = attrIdxToArrayIdx(Index); 1472 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1473 assert(Index < AttrSets.size()); 1474 1475 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind); 1476 1477 return getImpl(C, AttrSets); 1478 } 1479 1480 AttributeList 1481 AttributeList::removeAttributes(LLVMContext &C, unsigned Index, 1482 const AttrBuilder &AttrsToRemove) const { 1483 if (!pImpl) 1484 return {}; 1485 1486 Index = attrIdxToArrayIdx(Index); 1487 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1488 if (Index >= AttrSets.size()) 1489 AttrSets.resize(Index + 1); 1490 1491 AttrSets[Index] = AttrSets[Index].removeAttributes(C, AttrsToRemove); 1492 1493 return getImpl(C, AttrSets); 1494 } 1495 1496 AttributeList AttributeList::removeAttributes(LLVMContext &C, 1497 unsigned WithoutIndex) const { 1498 if (!pImpl) 1499 return {}; 1500 WithoutIndex = attrIdxToArrayIdx(WithoutIndex); 1501 if (WithoutIndex >= getNumAttrSets()) 1502 return *this; 1503 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1504 AttrSets[WithoutIndex] = AttributeSet(); 1505 return getImpl(C, AttrSets); 1506 } 1507 1508 AttributeList 1509 AttributeList::removeParamUndefImplyingAttributes(LLVMContext &C, 1510 unsigned ArgNo) const { 1511 AttrBuilder B; 1512 B.addAttribute(Attribute::NoUndef); 1513 B.addAttribute(Attribute::NonNull); 1514 B.addDereferenceableAttr(1); 1515 B.addDereferenceableOrNullAttr(1); 1516 return removeParamAttributes(C, ArgNo, B); 1517 } 1518 1519 AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C, 1520 unsigned Index, 1521 uint64_t Bytes) const { 1522 AttrBuilder B; 1523 B.addDereferenceableAttr(Bytes); 1524 return addAttributes(C, Index, B); 1525 } 1526 1527 AttributeList 1528 AttributeList::addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index, 1529 uint64_t Bytes) const { 1530 AttrBuilder B; 1531 B.addDereferenceableOrNullAttr(Bytes); 1532 return addAttributes(C, Index, B); 1533 } 1534 1535 AttributeList 1536 AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index, 1537 unsigned ElemSizeArg, 1538 const Optional<unsigned> &NumElemsArg) { 1539 AttrBuilder B; 1540 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg); 1541 return addAttributes(C, Index, B); 1542 } 1543 1544 AttributeList AttributeList::addVScaleRangeAttr(LLVMContext &C, unsigned Index, 1545 unsigned MinValue, 1546 unsigned MaxValue) { 1547 AttrBuilder B; 1548 B.addVScaleRangeAttr(MinValue, MaxValue); 1549 return addAttributes(C, Index, B); 1550 } 1551 1552 //===----------------------------------------------------------------------===// 1553 // AttributeList Accessor Methods 1554 //===----------------------------------------------------------------------===// 1555 1556 AttributeSet AttributeList::getParamAttributes(unsigned ArgNo) const { 1557 return getAttributes(ArgNo + FirstArgIndex); 1558 } 1559 1560 AttributeSet AttributeList::getRetAttributes() const { 1561 return getAttributes(ReturnIndex); 1562 } 1563 1564 AttributeSet AttributeList::getFnAttributes() const { 1565 return getAttributes(FunctionIndex); 1566 } 1567 1568 bool AttributeList::hasAttribute(unsigned Index, 1569 Attribute::AttrKind Kind) const { 1570 return getAttributes(Index).hasAttribute(Kind); 1571 } 1572 1573 bool AttributeList::hasAttribute(unsigned Index, StringRef Kind) const { 1574 return getAttributes(Index).hasAttribute(Kind); 1575 } 1576 1577 bool AttributeList::hasAttributes(unsigned Index) const { 1578 return getAttributes(Index).hasAttributes(); 1579 } 1580 1581 bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind) const { 1582 return pImpl && pImpl->hasFnAttribute(Kind); 1583 } 1584 1585 bool AttributeList::hasFnAttribute(StringRef Kind) const { 1586 return hasAttribute(AttributeList::FunctionIndex, Kind); 1587 } 1588 1589 bool AttributeList::hasParamAttribute(unsigned ArgNo, 1590 Attribute::AttrKind Kind) const { 1591 return hasAttribute(ArgNo + FirstArgIndex, Kind); 1592 } 1593 1594 bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr, 1595 unsigned *Index) const { 1596 return pImpl && pImpl->hasAttrSomewhere(Attr, Index); 1597 } 1598 1599 Attribute AttributeList::getAttribute(unsigned Index, 1600 Attribute::AttrKind Kind) const { 1601 return getAttributes(Index).getAttribute(Kind); 1602 } 1603 1604 Attribute AttributeList::getAttribute(unsigned Index, StringRef Kind) const { 1605 return getAttributes(Index).getAttribute(Kind); 1606 } 1607 1608 MaybeAlign AttributeList::getRetAlignment() const { 1609 return getAttributes(ReturnIndex).getAlignment(); 1610 } 1611 1612 MaybeAlign AttributeList::getParamAlignment(unsigned ArgNo) const { 1613 return getAttributes(ArgNo + FirstArgIndex).getAlignment(); 1614 } 1615 1616 MaybeAlign AttributeList::getParamStackAlignment(unsigned ArgNo) const { 1617 return getAttributes(ArgNo + FirstArgIndex).getStackAlignment(); 1618 } 1619 1620 Type *AttributeList::getParamByValType(unsigned Index) const { 1621 return getAttributes(Index+FirstArgIndex).getByValType(); 1622 } 1623 1624 Type *AttributeList::getParamStructRetType(unsigned Index) const { 1625 return getAttributes(Index + FirstArgIndex).getStructRetType(); 1626 } 1627 1628 Type *AttributeList::getParamByRefType(unsigned Index) const { 1629 return getAttributes(Index + FirstArgIndex).getByRefType(); 1630 } 1631 1632 Type *AttributeList::getParamPreallocatedType(unsigned Index) const { 1633 return getAttributes(Index + FirstArgIndex).getPreallocatedType(); 1634 } 1635 1636 Type *AttributeList::getParamInAllocaType(unsigned Index) const { 1637 return getAttributes(Index + FirstArgIndex).getInAllocaType(); 1638 } 1639 1640 MaybeAlign AttributeList::getStackAlignment(unsigned Index) const { 1641 return getAttributes(Index).getStackAlignment(); 1642 } 1643 1644 uint64_t AttributeList::getDereferenceableBytes(unsigned Index) const { 1645 return getAttributes(Index).getDereferenceableBytes(); 1646 } 1647 1648 uint64_t AttributeList::getDereferenceableOrNullBytes(unsigned Index) const { 1649 return getAttributes(Index).getDereferenceableOrNullBytes(); 1650 } 1651 1652 std::pair<unsigned, Optional<unsigned>> 1653 AttributeList::getAllocSizeArgs(unsigned Index) const { 1654 return getAttributes(Index).getAllocSizeArgs(); 1655 } 1656 1657 std::pair<unsigned, unsigned> 1658 AttributeList::getVScaleRangeArgs(unsigned Index) const { 1659 return getAttributes(Index).getVScaleRangeArgs(); 1660 } 1661 1662 std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const { 1663 return getAttributes(Index).getAsString(InAttrGrp); 1664 } 1665 1666 AttributeSet AttributeList::getAttributes(unsigned Index) const { 1667 Index = attrIdxToArrayIdx(Index); 1668 if (!pImpl || Index >= getNumAttrSets()) 1669 return {}; 1670 return pImpl->begin()[Index]; 1671 } 1672 1673 bool AttributeList::hasParentContext(LLVMContext &C) const { 1674 assert(!isEmpty() && "an empty attribute list has no parent context"); 1675 FoldingSetNodeID ID; 1676 pImpl->Profile(ID); 1677 void *Unused; 1678 return C.pImpl->AttrsLists.FindNodeOrInsertPos(ID, Unused) == pImpl; 1679 } 1680 1681 AttributeList::iterator AttributeList::begin() const { 1682 return pImpl ? pImpl->begin() : nullptr; 1683 } 1684 1685 AttributeList::iterator AttributeList::end() const { 1686 return pImpl ? pImpl->end() : nullptr; 1687 } 1688 1689 //===----------------------------------------------------------------------===// 1690 // AttributeList Introspection Methods 1691 //===----------------------------------------------------------------------===// 1692 1693 unsigned AttributeList::getNumAttrSets() const { 1694 return pImpl ? pImpl->NumAttrSets : 0; 1695 } 1696 1697 void AttributeList::print(raw_ostream &O) const { 1698 O << "AttributeList[\n"; 1699 1700 for (unsigned i = index_begin(), e = index_end(); i != e; ++i) { 1701 if (!getAttributes(i).hasAttributes()) 1702 continue; 1703 O << " { "; 1704 switch (i) { 1705 case AttrIndex::ReturnIndex: 1706 O << "return"; 1707 break; 1708 case AttrIndex::FunctionIndex: 1709 O << "function"; 1710 break; 1711 default: 1712 O << "arg(" << i - AttrIndex::FirstArgIndex << ")"; 1713 } 1714 O << " => " << getAsString(i) << " }\n"; 1715 } 1716 1717 O << "]\n"; 1718 } 1719 1720 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1721 LLVM_DUMP_METHOD void AttributeList::dump() const { print(dbgs()); } 1722 #endif 1723 1724 //===----------------------------------------------------------------------===// 1725 // AttrBuilder Method Implementations 1726 //===----------------------------------------------------------------------===// 1727 1728 // FIXME: Remove this ctor, use AttributeSet. 1729 AttrBuilder::AttrBuilder(AttributeList AL, unsigned Index) { 1730 AttributeSet AS = AL.getAttributes(Index); 1731 for (const auto &A : AS) 1732 addAttribute(A); 1733 } 1734 1735 AttrBuilder::AttrBuilder(AttributeSet AS) { 1736 for (const auto &A : AS) 1737 addAttribute(A); 1738 } 1739 1740 void AttrBuilder::clear() { 1741 Attrs.reset(); 1742 TargetDepAttrs.clear(); 1743 Alignment.reset(); 1744 StackAlignment.reset(); 1745 DerefBytes = DerefOrNullBytes = 0; 1746 AllocSizeArgs = 0; 1747 VScaleRangeArgs = 0; 1748 ByValType = nullptr; 1749 StructRetType = nullptr; 1750 ByRefType = nullptr; 1751 PreallocatedType = nullptr; 1752 } 1753 1754 AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) { 1755 if (Attr.isStringAttribute()) { 1756 addAttribute(Attr.getKindAsString(), Attr.getValueAsString()); 1757 return *this; 1758 } 1759 1760 Attribute::AttrKind Kind = Attr.getKindAsEnum(); 1761 Attrs[Kind] = true; 1762 1763 if (Kind == Attribute::Alignment) 1764 Alignment = Attr.getAlignment(); 1765 else if (Kind == Attribute::StackAlignment) 1766 StackAlignment = Attr.getStackAlignment(); 1767 else if (Kind == Attribute::ByVal) 1768 ByValType = Attr.getValueAsType(); 1769 else if (Kind == Attribute::StructRet) 1770 StructRetType = Attr.getValueAsType(); 1771 else if (Kind == Attribute::ByRef) 1772 ByRefType = Attr.getValueAsType(); 1773 else if (Kind == Attribute::Preallocated) 1774 PreallocatedType = Attr.getValueAsType(); 1775 else if (Kind == Attribute::Dereferenceable) 1776 DerefBytes = Attr.getDereferenceableBytes(); 1777 else if (Kind == Attribute::DereferenceableOrNull) 1778 DerefOrNullBytes = Attr.getDereferenceableOrNullBytes(); 1779 else if (Kind == Attribute::AllocSize) 1780 AllocSizeArgs = Attr.getValueAsInt(); 1781 else if (Kind == Attribute::VScaleRange) 1782 VScaleRangeArgs = Attr.getValueAsInt(); 1783 else if (Kind == Attribute::InAlloca) 1784 InAllocaType = Attr.getValueAsType(); 1785 1786 return *this; 1787 } 1788 1789 AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) { 1790 TargetDepAttrs[A] = V; 1791 return *this; 1792 } 1793 1794 AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { 1795 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!"); 1796 Attrs[Val] = false; 1797 1798 if (Val == Attribute::Alignment) 1799 Alignment.reset(); 1800 else if (Val == Attribute::StackAlignment) 1801 StackAlignment.reset(); 1802 else if (Val == Attribute::ByVal) 1803 ByValType = nullptr; 1804 else if (Val == Attribute::StructRet) 1805 StructRetType = nullptr; 1806 else if (Val == Attribute::ByRef) 1807 ByRefType = nullptr; 1808 else if (Val == Attribute::Preallocated) 1809 PreallocatedType = nullptr; 1810 else if (Val == Attribute::InAlloca) 1811 InAllocaType = nullptr; 1812 else if (Val == Attribute::Dereferenceable) 1813 DerefBytes = 0; 1814 else if (Val == Attribute::DereferenceableOrNull) 1815 DerefOrNullBytes = 0; 1816 else if (Val == Attribute::AllocSize) 1817 AllocSizeArgs = 0; 1818 else if (Val == Attribute::VScaleRange) 1819 VScaleRangeArgs = 0; 1820 1821 return *this; 1822 } 1823 1824 AttrBuilder &AttrBuilder::removeAttributes(AttributeList A, uint64_t Index) { 1825 remove(A.getAttributes(Index)); 1826 return *this; 1827 } 1828 1829 AttrBuilder &AttrBuilder::removeAttribute(StringRef A) { 1830 auto I = TargetDepAttrs.find(A); 1831 if (I != TargetDepAttrs.end()) 1832 TargetDepAttrs.erase(I); 1833 return *this; 1834 } 1835 1836 std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const { 1837 return unpackAllocSizeArgs(AllocSizeArgs); 1838 } 1839 1840 std::pair<unsigned, unsigned> AttrBuilder::getVScaleRangeArgs() const { 1841 return unpackVScaleRangeArgs(VScaleRangeArgs); 1842 } 1843 1844 AttrBuilder &AttrBuilder::addAlignmentAttr(MaybeAlign Align) { 1845 if (!Align) 1846 return *this; 1847 1848 assert(*Align <= llvm::Value::MaximumAlignment && "Alignment too large."); 1849 1850 Attrs[Attribute::Alignment] = true; 1851 Alignment = Align; 1852 return *this; 1853 } 1854 1855 AttrBuilder &AttrBuilder::addStackAlignmentAttr(MaybeAlign Align) { 1856 // Default alignment, allow the target to define how to align it. 1857 if (!Align) 1858 return *this; 1859 1860 assert(*Align <= 0x100 && "Alignment too large."); 1861 1862 Attrs[Attribute::StackAlignment] = true; 1863 StackAlignment = Align; 1864 return *this; 1865 } 1866 1867 AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) { 1868 if (Bytes == 0) return *this; 1869 1870 Attrs[Attribute::Dereferenceable] = true; 1871 DerefBytes = Bytes; 1872 return *this; 1873 } 1874 1875 AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) { 1876 if (Bytes == 0) 1877 return *this; 1878 1879 Attrs[Attribute::DereferenceableOrNull] = true; 1880 DerefOrNullBytes = Bytes; 1881 return *this; 1882 } 1883 1884 AttrBuilder &AttrBuilder::addAllocSizeAttr(unsigned ElemSize, 1885 const Optional<unsigned> &NumElems) { 1886 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems)); 1887 } 1888 1889 AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) { 1890 // (0, 0) is our "not present" value, so we need to check for it here. 1891 assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)"); 1892 1893 Attrs[Attribute::AllocSize] = true; 1894 // Reuse existing machinery to store this as a single 64-bit integer so we can 1895 // save a few bytes over using a pair<unsigned, Optional<unsigned>>. 1896 AllocSizeArgs = RawArgs; 1897 return *this; 1898 } 1899 1900 AttrBuilder &AttrBuilder::addVScaleRangeAttr(unsigned MinValue, 1901 unsigned MaxValue) { 1902 return addVScaleRangeAttrFromRawRepr(packVScaleRangeArgs(MinValue, MaxValue)); 1903 } 1904 1905 AttrBuilder &AttrBuilder::addVScaleRangeAttrFromRawRepr(uint64_t RawArgs) { 1906 // (0, 0) is not present hence ignore this case 1907 if (RawArgs == 0) 1908 return *this; 1909 1910 Attrs[Attribute::VScaleRange] = true; 1911 // Reuse existing machinery to store this as a single 64-bit integer so we can 1912 // save a few bytes over using a pair<unsigned, unsigned>. 1913 VScaleRangeArgs = RawArgs; 1914 return *this; 1915 } 1916 1917 AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) { 1918 Attrs[Attribute::ByVal] = true; 1919 ByValType = Ty; 1920 return *this; 1921 } 1922 1923 AttrBuilder &AttrBuilder::addStructRetAttr(Type *Ty) { 1924 Attrs[Attribute::StructRet] = true; 1925 StructRetType = Ty; 1926 return *this; 1927 } 1928 1929 AttrBuilder &AttrBuilder::addByRefAttr(Type *Ty) { 1930 Attrs[Attribute::ByRef] = true; 1931 ByRefType = Ty; 1932 return *this; 1933 } 1934 1935 AttrBuilder &AttrBuilder::addPreallocatedAttr(Type *Ty) { 1936 Attrs[Attribute::Preallocated] = true; 1937 PreallocatedType = Ty; 1938 return *this; 1939 } 1940 1941 AttrBuilder &AttrBuilder::addInAllocaAttr(Type *Ty) { 1942 Attrs[Attribute::InAlloca] = true; 1943 InAllocaType = Ty; 1944 return *this; 1945 } 1946 1947 AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { 1948 // FIXME: What if both have alignments, but they don't match?! 1949 if (!Alignment) 1950 Alignment = B.Alignment; 1951 1952 if (!StackAlignment) 1953 StackAlignment = B.StackAlignment; 1954 1955 if (!DerefBytes) 1956 DerefBytes = B.DerefBytes; 1957 1958 if (!DerefOrNullBytes) 1959 DerefOrNullBytes = B.DerefOrNullBytes; 1960 1961 if (!AllocSizeArgs) 1962 AllocSizeArgs = B.AllocSizeArgs; 1963 1964 if (!ByValType) 1965 ByValType = B.ByValType; 1966 1967 if (!StructRetType) 1968 StructRetType = B.StructRetType; 1969 1970 if (!ByRefType) 1971 ByRefType = B.ByRefType; 1972 1973 if (!PreallocatedType) 1974 PreallocatedType = B.PreallocatedType; 1975 1976 if (!InAllocaType) 1977 InAllocaType = B.InAllocaType; 1978 1979 if (!VScaleRangeArgs) 1980 VScaleRangeArgs = B.VScaleRangeArgs; 1981 1982 Attrs |= B.Attrs; 1983 1984 for (const auto &I : B.td_attrs()) 1985 TargetDepAttrs[I.first] = I.second; 1986 1987 return *this; 1988 } 1989 1990 AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) { 1991 // FIXME: What if both have alignments, but they don't match?! 1992 if (B.Alignment) 1993 Alignment.reset(); 1994 1995 if (B.StackAlignment) 1996 StackAlignment.reset(); 1997 1998 if (B.DerefBytes) 1999 DerefBytes = 0; 2000 2001 if (B.DerefOrNullBytes) 2002 DerefOrNullBytes = 0; 2003 2004 if (B.AllocSizeArgs) 2005 AllocSizeArgs = 0; 2006 2007 if (B.ByValType) 2008 ByValType = nullptr; 2009 2010 if (B.StructRetType) 2011 StructRetType = nullptr; 2012 2013 if (B.ByRefType) 2014 ByRefType = nullptr; 2015 2016 if (B.PreallocatedType) 2017 PreallocatedType = nullptr; 2018 2019 if (B.InAllocaType) 2020 InAllocaType = nullptr; 2021 2022 if (B.VScaleRangeArgs) 2023 VScaleRangeArgs = 0; 2024 2025 Attrs &= ~B.Attrs; 2026 2027 for (const auto &I : B.td_attrs()) 2028 TargetDepAttrs.erase(I.first); 2029 2030 return *this; 2031 } 2032 2033 bool AttrBuilder::overlaps(const AttrBuilder &B) const { 2034 // First check if any of the target independent attributes overlap. 2035 if ((Attrs & B.Attrs).any()) 2036 return true; 2037 2038 // Then check if any target dependent ones do. 2039 for (const auto &I : td_attrs()) 2040 if (B.contains(I.first)) 2041 return true; 2042 2043 return false; 2044 } 2045 2046 bool AttrBuilder::contains(StringRef A) const { 2047 return TargetDepAttrs.find(A) != TargetDepAttrs.end(); 2048 } 2049 2050 bool AttrBuilder::hasAttributes() const { 2051 return !Attrs.none() || !TargetDepAttrs.empty(); 2052 } 2053 2054 bool AttrBuilder::hasAttributes(AttributeList AL, uint64_t Index) const { 2055 AttributeSet AS = AL.getAttributes(Index); 2056 2057 for (const auto &Attr : AS) { 2058 if (Attr.isEnumAttribute() || Attr.isIntAttribute()) { 2059 if (contains(Attr.getKindAsEnum())) 2060 return true; 2061 } else { 2062 assert(Attr.isStringAttribute() && "Invalid attribute kind!"); 2063 return contains(Attr.getKindAsString()); 2064 } 2065 } 2066 2067 return false; 2068 } 2069 2070 bool AttrBuilder::hasAlignmentAttr() const { 2071 return Alignment != 0; 2072 } 2073 2074 bool AttrBuilder::operator==(const AttrBuilder &B) const { 2075 if (Attrs != B.Attrs) 2076 return false; 2077 2078 for (const auto &TDA : TargetDepAttrs) 2079 if (B.TargetDepAttrs.find(TDA.first) == B.TargetDepAttrs.end()) 2080 return false; 2081 2082 return Alignment == B.Alignment && StackAlignment == B.StackAlignment && 2083 DerefBytes == B.DerefBytes && ByValType == B.ByValType && 2084 StructRetType == B.StructRetType && ByRefType == B.ByRefType && 2085 PreallocatedType == B.PreallocatedType && 2086 InAllocaType == B.InAllocaType && 2087 VScaleRangeArgs == B.VScaleRangeArgs; 2088 } 2089 2090 //===----------------------------------------------------------------------===// 2091 // AttributeFuncs Function Defintions 2092 //===----------------------------------------------------------------------===// 2093 2094 /// Which attributes cannot be applied to a type. 2095 AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) { 2096 AttrBuilder Incompatible; 2097 2098 if (!Ty->isIntegerTy()) 2099 // Attribute that only apply to integers. 2100 Incompatible.addAttribute(Attribute::SExt) 2101 .addAttribute(Attribute::ZExt); 2102 2103 if (!Ty->isPointerTy()) 2104 // Attribute that only apply to pointers. 2105 Incompatible.addAttribute(Attribute::Nest) 2106 .addAttribute(Attribute::NoAlias) 2107 .addAttribute(Attribute::NoCapture) 2108 .addAttribute(Attribute::NonNull) 2109 .addAlignmentAttr(1) // the int here is ignored 2110 .addDereferenceableAttr(1) // the int here is ignored 2111 .addDereferenceableOrNullAttr(1) // the int here is ignored 2112 .addAttribute(Attribute::ReadNone) 2113 .addAttribute(Attribute::ReadOnly) 2114 .addAttribute(Attribute::InAlloca) 2115 .addPreallocatedAttr(Ty) 2116 .addInAllocaAttr(Ty) 2117 .addByValAttr(Ty) 2118 .addStructRetAttr(Ty) 2119 .addByRefAttr(Ty); 2120 2121 // Some attributes can apply to all "values" but there are no `void` values. 2122 if (Ty->isVoidTy()) 2123 Incompatible.addAttribute(Attribute::NoUndef); 2124 2125 return Incompatible; 2126 } 2127 2128 template<typename AttrClass> 2129 static bool isEqual(const Function &Caller, const Function &Callee) { 2130 return Caller.getFnAttribute(AttrClass::getKind()) == 2131 Callee.getFnAttribute(AttrClass::getKind()); 2132 } 2133 2134 /// Compute the logical AND of the attributes of the caller and the 2135 /// callee. 2136 /// 2137 /// This function sets the caller's attribute to false if the callee's attribute 2138 /// is false. 2139 template<typename AttrClass> 2140 static void setAND(Function &Caller, const Function &Callee) { 2141 if (AttrClass::isSet(Caller, AttrClass::getKind()) && 2142 !AttrClass::isSet(Callee, AttrClass::getKind())) 2143 AttrClass::set(Caller, AttrClass::getKind(), false); 2144 } 2145 2146 /// Compute the logical OR of the attributes of the caller and the 2147 /// callee. 2148 /// 2149 /// This function sets the caller's attribute to true if the callee's attribute 2150 /// is true. 2151 template<typename AttrClass> 2152 static void setOR(Function &Caller, const Function &Callee) { 2153 if (!AttrClass::isSet(Caller, AttrClass::getKind()) && 2154 AttrClass::isSet(Callee, AttrClass::getKind())) 2155 AttrClass::set(Caller, AttrClass::getKind(), true); 2156 } 2157 2158 /// If the inlined function had a higher stack protection level than the 2159 /// calling function, then bump up the caller's stack protection level. 2160 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) { 2161 #ifndef NDEBUG 2162 if (!Callee.hasFnAttribute(Attribute::AlwaysInline)) { 2163 assert(!(!Callee.hasStackProtectorFnAttr() && 2164 Caller.hasStackProtectorFnAttr()) && 2165 "stack protected caller but callee requested no stack protector"); 2166 assert(!(!Caller.hasStackProtectorFnAttr() && 2167 Callee.hasStackProtectorFnAttr()) && 2168 "stack protected callee but caller requested no stack protector"); 2169 } 2170 #endif 2171 // If upgrading the SSP attribute, clear out the old SSP Attributes first. 2172 // Having multiple SSP attributes doesn't actually hurt, but it adds useless 2173 // clutter to the IR. 2174 AttrBuilder OldSSPAttr; 2175 OldSSPAttr.addAttribute(Attribute::StackProtect) 2176 .addAttribute(Attribute::StackProtectStrong) 2177 .addAttribute(Attribute::StackProtectReq); 2178 2179 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) { 2180 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr); 2181 Caller.addFnAttr(Attribute::StackProtectReq); 2182 } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) && 2183 !Caller.hasFnAttribute(Attribute::StackProtectReq)) { 2184 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr); 2185 Caller.addFnAttr(Attribute::StackProtectStrong); 2186 } else if (Callee.hasFnAttribute(Attribute::StackProtect) && 2187 !Caller.hasFnAttribute(Attribute::StackProtectReq) && 2188 !Caller.hasFnAttribute(Attribute::StackProtectStrong)) 2189 Caller.addFnAttr(Attribute::StackProtect); 2190 } 2191 2192 /// If the inlined function required stack probes, then ensure that 2193 /// the calling function has those too. 2194 static void adjustCallerStackProbes(Function &Caller, const Function &Callee) { 2195 if (!Caller.hasFnAttribute("probe-stack") && 2196 Callee.hasFnAttribute("probe-stack")) { 2197 Caller.addFnAttr(Callee.getFnAttribute("probe-stack")); 2198 } 2199 } 2200 2201 /// If the inlined function defines the size of guard region 2202 /// on the stack, then ensure that the calling function defines a guard region 2203 /// that is no larger. 2204 static void 2205 adjustCallerStackProbeSize(Function &Caller, const Function &Callee) { 2206 Attribute CalleeAttr = Callee.getFnAttribute("stack-probe-size"); 2207 if (CalleeAttr.isValid()) { 2208 Attribute CallerAttr = Caller.getFnAttribute("stack-probe-size"); 2209 if (CallerAttr.isValid()) { 2210 uint64_t CallerStackProbeSize, CalleeStackProbeSize; 2211 CallerAttr.getValueAsString().getAsInteger(0, CallerStackProbeSize); 2212 CalleeAttr.getValueAsString().getAsInteger(0, CalleeStackProbeSize); 2213 2214 if (CallerStackProbeSize > CalleeStackProbeSize) { 2215 Caller.addFnAttr(CalleeAttr); 2216 } 2217 } else { 2218 Caller.addFnAttr(CalleeAttr); 2219 } 2220 } 2221 } 2222 2223 /// If the inlined function defines a min legal vector width, then ensure 2224 /// the calling function has the same or larger min legal vector width. If the 2225 /// caller has the attribute, but the callee doesn't, we need to remove the 2226 /// attribute from the caller since we can't make any guarantees about the 2227 /// caller's requirements. 2228 /// This function is called after the inlining decision has been made so we have 2229 /// to merge the attribute this way. Heuristics that would use 2230 /// min-legal-vector-width to determine inline compatibility would need to be 2231 /// handled as part of inline cost analysis. 2232 static void 2233 adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) { 2234 Attribute CallerAttr = Caller.getFnAttribute("min-legal-vector-width"); 2235 if (CallerAttr.isValid()) { 2236 Attribute CalleeAttr = Callee.getFnAttribute("min-legal-vector-width"); 2237 if (CalleeAttr.isValid()) { 2238 uint64_t CallerVectorWidth, CalleeVectorWidth; 2239 CallerAttr.getValueAsString().getAsInteger(0, CallerVectorWidth); 2240 CalleeAttr.getValueAsString().getAsInteger(0, CalleeVectorWidth); 2241 if (CallerVectorWidth < CalleeVectorWidth) 2242 Caller.addFnAttr(CalleeAttr); 2243 } else { 2244 // If the callee doesn't have the attribute then we don't know anything 2245 // and must drop the attribute from the caller. 2246 Caller.removeFnAttr("min-legal-vector-width"); 2247 } 2248 } 2249 } 2250 2251 /// If the inlined function has null_pointer_is_valid attribute, 2252 /// set this attribute in the caller post inlining. 2253 static void 2254 adjustNullPointerValidAttr(Function &Caller, const Function &Callee) { 2255 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) { 2256 Caller.addFnAttr(Attribute::NullPointerIsValid); 2257 } 2258 } 2259 2260 struct EnumAttr { 2261 static bool isSet(const Function &Fn, 2262 Attribute::AttrKind Kind) { 2263 return Fn.hasFnAttribute(Kind); 2264 } 2265 2266 static void set(Function &Fn, 2267 Attribute::AttrKind Kind, bool Val) { 2268 if (Val) 2269 Fn.addFnAttr(Kind); 2270 else 2271 Fn.removeFnAttr(Kind); 2272 } 2273 }; 2274 2275 struct StrBoolAttr { 2276 static bool isSet(const Function &Fn, 2277 StringRef Kind) { 2278 auto A = Fn.getFnAttribute(Kind); 2279 return A.getValueAsString().equals("true"); 2280 } 2281 2282 static void set(Function &Fn, 2283 StringRef Kind, bool Val) { 2284 Fn.addFnAttr(Kind, Val ? "true" : "false"); 2285 } 2286 }; 2287 2288 #define GET_ATTR_NAMES 2289 #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \ 2290 struct ENUM_NAME##Attr : EnumAttr { \ 2291 static enum Attribute::AttrKind getKind() { \ 2292 return llvm::Attribute::ENUM_NAME; \ 2293 } \ 2294 }; 2295 #define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME) \ 2296 struct ENUM_NAME##Attr : StrBoolAttr { \ 2297 static StringRef getKind() { return #DISPLAY_NAME; } \ 2298 }; 2299 #include "llvm/IR/Attributes.inc" 2300 2301 #define GET_ATTR_COMPAT_FUNC 2302 #include "llvm/IR/Attributes.inc" 2303 2304 bool AttributeFuncs::areInlineCompatible(const Function &Caller, 2305 const Function &Callee) { 2306 return hasCompatibleFnAttrs(Caller, Callee); 2307 } 2308 2309 bool AttributeFuncs::areOutlineCompatible(const Function &A, 2310 const Function &B) { 2311 return hasCompatibleFnAttrs(A, B); 2312 } 2313 2314 void AttributeFuncs::mergeAttributesForInlining(Function &Caller, 2315 const Function &Callee) { 2316 mergeFnAttrs(Caller, Callee); 2317 } 2318 2319 void AttributeFuncs::mergeAttributesForOutlining(Function &Base, 2320 const Function &ToMerge) { 2321 2322 // We merge functions so that they meet the most general case. 2323 // For example, if the NoNansFPMathAttr is set in one function, but not in 2324 // the other, in the merged function we can say that the NoNansFPMathAttr 2325 // is not set. 2326 // However if we have the SpeculativeLoadHardeningAttr set true in one 2327 // function, but not the other, we make sure that the function retains 2328 // that aspect in the merged function. 2329 mergeFnAttrs(Base, ToMerge); 2330 } 2331