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