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