mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-30 16:17:05 +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 | ||||
|  | ||||
| #include "llvm/ADT/ArrayRef.h" | ||||
| #include "llvm/ADT/DenseSet.h" | ||||
| #include "llvm/ADT/FoldingSet.h" | ||||
| #include "llvm/Support/PointerLikeTypeTraits.h" | ||||
| #include <cassert> | ||||
| #include <map> | ||||
| #include <string> | ||||
| @@ -30,6 +30,7 @@ class AttributeImpl; | ||||
| class AttributeSetImpl; | ||||
| class AttributeSetNode; | ||||
| class Constant; | ||||
| template<typename T> struct DenseMapInfo; | ||||
| class LLVMContext; | ||||
| class Type; | ||||
|  | ||||
| @@ -101,9 +102,6 @@ public: | ||||
|     ZExt,                  ///< Zero extended before/after call | ||||
|  | ||||
|     EndAttrKinds,          ///< Sentinal value useful for loops | ||||
|  | ||||
|     AttrKindEmptyKey,      ///< Empty key value for DenseMapInfo | ||||
|     AttrKindTombstoneKey   ///< Tombstone key value for DenseMapInfo | ||||
|   }; | ||||
| private: | ||||
|   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 | ||||
| /// \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 | ||||
| /// equality, presence of attributes, etc. | ||||
| class AttrBuilder { | ||||
|   DenseSet<Attribute::AttrKind> Attrs; | ||||
|   uint64_t Attrs; | ||||
|   std::map<std::string, std::string> TargetDepAttrs; | ||||
|   uint64_t Alignment; | ||||
|   uint64_t StackAlignment; | ||||
| public: | ||||
|   AttrBuilder() : Alignment(0), StackAlignment(0) {} | ||||
|   explicit AttrBuilder(uint64_t Val) : Alignment(0), StackAlignment(0) { | ||||
|   AttrBuilder() : Attrs(0), Alignment(0), StackAlignment(0) {} | ||||
|   explicit AttrBuilder(uint64_t Val) | ||||
|     : Attrs(0), Alignment(0), StackAlignment(0) { | ||||
|     addRawValue(Val); | ||||
|   } | ||||
|   AttrBuilder(const Attribute &A) : Alignment(0), StackAlignment(0) { | ||||
|   AttrBuilder(const Attribute &A) : Attrs(0), Alignment(0), StackAlignment(0) { | ||||
|     addAttribute(A); | ||||
|   } | ||||
|   AttrBuilder(AttributeSet AS, unsigned Idx); | ||||
| @@ -442,7 +421,11 @@ public: | ||||
|   AttrBuilder &merge(const AttrBuilder &B); | ||||
|  | ||||
|   /// \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 | ||||
|   /// attribute. | ||||
| @@ -472,17 +455,9 @@ public: | ||||
|   /// the form used internally in Attribute. | ||||
|   AttrBuilder &addStackAlignmentAttr(unsigned Align); | ||||
|  | ||||
|   // Iterators for target-independent attributes. | ||||
|   typedef DenseSet<Attribute::AttrKind>::iterator       iterator; | ||||
|   typedef DenseSet<Attribute::AttrKind>::const_iterator const_iterator; | ||||
|  | ||||
|   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(); } | ||||
|   /// \brief Return true if the builder contains no target-independent | ||||
|   /// attributes. | ||||
|   bool empty() const { return Attrs == 0; } | ||||
|  | ||||
|   // Iterators for target-dependent attributes. | ||||
|   typedef std::pair<std::string, std::string>                td_type; | ||||
|   | ||||
| @@ -355,8 +355,6 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { | ||||
|   // FIXME: Remove this. | ||||
|   switch (Val) { | ||||
|   case Attribute::EndAttrKinds: | ||||
|   case Attribute::AttrKindEmptyKey: | ||||
|   case Attribute::AttrKindTombstoneKey: | ||||
|     llvm_unreachable("Synthetic enumerators which should never get here"); | ||||
|  | ||||
|   case Attribute::None:            return 0; | ||||
| @@ -597,8 +595,11 @@ AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx, AttrBuilder &B) { | ||||
|  | ||||
|   // Add target-independent attributes. | ||||
|   SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; | ||||
|   for (AttrBuilder::iterator I = B.begin(), E = B.end(); I != E; ++I) { | ||||
|     Attribute::AttrKind Kind = *I; | ||||
|   for (Attribute::AttrKind Kind = Attribute::None; | ||||
|        Kind != Attribute::EndAttrKinds; ++Kind) { | ||||
|     if (!B.contains(Kind)) | ||||
|       continue; | ||||
|  | ||||
|     if (Kind == Attribute::Alignment) | ||||
|       Attrs.push_back(std::make_pair(Idx, Attribute:: | ||||
|                                      getWithAlignment(C, B.getAlignment()))); | ||||
| @@ -907,7 +908,7 @@ void AttributeSet::dump() const { | ||||
| //===----------------------------------------------------------------------===// | ||||
|  | ||||
| AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Idx) | ||||
|   : Alignment(0), StackAlignment(0) { | ||||
|   : Attrs(0), Alignment(0), StackAlignment(0) { | ||||
|   AttributeSetImpl *pImpl = AS.pImpl; | ||||
|   if (!pImpl) return; | ||||
|  | ||||
| @@ -923,14 +924,16 @@ AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Idx) | ||||
| } | ||||
|  | ||||
| void AttrBuilder::clear() { | ||||
|   Attrs.clear(); | ||||
|   Attrs = 0; | ||||
|   Alignment = StackAlignment = 0; | ||||
| } | ||||
|  | ||||
| AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { | ||||
|   assert((unsigned)Val < 64 && Val < Attribute::EndAttrKinds && | ||||
|          "Attribute out of range!"); | ||||
|   assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment && | ||||
|          "Adding alignment attribute without adding alignment value!"); | ||||
|   Attrs.insert(Val); | ||||
|   Attrs |= 1ULL << Val; | ||||
|   return *this; | ||||
| } | ||||
|  | ||||
| @@ -941,7 +944,7 @@ AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) { | ||||
|   } | ||||
|  | ||||
|   Attribute::AttrKind Kind = Attr.getKindAsEnum(); | ||||
|   Attrs.insert(Kind); | ||||
|   Attrs |= 1ULL << Kind; | ||||
|  | ||||
|   if (Kind == Attribute::Alignment) | ||||
|     Alignment = Attr.getAlignment(); | ||||
| @@ -956,7 +959,9 @@ AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) { | ||||
| } | ||||
|  | ||||
| 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) | ||||
|     Alignment = 0; | ||||
| @@ -980,7 +985,7 @@ AttrBuilder &AttrBuilder::removeAttributes(AttributeSet A, uint64_t Index) { | ||||
|     Attribute Attr = *I; | ||||
|     if (Attr.isEnumAttribute() || Attr.isAlignAttribute()) { | ||||
|       Attribute::AttrKind Kind = I->getKindAsEnum(); | ||||
|       Attrs.erase(Kind); | ||||
|       Attrs &= ~(1ULL << Kind); | ||||
|  | ||||
|       if (Kind == Attribute::Alignment) | ||||
|         Alignment = 0; | ||||
| @@ -1011,7 +1016,7 @@ AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) { | ||||
|   assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); | ||||
|   assert(Align <= 0x40000000 && "Alignment too large."); | ||||
|  | ||||
|   Attrs.insert(Attribute::Alignment); | ||||
|   Attrs |= 1ULL << Attribute::Alignment; | ||||
|   Alignment = Align; | ||||
|   return *this; | ||||
| } | ||||
| @@ -1023,7 +1028,7 @@ AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) { | ||||
|   assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); | ||||
|   assert(Align <= 0x100 && "Alignment too large."); | ||||
|  | ||||
|   Attrs.insert(Attribute::StackAlignment); | ||||
|   Attrs |= 1ULL << Attribute::StackAlignment; | ||||
|   StackAlignment = Align; | ||||
|   return *this; | ||||
| } | ||||
| @@ -1036,7 +1041,7 @@ AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { | ||||
|   if (!StackAlignment) | ||||
|     StackAlignment = B.StackAlignment; | ||||
|  | ||||
|   Attrs.insert(B.Attrs.begin(), B.Attrs.end()); | ||||
|   Attrs |= B.Attrs; | ||||
|  | ||||
|   for (td_const_iterator I = B.TargetDepAttrs.begin(), | ||||
|          E = B.TargetDepAttrs.end(); I != E; ++I) | ||||
| @@ -1045,16 +1050,12 @@ AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { | ||||
|   return *this; | ||||
| } | ||||
|  | ||||
| bool AttrBuilder::contains(Attribute::AttrKind A) const { | ||||
|   return Attrs.count(A); | ||||
| } | ||||
|  | ||||
| bool AttrBuilder::contains(StringRef A) const { | ||||
|   return TargetDepAttrs.find(A) != TargetDepAttrs.end(); | ||||
| } | ||||
|  | ||||
| bool AttrBuilder::hasAttributes() const { | ||||
|   return !Attrs.empty() || !TargetDepAttrs.empty(); | ||||
|   return Attrs != 0 || !TargetDepAttrs.empty(); | ||||
| } | ||||
|  | ||||
| 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) { | ||||
|     Attribute Attr = *I; | ||||
|     if (Attr.isEnumAttribute() || Attr.isAlignAttribute()) { | ||||
|       if (Attrs.count(I->getKindAsEnum())) | ||||
|       if (Attrs & (1ULL << I->getKindAsEnum())) | ||||
|         return true; | ||||
|     } else { | ||||
|       assert(Attr.isStringAttribute() && "Invalid attribute kind!"); | ||||
| @@ -1087,9 +1088,7 @@ bool AttrBuilder::hasAlignmentAttr() const { | ||||
| } | ||||
|  | ||||
| bool AttrBuilder::operator==(const AttrBuilder &B) { | ||||
|   for (DenseSet<Attribute::AttrKind>::iterator I = Attrs.begin(), | ||||
|          E = Attrs.end(); I != E; ++I) | ||||
|     if (!B.Attrs.count(*I)) | ||||
|   if (Attrs != B.Attrs) | ||||
|     return false; | ||||
|  | ||||
|   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; | ||||
|        I = Attribute::AttrKind(I + 1)) { | ||||
|     if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) { | ||||
|       Attrs.insert(I); | ||||
|       Attrs |= 1ULL << I; | ||||
|   | ||||
|       if (I == Attribute::Alignment) | ||||
|         Alignment = 1ULL << ((A >> 16) - 1); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user