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