diff options
Diffstat (limited to 'include/llvm/IR/Attributes.h')
-rw-r--r-- | include/llvm/IR/Attributes.h | 294 |
1 files changed, 199 insertions, 95 deletions
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index 15783858dd322..121f57a433acb 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -1,4 +1,4 @@ -//===-- llvm/Attributes.h - Container for Attributes ------------*- C++ -*-===// +//===- llvm/Attributes.h - Container for Attributes -------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -18,22 +18,24 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/Optional.h" -#include "llvm/Support/Compiler.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/PointerLikeTypeTraits.h" #include "llvm-c/Types.h" #include <bitset> #include <cassert> +#include <cstdint> #include <map> #include <string> +#include <utility> namespace llvm { class AttrBuilder; class AttributeImpl; -class AttributeSetImpl; +class AttributeListImpl; class AttributeSetNode; -class Constant; template<typename T> struct DenseMapInfo; class Function; class LLVMContext; @@ -73,11 +75,12 @@ public: }; private: - AttributeImpl *pImpl; + AttributeImpl *pImpl = nullptr; + Attribute(AttributeImpl *A) : pImpl(A) {} public: - Attribute() : pImpl(nullptr) {} + Attribute() = default; //===--------------------------------------------------------------------===// // Attribute Construction @@ -194,13 +197,91 @@ inline Attribute unwrap(LLVMAttributeRef Attr) { //===----------------------------------------------------------------------===// /// \class +/// This class holds the attributes for a particular argument, parameter, +/// function, or return value. It is an immutable value type that is cheap to +/// copy. Adding and removing enum attributes is intended to be fast, but adding +/// and removing string or integer attributes involves a FoldingSet lookup. +class AttributeSet { + // TODO: Extract AvailableAttrs from AttributeSetNode and store them here. + // This will allow an efficient implementation of addAttribute and + // removeAttribute for enum attrs. + + /// Private implementation pointer. + AttributeSetNode *SetNode = nullptr; + + friend AttributeListImpl; + template <typename Ty> friend struct DenseMapInfo; + +private: + explicit AttributeSet(AttributeSetNode *ASN) : SetNode(ASN) {} + +public: + /// AttributeSet is a trivially copyable value type. + AttributeSet() = default; + AttributeSet(const AttributeSet &) = default; + ~AttributeSet() = default; + + static AttributeSet get(LLVMContext &C, const AttrBuilder &B); + static AttributeSet get(LLVMContext &C, ArrayRef<Attribute> Attrs); + + bool operator==(const AttributeSet &O) { return SetNode == O.SetNode; } + bool operator!=(const AttributeSet &O) { return !(*this == O); } + + unsigned getNumAttributes() const; + + bool hasAttributes() const { return SetNode != nullptr; } + + bool hasAttribute(Attribute::AttrKind Kind) const; + bool hasAttribute(StringRef Kind) const; + + Attribute getAttribute(Attribute::AttrKind Kind) const; + Attribute getAttribute(StringRef Kind) const; + + unsigned getAlignment() const; + unsigned getStackAlignment() const; + uint64_t getDereferenceableBytes() const; + uint64_t getDereferenceableOrNullBytes() const; + std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const; + std::string getAsString(bool InAttrGrp = false) const; + + typedef const Attribute *iterator; + iterator begin() const; + iterator end() const; +}; + +//===----------------------------------------------------------------------===// +/// \class +/// \brief Provide DenseMapInfo for AttributeSet. +template <> struct DenseMapInfo<AttributeSet> { + static inline AttributeSet getEmptyKey() { + uintptr_t Val = static_cast<uintptr_t>(-1); + Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable; + return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val)); + } + + static inline AttributeSet getTombstoneKey() { + uintptr_t Val = static_cast<uintptr_t>(-2); + Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable; + return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val)); + } + + static unsigned getHashValue(AttributeSet AS) { + return (unsigned((uintptr_t)AS.SetNode) >> 4) ^ + (unsigned((uintptr_t)AS.SetNode) >> 9); + } + + static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; } +}; + +//===----------------------------------------------------------------------===// +/// \class /// \brief This class holds the attributes for a function, its return value, and /// its parameters. You access the attributes for each of them via an index into -/// the AttributeSet object. The function attributes are at index -/// `AttributeSet::FunctionIndex', the return value is at index -/// `AttributeSet::ReturnIndex', and the attributes for the parameters start at +/// the AttributeList object. The function attributes are at index +/// `AttributeList::FunctionIndex', the return value is at index +/// `AttributeList::ReturnIndex', and the attributes for the parameters start at /// index `1'. -class AttributeSet { +class AttributeList { public: enum AttrIndex : unsigned { ReturnIndex = 0U, @@ -209,115 +290,137 @@ public: private: friend class AttrBuilder; - friend class AttributeSetImpl; + friend class AttributeListImpl; + friend class AttributeSet; friend class AttributeSetNode; + template <typename Ty> friend struct DenseMapInfo; /// \brief The attributes that we are managing. This can be null to represent /// the empty attributes list. - AttributeSetImpl *pImpl; - - /// \brief The attributes for the specified index are returned. - AttributeSetNode *getAttributes(unsigned Index) const; - - /// \brief Create an AttributeSet with the specified parameters in it. - static AttributeSet get(LLVMContext &C, - ArrayRef<std::pair<unsigned, Attribute> > Attrs); - static AttributeSet get(LLVMContext &C, - ArrayRef<std::pair<unsigned, - AttributeSetNode*> > Attrs); + AttributeListImpl *pImpl = nullptr; - static AttributeSet getImpl(LLVMContext &C, - ArrayRef<std::pair<unsigned, - AttributeSetNode*> > Attrs); +public: + /// \brief Create an AttributeList with the specified parameters in it. + static AttributeList get(LLVMContext &C, + ArrayRef<std::pair<unsigned, Attribute>> Attrs); + static AttributeList + get(LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSet>> Attrs); + + /// \brief Create an AttributeList from attribute sets for a function, its + /// return value, and all of its arguments. + static AttributeList get(LLVMContext &C, AttributeSet FnAttrs, + AttributeSet RetAttrs, + ArrayRef<AttributeSet> ArgAttrs); + + static AttributeList + getImpl(LLVMContext &C, + ArrayRef<std::pair<unsigned, AttributeSet>> Attrs); - explicit AttributeSet(AttributeSetImpl *LI) : pImpl(LI) {} +private: + explicit AttributeList(AttributeListImpl *LI) : pImpl(LI) {} public: - AttributeSet() : pImpl(nullptr) {} + AttributeList() = default; //===--------------------------------------------------------------------===// - // AttributeSet Construction and Mutation + // AttributeList Construction and Mutation //===--------------------------------------------------------------------===// - /// \brief Return an AttributeSet with the specified parameters in it. - static AttributeSet get(LLVMContext &C, ArrayRef<AttributeSet> Attrs); - static AttributeSet get(LLVMContext &C, unsigned Index, - ArrayRef<Attribute::AttrKind> Kinds); - static AttributeSet get(LLVMContext &C, unsigned Index, - ArrayRef<StringRef> Kind); - static AttributeSet get(LLVMContext &C, unsigned Index, const AttrBuilder &B); + /// \brief Return an AttributeList with the specified parameters in it. + static AttributeList get(LLVMContext &C, ArrayRef<AttributeList> Attrs); + static AttributeList get(LLVMContext &C, unsigned Index, + ArrayRef<Attribute::AttrKind> Kinds); + static AttributeList get(LLVMContext &C, unsigned Index, + ArrayRef<StringRef> Kind); + static AttributeList get(LLVMContext &C, unsigned Index, + const AttrBuilder &B); /// \brief Add an attribute to the attribute set at the given index. Because /// attribute sets are immutable, this returns a new set. - AttributeSet addAttribute(LLVMContext &C, unsigned Index, - Attribute::AttrKind Kind) const; + AttributeList addAttribute(LLVMContext &C, unsigned Index, + Attribute::AttrKind Kind) const; /// \brief Add an attribute to the attribute set at the given index. Because /// attribute sets are immutable, this returns a new set. - AttributeSet addAttribute(LLVMContext &C, unsigned Index, StringRef Kind, - StringRef Value = StringRef()) const; + AttributeList addAttribute(LLVMContext &C, unsigned Index, StringRef Kind, + StringRef Value = StringRef()) const; /// Add an attribute to the attribute set at the given indices. Because /// attribute sets are immutable, this returns a new set. - AttributeSet addAttribute(LLVMContext &C, ArrayRef<unsigned> Indices, - Attribute A) const; + AttributeList addAttribute(LLVMContext &C, ArrayRef<unsigned> Indices, + Attribute A) const; /// \brief Add attributes to the attribute set at the given index. Because /// attribute sets are immutable, this returns a new set. - AttributeSet addAttributes(LLVMContext &C, unsigned Index, - AttributeSet Attrs) const; + AttributeList addAttributes(LLVMContext &C, unsigned Index, + AttributeList Attrs) const; + + AttributeList addAttributes(LLVMContext &C, unsigned Index, + AttributeSet AS) const; + + AttributeList addAttributes(LLVMContext &C, unsigned Index, + const AttrBuilder &B) const; /// \brief Remove the specified attribute at the specified index from this /// attribute list. Because attribute lists are immutable, this returns the /// new list. - AttributeSet removeAttribute(LLVMContext &C, unsigned Index, - Attribute::AttrKind Kind) const; + AttributeList removeAttribute(LLVMContext &C, unsigned Index, + Attribute::AttrKind Kind) const; /// \brief Remove the specified attribute at the specified index from this /// attribute list. Because attribute lists are immutable, this returns the /// new list. - AttributeSet removeAttribute(LLVMContext &C, unsigned Index, - StringRef Kind) const; + AttributeList removeAttribute(LLVMContext &C, unsigned Index, + StringRef Kind) const; /// \brief Remove the specified attributes at the specified index from this /// attribute list. Because attribute lists are immutable, this returns the /// new list. - AttributeSet removeAttributes(LLVMContext &C, unsigned Index, - AttributeSet Attrs) const; + AttributeList removeAttributes(LLVMContext &C, unsigned Index, + AttributeList Attrs) const; /// \brief Remove the specified attributes at the specified index from this /// attribute list. Because attribute lists are immutable, this returns the /// new list. - AttributeSet removeAttributes(LLVMContext &C, unsigned Index, - const AttrBuilder &Attrs) const; + AttributeList removeAttributes(LLVMContext &C, unsigned Index, + const AttrBuilder &Attrs) const; + + /// \brief Remove all attributes at the specified index from this + /// attribute list. Because attribute lists are immutable, this returns the + /// new list. + AttributeList removeAttributes(LLVMContext &C, unsigned Index) const; /// \brief Add the dereferenceable attribute to the attribute set at the given /// index. Because attribute sets are immutable, this returns a new set. - AttributeSet addDereferenceableAttr(LLVMContext &C, unsigned Index, - uint64_t Bytes) const; + AttributeList addDereferenceableAttr(LLVMContext &C, unsigned Index, + uint64_t Bytes) const; /// \brief Add the dereferenceable_or_null attribute to the attribute set at /// the given index. Because attribute sets are immutable, this returns a new /// set. - AttributeSet addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index, - uint64_t Bytes) const; + AttributeList addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index, + uint64_t Bytes) const; /// Add the allocsize attribute to the attribute set at the given index. /// Because attribute sets are immutable, this returns a new set. - AttributeSet addAllocSizeAttr(LLVMContext &C, unsigned Index, - unsigned ElemSizeArg, - const Optional<unsigned> &NumElemsArg); + AttributeList addAllocSizeAttr(LLVMContext &C, unsigned Index, + unsigned ElemSizeArg, + const Optional<unsigned> &NumElemsArg); //===--------------------------------------------------------------------===// - // AttributeSet Accessors + // AttributeList Accessors //===--------------------------------------------------------------------===// /// \brief Retrieve the LLVM context. LLVMContext &getContext() const; /// \brief The attributes for the specified index are returned. - AttributeSet getParamAttributes(unsigned Index) const; + AttributeSet getAttributes(unsigned Index) const; + + /// \brief The attributes for the argument or parameter at the given index are + /// returned. + AttributeSet getParamAttributes(unsigned ArgNo) const; /// \brief The attributes for the ret value are returned. AttributeSet getRetAttributes() const; @@ -334,14 +437,17 @@ public: /// \brief Return true if attribute exists at the given index. bool hasAttributes(unsigned Index) const; - /// \brief Equivalent to hasAttribute(AttributeSet::FunctionIndex, Kind) but + /// \brief Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but /// may be faster. bool hasFnAttribute(Attribute::AttrKind Kind) const; - /// \brief Equivalent to hasAttribute(AttributeSet::FunctionIndex, Kind) but + /// \brief Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but /// may be faster. bool hasFnAttribute(StringRef Kind) const; + /// \brief Equivalent to hasAttribute(ArgNo + 1, Kind). + bool hasParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const; + /// \brief Return true if the specified attribute is set for at least one /// parameter or for the return value. If Index is not nullptr, the index /// of a parameter with the specified attribute is provided. @@ -380,15 +486,11 @@ public: iterator end(unsigned Slot) const; /// operator==/!= - Provide equality predicates. - bool operator==(const AttributeSet &RHS) const { - return pImpl == RHS.pImpl; - } - bool operator!=(const AttributeSet &RHS) const { - return pImpl != RHS.pImpl; - } + bool operator==(const AttributeList &RHS) const { return pImpl == RHS.pImpl; } + bool operator!=(const AttributeList &RHS) const { return pImpl != RHS.pImpl; } //===--------------------------------------------------------------------===// - // AttributeSet Introspection + // AttributeList Introspection //===--------------------------------------------------------------------===// /// \brief Return a raw pointer that uniquely identifies this attribute list. @@ -410,30 +512,35 @@ public: unsigned getSlotIndex(unsigned Slot) const; /// \brief Return the attributes at the given slot. - AttributeSet getSlotAttributes(unsigned Slot) const; + AttributeList getSlotAttributes(unsigned Slot) const; void dump() const; }; //===----------------------------------------------------------------------===// /// \class -/// \brief Provide DenseMapInfo for AttributeSet. -template<> struct DenseMapInfo<AttributeSet> { - static inline AttributeSet getEmptyKey() { +/// \brief Provide DenseMapInfo for AttributeList. +template <> struct DenseMapInfo<AttributeList> { + static inline AttributeList getEmptyKey() { uintptr_t Val = static_cast<uintptr_t>(-1); Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable; - return AttributeSet(reinterpret_cast<AttributeSetImpl*>(Val)); + return AttributeList(reinterpret_cast<AttributeListImpl *>(Val)); } - static inline AttributeSet getTombstoneKey() { + + static inline AttributeList getTombstoneKey() { uintptr_t Val = static_cast<uintptr_t>(-2); Val <<= PointerLikeTypeTraits<void*>::NumLowBitsAvailable; - return AttributeSet(reinterpret_cast<AttributeSetImpl*>(Val)); + return AttributeList(reinterpret_cast<AttributeListImpl *>(Val)); } - static unsigned getHashValue(AttributeSet AS) { + + static unsigned getHashValue(AttributeList AS) { return (unsigned((uintptr_t)AS.pImpl) >> 4) ^ (unsigned((uintptr_t)AS.pImpl) >> 9); } - static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; } + + static bool isEqual(AttributeList LHS, AttributeList RHS) { + return LHS == RHS; + } }; //===----------------------------------------------------------------------===// @@ -445,22 +552,19 @@ template<> struct DenseMapInfo<AttributeSet> { class AttrBuilder { std::bitset<Attribute::EndAttrKinds> Attrs; std::map<std::string, std::string> TargetDepAttrs; - uint64_t Alignment; - uint64_t StackAlignment; - uint64_t DerefBytes; - uint64_t DerefOrNullBytes; - uint64_t AllocSizeArgs; + uint64_t Alignment = 0; + uint64_t StackAlignment = 0; + uint64_t DerefBytes = 0; + uint64_t DerefOrNullBytes = 0; + uint64_t AllocSizeArgs = 0; public: - AttrBuilder() - : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0), - DerefOrNullBytes(0), AllocSizeArgs(0) {} - AttrBuilder(const Attribute &A) - : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0), - DerefOrNullBytes(0), AllocSizeArgs(0) { + AttrBuilder() = default; + AttrBuilder(const Attribute &A) { addAttribute(A); } - AttrBuilder(AttributeSet AS, unsigned Idx); + AttrBuilder(AttributeList AS, unsigned Idx); + AttrBuilder(AttributeSet AS); void clear(); @@ -477,7 +581,7 @@ public: AttrBuilder &removeAttribute(Attribute::AttrKind Val); /// \brief Remove the attributes from the builder. - AttrBuilder &removeAttributes(AttributeSet A, uint64_t Index); + AttrBuilder &removeAttributes(AttributeList A, uint64_t WithoutIndex); /// \brief Remove the target-dependent attribute to the builder. AttrBuilder &removeAttribute(StringRef A); @@ -507,7 +611,7 @@ public: /// \brief Return true if the builder has any attribute that's in the /// specified attribute. - bool hasAttributes(AttributeSet A, uint64_t Index) const; + bool hasAttributes(AttributeList A, uint64_t Index) const; /// \brief Return true if the builder has an alignment attribute. bool hasAlignmentAttr() const; @@ -562,8 +666,8 @@ public: typedef std::pair<std::string, std::string> td_type; typedef std::map<std::string, std::string>::iterator td_iterator; typedef std::map<std::string, std::string>::const_iterator td_const_iterator; - typedef llvm::iterator_range<td_iterator> td_range; - typedef llvm::iterator_range<td_const_iterator> td_const_range; + typedef iterator_range<td_iterator> td_range; + typedef iterator_range<td_const_iterator> td_const_range; td_iterator td_begin() { return TargetDepAttrs.begin(); } td_iterator td_end() { return TargetDepAttrs.end(); } @@ -600,4 +704,4 @@ void mergeAttributesForInlining(Function &Caller, const Function &Callee); } // end llvm namespace -#endif +#endif // LLVM_IR_ATTRIBUTES_H |