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