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