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 { 508 raw_string_ostream OS(Result); 509 OS << '"' << getKindAsString() << '"'; 510 511 // Since some attribute strings contain special characters that cannot be 512 // printable, those have to be escaped to make the attribute value 513 // printable as is. e.g. "\01__gnu_mcount_nc" 514 const auto &AttrVal = pImpl->getValueAsString(); 515 if (!AttrVal.empty()) { 516 OS << "=\""; 517 printEscapedString(AttrVal, OS); 518 OS << "\""; 519 } 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 StringAttrs.insert({ I.getKindAsString(), I }); 775 } else { 776 Attribute::AttrKind Kind = I.getKindAsEnum(); 777 AvailableAttrs[Kind / 8] |= 1ULL << (Kind % 8); 778 } 779 } 780 } 781 782 AttributeSetNode *AttributeSetNode::get(LLVMContext &C, 783 ArrayRef<Attribute> Attrs) { 784 SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end()); 785 llvm::sort(SortedAttrs); 786 return getSorted(C, SortedAttrs); 787 } 788 789 AttributeSetNode *AttributeSetNode::getSorted(LLVMContext &C, 790 ArrayRef<Attribute> SortedAttrs) { 791 if (SortedAttrs.empty()) 792 return nullptr; 793 794 // Build a key to look up the existing attributes. 795 LLVMContextImpl *pImpl = C.pImpl; 796 FoldingSetNodeID ID; 797 798 assert(llvm::is_sorted(SortedAttrs) && "Expected sorted attributes!"); 799 for (const auto &Attr : SortedAttrs) 800 Attr.Profile(ID); 801 802 void *InsertPoint; 803 AttributeSetNode *PA = 804 pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint); 805 806 // If we didn't find any existing attributes of the same shape then create a 807 // new one and insert it. 808 if (!PA) { 809 // Coallocate entries after the AttributeSetNode itself. 810 void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size())); 811 PA = new (Mem) AttributeSetNode(SortedAttrs); 812 pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint); 813 } 814 815 // Return the AttributeSetNode that we found or created. 816 return PA; 817 } 818 819 AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) { 820 // Add target-independent attributes. 821 SmallVector<Attribute, 8> Attrs; 822 for (Attribute::AttrKind Kind = Attribute::None; 823 Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) { 824 if (!B.contains(Kind)) 825 continue; 826 827 Attribute Attr; 828 switch (Kind) { 829 case Attribute::ByVal: 830 Attr = Attribute::getWithByValType(C, B.getByValType()); 831 break; 832 case Attribute::Alignment: 833 assert(B.getAlignment() && "Alignment must be set"); 834 Attr = Attribute::getWithAlignment(C, *B.getAlignment()); 835 break; 836 case Attribute::StackAlignment: 837 assert(B.getStackAlignment() && "StackAlignment must be set"); 838 Attr = Attribute::getWithStackAlignment(C, *B.getStackAlignment()); 839 break; 840 case Attribute::Dereferenceable: 841 Attr = Attribute::getWithDereferenceableBytes( 842 C, B.getDereferenceableBytes()); 843 break; 844 case Attribute::DereferenceableOrNull: 845 Attr = Attribute::getWithDereferenceableOrNullBytes( 846 C, B.getDereferenceableOrNullBytes()); 847 break; 848 case Attribute::AllocSize: { 849 auto A = B.getAllocSizeArgs(); 850 Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second); 851 break; 852 } 853 default: 854 Attr = Attribute::get(C, Kind); 855 } 856 Attrs.push_back(Attr); 857 } 858 859 // Add target-dependent (string) attributes. 860 for (const auto &TDA : B.td_attrs()) 861 Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second)); 862 863 return getSorted(C, Attrs); 864 } 865 866 bool AttributeSetNode::hasAttribute(StringRef Kind) const { 867 return StringAttrs.count(Kind); 868 } 869 870 Optional<Attribute> 871 AttributeSetNode::findEnumAttribute(Attribute::AttrKind Kind) const { 872 // Do a quick presence check. 873 if (!hasAttribute(Kind)) 874 return None; 875 876 // Attributes in a set are sorted by enum value, followed by string 877 // attributes. Binary search the one we want. 878 const Attribute *I = 879 std::lower_bound(begin(), end() - StringAttrs.size(), Kind, 880 [](Attribute A, Attribute::AttrKind Kind) { 881 return A.getKindAsEnum() < Kind; 882 }); 883 assert(I != end() && I->hasAttribute(Kind) && "Presence check failed?"); 884 return *I; 885 } 886 887 Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const { 888 if (auto A = findEnumAttribute(Kind)) 889 return *A; 890 return {}; 891 } 892 893 Attribute AttributeSetNode::getAttribute(StringRef Kind) const { 894 return StringAttrs.lookup(Kind); 895 } 896 897 MaybeAlign AttributeSetNode::getAlignment() const { 898 if (auto A = findEnumAttribute(Attribute::Alignment)) 899 return A->getAlignment(); 900 return None; 901 } 902 903 MaybeAlign AttributeSetNode::getStackAlignment() const { 904 if (auto A = findEnumAttribute(Attribute::StackAlignment)) 905 return A->getStackAlignment(); 906 return None; 907 } 908 909 Type *AttributeSetNode::getByValType() const { 910 if (auto A = findEnumAttribute(Attribute::ByVal)) 911 return A->getValueAsType(); 912 return 0; 913 } 914 915 uint64_t AttributeSetNode::getDereferenceableBytes() const { 916 if (auto A = findEnumAttribute(Attribute::Dereferenceable)) 917 return A->getDereferenceableBytes(); 918 return 0; 919 } 920 921 uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const { 922 if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull)) 923 return A->getDereferenceableOrNullBytes(); 924 return 0; 925 } 926 927 std::pair<unsigned, Optional<unsigned>> 928 AttributeSetNode::getAllocSizeArgs() const { 929 if (auto A = findEnumAttribute(Attribute::AllocSize)) 930 return A->getAllocSizeArgs(); 931 return std::make_pair(0, 0); 932 } 933 934 std::string AttributeSetNode::getAsString(bool InAttrGrp) const { 935 std::string Str; 936 for (iterator I = begin(), E = end(); I != E; ++I) { 937 if (I != begin()) 938 Str += ' '; 939 Str += I->getAsString(InAttrGrp); 940 } 941 return Str; 942 } 943 944 //===----------------------------------------------------------------------===// 945 // AttributeListImpl Definition 946 //===----------------------------------------------------------------------===// 947 948 /// Map from AttributeList index to the internal array index. Adding one happens 949 /// to work, but it relies on unsigned integer wrapping. MSVC warns about 950 /// unsigned wrapping in constexpr functions, so write out the conditional. LLVM 951 /// folds it to add anyway. 952 static constexpr unsigned attrIdxToArrayIdx(unsigned Index) { 953 return Index == AttributeList::FunctionIndex ? 0 : Index + 1; 954 } 955 956 AttributeListImpl::AttributeListImpl(LLVMContext &C, 957 ArrayRef<AttributeSet> Sets) 958 : Context(C), NumAttrSets(Sets.size()) { 959 assert(!Sets.empty() && "pointless AttributeListImpl"); 960 961 // There's memory after the node where we can store the entries in. 962 llvm::copy(Sets, getTrailingObjects<AttributeSet>()); 963 964 // Initialize AvailableFunctionAttrs summary bitset. 965 static_assert(Attribute::EndAttrKinds <= 966 sizeof(AvailableFunctionAttrs) * CHAR_BIT, 967 "Too many attributes"); 968 static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U, 969 "function should be stored in slot 0"); 970 for (const auto &I : Sets[0]) { 971 if (!I.isStringAttribute()) { 972 Attribute::AttrKind Kind = I.getKindAsEnum(); 973 AvailableFunctionAttrs[Kind / 8] |= 1ULL << (Kind % 8); 974 } 975 } 976 } 977 978 void AttributeListImpl::Profile(FoldingSetNodeID &ID) const { 979 Profile(ID, makeArrayRef(begin(), end())); 980 } 981 982 void AttributeListImpl::Profile(FoldingSetNodeID &ID, 983 ArrayRef<AttributeSet> Sets) { 984 for (const auto &Set : Sets) 985 ID.AddPointer(Set.SetNode); 986 } 987 988 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 989 LLVM_DUMP_METHOD void AttributeListImpl::dump() const { 990 AttributeList(const_cast<AttributeListImpl *>(this)).dump(); 991 } 992 #endif 993 994 //===----------------------------------------------------------------------===// 995 // AttributeList Construction and Mutation Methods 996 //===----------------------------------------------------------------------===// 997 998 AttributeList AttributeList::getImpl(LLVMContext &C, 999 ArrayRef<AttributeSet> AttrSets) { 1000 assert(!AttrSets.empty() && "pointless AttributeListImpl"); 1001 1002 LLVMContextImpl *pImpl = C.pImpl; 1003 FoldingSetNodeID ID; 1004 AttributeListImpl::Profile(ID, AttrSets); 1005 1006 void *InsertPoint; 1007 AttributeListImpl *PA = 1008 pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint); 1009 1010 // If we didn't find any existing attributes of the same shape then 1011 // create a new one and insert it. 1012 if (!PA) { 1013 // Coallocate entries after the AttributeListImpl itself. 1014 void *Mem = ::operator new( 1015 AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size())); 1016 PA = new (Mem) AttributeListImpl(C, AttrSets); 1017 pImpl->AttrsLists.InsertNode(PA, InsertPoint); 1018 } 1019 1020 // Return the AttributesList that we found or created. 1021 return AttributeList(PA); 1022 } 1023 1024 AttributeList 1025 AttributeList::get(LLVMContext &C, 1026 ArrayRef<std::pair<unsigned, Attribute>> Attrs) { 1027 // If there are no attributes then return a null AttributesList pointer. 1028 if (Attrs.empty()) 1029 return {}; 1030 1031 assert(llvm::is_sorted(Attrs, 1032 [](const std::pair<unsigned, Attribute> &LHS, 1033 const std::pair<unsigned, Attribute> &RHS) { 1034 return LHS.first < RHS.first; 1035 }) && 1036 "Misordered Attributes list!"); 1037 assert(llvm::none_of(Attrs, 1038 [](const std::pair<unsigned, Attribute> &Pair) { 1039 return Pair.second.hasAttribute(Attribute::None); 1040 }) && 1041 "Pointless attribute!"); 1042 1043 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes 1044 // list. 1045 SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec; 1046 for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(), 1047 E = Attrs.end(); I != E; ) { 1048 unsigned Index = I->first; 1049 SmallVector<Attribute, 4> AttrVec; 1050 while (I != E && I->first == Index) { 1051 AttrVec.push_back(I->second); 1052 ++I; 1053 } 1054 1055 AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec)); 1056 } 1057 1058 return get(C, AttrPairVec); 1059 } 1060 1061 AttributeList 1062 AttributeList::get(LLVMContext &C, 1063 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) { 1064 // If there are no attributes then return a null AttributesList pointer. 1065 if (Attrs.empty()) 1066 return {}; 1067 1068 assert(llvm::is_sorted(Attrs, 1069 [](const std::pair<unsigned, AttributeSet> &LHS, 1070 const std::pair<unsigned, AttributeSet> &RHS) { 1071 return LHS.first < RHS.first; 1072 }) && 1073 "Misordered Attributes list!"); 1074 assert(llvm::none_of(Attrs, 1075 [](const std::pair<unsigned, AttributeSet> &Pair) { 1076 return !Pair.second.hasAttributes(); 1077 }) && 1078 "Pointless attribute!"); 1079 1080 unsigned MaxIndex = Attrs.back().first; 1081 // If the MaxIndex is FunctionIndex and there are other indices in front 1082 // of it, we need to use the largest of those to get the right size. 1083 if (MaxIndex == FunctionIndex && Attrs.size() > 1) 1084 MaxIndex = Attrs[Attrs.size() - 2].first; 1085 1086 SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1); 1087 for (const auto &Pair : Attrs) 1088 AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second; 1089 1090 return getImpl(C, AttrVec); 1091 } 1092 1093 AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs, 1094 AttributeSet RetAttrs, 1095 ArrayRef<AttributeSet> ArgAttrs) { 1096 // Scan from the end to find the last argument with attributes. Most 1097 // arguments don't have attributes, so it's nice if we can have fewer unique 1098 // AttributeListImpls by dropping empty attribute sets at the end of the list. 1099 unsigned NumSets = 0; 1100 for (size_t I = ArgAttrs.size(); I != 0; --I) { 1101 if (ArgAttrs[I - 1].hasAttributes()) { 1102 NumSets = I + 2; 1103 break; 1104 } 1105 } 1106 if (NumSets == 0) { 1107 // Check function and return attributes if we didn't have argument 1108 // attributes. 1109 if (RetAttrs.hasAttributes()) 1110 NumSets = 2; 1111 else if (FnAttrs.hasAttributes()) 1112 NumSets = 1; 1113 } 1114 1115 // If all attribute sets were empty, we can use the empty attribute list. 1116 if (NumSets == 0) 1117 return {}; 1118 1119 SmallVector<AttributeSet, 8> AttrSets; 1120 AttrSets.reserve(NumSets); 1121 // If we have any attributes, we always have function attributes. 1122 AttrSets.push_back(FnAttrs); 1123 if (NumSets > 1) 1124 AttrSets.push_back(RetAttrs); 1125 if (NumSets > 2) { 1126 // Drop the empty argument attribute sets at the end. 1127 ArgAttrs = ArgAttrs.take_front(NumSets - 2); 1128 AttrSets.insert(AttrSets.end(), ArgAttrs.begin(), ArgAttrs.end()); 1129 } 1130 1131 return getImpl(C, AttrSets); 1132 } 1133 1134 AttributeList AttributeList::get(LLVMContext &C, unsigned Index, 1135 const AttrBuilder &B) { 1136 if (!B.hasAttributes()) 1137 return {}; 1138 Index = attrIdxToArrayIdx(Index); 1139 SmallVector<AttributeSet, 8> AttrSets(Index + 1); 1140 AttrSets[Index] = AttributeSet::get(C, B); 1141 return getImpl(C, AttrSets); 1142 } 1143 1144 AttributeList AttributeList::get(LLVMContext &C, unsigned Index, 1145 ArrayRef<Attribute::AttrKind> Kinds) { 1146 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; 1147 for (const auto K : Kinds) 1148 Attrs.emplace_back(Index, Attribute::get(C, K)); 1149 return get(C, Attrs); 1150 } 1151 1152 AttributeList AttributeList::get(LLVMContext &C, unsigned Index, 1153 ArrayRef<StringRef> Kinds) { 1154 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; 1155 for (const auto &K : Kinds) 1156 Attrs.emplace_back(Index, Attribute::get(C, K)); 1157 return get(C, Attrs); 1158 } 1159 1160 AttributeList AttributeList::get(LLVMContext &C, 1161 ArrayRef<AttributeList> Attrs) { 1162 if (Attrs.empty()) 1163 return {}; 1164 if (Attrs.size() == 1) 1165 return Attrs[0]; 1166 1167 unsigned MaxSize = 0; 1168 for (const auto &List : Attrs) 1169 MaxSize = std::max(MaxSize, List.getNumAttrSets()); 1170 1171 // If every list was empty, there is no point in merging the lists. 1172 if (MaxSize == 0) 1173 return {}; 1174 1175 SmallVector<AttributeSet, 8> NewAttrSets(MaxSize); 1176 for (unsigned I = 0; I < MaxSize; ++I) { 1177 AttrBuilder CurBuilder; 1178 for (const auto &List : Attrs) 1179 CurBuilder.merge(List.getAttributes(I - 1)); 1180 NewAttrSets[I] = AttributeSet::get(C, CurBuilder); 1181 } 1182 1183 return getImpl(C, NewAttrSets); 1184 } 1185 1186 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index, 1187 Attribute::AttrKind Kind) const { 1188 if (hasAttribute(Index, Kind)) return *this; 1189 AttrBuilder B; 1190 B.addAttribute(Kind); 1191 return addAttributes(C, Index, B); 1192 } 1193 1194 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index, 1195 StringRef Kind, 1196 StringRef Value) const { 1197 AttrBuilder B; 1198 B.addAttribute(Kind, Value); 1199 return addAttributes(C, Index, B); 1200 } 1201 1202 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index, 1203 Attribute A) const { 1204 AttrBuilder B; 1205 B.addAttribute(A); 1206 return addAttributes(C, Index, B); 1207 } 1208 1209 AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index, 1210 const AttrBuilder &B) const { 1211 if (!B.hasAttributes()) 1212 return *this; 1213 1214 if (!pImpl) 1215 return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}}); 1216 1217 #ifndef NDEBUG 1218 // FIXME it is not obvious how this should work for alignment. For now, say 1219 // we can't change a known alignment. 1220 const MaybeAlign OldAlign = getAttributes(Index).getAlignment(); 1221 const MaybeAlign NewAlign = B.getAlignment(); 1222 assert((!OldAlign || !NewAlign || OldAlign == NewAlign) && 1223 "Attempt to change alignment!"); 1224 #endif 1225 1226 Index = attrIdxToArrayIdx(Index); 1227 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1228 if (Index >= AttrSets.size()) 1229 AttrSets.resize(Index + 1); 1230 1231 AttrBuilder Merged(AttrSets[Index]); 1232 Merged.merge(B); 1233 AttrSets[Index] = AttributeSet::get(C, Merged); 1234 1235 return getImpl(C, AttrSets); 1236 } 1237 1238 AttributeList AttributeList::addParamAttribute(LLVMContext &C, 1239 ArrayRef<unsigned> ArgNos, 1240 Attribute A) const { 1241 assert(llvm::is_sorted(ArgNos)); 1242 1243 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1244 unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex); 1245 if (MaxIndex >= AttrSets.size()) 1246 AttrSets.resize(MaxIndex + 1); 1247 1248 for (unsigned ArgNo : ArgNos) { 1249 unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex); 1250 AttrBuilder B(AttrSets[Index]); 1251 B.addAttribute(A); 1252 AttrSets[Index] = AttributeSet::get(C, B); 1253 } 1254 1255 return getImpl(C, AttrSets); 1256 } 1257 1258 AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index, 1259 Attribute::AttrKind Kind) const { 1260 if (!hasAttribute(Index, Kind)) return *this; 1261 1262 Index = attrIdxToArrayIdx(Index); 1263 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1264 assert(Index < AttrSets.size()); 1265 1266 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind); 1267 1268 return getImpl(C, AttrSets); 1269 } 1270 1271 AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index, 1272 StringRef Kind) const { 1273 if (!hasAttribute(Index, Kind)) return *this; 1274 1275 Index = attrIdxToArrayIdx(Index); 1276 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1277 assert(Index < AttrSets.size()); 1278 1279 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind); 1280 1281 return getImpl(C, AttrSets); 1282 } 1283 1284 AttributeList 1285 AttributeList::removeAttributes(LLVMContext &C, unsigned Index, 1286 const AttrBuilder &AttrsToRemove) const { 1287 if (!pImpl) 1288 return {}; 1289 1290 Index = attrIdxToArrayIdx(Index); 1291 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1292 if (Index >= AttrSets.size()) 1293 AttrSets.resize(Index + 1); 1294 1295 AttrSets[Index] = AttrSets[Index].removeAttributes(C, AttrsToRemove); 1296 1297 return getImpl(C, AttrSets); 1298 } 1299 1300 AttributeList AttributeList::removeAttributes(LLVMContext &C, 1301 unsigned WithoutIndex) const { 1302 if (!pImpl) 1303 return {}; 1304 WithoutIndex = attrIdxToArrayIdx(WithoutIndex); 1305 if (WithoutIndex >= getNumAttrSets()) 1306 return *this; 1307 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end()); 1308 AttrSets[WithoutIndex] = AttributeSet(); 1309 return getImpl(C, AttrSets); 1310 } 1311 1312 AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C, 1313 unsigned Index, 1314 uint64_t Bytes) const { 1315 AttrBuilder B; 1316 B.addDereferenceableAttr(Bytes); 1317 return addAttributes(C, Index, B); 1318 } 1319 1320 AttributeList 1321 AttributeList::addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index, 1322 uint64_t Bytes) const { 1323 AttrBuilder B; 1324 B.addDereferenceableOrNullAttr(Bytes); 1325 return addAttributes(C, Index, B); 1326 } 1327 1328 AttributeList 1329 AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index, 1330 unsigned ElemSizeArg, 1331 const Optional<unsigned> &NumElemsArg) { 1332 AttrBuilder B; 1333 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg); 1334 return addAttributes(C, Index, B); 1335 } 1336 1337 //===----------------------------------------------------------------------===// 1338 // AttributeList Accessor Methods 1339 //===----------------------------------------------------------------------===// 1340 1341 LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); } 1342 1343 AttributeSet AttributeList::getParamAttributes(unsigned ArgNo) const { 1344 return getAttributes(ArgNo + FirstArgIndex); 1345 } 1346 1347 AttributeSet AttributeList::getRetAttributes() const { 1348 return getAttributes(ReturnIndex); 1349 } 1350 1351 AttributeSet AttributeList::getFnAttributes() const { 1352 return getAttributes(FunctionIndex); 1353 } 1354 1355 bool AttributeList::hasAttribute(unsigned Index, 1356 Attribute::AttrKind Kind) const { 1357 return getAttributes(Index).hasAttribute(Kind); 1358 } 1359 1360 bool AttributeList::hasAttribute(unsigned Index, StringRef Kind) const { 1361 return getAttributes(Index).hasAttribute(Kind); 1362 } 1363 1364 bool AttributeList::hasAttributes(unsigned Index) const { 1365 return getAttributes(Index).hasAttributes(); 1366 } 1367 1368 bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind) const { 1369 return pImpl && pImpl->hasFnAttribute(Kind); 1370 } 1371 1372 bool AttributeList::hasFnAttribute(StringRef Kind) const { 1373 return hasAttribute(AttributeList::FunctionIndex, Kind); 1374 } 1375 1376 bool AttributeList::hasParamAttribute(unsigned ArgNo, 1377 Attribute::AttrKind Kind) const { 1378 return hasAttribute(ArgNo + FirstArgIndex, Kind); 1379 } 1380 1381 bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr, 1382 unsigned *Index) const { 1383 if (!pImpl) return false; 1384 1385 for (unsigned I = index_begin(), E = index_end(); I != E; ++I) { 1386 if (hasAttribute(I, Attr)) { 1387 if (Index) 1388 *Index = I; 1389 return true; 1390 } 1391 } 1392 1393 return false; 1394 } 1395 1396 Attribute AttributeList::getAttribute(unsigned Index, 1397 Attribute::AttrKind Kind) const { 1398 return getAttributes(Index).getAttribute(Kind); 1399 } 1400 1401 Attribute AttributeList::getAttribute(unsigned Index, StringRef Kind) const { 1402 return getAttributes(Index).getAttribute(Kind); 1403 } 1404 1405 MaybeAlign AttributeList::getRetAlignment() const { 1406 return getAttributes(ReturnIndex).getAlignment(); 1407 } 1408 1409 MaybeAlign AttributeList::getParamAlignment(unsigned ArgNo) const { 1410 return getAttributes(ArgNo + FirstArgIndex).getAlignment(); 1411 } 1412 1413 Type *AttributeList::getParamByValType(unsigned Index) const { 1414 return getAttributes(Index+FirstArgIndex).getByValType(); 1415 } 1416 1417 MaybeAlign AttributeList::getStackAlignment(unsigned Index) const { 1418 return getAttributes(Index).getStackAlignment(); 1419 } 1420 1421 uint64_t AttributeList::getDereferenceableBytes(unsigned Index) const { 1422 return getAttributes(Index).getDereferenceableBytes(); 1423 } 1424 1425 uint64_t AttributeList::getDereferenceableOrNullBytes(unsigned Index) const { 1426 return getAttributes(Index).getDereferenceableOrNullBytes(); 1427 } 1428 1429 std::pair<unsigned, Optional<unsigned>> 1430 AttributeList::getAllocSizeArgs(unsigned Index) const { 1431 return getAttributes(Index).getAllocSizeArgs(); 1432 } 1433 1434 std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const { 1435 return getAttributes(Index).getAsString(InAttrGrp); 1436 } 1437 1438 AttributeSet AttributeList::getAttributes(unsigned Index) const { 1439 Index = attrIdxToArrayIdx(Index); 1440 if (!pImpl || Index >= getNumAttrSets()) 1441 return {}; 1442 return pImpl->begin()[Index]; 1443 } 1444 1445 AttributeList::iterator AttributeList::begin() const { 1446 return pImpl ? pImpl->begin() : nullptr; 1447 } 1448 1449 AttributeList::iterator AttributeList::end() const { 1450 return pImpl ? pImpl->end() : nullptr; 1451 } 1452 1453 //===----------------------------------------------------------------------===// 1454 // AttributeList Introspection Methods 1455 //===----------------------------------------------------------------------===// 1456 1457 unsigned AttributeList::getNumAttrSets() const { 1458 return pImpl ? pImpl->NumAttrSets : 0; 1459 } 1460 1461 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1462 LLVM_DUMP_METHOD void AttributeList::dump() const { 1463 dbgs() << "PAL[\n"; 1464 1465 for (unsigned i = index_begin(), e = index_end(); i != e; ++i) { 1466 if (getAttributes(i).hasAttributes()) 1467 dbgs() << " { " << i << " => " << getAsString(i) << " }\n"; 1468 } 1469 1470 dbgs() << "]\n"; 1471 } 1472 #endif 1473 1474 //===----------------------------------------------------------------------===// 1475 // AttrBuilder Method Implementations 1476 //===----------------------------------------------------------------------===// 1477 1478 // FIXME: Remove this ctor, use AttributeSet. 1479 AttrBuilder::AttrBuilder(AttributeList AL, unsigned Index) { 1480 AttributeSet AS = AL.getAttributes(Index); 1481 for (const auto &A : AS) 1482 addAttribute(A); 1483 } 1484 1485 AttrBuilder::AttrBuilder(AttributeSet AS) { 1486 for (const auto &A : AS) 1487 addAttribute(A); 1488 } 1489 1490 void AttrBuilder::clear() { 1491 Attrs.reset(); 1492 TargetDepAttrs.clear(); 1493 Alignment.reset(); 1494 StackAlignment.reset(); 1495 DerefBytes = DerefOrNullBytes = 0; 1496 AllocSizeArgs = 0; 1497 ByValType = nullptr; 1498 } 1499 1500 AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { 1501 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!"); 1502 assert(!Attribute::doesAttrKindHaveArgument(Val) && 1503 "Adding integer attribute without adding a value!"); 1504 Attrs[Val] = true; 1505 return *this; 1506 } 1507 1508 AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) { 1509 if (Attr.isStringAttribute()) { 1510 addAttribute(Attr.getKindAsString(), Attr.getValueAsString()); 1511 return *this; 1512 } 1513 1514 Attribute::AttrKind Kind = Attr.getKindAsEnum(); 1515 Attrs[Kind] = true; 1516 1517 if (Kind == Attribute::Alignment) 1518 Alignment = Attr.getAlignment(); 1519 else if (Kind == Attribute::StackAlignment) 1520 StackAlignment = Attr.getStackAlignment(); 1521 else if (Kind == Attribute::ByVal) 1522 ByValType = Attr.getValueAsType(); 1523 else if (Kind == Attribute::Dereferenceable) 1524 DerefBytes = Attr.getDereferenceableBytes(); 1525 else if (Kind == Attribute::DereferenceableOrNull) 1526 DerefOrNullBytes = Attr.getDereferenceableOrNullBytes(); 1527 else if (Kind == Attribute::AllocSize) 1528 AllocSizeArgs = Attr.getValueAsInt(); 1529 return *this; 1530 } 1531 1532 AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) { 1533 TargetDepAttrs[std::string(A)] = std::string(V); 1534 return *this; 1535 } 1536 1537 AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { 1538 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!"); 1539 Attrs[Val] = false; 1540 1541 if (Val == Attribute::Alignment) 1542 Alignment.reset(); 1543 else if (Val == Attribute::StackAlignment) 1544 StackAlignment.reset(); 1545 else if (Val == Attribute::ByVal) 1546 ByValType = nullptr; 1547 else if (Val == Attribute::Dereferenceable) 1548 DerefBytes = 0; 1549 else if (Val == Attribute::DereferenceableOrNull) 1550 DerefOrNullBytes = 0; 1551 else if (Val == Attribute::AllocSize) 1552 AllocSizeArgs = 0; 1553 1554 return *this; 1555 } 1556 1557 AttrBuilder &AttrBuilder::removeAttributes(AttributeList A, uint64_t Index) { 1558 remove(A.getAttributes(Index)); 1559 return *this; 1560 } 1561 1562 AttrBuilder &AttrBuilder::removeAttribute(StringRef A) { 1563 auto I = TargetDepAttrs.find(A); 1564 if (I != TargetDepAttrs.end()) 1565 TargetDepAttrs.erase(I); 1566 return *this; 1567 } 1568 1569 std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const { 1570 return unpackAllocSizeArgs(AllocSizeArgs); 1571 } 1572 1573 AttrBuilder &AttrBuilder::addAlignmentAttr(MaybeAlign Align) { 1574 if (!Align) 1575 return *this; 1576 1577 assert(*Align <= llvm::Value::MaximumAlignment && "Alignment too large."); 1578 1579 Attrs[Attribute::Alignment] = true; 1580 Alignment = Align; 1581 return *this; 1582 } 1583 1584 AttrBuilder &AttrBuilder::addStackAlignmentAttr(MaybeAlign Align) { 1585 // Default alignment, allow the target to define how to align it. 1586 if (!Align) 1587 return *this; 1588 1589 assert(*Align <= 0x100 && "Alignment too large."); 1590 1591 Attrs[Attribute::StackAlignment] = true; 1592 StackAlignment = Align; 1593 return *this; 1594 } 1595 1596 AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) { 1597 if (Bytes == 0) return *this; 1598 1599 Attrs[Attribute::Dereferenceable] = true; 1600 DerefBytes = Bytes; 1601 return *this; 1602 } 1603 1604 AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) { 1605 if (Bytes == 0) 1606 return *this; 1607 1608 Attrs[Attribute::DereferenceableOrNull] = true; 1609 DerefOrNullBytes = Bytes; 1610 return *this; 1611 } 1612 1613 AttrBuilder &AttrBuilder::addAllocSizeAttr(unsigned ElemSize, 1614 const Optional<unsigned> &NumElems) { 1615 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems)); 1616 } 1617 1618 AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) { 1619 // (0, 0) is our "not present" value, so we need to check for it here. 1620 assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)"); 1621 1622 Attrs[Attribute::AllocSize] = true; 1623 // Reuse existing machinery to store this as a single 64-bit integer so we can 1624 // save a few bytes over using a pair<unsigned, Optional<unsigned>>. 1625 AllocSizeArgs = RawArgs; 1626 return *this; 1627 } 1628 1629 AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) { 1630 Attrs[Attribute::ByVal] = true; 1631 ByValType = Ty; 1632 return *this; 1633 } 1634 1635 AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { 1636 // FIXME: What if both have alignments, but they don't match?! 1637 if (!Alignment) 1638 Alignment = B.Alignment; 1639 1640 if (!StackAlignment) 1641 StackAlignment = B.StackAlignment; 1642 1643 if (!DerefBytes) 1644 DerefBytes = B.DerefBytes; 1645 1646 if (!DerefOrNullBytes) 1647 DerefOrNullBytes = B.DerefOrNullBytes; 1648 1649 if (!AllocSizeArgs) 1650 AllocSizeArgs = B.AllocSizeArgs; 1651 1652 if (!ByValType) 1653 ByValType = B.ByValType; 1654 1655 Attrs |= B.Attrs; 1656 1657 for (auto I : B.td_attrs()) 1658 TargetDepAttrs[I.first] = I.second; 1659 1660 return *this; 1661 } 1662 1663 AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) { 1664 // FIXME: What if both have alignments, but they don't match?! 1665 if (B.Alignment) 1666 Alignment.reset(); 1667 1668 if (B.StackAlignment) 1669 StackAlignment.reset(); 1670 1671 if (B.DerefBytes) 1672 DerefBytes = 0; 1673 1674 if (B.DerefOrNullBytes) 1675 DerefOrNullBytes = 0; 1676 1677 if (B.AllocSizeArgs) 1678 AllocSizeArgs = 0; 1679 1680 if (B.ByValType) 1681 ByValType = nullptr; 1682 1683 Attrs &= ~B.Attrs; 1684 1685 for (auto I : B.td_attrs()) 1686 TargetDepAttrs.erase(I.first); 1687 1688 return *this; 1689 } 1690 1691 bool AttrBuilder::overlaps(const AttrBuilder &B) const { 1692 // First check if any of the target independent attributes overlap. 1693 if ((Attrs & B.Attrs).any()) 1694 return true; 1695 1696 // Then check if any target dependent ones do. 1697 for (const auto &I : td_attrs()) 1698 if (B.contains(I.first)) 1699 return true; 1700 1701 return false; 1702 } 1703 1704 bool AttrBuilder::contains(StringRef A) const { 1705 return TargetDepAttrs.find(A) != TargetDepAttrs.end(); 1706 } 1707 1708 bool AttrBuilder::hasAttributes() const { 1709 return !Attrs.none() || !TargetDepAttrs.empty(); 1710 } 1711 1712 bool AttrBuilder::hasAttributes(AttributeList AL, uint64_t Index) const { 1713 AttributeSet AS = AL.getAttributes(Index); 1714 1715 for (const auto &Attr : AS) { 1716 if (Attr.isEnumAttribute() || Attr.isIntAttribute()) { 1717 if (contains(Attr.getKindAsEnum())) 1718 return true; 1719 } else { 1720 assert(Attr.isStringAttribute() && "Invalid attribute kind!"); 1721 return contains(Attr.getKindAsString()); 1722 } 1723 } 1724 1725 return false; 1726 } 1727 1728 bool AttrBuilder::hasAlignmentAttr() const { 1729 return Alignment != 0; 1730 } 1731 1732 bool AttrBuilder::operator==(const AttrBuilder &B) { 1733 if (Attrs != B.Attrs) 1734 return false; 1735 1736 for (td_const_iterator I = TargetDepAttrs.begin(), 1737 E = TargetDepAttrs.end(); I != E; ++I) 1738 if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end()) 1739 return false; 1740 1741 return Alignment == B.Alignment && StackAlignment == B.StackAlignment && 1742 DerefBytes == B.DerefBytes && ByValType == B.ByValType; 1743 } 1744 1745 //===----------------------------------------------------------------------===// 1746 // AttributeFuncs Function Defintions 1747 //===----------------------------------------------------------------------===// 1748 1749 /// Which attributes cannot be applied to a type. 1750 AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) { 1751 AttrBuilder Incompatible; 1752 1753 if (!Ty->isIntegerTy()) 1754 // Attribute that only apply to integers. 1755 Incompatible.addAttribute(Attribute::SExt) 1756 .addAttribute(Attribute::ZExt); 1757 1758 if (!Ty->isPointerTy()) 1759 // Attribute that only apply to pointers. 1760 Incompatible.addAttribute(Attribute::ByVal) 1761 .addAttribute(Attribute::Nest) 1762 .addAttribute(Attribute::NoAlias) 1763 .addAttribute(Attribute::NoCapture) 1764 .addAttribute(Attribute::NonNull) 1765 .addDereferenceableAttr(1) // the int here is ignored 1766 .addDereferenceableOrNullAttr(1) // the int here is ignored 1767 .addAttribute(Attribute::ReadNone) 1768 .addAttribute(Attribute::ReadOnly) 1769 .addAttribute(Attribute::StructRet) 1770 .addAttribute(Attribute::InAlloca); 1771 1772 return Incompatible; 1773 } 1774 1775 template<typename AttrClass> 1776 static bool isEqual(const Function &Caller, const Function &Callee) { 1777 return Caller.getFnAttribute(AttrClass::getKind()) == 1778 Callee.getFnAttribute(AttrClass::getKind()); 1779 } 1780 1781 /// Compute the logical AND of the attributes of the caller and the 1782 /// callee. 1783 /// 1784 /// This function sets the caller's attribute to false if the callee's attribute 1785 /// is false. 1786 template<typename AttrClass> 1787 static void setAND(Function &Caller, const Function &Callee) { 1788 if (AttrClass::isSet(Caller, AttrClass::getKind()) && 1789 !AttrClass::isSet(Callee, AttrClass::getKind())) 1790 AttrClass::set(Caller, AttrClass::getKind(), false); 1791 } 1792 1793 /// Compute the logical OR of the attributes of the caller and the 1794 /// callee. 1795 /// 1796 /// This function sets the caller's attribute to true if the callee's attribute 1797 /// is true. 1798 template<typename AttrClass> 1799 static void setOR(Function &Caller, const Function &Callee) { 1800 if (!AttrClass::isSet(Caller, AttrClass::getKind()) && 1801 AttrClass::isSet(Callee, AttrClass::getKind())) 1802 AttrClass::set(Caller, AttrClass::getKind(), true); 1803 } 1804 1805 /// If the inlined function had a higher stack protection level than the 1806 /// calling function, then bump up the caller's stack protection level. 1807 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) { 1808 // If upgrading the SSP attribute, clear out the old SSP Attributes first. 1809 // Having multiple SSP attributes doesn't actually hurt, but it adds useless 1810 // clutter to the IR. 1811 AttrBuilder OldSSPAttr; 1812 OldSSPAttr.addAttribute(Attribute::StackProtect) 1813 .addAttribute(Attribute::StackProtectStrong) 1814 .addAttribute(Attribute::StackProtectReq); 1815 1816 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) { 1817 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr); 1818 Caller.addFnAttr(Attribute::StackProtectReq); 1819 } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) && 1820 !Caller.hasFnAttribute(Attribute::StackProtectReq)) { 1821 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr); 1822 Caller.addFnAttr(Attribute::StackProtectStrong); 1823 } else if (Callee.hasFnAttribute(Attribute::StackProtect) && 1824 !Caller.hasFnAttribute(Attribute::StackProtectReq) && 1825 !Caller.hasFnAttribute(Attribute::StackProtectStrong)) 1826 Caller.addFnAttr(Attribute::StackProtect); 1827 } 1828 1829 /// If the inlined function required stack probes, then ensure that 1830 /// the calling function has those too. 1831 static void adjustCallerStackProbes(Function &Caller, const Function &Callee) { 1832 if (!Caller.hasFnAttribute("probe-stack") && 1833 Callee.hasFnAttribute("probe-stack")) { 1834 Caller.addFnAttr(Callee.getFnAttribute("probe-stack")); 1835 } 1836 } 1837 1838 /// If the inlined function defines the size of guard region 1839 /// on the stack, then ensure that the calling function defines a guard region 1840 /// that is no larger. 1841 static void 1842 adjustCallerStackProbeSize(Function &Caller, const Function &Callee) { 1843 if (Callee.hasFnAttribute("stack-probe-size")) { 1844 uint64_t CalleeStackProbeSize; 1845 Callee.getFnAttribute("stack-probe-size") 1846 .getValueAsString() 1847 .getAsInteger(0, CalleeStackProbeSize); 1848 if (Caller.hasFnAttribute("stack-probe-size")) { 1849 uint64_t CallerStackProbeSize; 1850 Caller.getFnAttribute("stack-probe-size") 1851 .getValueAsString() 1852 .getAsInteger(0, CallerStackProbeSize); 1853 if (CallerStackProbeSize > CalleeStackProbeSize) { 1854 Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size")); 1855 } 1856 } else { 1857 Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size")); 1858 } 1859 } 1860 } 1861 1862 /// If the inlined function defines a min legal vector width, then ensure 1863 /// the calling function has the same or larger min legal vector width. If the 1864 /// caller has the attribute, but the callee doesn't, we need to remove the 1865 /// attribute from the caller since we can't make any guarantees about the 1866 /// caller's requirements. 1867 /// This function is called after the inlining decision has been made so we have 1868 /// to merge the attribute this way. Heuristics that would use 1869 /// min-legal-vector-width to determine inline compatibility would need to be 1870 /// handled as part of inline cost analysis. 1871 static void 1872 adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) { 1873 if (Caller.hasFnAttribute("min-legal-vector-width")) { 1874 if (Callee.hasFnAttribute("min-legal-vector-width")) { 1875 uint64_t CallerVectorWidth; 1876 Caller.getFnAttribute("min-legal-vector-width") 1877 .getValueAsString() 1878 .getAsInteger(0, CallerVectorWidth); 1879 uint64_t CalleeVectorWidth; 1880 Callee.getFnAttribute("min-legal-vector-width") 1881 .getValueAsString() 1882 .getAsInteger(0, CalleeVectorWidth); 1883 if (CallerVectorWidth < CalleeVectorWidth) 1884 Caller.addFnAttr(Callee.getFnAttribute("min-legal-vector-width")); 1885 } else { 1886 // If the callee doesn't have the attribute then we don't know anything 1887 // and must drop the attribute from the caller. 1888 Caller.removeFnAttr("min-legal-vector-width"); 1889 } 1890 } 1891 } 1892 1893 /// If the inlined function has "null-pointer-is-valid=true" attribute, 1894 /// set this attribute in the caller post inlining. 1895 static void 1896 adjustNullPointerValidAttr(Function &Caller, const Function &Callee) { 1897 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) { 1898 Caller.addFnAttr(Callee.getFnAttribute("null-pointer-is-valid")); 1899 } 1900 } 1901 1902 struct EnumAttr { 1903 static bool isSet(const Function &Fn, 1904 Attribute::AttrKind Kind) { 1905 return Fn.hasFnAttribute(Kind); 1906 } 1907 1908 static void set(Function &Fn, 1909 Attribute::AttrKind Kind, bool Val) { 1910 if (Val) 1911 Fn.addFnAttr(Kind); 1912 else 1913 Fn.removeFnAttr(Kind); 1914 } 1915 }; 1916 1917 struct StrBoolAttr { 1918 static bool isSet(const Function &Fn, 1919 StringRef Kind) { 1920 auto A = Fn.getFnAttribute(Kind); 1921 return A.getValueAsString().equals("true"); 1922 } 1923 1924 static void set(Function &Fn, 1925 StringRef Kind, bool Val) { 1926 Fn.addFnAttr(Kind, Val ? "true" : "false"); 1927 } 1928 }; 1929 1930 #define GET_ATTR_NAMES 1931 #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \ 1932 struct ENUM_NAME##Attr : EnumAttr { \ 1933 static enum Attribute::AttrKind getKind() { \ 1934 return llvm::Attribute::ENUM_NAME; \ 1935 } \ 1936 }; 1937 #define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME) \ 1938 struct ENUM_NAME##Attr : StrBoolAttr { \ 1939 static StringRef getKind() { return #DISPLAY_NAME; } \ 1940 }; 1941 #include "llvm/IR/Attributes.inc" 1942 1943 #define GET_ATTR_COMPAT_FUNC 1944 #include "llvm/IR/Attributes.inc" 1945 1946 bool AttributeFuncs::areInlineCompatible(const Function &Caller, 1947 const Function &Callee) { 1948 return hasCompatibleFnAttrs(Caller, Callee); 1949 } 1950 1951 void AttributeFuncs::mergeAttributesForInlining(Function &Caller, 1952 const Function &Callee) { 1953 mergeFnAttrs(Caller, Callee); 1954 } 1955