xref: /freebsd/contrib/llvm-project/llvm/lib/IR/Attributes.cpp (revision e63d20b70ee1dbee9b075f29de6f30cdcfe1abe1)
1 //===- Attributes.cpp - Implement AttributesList --------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // \file
10 // This file implements the Attribute, AttributeImpl, AttrBuilder,
11 // AttributeListImpl, and AttributeList classes.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/IR/Attributes.h"
16 #include "AttributeImpl.h"
17 #include "LLVMContextImpl.h"
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/FoldingSet.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/StringExtras.h"
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/ADT/StringSwitch.h"
25 #include "llvm/Config/llvm-config.h"
26 #include "llvm/IR/AttributeMask.h"
27 #include "llvm/IR/Function.h"
28 #include "llvm/IR/LLVMContext.h"
29 #include "llvm/IR/Type.h"
30 #include "llvm/Support/Compiler.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/ModRef.h"
33 #include "llvm/Support/raw_ostream.h"
34 #include <algorithm>
35 #include <cassert>
36 #include <cstddef>
37 #include <cstdint>
38 #include <limits>
39 #include <optional>
40 #include <string>
41 #include <tuple>
42 #include <utility>
43 
44 using namespace llvm;
45 
46 //===----------------------------------------------------------------------===//
47 // Attribute Construction Methods
48 //===----------------------------------------------------------------------===//
49 
50 // allocsize has two integer arguments, but because they're both 32 bits, we can
51 // pack them into one 64-bit value, at the cost of making said value
52 // nonsensical.
53 //
54 // In order to do this, we need to reserve one value of the second (optional)
55 // allocsize argument to signify "not present."
56 static const unsigned AllocSizeNumElemsNotPresent = -1;
57 
58 static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
59                                   const std::optional<unsigned> &NumElemsArg) {
60   assert((!NumElemsArg || *NumElemsArg != AllocSizeNumElemsNotPresent) &&
61          "Attempting to pack a reserved value");
62 
63   return uint64_t(ElemSizeArg) << 32 |
64          NumElemsArg.value_or(AllocSizeNumElemsNotPresent);
65 }
66 
67 static std::pair<unsigned, std::optional<unsigned>>
68 unpackAllocSizeArgs(uint64_t Num) {
69   unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
70   unsigned ElemSizeArg = Num >> 32;
71 
72   std::optional<unsigned> NumElemsArg;
73   if (NumElems != AllocSizeNumElemsNotPresent)
74     NumElemsArg = NumElems;
75   return std::make_pair(ElemSizeArg, NumElemsArg);
76 }
77 
78 static uint64_t packVScaleRangeArgs(unsigned MinValue,
79                                     std::optional<unsigned> MaxValue) {
80   return uint64_t(MinValue) << 32 | MaxValue.value_or(0);
81 }
82 
83 static std::pair<unsigned, std::optional<unsigned>>
84 unpackVScaleRangeArgs(uint64_t Value) {
85   unsigned MaxValue = Value & std::numeric_limits<unsigned>::max();
86   unsigned MinValue = Value >> 32;
87 
88   return std::make_pair(MinValue,
89                         MaxValue > 0 ? MaxValue : std::optional<unsigned>());
90 }
91 
92 Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
93                          uint64_t Val) {
94   bool IsIntAttr = Attribute::isIntAttrKind(Kind);
95   assert((IsIntAttr || Attribute::isEnumAttrKind(Kind)) &&
96          "Not an enum or int attribute");
97 
98   LLVMContextImpl *pImpl = Context.pImpl;
99   FoldingSetNodeID ID;
100   ID.AddInteger(Kind);
101   if (IsIntAttr)
102     ID.AddInteger(Val);
103   else
104     assert(Val == 0 && "Value must be zero for enum attributes");
105 
106   void *InsertPoint;
107   AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
108 
109   if (!PA) {
110     // If we didn't find any existing attributes of the same shape then create a
111     // new one and insert it.
112     if (!IsIntAttr)
113       PA = new (pImpl->Alloc) EnumAttributeImpl(Kind);
114     else
115       PA = new (pImpl->Alloc) IntAttributeImpl(Kind, Val);
116     pImpl->AttrsSet.InsertNode(PA, InsertPoint);
117   }
118 
119   // Return the Attribute that we found or created.
120   return Attribute(PA);
121 }
122 
123 Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
124   LLVMContextImpl *pImpl = Context.pImpl;
125   FoldingSetNodeID ID;
126   ID.AddString(Kind);
127   if (!Val.empty()) ID.AddString(Val);
128 
129   void *InsertPoint;
130   AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
131 
132   if (!PA) {
133     // If we didn't find any existing attributes of the same shape then create a
134     // new one and insert it.
135     void *Mem =
136         pImpl->Alloc.Allocate(StringAttributeImpl::totalSizeToAlloc(Kind, Val),
137                               alignof(StringAttributeImpl));
138     PA = new (Mem) StringAttributeImpl(Kind, Val);
139     pImpl->AttrsSet.InsertNode(PA, InsertPoint);
140   }
141 
142   // Return the Attribute that we found or created.
143   return Attribute(PA);
144 }
145 
146 Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
147                          Type *Ty) {
148   assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute");
149   LLVMContextImpl *pImpl = Context.pImpl;
150   FoldingSetNodeID ID;
151   ID.AddInteger(Kind);
152   ID.AddPointer(Ty);
153 
154   void *InsertPoint;
155   AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
156 
157   if (!PA) {
158     // If we didn't find any existing attributes of the same shape then create a
159     // new one and insert it.
160     PA = new (pImpl->Alloc) TypeAttributeImpl(Kind, Ty);
161     pImpl->AttrsSet.InsertNode(PA, InsertPoint);
162   }
163 
164   // Return the Attribute that we found or created.
165   return Attribute(PA);
166 }
167 
168 Attribute Attribute::getWithAlignment(LLVMContext &Context, Align A) {
169   assert(A <= llvm::Value::MaximumAlignment && "Alignment too large.");
170   return get(Context, Alignment, A.value());
171 }
172 
173 Attribute Attribute::getWithStackAlignment(LLVMContext &Context, Align A) {
174   assert(A <= 0x100 && "Alignment too large.");
175   return get(Context, StackAlignment, A.value());
176 }
177 
178 Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context,
179                                                 uint64_t Bytes) {
180   assert(Bytes && "Bytes must be non-zero.");
181   return get(Context, Dereferenceable, Bytes);
182 }
183 
184 Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
185                                                        uint64_t Bytes) {
186   assert(Bytes && "Bytes must be non-zero.");
187   return get(Context, DereferenceableOrNull, Bytes);
188 }
189 
190 Attribute Attribute::getWithByValType(LLVMContext &Context, Type *Ty) {
191   return get(Context, ByVal, Ty);
192 }
193 
194 Attribute Attribute::getWithStructRetType(LLVMContext &Context, Type *Ty) {
195   return get(Context, StructRet, Ty);
196 }
197 
198 Attribute Attribute::getWithByRefType(LLVMContext &Context, Type *Ty) {
199   return get(Context, ByRef, Ty);
200 }
201 
202 Attribute Attribute::getWithPreallocatedType(LLVMContext &Context, Type *Ty) {
203   return get(Context, Preallocated, Ty);
204 }
205 
206 Attribute Attribute::getWithInAllocaType(LLVMContext &Context, Type *Ty) {
207   return get(Context, InAlloca, Ty);
208 }
209 
210 Attribute Attribute::getWithUWTableKind(LLVMContext &Context,
211                                         UWTableKind Kind) {
212   return get(Context, UWTable, uint64_t(Kind));
213 }
214 
215 Attribute Attribute::getWithMemoryEffects(LLVMContext &Context,
216                                           MemoryEffects ME) {
217   return get(Context, Memory, ME.toIntValue());
218 }
219 
220 Attribute Attribute::getWithNoFPClass(LLVMContext &Context,
221                                       FPClassTest ClassMask) {
222   return get(Context, NoFPClass, ClassMask);
223 }
224 
225 Attribute
226 Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
227                                 const std::optional<unsigned> &NumElemsArg) {
228   assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
229          "Invalid allocsize arguments -- given allocsize(0, 0)");
230   return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
231 }
232 
233 Attribute Attribute::getWithVScaleRangeArgs(LLVMContext &Context,
234                                             unsigned MinValue,
235                                             unsigned MaxValue) {
236   return get(Context, VScaleRange, packVScaleRangeArgs(MinValue, MaxValue));
237 }
238 
239 Attribute::AttrKind Attribute::getAttrKindFromName(StringRef AttrName) {
240   return StringSwitch<Attribute::AttrKind>(AttrName)
241 #define GET_ATTR_NAMES
242 #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME)                                \
243   .Case(#DISPLAY_NAME, Attribute::ENUM_NAME)
244 #include "llvm/IR/Attributes.inc"
245       .Default(Attribute::None);
246 }
247 
248 StringRef Attribute::getNameFromAttrKind(Attribute::AttrKind AttrKind) {
249   switch (AttrKind) {
250 #define GET_ATTR_NAMES
251 #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME)                                \
252   case Attribute::ENUM_NAME:                                                   \
253     return #DISPLAY_NAME;
254 #include "llvm/IR/Attributes.inc"
255   case Attribute::None:
256     return "none";
257   default:
258     llvm_unreachable("invalid Kind");
259   }
260 }
261 
262 bool Attribute::isExistingAttribute(StringRef Name) {
263   return StringSwitch<bool>(Name)
264 #define GET_ATTR_NAMES
265 #define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)
266 #include "llvm/IR/Attributes.inc"
267       .Default(false);
268 }
269 
270 //===----------------------------------------------------------------------===//
271 // Attribute Accessor Methods
272 //===----------------------------------------------------------------------===//
273 
274 bool Attribute::isEnumAttribute() const {
275   return pImpl && pImpl->isEnumAttribute();
276 }
277 
278 bool Attribute::isIntAttribute() const {
279   return pImpl && pImpl->isIntAttribute();
280 }
281 
282 bool Attribute::isStringAttribute() const {
283   return pImpl && pImpl->isStringAttribute();
284 }
285 
286 bool Attribute::isTypeAttribute() const {
287   return pImpl && pImpl->isTypeAttribute();
288 }
289 
290 Attribute::AttrKind Attribute::getKindAsEnum() const {
291   if (!pImpl) return None;
292   assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute()) &&
293          "Invalid attribute type to get the kind as an enum!");
294   return pImpl->getKindAsEnum();
295 }
296 
297 uint64_t Attribute::getValueAsInt() const {
298   if (!pImpl) return 0;
299   assert(isIntAttribute() &&
300          "Expected the attribute to be an integer attribute!");
301   return pImpl->getValueAsInt();
302 }
303 
304 bool Attribute::getValueAsBool() const {
305   if (!pImpl) return false;
306   assert(isStringAttribute() &&
307          "Expected the attribute to be a string attribute!");
308   return pImpl->getValueAsBool();
309 }
310 
311 StringRef Attribute::getKindAsString() const {
312   if (!pImpl) return {};
313   assert(isStringAttribute() &&
314          "Invalid attribute type to get the kind as a string!");
315   return pImpl->getKindAsString();
316 }
317 
318 StringRef Attribute::getValueAsString() const {
319   if (!pImpl) return {};
320   assert(isStringAttribute() &&
321          "Invalid attribute type to get the value as a string!");
322   return pImpl->getValueAsString();
323 }
324 
325 Type *Attribute::getValueAsType() const {
326   if (!pImpl) return {};
327   assert(isTypeAttribute() &&
328          "Invalid attribute type to get the value as a type!");
329   return pImpl->getValueAsType();
330 }
331 
332 
333 bool Attribute::hasAttribute(AttrKind Kind) const {
334   return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
335 }
336 
337 bool Attribute::hasAttribute(StringRef Kind) const {
338   if (!isStringAttribute()) return false;
339   return pImpl && pImpl->hasAttribute(Kind);
340 }
341 
342 MaybeAlign Attribute::getAlignment() const {
343   assert(hasAttribute(Attribute::Alignment) &&
344          "Trying to get alignment from non-alignment attribute!");
345   return MaybeAlign(pImpl->getValueAsInt());
346 }
347 
348 MaybeAlign Attribute::getStackAlignment() const {
349   assert(hasAttribute(Attribute::StackAlignment) &&
350          "Trying to get alignment from non-alignment attribute!");
351   return MaybeAlign(pImpl->getValueAsInt());
352 }
353 
354 uint64_t Attribute::getDereferenceableBytes() const {
355   assert(hasAttribute(Attribute::Dereferenceable) &&
356          "Trying to get dereferenceable bytes from "
357          "non-dereferenceable attribute!");
358   return pImpl->getValueAsInt();
359 }
360 
361 uint64_t Attribute::getDereferenceableOrNullBytes() const {
362   assert(hasAttribute(Attribute::DereferenceableOrNull) &&
363          "Trying to get dereferenceable bytes from "
364          "non-dereferenceable attribute!");
365   return pImpl->getValueAsInt();
366 }
367 
368 std::pair<unsigned, std::optional<unsigned>>
369 Attribute::getAllocSizeArgs() const {
370   assert(hasAttribute(Attribute::AllocSize) &&
371          "Trying to get allocsize args from non-allocsize attribute");
372   return unpackAllocSizeArgs(pImpl->getValueAsInt());
373 }
374 
375 unsigned Attribute::getVScaleRangeMin() const {
376   assert(hasAttribute(Attribute::VScaleRange) &&
377          "Trying to get vscale args from non-vscale attribute");
378   return unpackVScaleRangeArgs(pImpl->getValueAsInt()).first;
379 }
380 
381 std::optional<unsigned> Attribute::getVScaleRangeMax() const {
382   assert(hasAttribute(Attribute::VScaleRange) &&
383          "Trying to get vscale args from non-vscale attribute");
384   return unpackVScaleRangeArgs(pImpl->getValueAsInt()).second;
385 }
386 
387 UWTableKind Attribute::getUWTableKind() const {
388   assert(hasAttribute(Attribute::UWTable) &&
389          "Trying to get unwind table kind from non-uwtable attribute");
390   return UWTableKind(pImpl->getValueAsInt());
391 }
392 
393 AllocFnKind Attribute::getAllocKind() const {
394   assert(hasAttribute(Attribute::AllocKind) &&
395          "Trying to get allockind value from non-allockind attribute");
396   return AllocFnKind(pImpl->getValueAsInt());
397 }
398 
399 MemoryEffects Attribute::getMemoryEffects() const {
400   assert(hasAttribute(Attribute::Memory) &&
401          "Can only call getMemoryEffects() on memory attribute");
402   return MemoryEffects::createFromIntValue(pImpl->getValueAsInt());
403 }
404 
405 FPClassTest Attribute::getNoFPClass() const {
406   assert(hasAttribute(Attribute::NoFPClass) &&
407          "Can only call getNoFPClass() on nofpclass attribute");
408   return static_cast<FPClassTest>(pImpl->getValueAsInt());
409 }
410 
411 static const char *getModRefStr(ModRefInfo MR) {
412   switch (MR) {
413   case ModRefInfo::NoModRef:
414     return "none";
415   case ModRefInfo::Ref:
416     return "read";
417   case ModRefInfo::Mod:
418     return "write";
419   case ModRefInfo::ModRef:
420     return "readwrite";
421   }
422   llvm_unreachable("Invalid ModRefInfo");
423 }
424 
425 std::string Attribute::getAsString(bool InAttrGrp) const {
426   if (!pImpl) return {};
427 
428   if (isEnumAttribute())
429     return getNameFromAttrKind(getKindAsEnum()).str();
430 
431   if (isTypeAttribute()) {
432     std::string Result = getNameFromAttrKind(getKindAsEnum()).str();
433     Result += '(';
434     raw_string_ostream OS(Result);
435     getValueAsType()->print(OS, false, true);
436     OS.flush();
437     Result += ')';
438     return Result;
439   }
440 
441   // FIXME: These should be output like this:
442   //
443   //   align=4
444   //   alignstack=8
445   //
446   if (hasAttribute(Attribute::Alignment))
447     return (InAttrGrp ? "align=" + Twine(getValueAsInt())
448                       : "align " + Twine(getValueAsInt()))
449         .str();
450 
451   auto AttrWithBytesToString = [&](const char *Name) {
452     return (InAttrGrp ? Name + ("=" + Twine(getValueAsInt()))
453                       : Name + ("(" + Twine(getValueAsInt())) + ")")
454         .str();
455   };
456 
457   if (hasAttribute(Attribute::StackAlignment))
458     return AttrWithBytesToString("alignstack");
459 
460   if (hasAttribute(Attribute::Dereferenceable))
461     return AttrWithBytesToString("dereferenceable");
462 
463   if (hasAttribute(Attribute::DereferenceableOrNull))
464     return AttrWithBytesToString("dereferenceable_or_null");
465 
466   if (hasAttribute(Attribute::AllocSize)) {
467     unsigned ElemSize;
468     std::optional<unsigned> NumElems;
469     std::tie(ElemSize, NumElems) = getAllocSizeArgs();
470 
471     return (NumElems
472                 ? "allocsize(" + Twine(ElemSize) + "," + Twine(*NumElems) + ")"
473                 : "allocsize(" + Twine(ElemSize) + ")")
474         .str();
475   }
476 
477   if (hasAttribute(Attribute::VScaleRange)) {
478     unsigned MinValue = getVScaleRangeMin();
479     std::optional<unsigned> MaxValue = getVScaleRangeMax();
480     return ("vscale_range(" + Twine(MinValue) + "," +
481             Twine(MaxValue.value_or(0)) + ")")
482         .str();
483   }
484 
485   if (hasAttribute(Attribute::UWTable)) {
486     UWTableKind Kind = getUWTableKind();
487     if (Kind != UWTableKind::None) {
488       return Kind == UWTableKind::Default
489                  ? "uwtable"
490                  : ("uwtable(" +
491                     Twine(Kind == UWTableKind::Sync ? "sync" : "async") + ")")
492                        .str();
493     }
494   }
495 
496   if (hasAttribute(Attribute::AllocKind)) {
497     AllocFnKind Kind = getAllocKind();
498     SmallVector<StringRef> parts;
499     if ((Kind & AllocFnKind::Alloc) != AllocFnKind::Unknown)
500       parts.push_back("alloc");
501     if ((Kind & AllocFnKind::Realloc) != AllocFnKind::Unknown)
502       parts.push_back("realloc");
503     if ((Kind & AllocFnKind::Free) != AllocFnKind::Unknown)
504       parts.push_back("free");
505     if ((Kind & AllocFnKind::Uninitialized) != AllocFnKind::Unknown)
506       parts.push_back("uninitialized");
507     if ((Kind & AllocFnKind::Zeroed) != AllocFnKind::Unknown)
508       parts.push_back("zeroed");
509     if ((Kind & AllocFnKind::Aligned) != AllocFnKind::Unknown)
510       parts.push_back("aligned");
511     return ("allockind(\"" +
512             Twine(llvm::join(parts.begin(), parts.end(), ",")) + "\")")
513         .str();
514   }
515 
516   if (hasAttribute(Attribute::Memory)) {
517     std::string Result;
518     raw_string_ostream OS(Result);
519     bool First = true;
520     OS << "memory(";
521 
522     MemoryEffects ME = getMemoryEffects();
523 
524     // Print access kind for "other" as the default access kind. This way it
525     // will apply to any new location kinds that get split out of "other".
526     ModRefInfo OtherMR = ME.getModRef(IRMemLocation::Other);
527     if (OtherMR != ModRefInfo::NoModRef || ME.getModRef() == OtherMR) {
528       First = false;
529       OS << getModRefStr(OtherMR);
530     }
531 
532     for (auto Loc : MemoryEffects::locations()) {
533       ModRefInfo MR = ME.getModRef(Loc);
534       if (MR == OtherMR)
535         continue;
536 
537       if (!First)
538         OS << ", ";
539       First = false;
540 
541       switch (Loc) {
542       case IRMemLocation::ArgMem:
543         OS << "argmem: ";
544         break;
545       case IRMemLocation::InaccessibleMem:
546         OS << "inaccessiblemem: ";
547         break;
548       case IRMemLocation::Other:
549         llvm_unreachable("This is represented as the default access kind");
550       }
551       OS << getModRefStr(MR);
552     }
553     OS << ")";
554     OS.flush();
555     return Result;
556   }
557 
558   if (hasAttribute(Attribute::NoFPClass)) {
559     std::string Result = "nofpclass";
560     raw_string_ostream OS(Result);
561     OS << getNoFPClass();
562     return Result;
563   }
564 
565   // Convert target-dependent attributes to strings of the form:
566   //
567   //   "kind"
568   //   "kind" = "value"
569   //
570   if (isStringAttribute()) {
571     std::string Result;
572     {
573       raw_string_ostream OS(Result);
574       OS << '"' << getKindAsString() << '"';
575 
576       // Since some attribute strings contain special characters that cannot be
577       // printable, those have to be escaped to make the attribute value
578       // printable as is.  e.g. "\01__gnu_mcount_nc"
579       const auto &AttrVal = pImpl->getValueAsString();
580       if (!AttrVal.empty()) {
581         OS << "=\"";
582         printEscapedString(AttrVal, OS);
583         OS << "\"";
584       }
585     }
586     return Result;
587   }
588 
589   llvm_unreachable("Unknown attribute");
590 }
591 
592 bool Attribute::hasParentContext(LLVMContext &C) const {
593   assert(isValid() && "invalid Attribute doesn't refer to any context");
594   FoldingSetNodeID ID;
595   pImpl->Profile(ID);
596   void *Unused;
597   return C.pImpl->AttrsSet.FindNodeOrInsertPos(ID, Unused) == pImpl;
598 }
599 
600 bool Attribute::operator<(Attribute A) const {
601   if (!pImpl && !A.pImpl) return false;
602   if (!pImpl) return true;
603   if (!A.pImpl) return false;
604   return *pImpl < *A.pImpl;
605 }
606 
607 void Attribute::Profile(FoldingSetNodeID &ID) const {
608   ID.AddPointer(pImpl);
609 }
610 
611 enum AttributeProperty {
612   FnAttr = (1 << 0),
613   ParamAttr = (1 << 1),
614   RetAttr = (1 << 2),
615 };
616 
617 #define GET_ATTR_PROP_TABLE
618 #include "llvm/IR/Attributes.inc"
619 
620 static bool hasAttributeProperty(Attribute::AttrKind Kind,
621                                  AttributeProperty Prop) {
622   unsigned Index = Kind - 1;
623   assert(Index < std::size(AttrPropTable) && "Invalid attribute kind");
624   return AttrPropTable[Index] & Prop;
625 }
626 
627 bool Attribute::canUseAsFnAttr(AttrKind Kind) {
628   return hasAttributeProperty(Kind, AttributeProperty::FnAttr);
629 }
630 
631 bool Attribute::canUseAsParamAttr(AttrKind Kind) {
632   return hasAttributeProperty(Kind, AttributeProperty::ParamAttr);
633 }
634 
635 bool Attribute::canUseAsRetAttr(AttrKind Kind) {
636   return hasAttributeProperty(Kind, AttributeProperty::RetAttr);
637 }
638 
639 //===----------------------------------------------------------------------===//
640 // AttributeImpl Definition
641 //===----------------------------------------------------------------------===//
642 
643 bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
644   if (isStringAttribute()) return false;
645   return getKindAsEnum() == A;
646 }
647 
648 bool AttributeImpl::hasAttribute(StringRef Kind) const {
649   if (!isStringAttribute()) return false;
650   return getKindAsString() == Kind;
651 }
652 
653 Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
654   assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute());
655   return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
656 }
657 
658 uint64_t AttributeImpl::getValueAsInt() const {
659   assert(isIntAttribute());
660   return static_cast<const IntAttributeImpl *>(this)->getValue();
661 }
662 
663 bool AttributeImpl::getValueAsBool() const {
664   assert(getValueAsString().empty() || getValueAsString() == "false" || getValueAsString() == "true");
665   return getValueAsString() == "true";
666 }
667 
668 StringRef AttributeImpl::getKindAsString() const {
669   assert(isStringAttribute());
670   return static_cast<const StringAttributeImpl *>(this)->getStringKind();
671 }
672 
673 StringRef AttributeImpl::getValueAsString() const {
674   assert(isStringAttribute());
675   return static_cast<const StringAttributeImpl *>(this)->getStringValue();
676 }
677 
678 Type *AttributeImpl::getValueAsType() const {
679   assert(isTypeAttribute());
680   return static_cast<const TypeAttributeImpl *>(this)->getTypeValue();
681 }
682 
683 bool AttributeImpl::operator<(const AttributeImpl &AI) const {
684   if (this == &AI)
685     return false;
686 
687   // This sorts the attributes with Attribute::AttrKinds coming first (sorted
688   // relative to their enum value) and then strings.
689   if (!isStringAttribute()) {
690     if (AI.isStringAttribute())
691       return true;
692     if (getKindAsEnum() != AI.getKindAsEnum())
693       return getKindAsEnum() < AI.getKindAsEnum();
694     assert(!AI.isEnumAttribute() && "Non-unique attribute");
695     assert(!AI.isTypeAttribute() && "Comparison of types would be unstable");
696     // TODO: Is this actually needed?
697     assert(AI.isIntAttribute() && "Only possibility left");
698     return getValueAsInt() < AI.getValueAsInt();
699   }
700 
701   if (!AI.isStringAttribute())
702     return false;
703   if (getKindAsString() == AI.getKindAsString())
704     return getValueAsString() < AI.getValueAsString();
705   return getKindAsString() < AI.getKindAsString();
706 }
707 
708 //===----------------------------------------------------------------------===//
709 // AttributeSet Definition
710 //===----------------------------------------------------------------------===//
711 
712 AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) {
713   return AttributeSet(AttributeSetNode::get(C, B));
714 }
715 
716 AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
717   return AttributeSet(AttributeSetNode::get(C, Attrs));
718 }
719 
720 AttributeSet AttributeSet::addAttribute(LLVMContext &C,
721                                         Attribute::AttrKind Kind) const {
722   if (hasAttribute(Kind)) return *this;
723   AttrBuilder B(C);
724   B.addAttribute(Kind);
725   return addAttributes(C, AttributeSet::get(C, B));
726 }
727 
728 AttributeSet AttributeSet::addAttribute(LLVMContext &C, StringRef Kind,
729                                         StringRef Value) const {
730   AttrBuilder B(C);
731   B.addAttribute(Kind, Value);
732   return addAttributes(C, AttributeSet::get(C, B));
733 }
734 
735 AttributeSet AttributeSet::addAttributes(LLVMContext &C,
736                                          const AttributeSet AS) const {
737   if (!hasAttributes())
738     return AS;
739 
740   if (!AS.hasAttributes())
741     return *this;
742 
743   AttrBuilder B(C, *this);
744   B.merge(AttrBuilder(C, AS));
745   return get(C, B);
746 }
747 
748 AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
749                                              Attribute::AttrKind Kind) const {
750   if (!hasAttribute(Kind)) return *this;
751   AttrBuilder B(C, *this);
752   B.removeAttribute(Kind);
753   return get(C, B);
754 }
755 
756 AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
757                                              StringRef Kind) const {
758   if (!hasAttribute(Kind)) return *this;
759   AttrBuilder B(C, *this);
760   B.removeAttribute(Kind);
761   return get(C, B);
762 }
763 
764 AttributeSet AttributeSet::removeAttributes(LLVMContext &C,
765                                             const AttributeMask &Attrs) const {
766   AttrBuilder B(C, *this);
767   // If there is nothing to remove, directly return the original set.
768   if (!B.overlaps(Attrs))
769     return *this;
770 
771   B.remove(Attrs);
772   return get(C, B);
773 }
774 
775 unsigned AttributeSet::getNumAttributes() const {
776   return SetNode ? SetNode->getNumAttributes() : 0;
777 }
778 
779 bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const {
780   return SetNode ? SetNode->hasAttribute(Kind) : false;
781 }
782 
783 bool AttributeSet::hasAttribute(StringRef Kind) const {
784   return SetNode ? SetNode->hasAttribute(Kind) : false;
785 }
786 
787 Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const {
788   return SetNode ? SetNode->getAttribute(Kind) : Attribute();
789 }
790 
791 Attribute AttributeSet::getAttribute(StringRef Kind) const {
792   return SetNode ? SetNode->getAttribute(Kind) : Attribute();
793 }
794 
795 MaybeAlign AttributeSet::getAlignment() const {
796   return SetNode ? SetNode->getAlignment() : std::nullopt;
797 }
798 
799 MaybeAlign AttributeSet::getStackAlignment() const {
800   return SetNode ? SetNode->getStackAlignment() : std::nullopt;
801 }
802 
803 uint64_t AttributeSet::getDereferenceableBytes() const {
804   return SetNode ? SetNode->getDereferenceableBytes() : 0;
805 }
806 
807 uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
808   return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
809 }
810 
811 Type *AttributeSet::getByRefType() const {
812   return SetNode ? SetNode->getAttributeType(Attribute::ByRef) : nullptr;
813 }
814 
815 Type *AttributeSet::getByValType() const {
816   return SetNode ? SetNode->getAttributeType(Attribute::ByVal) : nullptr;
817 }
818 
819 Type *AttributeSet::getStructRetType() const {
820   return SetNode ? SetNode->getAttributeType(Attribute::StructRet) : nullptr;
821 }
822 
823 Type *AttributeSet::getPreallocatedType() const {
824   return SetNode ? SetNode->getAttributeType(Attribute::Preallocated) : nullptr;
825 }
826 
827 Type *AttributeSet::getInAllocaType() const {
828   return SetNode ? SetNode->getAttributeType(Attribute::InAlloca) : nullptr;
829 }
830 
831 Type *AttributeSet::getElementType() const {
832   return SetNode ? SetNode->getAttributeType(Attribute::ElementType) : nullptr;
833 }
834 
835 std::optional<std::pair<unsigned, std::optional<unsigned>>>
836 AttributeSet::getAllocSizeArgs() const {
837   if (SetNode)
838     return SetNode->getAllocSizeArgs();
839   return std::nullopt;
840 }
841 
842 unsigned AttributeSet::getVScaleRangeMin() const {
843   return SetNode ? SetNode->getVScaleRangeMin() : 1;
844 }
845 
846 std::optional<unsigned> AttributeSet::getVScaleRangeMax() const {
847   return SetNode ? SetNode->getVScaleRangeMax() : std::nullopt;
848 }
849 
850 UWTableKind AttributeSet::getUWTableKind() const {
851   return SetNode ? SetNode->getUWTableKind() : UWTableKind::None;
852 }
853 
854 AllocFnKind AttributeSet::getAllocKind() const {
855   return SetNode ? SetNode->getAllocKind() : AllocFnKind::Unknown;
856 }
857 
858 MemoryEffects AttributeSet::getMemoryEffects() const {
859   return SetNode ? SetNode->getMemoryEffects() : MemoryEffects::unknown();
860 }
861 
862 FPClassTest AttributeSet::getNoFPClass() const {
863   return SetNode ? SetNode->getNoFPClass() : fcNone;
864 }
865 
866 std::string AttributeSet::getAsString(bool InAttrGrp) const {
867   return SetNode ? SetNode->getAsString(InAttrGrp) : "";
868 }
869 
870 bool AttributeSet::hasParentContext(LLVMContext &C) const {
871   assert(hasAttributes() && "empty AttributeSet doesn't refer to any context");
872   FoldingSetNodeID ID;
873   SetNode->Profile(ID);
874   void *Unused;
875   return C.pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, Unused) == SetNode;
876 }
877 
878 AttributeSet::iterator AttributeSet::begin() const {
879   return SetNode ? SetNode->begin() : nullptr;
880 }
881 
882 AttributeSet::iterator AttributeSet::end() const {
883   return SetNode ? SetNode->end() : nullptr;
884 }
885 
886 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
887 LLVM_DUMP_METHOD void AttributeSet::dump() const {
888   dbgs() << "AS =\n";
889     dbgs() << "  { ";
890     dbgs() << getAsString(true) << " }\n";
891 }
892 #endif
893 
894 //===----------------------------------------------------------------------===//
895 // AttributeSetNode Definition
896 //===----------------------------------------------------------------------===//
897 
898 AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
899     : NumAttrs(Attrs.size()) {
900   // There's memory after the node where we can store the entries in.
901   llvm::copy(Attrs, getTrailingObjects<Attribute>());
902 
903   for (const auto &I : *this) {
904     if (I.isStringAttribute())
905       StringAttrs.insert({ I.getKindAsString(), I });
906     else
907       AvailableAttrs.addAttribute(I.getKindAsEnum());
908   }
909 }
910 
911 AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
912                                         ArrayRef<Attribute> Attrs) {
913   SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
914   llvm::sort(SortedAttrs);
915   return getSorted(C, SortedAttrs);
916 }
917 
918 AttributeSetNode *AttributeSetNode::getSorted(LLVMContext &C,
919                                               ArrayRef<Attribute> SortedAttrs) {
920   if (SortedAttrs.empty())
921     return nullptr;
922 
923   // Build a key to look up the existing attributes.
924   LLVMContextImpl *pImpl = C.pImpl;
925   FoldingSetNodeID ID;
926 
927   assert(llvm::is_sorted(SortedAttrs) && "Expected sorted attributes!");
928   for (const auto &Attr : SortedAttrs)
929     Attr.Profile(ID);
930 
931   void *InsertPoint;
932   AttributeSetNode *PA =
933     pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
934 
935   // If we didn't find any existing attributes of the same shape then create a
936   // new one and insert it.
937   if (!PA) {
938     // Coallocate entries after the AttributeSetNode itself.
939     void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
940     PA = new (Mem) AttributeSetNode(SortedAttrs);
941     pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
942   }
943 
944   // Return the AttributeSetNode that we found or created.
945   return PA;
946 }
947 
948 AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
949   return getSorted(C, B.attrs());
950 }
951 
952 bool AttributeSetNode::hasAttribute(StringRef Kind) const {
953   return StringAttrs.count(Kind);
954 }
955 
956 std::optional<Attribute>
957 AttributeSetNode::findEnumAttribute(Attribute::AttrKind Kind) const {
958   // Do a quick presence check.
959   if (!hasAttribute(Kind))
960     return std::nullopt;
961 
962   // Attributes in a set are sorted by enum value, followed by string
963   // attributes. Binary search the one we want.
964   const Attribute *I =
965       std::lower_bound(begin(), end() - StringAttrs.size(), Kind,
966                        [](Attribute A, Attribute::AttrKind Kind) {
967                          return A.getKindAsEnum() < Kind;
968                        });
969   assert(I != end() && I->hasAttribute(Kind) && "Presence check failed?");
970   return *I;
971 }
972 
973 Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
974   if (auto A = findEnumAttribute(Kind))
975     return *A;
976   return {};
977 }
978 
979 Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
980   return StringAttrs.lookup(Kind);
981 }
982 
983 MaybeAlign AttributeSetNode::getAlignment() const {
984   if (auto A = findEnumAttribute(Attribute::Alignment))
985     return A->getAlignment();
986   return std::nullopt;
987 }
988 
989 MaybeAlign AttributeSetNode::getStackAlignment() const {
990   if (auto A = findEnumAttribute(Attribute::StackAlignment))
991     return A->getStackAlignment();
992   return std::nullopt;
993 }
994 
995 Type *AttributeSetNode::getAttributeType(Attribute::AttrKind Kind) const {
996   if (auto A = findEnumAttribute(Kind))
997     return A->getValueAsType();
998   return nullptr;
999 }
1000 
1001 uint64_t AttributeSetNode::getDereferenceableBytes() const {
1002   if (auto A = findEnumAttribute(Attribute::Dereferenceable))
1003     return A->getDereferenceableBytes();
1004   return 0;
1005 }
1006 
1007 uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
1008   if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
1009     return A->getDereferenceableOrNullBytes();
1010   return 0;
1011 }
1012 
1013 std::optional<std::pair<unsigned, std::optional<unsigned>>>
1014 AttributeSetNode::getAllocSizeArgs() const {
1015   if (auto A = findEnumAttribute(Attribute::AllocSize))
1016     return A->getAllocSizeArgs();
1017   return std::nullopt;
1018 }
1019 
1020 unsigned AttributeSetNode::getVScaleRangeMin() const {
1021   if (auto A = findEnumAttribute(Attribute::VScaleRange))
1022     return A->getVScaleRangeMin();
1023   return 1;
1024 }
1025 
1026 std::optional<unsigned> AttributeSetNode::getVScaleRangeMax() const {
1027   if (auto A = findEnumAttribute(Attribute::VScaleRange))
1028     return A->getVScaleRangeMax();
1029   return std::nullopt;
1030 }
1031 
1032 UWTableKind AttributeSetNode::getUWTableKind() const {
1033   if (auto A = findEnumAttribute(Attribute::UWTable))
1034     return A->getUWTableKind();
1035   return UWTableKind::None;
1036 }
1037 
1038 AllocFnKind AttributeSetNode::getAllocKind() const {
1039   if (auto A = findEnumAttribute(Attribute::AllocKind))
1040     return A->getAllocKind();
1041   return AllocFnKind::Unknown;
1042 }
1043 
1044 MemoryEffects AttributeSetNode::getMemoryEffects() const {
1045   if (auto A = findEnumAttribute(Attribute::Memory))
1046     return A->getMemoryEffects();
1047   return MemoryEffects::unknown();
1048 }
1049 
1050 FPClassTest AttributeSetNode::getNoFPClass() const {
1051   if (auto A = findEnumAttribute(Attribute::NoFPClass))
1052     return A->getNoFPClass();
1053   return fcNone;
1054 }
1055 
1056 std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
1057   std::string Str;
1058   for (iterator I = begin(), E = end(); I != E; ++I) {
1059     if (I != begin())
1060       Str += ' ';
1061     Str += I->getAsString(InAttrGrp);
1062   }
1063   return Str;
1064 }
1065 
1066 //===----------------------------------------------------------------------===//
1067 // AttributeListImpl Definition
1068 //===----------------------------------------------------------------------===//
1069 
1070 /// Map from AttributeList index to the internal array index. Adding one happens
1071 /// to work, because -1 wraps around to 0.
1072 static unsigned attrIdxToArrayIdx(unsigned Index) {
1073   return Index + 1;
1074 }
1075 
1076 AttributeListImpl::AttributeListImpl(ArrayRef<AttributeSet> Sets)
1077     : NumAttrSets(Sets.size()) {
1078   assert(!Sets.empty() && "pointless AttributeListImpl");
1079 
1080   // There's memory after the node where we can store the entries in.
1081   llvm::copy(Sets, getTrailingObjects<AttributeSet>());
1082 
1083   // Initialize AvailableFunctionAttrs and AvailableSomewhereAttrs
1084   // summary bitsets.
1085   for (const auto &I : Sets[attrIdxToArrayIdx(AttributeList::FunctionIndex)])
1086     if (!I.isStringAttribute())
1087       AvailableFunctionAttrs.addAttribute(I.getKindAsEnum());
1088 
1089   for (const auto &Set : Sets)
1090     for (const auto &I : Set)
1091       if (!I.isStringAttribute())
1092         AvailableSomewhereAttrs.addAttribute(I.getKindAsEnum());
1093 }
1094 
1095 void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
1096   Profile(ID, ArrayRef(begin(), end()));
1097 }
1098 
1099 void AttributeListImpl::Profile(FoldingSetNodeID &ID,
1100                                 ArrayRef<AttributeSet> Sets) {
1101   for (const auto &Set : Sets)
1102     ID.AddPointer(Set.SetNode);
1103 }
1104 
1105 bool AttributeListImpl::hasAttrSomewhere(Attribute::AttrKind Kind,
1106                                         unsigned *Index) const {
1107   if (!AvailableSomewhereAttrs.hasAttribute(Kind))
1108     return false;
1109 
1110   if (Index) {
1111     for (unsigned I = 0, E = NumAttrSets; I != E; ++I) {
1112       if (begin()[I].hasAttribute(Kind)) {
1113         *Index = I - 1;
1114         break;
1115       }
1116     }
1117   }
1118 
1119   return true;
1120 }
1121 
1122 
1123 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1124 LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
1125   AttributeList(const_cast<AttributeListImpl *>(this)).dump();
1126 }
1127 #endif
1128 
1129 //===----------------------------------------------------------------------===//
1130 // AttributeList Construction and Mutation Methods
1131 //===----------------------------------------------------------------------===//
1132 
1133 AttributeList AttributeList::getImpl(LLVMContext &C,
1134                                      ArrayRef<AttributeSet> AttrSets) {
1135   assert(!AttrSets.empty() && "pointless AttributeListImpl");
1136 
1137   LLVMContextImpl *pImpl = C.pImpl;
1138   FoldingSetNodeID ID;
1139   AttributeListImpl::Profile(ID, AttrSets);
1140 
1141   void *InsertPoint;
1142   AttributeListImpl *PA =
1143       pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
1144 
1145   // If we didn't find any existing attributes of the same shape then
1146   // create a new one and insert it.
1147   if (!PA) {
1148     // Coallocate entries after the AttributeListImpl itself.
1149     void *Mem = pImpl->Alloc.Allocate(
1150         AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()),
1151         alignof(AttributeListImpl));
1152     PA = new (Mem) AttributeListImpl(AttrSets);
1153     pImpl->AttrsLists.InsertNode(PA, InsertPoint);
1154   }
1155 
1156   // Return the AttributesList that we found or created.
1157   return AttributeList(PA);
1158 }
1159 
1160 AttributeList
1161 AttributeList::get(LLVMContext &C,
1162                    ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
1163   // If there are no attributes then return a null AttributesList pointer.
1164   if (Attrs.empty())
1165     return {};
1166 
1167   assert(llvm::is_sorted(Attrs, llvm::less_first()) &&
1168          "Misordered Attributes list!");
1169   assert(llvm::all_of(Attrs,
1170                       [](const std::pair<unsigned, Attribute> &Pair) {
1171                         return Pair.second.isValid();
1172                       }) &&
1173          "Pointless attribute!");
1174 
1175   // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
1176   // list.
1177   SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec;
1178   for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
1179          E = Attrs.end(); I != E; ) {
1180     unsigned Index = I->first;
1181     SmallVector<Attribute, 4> AttrVec;
1182     while (I != E && I->first == Index) {
1183       AttrVec.push_back(I->second);
1184       ++I;
1185     }
1186 
1187     AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
1188   }
1189 
1190   return get(C, AttrPairVec);
1191 }
1192 
1193 AttributeList
1194 AttributeList::get(LLVMContext &C,
1195                    ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
1196   // If there are no attributes then return a null AttributesList pointer.
1197   if (Attrs.empty())
1198     return {};
1199 
1200   assert(llvm::is_sorted(Attrs, llvm::less_first()) &&
1201          "Misordered Attributes list!");
1202   assert(llvm::none_of(Attrs,
1203                        [](const std::pair<unsigned, AttributeSet> &Pair) {
1204                          return !Pair.second.hasAttributes();
1205                        }) &&
1206          "Pointless attribute!");
1207 
1208   unsigned MaxIndex = Attrs.back().first;
1209   // If the MaxIndex is FunctionIndex and there are other indices in front
1210   // of it, we need to use the largest of those to get the right size.
1211   if (MaxIndex == FunctionIndex && Attrs.size() > 1)
1212     MaxIndex = Attrs[Attrs.size() - 2].first;
1213 
1214   SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
1215   for (const auto &Pair : Attrs)
1216     AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;
1217 
1218   return getImpl(C, AttrVec);
1219 }
1220 
1221 AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs,
1222                                  AttributeSet RetAttrs,
1223                                  ArrayRef<AttributeSet> ArgAttrs) {
1224   // Scan from the end to find the last argument with attributes.  Most
1225   // arguments don't have attributes, so it's nice if we can have fewer unique
1226   // AttributeListImpls by dropping empty attribute sets at the end of the list.
1227   unsigned NumSets = 0;
1228   for (size_t I = ArgAttrs.size(); I != 0; --I) {
1229     if (ArgAttrs[I - 1].hasAttributes()) {
1230       NumSets = I + 2;
1231       break;
1232     }
1233   }
1234   if (NumSets == 0) {
1235     // Check function and return attributes if we didn't have argument
1236     // attributes.
1237     if (RetAttrs.hasAttributes())
1238       NumSets = 2;
1239     else if (FnAttrs.hasAttributes())
1240       NumSets = 1;
1241   }
1242 
1243   // If all attribute sets were empty, we can use the empty attribute list.
1244   if (NumSets == 0)
1245     return {};
1246 
1247   SmallVector<AttributeSet, 8> AttrSets;
1248   AttrSets.reserve(NumSets);
1249   // If we have any attributes, we always have function attributes.
1250   AttrSets.push_back(FnAttrs);
1251   if (NumSets > 1)
1252     AttrSets.push_back(RetAttrs);
1253   if (NumSets > 2) {
1254     // Drop the empty argument attribute sets at the end.
1255     ArgAttrs = ArgAttrs.take_front(NumSets - 2);
1256     llvm::append_range(AttrSets, ArgAttrs);
1257   }
1258 
1259   return getImpl(C, AttrSets);
1260 }
1261 
1262 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1263                                  AttributeSet Attrs) {
1264   if (!Attrs.hasAttributes())
1265     return {};
1266   Index = attrIdxToArrayIdx(Index);
1267   SmallVector<AttributeSet, 8> AttrSets(Index + 1);
1268   AttrSets[Index] = Attrs;
1269   return getImpl(C, AttrSets);
1270 }
1271 
1272 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1273                                  const AttrBuilder &B) {
1274   return get(C, Index, AttributeSet::get(C, B));
1275 }
1276 
1277 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1278                                  ArrayRef<Attribute::AttrKind> Kinds) {
1279   SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1280   for (const auto K : Kinds)
1281     Attrs.emplace_back(Index, Attribute::get(C, K));
1282   return get(C, Attrs);
1283 }
1284 
1285 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1286                                  ArrayRef<Attribute::AttrKind> Kinds,
1287                                  ArrayRef<uint64_t> Values) {
1288   assert(Kinds.size() == Values.size() && "Mismatched attribute values.");
1289   SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1290   auto VI = Values.begin();
1291   for (const auto K : Kinds)
1292     Attrs.emplace_back(Index, Attribute::get(C, K, *VI++));
1293   return get(C, Attrs);
1294 }
1295 
1296 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1297                                  ArrayRef<StringRef> Kinds) {
1298   SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1299   for (const auto &K : Kinds)
1300     Attrs.emplace_back(Index, Attribute::get(C, K));
1301   return get(C, Attrs);
1302 }
1303 
1304 AttributeList AttributeList::get(LLVMContext &C,
1305                                  ArrayRef<AttributeList> Attrs) {
1306   if (Attrs.empty())
1307     return {};
1308   if (Attrs.size() == 1)
1309     return Attrs[0];
1310 
1311   unsigned MaxSize = 0;
1312   for (const auto &List : Attrs)
1313     MaxSize = std::max(MaxSize, List.getNumAttrSets());
1314 
1315   // If every list was empty, there is no point in merging the lists.
1316   if (MaxSize == 0)
1317     return {};
1318 
1319   SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
1320   for (unsigned I = 0; I < MaxSize; ++I) {
1321     AttrBuilder CurBuilder(C);
1322     for (const auto &List : Attrs)
1323       CurBuilder.merge(AttrBuilder(C, List.getAttributes(I - 1)));
1324     NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
1325   }
1326 
1327   return getImpl(C, NewAttrSets);
1328 }
1329 
1330 AttributeList
1331 AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
1332                                    Attribute::AttrKind Kind) const {
1333   AttributeSet Attrs = getAttributes(Index);
1334   if (Attrs.hasAttribute(Kind))
1335     return *this;
1336   // TODO: Insert at correct position and avoid sort.
1337   SmallVector<Attribute, 8> NewAttrs(Attrs.begin(), Attrs.end());
1338   NewAttrs.push_back(Attribute::get(C, Kind));
1339   return setAttributesAtIndex(C, Index, AttributeSet::get(C, NewAttrs));
1340 }
1341 
1342 AttributeList AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
1343                                                  StringRef Kind,
1344                                                  StringRef Value) const {
1345   AttrBuilder B(C);
1346   B.addAttribute(Kind, Value);
1347   return addAttributesAtIndex(C, Index, B);
1348 }
1349 
1350 AttributeList AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
1351                                                  Attribute A) const {
1352   AttrBuilder B(C);
1353   B.addAttribute(A);
1354   return addAttributesAtIndex(C, Index, B);
1355 }
1356 
1357 AttributeList AttributeList::setAttributesAtIndex(LLVMContext &C,
1358                                                   unsigned Index,
1359                                                   AttributeSet Attrs) const {
1360   Index = attrIdxToArrayIdx(Index);
1361   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1362   if (Index >= AttrSets.size())
1363     AttrSets.resize(Index + 1);
1364   AttrSets[Index] = Attrs;
1365 
1366   // Remove trailing empty attribute sets.
1367   while (!AttrSets.empty() && !AttrSets.back().hasAttributes())
1368     AttrSets.pop_back();
1369   if (AttrSets.empty())
1370     return {};
1371   return AttributeList::getImpl(C, AttrSets);
1372 }
1373 
1374 AttributeList AttributeList::addAttributesAtIndex(LLVMContext &C,
1375                                                   unsigned Index,
1376                                                   const AttrBuilder &B) const {
1377   if (!B.hasAttributes())
1378     return *this;
1379 
1380   if (!pImpl)
1381     return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
1382 
1383   AttrBuilder Merged(C, getAttributes(Index));
1384   Merged.merge(B);
1385   return setAttributesAtIndex(C, Index, AttributeSet::get(C, Merged));
1386 }
1387 
1388 AttributeList AttributeList::addParamAttribute(LLVMContext &C,
1389                                                ArrayRef<unsigned> ArgNos,
1390                                                Attribute A) const {
1391   assert(llvm::is_sorted(ArgNos));
1392 
1393   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1394   unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
1395   if (MaxIndex >= AttrSets.size())
1396     AttrSets.resize(MaxIndex + 1);
1397 
1398   for (unsigned ArgNo : ArgNos) {
1399     unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
1400     AttrBuilder B(C, AttrSets[Index]);
1401     B.addAttribute(A);
1402     AttrSets[Index] = AttributeSet::get(C, B);
1403   }
1404 
1405   return getImpl(C, AttrSets);
1406 }
1407 
1408 AttributeList
1409 AttributeList::removeAttributeAtIndex(LLVMContext &C, unsigned Index,
1410                                       Attribute::AttrKind Kind) const {
1411   AttributeSet Attrs = getAttributes(Index);
1412   AttributeSet NewAttrs = Attrs.removeAttribute(C, Kind);
1413   if (Attrs == NewAttrs)
1414     return *this;
1415   return setAttributesAtIndex(C, Index, NewAttrs);
1416 }
1417 
1418 AttributeList AttributeList::removeAttributeAtIndex(LLVMContext &C,
1419                                                     unsigned Index,
1420                                                     StringRef Kind) const {
1421   AttributeSet Attrs = getAttributes(Index);
1422   AttributeSet NewAttrs = Attrs.removeAttribute(C, Kind);
1423   if (Attrs == NewAttrs)
1424     return *this;
1425   return setAttributesAtIndex(C, Index, NewAttrs);
1426 }
1427 
1428 AttributeList AttributeList::removeAttributesAtIndex(
1429     LLVMContext &C, unsigned Index, const AttributeMask &AttrsToRemove) const {
1430   AttributeSet Attrs = getAttributes(Index);
1431   AttributeSet NewAttrs = Attrs.removeAttributes(C, AttrsToRemove);
1432   // If nothing was removed, return the original list.
1433   if (Attrs == NewAttrs)
1434     return *this;
1435   return setAttributesAtIndex(C, Index, NewAttrs);
1436 }
1437 
1438 AttributeList
1439 AttributeList::removeAttributesAtIndex(LLVMContext &C,
1440                                        unsigned WithoutIndex) const {
1441   if (!pImpl)
1442     return {};
1443   if (attrIdxToArrayIdx(WithoutIndex) >= getNumAttrSets())
1444     return *this;
1445   return setAttributesAtIndex(C, WithoutIndex, AttributeSet());
1446 }
1447 
1448 AttributeList AttributeList::addDereferenceableRetAttr(LLVMContext &C,
1449                                                        uint64_t Bytes) const {
1450   AttrBuilder B(C);
1451   B.addDereferenceableAttr(Bytes);
1452   return addRetAttributes(C, B);
1453 }
1454 
1455 AttributeList AttributeList::addDereferenceableParamAttr(LLVMContext &C,
1456                                                          unsigned Index,
1457                                                          uint64_t Bytes) const {
1458   AttrBuilder B(C);
1459   B.addDereferenceableAttr(Bytes);
1460   return addParamAttributes(C, Index, B);
1461 }
1462 
1463 AttributeList
1464 AttributeList::addDereferenceableOrNullParamAttr(LLVMContext &C, unsigned Index,
1465                                                  uint64_t Bytes) const {
1466   AttrBuilder B(C);
1467   B.addDereferenceableOrNullAttr(Bytes);
1468   return addParamAttributes(C, Index, B);
1469 }
1470 
1471 AttributeList AttributeList::addAllocSizeParamAttr(
1472     LLVMContext &C, unsigned Index, unsigned ElemSizeArg,
1473     const std::optional<unsigned> &NumElemsArg) {
1474   AttrBuilder B(C);
1475   B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1476   return addParamAttributes(C, Index, B);
1477 }
1478 
1479 //===----------------------------------------------------------------------===//
1480 // AttributeList Accessor Methods
1481 //===----------------------------------------------------------------------===//
1482 
1483 AttributeSet AttributeList::getParamAttrs(unsigned ArgNo) const {
1484   return getAttributes(ArgNo + FirstArgIndex);
1485 }
1486 
1487 AttributeSet AttributeList::getRetAttrs() const {
1488   return getAttributes(ReturnIndex);
1489 }
1490 
1491 AttributeSet AttributeList::getFnAttrs() const {
1492   return getAttributes(FunctionIndex);
1493 }
1494 
1495 bool AttributeList::hasAttributeAtIndex(unsigned Index,
1496                                         Attribute::AttrKind Kind) const {
1497   return getAttributes(Index).hasAttribute(Kind);
1498 }
1499 
1500 bool AttributeList::hasAttributeAtIndex(unsigned Index, StringRef Kind) const {
1501   return getAttributes(Index).hasAttribute(Kind);
1502 }
1503 
1504 bool AttributeList::hasAttributesAtIndex(unsigned Index) const {
1505   return getAttributes(Index).hasAttributes();
1506 }
1507 
1508 bool AttributeList::hasFnAttr(Attribute::AttrKind Kind) const {
1509   return pImpl && pImpl->hasFnAttribute(Kind);
1510 }
1511 
1512 bool AttributeList::hasFnAttr(StringRef Kind) const {
1513   return hasAttributeAtIndex(AttributeList::FunctionIndex, Kind);
1514 }
1515 
1516 bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
1517                                      unsigned *Index) const {
1518   return pImpl && pImpl->hasAttrSomewhere(Attr, Index);
1519 }
1520 
1521 Attribute AttributeList::getAttributeAtIndex(unsigned Index,
1522                                              Attribute::AttrKind Kind) const {
1523   return getAttributes(Index).getAttribute(Kind);
1524 }
1525 
1526 Attribute AttributeList::getAttributeAtIndex(unsigned Index,
1527                                              StringRef Kind) const {
1528   return getAttributes(Index).getAttribute(Kind);
1529 }
1530 
1531 MaybeAlign AttributeList::getRetAlignment() const {
1532   return getAttributes(ReturnIndex).getAlignment();
1533 }
1534 
1535 MaybeAlign AttributeList::getParamAlignment(unsigned ArgNo) const {
1536   return getAttributes(ArgNo + FirstArgIndex).getAlignment();
1537 }
1538 
1539 MaybeAlign AttributeList::getParamStackAlignment(unsigned ArgNo) const {
1540   return getAttributes(ArgNo + FirstArgIndex).getStackAlignment();
1541 }
1542 
1543 Type *AttributeList::getParamByValType(unsigned Index) const {
1544   return getAttributes(Index+FirstArgIndex).getByValType();
1545 }
1546 
1547 Type *AttributeList::getParamStructRetType(unsigned Index) const {
1548   return getAttributes(Index + FirstArgIndex).getStructRetType();
1549 }
1550 
1551 Type *AttributeList::getParamByRefType(unsigned Index) const {
1552   return getAttributes(Index + FirstArgIndex).getByRefType();
1553 }
1554 
1555 Type *AttributeList::getParamPreallocatedType(unsigned Index) const {
1556   return getAttributes(Index + FirstArgIndex).getPreallocatedType();
1557 }
1558 
1559 Type *AttributeList::getParamInAllocaType(unsigned Index) const {
1560   return getAttributes(Index + FirstArgIndex).getInAllocaType();
1561 }
1562 
1563 Type *AttributeList::getParamElementType(unsigned Index) const {
1564   return getAttributes(Index + FirstArgIndex).getElementType();
1565 }
1566 
1567 MaybeAlign AttributeList::getFnStackAlignment() const {
1568   return getFnAttrs().getStackAlignment();
1569 }
1570 
1571 MaybeAlign AttributeList::getRetStackAlignment() const {
1572   return getRetAttrs().getStackAlignment();
1573 }
1574 
1575 uint64_t AttributeList::getRetDereferenceableBytes() const {
1576   return getRetAttrs().getDereferenceableBytes();
1577 }
1578 
1579 uint64_t AttributeList::getParamDereferenceableBytes(unsigned Index) const {
1580   return getParamAttrs(Index).getDereferenceableBytes();
1581 }
1582 
1583 uint64_t AttributeList::getRetDereferenceableOrNullBytes() const {
1584   return getRetAttrs().getDereferenceableOrNullBytes();
1585 }
1586 
1587 uint64_t
1588 AttributeList::getParamDereferenceableOrNullBytes(unsigned Index) const {
1589   return getParamAttrs(Index).getDereferenceableOrNullBytes();
1590 }
1591 
1592 FPClassTest AttributeList::getRetNoFPClass() const {
1593   return getRetAttrs().getNoFPClass();
1594 }
1595 
1596 FPClassTest AttributeList::getParamNoFPClass(unsigned Index) const {
1597   return getParamAttrs(Index).getNoFPClass();
1598 }
1599 
1600 UWTableKind AttributeList::getUWTableKind() const {
1601   return getFnAttrs().getUWTableKind();
1602 }
1603 
1604 AllocFnKind AttributeList::getAllocKind() const {
1605   return getFnAttrs().getAllocKind();
1606 }
1607 
1608 MemoryEffects AttributeList::getMemoryEffects() const {
1609   return getFnAttrs().getMemoryEffects();
1610 }
1611 
1612 std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
1613   return getAttributes(Index).getAsString(InAttrGrp);
1614 }
1615 
1616 AttributeSet AttributeList::getAttributes(unsigned Index) const {
1617   Index = attrIdxToArrayIdx(Index);
1618   if (!pImpl || Index >= getNumAttrSets())
1619     return {};
1620   return pImpl->begin()[Index];
1621 }
1622 
1623 bool AttributeList::hasParentContext(LLVMContext &C) const {
1624   assert(!isEmpty() && "an empty attribute list has no parent context");
1625   FoldingSetNodeID ID;
1626   pImpl->Profile(ID);
1627   void *Unused;
1628   return C.pImpl->AttrsLists.FindNodeOrInsertPos(ID, Unused) == pImpl;
1629 }
1630 
1631 AttributeList::iterator AttributeList::begin() const {
1632   return pImpl ? pImpl->begin() : nullptr;
1633 }
1634 
1635 AttributeList::iterator AttributeList::end() const {
1636   return pImpl ? pImpl->end() : nullptr;
1637 }
1638 
1639 //===----------------------------------------------------------------------===//
1640 // AttributeList Introspection Methods
1641 //===----------------------------------------------------------------------===//
1642 
1643 unsigned AttributeList::getNumAttrSets() const {
1644   return pImpl ? pImpl->NumAttrSets : 0;
1645 }
1646 
1647 void AttributeList::print(raw_ostream &O) const {
1648   O << "AttributeList[\n";
1649 
1650   for (unsigned i : indexes()) {
1651     if (!getAttributes(i).hasAttributes())
1652       continue;
1653     O << "  { ";
1654     switch (i) {
1655     case AttrIndex::ReturnIndex:
1656       O << "return";
1657       break;
1658     case AttrIndex::FunctionIndex:
1659       O << "function";
1660       break;
1661     default:
1662       O << "arg(" << i - AttrIndex::FirstArgIndex << ")";
1663     }
1664     O << " => " << getAsString(i) << " }\n";
1665   }
1666 
1667   O << "]\n";
1668 }
1669 
1670 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1671 LLVM_DUMP_METHOD void AttributeList::dump() const { print(dbgs()); }
1672 #endif
1673 
1674 //===----------------------------------------------------------------------===//
1675 // AttrBuilder Method Implementations
1676 //===----------------------------------------------------------------------===//
1677 
1678 AttrBuilder::AttrBuilder(LLVMContext &Ctx, AttributeSet AS) : Ctx(Ctx) {
1679   append_range(Attrs, AS);
1680   assert(is_sorted(Attrs) && "AttributeSet should be sorted");
1681 }
1682 
1683 void AttrBuilder::clear() { Attrs.clear(); }
1684 
1685 /// Attribute comparator that only compares attribute keys. Enum attributes are
1686 /// sorted before string attributes.
1687 struct AttributeComparator {
1688   bool operator()(Attribute A0, Attribute A1) const {
1689     bool A0IsString = A0.isStringAttribute();
1690     bool A1IsString = A1.isStringAttribute();
1691     if (A0IsString) {
1692       if (A1IsString)
1693         return A0.getKindAsString() < A1.getKindAsString();
1694       else
1695         return false;
1696     }
1697     if (A1IsString)
1698       return true;
1699     return A0.getKindAsEnum() < A1.getKindAsEnum();
1700   }
1701   bool operator()(Attribute A0, Attribute::AttrKind Kind) const {
1702     if (A0.isStringAttribute())
1703       return false;
1704     return A0.getKindAsEnum() < Kind;
1705   }
1706   bool operator()(Attribute A0, StringRef Kind) const {
1707     if (A0.isStringAttribute())
1708       return A0.getKindAsString() < Kind;
1709     return true;
1710   }
1711 };
1712 
1713 template <typename K>
1714 static void addAttributeImpl(SmallVectorImpl<Attribute> &Attrs, K Kind,
1715                              Attribute Attr) {
1716   auto It = lower_bound(Attrs, Kind, AttributeComparator());
1717   if (It != Attrs.end() && It->hasAttribute(Kind))
1718     std::swap(*It, Attr);
1719   else
1720     Attrs.insert(It, Attr);
1721 }
1722 
1723 AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
1724   if (Attr.isStringAttribute())
1725     addAttributeImpl(Attrs, Attr.getKindAsString(), Attr);
1726   else
1727     addAttributeImpl(Attrs, Attr.getKindAsEnum(), Attr);
1728   return *this;
1729 }
1730 
1731 AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Kind) {
1732   addAttributeImpl(Attrs, Kind, Attribute::get(Ctx, Kind));
1733   return *this;
1734 }
1735 
1736 AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
1737   addAttributeImpl(Attrs, A, Attribute::get(Ctx, A, V));
1738   return *this;
1739 }
1740 
1741 AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
1742   assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1743   auto It = lower_bound(Attrs, Val, AttributeComparator());
1744   if (It != Attrs.end() && It->hasAttribute(Val))
1745     Attrs.erase(It);
1746   return *this;
1747 }
1748 
1749 AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
1750   auto It = lower_bound(Attrs, A, AttributeComparator());
1751   if (It != Attrs.end() && It->hasAttribute(A))
1752     Attrs.erase(It);
1753   return *this;
1754 }
1755 
1756 std::optional<uint64_t>
1757 AttrBuilder::getRawIntAttr(Attribute::AttrKind Kind) const {
1758   assert(Attribute::isIntAttrKind(Kind) && "Not an int attribute");
1759   Attribute A = getAttribute(Kind);
1760   if (A.isValid())
1761     return A.getValueAsInt();
1762   return std::nullopt;
1763 }
1764 
1765 AttrBuilder &AttrBuilder::addRawIntAttr(Attribute::AttrKind Kind,
1766                                         uint64_t Value) {
1767   return addAttribute(Attribute::get(Ctx, Kind, Value));
1768 }
1769 
1770 std::optional<std::pair<unsigned, std::optional<unsigned>>>
1771 AttrBuilder::getAllocSizeArgs() const {
1772   Attribute A = getAttribute(Attribute::AllocSize);
1773   if (A.isValid())
1774     return A.getAllocSizeArgs();
1775   return std::nullopt;
1776 }
1777 
1778 AttrBuilder &AttrBuilder::addAlignmentAttr(MaybeAlign Align) {
1779   if (!Align)
1780     return *this;
1781 
1782   assert(*Align <= llvm::Value::MaximumAlignment && "Alignment too large.");
1783   return addRawIntAttr(Attribute::Alignment, Align->value());
1784 }
1785 
1786 AttrBuilder &AttrBuilder::addStackAlignmentAttr(MaybeAlign Align) {
1787   // Default alignment, allow the target to define how to align it.
1788   if (!Align)
1789     return *this;
1790 
1791   assert(*Align <= 0x100 && "Alignment too large.");
1792   return addRawIntAttr(Attribute::StackAlignment, Align->value());
1793 }
1794 
1795 AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
1796   if (Bytes == 0) return *this;
1797 
1798   return addRawIntAttr(Attribute::Dereferenceable, Bytes);
1799 }
1800 
1801 AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
1802   if (Bytes == 0)
1803     return *this;
1804 
1805   return addRawIntAttr(Attribute::DereferenceableOrNull, Bytes);
1806 }
1807 
1808 AttrBuilder &
1809 AttrBuilder::addAllocSizeAttr(unsigned ElemSize,
1810                               const std::optional<unsigned> &NumElems) {
1811   return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1812 }
1813 
1814 AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
1815   // (0, 0) is our "not present" value, so we need to check for it here.
1816   assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1817   return addRawIntAttr(Attribute::AllocSize, RawArgs);
1818 }
1819 
1820 AttrBuilder &AttrBuilder::addVScaleRangeAttr(unsigned MinValue,
1821                                              std::optional<unsigned> MaxValue) {
1822   return addVScaleRangeAttrFromRawRepr(packVScaleRangeArgs(MinValue, MaxValue));
1823 }
1824 
1825 AttrBuilder &AttrBuilder::addVScaleRangeAttrFromRawRepr(uint64_t RawArgs) {
1826   // (0, 0) is not present hence ignore this case
1827   if (RawArgs == 0)
1828     return *this;
1829 
1830   return addRawIntAttr(Attribute::VScaleRange, RawArgs);
1831 }
1832 
1833 AttrBuilder &AttrBuilder::addUWTableAttr(UWTableKind Kind) {
1834   if (Kind == UWTableKind::None)
1835     return *this;
1836   return addRawIntAttr(Attribute::UWTable, uint64_t(Kind));
1837 }
1838 
1839 AttrBuilder &AttrBuilder::addMemoryAttr(MemoryEffects ME) {
1840   return addRawIntAttr(Attribute::Memory, ME.toIntValue());
1841 }
1842 
1843 AttrBuilder &AttrBuilder::addNoFPClassAttr(FPClassTest Mask) {
1844   if (Mask == fcNone)
1845     return *this;
1846 
1847   return addRawIntAttr(Attribute::NoFPClass, Mask);
1848 }
1849 
1850 AttrBuilder &AttrBuilder::addAllocKindAttr(AllocFnKind Kind) {
1851   return addRawIntAttr(Attribute::AllocKind, static_cast<uint64_t>(Kind));
1852 }
1853 
1854 Type *AttrBuilder::getTypeAttr(Attribute::AttrKind Kind) const {
1855   assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute");
1856   Attribute A = getAttribute(Kind);
1857   return A.isValid() ? A.getValueAsType() : nullptr;
1858 }
1859 
1860 AttrBuilder &AttrBuilder::addTypeAttr(Attribute::AttrKind Kind, Type *Ty) {
1861   return addAttribute(Attribute::get(Ctx, Kind, Ty));
1862 }
1863 
1864 AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) {
1865   return addTypeAttr(Attribute::ByVal, Ty);
1866 }
1867 
1868 AttrBuilder &AttrBuilder::addStructRetAttr(Type *Ty) {
1869   return addTypeAttr(Attribute::StructRet, Ty);
1870 }
1871 
1872 AttrBuilder &AttrBuilder::addByRefAttr(Type *Ty) {
1873   return addTypeAttr(Attribute::ByRef, Ty);
1874 }
1875 
1876 AttrBuilder &AttrBuilder::addPreallocatedAttr(Type *Ty) {
1877   return addTypeAttr(Attribute::Preallocated, Ty);
1878 }
1879 
1880 AttrBuilder &AttrBuilder::addInAllocaAttr(Type *Ty) {
1881   return addTypeAttr(Attribute::InAlloca, Ty);
1882 }
1883 
1884 AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
1885   // TODO: Could make this O(n) as we're merging two sorted lists.
1886   for (const auto &I : B.attrs())
1887     addAttribute(I);
1888 
1889   return *this;
1890 }
1891 
1892 AttrBuilder &AttrBuilder::remove(const AttributeMask &AM) {
1893   erase_if(Attrs, [&](Attribute A) { return AM.contains(A); });
1894   return *this;
1895 }
1896 
1897 bool AttrBuilder::overlaps(const AttributeMask &AM) const {
1898   return any_of(Attrs, [&](Attribute A) { return AM.contains(A); });
1899 }
1900 
1901 Attribute AttrBuilder::getAttribute(Attribute::AttrKind A) const {
1902   assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!");
1903   auto It = lower_bound(Attrs, A, AttributeComparator());
1904   if (It != Attrs.end() && It->hasAttribute(A))
1905     return *It;
1906   return {};
1907 }
1908 
1909 Attribute AttrBuilder::getAttribute(StringRef A) const {
1910   auto It = lower_bound(Attrs, A, AttributeComparator());
1911   if (It != Attrs.end() && It->hasAttribute(A))
1912     return *It;
1913   return {};
1914 }
1915 
1916 bool AttrBuilder::contains(Attribute::AttrKind A) const {
1917   return getAttribute(A).isValid();
1918 }
1919 
1920 bool AttrBuilder::contains(StringRef A) const {
1921   return getAttribute(A).isValid();
1922 }
1923 
1924 bool AttrBuilder::operator==(const AttrBuilder &B) const {
1925   return Attrs == B.Attrs;
1926 }
1927 
1928 //===----------------------------------------------------------------------===//
1929 // AttributeFuncs Function Defintions
1930 //===----------------------------------------------------------------------===//
1931 
1932 /// Returns true if this is a type legal for the 'nofpclass' attribute. This
1933 /// follows the same type rules as FPMathOperator.
1934 ///
1935 /// TODO: Consider relaxing to any FP type struct fields.
1936 bool AttributeFuncs::isNoFPClassCompatibleType(Type *Ty) {
1937   while (ArrayType *ArrTy = dyn_cast<ArrayType>(Ty))
1938     Ty = ArrTy->getElementType();
1939   return Ty->isFPOrFPVectorTy();
1940 }
1941 
1942 /// Which attributes cannot be applied to a type.
1943 AttributeMask AttributeFuncs::typeIncompatible(Type *Ty,
1944                                                AttributeSafetyKind ASK) {
1945   AttributeMask Incompatible;
1946 
1947   if (!Ty->isIntegerTy()) {
1948     // Attributes that only apply to integers.
1949     if (ASK & ASK_SAFE_TO_DROP)
1950       Incompatible.addAttribute(Attribute::AllocAlign);
1951     if (ASK & ASK_UNSAFE_TO_DROP)
1952       Incompatible.addAttribute(Attribute::SExt).addAttribute(Attribute::ZExt);
1953   }
1954 
1955   if (!Ty->isPointerTy()) {
1956     // Attributes that only apply to pointers.
1957     if (ASK & ASK_SAFE_TO_DROP)
1958       Incompatible.addAttribute(Attribute::NoAlias)
1959           .addAttribute(Attribute::NoCapture)
1960           .addAttribute(Attribute::NonNull)
1961           .addAttribute(Attribute::ReadNone)
1962           .addAttribute(Attribute::ReadOnly)
1963           .addAttribute(Attribute::Dereferenceable)
1964           .addAttribute(Attribute::DereferenceableOrNull)
1965           .addAttribute(Attribute::Writable)
1966           .addAttribute(Attribute::DeadOnUnwind);
1967     if (ASK & ASK_UNSAFE_TO_DROP)
1968       Incompatible.addAttribute(Attribute::Nest)
1969           .addAttribute(Attribute::SwiftError)
1970           .addAttribute(Attribute::Preallocated)
1971           .addAttribute(Attribute::InAlloca)
1972           .addAttribute(Attribute::ByVal)
1973           .addAttribute(Attribute::StructRet)
1974           .addAttribute(Attribute::ByRef)
1975           .addAttribute(Attribute::ElementType)
1976           .addAttribute(Attribute::AllocatedPointer);
1977   }
1978 
1979     // Attributes that only apply to pointers or vectors of pointers.
1980   if (!Ty->isPtrOrPtrVectorTy()) {
1981     if (ASK & ASK_SAFE_TO_DROP)
1982       Incompatible.addAttribute(Attribute::Alignment);
1983   }
1984 
1985   if (ASK & ASK_SAFE_TO_DROP) {
1986     if (!isNoFPClassCompatibleType(Ty))
1987       Incompatible.addAttribute(Attribute::NoFPClass);
1988   }
1989 
1990   // Some attributes can apply to all "values" but there are no `void` values.
1991   if (Ty->isVoidTy()) {
1992     if (ASK & ASK_SAFE_TO_DROP)
1993       Incompatible.addAttribute(Attribute::NoUndef);
1994   }
1995 
1996   return Incompatible;
1997 }
1998 
1999 AttributeMask AttributeFuncs::getUBImplyingAttributes() {
2000   AttributeMask AM;
2001   AM.addAttribute(Attribute::NoUndef);
2002   AM.addAttribute(Attribute::Dereferenceable);
2003   AM.addAttribute(Attribute::DereferenceableOrNull);
2004   return AM;
2005 }
2006 
2007 /// Callees with dynamic denormal modes are compatible with any caller mode.
2008 static bool denormModeCompatible(DenormalMode CallerMode,
2009                                  DenormalMode CalleeMode) {
2010   if (CallerMode == CalleeMode || CalleeMode == DenormalMode::getDynamic())
2011     return true;
2012 
2013   // If they don't exactly match, it's OK if the mismatched component is
2014   // dynamic.
2015   if (CalleeMode.Input == CallerMode.Input &&
2016       CalleeMode.Output == DenormalMode::Dynamic)
2017     return true;
2018 
2019   if (CalleeMode.Output == CallerMode.Output &&
2020       CalleeMode.Input == DenormalMode::Dynamic)
2021     return true;
2022   return false;
2023 }
2024 
2025 static bool checkDenormMode(const Function &Caller, const Function &Callee) {
2026   DenormalMode CallerMode = Caller.getDenormalModeRaw();
2027   DenormalMode CalleeMode = Callee.getDenormalModeRaw();
2028 
2029   if (denormModeCompatible(CallerMode, CalleeMode)) {
2030     DenormalMode CallerModeF32 = Caller.getDenormalModeF32Raw();
2031     DenormalMode CalleeModeF32 = Callee.getDenormalModeF32Raw();
2032     if (CallerModeF32 == DenormalMode::getInvalid())
2033       CallerModeF32 = CallerMode;
2034     if (CalleeModeF32 == DenormalMode::getInvalid())
2035       CalleeModeF32 = CalleeMode;
2036     return denormModeCompatible(CallerModeF32, CalleeModeF32);
2037   }
2038 
2039   return false;
2040 }
2041 
2042 template<typename AttrClass>
2043 static bool isEqual(const Function &Caller, const Function &Callee) {
2044   return Caller.getFnAttribute(AttrClass::getKind()) ==
2045          Callee.getFnAttribute(AttrClass::getKind());
2046 }
2047 
2048 static bool isEqual(const Function &Caller, const Function &Callee,
2049                     const StringRef &AttrName) {
2050   return Caller.getFnAttribute(AttrName) == Callee.getFnAttribute(AttrName);
2051 }
2052 
2053 /// Compute the logical AND of the attributes of the caller and the
2054 /// callee.
2055 ///
2056 /// This function sets the caller's attribute to false if the callee's attribute
2057 /// is false.
2058 template<typename AttrClass>
2059 static void setAND(Function &Caller, const Function &Callee) {
2060   if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
2061       !AttrClass::isSet(Callee, AttrClass::getKind()))
2062     AttrClass::set(Caller, AttrClass::getKind(), false);
2063 }
2064 
2065 /// Compute the logical OR of the attributes of the caller and the
2066 /// callee.
2067 ///
2068 /// This function sets the caller's attribute to true if the callee's attribute
2069 /// is true.
2070 template<typename AttrClass>
2071 static void setOR(Function &Caller, const Function &Callee) {
2072   if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
2073       AttrClass::isSet(Callee, AttrClass::getKind()))
2074     AttrClass::set(Caller, AttrClass::getKind(), true);
2075 }
2076 
2077 /// If the inlined function had a higher stack protection level than the
2078 /// calling function, then bump up the caller's stack protection level.
2079 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
2080   // If the calling function has *no* stack protection level (e.g. it was built
2081   // with Clang's -fno-stack-protector or no_stack_protector attribute), don't
2082   // change it as that could change the program's semantics.
2083   if (!Caller.hasStackProtectorFnAttr())
2084     return;
2085 
2086   // If upgrading the SSP attribute, clear out the old SSP Attributes first.
2087   // Having multiple SSP attributes doesn't actually hurt, but it adds useless
2088   // clutter to the IR.
2089   AttributeMask OldSSPAttr;
2090   OldSSPAttr.addAttribute(Attribute::StackProtect)
2091       .addAttribute(Attribute::StackProtectStrong)
2092       .addAttribute(Attribute::StackProtectReq);
2093 
2094   if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
2095     Caller.removeFnAttrs(OldSSPAttr);
2096     Caller.addFnAttr(Attribute::StackProtectReq);
2097   } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
2098              !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
2099     Caller.removeFnAttrs(OldSSPAttr);
2100     Caller.addFnAttr(Attribute::StackProtectStrong);
2101   } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
2102              !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
2103              !Caller.hasFnAttribute(Attribute::StackProtectStrong))
2104     Caller.addFnAttr(Attribute::StackProtect);
2105 }
2106 
2107 /// If the inlined function required stack probes, then ensure that
2108 /// the calling function has those too.
2109 static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
2110   if (!Caller.hasFnAttribute("probe-stack") &&
2111       Callee.hasFnAttribute("probe-stack")) {
2112     Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
2113   }
2114 }
2115 
2116 /// If the inlined function defines the size of guard region
2117 /// on the stack, then ensure that the calling function defines a guard region
2118 /// that is no larger.
2119 static void
2120 adjustCallerStackProbeSize(Function &Caller, const Function &Callee) {
2121   Attribute CalleeAttr = Callee.getFnAttribute("stack-probe-size");
2122   if (CalleeAttr.isValid()) {
2123     Attribute CallerAttr = Caller.getFnAttribute("stack-probe-size");
2124     if (CallerAttr.isValid()) {
2125       uint64_t CallerStackProbeSize, CalleeStackProbeSize;
2126       CallerAttr.getValueAsString().getAsInteger(0, CallerStackProbeSize);
2127       CalleeAttr.getValueAsString().getAsInteger(0, CalleeStackProbeSize);
2128 
2129       if (CallerStackProbeSize > CalleeStackProbeSize) {
2130         Caller.addFnAttr(CalleeAttr);
2131       }
2132     } else {
2133       Caller.addFnAttr(CalleeAttr);
2134     }
2135   }
2136 }
2137 
2138 /// If the inlined function defines a min legal vector width, then ensure
2139 /// the calling function has the same or larger min legal vector width. If the
2140 /// caller has the attribute, but the callee doesn't, we need to remove the
2141 /// attribute from the caller since we can't make any guarantees about the
2142 /// caller's requirements.
2143 /// This function is called after the inlining decision has been made so we have
2144 /// to merge the attribute this way. Heuristics that would use
2145 /// min-legal-vector-width to determine inline compatibility would need to be
2146 /// handled as part of inline cost analysis.
2147 static void
2148 adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) {
2149   Attribute CallerAttr = Caller.getFnAttribute("min-legal-vector-width");
2150   if (CallerAttr.isValid()) {
2151     Attribute CalleeAttr = Callee.getFnAttribute("min-legal-vector-width");
2152     if (CalleeAttr.isValid()) {
2153       uint64_t CallerVectorWidth, CalleeVectorWidth;
2154       CallerAttr.getValueAsString().getAsInteger(0, CallerVectorWidth);
2155       CalleeAttr.getValueAsString().getAsInteger(0, CalleeVectorWidth);
2156       if (CallerVectorWidth < CalleeVectorWidth)
2157         Caller.addFnAttr(CalleeAttr);
2158     } else {
2159       // If the callee doesn't have the attribute then we don't know anything
2160       // and must drop the attribute from the caller.
2161       Caller.removeFnAttr("min-legal-vector-width");
2162     }
2163   }
2164 }
2165 
2166 /// If the inlined function has null_pointer_is_valid attribute,
2167 /// set this attribute in the caller post inlining.
2168 static void
2169 adjustNullPointerValidAttr(Function &Caller, const Function &Callee) {
2170   if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
2171     Caller.addFnAttr(Attribute::NullPointerIsValid);
2172   }
2173 }
2174 
2175 struct EnumAttr {
2176   static bool isSet(const Function &Fn,
2177                     Attribute::AttrKind Kind) {
2178     return Fn.hasFnAttribute(Kind);
2179   }
2180 
2181   static void set(Function &Fn,
2182                   Attribute::AttrKind Kind, bool Val) {
2183     if (Val)
2184       Fn.addFnAttr(Kind);
2185     else
2186       Fn.removeFnAttr(Kind);
2187   }
2188 };
2189 
2190 struct StrBoolAttr {
2191   static bool isSet(const Function &Fn,
2192                     StringRef Kind) {
2193     auto A = Fn.getFnAttribute(Kind);
2194     return A.getValueAsString().equals("true");
2195   }
2196 
2197   static void set(Function &Fn,
2198                   StringRef Kind, bool Val) {
2199     Fn.addFnAttr(Kind, Val ? "true" : "false");
2200   }
2201 };
2202 
2203 #define GET_ATTR_NAMES
2204 #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME)                                \
2205   struct ENUM_NAME##Attr : EnumAttr {                                          \
2206     static enum Attribute::AttrKind getKind() {                                \
2207       return llvm::Attribute::ENUM_NAME;                                       \
2208     }                                                                          \
2209   };
2210 #define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME)                             \
2211   struct ENUM_NAME##Attr : StrBoolAttr {                                       \
2212     static StringRef getKind() { return #DISPLAY_NAME; }                       \
2213   };
2214 #include "llvm/IR/Attributes.inc"
2215 
2216 #define GET_ATTR_COMPAT_FUNC
2217 #include "llvm/IR/Attributes.inc"
2218 
2219 bool AttributeFuncs::areInlineCompatible(const Function &Caller,
2220                                          const Function &Callee) {
2221   return hasCompatibleFnAttrs(Caller, Callee);
2222 }
2223 
2224 bool AttributeFuncs::areOutlineCompatible(const Function &A,
2225                                           const Function &B) {
2226   return hasCompatibleFnAttrs(A, B);
2227 }
2228 
2229 void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
2230                                                 const Function &Callee) {
2231   mergeFnAttrs(Caller, Callee);
2232 }
2233 
2234 void AttributeFuncs::mergeAttributesForOutlining(Function &Base,
2235                                                 const Function &ToMerge) {
2236 
2237   // We merge functions so that they meet the most general case.
2238   // For example, if the NoNansFPMathAttr is set in one function, but not in
2239   // the other, in the merged function we can say that the NoNansFPMathAttr
2240   // is not set.
2241   // However if we have the SpeculativeLoadHardeningAttr set true in one
2242   // function, but not the other, we make sure that the function retains
2243   // that aspect in the merged function.
2244   mergeFnAttrs(Base, ToMerge);
2245 }
2246 
2247 void AttributeFuncs::updateMinLegalVectorWidthAttr(Function &Fn,
2248                                                    uint64_t Width) {
2249   Attribute Attr = Fn.getFnAttribute("min-legal-vector-width");
2250   if (Attr.isValid()) {
2251     uint64_t OldWidth;
2252     Attr.getValueAsString().getAsInteger(0, OldWidth);
2253     if (Width > OldWidth)
2254       Fn.addFnAttr("min-legal-vector-width", llvm::utostr(Width));
2255   }
2256 }
2257