mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	Turn the enum attributes DenseSet in AttrBuilder into a set of bits.
Avoids malloc and is a lot denser. We lose iteration over target independent attributes, but that's a strange interface anyways and didn't have any users outside of AttrBuilder. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175370 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
		| @@ -17,8 +17,8 @@ | |||||||
| #define LLVM_IR_ATTRIBUTES_H | #define LLVM_IR_ATTRIBUTES_H | ||||||
|  |  | ||||||
| #include "llvm/ADT/ArrayRef.h" | #include "llvm/ADT/ArrayRef.h" | ||||||
| #include "llvm/ADT/DenseSet.h" |  | ||||||
| #include "llvm/ADT/FoldingSet.h" | #include "llvm/ADT/FoldingSet.h" | ||||||
|  | #include "llvm/Support/PointerLikeTypeTraits.h" | ||||||
| #include <cassert> | #include <cassert> | ||||||
| #include <map> | #include <map> | ||||||
| #include <string> | #include <string> | ||||||
| @@ -30,6 +30,7 @@ class AttributeImpl; | |||||||
| class AttributeSetImpl; | class AttributeSetImpl; | ||||||
| class AttributeSetNode; | class AttributeSetNode; | ||||||
| class Constant; | class Constant; | ||||||
|  | template<typename T> struct DenseMapInfo; | ||||||
| class LLVMContext; | class LLVMContext; | ||||||
| class Type; | class Type; | ||||||
|  |  | ||||||
| @@ -101,9 +102,6 @@ public: | |||||||
|     ZExt,                  ///< Zero extended before/after call |     ZExt,                  ///< Zero extended before/after call | ||||||
|  |  | ||||||
|     EndAttrKinds,          ///< Sentinal value useful for loops |     EndAttrKinds,          ///< Sentinal value useful for loops | ||||||
|  |  | ||||||
|     AttrKindEmptyKey,      ///< Empty key value for DenseMapInfo |  | ||||||
|     AttrKindTombstoneKey   ///< Tombstone key value for DenseMapInfo |  | ||||||
|   }; |   }; | ||||||
| private: | private: | ||||||
|   AttributeImpl *pImpl; |   AttributeImpl *pImpl; | ||||||
| @@ -185,26 +183,6 @@ public: | |||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| //===----------------------------------------------------------------------===// |  | ||||||
| /// \class |  | ||||||
| /// \brief Provide DenseMapInfo for Attribute::AttrKinds. This is used by |  | ||||||
| /// AttrBuilder. |  | ||||||
| template<> struct DenseMapInfo<Attribute::AttrKind> { |  | ||||||
|   static inline Attribute::AttrKind getEmptyKey() { |  | ||||||
|     return Attribute::AttrKindEmptyKey; |  | ||||||
|   } |  | ||||||
|   static inline Attribute::AttrKind getTombstoneKey() { |  | ||||||
|     return Attribute::AttrKindTombstoneKey; |  | ||||||
|   } |  | ||||||
|   static unsigned getHashValue(const Attribute::AttrKind &Val) { |  | ||||||
|     return Val * 37U; |  | ||||||
|   } |  | ||||||
|   static bool isEqual(const Attribute::AttrKind &LHS, |  | ||||||
|                       const Attribute::AttrKind &RHS) { |  | ||||||
|     return LHS == RHS; |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
| /// \class | /// \class | ||||||
| /// \brief This class holds the attributes for a function, its return value, and | /// \brief This class holds the attributes for a function, its return value, and | ||||||
| @@ -400,16 +378,17 @@ template<> struct DenseMapInfo<AttributeSet> { | |||||||
| /// value, however, is not. So this can be used as a quick way to test for | /// value, however, is not. So this can be used as a quick way to test for | ||||||
| /// equality, presence of attributes, etc. | /// equality, presence of attributes, etc. | ||||||
| class AttrBuilder { | class AttrBuilder { | ||||||
|   DenseSet<Attribute::AttrKind> Attrs; |   uint64_t Attrs; | ||||||
|   std::map<std::string, std::string> TargetDepAttrs; |   std::map<std::string, std::string> TargetDepAttrs; | ||||||
|   uint64_t Alignment; |   uint64_t Alignment; | ||||||
|   uint64_t StackAlignment; |   uint64_t StackAlignment; | ||||||
| public: | public: | ||||||
|   AttrBuilder() : Alignment(0), StackAlignment(0) {} |   AttrBuilder() : Attrs(0), Alignment(0), StackAlignment(0) {} | ||||||
|   explicit AttrBuilder(uint64_t Val) : Alignment(0), StackAlignment(0) { |   explicit AttrBuilder(uint64_t Val) | ||||||
|  |     : Attrs(0), Alignment(0), StackAlignment(0) { | ||||||
|     addRawValue(Val); |     addRawValue(Val); | ||||||
|   } |   } | ||||||
|   AttrBuilder(const Attribute &A) : Alignment(0), StackAlignment(0) { |   AttrBuilder(const Attribute &A) : Attrs(0), Alignment(0), StackAlignment(0) { | ||||||
|     addAttribute(A); |     addAttribute(A); | ||||||
|   } |   } | ||||||
|   AttrBuilder(AttributeSet AS, unsigned Idx); |   AttrBuilder(AttributeSet AS, unsigned Idx); | ||||||
| @@ -442,7 +421,11 @@ public: | |||||||
|   AttrBuilder &merge(const AttrBuilder &B); |   AttrBuilder &merge(const AttrBuilder &B); | ||||||
|  |  | ||||||
|   /// \brief Return true if the builder has the specified attribute. |   /// \brief Return true if the builder has the specified attribute. | ||||||
|   bool contains(Attribute::AttrKind A) const; |   bool contains(Attribute::AttrKind A) const { | ||||||
|  |     assert((unsigned)A < 64 && A < Attribute::EndAttrKinds && | ||||||
|  |            "Attribute out of range!"); | ||||||
|  |     return Attrs & (1ULL << A); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   /// \brief Return true if the builder has the specified target-dependent |   /// \brief Return true if the builder has the specified target-dependent | ||||||
|   /// attribute. |   /// attribute. | ||||||
| @@ -472,17 +455,9 @@ public: | |||||||
|   /// the form used internally in Attribute. |   /// the form used internally in Attribute. | ||||||
|   AttrBuilder &addStackAlignmentAttr(unsigned Align); |   AttrBuilder &addStackAlignmentAttr(unsigned Align); | ||||||
|  |  | ||||||
|   // Iterators for target-independent attributes. |   /// \brief Return true if the builder contains no target-independent | ||||||
|   typedef DenseSet<Attribute::AttrKind>::iterator       iterator; |   /// attributes. | ||||||
|   typedef DenseSet<Attribute::AttrKind>::const_iterator const_iterator; |   bool empty() const { return Attrs == 0; } | ||||||
|  |  | ||||||
|   iterator begin()             { return Attrs.begin(); } |  | ||||||
|   iterator end()               { return Attrs.end(); } |  | ||||||
|  |  | ||||||
|   const_iterator begin() const { return Attrs.begin(); } |  | ||||||
|   const_iterator end() const   { return Attrs.end(); } |  | ||||||
|  |  | ||||||
|   bool empty() const           { return Attrs.empty(); } |  | ||||||
|  |  | ||||||
|   // Iterators for target-dependent attributes. |   // Iterators for target-dependent attributes. | ||||||
|   typedef std::pair<std::string, std::string>                td_type; |   typedef std::pair<std::string, std::string>                td_type; | ||||||
|   | |||||||
| @@ -355,8 +355,6 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { | |||||||
|   // FIXME: Remove this. |   // FIXME: Remove this. | ||||||
|   switch (Val) { |   switch (Val) { | ||||||
|   case Attribute::EndAttrKinds: |   case Attribute::EndAttrKinds: | ||||||
|   case Attribute::AttrKindEmptyKey: |  | ||||||
|   case Attribute::AttrKindTombstoneKey: |  | ||||||
|     llvm_unreachable("Synthetic enumerators which should never get here"); |     llvm_unreachable("Synthetic enumerators which should never get here"); | ||||||
|  |  | ||||||
|   case Attribute::None:            return 0; |   case Attribute::None:            return 0; | ||||||
| @@ -597,8 +595,11 @@ AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx, AttrBuilder &B) { | |||||||
|  |  | ||||||
|   // Add target-independent attributes. |   // Add target-independent attributes. | ||||||
|   SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; |   SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; | ||||||
|   for (AttrBuilder::iterator I = B.begin(), E = B.end(); I != E; ++I) { |   for (Attribute::AttrKind Kind = Attribute::None; | ||||||
|     Attribute::AttrKind Kind = *I; |        Kind != Attribute::EndAttrKinds; ++Kind) { | ||||||
|  |     if (!B.contains(Kind)) | ||||||
|  |       continue; | ||||||
|  |  | ||||||
|     if (Kind == Attribute::Alignment) |     if (Kind == Attribute::Alignment) | ||||||
|       Attrs.push_back(std::make_pair(Idx, Attribute:: |       Attrs.push_back(std::make_pair(Idx, Attribute:: | ||||||
|                                      getWithAlignment(C, B.getAlignment()))); |                                      getWithAlignment(C, B.getAlignment()))); | ||||||
| @@ -907,7 +908,7 @@ void AttributeSet::dump() const { | |||||||
| //===----------------------------------------------------------------------===// | //===----------------------------------------------------------------------===// | ||||||
|  |  | ||||||
| AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Idx) | AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Idx) | ||||||
|   : Alignment(0), StackAlignment(0) { |   : Attrs(0), Alignment(0), StackAlignment(0) { | ||||||
|   AttributeSetImpl *pImpl = AS.pImpl; |   AttributeSetImpl *pImpl = AS.pImpl; | ||||||
|   if (!pImpl) return; |   if (!pImpl) return; | ||||||
|  |  | ||||||
| @@ -923,14 +924,16 @@ AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Idx) | |||||||
| } | } | ||||||
|  |  | ||||||
| void AttrBuilder::clear() { | void AttrBuilder::clear() { | ||||||
|   Attrs.clear(); |   Attrs = 0; | ||||||
|   Alignment = StackAlignment = 0; |   Alignment = StackAlignment = 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { | AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { | ||||||
|  |   assert((unsigned)Val < 64 && Val < Attribute::EndAttrKinds && | ||||||
|  |          "Attribute out of range!"); | ||||||
|   assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment && |   assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment && | ||||||
|          "Adding alignment attribute without adding alignment value!"); |          "Adding alignment attribute without adding alignment value!"); | ||||||
|   Attrs.insert(Val); |   Attrs |= 1ULL << Val; | ||||||
|   return *this; |   return *this; | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -941,7 +944,7 @@ AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   Attribute::AttrKind Kind = Attr.getKindAsEnum(); |   Attribute::AttrKind Kind = Attr.getKindAsEnum(); | ||||||
|   Attrs.insert(Kind); |   Attrs |= 1ULL << Kind; | ||||||
|  |  | ||||||
|   if (Kind == Attribute::Alignment) |   if (Kind == Attribute::Alignment) | ||||||
|     Alignment = Attr.getAlignment(); |     Alignment = Attr.getAlignment(); | ||||||
| @@ -956,7 +959,9 @@ AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) { | |||||||
| } | } | ||||||
|  |  | ||||||
| AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { | AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { | ||||||
|   Attrs.erase(Val); |   assert((unsigned)Val < 64 && Val < Attribute::EndAttrKinds && | ||||||
|  |          "Attribute out of range!"); | ||||||
|  |   Attrs &= ~(1ULL << Val); | ||||||
|  |  | ||||||
|   if (Val == Attribute::Alignment) |   if (Val == Attribute::Alignment) | ||||||
|     Alignment = 0; |     Alignment = 0; | ||||||
| @@ -980,7 +985,7 @@ AttrBuilder &AttrBuilder::removeAttributes(AttributeSet A, uint64_t Index) { | |||||||
|     Attribute Attr = *I; |     Attribute Attr = *I; | ||||||
|     if (Attr.isEnumAttribute() || Attr.isAlignAttribute()) { |     if (Attr.isEnumAttribute() || Attr.isAlignAttribute()) { | ||||||
|       Attribute::AttrKind Kind = I->getKindAsEnum(); |       Attribute::AttrKind Kind = I->getKindAsEnum(); | ||||||
|       Attrs.erase(Kind); |       Attrs &= ~(1ULL << Kind); | ||||||
|  |  | ||||||
|       if (Kind == Attribute::Alignment) |       if (Kind == Attribute::Alignment) | ||||||
|         Alignment = 0; |         Alignment = 0; | ||||||
| @@ -1011,7 +1016,7 @@ AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) { | |||||||
|   assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); |   assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); | ||||||
|   assert(Align <= 0x40000000 && "Alignment too large."); |   assert(Align <= 0x40000000 && "Alignment too large."); | ||||||
|  |  | ||||||
|   Attrs.insert(Attribute::Alignment); |   Attrs |= 1ULL << Attribute::Alignment; | ||||||
|   Alignment = Align; |   Alignment = Align; | ||||||
|   return *this; |   return *this; | ||||||
| } | } | ||||||
| @@ -1023,7 +1028,7 @@ AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) { | |||||||
|   assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); |   assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); | ||||||
|   assert(Align <= 0x100 && "Alignment too large."); |   assert(Align <= 0x100 && "Alignment too large."); | ||||||
|  |  | ||||||
|   Attrs.insert(Attribute::StackAlignment); |   Attrs |= 1ULL << Attribute::StackAlignment; | ||||||
|   StackAlignment = Align; |   StackAlignment = Align; | ||||||
|   return *this; |   return *this; | ||||||
| } | } | ||||||
| @@ -1036,7 +1041,7 @@ AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { | |||||||
|   if (!StackAlignment) |   if (!StackAlignment) | ||||||
|     StackAlignment = B.StackAlignment; |     StackAlignment = B.StackAlignment; | ||||||
|  |  | ||||||
|   Attrs.insert(B.Attrs.begin(), B.Attrs.end()); |   Attrs |= B.Attrs; | ||||||
|  |  | ||||||
|   for (td_const_iterator I = B.TargetDepAttrs.begin(), |   for (td_const_iterator I = B.TargetDepAttrs.begin(), | ||||||
|          E = B.TargetDepAttrs.end(); I != E; ++I) |          E = B.TargetDepAttrs.end(); I != E; ++I) | ||||||
| @@ -1045,16 +1050,12 @@ AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { | |||||||
|   return *this; |   return *this; | ||||||
| } | } | ||||||
|  |  | ||||||
| bool AttrBuilder::contains(Attribute::AttrKind A) const { |  | ||||||
|   return Attrs.count(A); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| bool AttrBuilder::contains(StringRef A) const { | bool AttrBuilder::contains(StringRef A) const { | ||||||
|   return TargetDepAttrs.find(A) != TargetDepAttrs.end(); |   return TargetDepAttrs.find(A) != TargetDepAttrs.end(); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool AttrBuilder::hasAttributes() const { | bool AttrBuilder::hasAttributes() const { | ||||||
|   return !Attrs.empty() || !TargetDepAttrs.empty(); |   return Attrs != 0 || !TargetDepAttrs.empty(); | ||||||
| } | } | ||||||
|  |  | ||||||
| bool AttrBuilder::hasAttributes(AttributeSet A, uint64_t Index) const { | bool AttrBuilder::hasAttributes(AttributeSet A, uint64_t Index) const { | ||||||
| @@ -1071,7 +1072,7 @@ bool AttrBuilder::hasAttributes(AttributeSet A, uint64_t Index) const { | |||||||
|        I != E; ++I) { |        I != E; ++I) { | ||||||
|     Attribute Attr = *I; |     Attribute Attr = *I; | ||||||
|     if (Attr.isEnumAttribute() || Attr.isAlignAttribute()) { |     if (Attr.isEnumAttribute() || Attr.isAlignAttribute()) { | ||||||
|       if (Attrs.count(I->getKindAsEnum())) |       if (Attrs & (1ULL << I->getKindAsEnum())) | ||||||
|         return true; |         return true; | ||||||
|     } else { |     } else { | ||||||
|       assert(Attr.isStringAttribute() && "Invalid attribute kind!"); |       assert(Attr.isStringAttribute() && "Invalid attribute kind!"); | ||||||
| @@ -1087,9 +1088,7 @@ bool AttrBuilder::hasAlignmentAttr() const { | |||||||
| } | } | ||||||
|  |  | ||||||
| bool AttrBuilder::operator==(const AttrBuilder &B) { | bool AttrBuilder::operator==(const AttrBuilder &B) { | ||||||
|   for (DenseSet<Attribute::AttrKind>::iterator I = Attrs.begin(), |   if (Attrs != B.Attrs) | ||||||
|          E = Attrs.end(); I != E; ++I) |  | ||||||
|     if (!B.Attrs.count(*I)) |  | ||||||
|     return false; |     return false; | ||||||
|  |  | ||||||
|   for (td_const_iterator I = TargetDepAttrs.begin(), |   for (td_const_iterator I = TargetDepAttrs.begin(), | ||||||
| @@ -1107,7 +1106,7 @@ AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) { | |||||||
|   for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; |   for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; | ||||||
|        I = Attribute::AttrKind(I + 1)) { |        I = Attribute::AttrKind(I + 1)) { | ||||||
|     if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) { |     if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) { | ||||||
|       Attrs.insert(I); |       Attrs |= 1ULL << I; | ||||||
|   |   | ||||||
|       if (I == Attribute::Alignment) |       if (I == Attribute::Alignment) | ||||||
|         Alignment = 1ULL << ((A >> 16) - 1); |         Alignment = 1ULL << ((A >> 16) - 1); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user