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, llvm::less_first()) && 1058 "Misordered Attributes list!"); 1059 assert(llvm::all_of(Attrs, 1060 [](const std::pair<unsigned, Attribute> &Pair) { 1061 return Pair.second.isValid(); 1062 }) && 1063 "Pointless attribute!"); 1064 1065 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes 1066 // list. 1067 SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec; 1068 for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(), 1069 E = Attrs.end(); I != E; ) { 1070 unsigned Index = I->first; 1071 SmallVector<Attribute, 4> AttrVec; 1072 while (I != E && I->first == Index) { 1073 AttrVec.push_back(I->second); 1074 ++I; 1075 } 1076 1077 AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec)); 1078 } 1079 1080 return get(C, AttrPairVec); 1081 } 1082 1083 AttributeList 1084 AttributeList::get(LLVMContext &C, 1085 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) { 1086 // If there are no attributes then return a null AttributesList pointer. 1087 if (Attrs.empty()) 1088 return {}; 1089 1090 assert(llvm::is_sorted(Attrs, llvm::less_first()) && 1091 "Misordered Attributes list!"); 1092 assert(llvm::none_of(Attrs, 1093 [](const std::pair<unsigned, AttributeSet> &Pair) { 1094 return !Pair.second.hasAttributes(); 1095 }) && 1096 "Pointless attribute!"); 1097 1098 unsigned MaxIndex = Attrs.back().first; 1099 // If the MaxIndex is FunctionIndex and there are other indices in front 1100 // of it, we need to use the largest of those to get the right size. 1101 if (MaxIndex == FunctionIndex && Attrs.size() > 1) 1102 MaxIndex = Attrs[Attrs.size() - 2].first; 1103 1104 SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1); 1105 for (const auto &Pair : Attrs) 1106 AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second; 1107 1108 return getImpl(C, AttrVec); 1109 } 1110 1111 AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs, 1112 AttributeSet RetAttrs, 1113 ArrayRef<AttributeSet> ArgAttrs) { 1114 // Scan from the end to find the last argument with attributes. Most 1115 // arguments don't have attributes, so it's nice if we can have fewer unique 1116 // AttributeListImpls by dropping empty attribute sets at the end of the list. 1117 unsigned NumSets = 0; 1118 for (size_t I = ArgAttrs.size(); I != 0; --I) { 1119 if (ArgAttrs[I - 1].hasAttributes()) { 1120 NumSets = I + 2; 1121 break; 1122 } 1123 } 1124 if (NumSets == 0) { 1125 // Check function and return attributes if we didn't have argument 1126 // attributes. 1127 if (RetAttrs.hasAttributes()) 1128 NumSets = 2; 1129 else if (FnAttrs.hasAttributes()) 1130 NumSets = 1; 1131 } 1132 1133 // If all attribute sets were empty, we can use the empty attribute list. 1134 if (NumSets == 0) 1135 return {}; 1136 1137 SmallVector<AttributeSet, 8> AttrSets; 1138 AttrSets.reserve(NumSets); 1139 // If we have any attributes, we always have function attributes. 1140 AttrSets.push_back(FnAttrs); 1141 if (NumSets > 1) 1142 AttrSets.push_back(RetAttrs); 1143 if (NumSets > 2) { 1144 // Drop the empty argument attribute sets at the end. 1145 ArgAttrs = ArgAttrs.take_front(NumSets - 2); 1146 llvm::append_range(AttrSets, ArgAttrs); 1147 } 1148 1149 return getImpl(C, AttrSets); 1150 } 1151 1152 AttributeList AttributeList::get(LLVMContext &C, unsigned Index, 1153 AttributeSet Attrs) { 1154 if (!Attrs.hasAttributes()) 1155 return {}; 1156 Index = attrIdxToArrayIdx(Index); 1157 SmallVector<AttributeSet, 8> AttrSets(Index + 1); 1158 AttrSets[Index] = Attrs; 1159 return getImpl(C, AttrSets); 1160 } 1161 1162 AttributeList AttributeList::get(LLVMContext &C, unsigned Index, 1163 const AttrBuilder &B) { 1164 return get(C, Index, AttributeSet::get(C, B)); 1165 } 1166 1167 AttributeList AttributeList::get(LLVMContext &C, unsigned Index, 1168 ArrayRef<Attribute::AttrKind> Kinds) { 1169 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; 1170 for (const auto K : Kinds) 1171 Attrs.emplace_back(Index, Attribute::get(C, K)); 1172 return get(C, Attrs); 1173 } 1174 1175 AttributeList AttributeList::get(LLVMContext &C, unsigned Index, 1176 ArrayRef<Attribute::AttrKind> Kinds, 1177 ArrayRef<uint64_t> Values) { 1178 assert(Kinds.size() == Values.size() && "Mismatched attribute values."); 1179 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; 1180 auto VI = Values.begin(); 1181 for (const auto K : Kinds) 1182 Attrs.emplace_back(Index, Attribute::get(C, K, *VI++)); 1183 return get(C, Attrs); 1184 } 1185 1186 AttributeList AttributeList::get(LLVMContext &C, unsigned Index, 1187 ArrayRef<StringRef> Kinds) { 1188 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; 1189 for (const auto &K : Kinds) 1190 Attrs.emplace_back(Index, Attribute::get(C, K)); 1191 return get(C, Attrs); 1192 } 1193 1194 AttributeList AttributeList::get(LLVMContext &C, 1195 ArrayRef<AttributeList> Attrs) { 1196 if (Attrs.empty()) 1197 return {}; 1198 if (Attrs.size() == 1) 1199 return Attrs[0]; 1200 1201 unsigned MaxSize = 0; 1202 for (const auto &List : Attrs) 1203 MaxSize = std::max(MaxSize, List.getNumAttrSets()); 1204 1205 // If every list was empty, there is no point in merging the lists. 1206 if (MaxSize == 0) 1207 return {}; 1208 1209 SmallVector<AttributeSet, 8> NewAttrSets(MaxSize); 1210 for (unsigned I = 0; I < MaxSize; ++I) { 1211 AttrBuilder CurBuilder(C); 1212 for (const auto &List : Attrs) 1213 CurBuilder.merge(AttrBuilder(C, List.getAttributes(I - 1))); 1214 NewAttrSets[I] = AttributeSet::get(C, CurBuilder); 1215 } 1216 1217 return getImpl(C, NewAttrSets); 1218 } 1219 1220 AttributeList 1221 AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index, 1222 Attribute::AttrKind Kind) const { 1223 if (hasAttributeAtIndex(Index, Kind)) 1224 return *this; 1225 AttributeSet Attrs = getAttributes(Index); 1226 // TODO: Insert at correct position and avoid sort. 1227 SmallVector<Attribute, 8> NewAttrs(Attrs.begin(), Attrs.end()); 1228 NewAttrs.push_back(Attribute::get(C, Kind)); 1229 return setAttributesAtIndex(C, Index, AttributeSet::get(C, NewAttrs)); 1230 } 1231 1232 AttributeList AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index, 1233 StringRef Kind, 1234 StringRef Value) const { 1235 AttrBuilder B(C); 1236 B.addAttribute(Kind, Value); 1237 return addAttributesAtIndex(C, Index, B); 1238 } 1239 1240 AttributeList AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index, 1241 Attribute A) const { 1242 AttrBuilder B(C); 1243 B.addAttribute(A); 1244 return addAttributesAtIndex(C, Index, B); 1245 } 1246 1247 AttributeList AttributeList::setAttributesAtIndex(LLVMContext &C, 1248 unsigned Index, 1249 AttributeSet Attrs) const { 1250 Index = attrIdxToArrayIdx(Index); 1251 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1252 if (Index >= AttrSets.size()) 1253 AttrSets.resize(Index + 1); 1254 AttrSets[Index] = Attrs; 1255 return AttributeList::getImpl(C, AttrSets); 1256 } 1257 1258 AttributeList AttributeList::addAttributesAtIndex(LLVMContext &C, 1259 unsigned Index, 1260 const AttrBuilder &B) const { 1261 if (!B.hasAttributes()) 1262 return *this; 1263 1264 if (!pImpl) 1265 return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}}); 1266 1267 AttrBuilder Merged(C, getAttributes(Index)); 1268 Merged.merge(B); 1269 return setAttributesAtIndex(C, Index, AttributeSet::get(C, Merged)); 1270 } 1271 1272 AttributeList AttributeList::addParamAttribute(LLVMContext &C, 1273 ArrayRef<unsigned> ArgNos, 1274 Attribute A) const { 1275 assert(llvm::is_sorted(ArgNos)); 1276 1277 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1278 unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex); 1279 if (MaxIndex >= AttrSets.size()) 1280 AttrSets.resize(MaxIndex + 1); 1281 1282 for (unsigned ArgNo : ArgNos) { 1283 unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex); 1284 AttrBuilder B(C, AttrSets[Index]); 1285 B.addAttribute(A); 1286 AttrSets[Index] = AttributeSet::get(C, B); 1287 } 1288 1289 return getImpl(C, AttrSets); 1290 } 1291 1292 AttributeList 1293 AttributeList::removeAttributeAtIndex(LLVMContext &C, unsigned Index, 1294 Attribute::AttrKind Kind) const { 1295 if (!hasAttributeAtIndex(Index, Kind)) 1296 return *this; 1297 1298 Index = attrIdxToArrayIdx(Index); 1299 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1300 assert(Index < AttrSets.size()); 1301 1302 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind); 1303 1304 return getImpl(C, AttrSets); 1305 } 1306 1307 AttributeList AttributeList::removeAttributeAtIndex(LLVMContext &C, 1308 unsigned Index, 1309 StringRef Kind) const { 1310 if (!hasAttributeAtIndex(Index, Kind)) 1311 return *this; 1312 1313 Index = attrIdxToArrayIdx(Index); 1314 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1315 assert(Index < AttrSets.size()); 1316 1317 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind); 1318 1319 return getImpl(C, AttrSets); 1320 } 1321 1322 AttributeList AttributeList::removeAttributesAtIndex( 1323 LLVMContext &C, unsigned Index, const AttributeMask &AttrsToRemove) const { 1324 AttributeSet Attrs = getAttributes(Index); 1325 AttributeSet NewAttrs = Attrs.removeAttributes(C, AttrsToRemove); 1326 // If nothing was removed, return the original list. 1327 if (Attrs == NewAttrs) 1328 return *this; 1329 return setAttributesAtIndex(C, Index, NewAttrs); 1330 } 1331 1332 AttributeList 1333 AttributeList::removeAttributesAtIndex(LLVMContext &C, 1334 unsigned WithoutIndex) const { 1335 if (!pImpl) 1336 return {}; 1337 WithoutIndex = attrIdxToArrayIdx(WithoutIndex); 1338 if (WithoutIndex >= getNumAttrSets()) 1339 return *this; 1340 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1341 AttrSets[WithoutIndex] = AttributeSet(); 1342 return getImpl(C, AttrSets); 1343 } 1344 1345 AttributeList AttributeList::addDereferenceableRetAttr(LLVMContext &C, 1346 uint64_t Bytes) const { 1347 AttrBuilder B(C); 1348 B.addDereferenceableAttr(Bytes); 1349 return addRetAttributes(C, B); 1350 } 1351 1352 AttributeList AttributeList::addDereferenceableParamAttr(LLVMContext &C, 1353 unsigned Index, 1354 uint64_t Bytes) const { 1355 AttrBuilder B(C); 1356 B.addDereferenceableAttr(Bytes); 1357 return addParamAttributes(C, Index, B); 1358 } 1359 1360 AttributeList 1361 AttributeList::addDereferenceableOrNullParamAttr(LLVMContext &C, unsigned Index, 1362 uint64_t Bytes) const { 1363 AttrBuilder B(C); 1364 B.addDereferenceableOrNullAttr(Bytes); 1365 return addParamAttributes(C, Index, B); 1366 } 1367 1368 AttributeList 1369 AttributeList::addAllocSizeParamAttr(LLVMContext &C, unsigned Index, 1370 unsigned ElemSizeArg, 1371 const Optional<unsigned> &NumElemsArg) { 1372 AttrBuilder B(C); 1373 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg); 1374 return addParamAttributes(C, Index, B); 1375 } 1376 1377 //===----------------------------------------------------------------------===// 1378 // AttributeList Accessor Methods 1379 //===----------------------------------------------------------------------===// 1380 1381 AttributeSet AttributeList::getParamAttrs(unsigned ArgNo) const { 1382 return getAttributes(ArgNo + FirstArgIndex); 1383 } 1384 1385 AttributeSet AttributeList::getRetAttrs() const { 1386 return getAttributes(ReturnIndex); 1387 } 1388 1389 AttributeSet AttributeList::getFnAttrs() const { 1390 return getAttributes(FunctionIndex); 1391 } 1392 1393 bool AttributeList::hasAttributeAtIndex(unsigned Index, 1394 Attribute::AttrKind Kind) const { 1395 return getAttributes(Index).hasAttribute(Kind); 1396 } 1397 1398 bool AttributeList::hasAttributeAtIndex(unsigned Index, StringRef Kind) const { 1399 return getAttributes(Index).hasAttribute(Kind); 1400 } 1401 1402 bool AttributeList::hasAttributesAtIndex(unsigned Index) const { 1403 return getAttributes(Index).hasAttributes(); 1404 } 1405 1406 bool AttributeList::hasFnAttr(Attribute::AttrKind Kind) const { 1407 return pImpl && pImpl->hasFnAttribute(Kind); 1408 } 1409 1410 bool AttributeList::hasFnAttr(StringRef Kind) const { 1411 return hasAttributeAtIndex(AttributeList::FunctionIndex, Kind); 1412 } 1413 1414 bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr, 1415 unsigned *Index) const { 1416 return pImpl && pImpl->hasAttrSomewhere(Attr, Index); 1417 } 1418 1419 Attribute AttributeList::getAttributeAtIndex(unsigned Index, 1420 Attribute::AttrKind Kind) const { 1421 return getAttributes(Index).getAttribute(Kind); 1422 } 1423 1424 Attribute AttributeList::getAttributeAtIndex(unsigned Index, 1425 StringRef Kind) const { 1426 return getAttributes(Index).getAttribute(Kind); 1427 } 1428 1429 MaybeAlign AttributeList::getRetAlignment() const { 1430 return getAttributes(ReturnIndex).getAlignment(); 1431 } 1432 1433 MaybeAlign AttributeList::getParamAlignment(unsigned ArgNo) const { 1434 return getAttributes(ArgNo + FirstArgIndex).getAlignment(); 1435 } 1436 1437 MaybeAlign AttributeList::getParamStackAlignment(unsigned ArgNo) const { 1438 return getAttributes(ArgNo + FirstArgIndex).getStackAlignment(); 1439 } 1440 1441 Type *AttributeList::getParamByValType(unsigned Index) const { 1442 return getAttributes(Index+FirstArgIndex).getByValType(); 1443 } 1444 1445 Type *AttributeList::getParamStructRetType(unsigned Index) const { 1446 return getAttributes(Index + FirstArgIndex).getStructRetType(); 1447 } 1448 1449 Type *AttributeList::getParamByRefType(unsigned Index) const { 1450 return getAttributes(Index + FirstArgIndex).getByRefType(); 1451 } 1452 1453 Type *AttributeList::getParamPreallocatedType(unsigned Index) const { 1454 return getAttributes(Index + FirstArgIndex).getPreallocatedType(); 1455 } 1456 1457 Type *AttributeList::getParamInAllocaType(unsigned Index) const { 1458 return getAttributes(Index + FirstArgIndex).getInAllocaType(); 1459 } 1460 1461 Type *AttributeList::getParamElementType(unsigned Index) const { 1462 return getAttributes(Index + FirstArgIndex).getElementType(); 1463 } 1464 1465 MaybeAlign AttributeList::getFnStackAlignment() const { 1466 return getFnAttrs().getStackAlignment(); 1467 } 1468 1469 MaybeAlign AttributeList::getRetStackAlignment() const { 1470 return getRetAttrs().getStackAlignment(); 1471 } 1472 1473 uint64_t AttributeList::getRetDereferenceableBytes() const { 1474 return getRetAttrs().getDereferenceableBytes(); 1475 } 1476 1477 uint64_t AttributeList::getParamDereferenceableBytes(unsigned Index) const { 1478 return getParamAttrs(Index).getDereferenceableBytes(); 1479 } 1480 1481 uint64_t AttributeList::getRetDereferenceableOrNullBytes() const { 1482 return getRetAttrs().getDereferenceableOrNullBytes(); 1483 } 1484 1485 uint64_t 1486 AttributeList::getParamDereferenceableOrNullBytes(unsigned Index) const { 1487 return getParamAttrs(Index).getDereferenceableOrNullBytes(); 1488 } 1489 1490 UWTableKind AttributeList::getUWTableKind() const { 1491 return getFnAttrs().getUWTableKind(); 1492 } 1493 1494 AllocFnKind AttributeList::getAllocKind() const { 1495 return getFnAttrs().getAllocKind(); 1496 } 1497 1498 std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const { 1499 return getAttributes(Index).getAsString(InAttrGrp); 1500 } 1501 1502 AttributeSet AttributeList::getAttributes(unsigned Index) const { 1503 Index = attrIdxToArrayIdx(Index); 1504 if (!pImpl || Index >= getNumAttrSets()) 1505 return {}; 1506 return pImpl->begin()[Index]; 1507 } 1508 1509 bool AttributeList::hasParentContext(LLVMContext &C) const { 1510 assert(!isEmpty() && "an empty attribute list has no parent context"); 1511 FoldingSetNodeID ID; 1512 pImpl->Profile(ID); 1513 void *Unused; 1514 return C.pImpl->AttrsLists.FindNodeOrInsertPos(ID, Unused) == pImpl; 1515 } 1516 1517 AttributeList::iterator AttributeList::begin() const { 1518 return pImpl ? pImpl->begin() : nullptr; 1519 } 1520 1521 AttributeList::iterator AttributeList::end() const { 1522 return pImpl ? pImpl->end() : nullptr; 1523 } 1524 1525 //===----------------------------------------------------------------------===// 1526 // AttributeList Introspection Methods 1527 //===----------------------------------------------------------------------===// 1528 1529 unsigned AttributeList::getNumAttrSets() const { 1530 return pImpl ? pImpl->NumAttrSets : 0; 1531 } 1532 1533 void AttributeList::print(raw_ostream &O) const { 1534 O << "AttributeList[\n"; 1535 1536 for (unsigned i : indexes()) { 1537 if (!getAttributes(i).hasAttributes()) 1538 continue; 1539 O << " { "; 1540 switch (i) { 1541 case AttrIndex::ReturnIndex: 1542 O << "return"; 1543 break; 1544 case AttrIndex::FunctionIndex: 1545 O << "function"; 1546 break; 1547 default: 1548 O << "arg(" << i - AttrIndex::FirstArgIndex << ")"; 1549 } 1550 O << " => " << getAsString(i) << " }\n"; 1551 } 1552 1553 O << "]\n"; 1554 } 1555 1556 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1557 LLVM_DUMP_METHOD void AttributeList::dump() const { print(dbgs()); } 1558 #endif 1559 1560 //===----------------------------------------------------------------------===// 1561 // AttrBuilder Method Implementations 1562 //===----------------------------------------------------------------------===// 1563 1564 AttrBuilder::AttrBuilder(LLVMContext &Ctx, AttributeSet AS) : Ctx(Ctx) { 1565 append_range(Attrs, AS); 1566 assert(is_sorted(Attrs) && "AttributeSet should be sorted"); 1567 } 1568 1569 void AttrBuilder::clear() { Attrs.clear(); } 1570 1571 /// Attribute comparator that only compares attribute keys. Enum attributes are 1572 /// sorted before string attributes. 1573 struct AttributeComparator { 1574 bool operator()(Attribute A0, Attribute A1) const { 1575 bool A0IsString = A0.isStringAttribute(); 1576 bool A1IsString = A1.isStringAttribute(); 1577 if (A0IsString) { 1578 if (A1IsString) 1579 return A0.getKindAsString() < A1.getKindAsString(); 1580 else 1581 return false; 1582 } 1583 if (A1IsString) 1584 return true; 1585 return A0.getKindAsEnum() < A1.getKindAsEnum(); 1586 } 1587 bool operator()(Attribute A0, Attribute::AttrKind Kind) const { 1588 if (A0.isStringAttribute()) 1589 return false; 1590 return A0.getKindAsEnum() < Kind; 1591 } 1592 bool operator()(Attribute A0, StringRef Kind) const { 1593 if (A0.isStringAttribute()) 1594 return A0.getKindAsString() < Kind; 1595 return true; 1596 } 1597 }; 1598 1599 template <typename K> 1600 static void addAttributeImpl(SmallVectorImpl<Attribute> &Attrs, K Kind, 1601 Attribute Attr) { 1602 auto It = lower_bound(Attrs, Kind, AttributeComparator()); 1603 if (It != Attrs.end() && It->hasAttribute(Kind)) 1604 std::swap(*It, Attr); 1605 else 1606 Attrs.insert(It, Attr); 1607 } 1608 1609 AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) { 1610 if (Attr.isStringAttribute()) 1611 addAttributeImpl(Attrs, Attr.getKindAsString(), Attr); 1612 else 1613 addAttributeImpl(Attrs, Attr.getKindAsEnum(), Attr); 1614 return *this; 1615 } 1616 1617 AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Kind) { 1618 addAttributeImpl(Attrs, Kind, Attribute::get(Ctx, Kind)); 1619 return *this; 1620 } 1621 1622 AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) { 1623 addAttributeImpl(Attrs, A, Attribute::get(Ctx, A, V)); 1624 return *this; 1625 } 1626 1627 AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { 1628 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!"); 1629 auto It = lower_bound(Attrs, Val, AttributeComparator()); 1630 if (It != Attrs.end() && It->hasAttribute(Val)) 1631 Attrs.erase(It); 1632 return *this; 1633 } 1634 1635 AttrBuilder &AttrBuilder::removeAttribute(StringRef A) { 1636 auto It = lower_bound(Attrs, A, AttributeComparator()); 1637 if (It != Attrs.end() && It->hasAttribute(A)) 1638 Attrs.erase(It); 1639 return *this; 1640 } 1641 1642 uint64_t AttrBuilder::getRawIntAttr(Attribute::AttrKind Kind) const { 1643 assert(Attribute::isIntAttrKind(Kind) && "Not an int attribute"); 1644 Attribute A = getAttribute(Kind); 1645 return A.isValid() ? A.getValueAsInt() : 0; 1646 } 1647 1648 AttrBuilder &AttrBuilder::addRawIntAttr(Attribute::AttrKind Kind, 1649 uint64_t Value) { 1650 return addAttribute(Attribute::get(Ctx, Kind, Value)); 1651 } 1652 1653 std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const { 1654 return unpackAllocSizeArgs(getRawIntAttr(Attribute::AllocSize)); 1655 } 1656 1657 unsigned AttrBuilder::getVScaleRangeMin() const { 1658 return unpackVScaleRangeArgs(getRawIntAttr(Attribute::VScaleRange)).first; 1659 } 1660 1661 Optional<unsigned> AttrBuilder::getVScaleRangeMax() const { 1662 return unpackVScaleRangeArgs(getRawIntAttr(Attribute::VScaleRange)).second; 1663 } 1664 1665 AttrBuilder &AttrBuilder::addAlignmentAttr(MaybeAlign Align) { 1666 if (!Align) 1667 return *this; 1668 1669 assert(*Align <= llvm::Value::MaximumAlignment && "Alignment too large."); 1670 return addRawIntAttr(Attribute::Alignment, Align->value()); 1671 } 1672 1673 AttrBuilder &AttrBuilder::addStackAlignmentAttr(MaybeAlign Align) { 1674 // Default alignment, allow the target to define how to align it. 1675 if (!Align) 1676 return *this; 1677 1678 assert(*Align <= 0x100 && "Alignment too large."); 1679 return addRawIntAttr(Attribute::StackAlignment, Align->value()); 1680 } 1681 1682 AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) { 1683 if (Bytes == 0) return *this; 1684 1685 return addRawIntAttr(Attribute::Dereferenceable, Bytes); 1686 } 1687 1688 AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) { 1689 if (Bytes == 0) 1690 return *this; 1691 1692 return addRawIntAttr(Attribute::DereferenceableOrNull, Bytes); 1693 } 1694 1695 AttrBuilder &AttrBuilder::addAllocSizeAttr(unsigned ElemSize, 1696 const Optional<unsigned> &NumElems) { 1697 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems)); 1698 } 1699 1700 AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) { 1701 // (0, 0) is our "not present" value, so we need to check for it here. 1702 assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)"); 1703 return addRawIntAttr(Attribute::AllocSize, RawArgs); 1704 } 1705 1706 AttrBuilder &AttrBuilder::addVScaleRangeAttr(unsigned MinValue, 1707 Optional<unsigned> MaxValue) { 1708 return addVScaleRangeAttrFromRawRepr(packVScaleRangeArgs(MinValue, MaxValue)); 1709 } 1710 1711 AttrBuilder &AttrBuilder::addVScaleRangeAttrFromRawRepr(uint64_t RawArgs) { 1712 // (0, 0) is not present hence ignore this case 1713 if (RawArgs == 0) 1714 return *this; 1715 1716 return addRawIntAttr(Attribute::VScaleRange, RawArgs); 1717 } 1718 1719 AttrBuilder &AttrBuilder::addUWTableAttr(UWTableKind Kind) { 1720 if (Kind == UWTableKind::None) 1721 return *this; 1722 return addRawIntAttr(Attribute::UWTable, uint64_t(Kind)); 1723 } 1724 1725 AttrBuilder &AttrBuilder::addAllocKindAttr(AllocFnKind Kind) { 1726 return addRawIntAttr(Attribute::AllocKind, static_cast<uint64_t>(Kind)); 1727 } 1728 1729 Type *AttrBuilder::getTypeAttr(Attribute::AttrKind Kind) const { 1730 assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute"); 1731 Attribute A = getAttribute(Kind); 1732 return A.isValid() ? A.getValueAsType() : nullptr; 1733 } 1734 1735 AttrBuilder &AttrBuilder::addTypeAttr(Attribute::AttrKind Kind, Type *Ty) { 1736 return addAttribute(Attribute::get(Ctx, Kind, Ty)); 1737 } 1738 1739 AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) { 1740 return addTypeAttr(Attribute::ByVal, Ty); 1741 } 1742 1743 AttrBuilder &AttrBuilder::addStructRetAttr(Type *Ty) { 1744 return addTypeAttr(Attribute::StructRet, Ty); 1745 } 1746 1747 AttrBuilder &AttrBuilder::addByRefAttr(Type *Ty) { 1748 return addTypeAttr(Attribute::ByRef, Ty); 1749 } 1750 1751 AttrBuilder &AttrBuilder::addPreallocatedAttr(Type *Ty) { 1752 return addTypeAttr(Attribute::Preallocated, Ty); 1753 } 1754 1755 AttrBuilder &AttrBuilder::addInAllocaAttr(Type *Ty) { 1756 return addTypeAttr(Attribute::InAlloca, Ty); 1757 } 1758 1759 AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { 1760 // TODO: Could make this O(n) as we're merging two sorted lists. 1761 for (const auto &I : B.attrs()) 1762 addAttribute(I); 1763 1764 return *this; 1765 } 1766 1767 AttrBuilder &AttrBuilder::remove(const AttributeMask &AM) { 1768 erase_if(Attrs, [&](Attribute A) { return AM.contains(A); }); 1769 return *this; 1770 } 1771 1772 bool AttrBuilder::overlaps(const AttributeMask &AM) const { 1773 return any_of(Attrs, [&](Attribute A) { return AM.contains(A); }); 1774 } 1775 1776 Attribute AttrBuilder::getAttribute(Attribute::AttrKind A) const { 1777 assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!"); 1778 auto It = lower_bound(Attrs, A, AttributeComparator()); 1779 if (It != Attrs.end() && It->hasAttribute(A)) 1780 return *It; 1781 return {}; 1782 } 1783 1784 Attribute AttrBuilder::getAttribute(StringRef A) const { 1785 auto It = lower_bound(Attrs, A, AttributeComparator()); 1786 if (It != Attrs.end() && It->hasAttribute(A)) 1787 return *It; 1788 return {}; 1789 } 1790 1791 bool AttrBuilder::contains(Attribute::AttrKind A) const { 1792 return getAttribute(A).isValid(); 1793 } 1794 1795 bool AttrBuilder::contains(StringRef A) const { 1796 return getAttribute(A).isValid(); 1797 } 1798 1799 bool AttrBuilder::hasAlignmentAttr() const { 1800 return getRawIntAttr(Attribute::Alignment) != 0; 1801 } 1802 1803 bool AttrBuilder::operator==(const AttrBuilder &B) const { 1804 return Attrs == B.Attrs; 1805 } 1806 1807 //===----------------------------------------------------------------------===// 1808 // AttributeFuncs Function Defintions 1809 //===----------------------------------------------------------------------===// 1810 1811 /// Which attributes cannot be applied to a type. 1812 AttributeMask AttributeFuncs::typeIncompatible(Type *Ty, 1813 AttributeSafetyKind ASK) { 1814 AttributeMask Incompatible; 1815 1816 if (!Ty->isIntegerTy()) { 1817 // Attributes that only apply to integers. 1818 if (ASK & ASK_SAFE_TO_DROP) 1819 Incompatible.addAttribute(Attribute::AllocAlign); 1820 if (ASK & ASK_UNSAFE_TO_DROP) 1821 Incompatible.addAttribute(Attribute::SExt).addAttribute(Attribute::ZExt); 1822 } 1823 1824 if (!Ty->isPointerTy()) { 1825 // Attributes that only apply to pointers. 1826 if (ASK & ASK_SAFE_TO_DROP) 1827 Incompatible.addAttribute(Attribute::NoAlias) 1828 .addAttribute(Attribute::NoCapture) 1829 .addAttribute(Attribute::NonNull) 1830 .addAttribute(Attribute::ReadNone) 1831 .addAttribute(Attribute::ReadOnly) 1832 .addAttribute(Attribute::Dereferenceable) 1833 .addAttribute(Attribute::DereferenceableOrNull); 1834 if (ASK & ASK_UNSAFE_TO_DROP) 1835 Incompatible.addAttribute(Attribute::Nest) 1836 .addAttribute(Attribute::SwiftError) 1837 .addAttribute(Attribute::Preallocated) 1838 .addAttribute(Attribute::InAlloca) 1839 .addAttribute(Attribute::ByVal) 1840 .addAttribute(Attribute::StructRet) 1841 .addAttribute(Attribute::ByRef) 1842 .addAttribute(Attribute::ElementType) 1843 .addAttribute(Attribute::AllocatedPointer); 1844 } 1845 1846 // Attributes that only apply to pointers or vectors of pointers. 1847 if (!Ty->isPtrOrPtrVectorTy()) { 1848 if (ASK & ASK_SAFE_TO_DROP) 1849 Incompatible.addAttribute(Attribute::Alignment); 1850 } 1851 1852 // Some attributes can apply to all "values" but there are no `void` values. 1853 if (Ty->isVoidTy()) { 1854 if (ASK & ASK_SAFE_TO_DROP) 1855 Incompatible.addAttribute(Attribute::NoUndef); 1856 } 1857 1858 return Incompatible; 1859 } 1860 1861 AttributeMask AttributeFuncs::getUBImplyingAttributes() { 1862 AttributeMask AM; 1863 AM.addAttribute(Attribute::NoUndef); 1864 AM.addAttribute(Attribute::Dereferenceable); 1865 AM.addAttribute(Attribute::DereferenceableOrNull); 1866 return AM; 1867 } 1868 1869 template<typename AttrClass> 1870 static bool isEqual(const Function &Caller, const Function &Callee) { 1871 return Caller.getFnAttribute(AttrClass::getKind()) == 1872 Callee.getFnAttribute(AttrClass::getKind()); 1873 } 1874 1875 /// Compute the logical AND of the attributes of the caller and the 1876 /// callee. 1877 /// 1878 /// This function sets the caller's attribute to false if the callee's attribute 1879 /// is false. 1880 template<typename AttrClass> 1881 static void setAND(Function &Caller, const Function &Callee) { 1882 if (AttrClass::isSet(Caller, AttrClass::getKind()) && 1883 !AttrClass::isSet(Callee, AttrClass::getKind())) 1884 AttrClass::set(Caller, AttrClass::getKind(), false); 1885 } 1886 1887 /// Compute the logical OR of the attributes of the caller and the 1888 /// callee. 1889 /// 1890 /// This function sets the caller's attribute to true if the callee's attribute 1891 /// is true. 1892 template<typename AttrClass> 1893 static void setOR(Function &Caller, const Function &Callee) { 1894 if (!AttrClass::isSet(Caller, AttrClass::getKind()) && 1895 AttrClass::isSet(Callee, AttrClass::getKind())) 1896 AttrClass::set(Caller, AttrClass::getKind(), true); 1897 } 1898 1899 /// If the inlined function had a higher stack protection level than the 1900 /// calling function, then bump up the caller's stack protection level. 1901 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) { 1902 // If the calling function has *no* stack protection level (e.g. it was built 1903 // with Clang's -fno-stack-protector or no_stack_protector attribute), don't 1904 // change it as that could change the program's semantics. 1905 if (!Caller.hasStackProtectorFnAttr()) 1906 return; 1907 1908 // If upgrading the SSP attribute, clear out the old SSP Attributes first. 1909 // Having multiple SSP attributes doesn't actually hurt, but it adds useless 1910 // clutter to the IR. 1911 AttributeMask OldSSPAttr; 1912 OldSSPAttr.addAttribute(Attribute::StackProtect) 1913 .addAttribute(Attribute::StackProtectStrong) 1914 .addAttribute(Attribute::StackProtectReq); 1915 1916 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) { 1917 Caller.removeFnAttrs(OldSSPAttr); 1918 Caller.addFnAttr(Attribute::StackProtectReq); 1919 } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) && 1920 !Caller.hasFnAttribute(Attribute::StackProtectReq)) { 1921 Caller.removeFnAttrs(OldSSPAttr); 1922 Caller.addFnAttr(Attribute::StackProtectStrong); 1923 } else if (Callee.hasFnAttribute(Attribute::StackProtect) && 1924 !Caller.hasFnAttribute(Attribute::StackProtectReq) && 1925 !Caller.hasFnAttribute(Attribute::StackProtectStrong)) 1926 Caller.addFnAttr(Attribute::StackProtect); 1927 } 1928 1929 /// If the inlined function required stack probes, then ensure that 1930 /// the calling function has those too. 1931 static void adjustCallerStackProbes(Function &Caller, const Function &Callee) { 1932 if (!Caller.hasFnAttribute("probe-stack") && 1933 Callee.hasFnAttribute("probe-stack")) { 1934 Caller.addFnAttr(Callee.getFnAttribute("probe-stack")); 1935 } 1936 } 1937 1938 /// If the inlined function defines the size of guard region 1939 /// on the stack, then ensure that the calling function defines a guard region 1940 /// that is no larger. 1941 static void 1942 adjustCallerStackProbeSize(Function &Caller, const Function &Callee) { 1943 Attribute CalleeAttr = Callee.getFnAttribute("stack-probe-size"); 1944 if (CalleeAttr.isValid()) { 1945 Attribute CallerAttr = Caller.getFnAttribute("stack-probe-size"); 1946 if (CallerAttr.isValid()) { 1947 uint64_t CallerStackProbeSize, CalleeStackProbeSize; 1948 CallerAttr.getValueAsString().getAsInteger(0, CallerStackProbeSize); 1949 CalleeAttr.getValueAsString().getAsInteger(0, CalleeStackProbeSize); 1950 1951 if (CallerStackProbeSize > CalleeStackProbeSize) { 1952 Caller.addFnAttr(CalleeAttr); 1953 } 1954 } else { 1955 Caller.addFnAttr(CalleeAttr); 1956 } 1957 } 1958 } 1959 1960 /// If the inlined function defines a min legal vector width, then ensure 1961 /// the calling function has the same or larger min legal vector width. If the 1962 /// caller has the attribute, but the callee doesn't, we need to remove the 1963 /// attribute from the caller since we can't make any guarantees about the 1964 /// caller's requirements. 1965 /// This function is called after the inlining decision has been made so we have 1966 /// to merge the attribute this way. Heuristics that would use 1967 /// min-legal-vector-width to determine inline compatibility would need to be 1968 /// handled as part of inline cost analysis. 1969 static void 1970 adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) { 1971 Attribute CallerAttr = Caller.getFnAttribute("min-legal-vector-width"); 1972 if (CallerAttr.isValid()) { 1973 Attribute CalleeAttr = Callee.getFnAttribute("min-legal-vector-width"); 1974 if (CalleeAttr.isValid()) { 1975 uint64_t CallerVectorWidth, CalleeVectorWidth; 1976 CallerAttr.getValueAsString().getAsInteger(0, CallerVectorWidth); 1977 CalleeAttr.getValueAsString().getAsInteger(0, CalleeVectorWidth); 1978 if (CallerVectorWidth < CalleeVectorWidth) 1979 Caller.addFnAttr(CalleeAttr); 1980 } else { 1981 // If the callee doesn't have the attribute then we don't know anything 1982 // and must drop the attribute from the caller. 1983 Caller.removeFnAttr("min-legal-vector-width"); 1984 } 1985 } 1986 } 1987 1988 /// If the inlined function has null_pointer_is_valid attribute, 1989 /// set this attribute in the caller post inlining. 1990 static void 1991 adjustNullPointerValidAttr(Function &Caller, const Function &Callee) { 1992 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) { 1993 Caller.addFnAttr(Attribute::NullPointerIsValid); 1994 } 1995 } 1996 1997 struct EnumAttr { 1998 static bool isSet(const Function &Fn, 1999 Attribute::AttrKind Kind) { 2000 return Fn.hasFnAttribute(Kind); 2001 } 2002 2003 static void set(Function &Fn, 2004 Attribute::AttrKind Kind, bool Val) { 2005 if (Val) 2006 Fn.addFnAttr(Kind); 2007 else 2008 Fn.removeFnAttr(Kind); 2009 } 2010 }; 2011 2012 struct StrBoolAttr { 2013 static bool isSet(const Function &Fn, 2014 StringRef Kind) { 2015 auto A = Fn.getFnAttribute(Kind); 2016 return A.getValueAsString().equals("true"); 2017 } 2018 2019 static void set(Function &Fn, 2020 StringRef Kind, bool Val) { 2021 Fn.addFnAttr(Kind, Val ? "true" : "false"); 2022 } 2023 }; 2024 2025 #define GET_ATTR_NAMES 2026 #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \ 2027 struct ENUM_NAME##Attr : EnumAttr { \ 2028 static enum Attribute::AttrKind getKind() { \ 2029 return llvm::Attribute::ENUM_NAME; \ 2030 } \ 2031 }; 2032 #define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME) \ 2033 struct ENUM_NAME##Attr : StrBoolAttr { \ 2034 static StringRef getKind() { return #DISPLAY_NAME; } \ 2035 }; 2036 #include "llvm/IR/Attributes.inc" 2037 2038 #define GET_ATTR_COMPAT_FUNC 2039 #include "llvm/IR/Attributes.inc" 2040 2041 bool AttributeFuncs::areInlineCompatible(const Function &Caller, 2042 const Function &Callee) { 2043 return hasCompatibleFnAttrs(Caller, Callee); 2044 } 2045 2046 bool AttributeFuncs::areOutlineCompatible(const Function &A, 2047 const Function &B) { 2048 return hasCompatibleFnAttrs(A, B); 2049 } 2050 2051 void AttributeFuncs::mergeAttributesForInlining(Function &Caller, 2052 const Function &Callee) { 2053 mergeFnAttrs(Caller, Callee); 2054 } 2055 2056 void AttributeFuncs::mergeAttributesForOutlining(Function &Base, 2057 const Function &ToMerge) { 2058 2059 // We merge functions so that they meet the most general case. 2060 // For example, if the NoNansFPMathAttr is set in one function, but not in 2061 // the other, in the merged function we can say that the NoNansFPMathAttr 2062 // is not set. 2063 // However if we have the SpeculativeLoadHardeningAttr set true in one 2064 // function, but not the other, we make sure that the function retains 2065 // that aspect in the merged function. 2066 mergeFnAttrs(Base, ToMerge); 2067 } 2068 2069 void AttributeFuncs::updateMinLegalVectorWidthAttr(Function &Fn, 2070 uint64_t Width) { 2071 Attribute Attr = Fn.getFnAttribute("min-legal-vector-width"); 2072 if (Attr.isValid()) { 2073 uint64_t OldWidth; 2074 Attr.getValueAsString().getAsInteger(0, OldWidth); 2075 if (Width > OldWidth) 2076 Fn.addFnAttr("min-legal-vector-width", llvm::utostr(Width)); 2077 } 2078 } 2079