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