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