xref: /freebsd/contrib/llvm-project/llvm/include/llvm/IR/Attributes.h (revision 5ca8e32633c4ffbbcd6762e5888b6a4ba0708c6c)
1 //===- llvm/Attributes.h - Container for Attributes -------------*- C++ -*-===//
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 contains the simple types necessary to represent the
11 /// attributes associated with functions and their calls.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_IR_ATTRIBUTES_H
16 #define LLVM_IR_ATTRIBUTES_H
17 
18 #include "llvm-c/Types.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/BitmaskEnum.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/Config/llvm-config.h"
23 #include "llvm/Support/Alignment.h"
24 #include "llvm/Support/CodeGen.h"
25 #include "llvm/Support/ModRef.h"
26 #include "llvm/Support/PointerLikeTypeTraits.h"
27 #include <cassert>
28 #include <cstdint>
29 #include <optional>
30 #include <string>
31 #include <utility>
32 
33 namespace llvm {
34 
35 class AttrBuilder;
36 class AttributeMask;
37 class AttributeImpl;
38 class AttributeListImpl;
39 class AttributeSetNode;
40 class FoldingSetNodeID;
41 class Function;
42 class LLVMContext;
43 class Type;
44 class raw_ostream;
45 enum FPClassTest : unsigned;
46 
47 enum class AllocFnKind : uint64_t {
48   Unknown = 0,
49   Alloc = 1 << 0,         // Allocator function returns a new allocation
50   Realloc = 1 << 1,       // Allocator function resizes the `allocptr` argument
51   Free = 1 << 2,          // Allocator function frees the `allocptr` argument
52   Uninitialized = 1 << 3, // Allocator function returns uninitialized memory
53   Zeroed = 1 << 4,        // Allocator function returns zeroed memory
54   Aligned = 1 << 5,       // Allocator function aligns allocations per the
55                           // `allocalign` argument
56   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ Aligned)
57 };
58 
59 //===----------------------------------------------------------------------===//
60 /// \class
61 /// Functions, function parameters, and return types can have attributes
62 /// to indicate how they should be treated by optimizations and code
63 /// generation. This class represents one of those attributes. It's light-weight
64 /// and should be passed around by-value.
65 class Attribute {
66 public:
67   /// This enumeration lists the attributes that can be associated with
68   /// parameters, function results, or the function itself.
69   ///
70   /// Note: The `uwtable' attribute is about the ABI or the user mandating an
71   /// entry in the unwind table. The `nounwind' attribute is about an exception
72   /// passing by the function.
73   ///
74   /// In a theoretical system that uses tables for profiling and SjLj for
75   /// exceptions, they would be fully independent. In a normal system that uses
76   /// tables for both, the semantics are:
77   ///
78   /// nil                = Needs an entry because an exception might pass by.
79   /// nounwind           = No need for an entry
80   /// uwtable            = Needs an entry because the ABI says so and because
81   ///                      an exception might pass by.
82   /// uwtable + nounwind = Needs an entry because the ABI says so.
83 
84   enum AttrKind {
85     // IR-Level Attributes
86     None,                  ///< No attributes have been set
87     #define GET_ATTR_ENUM
88     #include "llvm/IR/Attributes.inc"
89     EndAttrKinds,          ///< Sentinal value useful for loops
90     EmptyKey,              ///< Use as Empty key for DenseMap of AttrKind
91     TombstoneKey,          ///< Use as Tombstone key for DenseMap of AttrKind
92   };
93 
94   static const unsigned NumIntAttrKinds = LastIntAttr - FirstIntAttr + 1;
95   static const unsigned NumTypeAttrKinds = LastTypeAttr - FirstTypeAttr + 1;
96 
97   static bool isEnumAttrKind(AttrKind Kind) {
98     return Kind >= FirstEnumAttr && Kind <= LastEnumAttr;
99   }
100   static bool isIntAttrKind(AttrKind Kind) {
101     return Kind >= FirstIntAttr && Kind <= LastIntAttr;
102   }
103   static bool isTypeAttrKind(AttrKind Kind) {
104     return Kind >= FirstTypeAttr && Kind <= LastTypeAttr;
105   }
106 
107   static bool canUseAsFnAttr(AttrKind Kind);
108   static bool canUseAsParamAttr(AttrKind Kind);
109   static bool canUseAsRetAttr(AttrKind Kind);
110 
111 private:
112   AttributeImpl *pImpl = nullptr;
113 
114   Attribute(AttributeImpl *A) : pImpl(A) {}
115 
116 public:
117   Attribute() = default;
118 
119   //===--------------------------------------------------------------------===//
120   // Attribute Construction
121   //===--------------------------------------------------------------------===//
122 
123   /// Return a uniquified Attribute object.
124   static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val = 0);
125   static Attribute get(LLVMContext &Context, StringRef Kind,
126                        StringRef Val = StringRef());
127   static Attribute get(LLVMContext &Context, AttrKind Kind, Type *Ty);
128 
129   /// Return a uniquified Attribute object that has the specific
130   /// alignment set.
131   static Attribute getWithAlignment(LLVMContext &Context, Align Alignment);
132   static Attribute getWithStackAlignment(LLVMContext &Context, Align Alignment);
133   static Attribute getWithDereferenceableBytes(LLVMContext &Context,
134                                               uint64_t Bytes);
135   static Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context,
136                                                      uint64_t Bytes);
137   static Attribute getWithAllocSizeArgs(
138       LLVMContext &Context, unsigned ElemSizeArg,
139       const std::optional<unsigned> &NumElemsArg);
140   static Attribute getWithVScaleRangeArgs(LLVMContext &Context,
141                                           unsigned MinValue, unsigned MaxValue);
142   static Attribute getWithByValType(LLVMContext &Context, Type *Ty);
143   static Attribute getWithStructRetType(LLVMContext &Context, Type *Ty);
144   static Attribute getWithByRefType(LLVMContext &Context, Type *Ty);
145   static Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty);
146   static Attribute getWithInAllocaType(LLVMContext &Context, Type *Ty);
147   static Attribute getWithUWTableKind(LLVMContext &Context, UWTableKind Kind);
148   static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME);
149   static Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask);
150 
151   /// For a typed attribute, return the equivalent attribute with the type
152   /// changed to \p ReplacementTy.
153   Attribute getWithNewType(LLVMContext &Context, Type *ReplacementTy) {
154     assert(isTypeAttribute() && "this requires a typed attribute");
155     return get(Context, getKindAsEnum(), ReplacementTy);
156   }
157 
158   static Attribute::AttrKind getAttrKindFromName(StringRef AttrName);
159 
160   static StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind);
161 
162   /// Return true if the provided string matches the IR name of an attribute.
163   /// example: "noalias" return true but not "NoAlias"
164   static bool isExistingAttribute(StringRef Name);
165 
166   //===--------------------------------------------------------------------===//
167   // Attribute Accessors
168   //===--------------------------------------------------------------------===//
169 
170   /// Return true if the attribute is an Attribute::AttrKind type.
171   bool isEnumAttribute() const;
172 
173   /// Return true if the attribute is an integer attribute.
174   bool isIntAttribute() const;
175 
176   /// Return true if the attribute is a string (target-dependent)
177   /// attribute.
178   bool isStringAttribute() const;
179 
180   /// Return true if the attribute is a type attribute.
181   bool isTypeAttribute() const;
182 
183   /// Return true if the attribute is any kind of attribute.
184   bool isValid() const { return pImpl; }
185 
186   /// Return true if the attribute is present.
187   bool hasAttribute(AttrKind Val) const;
188 
189   /// Return true if the target-dependent attribute is present.
190   bool hasAttribute(StringRef Val) const;
191 
192   /// Return the attribute's kind as an enum (Attribute::AttrKind). This
193   /// requires the attribute to be an enum, integer, or type attribute.
194   Attribute::AttrKind getKindAsEnum() const;
195 
196   /// Return the attribute's value as an integer. This requires that the
197   /// attribute be an integer attribute.
198   uint64_t getValueAsInt() const;
199 
200   /// Return the attribute's value as a boolean. This requires that the
201   /// attribute be a string attribute.
202   bool getValueAsBool() const;
203 
204   /// Return the attribute's kind as a string. This requires the
205   /// attribute to be a string attribute.
206   StringRef getKindAsString() const;
207 
208   /// Return the attribute's value as a string. This requires the
209   /// attribute to be a string attribute.
210   StringRef getValueAsString() const;
211 
212   /// Return the attribute's value as a Type. This requires the attribute to be
213   /// a type attribute.
214   Type *getValueAsType() const;
215 
216   /// Returns the alignment field of an attribute as a byte alignment
217   /// value.
218   MaybeAlign getAlignment() const;
219 
220   /// Returns the stack alignment field of an attribute as a byte
221   /// alignment value.
222   MaybeAlign getStackAlignment() const;
223 
224   /// Returns the number of dereferenceable bytes from the
225   /// dereferenceable attribute.
226   uint64_t getDereferenceableBytes() const;
227 
228   /// Returns the number of dereferenceable_or_null bytes from the
229   /// dereferenceable_or_null attribute.
230   uint64_t getDereferenceableOrNullBytes() const;
231 
232   /// Returns the argument numbers for the allocsize attribute.
233   std::pair<unsigned, std::optional<unsigned>> getAllocSizeArgs() const;
234 
235   /// Returns the minimum value for the vscale_range attribute.
236   unsigned getVScaleRangeMin() const;
237 
238   /// Returns the maximum value for the vscale_range attribute or std::nullopt
239   /// when unknown.
240   std::optional<unsigned> getVScaleRangeMax() const;
241 
242   // Returns the unwind table kind.
243   UWTableKind getUWTableKind() const;
244 
245   // Returns the allocator function kind.
246   AllocFnKind getAllocKind() const;
247 
248   /// Returns memory effects.
249   MemoryEffects getMemoryEffects() const;
250 
251   /// Return the FPClassTest for nofpclass
252   FPClassTest getNoFPClass() const;
253 
254   /// The Attribute is converted to a string of equivalent mnemonic. This
255   /// is, presumably, for writing out the mnemonics for the assembly writer.
256   std::string getAsString(bool InAttrGrp = false) const;
257 
258   /// Return true if this attribute belongs to the LLVMContext.
259   bool hasParentContext(LLVMContext &C) const;
260 
261   /// Equality and non-equality operators.
262   bool operator==(Attribute A) const { return pImpl == A.pImpl; }
263   bool operator!=(Attribute A) const { return pImpl != A.pImpl; }
264 
265   /// Less-than operator. Useful for sorting the attributes list.
266   bool operator<(Attribute A) const;
267 
268   void Profile(FoldingSetNodeID &ID) const;
269 
270   /// Return a raw pointer that uniquely identifies this attribute.
271   void *getRawPointer() const {
272     return pImpl;
273   }
274 
275   /// Get an attribute from a raw pointer created by getRawPointer.
276   static Attribute fromRawPointer(void *RawPtr) {
277     return Attribute(reinterpret_cast<AttributeImpl*>(RawPtr));
278   }
279 };
280 
281 // Specialized opaque value conversions.
282 inline LLVMAttributeRef wrap(Attribute Attr) {
283   return reinterpret_cast<LLVMAttributeRef>(Attr.getRawPointer());
284 }
285 
286 // Specialized opaque value conversions.
287 inline Attribute unwrap(LLVMAttributeRef Attr) {
288   return Attribute::fromRawPointer(Attr);
289 }
290 
291 //===----------------------------------------------------------------------===//
292 /// \class
293 /// This class holds the attributes for a particular argument, parameter,
294 /// function, or return value. It is an immutable value type that is cheap to
295 /// copy. Adding and removing enum attributes is intended to be fast, but adding
296 /// and removing string or integer attributes involves a FoldingSet lookup.
297 class AttributeSet {
298   friend AttributeListImpl;
299   template <typename Ty, typename Enable> friend struct DenseMapInfo;
300 
301   // TODO: Extract AvailableAttrs from AttributeSetNode and store them here.
302   // This will allow an efficient implementation of addAttribute and
303   // removeAttribute for enum attrs.
304 
305   /// Private implementation pointer.
306   AttributeSetNode *SetNode = nullptr;
307 
308 private:
309   explicit AttributeSet(AttributeSetNode *ASN) : SetNode(ASN) {}
310 
311 public:
312   /// AttributeSet is a trivially copyable value type.
313   AttributeSet() = default;
314   AttributeSet(const AttributeSet &) = default;
315   ~AttributeSet() = default;
316 
317   static AttributeSet get(LLVMContext &C, const AttrBuilder &B);
318   static AttributeSet get(LLVMContext &C, ArrayRef<Attribute> Attrs);
319 
320   bool operator==(const AttributeSet &O) const { return SetNode == O.SetNode; }
321   bool operator!=(const AttributeSet &O) const { return !(*this == O); }
322 
323   /// Add an argument attribute. Returns a new set because attribute sets are
324   /// immutable.
325   [[nodiscard]] AttributeSet addAttribute(LLVMContext &C,
326                                           Attribute::AttrKind Kind) const;
327 
328   /// Add a target-dependent attribute. Returns a new set because attribute sets
329   /// are immutable.
330   [[nodiscard]] AttributeSet addAttribute(LLVMContext &C, StringRef Kind,
331                                           StringRef Value = StringRef()) const;
332 
333   /// Add attributes to the attribute set. Returns a new set because attribute
334   /// sets are immutable.
335   [[nodiscard]] AttributeSet addAttributes(LLVMContext &C,
336                                            AttributeSet AS) const;
337 
338   /// Remove the specified attribute from this set. Returns a new set because
339   /// attribute sets are immutable.
340   [[nodiscard]] AttributeSet removeAttribute(LLVMContext &C,
341                                              Attribute::AttrKind Kind) const;
342 
343   /// Remove the specified attribute from this set. Returns a new set because
344   /// attribute sets are immutable.
345   [[nodiscard]] AttributeSet removeAttribute(LLVMContext &C,
346                                              StringRef Kind) const;
347 
348   /// Remove the specified attributes from this set. Returns a new set because
349   /// attribute sets are immutable.
350   [[nodiscard]] AttributeSet
351   removeAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const;
352 
353   /// Return the number of attributes in this set.
354   unsigned getNumAttributes() const;
355 
356   /// Return true if attributes exists in this set.
357   bool hasAttributes() const { return SetNode != nullptr; }
358 
359   /// Return true if the attribute exists in this set.
360   bool hasAttribute(Attribute::AttrKind Kind) const;
361 
362   /// Return true if the attribute exists in this set.
363   bool hasAttribute(StringRef Kind) const;
364 
365   /// Return the attribute object.
366   Attribute getAttribute(Attribute::AttrKind Kind) const;
367 
368   /// Return the target-dependent attribute object.
369   Attribute getAttribute(StringRef Kind) const;
370 
371   MaybeAlign getAlignment() const;
372   MaybeAlign getStackAlignment() const;
373   uint64_t getDereferenceableBytes() const;
374   uint64_t getDereferenceableOrNullBytes() const;
375   Type *getByValType() const;
376   Type *getStructRetType() const;
377   Type *getByRefType() const;
378   Type *getPreallocatedType() const;
379   Type *getInAllocaType() const;
380   Type *getElementType() const;
381   std::optional<std::pair<unsigned, std::optional<unsigned>>> getAllocSizeArgs()
382       const;
383   unsigned getVScaleRangeMin() const;
384   std::optional<unsigned> getVScaleRangeMax() const;
385   UWTableKind getUWTableKind() const;
386   AllocFnKind getAllocKind() const;
387   MemoryEffects getMemoryEffects() const;
388   FPClassTest getNoFPClass() const;
389   std::string getAsString(bool InAttrGrp = false) const;
390 
391   /// Return true if this attribute set belongs to the LLVMContext.
392   bool hasParentContext(LLVMContext &C) const;
393 
394   using iterator = const Attribute *;
395 
396   iterator begin() const;
397   iterator end() const;
398 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
399   void dump() const;
400 #endif
401 };
402 
403 //===----------------------------------------------------------------------===//
404 /// \class
405 /// Provide DenseMapInfo for AttributeSet.
406 template <> struct DenseMapInfo<AttributeSet, void> {
407   static AttributeSet getEmptyKey() {
408     auto Val = static_cast<uintptr_t>(-1);
409     Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
410     return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val));
411   }
412 
413   static AttributeSet getTombstoneKey() {
414     auto Val = static_cast<uintptr_t>(-2);
415     Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
416     return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val));
417   }
418 
419   static unsigned getHashValue(AttributeSet AS) {
420     return (unsigned((uintptr_t)AS.SetNode) >> 4) ^
421            (unsigned((uintptr_t)AS.SetNode) >> 9);
422   }
423 
424   static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; }
425 };
426 
427 //===----------------------------------------------------------------------===//
428 /// \class
429 /// This class holds the attributes for a function, its return value, and
430 /// its parameters. You access the attributes for each of them via an index into
431 /// the AttributeList object. The function attributes are at index
432 /// `AttributeList::FunctionIndex', the return value is at index
433 /// `AttributeList::ReturnIndex', and the attributes for the parameters start at
434 /// index `AttributeList::FirstArgIndex'.
435 class AttributeList {
436 public:
437   enum AttrIndex : unsigned {
438     ReturnIndex = 0U,
439     FunctionIndex = ~0U,
440     FirstArgIndex = 1,
441   };
442 
443 private:
444   friend class AttrBuilder;
445   friend class AttributeListImpl;
446   friend class AttributeSet;
447   friend class AttributeSetNode;
448   template <typename Ty, typename Enable> friend struct DenseMapInfo;
449 
450   /// The attributes that we are managing. This can be null to represent
451   /// the empty attributes list.
452   AttributeListImpl *pImpl = nullptr;
453 
454 public:
455   /// Create an AttributeList with the specified parameters in it.
456   static AttributeList get(LLVMContext &C,
457                            ArrayRef<std::pair<unsigned, Attribute>> Attrs);
458   static AttributeList get(LLVMContext &C,
459                            ArrayRef<std::pair<unsigned, AttributeSet>> Attrs);
460 
461   /// Create an AttributeList from attribute sets for a function, its
462   /// return value, and all of its arguments.
463   static AttributeList get(LLVMContext &C, AttributeSet FnAttrs,
464                            AttributeSet RetAttrs,
465                            ArrayRef<AttributeSet> ArgAttrs);
466 
467 private:
468   explicit AttributeList(AttributeListImpl *LI) : pImpl(LI) {}
469 
470   static AttributeList getImpl(LLVMContext &C, ArrayRef<AttributeSet> AttrSets);
471 
472   AttributeList setAttributesAtIndex(LLVMContext &C, unsigned Index,
473                                      AttributeSet Attrs) const;
474 
475 public:
476   AttributeList() = default;
477 
478   //===--------------------------------------------------------------------===//
479   // AttributeList Construction and Mutation
480   //===--------------------------------------------------------------------===//
481 
482   /// Return an AttributeList with the specified parameters in it.
483   static AttributeList get(LLVMContext &C, ArrayRef<AttributeList> Attrs);
484   static AttributeList get(LLVMContext &C, unsigned Index,
485                            ArrayRef<Attribute::AttrKind> Kinds);
486   static AttributeList get(LLVMContext &C, unsigned Index,
487                            ArrayRef<Attribute::AttrKind> Kinds,
488                            ArrayRef<uint64_t> Values);
489   static AttributeList get(LLVMContext &C, unsigned Index,
490                            ArrayRef<StringRef> Kind);
491   static AttributeList get(LLVMContext &C, unsigned Index,
492                            AttributeSet Attrs);
493   static AttributeList get(LLVMContext &C, unsigned Index,
494                            const AttrBuilder &B);
495 
496   // TODO: remove non-AtIndex versions of these methods.
497   /// Add an attribute to the attribute set at the given index.
498   /// Returns a new list because attribute lists are immutable.
499   [[nodiscard]] AttributeList
500   addAttributeAtIndex(LLVMContext &C, unsigned Index,
501                       Attribute::AttrKind Kind) const;
502 
503   /// Add an attribute to the attribute set at the given index.
504   /// Returns a new list because attribute lists are immutable.
505   [[nodiscard]] AttributeList
506   addAttributeAtIndex(LLVMContext &C, unsigned Index, StringRef Kind,
507                       StringRef Value = StringRef()) const;
508 
509   /// Add an attribute to the attribute set at the given index.
510   /// Returns a new list because attribute lists are immutable.
511   [[nodiscard]] AttributeList
512   addAttributeAtIndex(LLVMContext &C, unsigned Index, Attribute A) const;
513 
514   /// Add attributes to the attribute set at the given index.
515   /// Returns a new list because attribute lists are immutable.
516   [[nodiscard]] AttributeList addAttributesAtIndex(LLVMContext &C,
517                                                    unsigned Index,
518                                                    const AttrBuilder &B) const;
519 
520   /// Add a function attribute to the list. Returns a new list because
521   /// attribute lists are immutable.
522   [[nodiscard]] AttributeList addFnAttribute(LLVMContext &C,
523                                              Attribute::AttrKind Kind) const {
524     return addAttributeAtIndex(C, FunctionIndex, Kind);
525   }
526 
527   /// Add a function attribute to the list. Returns a new list because
528   /// attribute lists are immutable.
529   [[nodiscard]] AttributeList addFnAttribute(LLVMContext &C,
530                                              Attribute Attr) const {
531     return addAttributeAtIndex(C, FunctionIndex, Attr);
532   }
533 
534   /// Add a function attribute to the list. Returns a new list because
535   /// attribute lists are immutable.
536   [[nodiscard]] AttributeList
537   addFnAttribute(LLVMContext &C, StringRef Kind,
538                  StringRef Value = StringRef()) const {
539     return addAttributeAtIndex(C, FunctionIndex, Kind, Value);
540   }
541 
542   /// Add function attribute to the list. Returns a new list because
543   /// attribute lists are immutable.
544   [[nodiscard]] AttributeList addFnAttributes(LLVMContext &C,
545                                               const AttrBuilder &B) const {
546     return addAttributesAtIndex(C, FunctionIndex, B);
547   }
548 
549   /// Add a return value attribute to the list. Returns a new list because
550   /// attribute lists are immutable.
551   [[nodiscard]] AttributeList addRetAttribute(LLVMContext &C,
552                                               Attribute::AttrKind Kind) const {
553     return addAttributeAtIndex(C, ReturnIndex, Kind);
554   }
555 
556   /// Add a return value attribute to the list. Returns a new list because
557   /// attribute lists are immutable.
558   [[nodiscard]] AttributeList addRetAttribute(LLVMContext &C,
559                                               Attribute Attr) const {
560     return addAttributeAtIndex(C, ReturnIndex, Attr);
561   }
562 
563   /// Add a return value attribute to the list. Returns a new list because
564   /// attribute lists are immutable.
565   [[nodiscard]] AttributeList addRetAttributes(LLVMContext &C,
566                                                const AttrBuilder &B) const {
567     return addAttributesAtIndex(C, ReturnIndex, B);
568   }
569 
570   /// Add an argument attribute to the list. Returns a new list because
571   /// attribute lists are immutable.
572   [[nodiscard]] AttributeList
573   addParamAttribute(LLVMContext &C, unsigned ArgNo,
574                     Attribute::AttrKind Kind) const {
575     return addAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind);
576   }
577 
578   /// Add an argument attribute to the list. Returns a new list because
579   /// attribute lists are immutable.
580   [[nodiscard]] AttributeList
581   addParamAttribute(LLVMContext &C, unsigned ArgNo, StringRef Kind,
582                     StringRef Value = StringRef()) const {
583     return addAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind, Value);
584   }
585 
586   /// Add an attribute to the attribute list at the given arg indices. Returns a
587   /// new list because attribute lists are immutable.
588   [[nodiscard]] AttributeList addParamAttribute(LLVMContext &C,
589                                                 ArrayRef<unsigned> ArgNos,
590                                                 Attribute A) const;
591 
592   /// Add an argument attribute to the list. Returns a new list because
593   /// attribute lists are immutable.
594   [[nodiscard]] AttributeList addParamAttributes(LLVMContext &C, unsigned ArgNo,
595                                                  const AttrBuilder &B) const {
596     return addAttributesAtIndex(C, ArgNo + FirstArgIndex, B);
597   }
598 
599   /// Remove the specified attribute at the specified index from this
600   /// attribute list. Returns a new list because attribute lists are immutable.
601   [[nodiscard]] AttributeList
602   removeAttributeAtIndex(LLVMContext &C, unsigned Index,
603                          Attribute::AttrKind Kind) const;
604 
605   /// Remove the specified attribute at the specified index from this
606   /// attribute list. Returns a new list because attribute lists are immutable.
607   [[nodiscard]] AttributeList
608   removeAttributeAtIndex(LLVMContext &C, unsigned Index, StringRef Kind) const;
609   [[nodiscard]] AttributeList removeAttribute(LLVMContext &C, unsigned Index,
610                                               StringRef Kind) const {
611     return removeAttributeAtIndex(C, Index, Kind);
612   }
613 
614   /// Remove the specified attributes at the specified index from this
615   /// attribute list. Returns a new list because attribute lists are immutable.
616   [[nodiscard]] AttributeList
617   removeAttributesAtIndex(LLVMContext &C, unsigned Index,
618                           const AttributeMask &AttrsToRemove) const;
619 
620   /// Remove all attributes at the specified index from this
621   /// attribute list. Returns a new list because attribute lists are immutable.
622   [[nodiscard]] AttributeList removeAttributesAtIndex(LLVMContext &C,
623                                                       unsigned Index) const;
624 
625   /// Remove the specified attribute at the function index from this
626   /// attribute list. Returns a new list because attribute lists are immutable.
627   [[nodiscard]] AttributeList
628   removeFnAttribute(LLVMContext &C, Attribute::AttrKind Kind) const {
629     return removeAttributeAtIndex(C, FunctionIndex, Kind);
630   }
631 
632   /// Remove the specified attribute at the function index from this
633   /// attribute list. Returns a new list because attribute lists are immutable.
634   [[nodiscard]] AttributeList removeFnAttribute(LLVMContext &C,
635                                                 StringRef Kind) const {
636     return removeAttributeAtIndex(C, FunctionIndex, Kind);
637   }
638 
639   /// Remove the specified attribute at the function index from this
640   /// attribute list. Returns a new list because attribute lists are immutable.
641   [[nodiscard]] AttributeList
642   removeFnAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const {
643     return removeAttributesAtIndex(C, FunctionIndex, AttrsToRemove);
644   }
645 
646   /// Remove the attributes at the function index from this
647   /// attribute list. Returns a new list because attribute lists are immutable.
648   [[nodiscard]] AttributeList removeFnAttributes(LLVMContext &C) const {
649     return removeAttributesAtIndex(C, FunctionIndex);
650   }
651 
652   /// Remove the specified attribute at the return value index from this
653   /// attribute list. Returns a new list because attribute lists are immutable.
654   [[nodiscard]] AttributeList
655   removeRetAttribute(LLVMContext &C, Attribute::AttrKind Kind) const {
656     return removeAttributeAtIndex(C, ReturnIndex, Kind);
657   }
658 
659   /// Remove the specified attribute at the return value index from this
660   /// attribute list. Returns a new list because attribute lists are immutable.
661   [[nodiscard]] AttributeList removeRetAttribute(LLVMContext &C,
662                                                  StringRef Kind) const {
663     return removeAttributeAtIndex(C, ReturnIndex, Kind);
664   }
665 
666   /// Remove the specified attribute at the return value index from this
667   /// attribute list. Returns a new list because attribute lists are immutable.
668   [[nodiscard]] AttributeList
669   removeRetAttributes(LLVMContext &C,
670                       const AttributeMask &AttrsToRemove) const {
671     return removeAttributesAtIndex(C, ReturnIndex, AttrsToRemove);
672   }
673 
674   /// Remove the specified attribute at the specified arg index from this
675   /// attribute list. Returns a new list because attribute lists are immutable.
676   [[nodiscard]] AttributeList
677   removeParamAttribute(LLVMContext &C, unsigned ArgNo,
678                        Attribute::AttrKind Kind) const {
679     return removeAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind);
680   }
681 
682   /// Remove the specified attribute at the specified arg index from this
683   /// attribute list. Returns a new list because attribute lists are immutable.
684   [[nodiscard]] AttributeList
685   removeParamAttribute(LLVMContext &C, unsigned ArgNo, StringRef Kind) const {
686     return removeAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind);
687   }
688 
689   /// Remove the specified attribute at the specified arg index from this
690   /// attribute list. Returns a new list because attribute lists are immutable.
691   [[nodiscard]] AttributeList
692   removeParamAttributes(LLVMContext &C, unsigned ArgNo,
693                         const AttributeMask &AttrsToRemove) const {
694     return removeAttributesAtIndex(C, ArgNo + FirstArgIndex, AttrsToRemove);
695   }
696 
697   /// Remove all attributes at the specified arg index from this
698   /// attribute list. Returns a new list because attribute lists are immutable.
699   [[nodiscard]] AttributeList removeParamAttributes(LLVMContext &C,
700                                                     unsigned ArgNo) const {
701     return removeAttributesAtIndex(C, ArgNo + FirstArgIndex);
702   }
703 
704   /// Replace the type contained by attribute \p AttrKind at index \p ArgNo wih
705   /// \p ReplacementTy, preserving all other attributes.
706   [[nodiscard]] AttributeList
707   replaceAttributeTypeAtIndex(LLVMContext &C, unsigned ArgNo,
708                               Attribute::AttrKind Kind,
709                               Type *ReplacementTy) const {
710     Attribute Attr = getAttributeAtIndex(ArgNo, Kind);
711     auto Attrs = removeAttributeAtIndex(C, ArgNo, Kind);
712     return Attrs.addAttributeAtIndex(C, ArgNo,
713                                      Attr.getWithNewType(C, ReplacementTy));
714   }
715 
716   /// \brief Add the dereferenceable attribute to the attribute set at the given
717   /// index. Returns a new list because attribute lists are immutable.
718   [[nodiscard]] AttributeList addDereferenceableRetAttr(LLVMContext &C,
719                                                         uint64_t Bytes) const;
720 
721   /// \brief Add the dereferenceable attribute to the attribute set at the given
722   /// arg index. Returns a new list because attribute lists are immutable.
723   [[nodiscard]] AttributeList addDereferenceableParamAttr(LLVMContext &C,
724                                                           unsigned ArgNo,
725                                                           uint64_t Bytes) const;
726 
727   /// Add the dereferenceable_or_null attribute to the attribute set at
728   /// the given arg index. Returns a new list because attribute lists are
729   /// immutable.
730   [[nodiscard]] AttributeList
731   addDereferenceableOrNullParamAttr(LLVMContext &C, unsigned ArgNo,
732                                     uint64_t Bytes) const;
733 
734   /// Add the allocsize attribute to the attribute set at the given arg index.
735   /// Returns a new list because attribute lists are immutable.
736   [[nodiscard]] AttributeList
737   addAllocSizeParamAttr(LLVMContext &C, unsigned ArgNo, unsigned ElemSizeArg,
738                         const std::optional<unsigned> &NumElemsArg);
739 
740   //===--------------------------------------------------------------------===//
741   // AttributeList Accessors
742   //===--------------------------------------------------------------------===//
743 
744   /// The attributes for the specified index are returned.
745   AttributeSet getAttributes(unsigned Index) const;
746 
747   /// The attributes for the argument or parameter at the given index are
748   /// returned.
749   AttributeSet getParamAttrs(unsigned ArgNo) const;
750 
751   /// The attributes for the ret value are returned.
752   AttributeSet getRetAttrs() const;
753 
754   /// The function attributes are returned.
755   AttributeSet getFnAttrs() const;
756 
757   /// Return true if the attribute exists at the given index.
758   bool hasAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const;
759 
760   /// Return true if the attribute exists at the given index.
761   bool hasAttributeAtIndex(unsigned Index, StringRef Kind) const;
762 
763   /// Return true if attribute exists at the given index.
764   bool hasAttributesAtIndex(unsigned Index) const;
765 
766   /// Return true if the attribute exists for the given argument
767   bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
768     return hasAttributeAtIndex(ArgNo + FirstArgIndex, Kind);
769   }
770 
771   /// Return true if the attribute exists for the given argument
772   bool hasParamAttr(unsigned ArgNo, StringRef Kind) const {
773     return hasAttributeAtIndex(ArgNo + FirstArgIndex, Kind);
774   }
775 
776   /// Return true if attributes exists for the given argument
777   bool hasParamAttrs(unsigned ArgNo) const {
778     return hasAttributesAtIndex(ArgNo + FirstArgIndex);
779   }
780 
781   /// Return true if the attribute exists for the return value.
782   bool hasRetAttr(Attribute::AttrKind Kind) const {
783     return hasAttributeAtIndex(ReturnIndex, Kind);
784   }
785 
786   /// Return true if the attribute exists for the return value.
787   bool hasRetAttr(StringRef Kind) const {
788     return hasAttributeAtIndex(ReturnIndex, Kind);
789   }
790 
791   /// Return true if attributes exist for the return value.
792   bool hasRetAttrs() const { return hasAttributesAtIndex(ReturnIndex); }
793 
794   /// Return true if the attribute exists for the function.
795   bool hasFnAttr(Attribute::AttrKind Kind) const;
796 
797   /// Return true if the attribute exists for the function.
798   bool hasFnAttr(StringRef Kind) const;
799 
800   /// Return true the attributes exist for the function.
801   bool hasFnAttrs() const { return hasAttributesAtIndex(FunctionIndex); }
802 
803   /// Return true if the specified attribute is set for at least one
804   /// parameter or for the return value. If Index is not nullptr, the index
805   /// of a parameter with the specified attribute is provided.
806   bool hasAttrSomewhere(Attribute::AttrKind Kind,
807                         unsigned *Index = nullptr) const;
808 
809   /// Return the attribute object that exists at the given index.
810   Attribute getAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const;
811 
812   /// Return the attribute object that exists at the given index.
813   Attribute getAttributeAtIndex(unsigned Index, StringRef Kind) const;
814 
815   /// Return the attribute object that exists at the arg index.
816   Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
817     return getAttributeAtIndex(ArgNo + FirstArgIndex, Kind);
818   }
819 
820   /// Return the attribute object that exists at the given index.
821   Attribute getParamAttr(unsigned ArgNo, StringRef Kind) const {
822     return getAttributeAtIndex(ArgNo + FirstArgIndex, Kind);
823   }
824 
825   /// Return the attribute object that exists for the function.
826   Attribute getFnAttr(Attribute::AttrKind Kind) const {
827     return getAttributeAtIndex(FunctionIndex, Kind);
828   }
829 
830   /// Return the attribute object that exists for the function.
831   Attribute getFnAttr(StringRef Kind) const {
832     return getAttributeAtIndex(FunctionIndex, Kind);
833   }
834 
835   /// Return the alignment of the return value.
836   MaybeAlign getRetAlignment() const;
837 
838   /// Return the alignment for the specified function parameter.
839   MaybeAlign getParamAlignment(unsigned ArgNo) const;
840 
841   /// Return the stack alignment for the specified function parameter.
842   MaybeAlign getParamStackAlignment(unsigned ArgNo) const;
843 
844   /// Return the byval type for the specified function parameter.
845   Type *getParamByValType(unsigned ArgNo) const;
846 
847   /// Return the sret type for the specified function parameter.
848   Type *getParamStructRetType(unsigned ArgNo) const;
849 
850   /// Return the byref type for the specified function parameter.
851   Type *getParamByRefType(unsigned ArgNo) const;
852 
853   /// Return the preallocated type for the specified function parameter.
854   Type *getParamPreallocatedType(unsigned ArgNo) const;
855 
856   /// Return the inalloca type for the specified function parameter.
857   Type *getParamInAllocaType(unsigned ArgNo) const;
858 
859   /// Return the elementtype type for the specified function parameter.
860   Type *getParamElementType(unsigned ArgNo) const;
861 
862   /// Get the stack alignment of the function.
863   MaybeAlign getFnStackAlignment() const;
864 
865   /// Get the stack alignment of the return value.
866   MaybeAlign getRetStackAlignment() const;
867 
868   /// Get the number of dereferenceable bytes (or zero if unknown) of the return
869   /// value.
870   uint64_t getRetDereferenceableBytes() const;
871 
872   /// Get the number of dereferenceable bytes (or zero if unknown) of an arg.
873   uint64_t getParamDereferenceableBytes(unsigned Index) const;
874 
875   /// Get the number of dereferenceable_or_null bytes (or zero if unknown) of
876   /// the return value.
877   uint64_t getRetDereferenceableOrNullBytes() const;
878 
879   /// Get the number of dereferenceable_or_null bytes (or zero if unknown) of an
880   /// arg.
881   uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const;
882 
883   /// Get the disallowed floating-point classes of the return value.
884   FPClassTest getRetNoFPClass() const;
885 
886   /// Get the disallowed floating-point classes of the argument value.
887   FPClassTest getParamNoFPClass(unsigned ArgNo) const;
888 
889   /// Get the unwind table kind requested for the function.
890   UWTableKind getUWTableKind() const;
891 
892   AllocFnKind getAllocKind() const;
893 
894   /// Returns memory effects of the function.
895   MemoryEffects getMemoryEffects() const;
896 
897   /// Return the attributes at the index as a string.
898   std::string getAsString(unsigned Index, bool InAttrGrp = false) const;
899 
900   /// Return true if this attribute list belongs to the LLVMContext.
901   bool hasParentContext(LLVMContext &C) const;
902 
903   //===--------------------------------------------------------------------===//
904   // AttributeList Introspection
905   //===--------------------------------------------------------------------===//
906 
907   using iterator = const AttributeSet *;
908 
909   iterator begin() const;
910   iterator end() const;
911 
912   unsigned getNumAttrSets() const;
913 
914   // Implementation of indexes(). Produces iterators that wrap an index. Mostly
915   // to hide the awkwardness of unsigned wrapping when iterating over valid
916   // indexes.
917   struct index_iterator {
918     unsigned NumAttrSets;
919     index_iterator(int NumAttrSets) : NumAttrSets(NumAttrSets) {}
920     struct int_wrapper {
921       int_wrapper(unsigned i) : i(i) {}
922       unsigned i;
923       unsigned operator*() { return i; }
924       bool operator!=(const int_wrapper &Other) { return i != Other.i; }
925       int_wrapper &operator++() {
926         // This is expected to undergo unsigned wrapping since FunctionIndex is
927         // ~0 and that's where we start.
928         ++i;
929         return *this;
930       }
931     };
932 
933     int_wrapper begin() { return int_wrapper(AttributeList::FunctionIndex); }
934 
935     int_wrapper end() { return int_wrapper(NumAttrSets - 1); }
936   };
937 
938   /// Use this to iterate over the valid attribute indexes.
939   index_iterator indexes() const { return index_iterator(getNumAttrSets()); }
940 
941   /// operator==/!= - Provide equality predicates.
942   bool operator==(const AttributeList &RHS) const { return pImpl == RHS.pImpl; }
943   bool operator!=(const AttributeList &RHS) const { return pImpl != RHS.pImpl; }
944 
945   /// Return a raw pointer that uniquely identifies this attribute list.
946   void *getRawPointer() const {
947     return pImpl;
948   }
949 
950   /// Return true if there are no attributes.
951   bool isEmpty() const { return pImpl == nullptr; }
952 
953   void print(raw_ostream &O) const;
954 
955   void dump() const;
956 };
957 
958 //===----------------------------------------------------------------------===//
959 /// \class
960 /// Provide DenseMapInfo for AttributeList.
961 template <> struct DenseMapInfo<AttributeList, void> {
962   static AttributeList getEmptyKey() {
963     auto Val = static_cast<uintptr_t>(-1);
964     Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable;
965     return AttributeList(reinterpret_cast<AttributeListImpl *>(Val));
966   }
967 
968   static AttributeList getTombstoneKey() {
969     auto Val = static_cast<uintptr_t>(-2);
970     Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable;
971     return AttributeList(reinterpret_cast<AttributeListImpl *>(Val));
972   }
973 
974   static unsigned getHashValue(AttributeList AS) {
975     return (unsigned((uintptr_t)AS.pImpl) >> 4) ^
976            (unsigned((uintptr_t)AS.pImpl) >> 9);
977   }
978 
979   static bool isEqual(AttributeList LHS, AttributeList RHS) {
980     return LHS == RHS;
981   }
982 };
983 
984 //===----------------------------------------------------------------------===//
985 /// \class
986 /// This class is used in conjunction with the Attribute::get method to
987 /// create an Attribute object. The object itself is uniquified. The Builder's
988 /// value, however, is not. So this can be used as a quick way to test for
989 /// equality, presence of attributes, etc.
990 class AttrBuilder {
991   LLVMContext &Ctx;
992   SmallVector<Attribute, 8> Attrs;
993 
994 public:
995   AttrBuilder(LLVMContext &Ctx) : Ctx(Ctx) {}
996   AttrBuilder(const AttrBuilder &) = delete;
997   AttrBuilder(AttrBuilder &&) = default;
998 
999   AttrBuilder(LLVMContext &Ctx, const Attribute &A) : Ctx(Ctx) {
1000     addAttribute(A);
1001   }
1002 
1003   AttrBuilder(LLVMContext &Ctx, AttributeSet AS);
1004 
1005   void clear();
1006 
1007   /// Add an attribute to the builder.
1008   AttrBuilder &addAttribute(Attribute::AttrKind Val);
1009 
1010   /// Add the Attribute object to the builder.
1011   AttrBuilder &addAttribute(Attribute A);
1012 
1013   /// Add the target-dependent attribute to the builder.
1014   AttrBuilder &addAttribute(StringRef A, StringRef V = StringRef());
1015 
1016   /// Remove an attribute from the builder.
1017   AttrBuilder &removeAttribute(Attribute::AttrKind Val);
1018 
1019   /// Remove the target-dependent attribute from the builder.
1020   AttrBuilder &removeAttribute(StringRef A);
1021 
1022   /// Remove the target-dependent attribute from the builder.
1023   AttrBuilder &removeAttribute(Attribute A) {
1024     if (A.isStringAttribute())
1025       return removeAttribute(A.getKindAsString());
1026     else
1027       return removeAttribute(A.getKindAsEnum());
1028   }
1029 
1030   /// Add the attributes from the builder. Attributes in the passed builder
1031   /// overwrite attributes in this builder if they have the same key.
1032   AttrBuilder &merge(const AttrBuilder &B);
1033 
1034   /// Remove the attributes from the builder.
1035   AttrBuilder &remove(const AttributeMask &AM);
1036 
1037   /// Return true if the builder has any attribute that's in the
1038   /// specified builder.
1039   bool overlaps(const AttributeMask &AM) const;
1040 
1041   /// Return true if the builder has the specified attribute.
1042   bool contains(Attribute::AttrKind A) const;
1043 
1044   /// Return true if the builder has the specified target-dependent
1045   /// attribute.
1046   bool contains(StringRef A) const;
1047 
1048   /// Return true if the builder has IR-level attributes.
1049   bool hasAttributes() const { return !Attrs.empty(); }
1050 
1051   /// Return Attribute with the given Kind. The returned attribute will be
1052   /// invalid if the Kind is not present in the builder.
1053   Attribute getAttribute(Attribute::AttrKind Kind) const;
1054 
1055   /// Return Attribute with the given Kind. The returned attribute will be
1056   /// invalid if the Kind is not present in the builder.
1057   Attribute getAttribute(StringRef Kind) const;
1058 
1059   /// Return raw (possibly packed/encoded) value of integer attribute or
1060   /// std::nullopt if not set.
1061   std::optional<uint64_t> getRawIntAttr(Attribute::AttrKind Kind) const;
1062 
1063   /// Retrieve the alignment attribute, if it exists.
1064   MaybeAlign getAlignment() const {
1065     return MaybeAlign(getRawIntAttr(Attribute::Alignment).value_or(0));
1066   }
1067 
1068   /// Retrieve the stack alignment attribute, if it exists.
1069   MaybeAlign getStackAlignment() const {
1070     return MaybeAlign(getRawIntAttr(Attribute::StackAlignment).value_or(0));
1071   }
1072 
1073   /// Retrieve the number of dereferenceable bytes, if the
1074   /// dereferenceable attribute exists (zero is returned otherwise).
1075   uint64_t getDereferenceableBytes() const {
1076     return getRawIntAttr(Attribute::Dereferenceable).value_or(0);
1077   }
1078 
1079   /// Retrieve the number of dereferenceable_or_null bytes, if the
1080   /// dereferenceable_or_null attribute exists (zero is returned otherwise).
1081   uint64_t getDereferenceableOrNullBytes() const {
1082     return getRawIntAttr(Attribute::DereferenceableOrNull).value_or(0);
1083   }
1084 
1085   /// Retrieve type for the given type attribute.
1086   Type *getTypeAttr(Attribute::AttrKind Kind) const;
1087 
1088   /// Retrieve the byval type.
1089   Type *getByValType() const { return getTypeAttr(Attribute::ByVal); }
1090 
1091   /// Retrieve the sret type.
1092   Type *getStructRetType() const { return getTypeAttr(Attribute::StructRet); }
1093 
1094   /// Retrieve the byref type.
1095   Type *getByRefType() const { return getTypeAttr(Attribute::ByRef); }
1096 
1097   /// Retrieve the preallocated type.
1098   Type *getPreallocatedType() const {
1099     return getTypeAttr(Attribute::Preallocated);
1100   }
1101 
1102   /// Retrieve the inalloca type.
1103   Type *getInAllocaType() const { return getTypeAttr(Attribute::InAlloca); }
1104 
1105   /// Retrieve the allocsize args, or std::nullopt if the attribute does not
1106   /// exist.
1107   std::optional<std::pair<unsigned, std::optional<unsigned>>> getAllocSizeArgs()
1108       const;
1109 
1110   /// Add integer attribute with raw value (packed/encoded if necessary).
1111   AttrBuilder &addRawIntAttr(Attribute::AttrKind Kind, uint64_t Value);
1112 
1113   /// This turns an alignment into the form used internally in Attribute.
1114   /// This call has no effect if Align is not set.
1115   AttrBuilder &addAlignmentAttr(MaybeAlign Align);
1116 
1117   /// This turns an int alignment (which must be a power of 2) into the
1118   /// form used internally in Attribute.
1119   /// This call has no effect if Align is 0.
1120   /// Deprecated, use the version using a MaybeAlign.
1121   inline AttrBuilder &addAlignmentAttr(unsigned Align) {
1122     return addAlignmentAttr(MaybeAlign(Align));
1123   }
1124 
1125   /// This turns a stack alignment into the form used internally in Attribute.
1126   /// This call has no effect if Align is not set.
1127   AttrBuilder &addStackAlignmentAttr(MaybeAlign Align);
1128 
1129   /// This turns an int stack alignment (which must be a power of 2) into
1130   /// the form used internally in Attribute.
1131   /// This call has no effect if Align is 0.
1132   /// Deprecated, use the version using a MaybeAlign.
1133   inline AttrBuilder &addStackAlignmentAttr(unsigned Align) {
1134     return addStackAlignmentAttr(MaybeAlign(Align));
1135   }
1136 
1137   /// This turns the number of dereferenceable bytes into the form used
1138   /// internally in Attribute.
1139   AttrBuilder &addDereferenceableAttr(uint64_t Bytes);
1140 
1141   /// This turns the number of dereferenceable_or_null bytes into the
1142   /// form used internally in Attribute.
1143   AttrBuilder &addDereferenceableOrNullAttr(uint64_t Bytes);
1144 
1145   /// This turns one (or two) ints into the form used internally in Attribute.
1146   AttrBuilder &addAllocSizeAttr(unsigned ElemSizeArg,
1147                                 const std::optional<unsigned> &NumElemsArg);
1148 
1149   /// This turns two ints into the form used internally in Attribute.
1150   AttrBuilder &addVScaleRangeAttr(unsigned MinValue,
1151                                   std::optional<unsigned> MaxValue);
1152 
1153   /// Add a type attribute with the given type.
1154   AttrBuilder &addTypeAttr(Attribute::AttrKind Kind, Type *Ty);
1155 
1156   /// This turns a byval type into the form used internally in Attribute.
1157   AttrBuilder &addByValAttr(Type *Ty);
1158 
1159   /// This turns a sret type into the form used internally in Attribute.
1160   AttrBuilder &addStructRetAttr(Type *Ty);
1161 
1162   /// This turns a byref type into the form used internally in Attribute.
1163   AttrBuilder &addByRefAttr(Type *Ty);
1164 
1165   /// This turns a preallocated type into the form used internally in Attribute.
1166   AttrBuilder &addPreallocatedAttr(Type *Ty);
1167 
1168   /// This turns an inalloca type into the form used internally in Attribute.
1169   AttrBuilder &addInAllocaAttr(Type *Ty);
1170 
1171   /// Add an allocsize attribute, using the representation returned by
1172   /// Attribute.getIntValue().
1173   AttrBuilder &addAllocSizeAttrFromRawRepr(uint64_t RawAllocSizeRepr);
1174 
1175   /// Add a vscale_range attribute, using the representation returned by
1176   /// Attribute.getIntValue().
1177   AttrBuilder &addVScaleRangeAttrFromRawRepr(uint64_t RawVScaleRangeRepr);
1178 
1179   /// This turns the unwind table kind into the form used internally in
1180   /// Attribute.
1181   AttrBuilder &addUWTableAttr(UWTableKind Kind);
1182 
1183   // This turns the allocator kind into the form used internally in Attribute.
1184   AttrBuilder &addAllocKindAttr(AllocFnKind Kind);
1185 
1186   /// Add memory effect attribute.
1187   AttrBuilder &addMemoryAttr(MemoryEffects ME);
1188 
1189   // Add nofpclass attribute
1190   AttrBuilder &addNoFPClassAttr(FPClassTest NoFPClassMask);
1191 
1192   ArrayRef<Attribute> attrs() const { return Attrs; }
1193 
1194   bool operator==(const AttrBuilder &B) const;
1195   bool operator!=(const AttrBuilder &B) const { return !(*this == B); }
1196 };
1197 
1198 namespace AttributeFuncs {
1199 
1200 enum AttributeSafetyKind : uint8_t {
1201   ASK_SAFE_TO_DROP = 1,
1202   ASK_UNSAFE_TO_DROP = 2,
1203   ASK_ALL = ASK_SAFE_TO_DROP | ASK_UNSAFE_TO_DROP,
1204 };
1205 
1206 /// Returns true if this is a type legal for the 'nofpclass' attribute. This
1207 /// follows the same type rules as FPMathOperator.
1208 bool isNoFPClassCompatibleType(Type *Ty);
1209 
1210 /// Which attributes cannot be applied to a type. The argument \p ASK indicates,
1211 /// if only attributes that are known to be safely droppable are contained in
1212 /// the mask; only attributes that might be unsafe to drop (e.g., ABI-related
1213 /// attributes) are in the mask; or both.
1214 AttributeMask typeIncompatible(Type *Ty, AttributeSafetyKind ASK = ASK_ALL);
1215 
1216 /// Get param/return attributes which imply immediate undefined behavior if an
1217 /// invalid value is passed. For example, this includes noundef (where undef
1218 /// implies UB), but not nonnull (where null implies poison). It also does not
1219 /// include attributes like nocapture, which constrain the function
1220 /// implementation rather than the passed value.
1221 AttributeMask getUBImplyingAttributes();
1222 
1223 /// \returns Return true if the two functions have compatible target-independent
1224 /// attributes for inlining purposes.
1225 bool areInlineCompatible(const Function &Caller, const Function &Callee);
1226 
1227 
1228 /// Checks  if there are any incompatible function attributes between
1229 /// \p A and \p B.
1230 ///
1231 /// \param [in] A - The first function to be compared with.
1232 /// \param [in] B - The second function to be compared with.
1233 /// \returns true if the functions have compatible attributes.
1234 bool areOutlineCompatible(const Function &A, const Function &B);
1235 
1236 /// Merge caller's and callee's attributes.
1237 void mergeAttributesForInlining(Function &Caller, const Function &Callee);
1238 
1239 /// Merges the functions attributes from \p ToMerge into function \p Base.
1240 ///
1241 /// \param [in,out] Base - The function being merged into.
1242 /// \param [in] ToMerge - The function to merge attributes from.
1243 void mergeAttributesForOutlining(Function &Base, const Function &ToMerge);
1244 
1245 /// Update min-legal-vector-width if it is in Attribute and less than Width.
1246 void updateMinLegalVectorWidthAttr(Function &Fn, uint64_t Width);
1247 
1248 } // end namespace AttributeFuncs
1249 
1250 } // end namespace llvm
1251 
1252 #endif // LLVM_IR_ATTRIBUTES_H
1253