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