Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:57

0001 //===- llvm/Attributes.h - Container for Attributes -------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 /// \file
0010 /// This file contains the simple types necessary to represent the
0011 /// attributes associated with functions and their calls.
0012 //
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_IR_ATTRIBUTES_H
0016 #define LLVM_IR_ATTRIBUTES_H
0017 
0018 #include "llvm-c/Types.h"
0019 #include "llvm/ADT/ArrayRef.h"
0020 #include "llvm/ADT/BitmaskEnum.h"
0021 #include "llvm/ADT/StringRef.h"
0022 #include "llvm/Config/llvm-config.h"
0023 #include "llvm/Support/Alignment.h"
0024 #include "llvm/Support/CodeGen.h"
0025 #include "llvm/Support/ModRef.h"
0026 #include "llvm/Support/PointerLikeTypeTraits.h"
0027 #include <cassert>
0028 #include <cstdint>
0029 #include <optional>
0030 #include <string>
0031 #include <utility>
0032 
0033 namespace llvm {
0034 
0035 class AttrBuilder;
0036 class AttributeMask;
0037 class AttributeImpl;
0038 class AttributeListImpl;
0039 class AttributeSetNode;
0040 class ConstantRange;
0041 class ConstantRangeList;
0042 class FoldingSetNodeID;
0043 class Function;
0044 class LLVMContext;
0045 class Type;
0046 class raw_ostream;
0047 enum FPClassTest : unsigned;
0048 
0049 enum class AllocFnKind : uint64_t {
0050   Unknown = 0,
0051   Alloc = 1 << 0,         // Allocator function returns a new allocation
0052   Realloc = 1 << 1,       // Allocator function resizes the `allocptr` argument
0053   Free = 1 << 2,          // Allocator function frees the `allocptr` argument
0054   Uninitialized = 1 << 3, // Allocator function returns uninitialized memory
0055   Zeroed = 1 << 4,        // Allocator function returns zeroed memory
0056   Aligned = 1 << 5,       // Allocator function aligns allocations per the
0057                           // `allocalign` argument
0058   LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ Aligned)
0059 };
0060 
0061 //===----------------------------------------------------------------------===//
0062 /// \class
0063 /// Functions, function parameters, and return types can have attributes
0064 /// to indicate how they should be treated by optimizations and code
0065 /// generation. This class represents one of those attributes. It's light-weight
0066 /// and should be passed around by-value.
0067 class Attribute {
0068 public:
0069   /// This enumeration lists the attributes that can be associated with
0070   /// parameters, function results, or the function itself.
0071   ///
0072   /// Note: The `uwtable' attribute is about the ABI or the user mandating an
0073   /// entry in the unwind table. The `nounwind' attribute is about an exception
0074   /// passing by the function.
0075   ///
0076   /// In a theoretical system that uses tables for profiling and SjLj for
0077   /// exceptions, they would be fully independent. In a normal system that uses
0078   /// tables for both, the semantics are:
0079   ///
0080   /// nil                = Needs an entry because an exception might pass by.
0081   /// nounwind           = No need for an entry
0082   /// uwtable            = Needs an entry because the ABI says so and because
0083   ///                      an exception might pass by.
0084   /// uwtable + nounwind = Needs an entry because the ABI says so.
0085 
0086   enum AttrKind {
0087     // IR-Level Attributes
0088     None,                  ///< No attributes have been set
0089     #define GET_ATTR_ENUM
0090     #include "llvm/IR/Attributes.inc"
0091     EndAttrKinds,          ///< Sentinel value useful for loops
0092     EmptyKey,              ///< Use as Empty key for DenseMap of AttrKind
0093     TombstoneKey,          ///< Use as Tombstone key for DenseMap of AttrKind
0094   };
0095 
0096   static const unsigned NumIntAttrKinds = LastIntAttr - FirstIntAttr + 1;
0097   static const unsigned NumTypeAttrKinds = LastTypeAttr - FirstTypeAttr + 1;
0098 
0099   static bool isEnumAttrKind(AttrKind Kind) {
0100     return Kind >= FirstEnumAttr && Kind <= LastEnumAttr;
0101   }
0102   static bool isIntAttrKind(AttrKind Kind) {
0103     return Kind >= FirstIntAttr && Kind <= LastIntAttr;
0104   }
0105   static bool isTypeAttrKind(AttrKind Kind) {
0106     return Kind >= FirstTypeAttr && Kind <= LastTypeAttr;
0107   }
0108   static bool isConstantRangeAttrKind(AttrKind Kind) {
0109     return Kind >= FirstConstantRangeAttr && Kind <= LastConstantRangeAttr;
0110   }
0111   static bool isConstantRangeListAttrKind(AttrKind Kind) {
0112     return Kind >= FirstConstantRangeListAttr &&
0113            Kind <= LastConstantRangeListAttr;
0114   }
0115 
0116   static bool canUseAsFnAttr(AttrKind Kind);
0117   static bool canUseAsParamAttr(AttrKind Kind);
0118   static bool canUseAsRetAttr(AttrKind Kind);
0119 
0120   static bool intersectMustPreserve(AttrKind Kind);
0121   static bool intersectWithAnd(AttrKind Kind);
0122   static bool intersectWithMin(AttrKind Kind);
0123   static bool intersectWithCustom(AttrKind Kind);
0124 
0125 private:
0126   AttributeImpl *pImpl = nullptr;
0127 
0128   Attribute(AttributeImpl *A) : pImpl(A) {}
0129 
0130 public:
0131   Attribute() = default;
0132 
0133   //===--------------------------------------------------------------------===//
0134   // Attribute Construction
0135   //===--------------------------------------------------------------------===//
0136 
0137   /// Return a uniquified Attribute object.
0138   static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val = 0);
0139   static Attribute get(LLVMContext &Context, StringRef Kind,
0140                        StringRef Val = StringRef());
0141   static Attribute get(LLVMContext &Context, AttrKind Kind, Type *Ty);
0142   static Attribute get(LLVMContext &Context, AttrKind Kind,
0143                        const ConstantRange &CR);
0144   static Attribute get(LLVMContext &Context, AttrKind Kind,
0145                        ArrayRef<ConstantRange> Val);
0146 
0147   /// Return a uniquified Attribute object that has the specific
0148   /// alignment set.
0149   static Attribute getWithAlignment(LLVMContext &Context, Align Alignment);
0150   static Attribute getWithStackAlignment(LLVMContext &Context, Align Alignment);
0151   static Attribute getWithDereferenceableBytes(LLVMContext &Context,
0152                                               uint64_t Bytes);
0153   static Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context,
0154                                                      uint64_t Bytes);
0155   static Attribute getWithAllocSizeArgs(
0156       LLVMContext &Context, unsigned ElemSizeArg,
0157       const std::optional<unsigned> &NumElemsArg);
0158   static Attribute getWithVScaleRangeArgs(LLVMContext &Context,
0159                                           unsigned MinValue, unsigned MaxValue);
0160   static Attribute getWithByValType(LLVMContext &Context, Type *Ty);
0161   static Attribute getWithStructRetType(LLVMContext &Context, Type *Ty);
0162   static Attribute getWithByRefType(LLVMContext &Context, Type *Ty);
0163   static Attribute getWithPreallocatedType(LLVMContext &Context, Type *Ty);
0164   static Attribute getWithInAllocaType(LLVMContext &Context, Type *Ty);
0165   static Attribute getWithUWTableKind(LLVMContext &Context, UWTableKind Kind);
0166   static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME);
0167   static Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask);
0168 
0169   /// For a typed attribute, return the equivalent attribute with the type
0170   /// changed to \p ReplacementTy.
0171   Attribute getWithNewType(LLVMContext &Context, Type *ReplacementTy) {
0172     assert(isTypeAttribute() && "this requires a typed attribute");
0173     return get(Context, getKindAsEnum(), ReplacementTy);
0174   }
0175 
0176   static Attribute::AttrKind getAttrKindFromName(StringRef AttrName);
0177 
0178   static StringRef getNameFromAttrKind(Attribute::AttrKind AttrKind);
0179 
0180   /// Return true if the provided string matches the IR name of an attribute.
0181   /// example: "noalias" return true but not "NoAlias"
0182   static bool isExistingAttribute(StringRef Name);
0183 
0184   //===--------------------------------------------------------------------===//
0185   // Attribute Accessors
0186   //===--------------------------------------------------------------------===//
0187 
0188   /// Return true if the attribute is an Attribute::AttrKind type.
0189   bool isEnumAttribute() const;
0190 
0191   /// Return true if the attribute is an integer attribute.
0192   bool isIntAttribute() const;
0193 
0194   /// Return true if the attribute is a string (target-dependent)
0195   /// attribute.
0196   bool isStringAttribute() const;
0197 
0198   /// Return true if the attribute is a type attribute.
0199   bool isTypeAttribute() const;
0200 
0201   /// Return true if the attribute is a ConstantRange attribute.
0202   bool isConstantRangeAttribute() const;
0203 
0204   /// Return true if the attribute is a ConstantRangeList attribute.
0205   bool isConstantRangeListAttribute() const;
0206 
0207   /// Return true if the attribute is any kind of attribute.
0208   bool isValid() const { return pImpl; }
0209 
0210   /// Return true if the attribute is present.
0211   bool hasAttribute(AttrKind Val) const;
0212 
0213   /// Return true if the target-dependent attribute is present.
0214   bool hasAttribute(StringRef Val) const;
0215 
0216   /// Returns true if the attribute's kind can be represented as an enum (Enum,
0217   /// Integer, Type, ConstantRange, or ConstantRangeList attribute).
0218   bool hasKindAsEnum() const { return !isStringAttribute(); }
0219 
0220   /// Return the attribute's kind as an enum (Attribute::AttrKind). This
0221   /// requires the attribute be representable as an enum (see: `hasKindAsEnum`).
0222   Attribute::AttrKind getKindAsEnum() const;
0223 
0224   /// Return the attribute's value as an integer. This requires that the
0225   /// attribute be an integer attribute.
0226   uint64_t getValueAsInt() const;
0227 
0228   /// Return the attribute's value as a boolean. This requires that the
0229   /// attribute be a string attribute.
0230   bool getValueAsBool() const;
0231 
0232   /// Return the attribute's kind as a string. This requires the
0233   /// attribute to be a string attribute.
0234   StringRef getKindAsString() const;
0235 
0236   /// Return the attribute's value as a string. This requires the
0237   /// attribute to be a string attribute.
0238   StringRef getValueAsString() const;
0239 
0240   /// Return the attribute's value as a Type. This requires the attribute to be
0241   /// a type attribute.
0242   Type *getValueAsType() const;
0243 
0244   /// Return the attribute's value as a ConstantRange. This requires the
0245   /// attribute to be a ConstantRange attribute.
0246   const ConstantRange &getValueAsConstantRange() const;
0247 
0248   /// Return the attribute's value as a ConstantRange array. This requires the
0249   /// attribute to be a ConstantRangeList attribute.
0250   ArrayRef<ConstantRange> getValueAsConstantRangeList() const;
0251 
0252   /// Returns the alignment field of an attribute as a byte alignment
0253   /// value.
0254   MaybeAlign getAlignment() const;
0255 
0256   /// Returns the stack alignment field of an attribute as a byte
0257   /// alignment value.
0258   MaybeAlign getStackAlignment() const;
0259 
0260   /// Returns the number of dereferenceable bytes from the
0261   /// dereferenceable attribute.
0262   uint64_t getDereferenceableBytes() const;
0263 
0264   /// Returns the number of dereferenceable_or_null bytes from the
0265   /// dereferenceable_or_null attribute.
0266   uint64_t getDereferenceableOrNullBytes() const;
0267 
0268   /// Returns the argument numbers for the allocsize attribute.
0269   std::pair<unsigned, std::optional<unsigned>> getAllocSizeArgs() const;
0270 
0271   /// Returns the minimum value for the vscale_range attribute.
0272   unsigned getVScaleRangeMin() const;
0273 
0274   /// Returns the maximum value for the vscale_range attribute or std::nullopt
0275   /// when unknown.
0276   std::optional<unsigned> getVScaleRangeMax() const;
0277 
0278   // Returns the unwind table kind.
0279   UWTableKind getUWTableKind() const;
0280 
0281   // Returns the allocator function kind.
0282   AllocFnKind getAllocKind() const;
0283 
0284   /// Returns memory effects.
0285   MemoryEffects getMemoryEffects() const;
0286 
0287   /// Returns information from captures attribute.
0288   CaptureInfo getCaptureInfo() const;
0289 
0290   /// Return the FPClassTest for nofpclass
0291   FPClassTest getNoFPClass() const;
0292 
0293   /// Returns the value of the range attribute.
0294   const ConstantRange &getRange() const;
0295 
0296   /// Returns the value of the initializes attribute.
0297   ArrayRef<ConstantRange> getInitializes() const;
0298 
0299   /// The Attribute is converted to a string of equivalent mnemonic. This
0300   /// is, presumably, for writing out the mnemonics for the assembly writer.
0301   std::string getAsString(bool InAttrGrp = false) const;
0302 
0303   /// Return true if this attribute belongs to the LLVMContext.
0304   bool hasParentContext(LLVMContext &C) const;
0305 
0306   /// Equality and non-equality operators.
0307   bool operator==(Attribute A) const { return pImpl == A.pImpl; }
0308   bool operator!=(Attribute A) const { return pImpl != A.pImpl; }
0309 
0310   /// Used to sort attribute by kind.
0311   int cmpKind(Attribute A) const;
0312 
0313   /// Less-than operator. Useful for sorting the attributes list.
0314   bool operator<(Attribute A) const;
0315 
0316   void Profile(FoldingSetNodeID &ID) const;
0317 
0318   /// Return a raw pointer that uniquely identifies this attribute.
0319   void *getRawPointer() const {
0320     return pImpl;
0321   }
0322 
0323   /// Get an attribute from a raw pointer created by getRawPointer.
0324   static Attribute fromRawPointer(void *RawPtr) {
0325     return Attribute(reinterpret_cast<AttributeImpl*>(RawPtr));
0326   }
0327 };
0328 
0329 // Specialized opaque value conversions.
0330 inline LLVMAttributeRef wrap(Attribute Attr) {
0331   return reinterpret_cast<LLVMAttributeRef>(Attr.getRawPointer());
0332 }
0333 
0334 // Specialized opaque value conversions.
0335 inline Attribute unwrap(LLVMAttributeRef Attr) {
0336   return Attribute::fromRawPointer(Attr);
0337 }
0338 
0339 //===----------------------------------------------------------------------===//
0340 /// \class
0341 /// This class holds the attributes for a particular argument, parameter,
0342 /// function, or return value. It is an immutable value type that is cheap to
0343 /// copy. Adding and removing enum attributes is intended to be fast, but adding
0344 /// and removing string or integer attributes involves a FoldingSet lookup.
0345 class AttributeSet {
0346   friend AttributeListImpl;
0347   template <typename Ty, typename Enable> friend struct DenseMapInfo;
0348 
0349   // TODO: Extract AvailableAttrs from AttributeSetNode and store them here.
0350   // This will allow an efficient implementation of addAttribute and
0351   // removeAttribute for enum attrs.
0352 
0353   /// Private implementation pointer.
0354   AttributeSetNode *SetNode = nullptr;
0355 
0356 private:
0357   explicit AttributeSet(AttributeSetNode *ASN) : SetNode(ASN) {}
0358 
0359 public:
0360   /// AttributeSet is a trivially copyable value type.
0361   AttributeSet() = default;
0362   AttributeSet(const AttributeSet &) = default;
0363   ~AttributeSet() = default;
0364 
0365   static AttributeSet get(LLVMContext &C, const AttrBuilder &B);
0366   static AttributeSet get(LLVMContext &C, ArrayRef<Attribute> Attrs);
0367 
0368   bool operator==(const AttributeSet &O) const { return SetNode == O.SetNode; }
0369   bool operator!=(const AttributeSet &O) const { return !(*this == O); }
0370 
0371   /// Add an argument attribute. Returns a new set because attribute sets are
0372   /// immutable.
0373   [[nodiscard]] AttributeSet addAttribute(LLVMContext &C,
0374                                           Attribute::AttrKind Kind) const;
0375 
0376   /// Add a target-dependent attribute. Returns a new set because attribute sets
0377   /// are immutable.
0378   [[nodiscard]] AttributeSet addAttribute(LLVMContext &C, StringRef Kind,
0379                                           StringRef Value = StringRef()) const;
0380 
0381   /// Add attributes to the attribute set. Returns a new set because attribute
0382   /// sets are immutable.
0383   [[nodiscard]] AttributeSet addAttributes(LLVMContext &C,
0384                                            AttributeSet AS) const;
0385 
0386   /// Remove the specified attribute from this set. Returns a new set because
0387   /// attribute sets are immutable.
0388   [[nodiscard]] AttributeSet removeAttribute(LLVMContext &C,
0389                                              Attribute::AttrKind Kind) const;
0390 
0391   /// Remove the specified attribute from this set. Returns a new set because
0392   /// attribute sets are immutable.
0393   [[nodiscard]] AttributeSet removeAttribute(LLVMContext &C,
0394                                              StringRef Kind) const;
0395 
0396   /// Remove the specified attributes from this set. Returns a new set because
0397   /// attribute sets are immutable.
0398   [[nodiscard]] AttributeSet
0399   removeAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const;
0400 
0401   /// Try to intersect this AttributeSet with Other. Returns std::nullopt if
0402   /// the two lists are inherently incompatible (imply different behavior, not
0403   /// just analysis).
0404   [[nodiscard]] std::optional<AttributeSet>
0405   intersectWith(LLVMContext &C, AttributeSet Other) const;
0406 
0407   /// Return the number of attributes in this set.
0408   unsigned getNumAttributes() const;
0409 
0410   /// Return true if attributes exists in this set.
0411   bool hasAttributes() const { return SetNode != nullptr; }
0412 
0413   /// Return true if the attribute exists in this set.
0414   bool hasAttribute(Attribute::AttrKind Kind) const;
0415 
0416   /// Return true if the attribute exists in this set.
0417   bool hasAttribute(StringRef Kind) const;
0418 
0419   /// Return the attribute object.
0420   Attribute getAttribute(Attribute::AttrKind Kind) const;
0421 
0422   /// Return the target-dependent attribute object.
0423   Attribute getAttribute(StringRef Kind) const;
0424 
0425   MaybeAlign getAlignment() const;
0426   MaybeAlign getStackAlignment() const;
0427   uint64_t getDereferenceableBytes() const;
0428   uint64_t getDereferenceableOrNullBytes() const;
0429   Type *getByValType() const;
0430   Type *getStructRetType() const;
0431   Type *getByRefType() const;
0432   Type *getPreallocatedType() const;
0433   Type *getInAllocaType() const;
0434   Type *getElementType() const;
0435   std::optional<std::pair<unsigned, std::optional<unsigned>>> getAllocSizeArgs()
0436       const;
0437   unsigned getVScaleRangeMin() const;
0438   std::optional<unsigned> getVScaleRangeMax() const;
0439   UWTableKind getUWTableKind() const;
0440   AllocFnKind getAllocKind() const;
0441   MemoryEffects getMemoryEffects() const;
0442   CaptureInfo getCaptureInfo() const;
0443   FPClassTest getNoFPClass() const;
0444   std::string getAsString(bool InAttrGrp = false) const;
0445 
0446   /// Return true if this attribute set belongs to the LLVMContext.
0447   bool hasParentContext(LLVMContext &C) const;
0448 
0449   using iterator = const Attribute *;
0450 
0451   iterator begin() const;
0452   iterator end() const;
0453 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0454   void dump() const;
0455 #endif
0456 };
0457 
0458 //===----------------------------------------------------------------------===//
0459 /// \class
0460 /// Provide DenseMapInfo for AttributeSet.
0461 template <> struct DenseMapInfo<AttributeSet, void> {
0462   static AttributeSet getEmptyKey() {
0463     auto Val = static_cast<uintptr_t>(-1);
0464     Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
0465     return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val));
0466   }
0467 
0468   static AttributeSet getTombstoneKey() {
0469     auto Val = static_cast<uintptr_t>(-2);
0470     Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
0471     return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val));
0472   }
0473 
0474   static unsigned getHashValue(AttributeSet AS) {
0475     return (unsigned((uintptr_t)AS.SetNode) >> 4) ^
0476            (unsigned((uintptr_t)AS.SetNode) >> 9);
0477   }
0478 
0479   static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; }
0480 };
0481 
0482 //===----------------------------------------------------------------------===//
0483 /// \class
0484 /// This class holds the attributes for a function, its return value, and
0485 /// its parameters. You access the attributes for each of them via an index into
0486 /// the AttributeList object. The function attributes are at index
0487 /// `AttributeList::FunctionIndex', the return value is at index
0488 /// `AttributeList::ReturnIndex', and the attributes for the parameters start at
0489 /// index `AttributeList::FirstArgIndex'.
0490 class AttributeList {
0491 public:
0492   enum AttrIndex : unsigned {
0493     ReturnIndex = 0U,
0494     FunctionIndex = ~0U,
0495     FirstArgIndex = 1,
0496   };
0497 
0498 private:
0499   friend class AttrBuilder;
0500   friend class AttributeListImpl;
0501   friend class AttributeSet;
0502   friend class AttributeSetNode;
0503   template <typename Ty, typename Enable> friend struct DenseMapInfo;
0504 
0505   /// The attributes that we are managing. This can be null to represent
0506   /// the empty attributes list.
0507   AttributeListImpl *pImpl = nullptr;
0508 
0509 public:
0510   /// Create an AttributeList with the specified parameters in it.
0511   static AttributeList get(LLVMContext &C,
0512                            ArrayRef<std::pair<unsigned, Attribute>> Attrs);
0513   static AttributeList get(LLVMContext &C,
0514                            ArrayRef<std::pair<unsigned, AttributeSet>> Attrs);
0515 
0516   /// Create an AttributeList from attribute sets for a function, its
0517   /// return value, and all of its arguments.
0518   static AttributeList get(LLVMContext &C, AttributeSet FnAttrs,
0519                            AttributeSet RetAttrs,
0520                            ArrayRef<AttributeSet> ArgAttrs);
0521 
0522 private:
0523   explicit AttributeList(AttributeListImpl *LI) : pImpl(LI) {}
0524 
0525   static AttributeList getImpl(LLVMContext &C, ArrayRef<AttributeSet> AttrSets);
0526 
0527   AttributeList setAttributesAtIndex(LLVMContext &C, unsigned Index,
0528                                      AttributeSet Attrs) const;
0529 
0530 public:
0531   AttributeList() = default;
0532 
0533   //===--------------------------------------------------------------------===//
0534   // AttributeList Construction and Mutation
0535   //===--------------------------------------------------------------------===//
0536 
0537   /// Return an AttributeList with the specified parameters in it.
0538   static AttributeList get(LLVMContext &C, ArrayRef<AttributeList> Attrs);
0539   static AttributeList get(LLVMContext &C, unsigned Index,
0540                            ArrayRef<Attribute::AttrKind> Kinds);
0541   static AttributeList get(LLVMContext &C, unsigned Index,
0542                            ArrayRef<Attribute::AttrKind> Kinds,
0543                            ArrayRef<uint64_t> Values);
0544   static AttributeList get(LLVMContext &C, unsigned Index,
0545                            ArrayRef<StringRef> Kind);
0546   static AttributeList get(LLVMContext &C, unsigned Index,
0547                            AttributeSet Attrs);
0548   static AttributeList get(LLVMContext &C, unsigned Index,
0549                            const AttrBuilder &B);
0550 
0551   // TODO: remove non-AtIndex versions of these methods.
0552   /// Add an attribute to the attribute set at the given index.
0553   /// Returns a new list because attribute lists are immutable.
0554   [[nodiscard]] AttributeList
0555   addAttributeAtIndex(LLVMContext &C, unsigned Index,
0556                       Attribute::AttrKind Kind) const;
0557 
0558   /// Add an attribute to the attribute set at the given index.
0559   /// Returns a new list because attribute lists are immutable.
0560   [[nodiscard]] AttributeList
0561   addAttributeAtIndex(LLVMContext &C, unsigned Index, StringRef Kind,
0562                       StringRef Value = StringRef()) const;
0563 
0564   /// Add an attribute to the attribute set at the given index.
0565   /// Returns a new list because attribute lists are immutable.
0566   [[nodiscard]] AttributeList
0567   addAttributeAtIndex(LLVMContext &C, unsigned Index, Attribute A) const;
0568 
0569   /// Add attributes to the attribute set at the given index.
0570   /// Returns a new list because attribute lists are immutable.
0571   [[nodiscard]] AttributeList addAttributesAtIndex(LLVMContext &C,
0572                                                    unsigned Index,
0573                                                    const AttrBuilder &B) const;
0574 
0575   /// Add a function attribute to the list. Returns a new list because
0576   /// attribute lists are immutable.
0577   [[nodiscard]] AttributeList addFnAttribute(LLVMContext &C,
0578                                              Attribute::AttrKind Kind) const {
0579     return addAttributeAtIndex(C, FunctionIndex, Kind);
0580   }
0581 
0582   /// Add a function attribute to the list. Returns a new list because
0583   /// attribute lists are immutable.
0584   [[nodiscard]] AttributeList addFnAttribute(LLVMContext &C,
0585                                              Attribute Attr) const {
0586     return addAttributeAtIndex(C, FunctionIndex, Attr);
0587   }
0588 
0589   /// Add a function attribute to the list. Returns a new list because
0590   /// attribute lists are immutable.
0591   [[nodiscard]] AttributeList
0592   addFnAttribute(LLVMContext &C, StringRef Kind,
0593                  StringRef Value = StringRef()) const {
0594     return addAttributeAtIndex(C, FunctionIndex, Kind, Value);
0595   }
0596 
0597   /// Add function attribute to the list. Returns a new list because
0598   /// attribute lists are immutable.
0599   [[nodiscard]] AttributeList addFnAttributes(LLVMContext &C,
0600                                               const AttrBuilder &B) const {
0601     return addAttributesAtIndex(C, FunctionIndex, B);
0602   }
0603 
0604   /// Add a return value attribute to the list. Returns a new list because
0605   /// attribute lists are immutable.
0606   [[nodiscard]] AttributeList addRetAttribute(LLVMContext &C,
0607                                               Attribute::AttrKind Kind) const {
0608     return addAttributeAtIndex(C, ReturnIndex, Kind);
0609   }
0610 
0611   /// Add a return value attribute to the list. Returns a new list because
0612   /// attribute lists are immutable.
0613   [[nodiscard]] AttributeList addRetAttribute(LLVMContext &C,
0614                                               Attribute Attr) const {
0615     return addAttributeAtIndex(C, ReturnIndex, Attr);
0616   }
0617 
0618   /// Add a return value attribute to the list. Returns a new list because
0619   /// attribute lists are immutable.
0620   [[nodiscard]] AttributeList addRetAttributes(LLVMContext &C,
0621                                                const AttrBuilder &B) const {
0622     return addAttributesAtIndex(C, ReturnIndex, B);
0623   }
0624 
0625   /// Add an argument attribute to the list. Returns a new list because
0626   /// attribute lists are immutable.
0627   [[nodiscard]] AttributeList
0628   addParamAttribute(LLVMContext &C, unsigned ArgNo,
0629                     Attribute::AttrKind Kind) const {
0630     return addAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind);
0631   }
0632 
0633   /// Add an argument attribute to the list. Returns a new list because
0634   /// attribute lists are immutable.
0635   [[nodiscard]] AttributeList
0636   addParamAttribute(LLVMContext &C, unsigned ArgNo, StringRef Kind,
0637                     StringRef Value = StringRef()) const {
0638     return addAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind, Value);
0639   }
0640 
0641   /// Add an attribute to the attribute list at the given arg indices. Returns a
0642   /// new list because attribute lists are immutable.
0643   [[nodiscard]] AttributeList addParamAttribute(LLVMContext &C,
0644                                                 ArrayRef<unsigned> ArgNos,
0645                                                 Attribute A) const;
0646 
0647   /// Add an argument attribute to the list. Returns a new list because
0648   /// attribute lists are immutable.
0649   [[nodiscard]] AttributeList addParamAttributes(LLVMContext &C, unsigned ArgNo,
0650                                                  const AttrBuilder &B) const {
0651     return addAttributesAtIndex(C, ArgNo + FirstArgIndex, B);
0652   }
0653 
0654   /// Remove the specified attribute at the specified index from this
0655   /// attribute list. Returns a new list because attribute lists are immutable.
0656   [[nodiscard]] AttributeList
0657   removeAttributeAtIndex(LLVMContext &C, unsigned Index,
0658                          Attribute::AttrKind Kind) const;
0659 
0660   /// Remove the specified attribute at the specified index from this
0661   /// attribute list. Returns a new list because attribute lists are immutable.
0662   [[nodiscard]] AttributeList
0663   removeAttributeAtIndex(LLVMContext &C, unsigned Index, StringRef Kind) const;
0664   [[nodiscard]] AttributeList removeAttribute(LLVMContext &C, unsigned Index,
0665                                               StringRef Kind) const {
0666     return removeAttributeAtIndex(C, Index, Kind);
0667   }
0668 
0669   /// Remove the specified attributes at the specified index from this
0670   /// attribute list. Returns a new list because attribute lists are immutable.
0671   [[nodiscard]] AttributeList
0672   removeAttributesAtIndex(LLVMContext &C, unsigned Index,
0673                           const AttributeMask &AttrsToRemove) const;
0674 
0675   /// Remove all attributes at the specified index from this
0676   /// attribute list. Returns a new list because attribute lists are immutable.
0677   [[nodiscard]] AttributeList removeAttributesAtIndex(LLVMContext &C,
0678                                                       unsigned Index) const;
0679 
0680   /// Remove the specified attribute at the function index from this
0681   /// attribute list. Returns a new list because attribute lists are immutable.
0682   [[nodiscard]] AttributeList
0683   removeFnAttribute(LLVMContext &C, Attribute::AttrKind Kind) const {
0684     return removeAttributeAtIndex(C, FunctionIndex, Kind);
0685   }
0686 
0687   /// Remove the specified attribute at the function index from this
0688   /// attribute list. Returns a new list because attribute lists are immutable.
0689   [[nodiscard]] AttributeList removeFnAttribute(LLVMContext &C,
0690                                                 StringRef Kind) const {
0691     return removeAttributeAtIndex(C, FunctionIndex, Kind);
0692   }
0693 
0694   /// Remove the specified attribute at the function index from this
0695   /// attribute list. Returns a new list because attribute lists are immutable.
0696   [[nodiscard]] AttributeList
0697   removeFnAttributes(LLVMContext &C, const AttributeMask &AttrsToRemove) const {
0698     return removeAttributesAtIndex(C, FunctionIndex, AttrsToRemove);
0699   }
0700 
0701   /// Remove the attributes at the function index from this
0702   /// attribute list. Returns a new list because attribute lists are immutable.
0703   [[nodiscard]] AttributeList removeFnAttributes(LLVMContext &C) const {
0704     return removeAttributesAtIndex(C, FunctionIndex);
0705   }
0706 
0707   /// Remove the specified attribute at the return value index from this
0708   /// attribute list. Returns a new list because attribute lists are immutable.
0709   [[nodiscard]] AttributeList
0710   removeRetAttribute(LLVMContext &C, Attribute::AttrKind Kind) const {
0711     return removeAttributeAtIndex(C, ReturnIndex, Kind);
0712   }
0713 
0714   /// Remove the specified attribute at the return value index from this
0715   /// attribute list. Returns a new list because attribute lists are immutable.
0716   [[nodiscard]] AttributeList removeRetAttribute(LLVMContext &C,
0717                                                  StringRef Kind) const {
0718     return removeAttributeAtIndex(C, ReturnIndex, Kind);
0719   }
0720 
0721   /// Remove the specified attribute at the return value index from this
0722   /// attribute list. Returns a new list because attribute lists are immutable.
0723   [[nodiscard]] AttributeList
0724   removeRetAttributes(LLVMContext &C,
0725                       const AttributeMask &AttrsToRemove) const {
0726     return removeAttributesAtIndex(C, ReturnIndex, AttrsToRemove);
0727   }
0728 
0729   /// Remove the specified attribute at the specified arg index from this
0730   /// attribute list. Returns a new list because attribute lists are immutable.
0731   [[nodiscard]] AttributeList
0732   removeParamAttribute(LLVMContext &C, unsigned ArgNo,
0733                        Attribute::AttrKind Kind) const {
0734     return removeAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind);
0735   }
0736 
0737   /// Remove the specified attribute at the specified arg index from this
0738   /// attribute list. Returns a new list because attribute lists are immutable.
0739   [[nodiscard]] AttributeList
0740   removeParamAttribute(LLVMContext &C, unsigned ArgNo, StringRef Kind) const {
0741     return removeAttributeAtIndex(C, ArgNo + FirstArgIndex, Kind);
0742   }
0743 
0744   /// Remove the specified attribute at the specified arg index from this
0745   /// attribute list. Returns a new list because attribute lists are immutable.
0746   [[nodiscard]] AttributeList
0747   removeParamAttributes(LLVMContext &C, unsigned ArgNo,
0748                         const AttributeMask &AttrsToRemove) const {
0749     return removeAttributesAtIndex(C, ArgNo + FirstArgIndex, AttrsToRemove);
0750   }
0751 
0752   /// Remove all attributes at the specified arg index from this
0753   /// attribute list. Returns a new list because attribute lists are immutable.
0754   [[nodiscard]] AttributeList removeParamAttributes(LLVMContext &C,
0755                                                     unsigned ArgNo) const {
0756     return removeAttributesAtIndex(C, ArgNo + FirstArgIndex);
0757   }
0758 
0759   /// Replace the type contained by attribute \p AttrKind at index \p ArgNo wih
0760   /// \p ReplacementTy, preserving all other attributes.
0761   [[nodiscard]] AttributeList
0762   replaceAttributeTypeAtIndex(LLVMContext &C, unsigned ArgNo,
0763                               Attribute::AttrKind Kind,
0764                               Type *ReplacementTy) const {
0765     Attribute Attr = getAttributeAtIndex(ArgNo, Kind);
0766     auto Attrs = removeAttributeAtIndex(C, ArgNo, Kind);
0767     return Attrs.addAttributeAtIndex(C, ArgNo,
0768                                      Attr.getWithNewType(C, ReplacementTy));
0769   }
0770 
0771   /// \brief Add the dereferenceable attribute to the attribute set at the given
0772   /// index. Returns a new list because attribute lists are immutable.
0773   [[nodiscard]] AttributeList addDereferenceableRetAttr(LLVMContext &C,
0774                                                         uint64_t Bytes) const;
0775 
0776   /// \brief Add the dereferenceable attribute to the attribute set at the given
0777   /// arg index. Returns a new list because attribute lists are immutable.
0778   [[nodiscard]] AttributeList addDereferenceableParamAttr(LLVMContext &C,
0779                                                           unsigned ArgNo,
0780                                                           uint64_t Bytes) const;
0781 
0782   /// Add the dereferenceable_or_null attribute to the attribute set at
0783   /// the given arg index. Returns a new list because attribute lists are
0784   /// immutable.
0785   [[nodiscard]] AttributeList
0786   addDereferenceableOrNullParamAttr(LLVMContext &C, unsigned ArgNo,
0787                                     uint64_t Bytes) const;
0788 
0789   /// Add the range attribute to the attribute set at the return value index.
0790   /// Returns a new list because attribute lists are immutable.
0791   [[nodiscard]] AttributeList addRangeRetAttr(LLVMContext &C,
0792                                               const ConstantRange &CR) const;
0793 
0794   /// Add the allocsize attribute to the attribute set at the given arg index.
0795   /// Returns a new list because attribute lists are immutable.
0796   [[nodiscard]] AttributeList
0797   addAllocSizeParamAttr(LLVMContext &C, unsigned ArgNo, unsigned ElemSizeArg,
0798                         const std::optional<unsigned> &NumElemsArg) const;
0799 
0800   /// Try to intersect this AttributeList with Other. Returns std::nullopt if
0801   /// the two lists are inherently incompatible (imply different behavior, not
0802   /// just analysis).
0803   [[nodiscard]] std::optional<AttributeList>
0804   intersectWith(LLVMContext &C, AttributeList Other) const;
0805 
0806   //===--------------------------------------------------------------------===//
0807   // AttributeList Accessors
0808   //===--------------------------------------------------------------------===//
0809 
0810   /// The attributes for the specified index are returned.
0811   AttributeSet getAttributes(unsigned Index) const;
0812 
0813   /// The attributes for the argument or parameter at the given index are
0814   /// returned.
0815   AttributeSet getParamAttrs(unsigned ArgNo) const;
0816 
0817   /// The attributes for the ret value are returned.
0818   AttributeSet getRetAttrs() const;
0819 
0820   /// The function attributes are returned.
0821   AttributeSet getFnAttrs() const;
0822 
0823   /// Return true if the attribute exists at the given index.
0824   bool hasAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const;
0825 
0826   /// Return true if the attribute exists at the given index.
0827   bool hasAttributeAtIndex(unsigned Index, StringRef Kind) const;
0828 
0829   /// Return true if attribute exists at the given index.
0830   bool hasAttributesAtIndex(unsigned Index) const;
0831 
0832   /// Return true if the attribute exists for the given argument
0833   bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
0834     return hasAttributeAtIndex(ArgNo + FirstArgIndex, Kind);
0835   }
0836 
0837   /// Return true if the attribute exists for the given argument
0838   bool hasParamAttr(unsigned ArgNo, StringRef Kind) const {
0839     return hasAttributeAtIndex(ArgNo + FirstArgIndex, Kind);
0840   }
0841 
0842   /// Return true if attributes exists for the given argument
0843   bool hasParamAttrs(unsigned ArgNo) const {
0844     return hasAttributesAtIndex(ArgNo + FirstArgIndex);
0845   }
0846 
0847   /// Return true if the attribute exists for the return value.
0848   bool hasRetAttr(Attribute::AttrKind Kind) const {
0849     return hasAttributeAtIndex(ReturnIndex, Kind);
0850   }
0851 
0852   /// Return true if the attribute exists for the return value.
0853   bool hasRetAttr(StringRef Kind) const {
0854     return hasAttributeAtIndex(ReturnIndex, Kind);
0855   }
0856 
0857   /// Return true if attributes exist for the return value.
0858   bool hasRetAttrs() const { return hasAttributesAtIndex(ReturnIndex); }
0859 
0860   /// Return true if the attribute exists for the function.
0861   bool hasFnAttr(Attribute::AttrKind Kind) const;
0862 
0863   /// Return true if the attribute exists for the function.
0864   bool hasFnAttr(StringRef Kind) const;
0865 
0866   /// Return true the attributes exist for the function.
0867   bool hasFnAttrs() const { return hasAttributesAtIndex(FunctionIndex); }
0868 
0869   /// Return true if the specified attribute is set for at least one
0870   /// parameter or for the return value. If Index is not nullptr, the index
0871   /// of a parameter with the specified attribute is provided.
0872   bool hasAttrSomewhere(Attribute::AttrKind Kind,
0873                         unsigned *Index = nullptr) const;
0874 
0875   /// Return the attribute object that exists at the given index.
0876   Attribute getAttributeAtIndex(unsigned Index, Attribute::AttrKind Kind) const;
0877 
0878   /// Return the attribute object that exists at the given index.
0879   Attribute getAttributeAtIndex(unsigned Index, StringRef Kind) const;
0880 
0881   /// Return the attribute object that exists at the arg index.
0882   Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const {
0883     return getAttributeAtIndex(ArgNo + FirstArgIndex, Kind);
0884   }
0885 
0886   /// Return the attribute object that exists at the given index.
0887   Attribute getParamAttr(unsigned ArgNo, StringRef Kind) const {
0888     return getAttributeAtIndex(ArgNo + FirstArgIndex, Kind);
0889   }
0890 
0891   /// Return the attribute object that exists for the function.
0892   Attribute getFnAttr(Attribute::AttrKind Kind) const {
0893     return getAttributeAtIndex(FunctionIndex, Kind);
0894   }
0895 
0896   /// Return the attribute object that exists for the function.
0897   Attribute getFnAttr(StringRef Kind) const {
0898     return getAttributeAtIndex(FunctionIndex, Kind);
0899   }
0900 
0901   /// Return the attribute for the given attribute kind for the return value.
0902   Attribute getRetAttr(Attribute::AttrKind Kind) const {
0903     return getAttributeAtIndex(ReturnIndex, Kind);
0904   }
0905 
0906   /// Return the alignment of the return value.
0907   MaybeAlign getRetAlignment() const;
0908 
0909   /// Return the alignment for the specified function parameter.
0910   MaybeAlign getParamAlignment(unsigned ArgNo) const;
0911 
0912   /// Return the stack alignment for the specified function parameter.
0913   MaybeAlign getParamStackAlignment(unsigned ArgNo) const;
0914 
0915   /// Return the byval type for the specified function parameter.
0916   Type *getParamByValType(unsigned ArgNo) const;
0917 
0918   /// Return the sret type for the specified function parameter.
0919   Type *getParamStructRetType(unsigned ArgNo) const;
0920 
0921   /// Return the byref type for the specified function parameter.
0922   Type *getParamByRefType(unsigned ArgNo) const;
0923 
0924   /// Return the preallocated type for the specified function parameter.
0925   Type *getParamPreallocatedType(unsigned ArgNo) const;
0926 
0927   /// Return the inalloca type for the specified function parameter.
0928   Type *getParamInAllocaType(unsigned ArgNo) const;
0929 
0930   /// Return the elementtype type for the specified function parameter.
0931   Type *getParamElementType(unsigned ArgNo) const;
0932 
0933   /// Get the stack alignment of the function.
0934   MaybeAlign getFnStackAlignment() const;
0935 
0936   /// Get the stack alignment of the return value.
0937   MaybeAlign getRetStackAlignment() const;
0938 
0939   /// Get the number of dereferenceable bytes (or zero if unknown) of the return
0940   /// value.
0941   uint64_t getRetDereferenceableBytes() const;
0942 
0943   /// Get the number of dereferenceable bytes (or zero if unknown) of an arg.
0944   uint64_t getParamDereferenceableBytes(unsigned Index) const;
0945 
0946   /// Get the number of dereferenceable_or_null bytes (or zero if unknown) of
0947   /// the return value.
0948   uint64_t getRetDereferenceableOrNullBytes() const;
0949 
0950   /// Get the number of dereferenceable_or_null bytes (or zero if unknown) of an
0951   /// arg.
0952   uint64_t getParamDereferenceableOrNullBytes(unsigned ArgNo) const;
0953 
0954   /// Get range (or std::nullopt if unknown) of an arg.
0955   std::optional<ConstantRange> getParamRange(unsigned ArgNo) const;
0956 
0957   /// Get the disallowed floating-point classes of the return value.
0958   FPClassTest getRetNoFPClass() const;
0959 
0960   /// Get the disallowed floating-point classes of the argument value.
0961   FPClassTest getParamNoFPClass(unsigned ArgNo) const;
0962 
0963   /// Get the unwind table kind requested for the function.
0964   UWTableKind getUWTableKind() const;
0965 
0966   AllocFnKind getAllocKind() const;
0967 
0968   /// Returns memory effects of the function.
0969   MemoryEffects getMemoryEffects() const;
0970 
0971   /// Return the attributes at the index as a string.
0972   std::string getAsString(unsigned Index, bool InAttrGrp = false) const;
0973 
0974   /// Return true if this attribute list belongs to the LLVMContext.
0975   bool hasParentContext(LLVMContext &C) const;
0976 
0977   //===--------------------------------------------------------------------===//
0978   // AttributeList Introspection
0979   //===--------------------------------------------------------------------===//
0980 
0981   using iterator = const AttributeSet *;
0982 
0983   iterator begin() const;
0984   iterator end() const;
0985 
0986   unsigned getNumAttrSets() const;
0987 
0988   // Implementation of indexes(). Produces iterators that wrap an index. Mostly
0989   // to hide the awkwardness of unsigned wrapping when iterating over valid
0990   // indexes.
0991   struct index_iterator {
0992     unsigned NumAttrSets;
0993     index_iterator(int NumAttrSets) : NumAttrSets(NumAttrSets) {}
0994     struct int_wrapper {
0995       int_wrapper(unsigned i) : i(i) {}
0996       unsigned i;
0997       unsigned operator*() { return i; }
0998       bool operator!=(const int_wrapper &Other) { return i != Other.i; }
0999       int_wrapper &operator++() {
1000         // This is expected to undergo unsigned wrapping since FunctionIndex is
1001         // ~0 and that's where we start.
1002         ++i;
1003         return *this;
1004       }
1005     };
1006 
1007     int_wrapper begin() { return int_wrapper(AttributeList::FunctionIndex); }
1008 
1009     int_wrapper end() { return int_wrapper(NumAttrSets - 1); }
1010   };
1011 
1012   /// Use this to iterate over the valid attribute indexes.
1013   index_iterator indexes() const { return index_iterator(getNumAttrSets()); }
1014 
1015   /// operator==/!= - Provide equality predicates.
1016   bool operator==(const AttributeList &RHS) const { return pImpl == RHS.pImpl; }
1017   bool operator!=(const AttributeList &RHS) const { return pImpl != RHS.pImpl; }
1018 
1019   /// Return a raw pointer that uniquely identifies this attribute list.
1020   void *getRawPointer() const {
1021     return pImpl;
1022   }
1023 
1024   /// Return true if there are no attributes.
1025   bool isEmpty() const { return pImpl == nullptr; }
1026 
1027   void print(raw_ostream &O) const;
1028 
1029   void dump() const;
1030 };
1031 
1032 //===----------------------------------------------------------------------===//
1033 /// \class
1034 /// Provide DenseMapInfo for AttributeList.
1035 template <> struct DenseMapInfo<AttributeList, void> {
1036   static AttributeList getEmptyKey() {
1037     auto Val = static_cast<uintptr_t>(-1);
1038     Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable;
1039     return AttributeList(reinterpret_cast<AttributeListImpl *>(Val));
1040   }
1041 
1042   static AttributeList getTombstoneKey() {
1043     auto Val = static_cast<uintptr_t>(-2);
1044     Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable;
1045     return AttributeList(reinterpret_cast<AttributeListImpl *>(Val));
1046   }
1047 
1048   static unsigned getHashValue(AttributeList AS) {
1049     return (unsigned((uintptr_t)AS.pImpl) >> 4) ^
1050            (unsigned((uintptr_t)AS.pImpl) >> 9);
1051   }
1052 
1053   static bool isEqual(AttributeList LHS, AttributeList RHS) {
1054     return LHS == RHS;
1055   }
1056 };
1057 
1058 //===----------------------------------------------------------------------===//
1059 /// \class
1060 /// This class is used in conjunction with the Attribute::get method to
1061 /// create an Attribute object. The object itself is uniquified. The Builder's
1062 /// value, however, is not. So this can be used as a quick way to test for
1063 /// equality, presence of attributes, etc.
1064 class AttrBuilder {
1065   LLVMContext &Ctx;
1066   SmallVector<Attribute, 8> Attrs;
1067 
1068 public:
1069   AttrBuilder(LLVMContext &Ctx) : Ctx(Ctx) {}
1070   AttrBuilder(const AttrBuilder &) = delete;
1071   AttrBuilder(AttrBuilder &&) = default;
1072 
1073   AttrBuilder(LLVMContext &Ctx, const Attribute &A) : Ctx(Ctx) {
1074     addAttribute(A);
1075   }
1076 
1077   AttrBuilder(LLVMContext &Ctx, AttributeSet AS);
1078 
1079   void clear();
1080 
1081   /// Add an attribute to the builder.
1082   AttrBuilder &addAttribute(Attribute::AttrKind Val);
1083 
1084   /// Add the Attribute object to the builder.
1085   AttrBuilder &addAttribute(Attribute A);
1086 
1087   /// Add the target-dependent attribute to the builder.
1088   AttrBuilder &addAttribute(StringRef A, StringRef V = StringRef());
1089 
1090   /// Remove an attribute from the builder.
1091   AttrBuilder &removeAttribute(Attribute::AttrKind Val);
1092 
1093   /// Remove the target-dependent attribute from the builder.
1094   AttrBuilder &removeAttribute(StringRef A);
1095 
1096   /// Remove the target-dependent attribute from the builder.
1097   AttrBuilder &removeAttribute(Attribute A) {
1098     if (A.isStringAttribute())
1099       return removeAttribute(A.getKindAsString());
1100     else
1101       return removeAttribute(A.getKindAsEnum());
1102   }
1103 
1104   /// Add the attributes from the builder. Attributes in the passed builder
1105   /// overwrite attributes in this builder if they have the same key.
1106   AttrBuilder &merge(const AttrBuilder &B);
1107 
1108   /// Remove the attributes from the builder.
1109   AttrBuilder &remove(const AttributeMask &AM);
1110 
1111   /// Return true if the builder has any attribute that's in the
1112   /// specified builder.
1113   bool overlaps(const AttributeMask &AM) const;
1114 
1115   /// Return true if the builder has the specified attribute.
1116   bool contains(Attribute::AttrKind A) const;
1117 
1118   /// Return true if the builder has the specified target-dependent
1119   /// attribute.
1120   bool contains(StringRef A) const;
1121 
1122   /// Return true if the builder has IR-level attributes.
1123   bool hasAttributes() const { return !Attrs.empty(); }
1124 
1125   /// Return Attribute with the given Kind. The returned attribute will be
1126   /// invalid if the Kind is not present in the builder.
1127   Attribute getAttribute(Attribute::AttrKind Kind) const;
1128 
1129   /// Return Attribute with the given Kind. The returned attribute will be
1130   /// invalid if the Kind is not present in the builder.
1131   Attribute getAttribute(StringRef Kind) const;
1132 
1133   /// Retrieve the range if the attribute exists (std::nullopt is returned
1134   /// otherwise).
1135   std::optional<ConstantRange> getRange() const;
1136 
1137   /// Return raw (possibly packed/encoded) value of integer attribute or
1138   /// std::nullopt if not set.
1139   std::optional<uint64_t> getRawIntAttr(Attribute::AttrKind Kind) const;
1140 
1141   /// Retrieve the alignment attribute, if it exists.
1142   MaybeAlign getAlignment() const {
1143     return MaybeAlign(getRawIntAttr(Attribute::Alignment).value_or(0));
1144   }
1145 
1146   /// Retrieve the stack alignment attribute, if it exists.
1147   MaybeAlign getStackAlignment() const {
1148     return MaybeAlign(getRawIntAttr(Attribute::StackAlignment).value_or(0));
1149   }
1150 
1151   /// Retrieve the number of dereferenceable bytes, if the
1152   /// dereferenceable attribute exists (zero is returned otherwise).
1153   uint64_t getDereferenceableBytes() const {
1154     return getRawIntAttr(Attribute::Dereferenceable).value_or(0);
1155   }
1156 
1157   /// Retrieve the number of dereferenceable_or_null bytes, if the
1158   /// dereferenceable_or_null attribute exists (zero is returned otherwise).
1159   uint64_t getDereferenceableOrNullBytes() const {
1160     return getRawIntAttr(Attribute::DereferenceableOrNull).value_or(0);
1161   }
1162 
1163   /// Retrieve type for the given type attribute.
1164   Type *getTypeAttr(Attribute::AttrKind Kind) const;
1165 
1166   /// Retrieve the byval type.
1167   Type *getByValType() const { return getTypeAttr(Attribute::ByVal); }
1168 
1169   /// Retrieve the sret type.
1170   Type *getStructRetType() const { return getTypeAttr(Attribute::StructRet); }
1171 
1172   /// Retrieve the byref type.
1173   Type *getByRefType() const { return getTypeAttr(Attribute::ByRef); }
1174 
1175   /// Retrieve the preallocated type.
1176   Type *getPreallocatedType() const {
1177     return getTypeAttr(Attribute::Preallocated);
1178   }
1179 
1180   /// Retrieve the inalloca type.
1181   Type *getInAllocaType() const { return getTypeAttr(Attribute::InAlloca); }
1182 
1183   /// Retrieve the allocsize args, or std::nullopt if the attribute does not
1184   /// exist.
1185   std::optional<std::pair<unsigned, std::optional<unsigned>>> getAllocSizeArgs()
1186       const;
1187 
1188   /// Add integer attribute with raw value (packed/encoded if necessary).
1189   AttrBuilder &addRawIntAttr(Attribute::AttrKind Kind, uint64_t Value);
1190 
1191   /// This turns an alignment into the form used internally in Attribute.
1192   /// This call has no effect if Align is not set.
1193   AttrBuilder &addAlignmentAttr(MaybeAlign Align);
1194 
1195   /// This turns an int alignment (which must be a power of 2) into the
1196   /// form used internally in Attribute.
1197   /// This call has no effect if Align is 0.
1198   /// Deprecated, use the version using a MaybeAlign.
1199   inline AttrBuilder &addAlignmentAttr(unsigned Align) {
1200     return addAlignmentAttr(MaybeAlign(Align));
1201   }
1202 
1203   /// This turns a stack alignment into the form used internally in Attribute.
1204   /// This call has no effect if Align is not set.
1205   AttrBuilder &addStackAlignmentAttr(MaybeAlign Align);
1206 
1207   /// This turns an int stack alignment (which must be a power of 2) into
1208   /// the form used internally in Attribute.
1209   /// This call has no effect if Align is 0.
1210   /// Deprecated, use the version using a MaybeAlign.
1211   inline AttrBuilder &addStackAlignmentAttr(unsigned Align) {
1212     return addStackAlignmentAttr(MaybeAlign(Align));
1213   }
1214 
1215   /// This turns the number of dereferenceable bytes into the form used
1216   /// internally in Attribute.
1217   AttrBuilder &addDereferenceableAttr(uint64_t Bytes);
1218 
1219   /// This turns the number of dereferenceable_or_null bytes into the
1220   /// form used internally in Attribute.
1221   AttrBuilder &addDereferenceableOrNullAttr(uint64_t Bytes);
1222 
1223   /// This turns one (or two) ints into the form used internally in Attribute.
1224   AttrBuilder &addAllocSizeAttr(unsigned ElemSizeArg,
1225                                 const std::optional<unsigned> &NumElemsArg);
1226 
1227   /// This turns two ints into the form used internally in Attribute.
1228   AttrBuilder &addVScaleRangeAttr(unsigned MinValue,
1229                                   std::optional<unsigned> MaxValue);
1230 
1231   /// Add a type attribute with the given type.
1232   AttrBuilder &addTypeAttr(Attribute::AttrKind Kind, Type *Ty);
1233 
1234   /// This turns a byval type into the form used internally in Attribute.
1235   AttrBuilder &addByValAttr(Type *Ty);
1236 
1237   /// This turns a sret type into the form used internally in Attribute.
1238   AttrBuilder &addStructRetAttr(Type *Ty);
1239 
1240   /// This turns a byref type into the form used internally in Attribute.
1241   AttrBuilder &addByRefAttr(Type *Ty);
1242 
1243   /// This turns a preallocated type into the form used internally in Attribute.
1244   AttrBuilder &addPreallocatedAttr(Type *Ty);
1245 
1246   /// This turns an inalloca type into the form used internally in Attribute.
1247   AttrBuilder &addInAllocaAttr(Type *Ty);
1248 
1249   /// Add an allocsize attribute, using the representation returned by
1250   /// Attribute.getIntValue().
1251   AttrBuilder &addAllocSizeAttrFromRawRepr(uint64_t RawAllocSizeRepr);
1252 
1253   /// Add a vscale_range attribute, using the representation returned by
1254   /// Attribute.getIntValue().
1255   AttrBuilder &addVScaleRangeAttrFromRawRepr(uint64_t RawVScaleRangeRepr);
1256 
1257   /// This turns the unwind table kind into the form used internally in
1258   /// Attribute.
1259   AttrBuilder &addUWTableAttr(UWTableKind Kind);
1260 
1261   // This turns the allocator kind into the form used internally in Attribute.
1262   AttrBuilder &addAllocKindAttr(AllocFnKind Kind);
1263 
1264   /// Add memory effect attribute.
1265   AttrBuilder &addMemoryAttr(MemoryEffects ME);
1266 
1267   /// Add captures attribute.
1268   AttrBuilder &addCapturesAttr(CaptureInfo CI);
1269 
1270   // Add nofpclass attribute
1271   AttrBuilder &addNoFPClassAttr(FPClassTest NoFPClassMask);
1272 
1273   /// Add a ConstantRange attribute with the given range.
1274   AttrBuilder &addConstantRangeAttr(Attribute::AttrKind Kind,
1275                                     const ConstantRange &CR);
1276 
1277   /// Add range attribute.
1278   AttrBuilder &addRangeAttr(const ConstantRange &CR);
1279 
1280   /// Add a ConstantRangeList attribute with the given ranges.
1281   AttrBuilder &addConstantRangeListAttr(Attribute::AttrKind Kind,
1282                                         ArrayRef<ConstantRange> Val);
1283 
1284   /// Add initializes attribute.
1285   AttrBuilder &addInitializesAttr(const ConstantRangeList &CRL);
1286 
1287   ArrayRef<Attribute> attrs() const { return Attrs; }
1288 
1289   bool operator==(const AttrBuilder &B) const;
1290   bool operator!=(const AttrBuilder &B) const { return !(*this == B); }
1291 };
1292 
1293 namespace AttributeFuncs {
1294 
1295 enum AttributeSafetyKind : uint8_t {
1296   ASK_SAFE_TO_DROP = 1,
1297   ASK_UNSAFE_TO_DROP = 2,
1298   ASK_ALL = ASK_SAFE_TO_DROP | ASK_UNSAFE_TO_DROP,
1299 };
1300 
1301 /// Returns true if this is a type legal for the 'nofpclass' attribute. This
1302 /// follows the same type rules as FPMathOperator.
1303 bool isNoFPClassCompatibleType(Type *Ty);
1304 
1305 /// Which attributes cannot be applied to a type. The argument \p AS
1306 /// is used as a hint for the attributes whose compatibility is being
1307 /// checked against \p Ty. This does not mean the return will be a
1308 /// subset of \p AS, just that attributes that have specific dynamic
1309 /// type compatibilities (i.e `range`) will be checked against what is
1310 /// contained in \p AS. The argument \p ASK indicates, if only
1311 /// attributes that are known to be safely droppable are contained in
1312 /// the mask; only attributes that might be unsafe to drop (e.g.,
1313 /// ABI-related attributes) are in the mask; or both.
1314 AttributeMask typeIncompatible(Type *Ty, AttributeSet AS,
1315                                AttributeSafetyKind ASK = ASK_ALL);
1316 
1317 /// Get param/return attributes which imply immediate undefined behavior if an
1318 /// invalid value is passed. For example, this includes noundef (where undef
1319 /// implies UB), but not nonnull (where null implies poison). It also does not
1320 /// include attributes like nocapture, which constrain the function
1321 /// implementation rather than the passed value.
1322 AttributeMask getUBImplyingAttributes();
1323 
1324 /// \returns Return true if the two functions have compatible target-independent
1325 /// attributes for inlining purposes.
1326 bool areInlineCompatible(const Function &Caller, const Function &Callee);
1327 
1328 
1329 /// Checks  if there are any incompatible function attributes between
1330 /// \p A and \p B.
1331 ///
1332 /// \param [in] A - The first function to be compared with.
1333 /// \param [in] B - The second function to be compared with.
1334 /// \returns true if the functions have compatible attributes.
1335 bool areOutlineCompatible(const Function &A, const Function &B);
1336 
1337 /// Merge caller's and callee's attributes.
1338 void mergeAttributesForInlining(Function &Caller, const Function &Callee);
1339 
1340 /// Merges the functions attributes from \p ToMerge into function \p Base.
1341 ///
1342 /// \param [in,out] Base - The function being merged into.
1343 /// \param [in] ToMerge - The function to merge attributes from.
1344 void mergeAttributesForOutlining(Function &Base, const Function &ToMerge);
1345 
1346 /// Update min-legal-vector-width if it is in Attribute and less than Width.
1347 void updateMinLegalVectorWidthAttr(Function &Fn, uint64_t Width);
1348 
1349 } // end namespace AttributeFuncs
1350 
1351 } // end namespace llvm
1352 
1353 #endif // LLVM_IR_ATTRIBUTES_H