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