xref: /aosp_15_r20/external/llvm/lib/IR/Attributes.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1  //===-- Attributes.cpp - Implement AttributesList -------------------------===//
2  //
3  //                     The LLVM Compiler Infrastructure
4  //
5  // This file is distributed under the University of Illinois Open Source
6  // License. See LICENSE.TXT for details.
7  //
8  //===----------------------------------------------------------------------===//
9  //
10  // \file
11  // \brief This file implements the Attribute, AttributeImpl, AttrBuilder,
12  // AttributeSetImpl, and AttributeSet classes.
13  //
14  //===----------------------------------------------------------------------===//
15  
16  #include "llvm/IR/Attributes.h"
17  #include "llvm/IR/Function.h"
18  #include "AttributeImpl.h"
19  #include "LLVMContextImpl.h"
20  #include "llvm/ADT/STLExtras.h"
21  #include "llvm/ADT/StringExtras.h"
22  #include "llvm/IR/Type.h"
23  #include "llvm/Support/Atomic.h"
24  #include "llvm/Support/Debug.h"
25  #include "llvm/Support/ManagedStatic.h"
26  #include "llvm/Support/Mutex.h"
27  #include "llvm/Support/raw_ostream.h"
28  #include <algorithm>
29  using namespace llvm;
30  
31  //===----------------------------------------------------------------------===//
32  // Attribute Construction Methods
33  //===----------------------------------------------------------------------===//
34  
35  // allocsize has two integer arguments, but because they're both 32 bits, we can
36  // pack them into one 64-bit value, at the cost of making said value
37  // nonsensical.
38  //
39  // In order to do this, we need to reserve one value of the second (optional)
40  // allocsize argument to signify "not present."
41  LLVM_CONSTEXPR static unsigned AllocSizeNumElemsNotPresent = -1;
42  
packAllocSizeArgs(unsigned ElemSizeArg,const Optional<unsigned> & NumElemsArg)43  static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
44                                    const Optional<unsigned> &NumElemsArg) {
45    assert((!NumElemsArg.hasValue() ||
46            *NumElemsArg != AllocSizeNumElemsNotPresent) &&
47           "Attempting to pack a reserved value");
48  
49    return uint64_t(ElemSizeArg) << 32 |
50           NumElemsArg.getValueOr(AllocSizeNumElemsNotPresent);
51  }
52  
53  static std::pair<unsigned, Optional<unsigned>>
unpackAllocSizeArgs(uint64_t Num)54  unpackAllocSizeArgs(uint64_t Num) {
55    unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
56    unsigned ElemSizeArg = Num >> 32;
57  
58    Optional<unsigned> NumElemsArg;
59    if (NumElems != AllocSizeNumElemsNotPresent)
60      NumElemsArg = NumElems;
61    return std::make_pair(ElemSizeArg, NumElemsArg);
62  }
63  
get(LLVMContext & Context,Attribute::AttrKind Kind,uint64_t Val)64  Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
65                           uint64_t Val) {
66    LLVMContextImpl *pImpl = Context.pImpl;
67    FoldingSetNodeID ID;
68    ID.AddInteger(Kind);
69    if (Val) ID.AddInteger(Val);
70  
71    void *InsertPoint;
72    AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
73  
74    if (!PA) {
75      // If we didn't find any existing attributes of the same shape then create a
76      // new one and insert it.
77      if (!Val)
78        PA = new EnumAttributeImpl(Kind);
79      else
80        PA = new IntAttributeImpl(Kind, Val);
81      pImpl->AttrsSet.InsertNode(PA, InsertPoint);
82    }
83  
84    // Return the Attribute that we found or created.
85    return Attribute(PA);
86  }
87  
get(LLVMContext & Context,StringRef Kind,StringRef Val)88  Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
89    LLVMContextImpl *pImpl = Context.pImpl;
90    FoldingSetNodeID ID;
91    ID.AddString(Kind);
92    if (!Val.empty()) ID.AddString(Val);
93  
94    void *InsertPoint;
95    AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
96  
97    if (!PA) {
98      // If we didn't find any existing attributes of the same shape then create a
99      // new one and insert it.
100      PA = new StringAttributeImpl(Kind, Val);
101      pImpl->AttrsSet.InsertNode(PA, InsertPoint);
102    }
103  
104    // Return the Attribute that we found or created.
105    return Attribute(PA);
106  }
107  
getWithAlignment(LLVMContext & Context,uint64_t Align)108  Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) {
109    assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
110    assert(Align <= 0x40000000 && "Alignment too large.");
111    return get(Context, Alignment, Align);
112  }
113  
getWithStackAlignment(LLVMContext & Context,uint64_t Align)114  Attribute Attribute::getWithStackAlignment(LLVMContext &Context,
115                                             uint64_t Align) {
116    assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
117    assert(Align <= 0x100 && "Alignment too large.");
118    return get(Context, StackAlignment, Align);
119  }
120  
getWithDereferenceableBytes(LLVMContext & Context,uint64_t Bytes)121  Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context,
122                                                  uint64_t Bytes) {
123    assert(Bytes && "Bytes must be non-zero.");
124    return get(Context, Dereferenceable, Bytes);
125  }
126  
getWithDereferenceableOrNullBytes(LLVMContext & Context,uint64_t Bytes)127  Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
128                                                         uint64_t Bytes) {
129    assert(Bytes && "Bytes must be non-zero.");
130    return get(Context, DereferenceableOrNull, Bytes);
131  }
132  
133  Attribute
getWithAllocSizeArgs(LLVMContext & Context,unsigned ElemSizeArg,const Optional<unsigned> & NumElemsArg)134  Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
135                                  const Optional<unsigned> &NumElemsArg) {
136    assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
137           "Invalid allocsize arguments -- given allocsize(0, 0)");
138    return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
139  }
140  
141  //===----------------------------------------------------------------------===//
142  // Attribute Accessor Methods
143  //===----------------------------------------------------------------------===//
144  
isEnumAttribute() const145  bool Attribute::isEnumAttribute() const {
146    return pImpl && pImpl->isEnumAttribute();
147  }
148  
isIntAttribute() const149  bool Attribute::isIntAttribute() const {
150    return pImpl && pImpl->isIntAttribute();
151  }
152  
isStringAttribute() const153  bool Attribute::isStringAttribute() const {
154    return pImpl && pImpl->isStringAttribute();
155  }
156  
getKindAsEnum() const157  Attribute::AttrKind Attribute::getKindAsEnum() const {
158    if (!pImpl) return None;
159    assert((isEnumAttribute() || isIntAttribute()) &&
160           "Invalid attribute type to get the kind as an enum!");
161    return pImpl->getKindAsEnum();
162  }
163  
getValueAsInt() const164  uint64_t Attribute::getValueAsInt() const {
165    if (!pImpl) return 0;
166    assert(isIntAttribute() &&
167           "Expected the attribute to be an integer attribute!");
168    return pImpl->getValueAsInt();
169  }
170  
getKindAsString() const171  StringRef Attribute::getKindAsString() const {
172    if (!pImpl) return StringRef();
173    assert(isStringAttribute() &&
174           "Invalid attribute type to get the kind as a string!");
175    return pImpl->getKindAsString();
176  }
177  
getValueAsString() const178  StringRef Attribute::getValueAsString() const {
179    if (!pImpl) return StringRef();
180    assert(isStringAttribute() &&
181           "Invalid attribute type to get the value as a string!");
182    return pImpl->getValueAsString();
183  }
184  
hasAttribute(AttrKind Kind) const185  bool Attribute::hasAttribute(AttrKind Kind) const {
186    return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
187  }
188  
hasAttribute(StringRef Kind) const189  bool Attribute::hasAttribute(StringRef Kind) const {
190    if (!isStringAttribute()) return false;
191    return pImpl && pImpl->hasAttribute(Kind);
192  }
193  
getAlignment() const194  unsigned Attribute::getAlignment() const {
195    assert(hasAttribute(Attribute::Alignment) &&
196           "Trying to get alignment from non-alignment attribute!");
197    return pImpl->getValueAsInt();
198  }
199  
getStackAlignment() const200  unsigned Attribute::getStackAlignment() const {
201    assert(hasAttribute(Attribute::StackAlignment) &&
202           "Trying to get alignment from non-alignment attribute!");
203    return pImpl->getValueAsInt();
204  }
205  
getDereferenceableBytes() const206  uint64_t Attribute::getDereferenceableBytes() const {
207    assert(hasAttribute(Attribute::Dereferenceable) &&
208           "Trying to get dereferenceable bytes from "
209           "non-dereferenceable attribute!");
210    return pImpl->getValueAsInt();
211  }
212  
getDereferenceableOrNullBytes() const213  uint64_t Attribute::getDereferenceableOrNullBytes() const {
214    assert(hasAttribute(Attribute::DereferenceableOrNull) &&
215           "Trying to get dereferenceable bytes from "
216           "non-dereferenceable attribute!");
217    return pImpl->getValueAsInt();
218  }
219  
getAllocSizeArgs() const220  std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const {
221    assert(hasAttribute(Attribute::AllocSize) &&
222           "Trying to get allocsize args from non-allocsize attribute");
223    return unpackAllocSizeArgs(pImpl->getValueAsInt());
224  }
225  
getAsString(bool InAttrGrp) const226  std::string Attribute::getAsString(bool InAttrGrp) const {
227    if (!pImpl) return "";
228  
229    if (hasAttribute(Attribute::SanitizeAddress))
230      return "sanitize_address";
231    if (hasAttribute(Attribute::AlwaysInline))
232      return "alwaysinline";
233    if (hasAttribute(Attribute::ArgMemOnly))
234      return "argmemonly";
235    if (hasAttribute(Attribute::Builtin))
236      return "builtin";
237    if (hasAttribute(Attribute::ByVal))
238      return "byval";
239    if (hasAttribute(Attribute::Convergent))
240      return "convergent";
241    if (hasAttribute(Attribute::SwiftError))
242      return "swifterror";
243    if (hasAttribute(Attribute::SwiftSelf))
244      return "swiftself";
245    if (hasAttribute(Attribute::InaccessibleMemOnly))
246      return "inaccessiblememonly";
247    if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly))
248      return "inaccessiblemem_or_argmemonly";
249    if (hasAttribute(Attribute::InAlloca))
250      return "inalloca";
251    if (hasAttribute(Attribute::InlineHint))
252      return "inlinehint";
253    if (hasAttribute(Attribute::InReg))
254      return "inreg";
255    if (hasAttribute(Attribute::JumpTable))
256      return "jumptable";
257    if (hasAttribute(Attribute::MinSize))
258      return "minsize";
259    if (hasAttribute(Attribute::Naked))
260      return "naked";
261    if (hasAttribute(Attribute::Nest))
262      return "nest";
263    if (hasAttribute(Attribute::NoAlias))
264      return "noalias";
265    if (hasAttribute(Attribute::NoBuiltin))
266      return "nobuiltin";
267    if (hasAttribute(Attribute::NoCapture))
268      return "nocapture";
269    if (hasAttribute(Attribute::NoDuplicate))
270      return "noduplicate";
271    if (hasAttribute(Attribute::NoImplicitFloat))
272      return "noimplicitfloat";
273    if (hasAttribute(Attribute::NoInline))
274      return "noinline";
275    if (hasAttribute(Attribute::NonLazyBind))
276      return "nonlazybind";
277    if (hasAttribute(Attribute::NonNull))
278      return "nonnull";
279    if (hasAttribute(Attribute::NoRedZone))
280      return "noredzone";
281    if (hasAttribute(Attribute::NoReturn))
282      return "noreturn";
283    if (hasAttribute(Attribute::NoRecurse))
284      return "norecurse";
285    if (hasAttribute(Attribute::NoUnwind))
286      return "nounwind";
287    if (hasAttribute(Attribute::OptimizeNone))
288      return "optnone";
289    if (hasAttribute(Attribute::OptimizeForSize))
290      return "optsize";
291    if (hasAttribute(Attribute::ReadNone))
292      return "readnone";
293    if (hasAttribute(Attribute::ReadOnly))
294      return "readonly";
295    if (hasAttribute(Attribute::WriteOnly))
296      return "writeonly";
297    if (hasAttribute(Attribute::Returned))
298      return "returned";
299    if (hasAttribute(Attribute::ReturnsTwice))
300      return "returns_twice";
301    if (hasAttribute(Attribute::SExt))
302      return "signext";
303    if (hasAttribute(Attribute::StackProtect))
304      return "ssp";
305    if (hasAttribute(Attribute::StackProtectReq))
306      return "sspreq";
307    if (hasAttribute(Attribute::StackProtectStrong))
308      return "sspstrong";
309    if (hasAttribute(Attribute::SafeStack))
310      return "safestack";
311    if (hasAttribute(Attribute::StructRet))
312      return "sret";
313    if (hasAttribute(Attribute::SanitizeThread))
314      return "sanitize_thread";
315    if (hasAttribute(Attribute::SanitizeMemory))
316      return "sanitize_memory";
317    if (hasAttribute(Attribute::UWTable))
318      return "uwtable";
319    if (hasAttribute(Attribute::ZExt))
320      return "zeroext";
321    if (hasAttribute(Attribute::Cold))
322      return "cold";
323  
324    // FIXME: These should be output like this:
325    //
326    //   align=4
327    //   alignstack=8
328    //
329    if (hasAttribute(Attribute::Alignment)) {
330      std::string Result;
331      Result += "align";
332      Result += (InAttrGrp) ? "=" : " ";
333      Result += utostr(getValueAsInt());
334      return Result;
335    }
336  
337    auto AttrWithBytesToString = [&](const char *Name) {
338      std::string Result;
339      Result += Name;
340      if (InAttrGrp) {
341        Result += "=";
342        Result += utostr(getValueAsInt());
343      } else {
344        Result += "(";
345        Result += utostr(getValueAsInt());
346        Result += ")";
347      }
348      return Result;
349    };
350  
351    if (hasAttribute(Attribute::StackAlignment))
352      return AttrWithBytesToString("alignstack");
353  
354    if (hasAttribute(Attribute::Dereferenceable))
355      return AttrWithBytesToString("dereferenceable");
356  
357    if (hasAttribute(Attribute::DereferenceableOrNull))
358      return AttrWithBytesToString("dereferenceable_or_null");
359  
360    if (hasAttribute(Attribute::AllocSize)) {
361      unsigned ElemSize;
362      Optional<unsigned> NumElems;
363      std::tie(ElemSize, NumElems) = getAllocSizeArgs();
364  
365      std::string Result = "allocsize(";
366      Result += utostr(ElemSize);
367      if (NumElems.hasValue()) {
368        Result += ',';
369        Result += utostr(*NumElems);
370      }
371      Result += ')';
372      return Result;
373    }
374  
375    // Convert target-dependent attributes to strings of the form:
376    //
377    //   "kind"
378    //   "kind" = "value"
379    //
380    if (isStringAttribute()) {
381      std::string Result;
382      Result += (Twine('"') + getKindAsString() + Twine('"')).str();
383  
384      StringRef Val = pImpl->getValueAsString();
385      if (Val.empty()) return Result;
386  
387      Result += ("=\"" + Val + Twine('"')).str();
388      return Result;
389    }
390  
391    llvm_unreachable("Unknown attribute");
392  }
393  
operator <(Attribute A) const394  bool Attribute::operator<(Attribute A) const {
395    if (!pImpl && !A.pImpl) return false;
396    if (!pImpl) return true;
397    if (!A.pImpl) return false;
398    return *pImpl < *A.pImpl;
399  }
400  
401  //===----------------------------------------------------------------------===//
402  // AttributeImpl Definition
403  //===----------------------------------------------------------------------===//
404  
405  // Pin the vtables to this file.
~AttributeImpl()406  AttributeImpl::~AttributeImpl() {}
anchor()407  void EnumAttributeImpl::anchor() {}
anchor()408  void IntAttributeImpl::anchor() {}
anchor()409  void StringAttributeImpl::anchor() {}
410  
hasAttribute(Attribute::AttrKind A) const411  bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
412    if (isStringAttribute()) return false;
413    return getKindAsEnum() == A;
414  }
415  
hasAttribute(StringRef Kind) const416  bool AttributeImpl::hasAttribute(StringRef Kind) const {
417    if (!isStringAttribute()) return false;
418    return getKindAsString() == Kind;
419  }
420  
getKindAsEnum() const421  Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
422    assert(isEnumAttribute() || isIntAttribute());
423    return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
424  }
425  
getValueAsInt() const426  uint64_t AttributeImpl::getValueAsInt() const {
427    assert(isIntAttribute());
428    return static_cast<const IntAttributeImpl *>(this)->getValue();
429  }
430  
getKindAsString() const431  StringRef AttributeImpl::getKindAsString() const {
432    assert(isStringAttribute());
433    return static_cast<const StringAttributeImpl *>(this)->getStringKind();
434  }
435  
getValueAsString() const436  StringRef AttributeImpl::getValueAsString() const {
437    assert(isStringAttribute());
438    return static_cast<const StringAttributeImpl *>(this)->getStringValue();
439  }
440  
operator <(const AttributeImpl & AI) const441  bool AttributeImpl::operator<(const AttributeImpl &AI) const {
442    // This sorts the attributes with Attribute::AttrKinds coming first (sorted
443    // relative to their enum value) and then strings.
444    if (isEnumAttribute()) {
445      if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
446      if (AI.isIntAttribute()) return true;
447      if (AI.isStringAttribute()) return true;
448    }
449  
450    if (isIntAttribute()) {
451      if (AI.isEnumAttribute()) return false;
452      if (AI.isIntAttribute()) {
453        if (getKindAsEnum() == AI.getKindAsEnum())
454          return getValueAsInt() < AI.getValueAsInt();
455        return getKindAsEnum() < AI.getKindAsEnum();
456      }
457      if (AI.isStringAttribute()) return true;
458    }
459  
460    if (AI.isEnumAttribute()) return false;
461    if (AI.isIntAttribute()) return false;
462    if (getKindAsString() == AI.getKindAsString())
463      return getValueAsString() < AI.getValueAsString();
464    return getKindAsString() < AI.getKindAsString();
465  }
466  
getAttrMask(Attribute::AttrKind Val)467  uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) {
468    // FIXME: Remove this.
469    switch (Val) {
470    case Attribute::EndAttrKinds:
471      llvm_unreachable("Synthetic enumerators which should never get here");
472  
473    case Attribute::None:            return 0;
474    case Attribute::ZExt:            return 1 << 0;
475    case Attribute::SExt:            return 1 << 1;
476    case Attribute::NoReturn:        return 1 << 2;
477    case Attribute::InReg:           return 1 << 3;
478    case Attribute::StructRet:       return 1 << 4;
479    case Attribute::NoUnwind:        return 1 << 5;
480    case Attribute::NoAlias:         return 1 << 6;
481    case Attribute::ByVal:           return 1 << 7;
482    case Attribute::Nest:            return 1 << 8;
483    case Attribute::ReadNone:        return 1 << 9;
484    case Attribute::ReadOnly:        return 1 << 10;
485    case Attribute::NoInline:        return 1 << 11;
486    case Attribute::AlwaysInline:    return 1 << 12;
487    case Attribute::OptimizeForSize: return 1 << 13;
488    case Attribute::StackProtect:    return 1 << 14;
489    case Attribute::StackProtectReq: return 1 << 15;
490    case Attribute::Alignment:       return 31 << 16;
491    case Attribute::NoCapture:       return 1 << 21;
492    case Attribute::NoRedZone:       return 1 << 22;
493    case Attribute::NoImplicitFloat: return 1 << 23;
494    case Attribute::Naked:           return 1 << 24;
495    case Attribute::InlineHint:      return 1 << 25;
496    case Attribute::StackAlignment:  return 7 << 26;
497    case Attribute::ReturnsTwice:    return 1 << 29;
498    case Attribute::UWTable:         return 1 << 30;
499    case Attribute::NonLazyBind:     return 1U << 31;
500    case Attribute::SanitizeAddress: return 1ULL << 32;
501    case Attribute::MinSize:         return 1ULL << 33;
502    case Attribute::NoDuplicate:     return 1ULL << 34;
503    case Attribute::StackProtectStrong: return 1ULL << 35;
504    case Attribute::SanitizeThread:  return 1ULL << 36;
505    case Attribute::SanitizeMemory:  return 1ULL << 37;
506    case Attribute::NoBuiltin:       return 1ULL << 38;
507    case Attribute::Returned:        return 1ULL << 39;
508    case Attribute::Cold:            return 1ULL << 40;
509    case Attribute::Builtin:         return 1ULL << 41;
510    case Attribute::OptimizeNone:    return 1ULL << 42;
511    case Attribute::InAlloca:        return 1ULL << 43;
512    case Attribute::NonNull:         return 1ULL << 44;
513    case Attribute::JumpTable:       return 1ULL << 45;
514    case Attribute::Convergent:      return 1ULL << 46;
515    case Attribute::SafeStack:       return 1ULL << 47;
516    case Attribute::NoRecurse:       return 1ULL << 48;
517    case Attribute::InaccessibleMemOnly:         return 1ULL << 49;
518    case Attribute::InaccessibleMemOrArgMemOnly: return 1ULL << 50;
519    case Attribute::SwiftSelf:       return 1ULL << 51;
520    case Attribute::SwiftError:      return 1ULL << 52;
521    case Attribute::WriteOnly:       return 1ULL << 53;
522    case Attribute::Dereferenceable:
523      llvm_unreachable("dereferenceable attribute not supported in raw format");
524      break;
525    case Attribute::DereferenceableOrNull:
526      llvm_unreachable("dereferenceable_or_null attribute not supported in raw "
527                       "format");
528      break;
529    case Attribute::ArgMemOnly:
530      llvm_unreachable("argmemonly attribute not supported in raw format");
531      break;
532    case Attribute::AllocSize:
533      llvm_unreachable("allocsize not supported in raw format");
534      break;
535    }
536    llvm_unreachable("Unsupported attribute type");
537  }
538  
539  //===----------------------------------------------------------------------===//
540  // AttributeSetNode Definition
541  //===----------------------------------------------------------------------===//
542  
get(LLVMContext & C,ArrayRef<Attribute> Attrs)543  AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
544                                          ArrayRef<Attribute> Attrs) {
545    if (Attrs.empty())
546      return nullptr;
547  
548    // Otherwise, build a key to look up the existing attributes.
549    LLVMContextImpl *pImpl = C.pImpl;
550    FoldingSetNodeID ID;
551  
552    SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
553    std::sort(SortedAttrs.begin(), SortedAttrs.end());
554  
555    for (Attribute Attr : SortedAttrs)
556      Attr.Profile(ID);
557  
558    void *InsertPoint;
559    AttributeSetNode *PA =
560      pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
561  
562    // If we didn't find any existing attributes of the same shape then create a
563    // new one and insert it.
564    if (!PA) {
565      // Coallocate entries after the AttributeSetNode itself.
566      void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
567      PA = new (Mem) AttributeSetNode(SortedAttrs);
568      pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
569    }
570  
571    // Return the AttributesListNode that we found or created.
572    return PA;
573  }
574  
hasAttribute(StringRef Kind) const575  bool AttributeSetNode::hasAttribute(StringRef Kind) const {
576    for (Attribute I : *this)
577      if (I.hasAttribute(Kind))
578        return true;
579    return false;
580  }
581  
getAttribute(Attribute::AttrKind Kind) const582  Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
583    if (hasAttribute(Kind)) {
584      for (Attribute I : *this)
585        if (I.hasAttribute(Kind))
586          return I;
587    }
588    return Attribute();
589  }
590  
getAttribute(StringRef Kind) const591  Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
592    for (Attribute I : *this)
593      if (I.hasAttribute(Kind))
594        return I;
595    return Attribute();
596  }
597  
getAlignment() const598  unsigned AttributeSetNode::getAlignment() const {
599    for (Attribute I : *this)
600      if (I.hasAttribute(Attribute::Alignment))
601        return I.getAlignment();
602    return 0;
603  }
604  
getStackAlignment() const605  unsigned AttributeSetNode::getStackAlignment() const {
606    for (Attribute I : *this)
607      if (I.hasAttribute(Attribute::StackAlignment))
608        return I.getStackAlignment();
609    return 0;
610  }
611  
getDereferenceableBytes() const612  uint64_t AttributeSetNode::getDereferenceableBytes() const {
613    for (Attribute I : *this)
614      if (I.hasAttribute(Attribute::Dereferenceable))
615        return I.getDereferenceableBytes();
616    return 0;
617  }
618  
getDereferenceableOrNullBytes() const619  uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
620    for (Attribute I : *this)
621      if (I.hasAttribute(Attribute::DereferenceableOrNull))
622        return I.getDereferenceableOrNullBytes();
623    return 0;
624  }
625  
626  std::pair<unsigned, Optional<unsigned>>
getAllocSizeArgs() const627  AttributeSetNode::getAllocSizeArgs() const {
628    for (Attribute I : *this)
629      if (I.hasAttribute(Attribute::AllocSize))
630        return I.getAllocSizeArgs();
631    return std::make_pair(0, 0);
632  }
633  
getAsString(bool InAttrGrp) const634  std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
635    std::string Str;
636    for (iterator I = begin(), E = end(); I != E; ++I) {
637      if (I != begin())
638        Str += ' ';
639      Str += I->getAsString(InAttrGrp);
640    }
641    return Str;
642  }
643  
644  //===----------------------------------------------------------------------===//
645  // AttributeSetImpl Definition
646  //===----------------------------------------------------------------------===//
647  
Raw(unsigned Index) const648  uint64_t AttributeSetImpl::Raw(unsigned Index) const {
649    for (unsigned I = 0, E = getNumSlots(); I != E; ++I) {
650      if (getSlotIndex(I) != Index) continue;
651      const AttributeSetNode *ASN = getSlotNode(I);
652      uint64_t Mask = 0;
653  
654      for (AttributeSetNode::iterator II = ASN->begin(),
655             IE = ASN->end(); II != IE; ++II) {
656        Attribute Attr = *II;
657  
658        // This cannot handle string attributes.
659        if (Attr.isStringAttribute()) continue;
660  
661        Attribute::AttrKind Kind = Attr.getKindAsEnum();
662  
663        if (Kind == Attribute::Alignment)
664          Mask |= (Log2_32(ASN->getAlignment()) + 1) << 16;
665        else if (Kind == Attribute::StackAlignment)
666          Mask |= (Log2_32(ASN->getStackAlignment()) + 1) << 26;
667        else if (Kind == Attribute::Dereferenceable)
668          llvm_unreachable("dereferenceable not supported in bit mask");
669        else if (Kind == Attribute::AllocSize)
670          llvm_unreachable("allocsize not supported in bit mask");
671        else
672          Mask |= AttributeImpl::getAttrMask(Kind);
673      }
674  
675      return Mask;
676    }
677  
678    return 0;
679  }
680  
dump() const681  LLVM_DUMP_METHOD void AttributeSetImpl::dump() const {
682    AttributeSet(const_cast<AttributeSetImpl *>(this)).dump();
683  }
684  
685  //===----------------------------------------------------------------------===//
686  // AttributeSet Construction and Mutation Methods
687  //===----------------------------------------------------------------------===//
688  
689  AttributeSet
getImpl(LLVMContext & C,ArrayRef<std::pair<unsigned,AttributeSetNode * >> Attrs)690  AttributeSet::getImpl(LLVMContext &C,
691                        ArrayRef<std::pair<unsigned, AttributeSetNode*> > Attrs) {
692    LLVMContextImpl *pImpl = C.pImpl;
693    FoldingSetNodeID ID;
694    AttributeSetImpl::Profile(ID, Attrs);
695  
696    void *InsertPoint;
697    AttributeSetImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
698  
699    // If we didn't find any existing attributes of the same shape then
700    // create a new one and insert it.
701    if (!PA) {
702      // Coallocate entries after the AttributeSetImpl itself.
703      void *Mem = ::operator new(
704          AttributeSetImpl::totalSizeToAlloc<IndexAttrPair>(Attrs.size()));
705      PA = new (Mem) AttributeSetImpl(C, Attrs);
706      pImpl->AttrsLists.InsertNode(PA, InsertPoint);
707    }
708  
709    // Return the AttributesList that we found or created.
710    return AttributeSet(PA);
711  }
712  
get(LLVMContext & C,ArrayRef<std::pair<unsigned,Attribute>> Attrs)713  AttributeSet AttributeSet::get(LLVMContext &C,
714                                 ArrayRef<std::pair<unsigned, Attribute> > Attrs){
715    // If there are no attributes then return a null AttributesList pointer.
716    if (Attrs.empty())
717      return AttributeSet();
718  
719    assert(std::is_sorted(Attrs.begin(), Attrs.end(),
720                          [](const std::pair<unsigned, Attribute> &LHS,
721                             const std::pair<unsigned, Attribute> &RHS) {
722                            return LHS.first < RHS.first;
723                          }) && "Misordered Attributes list!");
724    assert(std::none_of(Attrs.begin(), Attrs.end(),
725                        [](const std::pair<unsigned, Attribute> &Pair) {
726                          return Pair.second.hasAttribute(Attribute::None);
727                        }) && "Pointless attribute!");
728  
729    // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
730    // list.
731    SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrPairVec;
732    for (ArrayRef<std::pair<unsigned, Attribute> >::iterator I = Attrs.begin(),
733           E = Attrs.end(); I != E; ) {
734      unsigned Index = I->first;
735      SmallVector<Attribute, 4> AttrVec;
736      while (I != E && I->first == Index) {
737        AttrVec.push_back(I->second);
738        ++I;
739      }
740  
741      AttrPairVec.push_back(std::make_pair(Index,
742                                           AttributeSetNode::get(C, AttrVec)));
743    }
744  
745    return getImpl(C, AttrPairVec);
746  }
747  
get(LLVMContext & C,ArrayRef<std::pair<unsigned,AttributeSetNode * >> Attrs)748  AttributeSet AttributeSet::get(LLVMContext &C,
749                                 ArrayRef<std::pair<unsigned,
750                                                    AttributeSetNode*> > Attrs) {
751    // If there are no attributes then return a null AttributesList pointer.
752    if (Attrs.empty())
753      return AttributeSet();
754  
755    return getImpl(C, Attrs);
756  }
757  
get(LLVMContext & C,unsigned Index,const AttrBuilder & B)758  AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index,
759                                 const AttrBuilder &B) {
760    if (!B.hasAttributes())
761      return AttributeSet();
762  
763    // Add target-independent attributes.
764    SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
765    for (Attribute::AttrKind Kind = Attribute::None;
766         Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) {
767      if (!B.contains(Kind))
768        continue;
769  
770      Attribute Attr;
771      switch (Kind) {
772      case Attribute::Alignment:
773        Attr = Attribute::getWithAlignment(C, B.getAlignment());
774        break;
775      case Attribute::StackAlignment:
776        Attr = Attribute::getWithStackAlignment(C, B.getStackAlignment());
777        break;
778      case Attribute::Dereferenceable:
779        Attr = Attribute::getWithDereferenceableBytes(
780            C, B.getDereferenceableBytes());
781        break;
782      case Attribute::DereferenceableOrNull:
783        Attr = Attribute::getWithDereferenceableOrNullBytes(
784            C, B.getDereferenceableOrNullBytes());
785        break;
786      case Attribute::AllocSize: {
787        auto A = B.getAllocSizeArgs();
788        Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
789        break;
790      }
791      default:
792        Attr = Attribute::get(C, Kind);
793      }
794      Attrs.push_back(std::make_pair(Index, Attr));
795    }
796  
797    // Add target-dependent (string) attributes.
798    for (const auto &TDA : B.td_attrs())
799      Attrs.push_back(
800          std::make_pair(Index, Attribute::get(C, TDA.first, TDA.second)));
801  
802    return get(C, Attrs);
803  }
804  
get(LLVMContext & C,unsigned Index,ArrayRef<Attribute::AttrKind> Kinds)805  AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index,
806                                 ArrayRef<Attribute::AttrKind> Kinds) {
807    SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
808    for (Attribute::AttrKind K : Kinds)
809      Attrs.push_back(std::make_pair(Index, Attribute::get(C, K)));
810    return get(C, Attrs);
811  }
812  
get(LLVMContext & C,unsigned Index,ArrayRef<StringRef> Kinds)813  AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index,
814                                 ArrayRef<StringRef> Kinds) {
815    SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
816    for (StringRef K : Kinds)
817      Attrs.push_back(std::make_pair(Index, Attribute::get(C, K)));
818    return get(C, Attrs);
819  }
820  
get(LLVMContext & C,ArrayRef<AttributeSet> Attrs)821  AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<AttributeSet> Attrs) {
822    if (Attrs.empty()) return AttributeSet();
823    if (Attrs.size() == 1) return Attrs[0];
824  
825    SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrNodeVec;
826    AttributeSetImpl *A0 = Attrs[0].pImpl;
827    if (A0)
828      AttrNodeVec.append(A0->getNode(0), A0->getNode(A0->getNumSlots()));
829    // Copy all attributes from Attrs into AttrNodeVec while keeping AttrNodeVec
830    // ordered by index.  Because we know that each list in Attrs is ordered by
831    // index we only need to merge each successive list in rather than doing a
832    // full sort.
833    for (unsigned I = 1, E = Attrs.size(); I != E; ++I) {
834      AttributeSetImpl *AS = Attrs[I].pImpl;
835      if (!AS) continue;
836      SmallVector<std::pair<unsigned, AttributeSetNode *>, 8>::iterator
837        ANVI = AttrNodeVec.begin(), ANVE;
838      for (const IndexAttrPair *AI = AS->getNode(0),
839                               *AE = AS->getNode(AS->getNumSlots());
840           AI != AE; ++AI) {
841        ANVE = AttrNodeVec.end();
842        while (ANVI != ANVE && ANVI->first <= AI->first)
843          ++ANVI;
844        ANVI = AttrNodeVec.insert(ANVI, *AI) + 1;
845      }
846    }
847  
848    return getImpl(C, AttrNodeVec);
849  }
850  
addAttribute(LLVMContext & C,unsigned Index,Attribute::AttrKind Kind) const851  AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index,
852                                          Attribute::AttrKind Kind) const {
853    if (hasAttribute(Index, Kind)) return *this;
854    return addAttributes(C, Index, AttributeSet::get(C, Index, Kind));
855  }
856  
addAttribute(LLVMContext & C,unsigned Index,StringRef Kind,StringRef Value) const857  AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index,
858                                          StringRef Kind, StringRef Value) const {
859    llvm::AttrBuilder B;
860    B.addAttribute(Kind, Value);
861    return addAttributes(C, Index, AttributeSet::get(C, Index, B));
862  }
863  
addAttribute(LLVMContext & C,ArrayRef<unsigned> Indices,Attribute A) const864  AttributeSet AttributeSet::addAttribute(LLVMContext &C,
865                                          ArrayRef<unsigned> Indices,
866                                          Attribute A) const {
867    unsigned I = 0, E = pImpl ? pImpl->getNumSlots() : 0;
868    auto IdxI = Indices.begin(), IdxE = Indices.end();
869    SmallVector<AttributeSet, 4> AttrSet;
870  
871    while (I != E && IdxI != IdxE) {
872      if (getSlotIndex(I) < *IdxI)
873        AttrSet.emplace_back(getSlotAttributes(I++));
874      else if (getSlotIndex(I) > *IdxI)
875        AttrSet.emplace_back(AttributeSet::get(C, std::make_pair(*IdxI++, A)));
876      else {
877        AttrBuilder B(getSlotAttributes(I), *IdxI);
878        B.addAttribute(A);
879        AttrSet.emplace_back(AttributeSet::get(C, *IdxI, B));
880        ++I;
881        ++IdxI;
882      }
883    }
884  
885    while (I != E)
886      AttrSet.emplace_back(getSlotAttributes(I++));
887  
888    while (IdxI != IdxE)
889      AttrSet.emplace_back(AttributeSet::get(C, std::make_pair(*IdxI++, A)));
890  
891    return get(C, AttrSet);
892  }
893  
addAttributes(LLVMContext & C,unsigned Index,AttributeSet Attrs) const894  AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Index,
895                                           AttributeSet Attrs) const {
896    if (!pImpl) return Attrs;
897    if (!Attrs.pImpl) return *this;
898  
899  #ifndef NDEBUG
900    // FIXME it is not obvious how this should work for alignment. For now, say
901    // we can't change a known alignment.
902    unsigned OldAlign = getParamAlignment(Index);
903    unsigned NewAlign = Attrs.getParamAlignment(Index);
904    assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
905           "Attempt to change alignment!");
906  #endif
907  
908    // Add the attribute slots before the one we're trying to add.
909    SmallVector<AttributeSet, 4> AttrSet;
910    uint64_t NumAttrs = pImpl->getNumSlots();
911    AttributeSet AS;
912    uint64_t LastIndex = 0;
913    for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
914      if (getSlotIndex(I) >= Index) {
915        if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
916        break;
917      }
918      LastIndex = I + 1;
919      AttrSet.push_back(getSlotAttributes(I));
920    }
921  
922    // Now add the attribute into the correct slot. There may already be an
923    // AttributeSet there.
924    AttrBuilder B(AS, Index);
925  
926    for (unsigned I = 0, E = Attrs.pImpl->getNumSlots(); I != E; ++I)
927      if (Attrs.getSlotIndex(I) == Index) {
928        for (AttributeSetImpl::iterator II = Attrs.pImpl->begin(I),
929               IE = Attrs.pImpl->end(I); II != IE; ++II)
930          B.addAttribute(*II);
931        break;
932      }
933  
934    AttrSet.push_back(AttributeSet::get(C, Index, B));
935  
936    // Add the remaining attribute slots.
937    for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
938      AttrSet.push_back(getSlotAttributes(I));
939  
940    return get(C, AttrSet);
941  }
942  
removeAttribute(LLVMContext & C,unsigned Index,Attribute::AttrKind Kind) const943  AttributeSet AttributeSet::removeAttribute(LLVMContext &C, unsigned Index,
944                                             Attribute::AttrKind Kind) const {
945    if (!hasAttribute(Index, Kind)) return *this;
946    return removeAttributes(C, Index, AttributeSet::get(C, Index, Kind));
947  }
948  
removeAttribute(LLVMContext & C,unsigned Index,StringRef Kind) const949  AttributeSet AttributeSet::removeAttribute(LLVMContext &C, unsigned Index,
950                                             StringRef Kind) const {
951    if (!hasAttribute(Index, Kind)) return *this;
952    return removeAttributes(C, Index, AttributeSet::get(C, Index, Kind));
953  }
954  
removeAttributes(LLVMContext & C,unsigned Index,AttributeSet Attrs) const955  AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Index,
956                                              AttributeSet Attrs) const {
957    if (!pImpl) return AttributeSet();
958    if (!Attrs.pImpl) return *this;
959  
960    // FIXME it is not obvious how this should work for alignment.
961    // For now, say we can't pass in alignment, which no current use does.
962    assert(!Attrs.hasAttribute(Index, Attribute::Alignment) &&
963           "Attempt to change alignment!");
964  
965    // Add the attribute slots before the one we're trying to add.
966    SmallVector<AttributeSet, 4> AttrSet;
967    uint64_t NumAttrs = pImpl->getNumSlots();
968    AttributeSet AS;
969    uint64_t LastIndex = 0;
970    for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
971      if (getSlotIndex(I) >= Index) {
972        if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
973        break;
974      }
975      LastIndex = I + 1;
976      AttrSet.push_back(getSlotAttributes(I));
977    }
978  
979    // Now remove the attribute from the correct slot. There may already be an
980    // AttributeSet there.
981    AttrBuilder B(AS, Index);
982  
983    for (unsigned I = 0, E = Attrs.pImpl->getNumSlots(); I != E; ++I)
984      if (Attrs.getSlotIndex(I) == Index) {
985        B.removeAttributes(Attrs.pImpl->getSlotAttributes(I), Index);
986        break;
987      }
988  
989    AttrSet.push_back(AttributeSet::get(C, Index, B));
990  
991    // Add the remaining attribute slots.
992    for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
993      AttrSet.push_back(getSlotAttributes(I));
994  
995    return get(C, AttrSet);
996  }
997  
removeAttributes(LLVMContext & C,unsigned Index,const AttrBuilder & Attrs) const998  AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Index,
999                                              const AttrBuilder &Attrs) const {
1000    if (!pImpl) return AttributeSet();
1001  
1002    // FIXME it is not obvious how this should work for alignment.
1003    // For now, say we can't pass in alignment, which no current use does.
1004    assert(!Attrs.hasAlignmentAttr() && "Attempt to change alignment!");
1005  
1006    // Add the attribute slots before the one we're trying to add.
1007    SmallVector<AttributeSet, 4> AttrSet;
1008    uint64_t NumAttrs = pImpl->getNumSlots();
1009    AttributeSet AS;
1010    uint64_t LastIndex = 0;
1011    for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
1012      if (getSlotIndex(I) >= Index) {
1013        if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
1014        break;
1015      }
1016      LastIndex = I + 1;
1017      AttrSet.push_back(getSlotAttributes(I));
1018    }
1019  
1020    // Now remove the attribute from the correct slot. There may already be an
1021    // AttributeSet there.
1022    AttrBuilder B(AS, Index);
1023    B.remove(Attrs);
1024  
1025    AttrSet.push_back(AttributeSet::get(C, Index, B));
1026  
1027    // Add the remaining attribute slots.
1028    for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
1029      AttrSet.push_back(getSlotAttributes(I));
1030  
1031    return get(C, AttrSet);
1032  }
1033  
addDereferenceableAttr(LLVMContext & C,unsigned Index,uint64_t Bytes) const1034  AttributeSet AttributeSet::addDereferenceableAttr(LLVMContext &C, unsigned Index,
1035                                                    uint64_t Bytes) const {
1036    llvm::AttrBuilder B;
1037    B.addDereferenceableAttr(Bytes);
1038    return addAttributes(C, Index, AttributeSet::get(C, Index, B));
1039  }
1040  
addDereferenceableOrNullAttr(LLVMContext & C,unsigned Index,uint64_t Bytes) const1041  AttributeSet AttributeSet::addDereferenceableOrNullAttr(LLVMContext &C,
1042                                                          unsigned Index,
1043                                                          uint64_t Bytes) const {
1044    llvm::AttrBuilder B;
1045    B.addDereferenceableOrNullAttr(Bytes);
1046    return addAttributes(C, Index, AttributeSet::get(C, Index, B));
1047  }
1048  
1049  AttributeSet
addAllocSizeAttr(LLVMContext & C,unsigned Index,unsigned ElemSizeArg,const Optional<unsigned> & NumElemsArg)1050  AttributeSet::addAllocSizeAttr(LLVMContext &C, unsigned Index,
1051                                 unsigned ElemSizeArg,
1052                                 const Optional<unsigned> &NumElemsArg) {
1053    llvm::AttrBuilder B;
1054    B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1055    return addAttributes(C, Index, AttributeSet::get(C, Index, B));
1056  }
1057  
1058  //===----------------------------------------------------------------------===//
1059  // AttributeSet Accessor Methods
1060  //===----------------------------------------------------------------------===//
1061  
getContext() const1062  LLVMContext &AttributeSet::getContext() const {
1063    return pImpl->getContext();
1064  }
1065  
getParamAttributes(unsigned Index) const1066  AttributeSet AttributeSet::getParamAttributes(unsigned Index) const {
1067    return pImpl && hasAttributes(Index) ?
1068      AttributeSet::get(pImpl->getContext(),
1069                        ArrayRef<std::pair<unsigned, AttributeSetNode*> >(
1070                          std::make_pair(Index, getAttributes(Index)))) :
1071      AttributeSet();
1072  }
1073  
getRetAttributes() const1074  AttributeSet AttributeSet::getRetAttributes() const {
1075    return pImpl && hasAttributes(ReturnIndex) ?
1076      AttributeSet::get(pImpl->getContext(),
1077                        ArrayRef<std::pair<unsigned, AttributeSetNode*> >(
1078                          std::make_pair(ReturnIndex,
1079                                         getAttributes(ReturnIndex)))) :
1080      AttributeSet();
1081  }
1082  
getFnAttributes() const1083  AttributeSet AttributeSet::getFnAttributes() const {
1084    return pImpl && hasAttributes(FunctionIndex) ?
1085      AttributeSet::get(pImpl->getContext(),
1086                        ArrayRef<std::pair<unsigned, AttributeSetNode*> >(
1087                          std::make_pair(FunctionIndex,
1088                                         getAttributes(FunctionIndex)))) :
1089      AttributeSet();
1090  }
1091  
hasAttribute(unsigned Index,Attribute::AttrKind Kind) const1092  bool AttributeSet::hasAttribute(unsigned Index, Attribute::AttrKind Kind) const{
1093    AttributeSetNode *ASN = getAttributes(Index);
1094    return ASN && ASN->hasAttribute(Kind);
1095  }
1096  
hasAttribute(unsigned Index,StringRef Kind) const1097  bool AttributeSet::hasAttribute(unsigned Index, StringRef Kind) const {
1098    AttributeSetNode *ASN = getAttributes(Index);
1099    return ASN && ASN->hasAttribute(Kind);
1100  }
1101  
hasAttributes(unsigned Index) const1102  bool AttributeSet::hasAttributes(unsigned Index) const {
1103    AttributeSetNode *ASN = getAttributes(Index);
1104    return ASN && ASN->hasAttributes();
1105  }
1106  
hasFnAttribute(Attribute::AttrKind Kind) const1107  bool AttributeSet::hasFnAttribute(Attribute::AttrKind Kind) const {
1108    return pImpl && pImpl->hasFnAttribute(Kind);
1109  }
1110  
hasAttrSomewhere(Attribute::AttrKind Attr,unsigned * Index) const1111  bool AttributeSet::hasAttrSomewhere(Attribute::AttrKind Attr,
1112                                      unsigned *Index) const {
1113    if (!pImpl) return false;
1114  
1115    for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I)
1116      for (AttributeSetImpl::iterator II = pImpl->begin(I),
1117             IE = pImpl->end(I); II != IE; ++II)
1118        if (II->hasAttribute(Attr)) {
1119          if (Index) *Index = pImpl->getSlotIndex(I);
1120          return true;
1121        }
1122  
1123    return false;
1124  }
1125  
getAttribute(unsigned Index,Attribute::AttrKind Kind) const1126  Attribute AttributeSet::getAttribute(unsigned Index,
1127                                       Attribute::AttrKind Kind) const {
1128    AttributeSetNode *ASN = getAttributes(Index);
1129    return ASN ? ASN->getAttribute(Kind) : Attribute();
1130  }
1131  
getAttribute(unsigned Index,StringRef Kind) const1132  Attribute AttributeSet::getAttribute(unsigned Index,
1133                                       StringRef Kind) const {
1134    AttributeSetNode *ASN = getAttributes(Index);
1135    return ASN ? ASN->getAttribute(Kind) : Attribute();
1136  }
1137  
getParamAlignment(unsigned Index) const1138  unsigned AttributeSet::getParamAlignment(unsigned Index) const {
1139    AttributeSetNode *ASN = getAttributes(Index);
1140    return ASN ? ASN->getAlignment() : 0;
1141  }
1142  
getStackAlignment(unsigned Index) const1143  unsigned AttributeSet::getStackAlignment(unsigned Index) const {
1144    AttributeSetNode *ASN = getAttributes(Index);
1145    return ASN ? ASN->getStackAlignment() : 0;
1146  }
1147  
getDereferenceableBytes(unsigned Index) const1148  uint64_t AttributeSet::getDereferenceableBytes(unsigned Index) const {
1149    AttributeSetNode *ASN = getAttributes(Index);
1150    return ASN ? ASN->getDereferenceableBytes() : 0;
1151  }
1152  
getDereferenceableOrNullBytes(unsigned Index) const1153  uint64_t AttributeSet::getDereferenceableOrNullBytes(unsigned Index) const {
1154    AttributeSetNode *ASN = getAttributes(Index);
1155    return ASN ? ASN->getDereferenceableOrNullBytes() : 0;
1156  }
1157  
1158  std::pair<unsigned, Optional<unsigned>>
getAllocSizeArgs(unsigned Index) const1159  AttributeSet::getAllocSizeArgs(unsigned Index) const {
1160    AttributeSetNode *ASN = getAttributes(Index);
1161    return ASN ? ASN->getAllocSizeArgs() : std::make_pair(0, 0);
1162  }
1163  
getAsString(unsigned Index,bool InAttrGrp) const1164  std::string AttributeSet::getAsString(unsigned Index, bool InAttrGrp) const {
1165    AttributeSetNode *ASN = getAttributes(Index);
1166    return ASN ? ASN->getAsString(InAttrGrp) : std::string("");
1167  }
1168  
getAttributes(unsigned Index) const1169  AttributeSetNode *AttributeSet::getAttributes(unsigned Index) const {
1170    if (!pImpl) return nullptr;
1171  
1172    // Loop through to find the attribute node we want.
1173    for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I)
1174      if (pImpl->getSlotIndex(I) == Index)
1175        return pImpl->getSlotNode(I);
1176  
1177    return nullptr;
1178  }
1179  
begin(unsigned Slot) const1180  AttributeSet::iterator AttributeSet::begin(unsigned Slot) const {
1181    if (!pImpl)
1182      return ArrayRef<Attribute>().begin();
1183    return pImpl->begin(Slot);
1184  }
1185  
end(unsigned Slot) const1186  AttributeSet::iterator AttributeSet::end(unsigned Slot) const {
1187    if (!pImpl)
1188      return ArrayRef<Attribute>().end();
1189    return pImpl->end(Slot);
1190  }
1191  
1192  //===----------------------------------------------------------------------===//
1193  // AttributeSet Introspection Methods
1194  //===----------------------------------------------------------------------===//
1195  
getNumSlots() const1196  unsigned AttributeSet::getNumSlots() const {
1197    return pImpl ? pImpl->getNumSlots() : 0;
1198  }
1199  
getSlotIndex(unsigned Slot) const1200  unsigned AttributeSet::getSlotIndex(unsigned Slot) const {
1201    assert(pImpl && Slot < pImpl->getNumSlots() &&
1202           "Slot # out of range!");
1203    return pImpl->getSlotIndex(Slot);
1204  }
1205  
getSlotAttributes(unsigned Slot) const1206  AttributeSet AttributeSet::getSlotAttributes(unsigned Slot) const {
1207    assert(pImpl && Slot < pImpl->getNumSlots() &&
1208           "Slot # out of range!");
1209    return pImpl->getSlotAttributes(Slot);
1210  }
1211  
Raw(unsigned Index) const1212  uint64_t AttributeSet::Raw(unsigned Index) const {
1213    // FIXME: Remove this.
1214    return pImpl ? pImpl->Raw(Index) : 0;
1215  }
1216  
dump() const1217  LLVM_DUMP_METHOD void AttributeSet::dump() const {
1218    dbgs() << "PAL[\n";
1219  
1220    for (unsigned i = 0, e = getNumSlots(); i < e; ++i) {
1221      uint64_t Index = getSlotIndex(i);
1222      dbgs() << "  { ";
1223      if (Index == ~0U)
1224        dbgs() << "~0U";
1225      else
1226        dbgs() << Index;
1227      dbgs() << " => " << getAsString(Index) << " }\n";
1228    }
1229  
1230    dbgs() << "]\n";
1231  }
1232  
1233  //===----------------------------------------------------------------------===//
1234  // AttrBuilder Method Implementations
1235  //===----------------------------------------------------------------------===//
1236  
AttrBuilder(AttributeSet AS,unsigned Index)1237  AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Index)
1238      : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0),
1239        DerefOrNullBytes(0), AllocSizeArgs(0) {
1240    AttributeSetImpl *pImpl = AS.pImpl;
1241    if (!pImpl) return;
1242  
1243    for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) {
1244      if (pImpl->getSlotIndex(I) != Index) continue;
1245  
1246      for (AttributeSetImpl::iterator II = pImpl->begin(I),
1247             IE = pImpl->end(I); II != IE; ++II)
1248        addAttribute(*II);
1249  
1250      break;
1251    }
1252  }
1253  
clear()1254  void AttrBuilder::clear() {
1255    Attrs.reset();
1256    TargetDepAttrs.clear();
1257    Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0;
1258    AllocSizeArgs = 0;
1259  }
1260  
addAttribute(Attribute::AttrKind Val)1261  AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
1262    assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1263    assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment &&
1264           Val != Attribute::Dereferenceable && Val != Attribute::AllocSize &&
1265           "Adding integer attribute without adding a value!");
1266    Attrs[Val] = true;
1267    return *this;
1268  }
1269  
addAttribute(Attribute Attr)1270  AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
1271    if (Attr.isStringAttribute()) {
1272      addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
1273      return *this;
1274    }
1275  
1276    Attribute::AttrKind Kind = Attr.getKindAsEnum();
1277    Attrs[Kind] = true;
1278  
1279    if (Kind == Attribute::Alignment)
1280      Alignment = Attr.getAlignment();
1281    else if (Kind == Attribute::StackAlignment)
1282      StackAlignment = Attr.getStackAlignment();
1283    else if (Kind == Attribute::Dereferenceable)
1284      DerefBytes = Attr.getDereferenceableBytes();
1285    else if (Kind == Attribute::DereferenceableOrNull)
1286      DerefOrNullBytes = Attr.getDereferenceableOrNullBytes();
1287    else if (Kind == Attribute::AllocSize)
1288      AllocSizeArgs = Attr.getValueAsInt();
1289    return *this;
1290  }
1291  
addAttribute(StringRef A,StringRef V)1292  AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
1293    TargetDepAttrs[A] = V;
1294    return *this;
1295  }
1296  
removeAttribute(Attribute::AttrKind Val)1297  AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
1298    assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1299    Attrs[Val] = false;
1300  
1301    if (Val == Attribute::Alignment)
1302      Alignment = 0;
1303    else if (Val == Attribute::StackAlignment)
1304      StackAlignment = 0;
1305    else if (Val == Attribute::Dereferenceable)
1306      DerefBytes = 0;
1307    else if (Val == Attribute::DereferenceableOrNull)
1308      DerefOrNullBytes = 0;
1309    else if (Val == Attribute::AllocSize)
1310      AllocSizeArgs = 0;
1311  
1312    return *this;
1313  }
1314  
removeAttributes(AttributeSet A,uint64_t Index)1315  AttrBuilder &AttrBuilder::removeAttributes(AttributeSet A, uint64_t Index) {
1316    unsigned Slot = ~0U;
1317    for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I)
1318      if (A.getSlotIndex(I) == Index) {
1319        Slot = I;
1320        break;
1321      }
1322  
1323    assert(Slot != ~0U && "Couldn't find index in AttributeSet!");
1324  
1325    for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot); I != E; ++I) {
1326      Attribute Attr = *I;
1327      if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
1328        removeAttribute(Attr.getKindAsEnum());
1329      } else {
1330        assert(Attr.isStringAttribute() && "Invalid attribute type!");
1331        removeAttribute(Attr.getKindAsString());
1332      }
1333    }
1334  
1335    return *this;
1336  }
1337  
removeAttribute(StringRef A)1338  AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
1339    std::map<std::string, std::string>::iterator I = TargetDepAttrs.find(A);
1340    if (I != TargetDepAttrs.end())
1341      TargetDepAttrs.erase(I);
1342    return *this;
1343  }
1344  
getAllocSizeArgs() const1345  std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1346    return unpackAllocSizeArgs(AllocSizeArgs);
1347  }
1348  
addAlignmentAttr(unsigned Align)1349  AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) {
1350    if (Align == 0) return *this;
1351  
1352    assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1353    assert(Align <= 0x40000000 && "Alignment too large.");
1354  
1355    Attrs[Attribute::Alignment] = true;
1356    Alignment = Align;
1357    return *this;
1358  }
1359  
addStackAlignmentAttr(unsigned Align)1360  AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) {
1361    // Default alignment, allow the target to define how to align it.
1362    if (Align == 0) return *this;
1363  
1364    assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1365    assert(Align <= 0x100 && "Alignment too large.");
1366  
1367    Attrs[Attribute::StackAlignment] = true;
1368    StackAlignment = Align;
1369    return *this;
1370  }
1371  
addDereferenceableAttr(uint64_t Bytes)1372  AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
1373    if (Bytes == 0) return *this;
1374  
1375    Attrs[Attribute::Dereferenceable] = true;
1376    DerefBytes = Bytes;
1377    return *this;
1378  }
1379  
addDereferenceableOrNullAttr(uint64_t Bytes)1380  AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
1381    if (Bytes == 0)
1382      return *this;
1383  
1384    Attrs[Attribute::DereferenceableOrNull] = true;
1385    DerefOrNullBytes = Bytes;
1386    return *this;
1387  }
1388  
addAllocSizeAttr(unsigned ElemSize,const Optional<unsigned> & NumElems)1389  AttrBuilder &AttrBuilder::addAllocSizeAttr(unsigned ElemSize,
1390                                             const Optional<unsigned> &NumElems) {
1391    return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1392  }
1393  
addAllocSizeAttrFromRawRepr(uint64_t RawArgs)1394  AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
1395    // (0, 0) is our "not present" value, so we need to check for it here.
1396    assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1397  
1398    Attrs[Attribute::AllocSize] = true;
1399    // Reuse existing machinery to store this as a single 64-bit integer so we can
1400    // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
1401    AllocSizeArgs = RawArgs;
1402    return *this;
1403  }
1404  
merge(const AttrBuilder & B)1405  AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
1406    // FIXME: What if both have alignments, but they don't match?!
1407    if (!Alignment)
1408      Alignment = B.Alignment;
1409  
1410    if (!StackAlignment)
1411      StackAlignment = B.StackAlignment;
1412  
1413    if (!DerefBytes)
1414      DerefBytes = B.DerefBytes;
1415  
1416    if (!DerefOrNullBytes)
1417      DerefOrNullBytes = B.DerefOrNullBytes;
1418  
1419    if (!AllocSizeArgs)
1420      AllocSizeArgs = B.AllocSizeArgs;
1421  
1422    Attrs |= B.Attrs;
1423  
1424    for (auto I : B.td_attrs())
1425      TargetDepAttrs[I.first] = I.second;
1426  
1427    return *this;
1428  }
1429  
remove(const AttrBuilder & B)1430  AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) {
1431    // FIXME: What if both have alignments, but they don't match?!
1432    if (B.Alignment)
1433      Alignment = 0;
1434  
1435    if (B.StackAlignment)
1436      StackAlignment = 0;
1437  
1438    if (B.DerefBytes)
1439      DerefBytes = 0;
1440  
1441    if (B.DerefOrNullBytes)
1442      DerefOrNullBytes = 0;
1443  
1444    if (B.AllocSizeArgs)
1445      AllocSizeArgs = 0;
1446  
1447    Attrs &= ~B.Attrs;
1448  
1449    for (auto I : B.td_attrs())
1450      TargetDepAttrs.erase(I.first);
1451  
1452    return *this;
1453  }
1454  
overlaps(const AttrBuilder & B) const1455  bool AttrBuilder::overlaps(const AttrBuilder &B) const {
1456    // First check if any of the target independent attributes overlap.
1457    if ((Attrs & B.Attrs).any())
1458      return true;
1459  
1460    // Then check if any target dependent ones do.
1461    for (auto I : td_attrs())
1462      if (B.contains(I.first))
1463        return true;
1464  
1465    return false;
1466  }
1467  
contains(StringRef A) const1468  bool AttrBuilder::contains(StringRef A) const {
1469    return TargetDepAttrs.find(A) != TargetDepAttrs.end();
1470  }
1471  
hasAttributes() const1472  bool AttrBuilder::hasAttributes() const {
1473    return !Attrs.none() || !TargetDepAttrs.empty();
1474  }
1475  
hasAttributes(AttributeSet A,uint64_t Index) const1476  bool AttrBuilder::hasAttributes(AttributeSet A, uint64_t Index) const {
1477    unsigned Slot = ~0U;
1478    for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I)
1479      if (A.getSlotIndex(I) == Index) {
1480        Slot = I;
1481        break;
1482      }
1483  
1484    assert(Slot != ~0U && "Couldn't find the index!");
1485  
1486    for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot); I != E; ++I) {
1487      Attribute Attr = *I;
1488      if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
1489        if (Attrs[I->getKindAsEnum()])
1490          return true;
1491      } else {
1492        assert(Attr.isStringAttribute() && "Invalid attribute kind!");
1493        return TargetDepAttrs.find(Attr.getKindAsString())!=TargetDepAttrs.end();
1494      }
1495    }
1496  
1497    return false;
1498  }
1499  
hasAlignmentAttr() const1500  bool AttrBuilder::hasAlignmentAttr() const {
1501    return Alignment != 0;
1502  }
1503  
operator ==(const AttrBuilder & B)1504  bool AttrBuilder::operator==(const AttrBuilder &B) {
1505    if (Attrs != B.Attrs)
1506      return false;
1507  
1508    for (td_const_iterator I = TargetDepAttrs.begin(),
1509           E = TargetDepAttrs.end(); I != E; ++I)
1510      if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end())
1511        return false;
1512  
1513    return Alignment == B.Alignment && StackAlignment == B.StackAlignment &&
1514           DerefBytes == B.DerefBytes;
1515  }
1516  
addRawValue(uint64_t Val)1517  AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) {
1518    // FIXME: Remove this in 4.0.
1519    if (!Val) return *this;
1520  
1521    for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
1522         I = Attribute::AttrKind(I + 1)) {
1523      if (I == Attribute::Dereferenceable ||
1524          I == Attribute::DereferenceableOrNull ||
1525          I == Attribute::ArgMemOnly ||
1526          I == Attribute::AllocSize)
1527        continue;
1528      if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) {
1529        Attrs[I] = true;
1530  
1531        if (I == Attribute::Alignment)
1532          Alignment = 1ULL << ((A >> 16) - 1);
1533        else if (I == Attribute::StackAlignment)
1534          StackAlignment = 1ULL << ((A >> 26)-1);
1535      }
1536    }
1537  
1538    return *this;
1539  }
1540  
1541  //===----------------------------------------------------------------------===//
1542  // AttributeFuncs Function Defintions
1543  //===----------------------------------------------------------------------===//
1544  
1545  /// \brief Which attributes cannot be applied to a type.
typeIncompatible(Type * Ty)1546  AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
1547    AttrBuilder Incompatible;
1548  
1549    if (!Ty->isIntegerTy())
1550      // Attribute that only apply to integers.
1551      Incompatible.addAttribute(Attribute::SExt)
1552        .addAttribute(Attribute::ZExt);
1553  
1554    if (!Ty->isPointerTy())
1555      // Attribute that only apply to pointers.
1556      Incompatible.addAttribute(Attribute::ByVal)
1557        .addAttribute(Attribute::Nest)
1558        .addAttribute(Attribute::NoAlias)
1559        .addAttribute(Attribute::NoCapture)
1560        .addAttribute(Attribute::NonNull)
1561        .addDereferenceableAttr(1) // the int here is ignored
1562        .addDereferenceableOrNullAttr(1) // the int here is ignored
1563        .addAttribute(Attribute::ReadNone)
1564        .addAttribute(Attribute::ReadOnly)
1565        .addAttribute(Attribute::StructRet)
1566        .addAttribute(Attribute::InAlloca);
1567  
1568    return Incompatible;
1569  }
1570  
1571  template<typename AttrClass>
isEqual(const Function & Caller,const Function & Callee)1572  static bool isEqual(const Function &Caller, const Function &Callee) {
1573    return Caller.getFnAttribute(AttrClass::getKind()) ==
1574           Callee.getFnAttribute(AttrClass::getKind());
1575  }
1576  
1577  /// \brief Compute the logical AND of the attributes of the caller and the
1578  /// callee.
1579  ///
1580  /// This function sets the caller's attribute to false if the callee's attribute
1581  /// is false.
1582  template<typename AttrClass>
setAND(Function & Caller,const Function & Callee)1583  static void setAND(Function &Caller, const Function &Callee) {
1584    if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
1585        !AttrClass::isSet(Callee, AttrClass::getKind()))
1586      AttrClass::set(Caller, AttrClass::getKind(), false);
1587  }
1588  
1589  /// \brief Compute the logical OR of the attributes of the caller and the
1590  /// callee.
1591  ///
1592  /// This function sets the caller's attribute to true if the callee's attribute
1593  /// is true.
1594  template<typename AttrClass>
setOR(Function & Caller,const Function & Callee)1595  static void setOR(Function &Caller, const Function &Callee) {
1596    if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
1597        AttrClass::isSet(Callee, AttrClass::getKind()))
1598      AttrClass::set(Caller, AttrClass::getKind(), true);
1599  }
1600  
1601  /// \brief If the inlined function had a higher stack protection level than the
1602  /// calling function, then bump up the caller's stack protection level.
adjustCallerSSPLevel(Function & Caller,const Function & Callee)1603  static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
1604    // If upgrading the SSP attribute, clear out the old SSP Attributes first.
1605    // Having multiple SSP attributes doesn't actually hurt, but it adds useless
1606    // clutter to the IR.
1607    AttrBuilder B;
1608    B.addAttribute(Attribute::StackProtect)
1609      .addAttribute(Attribute::StackProtectStrong)
1610      .addAttribute(Attribute::StackProtectReq);
1611    AttributeSet OldSSPAttr = AttributeSet::get(Caller.getContext(),
1612                                                AttributeSet::FunctionIndex,
1613                                                B);
1614  
1615    if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
1616      Caller.removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
1617      Caller.addFnAttr(Attribute::StackProtectReq);
1618    } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
1619               !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
1620      Caller.removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
1621      Caller.addFnAttr(Attribute::StackProtectStrong);
1622    } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
1623               !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
1624               !Caller.hasFnAttribute(Attribute::StackProtectStrong))
1625      Caller.addFnAttr(Attribute::StackProtect);
1626  }
1627  
1628  #define GET_ATTR_COMPAT_FUNC
1629  #include "AttributesCompatFunc.inc"
1630  
areInlineCompatible(const Function & Caller,const Function & Callee)1631  bool AttributeFuncs::areInlineCompatible(const Function &Caller,
1632                                           const Function &Callee) {
1633    return hasCompatibleFnAttrs(Caller, Callee);
1634  }
1635  
1636  
mergeAttributesForInlining(Function & Caller,const Function & Callee)1637  void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
1638                                                  const Function &Callee) {
1639    mergeFnAttrs(Caller, Callee);
1640  }
1641