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