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