LCOV - code coverage report
Current view: top level - lib/IR - Attributes.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 742 781 95.0 %
Date: 2018-02-20 03:34:22 Functions: 147 156 94.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- Attributes.cpp - Implement AttributesList --------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // \file
      11             : // \brief This file implements the Attribute, AttributeImpl, AttrBuilder,
      12             : // AttributeListImpl, and AttributeList classes.
      13             : //
      14             : //===----------------------------------------------------------------------===//
      15             : 
      16             : #include "llvm/IR/Attributes.h"
      17             : #include "AttributeImpl.h"
      18             : #include "LLVMContextImpl.h"
      19             : #include "llvm/ADT/ArrayRef.h"
      20             : #include "llvm/ADT/FoldingSet.h"
      21             : #include "llvm/ADT/Optional.h"
      22             : #include "llvm/ADT/STLExtras.h"
      23             : #include "llvm/ADT/SmallVector.h"
      24             : #include "llvm/ADT/StringExtras.h"
      25             : #include "llvm/ADT/StringRef.h"
      26             : #include "llvm/ADT/Twine.h"
      27             : #include "llvm/IR/Function.h"
      28             : #include "llvm/IR/LLVMContext.h"
      29             : #include "llvm/IR/Type.h"
      30             : #include "llvm/Support/Compiler.h"
      31             : #include "llvm/Support/Debug.h"
      32             : #include "llvm/Support/ErrorHandling.h"
      33             : #include "llvm/Support/MathExtras.h"
      34             : #include "llvm/Support/raw_ostream.h"
      35             : #include <algorithm>
      36             : #include <cassert>
      37             : #include <climits>
      38             : #include <cstddef>
      39             : #include <cstdint>
      40             : #include <limits>
      41             : #include <map>
      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         160 :   return uint64_t(ElemSizeArg) << 32 |
      67         160 :          NumElemsArg.getValueOr(AllocSizeNumElemsNotPresent);
      68             : }
      69             : 
      70             : static std::pair<unsigned, Optional<unsigned>>
      71             : unpackAllocSizeArgs(uint64_t Num) {
      72         243 :   unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
      73         243 :   unsigned ElemSizeArg = Num >> 32;
      74             : 
      75             :   Optional<unsigned> NumElemsArg;
      76         243 :   if (NumElems != AllocSizeNumElemsNotPresent)
      77             :     NumElemsArg = NumElems;
      78             :   return std::make_pair(ElemSizeArg, NumElemsArg);
      79             : }
      80             : 
      81     3097017 : Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
      82             :                          uint64_t Val) {
      83     3097017 :   LLVMContextImpl *pImpl = Context.pImpl;
      84             :   FoldingSetNodeID ID;
      85     3097017 :   ID.AddInteger(Kind);
      86     3097017 :   if (Val) ID.AddInteger(Val);
      87             : 
      88             :   void *InsertPoint;
      89             :   AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
      90             : 
      91     2976661 :   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      120356 :     if (!Val)
      95      110767 :       PA = new EnumAttributeImpl(Kind);
      96             :     else
      97        9589 :       PA = new IntAttributeImpl(Kind, Val);
      98      120356 :     pImpl->AttrsSet.InsertNode(PA, InsertPoint);
      99             :   }
     100             : 
     101             :   // Return the Attribute that we found or created.
     102     6194034 :   return Attribute(PA);
     103             : }
     104             : 
     105    13983664 : Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
     106    13983664 :   LLVMContextImpl *pImpl = Context.pImpl;
     107             :   FoldingSetNodeID ID;
     108    13983664 :   ID.AddString(Kind);
     109    13983664 :   if (!Val.empty()) ID.AddString(Val);
     110             : 
     111             :   void *InsertPoint;
     112             :   AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
     113             : 
     114    13823957 :   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      159707 :     PA = new StringAttributeImpl(Kind, Val);
     118      159707 :     pImpl->AttrsSet.InsertNode(PA, InsertPoint);
     119             :   }
     120             : 
     121             :   // Return the Attribute that we found or created.
     122    27967328 :   return Attribute(PA);
     123             : }
     124             : 
     125      143808 : Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) {
     126             :   assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
     127             :   assert(Align <= 0x40000000 && "Alignment too large.");
     128      143808 :   return get(Context, Alignment, Align);
     129             : }
     130             : 
     131         204 : Attribute Attribute::getWithStackAlignment(LLVMContext &Context,
     132             :                                            uint64_t Align) {
     133             :   assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
     134             :   assert(Align <= 0x100 && "Alignment too large.");
     135         204 :   return get(Context, StackAlignment, Align);
     136             : }
     137             : 
     138      165242 : Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context,
     139             :                                                 uint64_t Bytes) {
     140             :   assert(Bytes && "Bytes must be non-zero.");
     141      165242 :   return get(Context, Dereferenceable, Bytes);
     142             : }
     143             : 
     144          83 : Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
     145             :                                                        uint64_t Bytes) {
     146             :   assert(Bytes && "Bytes must be non-zero.");
     147          83 :   return get(Context, DereferenceableOrNull, Bytes);
     148             : }
     149             : 
     150             : Attribute
     151         106 : Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
     152             :                                 const Optional<unsigned> &NumElemsArg) {
     153             :   assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
     154             :          "Invalid allocsize arguments -- given allocsize(0, 0)");
     155         106 :   return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
     156             : }
     157             : 
     158             : //===----------------------------------------------------------------------===//
     159             : // Attribute Accessor Methods
     160             : //===----------------------------------------------------------------------===//
     161             : 
     162       13863 : bool Attribute::isEnumAttribute() const {
     163       13863 :   return pImpl && pImpl->isEnumAttribute();
     164             : }
     165             : 
     166        8555 : bool Attribute::isIntAttribute() const {
     167        8555 :   return pImpl && pImpl->isIntAttribute();
     168             : }
     169             : 
     170   284801629 : bool Attribute::isStringAttribute() const {
     171   284801629 :   return pImpl && pImpl->isStringAttribute();
     172             : }
     173             : 
     174     3593183 : Attribute::AttrKind Attribute::getKindAsEnum() const {
     175     3593183 :   if (!pImpl) return None;
     176             :   assert((isEnumAttribute() || isIntAttribute()) &&
     177             :          "Invalid attribute type to get the kind as an enum!");
     178     3593183 :   return pImpl->getKindAsEnum();
     179             : }
     180             : 
     181       36924 : uint64_t Attribute::getValueAsInt() const {
     182       36924 :   if (!pImpl) return 0;
     183             :   assert(isIntAttribute() &&
     184             :          "Expected the attribute to be an integer attribute!");
     185       36924 :   return pImpl->getValueAsInt();
     186             : }
     187             : 
     188    11151416 : StringRef Attribute::getKindAsString() const {
     189    11151416 :   if (!pImpl) return StringRef();
     190             :   assert(isStringAttribute() &&
     191             :          "Invalid attribute type to get the kind as a string!");
     192    11151416 :   return pImpl->getKindAsString();
     193             : }
     194             : 
     195    25572389 : StringRef Attribute::getValueAsString() const {
     196    25572389 :   if (!pImpl) return StringRef();
     197             :   assert(isStringAttribute() &&
     198             :          "Invalid attribute type to get the value as a string!");
     199    20476212 :   return pImpl->getValueAsString();
     200             : }
     201             : 
     202    34847329 : bool Attribute::hasAttribute(AttrKind Kind) const {
     203    34847329 :   return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
     204             : }
     205             : 
     206   262534843 : bool Attribute::hasAttribute(StringRef Kind) const {
     207   262534843 :   if (!isStringAttribute()) return false;
     208   214611807 :   return pImpl && pImpl->hasAttribute(Kind);
     209             : }
     210             : 
     211      509190 : unsigned Attribute::getAlignment() const {
     212             :   assert(hasAttribute(Attribute::Alignment) &&
     213             :          "Trying to get alignment from non-alignment attribute!");
     214      509190 :   return pImpl->getValueAsInt();
     215             : }
     216             : 
     217         183 : unsigned Attribute::getStackAlignment() const {
     218             :   assert(hasAttribute(Attribute::StackAlignment) &&
     219             :          "Trying to get alignment from non-alignment attribute!");
     220         183 :   return pImpl->getValueAsInt();
     221             : }
     222             : 
     223       93758 : uint64_t Attribute::getDereferenceableBytes() const {
     224             :   assert(hasAttribute(Attribute::Dereferenceable) &&
     225             :          "Trying to get dereferenceable bytes from "
     226             :          "non-dereferenceable attribute!");
     227       93758 :   return pImpl->getValueAsInt();
     228             : }
     229             : 
     230          99 : uint64_t Attribute::getDereferenceableOrNullBytes() const {
     231             :   assert(hasAttribute(Attribute::DereferenceableOrNull) &&
     232             :          "Trying to get dereferenceable bytes from "
     233             :          "non-dereferenceable attribute!");
     234          99 :   return pImpl->getValueAsInt();
     235             : }
     236             : 
     237         138 : std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const {
     238             :   assert(hasAttribute(Attribute::AllocSize) &&
     239             :          "Trying to get allocsize args from non-allocsize attribute");
     240         276 :   return unpackAllocSizeArgs(pImpl->getValueAsInt());
     241             : }
     242             : 
     243      628093 : std::string Attribute::getAsString(bool InAttrGrp) const {
     244      628093 :   if (!pImpl) return "";
     245             : 
     246      628093 :   if (hasAttribute(Attribute::SanitizeAddress))
     247        1021 :     return "sanitize_address";
     248      627072 :   if (hasAttribute(Attribute::SanitizeHWAddress))
     249         116 :     return "sanitize_hwaddress";
     250      626956 :   if (hasAttribute(Attribute::AlwaysInline))
     251         798 :     return "alwaysinline";
     252      626158 :   if (hasAttribute(Attribute::ArgMemOnly))
     253        6225 :     return "argmemonly";
     254      619933 :   if (hasAttribute(Attribute::Builtin))
     255         339 :     return "builtin";
     256      619594 :   if (hasAttribute(Attribute::ByVal))
     257        1268 :     return "byval";
     258      618326 :   if (hasAttribute(Attribute::Convergent))
     259        1495 :     return "convergent";
     260      616831 :   if (hasAttribute(Attribute::SwiftError))
     261          63 :     return "swifterror";
     262      616768 :   if (hasAttribute(Attribute::SwiftSelf))
     263          46 :     return "swiftself";
     264      616722 :   if (hasAttribute(Attribute::InaccessibleMemOnly))
     265         124 :     return "inaccessiblememonly";
     266      616598 :   if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly))
     267          88 :     return "inaccessiblemem_or_argmemonly";
     268      616510 :   if (hasAttribute(Attribute::InAlloca))
     269         199 :     return "inalloca";
     270      616311 :   if (hasAttribute(Attribute::InlineHint))
     271        1101 :     return "inlinehint";
     272      615210 :   if (hasAttribute(Attribute::InReg))
     273         965 :     return "inreg";
     274      614245 :   if (hasAttribute(Attribute::JumpTable))
     275          26 :     return "jumptable";
     276      614219 :   if (hasAttribute(Attribute::MinSize))
     277         321 :     return "minsize";
     278      613898 :   if (hasAttribute(Attribute::Naked))
     279         100 :     return "naked";
     280      613798 :   if (hasAttribute(Attribute::Nest))
     281          38 :     return "nest";
     282      613760 :   if (hasAttribute(Attribute::NoAlias))
     283       15894 :     return "noalias";
     284      597866 :   if (hasAttribute(Attribute::NoBuiltin))
     285         880 :     return "nobuiltin";
     286      596986 :   if (hasAttribute(Attribute::NoCapture))
     287        9241 :     return "nocapture";
     288      587745 :   if (hasAttribute(Attribute::NoDuplicate))
     289          60 :     return "noduplicate";
     290      587685 :   if (hasAttribute(Attribute::NoImplicitFloat))
     291          77 :     return "noimplicitfloat";
     292      587608 :   if (hasAttribute(Attribute::NoInline))
     293       93179 :     return "noinline";
     294      494429 :   if (hasAttribute(Attribute::NonLazyBind))
     295         511 :     return "nonlazybind";
     296      493918 :   if (hasAttribute(Attribute::NonNull))
     297        2581 :     return "nonnull";
     298      491337 :   if (hasAttribute(Attribute::NoRedZone))
     299         159 :     return "noredzone";
     300      491178 :   if (hasAttribute(Attribute::NoReturn))
     301        1331 :     return "noreturn";
     302      489847 :   if (hasAttribute(Attribute::NoRecurse))
     303        6122 :     return "norecurse";
     304      483725 :   if (hasAttribute(Attribute::NoUnwind))
     305      144277 :     return "nounwind";
     306      339448 :   if (hasAttribute(Attribute::OptimizeNone))
     307       70319 :     return "optnone";
     308      269129 :   if (hasAttribute(Attribute::OptimizeForSize))
     309         784 :     return "optsize";
     310      268345 :   if (hasAttribute(Attribute::ReadNone))
     311       18252 :     return "readnone";
     312      250093 :   if (hasAttribute(Attribute::ReadOnly))
     313        5920 :     return "readonly";
     314      244173 :   if (hasAttribute(Attribute::WriteOnly))
     315        1884 :     return "writeonly";
     316      242289 :   if (hasAttribute(Attribute::Returned))
     317        1576 :     return "returned";
     318      240713 :   if (hasAttribute(Attribute::ReturnsTwice))
     319         122 :     return "returns_twice";
     320      240591 :   if (hasAttribute(Attribute::SExt))
     321        7909 :     return "signext";
     322      232682 :   if (hasAttribute(Attribute::Speculatable))
     323        4342 :     return "speculatable";
     324      228340 :   if (hasAttribute(Attribute::StackProtect))
     325        1305 :     return "ssp";
     326      227035 :   if (hasAttribute(Attribute::StackProtectReq))
     327          84 :     return "sspreq";
     328      226951 :   if (hasAttribute(Attribute::StackProtectStrong))
     329         106 :     return "sspstrong";
     330      226845 :   if (hasAttribute(Attribute::SafeStack))
     331         314 :     return "safestack";
     332      226531 :   if (hasAttribute(Attribute::StrictFP))
     333           9 :     return "strictfp";
     334      226522 :   if (hasAttribute(Attribute::StructRet))
     335        2359 :     return "sret";
     336      224163 :   if (hasAttribute(Attribute::SanitizeThread))
     337         153 :     return "sanitize_thread";
     338      224010 :   if (hasAttribute(Attribute::SanitizeMemory))
     339         586 :     return "sanitize_memory";
     340      223424 :   if (hasAttribute(Attribute::UWTable))
     341        3039 :     return "uwtable";
     342      220385 :   if (hasAttribute(Attribute::ZExt))
     343        6555 :     return "zeroext";
     344      213830 :   if (hasAttribute(Attribute::Cold))
     345          72 :     return "cold";
     346             : 
     347             :   // FIXME: These should be output like this:
     348             :   //
     349             :   //   align=4
     350             :   //   alignstack=8
     351             :   //
     352      213758 :   if (hasAttribute(Attribute::Alignment)) {
     353             :     std::string Result;
     354             :     Result += "align";
     355       19639 :     Result += (InAttrGrp) ? "=" : " ";
     356       39278 :     Result += utostr(getValueAsInt());
     357             :     return Result;
     358             :   }
     359             : 
     360       16494 :   auto AttrWithBytesToString = [&](const char *Name) {
     361             :     std::string Result;
     362             :     Result += Name;
     363       16494 :     if (InAttrGrp) {
     364             :       Result += "=";
     365       16532 :       Result += utostr(getValueAsInt());
     366             :     } else {
     367             :       Result += "(";
     368       32912 :       Result += utostr(getValueAsInt());
     369             :       Result += ")";
     370             :     }
     371       16494 :     return Result;
     372      194119 :   };
     373             : 
     374      194119 :   if (hasAttribute(Attribute::StackAlignment))
     375          76 :     return AttrWithBytesToString("alignstack");
     376             : 
     377      194043 :   if (hasAttribute(Attribute::Dereferenceable))
     378       16369 :     return AttrWithBytesToString("dereferenceable");
     379             : 
     380      177674 :   if (hasAttribute(Attribute::DereferenceableOrNull))
     381          49 :     return AttrWithBytesToString("dereferenceable_or_null");
     382             : 
     383      177625 :   if (hasAttribute(Attribute::AllocSize)) {
     384             :     unsigned ElemSize;
     385             :     Optional<unsigned> NumElems;
     386          82 :     std::tie(ElemSize, NumElems) = getAllocSizeArgs();
     387             : 
     388          41 :     std::string Result = "allocsize(";
     389          82 :     Result += utostr(ElemSize);
     390          41 :     if (NumElems.hasValue()) {
     391             :       Result += ',';
     392          40 :       Result += utostr(*NumElems);
     393             :     }
     394             :     Result += ')';
     395             :     return Result;
     396             :   }
     397             : 
     398             :   // Convert target-dependent attributes to strings of the form:
     399             :   //
     400             :   //   "kind"
     401             :   //   "kind" = "value"
     402             :   //
     403      177584 :   if (isStringAttribute()) {
     404             :     std::string Result;
     405      532752 :     Result += (Twine('"') + getKindAsString() + Twine('"')).str();
     406             : 
     407      355168 :     std::string AttrVal = pImpl->getValueAsString();
     408      177584 :     if (AttrVal.empty()) return Result;
     409             : 
     410             :     // Since some attribute strings contain special characters that cannot be
     411             :     // printable, those have to be escaped to make the attribute value printable
     412             :     // as is.  e.g. "\01__gnu_mcount_nc"
     413             :     {
     414      175760 :       raw_string_ostream OS(Result);
     415      175760 :       OS << "=\"";
     416      175760 :       PrintEscapedString(AttrVal, OS);
     417      175760 :       OS << "\"";
     418             :     }
     419             :     return Result;
     420             :   }
     421             : 
     422           0 :   llvm_unreachable("Unknown attribute");
     423             : }
     424             : 
     425    29687865 : bool Attribute::operator<(Attribute A) const {
     426    29687865 :   if (!pImpl && !A.pImpl) return false;
     427    29687865 :   if (!pImpl) return true;
     428    29687865 :   if (!A.pImpl) return false;
     429    29687865 :   return *pImpl < *A.pImpl;
     430             : }
     431             : 
     432             : //===----------------------------------------------------------------------===//
     433             : // AttributeImpl Definition
     434             : //===----------------------------------------------------------------------===//
     435             : 
     436             : // Pin the vtables to this file.
     437             : AttributeImpl::~AttributeImpl() = default;
     438             : 
     439           0 : void EnumAttributeImpl::anchor() {}
     440             : 
     441           0 : void IntAttributeImpl::anchor() {}
     442             : 
     443           0 : void StringAttributeImpl::anchor() {}
     444             : 
     445    30246599 : bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
     446    30246599 :   if (isStringAttribute()) return false;
     447    14983548 :   return getKindAsEnum() == A;
     448             : }
     449             : 
     450   214611807 : bool AttributeImpl::hasAttribute(StringRef Kind) const {
     451   214611807 :   if (!isStringAttribute()) return false;
     452   214611807 :   return getKindAsString() == Kind;
     453             : }
     454             : 
     455    28212946 : Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
     456             :   assert(isEnumAttribute() || isIntAttribute());
     457    28212946 :   return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
     458             : }
     459             : 
     460     2480328 : uint64_t AttributeImpl::getValueAsInt() const {
     461             :   assert(isIntAttribute());
     462     2480328 :   return static_cast<const IntAttributeImpl *>(this)->getValue();
     463             : }
     464             : 
     465   314191391 : StringRef AttributeImpl::getKindAsString() const {
     466             :   assert(isStringAttribute());
     467   314191391 :   return static_cast<const StringAttributeImpl *>(this)->getStringKind();
     468             : }
     469             : 
     470    34772660 : StringRef AttributeImpl::getValueAsString() const {
     471             :   assert(isStringAttribute());
     472    34772660 :   return static_cast<const StringAttributeImpl *>(this)->getStringValue();
     473             : }
     474             : 
     475    29687865 : bool AttributeImpl::operator<(const AttributeImpl &AI) const {
     476             :   // This sorts the attributes with Attribute::AttrKinds coming first (sorted
     477             :   // relative to their enum value) and then strings.
     478    29687865 :   if (isEnumAttribute()) {
     479     2025122 :     if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
     480      436995 :     if (AI.isIntAttribute()) return true;
     481      401084 :     if (AI.isStringAttribute()) return true;
     482             :   }
     483             : 
     484    27662743 :   if (isIntAttribute()) {
     485         264 :     if (AI.isEnumAttribute()) return false;
     486         145 :     if (AI.isIntAttribute()) {
     487         115 :       if (getKindAsEnum() == AI.getKindAsEnum())
     488           1 :         return getValueAsInt() < AI.getValueAsInt();
     489         114 :       return getKindAsEnum() < AI.getKindAsEnum();
     490             :     }
     491          30 :     if (AI.isStringAttribute()) return true;
     492             :   }
     493             : 
     494    27662479 :   if (AI.isEnumAttribute()) return false;
     495    18577685 :   if (AI.isIntAttribute()) return false;
     496    18577378 :   if (getKindAsString() == AI.getKindAsString())
     497          52 :     return getValueAsString() < AI.getValueAsString();
     498    18577326 :   return getKindAsString() < AI.getKindAsString();
     499             : }
     500             : 
     501             : //===----------------------------------------------------------------------===//
     502             : // AttributeSet Definition
     503             : //===----------------------------------------------------------------------===//
     504             : 
     505     4513601 : AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) {
     506     4513601 :   return AttributeSet(AttributeSetNode::get(C, B));
     507             : }
     508             : 
     509      142263 : AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
     510      142263 :   return AttributeSet(AttributeSetNode::get(C, Attrs));
     511             : }
     512             : 
     513           0 : AttributeSet AttributeSet::addAttribute(LLVMContext &C,
     514             :                                         Attribute::AttrKind Kind) const {
     515           0 :   if (hasAttribute(Kind)) return *this;
     516             :   AttrBuilder B;
     517           0 :   B.addAttribute(Kind);
     518           0 :   return addAttributes(C, AttributeSet::get(C, B));
     519             : }
     520             : 
     521          44 : AttributeSet AttributeSet::addAttribute(LLVMContext &C, StringRef Kind,
     522             :                                         StringRef Value) const {
     523             :   AttrBuilder B;
     524          44 :   B.addAttribute(Kind, Value);
     525          88 :   return addAttributes(C, AttributeSet::get(C, B));
     526             : }
     527             : 
     528          44 : AttributeSet AttributeSet::addAttributes(LLVMContext &C,
     529             :                                          const AttributeSet AS) const {
     530          44 :   if (!hasAttributes())
     531          19 :     return AS;
     532             : 
     533          25 :   if (!AS.hasAttributes())
     534           0 :     return *this;
     535             : 
     536          25 :   AttrBuilder B(AS);
     537          59 :   for (Attribute I : *this)
     538          34 :     B.addAttribute(I);
     539             : 
     540          25 :  return get(C, B);
     541             : }
     542             : 
     543       13733 : AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
     544             :                                              Attribute::AttrKind Kind) const {
     545       13733 :   if (!hasAttribute(Kind)) return *this;
     546       13733 :   AttrBuilder B(*this);
     547       13733 :   B.removeAttribute(Kind);
     548       13733 :   return get(C, B);
     549             : }
     550             : 
     551      225304 : AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
     552             :                                              StringRef Kind) const {
     553      225304 :   if (!hasAttribute(Kind)) return *this;
     554      225304 :   AttrBuilder B(*this);
     555      225304 :   B.removeAttribute(Kind);
     556      225304 :   return get(C, B);
     557             : }
     558             : 
     559       10207 : AttributeSet AttributeSet::removeAttributes(LLVMContext &C,
     560             :                                               const AttrBuilder &Attrs) const {
     561       10207 :   AttrBuilder B(*this);
     562       10207 :   B.remove(Attrs);
     563       20414 :   return get(C, B);
     564             : }
     565             : 
     566           4 : unsigned AttributeSet::getNumAttributes() const {
     567           4 :   return SetNode ? SetNode->getNumAttributes() : 0;
     568             : }
     569             : 
     570   359360040 : bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const {
     571   564078032 :   return SetNode ? SetNode->hasAttribute(Kind) : false;
     572             : }
     573             : 
     574    20492245 : bool AttributeSet::hasAttribute(StringRef Kind) const {
     575    20492245 :   return SetNode ? SetNode->hasAttribute(Kind) : false;
     576             : }
     577             : 
     578     3662743 : Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const {
     579     3662743 :   return SetNode ? SetNode->getAttribute(Kind) : Attribute();
     580             : }
     581             : 
     582    19819692 : Attribute AttributeSet::getAttribute(StringRef Kind) const {
     583    19819692 :   return SetNode ? SetNode->getAttribute(Kind) : Attribute();
     584             : }
     585             : 
     586     2075691 : unsigned AttributeSet::getAlignment() const {
     587     2075691 :   return SetNode ? SetNode->getAlignment() : 0;
     588             : }
     589             : 
     590          63 : unsigned AttributeSet::getStackAlignment() const {
     591          63 :   return SetNode ? SetNode->getStackAlignment() : 0;
     592             : }
     593             : 
     594     1363897 : uint64_t AttributeSet::getDereferenceableBytes() const {
     595     1363897 :   return SetNode ? SetNode->getDereferenceableBytes() : 0;
     596             : }
     597             : 
     598       55908 : uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
     599       55908 :   return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
     600             : }
     601             : 
     602          79 : std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const {
     603          79 :   return SetNode ? SetNode->getAllocSizeArgs()
     604         158 :                  : std::pair<unsigned, Optional<unsigned>>(0, 0);
     605             : }
     606             : 
     607      108420 : std::string AttributeSet::getAsString(bool InAttrGrp) const {
     608      108420 :   return SetNode ? SetNode->getAsString(InAttrGrp) : "";
     609             : }
     610             : 
     611     3858057 : AttributeSet::iterator AttributeSet::begin() const {
     612     7716114 :   return SetNode ? SetNode->begin() : nullptr;
     613             : }
     614             : 
     615     3858057 : AttributeSet::iterator AttributeSet::end() const {
     616     7716114 :   return SetNode ? SetNode->end() : nullptr;
     617             : }
     618             : 
     619             : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
     620             : LLVM_DUMP_METHOD void AttributeSet::dump() const {
     621             :   dbgs() << "AS =\n";
     622             :     dbgs() << "  { ";
     623             :     dbgs() << getAsString(true) << " }\n";
     624             : }
     625             : #endif
     626             : 
     627             : //===----------------------------------------------------------------------===//
     628             : // AttributeSetNode Definition
     629             : //===----------------------------------------------------------------------===//
     630             : 
     631      183431 : AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
     632      183431 :     : AvailableAttrs(0), NumAttrs(Attrs.size()) {
     633             :   // There's memory after the node where we can store the entries in.
     634             :   std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>());
     635             : 
     636     2802097 :   for (Attribute I : *this) {
     637     1309333 :     if (!I.isStringAttribute()) {
     638      251055 :       AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum();
     639             :     }
     640             :   }
     641      183431 : }
     642             : 
     643     4655865 : AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
     644             :                                         ArrayRef<Attribute> Attrs) {
     645     4655865 :   if (Attrs.empty())
     646             :     return nullptr;
     647             : 
     648             :   // Otherwise, build a key to look up the existing attributes.
     649     2487622 :   LLVMContextImpl *pImpl = C.pImpl;
     650             :   FoldingSetNodeID ID;
     651             : 
     652             :   SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
     653             :   std::sort(SortedAttrs.begin(), SortedAttrs.end());
     654             : 
     655    35813788 :   for (Attribute Attr : SortedAttrs)
     656             :     Attr.Profile(ID);
     657             : 
     658             :   void *InsertPoint;
     659             :   AttributeSetNode *PA =
     660             :     pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
     661             : 
     662             :   // If we didn't find any existing attributes of the same shape then create a
     663             :   // new one and insert it.
     664     2487622 :   if (!PA) {
     665             :     // Coallocate entries after the AttributeSetNode itself.
     666      183431 :     void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
     667      183431 :     PA = new (Mem) AttributeSetNode(SortedAttrs);
     668      183431 :     pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
     669             :   }
     670             : 
     671             :   // Return the AttributeSetNode that we found or created.
     672             :   return PA;
     673             : }
     674             : 
     675     4513601 : AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
     676             :   // Add target-independent attributes.
     677             :   SmallVector<Attribute, 8> Attrs;
     678   252761656 :   for (Attribute::AttrKind Kind = Attribute::None;
     679   510036913 :        Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) {
     680   252761656 :     if (!B.contains(Kind))
     681   250185357 :       continue;
     682             : 
     683     2576299 :     Attribute Attr;
     684     2576299 :     switch (Kind) {
     685       76722 :     case Attribute::Alignment:
     686       76722 :       Attr = Attribute::getWithAlignment(C, B.getAlignment());
     687       76722 :       break;
     688         203 :     case Attribute::StackAlignment:
     689         203 :       Attr = Attribute::getWithStackAlignment(C, B.getStackAlignment());
     690         203 :       break;
     691      165242 :     case Attribute::Dereferenceable:
     692      165242 :       Attr = Attribute::getWithDereferenceableBytes(
     693      165242 :           C, B.getDereferenceableBytes());
     694      165242 :       break;
     695          83 :     case Attribute::DereferenceableOrNull:
     696          83 :       Attr = Attribute::getWithDereferenceableOrNullBytes(
     697          83 :           C, B.getDereferenceableOrNullBytes());
     698          83 :       break;
     699         105 :     case Attribute::AllocSize: {
     700         105 :       auto A = B.getAllocSizeArgs();
     701         105 :       Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
     702             :       break;
     703             :     }
     704     2333944 :     default:
     705     2333944 :       Attr = Attribute::get(C, Kind);
     706             :     }
     707     2576299 :     Attrs.push_back(Attr);
     708             :   }
     709             : 
     710             :   // Add target-dependent (string) attributes.
     711    18324897 :   for (const auto &TDA : B.td_attrs())
     712    13811296 :     Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second));
     713             : 
     714     9027202 :   return get(C, Attrs);
     715             : }
     716             : 
     717    18849311 : bool AttributeSetNode::hasAttribute(StringRef Kind) const {
     718   311164273 :   for (Attribute I : *this)
     719   146846692 :     if (I.hasAttribute(Kind))
     720      689213 :       return true;
     721    18160100 :   return false;
     722             : }
     723             : 
     724     3649339 : Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
     725     7298678 :   if (hasAttribute(Kind)) {
     726         203 :     for (Attribute I : *this)
     727         159 :       if (I.hasAttribute(Kind))
     728         115 :         return I;
     729             :   }
     730     3649224 :   return Attribute();
     731             : }
     732             : 
     733    18613953 : Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
     734   230983521 :   for (Attribute I : *this)
     735   115688138 :     if (I.hasAttribute(Kind))
     736     9503354 :       return I;
     737     9110599 :   return Attribute();
     738             : }
     739             : 
     740      738350 : unsigned AttributeSetNode::getAlignment() const {
     741     1727046 :   for (Attribute I : *this)
     742      890605 :     if (I.hasAttribute(Attribute::Alignment))
     743      396257 :       return I.getAlignment();
     744      342093 :   return 0;
     745             : }
     746             : 
     747          63 : unsigned AttributeSetNode::getStackAlignment() const {
     748         105 :   for (Attribute I : *this)
     749          84 :     if (I.hasAttribute(Attribute::StackAlignment))
     750          63 :       return I.getStackAlignment();
     751           0 :   return 0;
     752             : }
     753             : 
     754      366196 : uint64_t AttributeSetNode::getDereferenceableBytes() const {
     755     1157196 :   for (Attribute I : *this)
     756      442523 :     if (I.hasAttribute(Attribute::Dereferenceable))
     757       47023 :       return I.getDereferenceableBytes();
     758      319173 :   return 0;
     759             : }
     760             : 
     761        7301 : uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
     762       29615 :   for (Attribute I : *this)
     763       11174 :     if (I.hasAttribute(Attribute::DereferenceableOrNull))
     764          17 :       return I.getDereferenceableOrNullBytes();
     765        7284 :   return 0;
     766             : }
     767             : 
     768             : std::pair<unsigned, Optional<unsigned>>
     769          79 : AttributeSetNode::getAllocSizeArgs() const {
     770          79 :   for (Attribute I : *this)
     771          79 :     if (I.hasAttribute(Attribute::AllocSize))
     772          79 :       return I.getAllocSizeArgs();
     773             :   return std::make_pair(0, 0);
     774             : }
     775             : 
     776      108420 : std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
     777             :   std::string Str;
     778      753230 :   for (iterator I = begin(), E = end(); I != E; ++I) {
     779      322405 :     if (I != begin())
     780             :       Str += ' ';
     781      644810 :     Str += I->getAsString(InAttrGrp);
     782             :   }
     783      108420 :   return Str;
     784             : }
     785             : 
     786             : //===----------------------------------------------------------------------===//
     787             : // AttributeListImpl Definition
     788             : //===----------------------------------------------------------------------===//
     789             : 
     790             : /// Map from AttributeList index to the internal array index. Adding one happens
     791             : /// to work, but it relies on unsigned integer wrapping. MSVC warns about
     792             : /// unsigned wrapping in constexpr functions, so write out the conditional. LLVM
     793             : /// folds it to add anyway.
     794             : static constexpr unsigned attrIdxToArrayIdx(unsigned Index) {
     795   394712035 :   return Index == AttributeList::FunctionIndex ? 0 : Index + 1;
     796             : }
     797             : 
     798      307752 : AttributeListImpl::AttributeListImpl(LLVMContext &C,
     799      307752 :                                      ArrayRef<AttributeSet> Sets)
     800      307752 :     : AvailableFunctionAttrs(0), Context(C), NumAttrSets(Sets.size()) {
     801             :   assert(!Sets.empty() && "pointless AttributeListImpl");
     802             : 
     803             :   // There's memory after the node where we can store the entries in.
     804             :   std::copy(Sets.begin(), Sets.end(), getTrailingObjects<AttributeSet>());
     805             : 
     806             :   // Initialize AvailableFunctionAttrs summary bitset.
     807             :   static_assert(Attribute::EndAttrKinds <=
     808             :                     sizeof(AvailableFunctionAttrs) * CHAR_BIT,
     809             :                 "Too many attributes");
     810             :   static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U,
     811             :                 "function should be stored in slot 0");
     812     2949361 :   for (Attribute I : Sets[0]) {
     813     2641609 :     if (!I.isStringAttribute())
     814      348125 :       AvailableFunctionAttrs |= 1ULL << I.getKindAsEnum();
     815             :   }
     816      307752 : }
     817             : 
     818     2733449 : void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
     819     2733449 :   Profile(ID, makeArrayRef(begin(), end()));
     820     2733449 : }
     821             : 
     822     5006505 : void AttributeListImpl::Profile(FoldingSetNodeID &ID,
     823             :                                 ArrayRef<AttributeSet> Sets) {
     824    26128229 :   for (const auto &Set : Sets)
     825    10560862 :     ID.AddPointer(Set.SetNode);
     826     5006505 : }
     827             : 
     828             : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
     829             : LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
     830             :   AttributeList(const_cast<AttributeListImpl *>(this)).dump();
     831             : }
     832             : #endif
     833             : 
     834             : //===----------------------------------------------------------------------===//
     835             : // AttributeList Construction and Mutation Methods
     836             : //===----------------------------------------------------------------------===//
     837             : 
     838     2273056 : AttributeList AttributeList::getImpl(LLVMContext &C,
     839             :                                      ArrayRef<AttributeSet> AttrSets) {
     840             :   assert(!AttrSets.empty() && "pointless AttributeListImpl");
     841             : 
     842     2273056 :   LLVMContextImpl *pImpl = C.pImpl;
     843             :   FoldingSetNodeID ID;
     844     2273056 :   AttributeListImpl::Profile(ID, AttrSets);
     845             : 
     846             :   void *InsertPoint;
     847             :   AttributeListImpl *PA =
     848             :       pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
     849             : 
     850             :   // If we didn't find any existing attributes of the same shape then
     851             :   // create a new one and insert it.
     852     2273056 :   if (!PA) {
     853             :     // Coallocate entries after the AttributeListImpl itself.
     854             :     void *Mem = ::operator new(
     855      307752 :         AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()));
     856      307752 :     PA = new (Mem) AttributeListImpl(C, AttrSets);
     857      307752 :     pImpl->AttrsLists.InsertNode(PA, InsertPoint);
     858             :   }
     859             : 
     860             :   // Return the AttributesList that we found or created.
     861     4546112 :   return AttributeList(PA);
     862             : }
     863             : 
     864             : AttributeList
     865      405568 : AttributeList::get(LLVMContext &C,
     866             :                    ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
     867             :   // If there are no attributes then return a null AttributesList pointer.
     868      405568 :   if (Attrs.empty())
     869      263304 :     return AttributeList();
     870             : 
     871             :   assert(std::is_sorted(Attrs.begin(), Attrs.end(),
     872             :                         [](const std::pair<unsigned, Attribute> &LHS,
     873             :                            const std::pair<unsigned, Attribute> &RHS) {
     874             :                           return LHS.first < RHS.first;
     875             :                         }) && "Misordered Attributes list!");
     876             :   assert(none_of(Attrs,
     877             :                  [](const std::pair<unsigned, Attribute> &Pair) {
     878             :                    return Pair.second.hasAttribute(Attribute::None);
     879             :                  }) &&
     880             :          "Pointless attribute!");
     881             : 
     882             :   // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
     883             :   // list.
     884             :   SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec;
     885      142263 :   for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
     886      284527 :          E = Attrs.end(); I != E; ) {
     887      142264 :     unsigned Index = I->first;
     888             :     SmallVector<Attribute, 4> AttrVec;
     889      693240 :     while (I != E && I->first == Index) {
     890      275488 :       AttrVec.push_back(I->second);
     891      275488 :       ++I;
     892             :     }
     893             : 
     894      142264 :     AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
     895             :   }
     896             : 
     897      142263 :   return get(C, AttrPairVec);
     898             : }
     899             : 
     900             : AttributeList
     901      390340 : AttributeList::get(LLVMContext &C,
     902             :                    ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
     903             :   // If there are no attributes then return a null AttributesList pointer.
     904      390340 :   if (Attrs.empty())
     905           0 :     return AttributeList();
     906             : 
     907             :   assert(std::is_sorted(Attrs.begin(), Attrs.end(),
     908             :                         [](const std::pair<unsigned, AttributeSet> &LHS,
     909             :                            const std::pair<unsigned, AttributeSet> &RHS) {
     910             :                           return LHS.first < RHS.first;
     911             :                         }) &&
     912             :          "Misordered Attributes list!");
     913             :   assert(none_of(Attrs,
     914             :                  [](const std::pair<unsigned, AttributeSet> &Pair) {
     915             :                    return !Pair.second.hasAttributes();
     916             :                  }) &&
     917             :          "Pointless attribute!");
     918             : 
     919      390340 :   unsigned MaxIndex = Attrs.back().first;
     920             : 
     921     1171021 :   SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
     922     1171021 :   for (auto Pair : Attrs)
     923      780680 :     AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;
     924             : 
     925      390341 :   return getImpl(C, AttrVec);
     926             : }
     927             : 
     928      849785 : AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs,
     929             :                                  AttributeSet RetAttrs,
     930             :                                  ArrayRef<AttributeSet> ArgAttrs) {
     931             :   // Scan from the end to find the last argument with attributes.  Most
     932             :   // arguments don't have attributes, so it's nice if we can have fewer unique
     933             :   // AttributeListImpls by dropping empty attribute sets at the end of the list.
     934             :   unsigned NumSets = 0;
     935     2015326 :   for (size_t I = ArgAttrs.size(); I != 0; --I) {
     936     2594648 :     if (ArgAttrs[I - 1].hasAttributes()) {
     937      131783 :       NumSets = I + 2;
     938      131783 :       break;
     939             :     }
     940             :   }
     941      849785 :   if (NumSets == 0) {
     942             :     // Check function and return attributes if we didn't have argument
     943             :     // attributes.
     944      718002 :     if (RetAttrs.hasAttributes())
     945             :       NumSets = 2;
     946      687010 :     else if (FnAttrs.hasAttributes())
     947             :       NumSets = 1;
     948             :   }
     949             : 
     950             :   // If all attribute sets were empty, we can use the empty attribute list.
     951      489728 :   if (NumSets == 0)
     952      357945 :     return AttributeList();
     953             : 
     954             :   SmallVector<AttributeSet, 8> AttrSets;
     955      491840 :   AttrSets.reserve(NumSets);
     956             :   // If we have any attributes, we always have function attributes.
     957      491840 :   AttrSets.push_back(FnAttrs);
     958      491840 :   if (NumSets > 1)
     959      162775 :     AttrSets.push_back(RetAttrs);
     960      491840 :   if (NumSets > 2) {
     961             :     // Drop the empty argument attribute sets at the end.
     962      131783 :     ArgAttrs = ArgAttrs.take_front(NumSets - 2);
     963      131783 :     AttrSets.insert(AttrSets.end(), ArgAttrs.begin(), ArgAttrs.end());
     964             :   }
     965             : 
     966      491840 :   return getImpl(C, AttrSets);
     967             : }
     968             : 
     969        5468 : AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
     970             :                                  const AttrBuilder &B) {
     971        5468 :   if (!B.hasAttributes())
     972          38 :     return AttributeList();
     973             :   Index = attrIdxToArrayIdx(Index);
     974       10860 :   SmallVector<AttributeSet, 8> AttrSets(Index + 1);
     975       10860 :   AttrSets[Index] = AttributeSet::get(C, B);
     976        5430 :   return getImpl(C, AttrSets);
     977             : }
     978             : 
     979      405568 : AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
     980             :                                  ArrayRef<Attribute::AttrKind> Kinds) {
     981             :   SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
     982      956544 :   for (Attribute::AttrKind K : Kinds)
     983      275488 :     Attrs.emplace_back(Index, Attribute::get(C, K));
     984      811136 :   return get(C, Attrs);
     985             : }
     986             : 
     987           0 : AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
     988             :                                  ArrayRef<StringRef> Kinds) {
     989             :   SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
     990           0 :   for (StringRef K : Kinds)
     991           0 :     Attrs.emplace_back(Index, Attribute::get(C, K));
     992           0 :   return get(C, Attrs);
     993             : }
     994             : 
     995      120017 : AttributeList AttributeList::get(LLVMContext &C,
     996             :                                  ArrayRef<AttributeList> Attrs) {
     997      120017 :   if (Attrs.empty())
     998           0 :     return AttributeList();
     999      120017 :   if (Attrs.size() == 1)
    1000      109528 :     return Attrs[0];
    1001             : 
    1002       10489 :   unsigned MaxSize = 0;
    1003       63197 :   for (AttributeList List : Attrs)
    1004       52708 :     MaxSize = std::max(MaxSize, List.getNumAttrSets());
    1005             : 
    1006             :   // If every list was empty, there is no point in merging the lists.
    1007       10489 :   if (MaxSize == 0)
    1008           1 :     return AttributeList();
    1009             : 
    1010       20976 :   SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
    1011       97496 :   for (unsigned I = 0; I < MaxSize; ++I) {
    1012             :     AttrBuilder CurBuilder;
    1013      270756 :     for (AttributeList List : Attrs)
    1014      227252 :       CurBuilder.merge(List.getAttributes(I - 1));
    1015       87008 :     NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
    1016             :   }
    1017             : 
    1018       10488 :   return getImpl(C, NewAttrSets);
    1019             : }
    1020             : 
    1021      321561 : AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
    1022             :                                           Attribute::AttrKind Kind) const {
    1023      321561 :   if (hasAttribute(Index, Kind)) return *this;
    1024             :   AttrBuilder B;
    1025      259551 :   B.addAttribute(Kind);
    1026      259551 :   return addAttributes(C, Index, B);
    1027             : }
    1028             : 
    1029          40 : AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
    1030             :                                           StringRef Kind,
    1031             :                                           StringRef Value) const {
    1032             :   AttrBuilder B;
    1033          40 :   B.addAttribute(Kind, Value);
    1034          80 :   return addAttributes(C, Index, B);
    1035             : }
    1036             : 
    1037      172474 : AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
    1038             :                                           Attribute A) const {
    1039             :   AttrBuilder B;
    1040      172474 :   B.addAttribute(A);
    1041      344948 :   return addAttributes(C, Index, B);
    1042             : }
    1043             : 
    1044     1403142 : AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
    1045             :                                            const AttrBuilder &B) const {
    1046     1403142 :   if (!B.hasAttributes())
    1047      374723 :     return *this;
    1048             : 
    1049     1028419 :   if (!pImpl)
    1050      496106 :     return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
    1051             : 
    1052             : #ifndef NDEBUG
    1053             :   // FIXME it is not obvious how this should work for alignment. For now, say
    1054             :   // we can't change a known alignment.
    1055             :   unsigned OldAlign = getAttributes(Index).getAlignment();
    1056             :   unsigned NewAlign = B.getAlignment();
    1057             :   assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
    1058             :          "Attempt to change alignment!");
    1059             : #endif
    1060             : 
    1061             :   Index = attrIdxToArrayIdx(Index);
    1062      780366 :   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
    1063     1560732 :   if (Index >= AttrSets.size())
    1064       14203 :     AttrSets.resize(Index + 1);
    1065             : 
    1066      780366 :   AttrBuilder Merged(AttrSets[Index]);
    1067      780366 :   Merged.merge(B);
    1068      780366 :   AttrSets[Index] = AttributeSet::get(C, Merged);
    1069             : 
    1070      780366 :   return getImpl(C, AttrSets);
    1071             : }
    1072             : 
    1073      245149 : AttributeList AttributeList::addParamAttribute(LLVMContext &C,
    1074             :                                                ArrayRef<unsigned> ArgNos,
    1075             :                                                Attribute A) const {
    1076             :   assert(std::is_sorted(ArgNos.begin(), ArgNos.end()));
    1077             : 
    1078      245149 :   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
    1079      245149 :   unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
    1080      490298 :   if (MaxIndex >= AttrSets.size())
    1081      201334 :     AttrSets.resize(MaxIndex + 1);
    1082             : 
    1083      775909 :   for (unsigned ArgNo : ArgNos) {
    1084      265380 :     unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
    1085      530760 :     AttrBuilder B(AttrSets[Index]);
    1086      265380 :     B.addAttribute(A);
    1087      265380 :     AttrSets[Index] = AttributeSet::get(C, B);
    1088             :   }
    1089             : 
    1090      490298 :   return getImpl(C, AttrSets);
    1091             : }
    1092             : 
    1093      278185 : AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
    1094             :                                              Attribute::AttrKind Kind) const {
    1095      278185 :   if (!hasAttribute(Index, Kind)) return *this;
    1096             : 
    1097             :   Index = attrIdxToArrayIdx(Index);
    1098       13732 :   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
    1099             :   assert(Index < AttrSets.size());
    1100             : 
    1101       27464 :   AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
    1102             : 
    1103       13732 :   return getImpl(C, AttrSets);
    1104             : }
    1105             : 
    1106      313474 : AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
    1107             :                                              StringRef Kind) const {
    1108      313474 :   if (!hasAttribute(Index, Kind)) return *this;
    1109             : 
    1110             :   Index = attrIdxToArrayIdx(Index);
    1111      225304 :   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
    1112             :   assert(Index < AttrSets.size());
    1113             : 
    1114      450608 :   AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
    1115             : 
    1116      225304 :   return getImpl(C, AttrSets);
    1117             : }
    1118             : 
    1119             : AttributeList
    1120       10378 : AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
    1121             :                                 const AttrBuilder &AttrsToRemove) const {
    1122       10378 :   if (!pImpl)
    1123         172 :     return AttributeList();
    1124             : 
    1125             :   Index = attrIdxToArrayIdx(Index);
    1126       10206 :   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
    1127       20412 :   if (Index >= AttrSets.size())
    1128          44 :     AttrSets.resize(Index + 1);
    1129             : 
    1130       10206 :   AttrSets[Index] = AttrSets[Index].removeAttributes(C, AttrsToRemove);
    1131             : 
    1132       10206 :   return getImpl(C, AttrSets);
    1133             : }
    1134             : 
    1135      387703 : AttributeList AttributeList::removeAttributes(LLVMContext &C,
    1136             :                                               unsigned WithoutIndex) const {
    1137      387703 :   if (!pImpl)
    1138      287503 :     return AttributeList();
    1139             :   WithoutIndex = attrIdxToArrayIdx(WithoutIndex);
    1140      100200 :   if (WithoutIndex >= getNumAttrSets())
    1141           0 :     return *this;
    1142      100200 :   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
    1143      200400 :   AttrSets[WithoutIndex] = AttributeSet();
    1144      100200 :   return getImpl(C, AttrSets);
    1145             : }
    1146             : 
    1147          66 : AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C,
    1148             :                                                     unsigned Index,
    1149             :                                                     uint64_t Bytes) const {
    1150             :   AttrBuilder B;
    1151          66 :   B.addDereferenceableAttr(Bytes);
    1152         132 :   return addAttributes(C, Index, B);
    1153             : }
    1154             : 
    1155             : AttributeList
    1156           0 : AttributeList::addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index,
    1157             :                                             uint64_t Bytes) const {
    1158             :   AttrBuilder B;
    1159           0 :   B.addDereferenceableOrNullAttr(Bytes);
    1160           0 :   return addAttributes(C, Index, B);
    1161             : }
    1162             : 
    1163             : AttributeList
    1164           0 : AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index,
    1165             :                                 unsigned ElemSizeArg,
    1166             :                                 const Optional<unsigned> &NumElemsArg) {
    1167             :   AttrBuilder B;
    1168           0 :   B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
    1169           0 :   return addAttributes(C, Index, B);
    1170             : }
    1171             : 
    1172             : //===----------------------------------------------------------------------===//
    1173             : // AttributeList Accessor Methods
    1174             : //===----------------------------------------------------------------------===//
    1175             : 
    1176           8 : LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); }
    1177             : 
    1178     2204982 : AttributeSet AttributeList::getParamAttributes(unsigned ArgNo) const {
    1179     2204982 :   return getAttributes(ArgNo + FirstArgIndex);
    1180             : }
    1181             : 
    1182      830389 : AttributeSet AttributeList::getRetAttributes() const {
    1183      830389 :   return getAttributes(ReturnIndex);
    1184             : }
    1185             : 
    1186     1949008 : AttributeSet AttributeList::getFnAttributes() const {
    1187     1949008 :   return getAttributes(FunctionIndex);
    1188             : }
    1189             : 
    1190   338214703 : bool AttributeList::hasAttribute(unsigned Index,
    1191             :                                  Attribute::AttrKind Kind) const {
    1192   338214703 :   return getAttributes(Index).hasAttribute(Kind);
    1193             : }
    1194             : 
    1195    20020312 : bool AttributeList::hasAttribute(unsigned Index, StringRef Kind) const {
    1196    20020312 :   return getAttributes(Index).hasAttribute(Kind);
    1197             : }
    1198             : 
    1199     1920012 : bool AttributeList::hasAttributes(unsigned Index) const {
    1200     3840024 :   return getAttributes(Index).hasAttributes();
    1201             : }
    1202             : 
    1203   100400668 : bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind) const {
    1204   198133227 :   return pImpl && pImpl->hasFnAttribute(Kind);
    1205             : }
    1206             : 
    1207    19277276 : bool AttributeList::hasFnAttribute(StringRef Kind) const {
    1208    19277276 :   return hasAttribute(AttributeList::FunctionIndex, Kind);
    1209             : }
    1210             : 
    1211    53114097 : bool AttributeList::hasParamAttribute(unsigned ArgNo,
    1212             :                                       Attribute::AttrKind Kind) const {
    1213    53114097 :   return hasAttribute(ArgNo + FirstArgIndex, Kind);
    1214             : }
    1215             : 
    1216     3823621 : bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
    1217             :                                      unsigned *Index) const {
    1218     3823621 :   if (!pImpl) return false;
    1219             : 
    1220    15072744 :   for (unsigned I = index_begin(), E = index_end(); I != E; ++I) {
    1221     5919199 :     if (hasAttribute(I, Attr)) {
    1222        3891 :       if (Index)
    1223         606 :         *Index = I;
    1224             :       return true;
    1225             :     }
    1226             :   }
    1227             : 
    1228             :   return false;
    1229             : }
    1230             : 
    1231     3662740 : Attribute AttributeList::getAttribute(unsigned Index,
    1232             :                                       Attribute::AttrKind Kind) const {
    1233     3662740 :   return getAttributes(Index).getAttribute(Kind);
    1234             : }
    1235             : 
    1236    19819674 : Attribute AttributeList::getAttribute(unsigned Index, StringRef Kind) const {
    1237    19819674 :   return getAttributes(Index).getAttribute(Kind);
    1238             : }
    1239             : 
    1240      128194 : unsigned AttributeList::getRetAlignment() const {
    1241      128194 :   return getAttributes(ReturnIndex).getAlignment();
    1242             : }
    1243             : 
    1244     1947495 : unsigned AttributeList::getParamAlignment(unsigned ArgNo) const {
    1245     1947495 :   return getAttributes(ArgNo + FirstArgIndex).getAlignment();
    1246             : }
    1247             : 
    1248          63 : unsigned AttributeList::getStackAlignment(unsigned Index) const {
    1249          63 :   return getAttributes(Index).getStackAlignment();
    1250             : }
    1251             : 
    1252     1363897 : uint64_t AttributeList::getDereferenceableBytes(unsigned Index) const {
    1253     1363897 :   return getAttributes(Index).getDereferenceableBytes();
    1254             : }
    1255             : 
    1256       55908 : uint64_t AttributeList::getDereferenceableOrNullBytes(unsigned Index) const {
    1257       55908 :   return getAttributes(Index).getDereferenceableOrNullBytes();
    1258             : }
    1259             : 
    1260             : std::pair<unsigned, Optional<unsigned>>
    1261          79 : AttributeList::getAllocSizeArgs(unsigned Index) const {
    1262          79 :   return getAttributes(Index).getAllocSizeArgs();
    1263             : }
    1264             : 
    1265        7854 : std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
    1266        7854 :   return getAttributes(Index).getAsString(InAttrGrp);
    1267             : }
    1268             : 
    1269   392285588 : AttributeSet AttributeList::getAttributes(unsigned Index) const {
    1270             :   Index = attrIdxToArrayIdx(Index);
    1271   392285588 :   if (!pImpl || Index >= getNumAttrSets())
    1272    66119104 :     return AttributeSet();
    1273   326166484 :   return pImpl->begin()[Index];
    1274             : }
    1275             : 
    1276     1374957 : AttributeList::iterator AttributeList::begin() const {
    1277     2749914 :   return pImpl ? pImpl->begin() : nullptr;
    1278             : }
    1279             : 
    1280     1374957 : AttributeList::iterator AttributeList::end() const {
    1281     2749914 :   return pImpl ? pImpl->end() : nullptr;
    1282             : }
    1283             : 
    1284             : //===----------------------------------------------------------------------===//
    1285             : // AttributeList Introspection Methods
    1286             : //===----------------------------------------------------------------------===//
    1287             : 
    1288   357262067 : unsigned AttributeList::getNumAttrSets() const {
    1289   357262067 :   return pImpl ? pImpl->NumAttrSets : 0;
    1290             : }
    1291             : 
    1292             : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
    1293             : LLVM_DUMP_METHOD void AttributeList::dump() const {
    1294             :   dbgs() << "PAL[\n";
    1295             : 
    1296             :   for (unsigned i = index_begin(), e = index_end(); i != e; ++i) {
    1297             :     if (getAttributes(i).hasAttributes())
    1298             :       dbgs() << "  { " << i << " => " << getAsString(i) << " }\n";
    1299             :   }
    1300             : 
    1301             :   dbgs() << "]\n";
    1302             : }
    1303             : #endif
    1304             : 
    1305             : //===----------------------------------------------------------------------===//
    1306             : // AttrBuilder Method Implementations
    1307             : //===----------------------------------------------------------------------===//
    1308             : 
    1309             : // FIXME: Remove this ctor, use AttributeSet.
    1310       19848 : AttrBuilder::AttrBuilder(AttributeList AL, unsigned Index) {
    1311        9924 :   AttributeSet AS = AL.getAttributes(Index);
    1312       10968 :   for (const Attribute &A : AS)
    1313        1044 :     addAttribute(A);
    1314        9923 : }
    1315             : 
    1316     4817608 : AttrBuilder::AttrBuilder(AttributeSet AS) {
    1317    14517033 :   for (const Attribute &A : AS)
    1318    12108229 :     addAttribute(A);
    1319     2408804 : }
    1320             : 
    1321     1506876 : void AttrBuilder::clear() {
    1322             :   Attrs.reset();
    1323             :   TargetDepAttrs.clear();
    1324     1506876 :   Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0;
    1325     1506876 :   AllocSizeArgs = 0;
    1326     1506876 : }
    1327             : 
    1328     2536748 : AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
    1329             :   assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
    1330             :   assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment &&
    1331             :          Val != Attribute::Dereferenceable && Val != Attribute::AllocSize &&
    1332             :          "Adding integer attribute without adding a value!");
    1333             :   Attrs[Val] = true;
    1334     2536748 :   return *this;
    1335             : }
    1336             : 
    1337    12547229 : AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
    1338    12547229 :   if (Attr.isStringAttribute()) {
    1339    10966021 :     addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
    1340    10966021 :     return *this;
    1341             :   }
    1342             : 
    1343     1581208 :   Attribute::AttrKind Kind = Attr.getKindAsEnum();
    1344             :   Attrs[Kind] = true;
    1345             : 
    1346     1581208 :   if (Kind == Attribute::Alignment)
    1347      112933 :     Alignment = Attr.getAlignment();
    1348     1468275 :   else if (Kind == Attribute::StackAlignment)
    1349         120 :     StackAlignment = Attr.getStackAlignment();
    1350     1468155 :   else if (Kind == Attribute::Dereferenceable)
    1351       46735 :     DerefBytes = Attr.getDereferenceableBytes();
    1352     1421420 :   else if (Kind == Attribute::DereferenceableOrNull)
    1353          82 :     DerefOrNullBytes = Attr.getDereferenceableOrNullBytes();
    1354     1421338 :   else if (Kind == Attribute::AllocSize)
    1355          38 :     AllocSizeArgs = Attr.getValueAsInt();
    1356             :   return *this;
    1357             : }
    1358             : 
    1359    13931707 : AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
    1360    41795121 :   TargetDepAttrs[A] = V;
    1361    13931707 :   return *this;
    1362             : }
    1363             : 
    1364       58904 : AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
    1365             :   assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
    1366             :   Attrs[Val] = false;
    1367             : 
    1368       58904 :   if (Val == Attribute::Alignment)
    1369       13220 :     Alignment = 0;
    1370       45684 :   else if (Val == Attribute::StackAlignment)
    1371           1 :     StackAlignment = 0;
    1372       45683 :   else if (Val == Attribute::Dereferenceable)
    1373           0 :     DerefBytes = 0;
    1374       45683 :   else if (Val == Attribute::DereferenceableOrNull)
    1375           0 :     DerefOrNullBytes = 0;
    1376       45683 :   else if (Val == Attribute::AllocSize)
    1377           0 :     AllocSizeArgs = 0;
    1378             : 
    1379       58904 :   return *this;
    1380             : }
    1381             : 
    1382           0 : AttrBuilder &AttrBuilder::removeAttributes(AttributeList A, uint64_t Index) {
    1383           0 :   remove(A.getAttributes(Index));
    1384           0 :   return *this;
    1385             : }
    1386             : 
    1387      225304 : AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
    1388      225304 :   std::map<std::string, std::string>::iterator I = TargetDepAttrs.find(A);
    1389      225304 :   if (I != TargetDepAttrs.end())
    1390             :     TargetDepAttrs.erase(I);
    1391      225304 :   return *this;
    1392             : }
    1393             : 
    1394         105 : std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
    1395         210 :   return unpackAllocSizeArgs(AllocSizeArgs);
    1396             : }
    1397             : 
    1398        8066 : AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) {
    1399        8066 :   if (Align == 0) return *this;
    1400             : 
    1401             :   assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
    1402             :   assert(Align <= 0x40000000 && "Alignment too large.");
    1403             : 
    1404             :   Attrs[Attribute::Alignment] = true;
    1405        8066 :   Alignment = Align;
    1406        8066 :   return *this;
    1407             : }
    1408             : 
    1409          85 : AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) {
    1410             :   // Default alignment, allow the target to define how to align it.
    1411          85 :   if (Align == 0) return *this;
    1412             : 
    1413             :   assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
    1414             :   assert(Align <= 0x100 && "Alignment too large.");
    1415             : 
    1416             :   Attrs[Attribute::StackAlignment] = true;
    1417          85 :   StackAlignment = Align;
    1418          85 :   return *this;
    1419             : }
    1420             : 
    1421      234735 : AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
    1422      234735 :   if (Bytes == 0) return *this;
    1423             : 
    1424             :   Attrs[Attribute::Dereferenceable] = true;
    1425      231508 :   DerefBytes = Bytes;
    1426      231508 :   return *this;
    1427             : }
    1428             : 
    1429       95754 : AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
    1430       95754 :   if (Bytes == 0)
    1431             :     return *this;
    1432             : 
    1433             :   Attrs[Attribute::DereferenceableOrNull] = true;
    1434       95754 :   DerefOrNullBytes = Bytes;
    1435       95754 :   return *this;
    1436             : }
    1437             : 
    1438          54 : AttrBuilder &AttrBuilder::addAllocSizeAttr(unsigned ElemSize,
    1439             :                                            const Optional<unsigned> &NumElems) {
    1440          54 :   return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
    1441             : }
    1442             : 
    1443          64 : AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
    1444             :   // (0, 0) is our "not present" value, so we need to check for it here.
    1445             :   assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
    1446             : 
    1447             :   Attrs[Attribute::AllocSize] = true;
    1448             :   // Reuse existing machinery to store this as a single 64-bit integer so we can
    1449             :   // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
    1450          64 :   AllocSizeArgs = RawArgs;
    1451          64 :   return *this;
    1452             : }
    1453             : 
    1454     1331544 : AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
    1455             :   // FIXME: What if both have alignments, but they don't match?!
    1456     1331544 :   if (!Alignment)
    1457     1331090 :     Alignment = B.Alignment;
    1458             : 
    1459     1331544 :   if (!StackAlignment)
    1460     1331475 :     StackAlignment = B.StackAlignment;
    1461             : 
    1462     1331544 :   if (!DerefBytes)
    1463     1330233 :     DerefBytes = B.DerefBytes;
    1464             : 
    1465     1331544 :   if (!DerefOrNullBytes)
    1466     1331539 :     DerefOrNullBytes = B.DerefOrNullBytes;
    1467             : 
    1468     1331544 :   if (!AllocSizeArgs)
    1469     1331532 :     AllocSizeArgs = B.AllocSizeArgs;
    1470             : 
    1471             :   Attrs |= B.Attrs;
    1472             : 
    1473     3595302 :   for (auto I : B.td_attrs())
    1474      754586 :     TargetDepAttrs[I.first] = I.second;
    1475             : 
    1476     1331544 :   return *this;
    1477             : }
    1478             : 
    1479       13134 : AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) {
    1480             :   // FIXME: What if both have alignments, but they don't match?!
    1481       13134 :   if (B.Alignment)
    1482           2 :     Alignment = 0;
    1483             : 
    1484       13134 :   if (B.StackAlignment)
    1485           1 :     StackAlignment = 0;
    1486             : 
    1487       13134 :   if (B.DerefBytes)
    1488        2944 :     DerefBytes = 0;
    1489             : 
    1490       13134 :   if (B.DerefOrNullBytes)
    1491        2940 :     DerefOrNullBytes = 0;
    1492             : 
    1493       13134 :   if (B.AllocSizeArgs)
    1494           0 :     AllocSizeArgs = 0;
    1495             : 
    1496             :   Attrs &= ~B.Attrs;
    1497             : 
    1498       13230 :   for (auto I : B.td_attrs())
    1499             :     TargetDepAttrs.erase(I.first);
    1500             : 
    1501       13134 :   return *this;
    1502             : }
    1503             : 
    1504      221595 : bool AttrBuilder::overlaps(const AttrBuilder &B) const {
    1505             :   // First check if any of the target independent attributes overlap.
    1506      221595 :   if ((Attrs & B.Attrs).any())
    1507             :     return true;
    1508             : 
    1509             :   // Then check if any target dependent ones do.
    1510      221656 :   for (const auto &I : td_attrs())
    1511          66 :     if (B.contains(I.first))
    1512             :       return true;
    1513             : 
    1514             :   return false;
    1515             : }
    1516             : 
    1517          66 : bool AttrBuilder::contains(StringRef A) const {
    1518          66 :   return TargetDepAttrs.find(A) != TargetDepAttrs.end();
    1519             : }
    1520             : 
    1521     2159436 : bool AttrBuilder::hasAttributes() const {
    1522     3645113 :   return !Attrs.none() || !TargetDepAttrs.empty();
    1523             : }
    1524             : 
    1525           0 : bool AttrBuilder::hasAttributes(AttributeList AL, uint64_t Index) const {
    1526           0 :   AttributeSet AS = AL.getAttributes(Index);
    1527             : 
    1528           0 :   for (Attribute Attr : AS) {
    1529           0 :     if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
    1530           0 :       if (contains(Attr.getKindAsEnum()))
    1531           0 :         return true;
    1532             :     } else {
    1533             :       assert(Attr.isStringAttribute() && "Invalid attribute kind!");
    1534           0 :       return contains(Attr.getKindAsString());
    1535             :     }
    1536             :   }
    1537             : 
    1538           0 :   return false;
    1539             : }
    1540             : 
    1541      652838 : bool AttrBuilder::hasAlignmentAttr() const {
    1542      652838 :   return Alignment != 0;
    1543             : }
    1544             : 
    1545        3013 : bool AttrBuilder::operator==(const AttrBuilder &B) {
    1546        3013 :   if (Attrs != B.Attrs)
    1547             :     return false;
    1548             : 
    1549             :   for (td_const_iterator I = TargetDepAttrs.begin(),
    1550        3000 :          E = TargetDepAttrs.end(); I != E; ++I)
    1551           0 :     if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end())
    1552             :       return false;
    1553             : 
    1554        5999 :   return Alignment == B.Alignment && StackAlignment == B.StackAlignment &&
    1555        2999 :          DerefBytes == B.DerefBytes;
    1556             : }
    1557             : 
    1558             : //===----------------------------------------------------------------------===//
    1559             : // AttributeFuncs Function Defintions
    1560             : //===----------------------------------------------------------------------===//
    1561             : 
    1562             : /// \brief Which attributes cannot be applied to a type.
    1563      224630 : AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
    1564             :   AttrBuilder Incompatible;
    1565             : 
    1566      224630 :   if (!Ty->isIntegerTy())
    1567             :     // Attribute that only apply to integers.
    1568      134437 :     Incompatible.addAttribute(Attribute::SExt)
    1569      134437 :       .addAttribute(Attribute::ZExt);
    1570             : 
    1571      224630 :   if (!Ty->isPointerTy())
    1572             :     // Attribute that only apply to pointers.
    1573       95682 :     Incompatible.addAttribute(Attribute::ByVal)
    1574       95682 :       .addAttribute(Attribute::Nest)
    1575       95682 :       .addAttribute(Attribute::NoAlias)
    1576       95682 :       .addAttribute(Attribute::NoCapture)
    1577       95682 :       .addAttribute(Attribute::NonNull)
    1578       95682 :       .addDereferenceableAttr(1) // the int here is ignored
    1579       95682 :       .addDereferenceableOrNullAttr(1) // the int here is ignored
    1580       95682 :       .addAttribute(Attribute::ReadNone)
    1581       95682 :       .addAttribute(Attribute::ReadOnly)
    1582       95682 :       .addAttribute(Attribute::StructRet)
    1583       95682 :       .addAttribute(Attribute::InAlloca);
    1584             : 
    1585      224630 :   return Incompatible;
    1586             : }
    1587             : 
    1588             : template<typename AttrClass>
    1589     1827125 : static bool isEqual(const Function &Caller, const Function &Callee) {
    1590             :   return Caller.getFnAttribute(AttrClass::getKind()) ==
    1591     1827124 :          Callee.getFnAttribute(AttrClass::getKind());
    1592             : }
    1593             : 
    1594             : /// \brief Compute the logical AND of the attributes of the caller and the
    1595             : /// callee.
    1596             : ///
    1597             : /// This function sets the caller's attribute to false if the callee's attribute
    1598             : /// is false.
    1599             : template<typename AttrClass>
    1600      366016 : static void setAND(Function &Caller, const Function &Callee) {
    1601      366032 :   if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
    1602          16 :       !AttrClass::isSet(Callee, AttrClass::getKind()))
    1603           8 :     AttrClass::set(Caller, AttrClass::getKind(), false);
    1604      366016 : }
    1605             : 
    1606             : /// \brief Compute the logical OR of the attributes of the caller and the
    1607             : /// callee.
    1608             : ///
    1609             : /// This function sets the caller's attribute to true if the callee's attribute
    1610             : /// is true.
    1611             : template<typename AttrClass>
    1612      274512 : static void setOR(Function &Caller, const Function &Callee) {
    1613      549015 :   if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
    1614      183004 :       AttrClass::isSet(Callee, AttrClass::getKind()))
    1615           2 :     AttrClass::set(Caller, AttrClass::getKind(), true);
    1616      274512 : }
    1617             : 
    1618             : /// \brief If the inlined function had a higher stack protection level than the
    1619             : /// calling function, then bump up the caller's stack protection level.
    1620       91504 : static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
    1621             :   // If upgrading the SSP attribute, clear out the old SSP Attributes first.
    1622             :   // Having multiple SSP attributes doesn't actually hurt, but it adds useless
    1623             :   // clutter to the IR.
    1624             :   AttrBuilder OldSSPAttr;
    1625       91504 :   OldSSPAttr.addAttribute(Attribute::StackProtect)
    1626       91504 :       .addAttribute(Attribute::StackProtectStrong)
    1627       91504 :       .addAttribute(Attribute::StackProtectReq);
    1628             : 
    1629       91504 :   if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
    1630           8 :     Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
    1631             :     Caller.addFnAttr(Attribute::StackProtectReq);
    1632      101148 :   } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
    1633             :              !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
    1634        9650 :     Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
    1635             :     Caller.addFnAttr(Attribute::StackProtectStrong);
    1636          87 :   } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
    1637       81931 :              !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
    1638             :              !Caller.hasFnAttribute(Attribute::StackProtectStrong))
    1639             :     Caller.addFnAttr(Attribute::StackProtect);
    1640       91504 : }
    1641             : 
    1642             : /// \brief If the inlined function required stack probes, then ensure that
    1643             : /// the calling function has those too.
    1644       91504 : static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
    1645      183007 :   if (!Caller.hasFnAttribute("probe-stack") &&
    1646             :       Callee.hasFnAttribute("probe-stack")) {
    1647             :     Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
    1648             :   }
    1649       91504 : }
    1650             : 
    1651             : /// \brief If the inlined function defines the size of guard region
    1652             : /// on the stack, then ensure that the calling function defines a guard region
    1653             : /// that is no larger.
    1654             : static void
    1655       91504 : adjustCallerStackProbeSize(Function &Caller, const Function &Callee) {
    1656       91504 :   if (Callee.hasFnAttribute("stack-probe-size")) {
    1657             :     uint64_t CalleeStackProbeSize;
    1658           6 :     Callee.getFnAttribute("stack-probe-size")
    1659           6 :           .getValueAsString()
    1660             :           .getAsInteger(0, CalleeStackProbeSize);
    1661           3 :     if (Caller.hasFnAttribute("stack-probe-size")) {
    1662             :       uint64_t CallerStackProbeSize;
    1663           4 :       Caller.getFnAttribute("stack-probe-size")
    1664           4 :             .getValueAsString()
    1665             :             .getAsInteger(0, CallerStackProbeSize);
    1666           2 :       if (CallerStackProbeSize > CalleeStackProbeSize) {
    1667             :         Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
    1668             :       }
    1669             :     } else {
    1670             :       Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
    1671             :     }
    1672             :   }
    1673       91504 : }
    1674             : 
    1675             : #define GET_ATTR_COMPAT_FUNC
    1676             : #include "AttributesCompatFunc.inc"
    1677             : 
    1678      365425 : bool AttributeFuncs::areInlineCompatible(const Function &Caller,
    1679             :                                          const Function &Callee) {
    1680      365425 :   return hasCompatibleFnAttrs(Caller, Callee);
    1681             : }
    1682             : 
    1683       91504 : void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
    1684             :                                                 const Function &Callee) {
    1685       91504 :   mergeFnAttrs(Caller, Callee);
    1686       91504 : }

Generated by: LCOV version 1.13