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