LCOV - code coverage report
Current view: top level - lib/IR - Attributes.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 751 789 95.2 %
Date: 2018-07-13 00:08:38 Functions: 148 157 94.3 %
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             : // 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/Config/llvm-config.h"
      28             : #include "llvm/IR/Function.h"
      29             : #include "llvm/IR/LLVMContext.h"
      30             : #include "llvm/IR/Type.h"
      31             : #include "llvm/Support/Compiler.h"
      32             : #include "llvm/Support/Debug.h"
      33             : #include "llvm/Support/ErrorHandling.h"
      34             : #include "llvm/Support/MathExtras.h"
      35             : #include "llvm/Support/raw_ostream.h"
      36             : #include <algorithm>
      37             : #include <cassert>
      38             : #include <climits>
      39             : #include <cstddef>
      40             : #include <cstdint>
      41             : #include <limits>
      42             : #include <string>
      43             : #include <tuple>
      44             : #include <utility>
      45             : 
      46             : using namespace llvm;
      47             : 
      48             : //===----------------------------------------------------------------------===//
      49             : // Attribute Construction Methods
      50             : //===----------------------------------------------------------------------===//
      51             : 
      52             : // allocsize has two integer arguments, but because they're both 32 bits, we can
      53             : // pack them into one 64-bit value, at the cost of making said value
      54             : // nonsensical.
      55             : //
      56             : // In order to do this, we need to reserve one value of the second (optional)
      57             : // allocsize argument to signify "not present."
      58             : static const unsigned AllocSizeNumElemsNotPresent = -1;
      59             : 
      60             : static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
      61             :                                   const Optional<unsigned> &NumElemsArg) {
      62             :   assert((!NumElemsArg.hasValue() ||
      63             :           *NumElemsArg != AllocSizeNumElemsNotPresent) &&
      64             :          "Attempting to pack a reserved value");
      65             : 
      66         172 :   return uint64_t(ElemSizeArg) << 32 |
      67         172 :          NumElemsArg.getValueOr(AllocSizeNumElemsNotPresent);
      68             : }
      69             : 
      70             : static std::pair<unsigned, Optional<unsigned>>
      71             : unpackAllocSizeArgs(uint64_t Num) {
      72         258 :   unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
      73         258 :   unsigned ElemSizeArg = Num >> 32;
      74             : 
      75             :   Optional<unsigned> NumElemsArg;
      76         258 :   if (NumElems != AllocSizeNumElemsNotPresent)
      77             :     NumElemsArg = NumElems;
      78             :   return std::make_pair(ElemSizeArg, NumElemsArg);
      79             : }
      80             : 
      81     3407412 : Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
      82             :                          uint64_t Val) {
      83     3407412 :   LLVMContextImpl *pImpl = Context.pImpl;
      84             :   FoldingSetNodeID ID;
      85     3407412 :   ID.AddInteger(Kind);
      86     3407412 :   if (Val) ID.AddInteger(Val);
      87             : 
      88             :   void *InsertPoint;
      89             :   AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
      90             : 
      91     3276494 :   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      130918 :     if (!Val)
      95      116831 :       PA = new EnumAttributeImpl(Kind);
      96             :     else
      97       14087 :       PA = new IntAttributeImpl(Kind, Val);
      98      130918 :     pImpl->AttrsSet.InsertNode(PA, InsertPoint);
      99             :   }
     100             : 
     101             :   // Return the Attribute that we found or created.
     102     6814824 :   return Attribute(PA);
     103             : }
     104             : 
     105    14320803 : Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
     106    14320803 :   LLVMContextImpl *pImpl = Context.pImpl;
     107             :   FoldingSetNodeID ID;
     108    14320803 :   ID.AddString(Kind);
     109    14320803 :   if (!Val.empty()) ID.AddString(Val);
     110             : 
     111             :   void *InsertPoint;
     112             :   AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
     113             : 
     114    14159001 :   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      161802 :     PA = new StringAttributeImpl(Kind, Val);
     118      161802 :     pImpl->AttrsSet.InsertNode(PA, InsertPoint);
     119             :   }
     120             : 
     121             :   // Return the Attribute that we found or created.
     122    28641606 :   return Attribute(PA);
     123             : }
     124             : 
     125      173664 : 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      173664 :   return get(Context, Alignment, Align);
     129             : }
     130             : 
     131         205 : 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         205 :   return get(Context, StackAlignment, Align);
     136             : }
     137             : 
     138      202237 : Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context,
     139             :                                                 uint64_t Bytes) {
     140             :   assert(Bytes && "Bytes must be non-zero.");
     141      202237 :   return get(Context, Dereferenceable, Bytes);
     142             : }
     143             : 
     144          95 : Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
     145             :                                                        uint64_t Bytes) {
     146             :   assert(Bytes && "Bytes must be non-zero.");
     147          95 :   return get(Context, DereferenceableOrNull, Bytes);
     148             : }
     149             : 
     150             : Attribute
     151         114 : 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         114 :   return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
     156             : }
     157             : 
     158             : //===----------------------------------------------------------------------===//
     159             : // Attribute Accessor Methods
     160             : //===----------------------------------------------------------------------===//
     161             : 
     162       17962 : bool Attribute::isEnumAttribute() const {
     163       17962 :   return pImpl && pImpl->isEnumAttribute();
     164             : }
     165             : 
     166       11537 : bool Attribute::isIntAttribute() const {
     167       11537 :   return pImpl && pImpl->isIntAttribute();
     168             : }
     169             : 
     170   437130072 : bool Attribute::isStringAttribute() const {
     171   437130072 :   return pImpl && pImpl->isStringAttribute();
     172             : }
     173             : 
     174     4143389 : Attribute::AttrKind Attribute::getKindAsEnum() const {
     175     4143389 :   if (!pImpl) return None;
     176             :   assert((isEnumAttribute() || isIntAttribute()) &&
     177             :          "Invalid attribute type to get the kind as an enum!");
     178     4143389 :   return pImpl->getKindAsEnum();
     179             : }
     180             : 
     181       37528 : uint64_t Attribute::getValueAsInt() const {
     182       37528 :   if (!pImpl) return 0;
     183             :   assert(isIntAttribute() &&
     184             :          "Expected the attribute to be an integer attribute!");
     185       37528 :   return pImpl->getValueAsInt();
     186             : }
     187             : 
     188    11469843 : StringRef Attribute::getKindAsString() const {
     189    11469843 :   if (!pImpl) return {};
     190             :   assert(isStringAttribute() &&
     191             :          "Invalid attribute type to get the kind as a string!");
     192    11469843 :   return pImpl->getKindAsString();
     193             : }
     194             : 
     195    37827574 : StringRef Attribute::getValueAsString() const {
     196    37827574 :   if (!pImpl) return {};
     197             :   assert(isStringAttribute() &&
     198             :          "Invalid attribute type to get the value as a string!");
     199    21938159 :   return pImpl->getValueAsString();
     200             : }
     201             : 
     202    40107550 : bool Attribute::hasAttribute(AttrKind Kind) const {
     203    40107550 :   return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
     204             : }
     205             : 
     206   413631241 : bool Attribute::hasAttribute(StringRef Kind) const {
     207   413631241 :   if (!isStringAttribute()) return false;
     208   356613240 :   return pImpl && pImpl->hasAttribute(Kind);
     209             : }
     210             : 
     211      570260 : unsigned Attribute::getAlignment() const {
     212             :   assert(hasAttribute(Attribute::Alignment) &&
     213             :          "Trying to get alignment from non-alignment attribute!");
     214      570260 :   return pImpl->getValueAsInt();
     215             : }
     216             : 
     217         184 : unsigned Attribute::getStackAlignment() const {
     218             :   assert(hasAttribute(Attribute::StackAlignment) &&
     219             :          "Trying to get alignment from non-alignment attribute!");
     220         184 :   return pImpl->getValueAsInt();
     221             : }
     222             : 
     223      159389 : uint64_t Attribute::getDereferenceableBytes() const {
     224             :   assert(hasAttribute(Attribute::Dereferenceable) &&
     225             :          "Trying to get dereferenceable bytes from "
     226             :          "non-dereferenceable attribute!");
     227      159389 :   return pImpl->getValueAsInt();
     228             : }
     229             : 
     230         121 : uint64_t Attribute::getDereferenceableOrNullBytes() const {
     231             :   assert(hasAttribute(Attribute::DereferenceableOrNull) &&
     232             :          "Trying to get dereferenceable bytes from "
     233             :          "non-dereferenceable attribute!");
     234         121 :   return pImpl->getValueAsInt();
     235             : }
     236             : 
     237         145 : std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const {
     238             :   assert(hasAttribute(Attribute::AllocSize) &&
     239             :          "Trying to get allocsize args from non-allocsize attribute");
     240         290 :   return unpackAllocSizeArgs(pImpl->getValueAsInt());
     241             : }
     242             : 
     243      684133 : std::string Attribute::getAsString(bool InAttrGrp) const {
     244      684133 :   if (!pImpl) return {};
     245             : 
     246      684133 :   if (hasAttribute(Attribute::SanitizeAddress))
     247        1026 :     return "sanitize_address";
     248      683107 :   if (hasAttribute(Attribute::SanitizeHWAddress))
     249         206 :     return "sanitize_hwaddress";
     250      682901 :   if (hasAttribute(Attribute::AlwaysInline))
     251         848 :     return "alwaysinline";
     252      682053 :   if (hasAttribute(Attribute::ArgMemOnly))
     253        6740 :     return "argmemonly";
     254      675313 :   if (hasAttribute(Attribute::Builtin))
     255         351 :     return "builtin";
     256      674962 :   if (hasAttribute(Attribute::ByVal))
     257        1311 :     return "byval";
     258      673651 :   if (hasAttribute(Attribute::Convergent))
     259        1828 :     return "convergent";
     260      671823 :   if (hasAttribute(Attribute::SwiftError))
     261          65 :     return "swifterror";
     262      671758 :   if (hasAttribute(Attribute::SwiftSelf))
     263          46 :     return "swiftself";
     264      671712 :   if (hasAttribute(Attribute::InaccessibleMemOnly))
     265         187 :     return "inaccessiblememonly";
     266      671525 :   if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly))
     267          92 :     return "inaccessiblemem_or_argmemonly";
     268      671433 :   if (hasAttribute(Attribute::InAlloca))
     269         204 :     return "inalloca";
     270      671229 :   if (hasAttribute(Attribute::InlineHint))
     271        1172 :     return "inlinehint";
     272      670057 :   if (hasAttribute(Attribute::InReg))
     273         990 :     return "inreg";
     274      669067 :   if (hasAttribute(Attribute::JumpTable))
     275          28 :     return "jumptable";
     276      669039 :   if (hasAttribute(Attribute::MinSize))
     277         353 :     return "minsize";
     278      668686 :   if (hasAttribute(Attribute::Naked))
     279         120 :     return "naked";
     280      668566 :   if (hasAttribute(Attribute::Nest))
     281          81 :     return "nest";
     282      668485 :   if (hasAttribute(Attribute::NoAlias))
     283       16372 :     return "noalias";
     284      652113 :   if (hasAttribute(Attribute::NoBuiltin))
     285         923 :     return "nobuiltin";
     286      651190 :   if (hasAttribute(Attribute::NoCapture))
     287       10113 :     return "nocapture";
     288      641077 :   if (hasAttribute(Attribute::NoDuplicate))
     289          65 :     return "noduplicate";
     290      641012 :   if (hasAttribute(Attribute::NoImplicitFloat))
     291          81 :     return "noimplicitfloat";
     292      640931 :   if (hasAttribute(Attribute::NoInline))
     293       97943 :     return "noinline";
     294      542988 :   if (hasAttribute(Attribute::NonLazyBind))
     295         640 :     return "nonlazybind";
     296      542348 :   if (hasAttribute(Attribute::NonNull))
     297        2913 :     return "nonnull";
     298      539435 :   if (hasAttribute(Attribute::NoRedZone))
     299         179 :     return "noredzone";
     300      539256 :   if (hasAttribute(Attribute::NoReturn))
     301        1392 :     return "noreturn";
     302      537864 :   if (hasAttribute(Attribute::NoCfCheck))
     303           3 :     return "nocf_check";
     304      537861 :   if (hasAttribute(Attribute::NoRecurse))
     305       18606 :     return "norecurse";
     306      519255 :   if (hasAttribute(Attribute::NoUnwind))
     307      152030 :     return "nounwind";
     308      367225 :   if (hasAttribute(Attribute::OptForFuzzing))
     309           2 :     return "optforfuzzing";
     310      367223 :   if (hasAttribute(Attribute::OptimizeNone))
     311       73967 :     return "optnone";
     312      293256 :   if (hasAttribute(Attribute::OptimizeForSize))
     313         828 :     return "optsize";
     314      292428 :   if (hasAttribute(Attribute::ReadNone))
     315       19279 :     return "readnone";
     316      273149 :   if (hasAttribute(Attribute::ReadOnly))
     317        6553 :     return "readonly";
     318      266596 :   if (hasAttribute(Attribute::WriteOnly))
     319        2028 :     return "writeonly";
     320      264568 :   if (hasAttribute(Attribute::Returned))
     321        1720 :     return "returned";
     322      262848 :   if (hasAttribute(Attribute::ReturnsTwice))
     323         145 :     return "returns_twice";
     324      262703 :   if (hasAttribute(Attribute::SExt))
     325        8295 :     return "signext";
     326      254408 :   if (hasAttribute(Attribute::Speculatable))
     327        4912 :     return "speculatable";
     328      249496 :   if (hasAttribute(Attribute::StackProtect))
     329        1368 :     return "ssp";
     330      248128 :   if (hasAttribute(Attribute::StackProtectReq))
     331          86 :     return "sspreq";
     332      248042 :   if (hasAttribute(Attribute::StackProtectStrong))
     333         109 :     return "sspstrong";
     334      247933 :   if (hasAttribute(Attribute::SafeStack))
     335         324 :     return "safestack";
     336      247609 :   if (hasAttribute(Attribute::ShadowCallStack))
     337          21 :     return "shadowcallstack";
     338      247588 :   if (hasAttribute(Attribute::StrictFP))
     339          10 :     return "strictfp";
     340      247578 :   if (hasAttribute(Attribute::StructRet))
     341        2537 :     return "sret";
     342      245041 :   if (hasAttribute(Attribute::SanitizeThread))
     343         166 :     return "sanitize_thread";
     344      244875 :   if (hasAttribute(Attribute::SanitizeMemory))
     345         612 :     return "sanitize_memory";
     346      244263 :   if (hasAttribute(Attribute::UWTable))
     347        3184 :     return "uwtable";
     348      241079 :   if (hasAttribute(Attribute::ZExt))
     349        7324 :     return "zeroext";
     350      233755 :   if (hasAttribute(Attribute::Cold))
     351          74 :     return "cold";
     352             : 
     353             :   // FIXME: These should be output like this:
     354             :   //
     355             :   //   align=4
     356             :   //   alignstack=8
     357             :   //
     358      233681 :   if (hasAttribute(Attribute::Alignment)) {
     359             :     std::string Result;
     360             :     Result += "align";
     361       19450 :     Result += (InAttrGrp) ? "=" : " ";
     362       38900 :     Result += utostr(getValueAsInt());
     363             :     return Result;
     364             :   }
     365             : 
     366       17145 :   auto AttrWithBytesToString = [&](const char *Name) {
     367             :     std::string Result;
     368             :     Result += Name;
     369       17145 :     if (InAttrGrp) {
     370             :       Result += "=";
     371       17182 :       Result += utostr(getValueAsInt());
     372             :     } else {
     373             :       Result += "(";
     374       34216 :       Result += utostr(getValueAsInt());
     375             :       Result += ")";
     376             :     }
     377       17145 :     return Result;
     378      214231 :   };
     379             : 
     380      214231 :   if (hasAttribute(Attribute::StackAlignment))
     381          74 :     return AttrWithBytesToString("alignstack");
     382             : 
     383      214157 :   if (hasAttribute(Attribute::Dereferenceable))
     384       17014 :     return AttrWithBytesToString("dereferenceable");
     385             : 
     386      197143 :   if (hasAttribute(Attribute::DereferenceableOrNull))
     387          57 :     return AttrWithBytesToString("dereferenceable_or_null");
     388             : 
     389      197086 :   if (hasAttribute(Attribute::AllocSize)) {
     390             :     unsigned ElemSize;
     391             :     Optional<unsigned> NumElems;
     392          88 :     std::tie(ElemSize, NumElems) = getAllocSizeArgs();
     393             : 
     394          44 :     std::string Result = "allocsize(";
     395          88 :     Result += utostr(ElemSize);
     396          44 :     if (NumElems.hasValue()) {
     397             :       Result += ',';
     398          40 :       Result += utostr(*NumElems);
     399             :     }
     400             :     Result += ')';
     401             :     return Result;
     402             :   }
     403             : 
     404             :   // Convert target-dependent attributes to strings of the form:
     405             :   //
     406             :   //   "kind"
     407             :   //   "kind" = "value"
     408             :   //
     409      197042 :   if (isStringAttribute()) {
     410             :     std::string Result;
     411      591126 :     Result += (Twine('"') + getKindAsString() + Twine('"')).str();
     412             : 
     413      394084 :     std::string AttrVal = pImpl->getValueAsString();
     414      197042 :     if (AttrVal.empty()) return Result;
     415             : 
     416             :     // Since some attribute strings contain special characters that cannot be
     417             :     // printable, those have to be escaped to make the attribute value printable
     418             :     // as is.  e.g. "\01__gnu_mcount_nc"
     419             :     {
     420      195116 :       raw_string_ostream OS(Result);
     421      195116 :       OS << "=\"";
     422      195116 :       printEscapedString(AttrVal, OS);
     423      195116 :       OS << "\"";
     424             :     }
     425             :     return Result;
     426             :   }
     427             : 
     428           0 :   llvm_unreachable("Unknown attribute");
     429             : }
     430             : 
     431    30806331 : bool Attribute::operator<(Attribute A) const {
     432    30806331 :   if (!pImpl && !A.pImpl) return false;
     433    30806331 :   if (!pImpl) return true;
     434    30806331 :   if (!A.pImpl) return false;
     435    30806331 :   return *pImpl < *A.pImpl;
     436             : }
     437             : 
     438             : //===----------------------------------------------------------------------===//
     439             : // AttributeImpl Definition
     440             : //===----------------------------------------------------------------------===//
     441             : 
     442             : // Pin the vtables to this file.
     443             : AttributeImpl::~AttributeImpl() = default;
     444             : 
     445           0 : void EnumAttributeImpl::anchor() {}
     446             : 
     447           0 : void IntAttributeImpl::anchor() {}
     448             : 
     449           0 : void StringAttributeImpl::anchor() {}
     450             : 
     451    34737611 : bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
     452    34737611 :   if (isStringAttribute()) return false;
     453    16744744 :   return getKindAsEnum() == A;
     454             : }
     455             : 
     456   356613240 : bool AttributeImpl::hasAttribute(StringRef Kind) const {
     457   356613240 :   if (!isStringAttribute()) return false;
     458   356613240 :   return getKindAsString() == Kind;
     459             : }
     460             : 
     461    31455223 : Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
     462             :   assert(isEnumAttribute() || isIntAttribute());
     463    31455223 :   return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
     464             : }
     465             : 
     466     2756983 : uint64_t AttributeImpl::getValueAsInt() const {
     467             :   assert(isIntAttribute());
     468     2756983 :   return static_cast<const IntAttributeImpl *>(this)->getValue();
     469             : }
     470             : 
     471   459149732 : StringRef AttributeImpl::getKindAsString() const {
     472             :   assert(isStringAttribute());
     473   459149732 :   return static_cast<const StringAttributeImpl *>(this)->getStringKind();
     474             : }
     475             : 
     476    36659642 : StringRef AttributeImpl::getValueAsString() const {
     477             :   assert(isStringAttribute());
     478    36659642 :   return static_cast<const StringAttributeImpl *>(this)->getStringValue();
     479             : }
     480             : 
     481    30806331 : bool AttributeImpl::operator<(const AttributeImpl &AI) const {
     482             :   // This sorts the attributes with Attribute::AttrKinds coming first (sorted
     483             :   // relative to their enum value) and then strings.
     484    30806331 :   if (isEnumAttribute()) {
     485     2328823 :     if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
     486      561623 :     if (AI.isIntAttribute()) return true;
     487      495768 :     if (AI.isStringAttribute()) return true;
     488             :   }
     489             : 
     490    28477508 :   if (isIntAttribute()) {
     491       28584 :     if (AI.isEnumAttribute()) return false;
     492       28481 :     if (AI.isIntAttribute()) {
     493       28451 :       if (getKindAsEnum() == AI.getKindAsEnum())
     494           1 :         return getValueAsInt() < AI.getValueAsInt();
     495       28450 :       return getKindAsEnum() < AI.getKindAsEnum();
     496             :     }
     497          30 :     if (AI.isStringAttribute()) return true;
     498             :   }
     499             : 
     500    28448924 :   if (AI.isEnumAttribute()) return false;
     501    19135919 :   if (AI.isIntAttribute()) return false;
     502    19135604 :   if (getKindAsString() == AI.getKindAsString())
     503          52 :     return getValueAsString() < AI.getValueAsString();
     504    19135552 :   return getKindAsString() < AI.getKindAsString();
     505             : }
     506             : 
     507             : //===----------------------------------------------------------------------===//
     508             : // AttributeSet Definition
     509             : //===----------------------------------------------------------------------===//
     510             : 
     511     4972317 : AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) {
     512     4972317 :   return AttributeSet(AttributeSetNode::get(C, B));
     513             : }
     514             : 
     515      163568 : AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
     516      163568 :   return AttributeSet(AttributeSetNode::get(C, Attrs));
     517             : }
     518             : 
     519           0 : AttributeSet AttributeSet::addAttribute(LLVMContext &C,
     520             :                                         Attribute::AttrKind Kind) const {
     521           0 :   if (hasAttribute(Kind)) return *this;
     522             :   AttrBuilder B;
     523           0 :   B.addAttribute(Kind);
     524           0 :   return addAttributes(C, AttributeSet::get(C, B));
     525             : }
     526             : 
     527          44 : AttributeSet AttributeSet::addAttribute(LLVMContext &C, StringRef Kind,
     528             :                                         StringRef Value) const {
     529             :   AttrBuilder B;
     530          44 :   B.addAttribute(Kind, Value);
     531          88 :   return addAttributes(C, AttributeSet::get(C, B));
     532             : }
     533             : 
     534          44 : AttributeSet AttributeSet::addAttributes(LLVMContext &C,
     535             :                                          const AttributeSet AS) const {
     536          44 :   if (!hasAttributes())
     537          19 :     return AS;
     538             : 
     539          25 :   if (!AS.hasAttributes())
     540           0 :     return *this;
     541             : 
     542          25 :   AttrBuilder B(AS);
     543          59 :   for (const auto I : *this)
     544          34 :     B.addAttribute(I);
     545             : 
     546          25 :  return get(C, B);
     547             : }
     548             : 
     549       18139 : AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
     550             :                                              Attribute::AttrKind Kind) const {
     551       18139 :   if (!hasAttribute(Kind)) return *this;
     552       14874 :   AttrBuilder B(*this);
     553       14874 :   B.removeAttribute(Kind);
     554       14874 :   return get(C, B);
     555             : }
     556             : 
     557      221377 : AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
     558             :                                              StringRef Kind) const {
     559      221377 :   if (!hasAttribute(Kind)) return *this;
     560      221377 :   AttrBuilder B(*this);
     561      221377 :   B.removeAttribute(Kind);
     562      221377 :   return get(C, B);
     563             : }
     564             : 
     565       10940 : AttributeSet AttributeSet::removeAttributes(LLVMContext &C,
     566             :                                               const AttrBuilder &Attrs) const {
     567       10940 :   AttrBuilder B(*this);
     568       10940 :   B.remove(Attrs);
     569       21880 :   return get(C, B);
     570             : }
     571             : 
     572           4 : unsigned AttributeSet::getNumAttributes() const {
     573           4 :   return SetNode ? SetNode->getNumAttributes() : 0;
     574             : }
     575             : 
     576   367417712 : bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const {
     577   589785455 :   return SetNode ? SetNode->hasAttribute(Kind) : false;
     578             : }
     579             : 
     580    22297017 : bool AttributeSet::hasAttribute(StringRef Kind) const {
     581    22297017 :   return SetNode ? SetNode->hasAttribute(Kind) : false;
     582             : }
     583             : 
     584     4563931 : Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const {
     585     4563931 :   return SetNode ? SetNode->getAttribute(Kind) : Attribute();
     586             : }
     587             : 
     588    32659063 : Attribute AttributeSet::getAttribute(StringRef Kind) const {
     589    32659063 :   return SetNode ? SetNode->getAttribute(Kind) : Attribute();
     590             : }
     591             : 
     592     2036308 : unsigned AttributeSet::getAlignment() const {
     593     2036308 :   return SetNode ? SetNode->getAlignment() : 0;
     594             : }
     595             : 
     596          65 : unsigned AttributeSet::getStackAlignment() const {
     597          65 :   return SetNode ? SetNode->getStackAlignment() : 0;
     598             : }
     599             : 
     600     1488186 : uint64_t AttributeSet::getDereferenceableBytes() const {
     601     1488186 :   return SetNode ? SetNode->getDereferenceableBytes() : 0;
     602             : }
     603             : 
     604       76880 : uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
     605       76880 :   return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
     606             : }
     607             : 
     608          83 : std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const {
     609          83 :   return SetNode ? SetNode->getAllocSizeArgs()
     610         166 :                  : std::pair<unsigned, Optional<unsigned>>(0, 0);
     611             : }
     612             : 
     613      114292 : std::string AttributeSet::getAsString(bool InAttrGrp) const {
     614      114292 :   return SetNode ? SetNode->getAsString(InAttrGrp) : "";
     615             : }
     616             : 
     617     4291547 : AttributeSet::iterator AttributeSet::begin() const {
     618     8583094 :   return SetNode ? SetNode->begin() : nullptr;
     619             : }
     620             : 
     621     4291547 : AttributeSet::iterator AttributeSet::end() const {
     622     8583094 :   return SetNode ? SetNode->end() : nullptr;
     623             : }
     624             : 
     625             : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
     626             : LLVM_DUMP_METHOD void AttributeSet::dump() const {
     627             :   dbgs() << "AS =\n";
     628             :     dbgs() << "  { ";
     629             :     dbgs() << getAsString(true) << " }\n";
     630             : }
     631             : #endif
     632             : 
     633             : //===----------------------------------------------------------------------===//
     634             : // AttributeSetNode Definition
     635             : //===----------------------------------------------------------------------===//
     636             : 
     637      200012 : AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
     638      200012 :     : AvailableAttrs(0), NumAttrs(Attrs.size()) {
     639             :   // There's memory after the node where we can store the entries in.
     640             :   std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>());
     641             : 
     642     2929072 :   for (const auto I : *this) {
     643     1364530 :     if (!I.isStringAttribute()) {
     644      286898 :       AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum();
     645             :     }
     646             :   }
     647      200012 : }
     648             : 
     649     5135885 : AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
     650             :                                         ArrayRef<Attribute> Attrs) {
     651     5135885 :   if (Attrs.empty())
     652             :     return nullptr;
     653             : 
     654             :   // Otherwise, build a key to look up the existing attributes.
     655     2654515 :   LLVMContextImpl *pImpl = C.pImpl;
     656             :   FoldingSetNodeID ID;
     657             : 
     658             :   SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
     659             :   llvm::sort(SortedAttrs.begin(), SortedAttrs.end());
     660             : 
     661    37160777 :   for (const auto Attr : SortedAttrs)
     662             :     Attr.Profile(ID);
     663             : 
     664             :   void *InsertPoint;
     665             :   AttributeSetNode *PA =
     666             :     pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
     667             : 
     668             :   // If we didn't find any existing attributes of the same shape then create a
     669             :   // new one and insert it.
     670     2654515 :   if (!PA) {
     671             :     // Coallocate entries after the AttributeSetNode itself.
     672      200012 :     void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
     673      200012 :     PA = new (Mem) AttributeSetNode(SortedAttrs);
     674      200012 :     pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
     675             :   }
     676             : 
     677             :   // Return the AttributeSetNode that we found or created.
     678             :   return PA;
     679             : }
     680             : 
     681     4972317 : AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
     682             :   // Add target-independent attributes.
     683             :   SmallVector<Attribute, 8> Attrs;
     684   293366703 :   for (Attribute::AttrKind Kind = Attribute::None;
     685   591705723 :        Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) {
     686   293366703 :     if (!B.contains(Kind))
     687   290559425 :       continue;
     688             : 
     689     2807278 :     Attribute Attr;
     690     2807278 :     switch (Kind) {
     691       92092 :     case Attribute::Alignment:
     692       92092 :       Attr = Attribute::getWithAlignment(C, B.getAlignment());
     693       92092 :       break;
     694         204 :     case Attribute::StackAlignment:
     695         204 :       Attr = Attribute::getWithStackAlignment(C, B.getStackAlignment());
     696         204 :       break;
     697      188076 :     case Attribute::Dereferenceable:
     698      188076 :       Attr = Attribute::getWithDereferenceableBytes(
     699      188076 :           C, B.getDereferenceableBytes());
     700      188076 :       break;
     701          95 :     case Attribute::DereferenceableOrNull:
     702          95 :       Attr = Attribute::getWithDereferenceableOrNullBytes(
     703          95 :           C, B.getDereferenceableOrNullBytes());
     704          95 :       break;
     705         113 :     case Attribute::AllocSize: {
     706         113 :       auto A = B.getAllocSizeArgs();
     707         113 :       Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
     708             :       break;
     709             :     }
     710     2526698 :     default:
     711     2526698 :       Attr = Attribute::get(C, Kind);
     712             :     }
     713     2807278 :     Attrs.push_back(Attr);
     714             :   }
     715             : 
     716             :   // Add target-dependent (string) attributes.
     717    19098044 :   for (const auto &TDA : B.td_attrs())
     718    14125727 :     Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second));
     719             : 
     720     9944634 :   return get(C, Attrs);
     721             : }
     722             : 
     723    20639656 : bool AttributeSetNode::hasAttribute(StringRef Kind) const {
     724   320104710 :   for (const auto I : *this)
     725   150399805 :     if (I.hasAttribute(Kind))
     726      667279 :       return true;
     727    19972378 :   return false;
     728             : }
     729             : 
     730     4547602 : Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
     731     9095204 :   if (hasAttribute(Kind)) {
     732         203 :     for (const auto I : *this)
     733         159 :       if (I.hasAttribute(Kind))
     734         115 :         return I;
     735             :   }
     736     4547487 :   return {};
     737             : }
     738             : 
     739    31205803 : Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
     740   536335869 :   for (const auto I : *this)
     741   263231411 :     if (I.hasAttribute(Kind))
     742    10666382 :       return I;
     743    20539425 :   return {};
     744             : }
     745             : 
     746      781295 : unsigned AttributeSetNode::getAlignment() const {
     747     1840561 :   for (const auto I : *this)
     748      957324 :     if (I.hasAttribute(Attribute::Alignment))
     749      427691 :       return I.getAlignment();
     750      353604 :   return 0;
     751             : }
     752             : 
     753          65 : unsigned AttributeSetNode::getStackAlignment() const {
     754         115 :   for (const auto I : *this)
     755          90 :     if (I.hasAttribute(Attribute::StackAlignment))
     756          65 :       return I.getStackAlignment();
     757           0 :   return 0;
     758             : }
     759             : 
     760      398649 : uint64_t AttributeSetNode::getDereferenceableBytes() const {
     761     1290529 :   for (const auto I : *this)
     762      513932 :     if (I.hasAttribute(Attribute::Dereferenceable))
     763       67992 :       return I.getDereferenceableBytes();
     764      330657 :   return 0;
     765             : }
     766             : 
     767        7163 : uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
     768       28471 :   for (const auto I : *this)
     769       10673 :     if (I.hasAttribute(Attribute::DereferenceableOrNull))
     770          19 :       return I.getDereferenceableOrNullBytes();
     771        7144 :   return 0;
     772             : }
     773             : 
     774             : std::pair<unsigned, Optional<unsigned>>
     775          83 : AttributeSetNode::getAllocSizeArgs() const {
     776          83 :   for (const auto I : *this)
     777          83 :     if (I.hasAttribute(Attribute::AllocSize))
     778          83 :       return I.getAllocSizeArgs();
     779             :   return std::make_pair(0, 0);
     780             : }
     781             : 
     782      114292 : std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
     783             :   std::string Str;
     784      819720 :   for (iterator I = begin(), E = end(); I != E; ++I) {
     785      352714 :     if (I != begin())
     786             :       Str += ' ';
     787      705428 :     Str += I->getAsString(InAttrGrp);
     788             :   }
     789      114292 :   return Str;
     790             : }
     791             : 
     792             : //===----------------------------------------------------------------------===//
     793             : // AttributeListImpl Definition
     794             : //===----------------------------------------------------------------------===//
     795             : 
     796             : /// Map from AttributeList index to the internal array index. Adding one happens
     797             : /// to work, but it relies on unsigned integer wrapping. MSVC warns about
     798             : /// unsigned wrapping in constexpr functions, so write out the conditional. LLVM
     799             : /// folds it to add anyway.
     800             : static constexpr unsigned attrIdxToArrayIdx(unsigned Index) {
     801   416458924 :   return Index == AttributeList::FunctionIndex ? 0 : Index + 1;
     802             : }
     803             : 
     804      325812 : AttributeListImpl::AttributeListImpl(LLVMContext &C,
     805      325812 :                                      ArrayRef<AttributeSet> Sets)
     806      325812 :     : AvailableFunctionAttrs(0), Context(C), NumAttrSets(Sets.size()) {
     807             :   assert(!Sets.empty() && "pointless AttributeListImpl");
     808             : 
     809             :   // There's memory after the node where we can store the entries in.
     810             :   std::copy(Sets.begin(), Sets.end(), getTrailingObjects<AttributeSet>());
     811             : 
     812             :   // Initialize AvailableFunctionAttrs summary bitset.
     813             :   static_assert(Attribute::EndAttrKinds <=
     814             :                     sizeof(AvailableFunctionAttrs) * CHAR_BIT,
     815             :                 "Too many attributes");
     816             :   static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U,
     817             :                 "function should be stored in slot 0");
     818     3017791 :   for (const auto I : Sets[0]) {
     819     2691979 :     if (!I.isStringAttribute())
     820      383956 :       AvailableFunctionAttrs |= 1ULL << I.getKindAsEnum();
     821             :   }
     822      325812 : }
     823             : 
     824     2901894 : void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
     825     2901894 :   Profile(ID, makeArrayRef(begin(), end()));
     826     2901894 : }
     827             : 
     828     5345126 : void AttributeListImpl::Profile(FoldingSetNodeID &ID,
     829             :                                 ArrayRef<AttributeSet> Sets) {
     830    27714620 :   for (const auto &Set : Sets)
     831    11184747 :     ID.AddPointer(Set.SetNode);
     832     5345126 : }
     833             : 
     834             : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
     835             : LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
     836             :   AttributeList(const_cast<AttributeListImpl *>(this)).dump();
     837             : }
     838             : #endif
     839             : 
     840             : //===----------------------------------------------------------------------===//
     841             : // AttributeList Construction and Mutation Methods
     842             : //===----------------------------------------------------------------------===//
     843             : 
     844     2443232 : AttributeList AttributeList::getImpl(LLVMContext &C,
     845             :                                      ArrayRef<AttributeSet> AttrSets) {
     846             :   assert(!AttrSets.empty() && "pointless AttributeListImpl");
     847             : 
     848     2443232 :   LLVMContextImpl *pImpl = C.pImpl;
     849             :   FoldingSetNodeID ID;
     850     2443232 :   AttributeListImpl::Profile(ID, AttrSets);
     851             : 
     852             :   void *InsertPoint;
     853             :   AttributeListImpl *PA =
     854             :       pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
     855             : 
     856             :   // If we didn't find any existing attributes of the same shape then
     857             :   // create a new one and insert it.
     858     2443232 :   if (!PA) {
     859             :     // Coallocate entries after the AttributeListImpl itself.
     860             :     void *Mem = ::operator new(
     861      325812 :         AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()));
     862      325812 :     PA = new (Mem) AttributeListImpl(C, AttrSets);
     863      325812 :     pImpl->AttrsLists.InsertNode(PA, InsertPoint);
     864             :   }
     865             : 
     866             :   // Return the AttributesList that we found or created.
     867     4886464 :   return AttributeList(PA);
     868             : }
     869             : 
     870             : AttributeList
     871      376312 : AttributeList::get(LLVMContext &C,
     872             :                    ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
     873             :   // If there are no attributes then return a null AttributesList pointer.
     874      376312 :   if (Attrs.empty())
     875      212760 :     return {};
     876             : 
     877             :   assert(std::is_sorted(Attrs.begin(), Attrs.end(),
     878             :                         [](const std::pair<unsigned, Attribute> &LHS,
     879             :                            const std::pair<unsigned, Attribute> &RHS) {
     880             :                           return LHS.first < RHS.first;
     881             :                         }) && "Misordered Attributes list!");
     882             :   assert(llvm::none_of(Attrs,
     883             :                        [](const std::pair<unsigned, Attribute> &Pair) {
     884             :                          return Pair.second.hasAttribute(Attribute::None);
     885             :                        }) &&
     886             :          "Pointless attribute!");
     887             : 
     888             :   // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
     889             :   // list.
     890             :   SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec;
     891      163553 :   for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
     892      327105 :          E = Attrs.end(); I != E; ) {
     893      163553 :     unsigned Index = I->first;
     894             :     SmallVector<Attribute, 4> AttrVec;
     895      803775 :     while (I != E && I->first == Index) {
     896      320111 :       AttrVec.push_back(I->second);
     897      320111 :       ++I;
     898             :     }
     899             : 
     900      163553 :     AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
     901             :   }
     902             : 
     903      163552 :   return get(C, AttrPairVec);
     904             : }
     905             : 
     906             : AttributeList
     907      449836 : AttributeList::get(LLVMContext &C,
     908             :                    ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
     909             :   // If there are no attributes then return a null AttributesList pointer.
     910      449836 :   if (Attrs.empty())
     911           0 :     return {};
     912             : 
     913             :   assert(std::is_sorted(Attrs.begin(), Attrs.end(),
     914             :                         [](const std::pair<unsigned, AttributeSet> &LHS,
     915             :                            const std::pair<unsigned, AttributeSet> &RHS) {
     916             :                           return LHS.first < RHS.first;
     917             :                         }) &&
     918             :          "Misordered Attributes list!");
     919             :   assert(llvm::none_of(Attrs,
     920             :                        [](const std::pair<unsigned, AttributeSet> &Pair) {
     921             :                          return !Pair.second.hasAttributes();
     922             :                        }) &&
     923             :          "Pointless attribute!");
     924             : 
     925      449836 :   unsigned MaxIndex = Attrs.back().first;
     926             :   // If the MaxIndex is FunctionIndex and there are other indices in front
     927             :   // of it, we need to use the largest of those to get the right size.
     928      449836 :   if (MaxIndex == FunctionIndex && Attrs.size() > 1)
     929           2 :     MaxIndex = Attrs[Attrs.size() - 2].first;
     930             : 
     931     1349508 :   SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
     932     1349510 :   for (const auto Pair : Attrs)
     933      899674 :     AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;
     934             : 
     935      449836 :   return getImpl(C, AttrVec);
     936             : }
     937             : 
     938      911169 : AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs,
     939             :                                  AttributeSet RetAttrs,
     940             :                                  ArrayRef<AttributeSet> ArgAttrs) {
     941             :   // Scan from the end to find the last argument with attributes.  Most
     942             :   // arguments don't have attributes, so it's nice if we can have fewer unique
     943             :   // AttributeListImpls by dropping empty attribute sets at the end of the list.
     944             :   unsigned NumSets = 0;
     945     2196086 :   for (size_t I = ArgAttrs.size(); I != 0; --I) {
     946     2835982 :     if (ArgAttrs[I - 1].hasAttributes()) {
     947      133074 :       NumSets = I + 2;
     948      133074 :       break;
     949             :     }
     950             :   }
     951      911169 :   if (NumSets == 0) {
     952             :     // Check function and return attributes if we didn't have argument
     953             :     // attributes.
     954      778095 :     if (RetAttrs.hasAttributes())
     955             :       NumSets = 2;
     956      746406 :     else if (FnAttrs.hasAttributes())
     957             :       NumSets = 1;
     958             :   }
     959             : 
     960             :   // If all attribute sets were empty, we can use the empty attribute list.
     961      548893 :   if (NumSets == 0)
     962      415819 :     return {};
     963             : 
     964             :   SmallVector<AttributeSet, 8> AttrSets;
     965      495350 :   AttrSets.reserve(NumSets);
     966             :   // If we have any attributes, we always have function attributes.
     967      495350 :   AttrSets.push_back(FnAttrs);
     968      495350 :   if (NumSets > 1)
     969      164763 :     AttrSets.push_back(RetAttrs);
     970      495350 :   if (NumSets > 2) {
     971             :     // Drop the empty argument attribute sets at the end.
     972      133074 :     ArgAttrs = ArgAttrs.take_front(NumSets - 2);
     973      133074 :     AttrSets.insert(AttrSets.end(), ArgAttrs.begin(), ArgAttrs.end());
     974             :   }
     975             : 
     976      495350 :   return getImpl(C, AttrSets);
     977             : }
     978             : 
     979        6378 : AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
     980             :                                  const AttrBuilder &B) {
     981        6378 :   if (!B.hasAttributes())
     982          38 :     return {};
     983             :   Index = attrIdxToArrayIdx(Index);
     984       12680 :   SmallVector<AttributeSet, 8> AttrSets(Index + 1);
     985       12680 :   AttrSets[Index] = AttributeSet::get(C, B);
     986        6340 :   return getImpl(C, AttrSets);
     987             : }
     988             : 
     989      376311 : AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
     990             :                                  ArrayRef<Attribute::AttrKind> Kinds) {
     991             :   SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
     992     1016529 :   for (const auto K : Kinds)
     993      320109 :     Attrs.emplace_back(Index, Attribute::get(C, K));
     994      752622 :   return get(C, Attrs);
     995             : }
     996             : 
     997           0 : AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
     998             :                                  ArrayRef<StringRef> Kinds) {
     999             :   SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
    1000           0 :   for (const auto K : Kinds)
    1001           0 :     Attrs.emplace_back(Index, Attribute::get(C, K));
    1002           0 :   return get(C, Attrs);
    1003             : }
    1004             : 
    1005      140546 : AttributeList AttributeList::get(LLVMContext &C,
    1006             :                                  ArrayRef<AttributeList> Attrs) {
    1007      140546 :   if (Attrs.empty())
    1008           0 :     return {};
    1009      140546 :   if (Attrs.size() == 1)
    1010      128929 :     return Attrs[0];
    1011             : 
    1012       11617 :   unsigned MaxSize = 0;
    1013       69395 :   for (const auto List : Attrs)
    1014       57778 :     MaxSize = std::max(MaxSize, List.getNumAttrSets());
    1015             : 
    1016             :   // If every list was empty, there is no point in merging the lists.
    1017       11617 :   if (MaxSize == 0)
    1018           1 :     return {};
    1019             : 
    1020       23232 :   SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
    1021      107354 :   for (unsigned I = 0; I < MaxSize; ++I) {
    1022             :     AttrBuilder CurBuilder;
    1023      296035 :     for (const auto List : Attrs)
    1024      248166 :       CurBuilder.merge(List.getAttributes(I - 1));
    1025       95738 :     NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
    1026             :   }
    1027             : 
    1028       11616 :   return getImpl(C, NewAttrSets);
    1029             : }
    1030             : 
    1031      360780 : AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
    1032             :                                           Attribute::AttrKind Kind) const {
    1033      360780 :   if (hasAttribute(Index, Kind)) return *this;
    1034             :   AttrBuilder B;
    1035      295817 :   B.addAttribute(Kind);
    1036      295817 :   return addAttributes(C, Index, B);
    1037             : }
    1038             : 
    1039          40 : AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
    1040             :                                           StringRef Kind,
    1041             :                                           StringRef Value) const {
    1042             :   AttrBuilder B;
    1043          40 :   B.addAttribute(Kind, Value);
    1044          80 :   return addAttributes(C, Index, B);
    1045             : }
    1046             : 
    1047      223504 : AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
    1048             :                                           Attribute A) const {
    1049             :   AttrBuilder B;
    1050      223504 :   B.addAttribute(A);
    1051      447008 :   return addAttributes(C, Index, B);
    1052             : }
    1053             : 
    1054     1597443 : AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
    1055             :                                            const AttrBuilder &B) const {
    1056     1597443 :   if (!B.hasAttributes())
    1057      442486 :     return *this;
    1058             : 
    1059     1154957 :   if (!pImpl)
    1060      572520 :     return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
    1061             : 
    1062             : #ifndef NDEBUG
    1063             :   // FIXME it is not obvious how this should work for alignment. For now, say
    1064             :   // we can't change a known alignment.
    1065             :   unsigned OldAlign = getAttributes(Index).getAlignment();
    1066             :   unsigned NewAlign = B.getAlignment();
    1067             :   assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
    1068             :          "Attempt to change alignment!");
    1069             : #endif
    1070             : 
    1071             :   Index = attrIdxToArrayIdx(Index);
    1072      868697 :   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
    1073     1737394 :   if (Index >= AttrSets.size())
    1074       16033 :     AttrSets.resize(Index + 1);
    1075             : 
    1076      868697 :   AttrBuilder Merged(AttrSets[Index]);
    1077      868697 :   Merged.merge(B);
    1078      868697 :   AttrSets[Index] = AttributeSet::get(C, Merged);
    1079             : 
    1080      868697 :   return getImpl(C, AttrSets);
    1081             : }
    1082             : 
    1083      251605 : AttributeList AttributeList::addParamAttribute(LLVMContext &C,
    1084             :                                                ArrayRef<unsigned> ArgNos,
    1085             :                                                Attribute A) const {
    1086             :   assert(std::is_sorted(ArgNos.begin(), ArgNos.end()));
    1087             : 
    1088      251605 :   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
    1089      251605 :   unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
    1090      503210 :   if (MaxIndex >= AttrSets.size())
    1091      205523 :     AttrSets.resize(MaxIndex + 1);
    1092             : 
    1093      796677 :   for (unsigned ArgNo : ArgNos) {
    1094      272536 :     unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
    1095      545072 :     AttrBuilder B(AttrSets[Index]);
    1096      272536 :     B.addAttribute(A);
    1097      272536 :     AttrSets[Index] = AttributeSet::get(C, B);
    1098             :   }
    1099             : 
    1100      503210 :   return getImpl(C, AttrSets);
    1101             : }
    1102             : 
    1103      273650 : AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
    1104             :                                              Attribute::AttrKind Kind) const {
    1105      273650 :   if (!hasAttribute(Index, Kind)) return *this;
    1106             : 
    1107             :   Index = attrIdxToArrayIdx(Index);
    1108       14871 :   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
    1109             :   assert(Index < AttrSets.size());
    1110             : 
    1111       29742 :   AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
    1112             : 
    1113       14871 :   return getImpl(C, AttrSets);
    1114             : }
    1115             : 
    1116      312732 : AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
    1117             :                                              StringRef Kind) const {
    1118      312732 :   if (!hasAttribute(Index, Kind)) return *this;
    1119             : 
    1120             :   Index = attrIdxToArrayIdx(Index);
    1121      221377 :   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
    1122             :   assert(Index < AttrSets.size());
    1123             : 
    1124      442754 :   AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
    1125             : 
    1126      221377 :   return getImpl(C, AttrSets);
    1127             : }
    1128             : 
    1129             : AttributeList
    1130       11158 : AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
    1131             :                                 const AttrBuilder &AttrsToRemove) const {
    1132       11158 :   if (!pImpl)
    1133         219 :     return {};
    1134             : 
    1135             :   Index = attrIdxToArrayIdx(Index);
    1136       10939 :   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
    1137       21878 :   if (Index >= AttrSets.size())
    1138          44 :     AttrSets.resize(Index + 1);
    1139             : 
    1140       10939 :   AttrSets[Index] = AttrSets[Index].removeAttributes(C, AttrsToRemove);
    1141             : 
    1142       10939 :   return getImpl(C, AttrSets);
    1143             : }
    1144             : 
    1145      455553 : AttributeList AttributeList::removeAttributes(LLVMContext &C,
    1146             :                                               unsigned WithoutIndex) const {
    1147      455553 :   if (!pImpl)
    1148      342952 :     return {};
    1149             :   WithoutIndex = attrIdxToArrayIdx(WithoutIndex);
    1150      112601 :   if (WithoutIndex >= getNumAttrSets())
    1151           0 :     return *this;
    1152      112601 :   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
    1153      225202 :   AttrSets[WithoutIndex] = AttributeSet();
    1154      112601 :   return getImpl(C, AttrSets);
    1155             : }
    1156             : 
    1157          66 : AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C,
    1158             :                                                     unsigned Index,
    1159             :                                                     uint64_t Bytes) const {
    1160             :   AttrBuilder B;
    1161          66 :   B.addDereferenceableAttr(Bytes);
    1162         132 :   return addAttributes(C, Index, B);
    1163             : }
    1164             : 
    1165             : AttributeList
    1166           0 : AttributeList::addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index,
    1167             :                                             uint64_t Bytes) const {
    1168             :   AttrBuilder B;
    1169           0 :   B.addDereferenceableOrNullAttr(Bytes);
    1170           0 :   return addAttributes(C, Index, B);
    1171             : }
    1172             : 
    1173             : AttributeList
    1174           0 : AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index,
    1175             :                                 unsigned ElemSizeArg,
    1176             :                                 const Optional<unsigned> &NumElemsArg) {
    1177             :   AttrBuilder B;
    1178           0 :   B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
    1179           0 :   return addAttributes(C, Index, B);
    1180             : }
    1181             : 
    1182             : //===----------------------------------------------------------------------===//
    1183             : // AttributeList Accessor Methods
    1184             : //===----------------------------------------------------------------------===//
    1185             : 
    1186          10 : LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); }
    1187             : 
    1188     2439102 : AttributeSet AttributeList::getParamAttributes(unsigned ArgNo) const {
    1189     2439102 :   return getAttributes(ArgNo + FirstArgIndex);
    1190             : }
    1191             : 
    1192      943079 : AttributeSet AttributeList::getRetAttributes() const {
    1193      943079 :   return getAttributes(ReturnIndex);
    1194             : }
    1195             : 
    1196     2178756 : AttributeSet AttributeList::getFnAttributes() const {
    1197     2178756 :   return getAttributes(FunctionIndex);
    1198             : }
    1199             : 
    1200   343315528 : bool AttributeList::hasAttribute(unsigned Index,
    1201             :                                  Attribute::AttrKind Kind) const {
    1202   343315528 :   return getAttributes(Index).hasAttribute(Kind);
    1203             : }
    1204             : 
    1205    21824714 : bool AttributeList::hasAttribute(unsigned Index, StringRef Kind) const {
    1206    21824714 :   return getAttributes(Index).hasAttribute(Kind);
    1207             : }
    1208             : 
    1209     2090305 : bool AttributeList::hasAttributes(unsigned Index) const {
    1210     4180610 :   return getAttributes(Index).hasAttributes();
    1211             : }
    1212             : 
    1213   108204020 : bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind) const {
    1214   213772984 :   return pImpl && pImpl->hasFnAttribute(Kind);
    1215             : }
    1216             : 
    1217    21183512 : bool AttributeList::hasFnAttribute(StringRef Kind) const {
    1218    21183512 :   return hasAttribute(AttributeList::FunctionIndex, Kind);
    1219             : }
    1220             : 
    1221    51556782 : bool AttributeList::hasParamAttribute(unsigned ArgNo,
    1222             :                                       Attribute::AttrKind Kind) const {
    1223    51556782 :   return hasAttribute(ArgNo + FirstArgIndex, Kind);
    1224             : }
    1225             : 
    1226     4618830 : bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
    1227             :                                      unsigned *Index) const {
    1228     4618830 :   if (!pImpl) return false;
    1229             : 
    1230    18180851 :   for (unsigned I = index_begin(), E = index_end(); I != E; ++I) {
    1231     7104658 :     if (hasAttribute(I, Attr)) {
    1232        3981 :       if (Index)
    1233         634 :         *Index = I;
    1234             :       return true;
    1235             :     }
    1236             :   }
    1237             : 
    1238             :   return false;
    1239             : }
    1240             : 
    1241     4563931 : Attribute AttributeList::getAttribute(unsigned Index,
    1242             :                                       Attribute::AttrKind Kind) const {
    1243     4563931 :   return getAttributes(Index).getAttribute(Kind);
    1244             : }
    1245             : 
    1246    32659048 : Attribute AttributeList::getAttribute(unsigned Index, StringRef Kind) const {
    1247    32659048 :   return getAttributes(Index).getAttribute(Kind);
    1248             : }
    1249             : 
    1250      152950 : unsigned AttributeList::getRetAlignment() const {
    1251      152950 :   return getAttributes(ReturnIndex).getAlignment();
    1252             : }
    1253             : 
    1254     1883356 : unsigned AttributeList::getParamAlignment(unsigned ArgNo) const {
    1255     1883356 :   return getAttributes(ArgNo + FirstArgIndex).getAlignment();
    1256             : }
    1257             : 
    1258          65 : unsigned AttributeList::getStackAlignment(unsigned Index) const {
    1259          65 :   return getAttributes(Index).getStackAlignment();
    1260             : }
    1261             : 
    1262     1488186 : uint64_t AttributeList::getDereferenceableBytes(unsigned Index) const {
    1263     1488186 :   return getAttributes(Index).getDereferenceableBytes();
    1264             : }
    1265             : 
    1266       76880 : uint64_t AttributeList::getDereferenceableOrNullBytes(unsigned Index) const {
    1267       76880 :   return getAttributes(Index).getDereferenceableOrNullBytes();
    1268             : }
    1269             : 
    1270             : std::pair<unsigned, Optional<unsigned>>
    1271          83 : AttributeList::getAllocSizeArgs(unsigned Index) const {
    1272          83 :   return getAttributes(Index).getAllocSizeArgs();
    1273             : }
    1274             : 
    1275        8740 : std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
    1276        8740 :   return getAttributes(Index).getAsString(InAttrGrp);
    1277             : }
    1278             : 
    1279   413800285 : AttributeSet AttributeList::getAttributes(unsigned Index) const {
    1280             :   Index = attrIdxToArrayIdx(Index);
    1281   413800285 :   if (!pImpl || Index >= getNumAttrSets())
    1282    48005700 :     return {};
    1283   365794586 :   return pImpl->begin()[Index];
    1284             : }
    1285             : 
    1286     1480090 : AttributeList::iterator AttributeList::begin() const {
    1287     2960180 :   return pImpl ? pImpl->begin() : nullptr;
    1288             : }
    1289             : 
    1290     1480090 : AttributeList::iterator AttributeList::end() const {
    1291     2960180 :   return pImpl ? pImpl->end() : nullptr;
    1292             : }
    1293             : 
    1294             : //===----------------------------------------------------------------------===//
    1295             : // AttributeList Introspection Methods
    1296             : //===----------------------------------------------------------------------===//
    1297             : 
    1298   399871967 : unsigned AttributeList::getNumAttrSets() const {
    1299   399871967 :   return pImpl ? pImpl->NumAttrSets : 0;
    1300             : }
    1301             : 
    1302             : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
    1303             : LLVM_DUMP_METHOD void AttributeList::dump() const {
    1304             :   dbgs() << "PAL[\n";
    1305             : 
    1306             :   for (unsigned i = index_begin(), e = index_end(); i != e; ++i) {
    1307             :     if (getAttributes(i).hasAttributes())
    1308             :       dbgs() << "  { " << i << " => " << getAsString(i) << " }\n";
    1309             :   }
    1310             : 
    1311             :   dbgs() << "]\n";
    1312             : }
    1313             : #endif
    1314             : 
    1315             : //===----------------------------------------------------------------------===//
    1316             : // AttrBuilder Method Implementations
    1317             : //===----------------------------------------------------------------------===//
    1318             : 
    1319             : // FIXME: Remove this ctor, use AttributeSet.
    1320       21960 : AttrBuilder::AttrBuilder(AttributeList AL, unsigned Index) {
    1321       10980 :   AttributeSet AS = AL.getAttributes(Index);
    1322       12110 :   for (const auto &A : AS)
    1323        1130 :     addAttribute(A);
    1324       10980 : }
    1325             : 
    1326     5371890 : AttrBuilder::AttrBuilder(AttributeSet AS) {
    1327    15296435 :   for (const auto &A : AS)
    1328    12610490 :     addAttribute(A);
    1329     2685945 : }
    1330             : 
    1331     1778669 : void AttrBuilder::clear() {
    1332             :   Attrs.reset();
    1333             :   TargetDepAttrs.clear();
    1334     1778669 :   Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0;
    1335     1778669 :   AllocSizeArgs = 0;
    1336     1778669 : }
    1337             : 
    1338     2766478 : AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
    1339             :   assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
    1340             :   assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment &&
    1341             :          Val != Attribute::Dereferenceable && Val != Attribute::AllocSize &&
    1342             :          "Adding integer attribute without adding a value!");
    1343             :   Attrs[Val] = true;
    1344     2766478 :   return *this;
    1345             : }
    1346             : 
    1347    13107762 : AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
    1348    13107762 :   if (Attr.isStringAttribute()) {
    1349    11262144 :     addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
    1350    11262144 :     return *this;
    1351             :   }
    1352             : 
    1353     1845618 :   Attribute::AttrKind Kind = Attr.getKindAsEnum();
    1354             :   Attrs[Kind] = true;
    1355             : 
    1356     1845618 :   if (Kind == Attribute::Alignment)
    1357      142569 :     Alignment = Attr.getAlignment();
    1358     1703049 :   else if (Kind == Attribute::StackAlignment)
    1359         119 :     StackAlignment = Attr.getStackAlignment();
    1360     1702930 :   else if (Kind == Attribute::Dereferenceable)
    1361       91397 :     DerefBytes = Attr.getDereferenceableBytes();
    1362     1611533 :   else if (Kind == Attribute::DereferenceableOrNull)
    1363         102 :     DerefOrNullBytes = Attr.getDereferenceableOrNullBytes();
    1364     1611431 :   else if (Kind == Attribute::AllocSize)
    1365          44 :     AllocSizeArgs = Attr.getValueAsInt();
    1366             :   return *this;
    1367             : }
    1368             : 
    1369    14234108 : AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
    1370    42702324 :   TargetDepAttrs[A] = V;
    1371    14234108 :   return *this;
    1372             : }
    1373             : 
    1374       61783 : AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
    1375             :   assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
    1376             :   Attrs[Val] = false;
    1377             : 
    1378       61783 :   if (Val == Attribute::Alignment)
    1379       14267 :     Alignment = 0;
    1380       47516 :   else if (Val == Attribute::StackAlignment)
    1381           1 :     StackAlignment = 0;
    1382       47515 :   else if (Val == Attribute::Dereferenceable)
    1383           0 :     DerefBytes = 0;
    1384       47515 :   else if (Val == Attribute::DereferenceableOrNull)
    1385           0 :     DerefOrNullBytes = 0;
    1386       47515 :   else if (Val == Attribute::AllocSize)
    1387           2 :     AllocSizeArgs = 0;
    1388             : 
    1389       61783 :   return *this;
    1390             : }
    1391             : 
    1392           0 : AttrBuilder &AttrBuilder::removeAttributes(AttributeList A, uint64_t Index) {
    1393           0 :   remove(A.getAttributes(Index));
    1394           0 :   return *this;
    1395             : }
    1396             : 
    1397      221377 : AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
    1398      221377 :   auto I = TargetDepAttrs.find(A);
    1399      221377 :   if (I != TargetDepAttrs.end())
    1400             :     TargetDepAttrs.erase(I);
    1401      221377 :   return *this;
    1402             : }
    1403             : 
    1404         113 : std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
    1405         226 :   return unpackAllocSizeArgs(AllocSizeArgs);
    1406             : }
    1407             : 
    1408        8873 : AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) {
    1409        8873 :   if (Align == 0) return *this;
    1410             : 
    1411             :   assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
    1412             :   assert(Align <= 0x40000000 && "Alignment too large.");
    1413             : 
    1414             :   Attrs[Attribute::Alignment] = true;
    1415        8873 :   Alignment = Align;
    1416        8873 :   return *this;
    1417             : }
    1418             : 
    1419          87 : AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) {
    1420             :   // Default alignment, allow the target to define how to align it.
    1421          87 :   if (Align == 0) return *this;
    1422             : 
    1423             :   assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
    1424             :   assert(Align <= 0x100 && "Alignment too large.");
    1425             : 
    1426             :   Attrs[Attribute::StackAlignment] = true;
    1427          87 :   StackAlignment = Align;
    1428          87 :   return *this;
    1429             : }
    1430             : 
    1431      240790 : AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
    1432      240790 :   if (Bytes == 0) return *this;
    1433             : 
    1434             :   Attrs[Attribute::Dereferenceable] = true;
    1435      238872 :   DerefBytes = Bytes;
    1436      238872 :   return *this;
    1437             : }
    1438             : 
    1439      110010 : AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
    1440      110010 :   if (Bytes == 0)
    1441             :     return *this;
    1442             : 
    1443             :   Attrs[Attribute::DereferenceableOrNull] = true;
    1444      110010 :   DerefOrNullBytes = Bytes;
    1445      110010 :   return *this;
    1446             : }
    1447             : 
    1448          58 : AttrBuilder &AttrBuilder::addAllocSizeAttr(unsigned ElemSize,
    1449             :                                            const Optional<unsigned> &NumElems) {
    1450          58 :   return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
    1451             : }
    1452             : 
    1453          68 : AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
    1454             :   // (0, 0) is our "not present" value, so we need to check for it here.
    1455             :   assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
    1456             : 
    1457             :   Attrs[Attribute::AllocSize] = true;
    1458             :   // Reuse existing machinery to store this as a single 64-bit integer so we can
    1459             :   // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
    1460          68 :   AllocSizeArgs = RawArgs;
    1461          68 :   return *this;
    1462             : }
    1463             : 
    1464     1505358 : AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
    1465             :   // FIXME: What if both have alignments, but they don't match?!
    1466     1505358 :   if (!Alignment)
    1467     1504900 :     Alignment = B.Alignment;
    1468             : 
    1469     1505358 :   if (!StackAlignment)
    1470     1505291 :     StackAlignment = B.StackAlignment;
    1471             : 
    1472     1505358 :   if (!DerefBytes)
    1473     1489797 :     DerefBytes = B.DerefBytes;
    1474             : 
    1475     1505358 :   if (!DerefOrNullBytes)
    1476     1505353 :     DerefOrNullBytes = B.DerefOrNullBytes;
    1477             : 
    1478     1505358 :   if (!AllocSizeArgs)
    1479     1505344 :     AllocSizeArgs = B.AllocSizeArgs;
    1480             : 
    1481             :   Attrs |= B.Attrs;
    1482             : 
    1483     3941262 :   for (auto I : B.td_attrs())
    1484      811968 :     TargetDepAttrs[I.first] = I.second;
    1485             : 
    1486     1505358 :   return *this;
    1487             : }
    1488             : 
    1489       14016 : AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) {
    1490             :   // FIXME: What if both have alignments, but they don't match?!
    1491       14016 :   if (B.Alignment)
    1492           2 :     Alignment = 0;
    1493             : 
    1494       14016 :   if (B.StackAlignment)
    1495           1 :     StackAlignment = 0;
    1496             : 
    1497       14016 :   if (B.DerefBytes)
    1498        3093 :     DerefBytes = 0;
    1499             : 
    1500       14016 :   if (B.DerefOrNullBytes)
    1501        3089 :     DerefOrNullBytes = 0;
    1502             : 
    1503       14016 :   if (B.AllocSizeArgs)
    1504           0 :     AllocSizeArgs = 0;
    1505             : 
    1506             :   Attrs &= ~B.Attrs;
    1507             : 
    1508       14112 :   for (auto I : B.td_attrs())
    1509             :     TargetDepAttrs.erase(I.first);
    1510             : 
    1511       14016 :   return *this;
    1512             : }
    1513             : 
    1514      259131 : bool AttrBuilder::overlaps(const AttrBuilder &B) const {
    1515             :   // First check if any of the target independent attributes overlap.
    1516      259131 :   if ((Attrs & B.Attrs).any())
    1517             :     return true;
    1518             : 
    1519             :   // Then check if any target dependent ones do.
    1520      259192 :   for (const auto &I : td_attrs())
    1521          66 :     if (B.contains(I.first))
    1522             :       return true;
    1523             : 
    1524             :   return false;
    1525             : }
    1526             : 
    1527          66 : bool AttrBuilder::contains(StringRef A) const {
    1528          66 :   return TargetDepAttrs.find(A) != TargetDepAttrs.end();
    1529             : }
    1530             : 
    1531     2347959 : bool AttrBuilder::hasAttributes() const {
    1532     3947259 :   return !Attrs.none() || !TargetDepAttrs.empty();
    1533             : }
    1534             : 
    1535           0 : bool AttrBuilder::hasAttributes(AttributeList AL, uint64_t Index) const {
    1536           0 :   AttributeSet AS = AL.getAttributes(Index);
    1537             : 
    1538           0 :   for (const auto Attr : AS) {
    1539           0 :     if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
    1540           0 :       if (contains(Attr.getKindAsEnum()))
    1541           0 :         return true;
    1542             :     } else {
    1543             :       assert(Attr.isStringAttribute() && "Invalid attribute kind!");
    1544           0 :       return contains(Attr.getKindAsString());
    1545             :     }
    1546             :   }
    1547             : 
    1548           0 :   return false;
    1549             : }
    1550             : 
    1551      761548 : bool AttrBuilder::hasAlignmentAttr() const {
    1552      761548 :   return Alignment != 0;
    1553             : }
    1554             : 
    1555        3407 : bool AttrBuilder::operator==(const AttrBuilder &B) {
    1556        3407 :   if (Attrs != B.Attrs)
    1557             :     return false;
    1558             : 
    1559             :   for (td_const_iterator I = TargetDepAttrs.begin(),
    1560        3394 :          E = TargetDepAttrs.end(); I != E; ++I)
    1561           0 :     if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end())
    1562             :       return false;
    1563             : 
    1564        6787 :   return Alignment == B.Alignment && StackAlignment == B.StackAlignment &&
    1565        3393 :          DerefBytes == B.DerefBytes;
    1566             : }
    1567             : 
    1568             : //===----------------------------------------------------------------------===//
    1569             : // AttributeFuncs Function Defintions
    1570             : //===----------------------------------------------------------------------===//
    1571             : 
    1572             : /// Which attributes cannot be applied to a type.
    1573      262339 : AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
    1574             :   AttrBuilder Incompatible;
    1575             : 
    1576      262339 :   if (!Ty->isIntegerTy())
    1577             :     // Attribute that only apply to integers.
    1578      159966 :     Incompatible.addAttribute(Attribute::SExt)
    1579      159966 :       .addAttribute(Attribute::ZExt);
    1580             : 
    1581      262339 :   if (!Ty->isPointerTy())
    1582             :     // Attribute that only apply to pointers.
    1583      109926 :     Incompatible.addAttribute(Attribute::ByVal)
    1584      109926 :       .addAttribute(Attribute::Nest)
    1585      109926 :       .addAttribute(Attribute::NoAlias)
    1586      109926 :       .addAttribute(Attribute::NoCapture)
    1587      109926 :       .addAttribute(Attribute::NonNull)
    1588      109926 :       .addDereferenceableAttr(1) // the int here is ignored
    1589      109926 :       .addDereferenceableOrNullAttr(1) // the int here is ignored
    1590      109926 :       .addAttribute(Attribute::ReadNone)
    1591      109926 :       .addAttribute(Attribute::ReadOnly)
    1592      109926 :       .addAttribute(Attribute::StructRet)
    1593      109926 :       .addAttribute(Attribute::InAlloca);
    1594             : 
    1595      262339 :   return Incompatible;
    1596             : }
    1597             : 
    1598             : template<typename AttrClass>
    1599     2277300 : static bool isEqual(const Function &Caller, const Function &Callee) {
    1600             :   return Caller.getFnAttribute(AttrClass::getKind()) ==
    1601     2277300 :          Callee.getFnAttribute(AttrClass::getKind());
    1602             : }
    1603             : 
    1604             : /// Compute the logical AND of the attributes of the caller and the
    1605             : /// callee.
    1606             : ///
    1607             : /// This function sets the caller's attribute to false if the callee's attribute
    1608             : /// is false.
    1609             : template<typename AttrClass>
    1610      380672 : static void setAND(Function &Caller, const Function &Callee) {
    1611      380688 :   if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
    1612          16 :       !AttrClass::isSet(Callee, AttrClass::getKind()))
    1613           8 :     AttrClass::set(Caller, AttrClass::getKind(), false);
    1614      380672 : }
    1615             : 
    1616             : /// Compute the logical OR of the attributes of the caller and the
    1617             : /// callee.
    1618             : ///
    1619             : /// This function sets the caller's attribute to true if the callee's attribute
    1620             : /// is true.
    1621             : template<typename AttrClass>
    1622      285504 : static void setOR(Function &Caller, const Function &Callee) {
    1623      570999 :   if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
    1624      190332 :       AttrClass::isSet(Callee, AttrClass::getKind()))
    1625           2 :     AttrClass::set(Caller, AttrClass::getKind(), true);
    1626      285504 : }
    1627             : 
    1628             : /// If the inlined function had a higher stack protection level than the
    1629             : /// calling function, then bump up the caller's stack protection level.
    1630       95168 : static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
    1631             :   // If upgrading the SSP attribute, clear out the old SSP Attributes first.
    1632             :   // Having multiple SSP attributes doesn't actually hurt, but it adds useless
    1633             :   // clutter to the IR.
    1634             :   AttrBuilder OldSSPAttr;
    1635       95168 :   OldSSPAttr.addAttribute(Attribute::StackProtect)
    1636       95168 :       .addAttribute(Attribute::StackProtectStrong)
    1637       95168 :       .addAttribute(Attribute::StackProtectReq);
    1638             : 
    1639       95168 :   if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
    1640           8 :     Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
    1641             :     Caller.addFnAttr(Attribute::StackProtectReq);
    1642      105531 :   } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
    1643             :              !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
    1644       10369 :     Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
    1645             :     Caller.addFnAttr(Attribute::StackProtectStrong);
    1646          87 :   } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
    1647       84876 :              !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
    1648             :              !Caller.hasFnAttribute(Attribute::StackProtectStrong))
    1649             :     Caller.addFnAttr(Attribute::StackProtect);
    1650       95168 : }
    1651             : 
    1652             : /// If the inlined function required stack probes, then ensure that
    1653             : /// the calling function has those too.
    1654       95168 : static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
    1655      190335 :   if (!Caller.hasFnAttribute("probe-stack") &&
    1656             :       Callee.hasFnAttribute("probe-stack")) {
    1657             :     Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
    1658             :   }
    1659       95168 : }
    1660             : 
    1661             : /// If the inlined function defines the size of guard region
    1662             : /// on the stack, then ensure that the calling function defines a guard region
    1663             : /// that is no larger.
    1664             : static void
    1665       95168 : adjustCallerStackProbeSize(Function &Caller, const Function &Callee) {
    1666       95168 :   if (Callee.hasFnAttribute("stack-probe-size")) {
    1667             :     uint64_t CalleeStackProbeSize;
    1668           6 :     Callee.getFnAttribute("stack-probe-size")
    1669           6 :           .getValueAsString()
    1670             :           .getAsInteger(0, CalleeStackProbeSize);
    1671           3 :     if (Caller.hasFnAttribute("stack-probe-size")) {
    1672             :       uint64_t CallerStackProbeSize;
    1673           4 :       Caller.getFnAttribute("stack-probe-size")
    1674           4 :             .getValueAsString()
    1675             :             .getAsInteger(0, CallerStackProbeSize);
    1676           2 :       if (CallerStackProbeSize > CalleeStackProbeSize) {
    1677             :         Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
    1678             :       }
    1679             :     } else {
    1680             :       Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
    1681             :     }
    1682             :   }
    1683       95168 : }
    1684             : 
    1685             : #define GET_ATTR_COMPAT_FUNC
    1686             : #include "AttributesCompatFunc.inc"
    1687             : 
    1688      379550 : bool AttributeFuncs::areInlineCompatible(const Function &Caller,
    1689             :                                          const Function &Callee) {
    1690      379550 :   return hasCompatibleFnAttrs(Caller, Callee);
    1691             : }
    1692             : 
    1693       95168 : void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
    1694             :                                                 const Function &Callee) {
    1695       95168 :   mergeFnAttrs(Caller, Callee);
    1696       95168 : }

Generated by: LCOV version 1.13