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