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
diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp
index 629679c..99df5ff 100644
--- a/lib/IR/Attributes.cpp
+++ b/lib/IR/Attributes.cpp
@@ -355,8 +355,6 @@
   // 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 @@
 
   // 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 @@
 //===----------------------------------------------------------------------===//
 
 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 @@
 }
 
 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 @@
   }
 
   Attribute::AttrKind Kind = Attr.getKindAsEnum();
-  Attrs.insert(Kind);
+  Attrs |= 1ULL << Kind;
 
   if (Kind == Attribute::Alignment)
     Alignment = Attr.getAlignment();
@@ -956,7 +959,9 @@
 }
 
 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 @@
     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 @@
   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 @@
   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 @@
   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 @@
   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 @@
        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,10 +1088,8 @@
 }
 
 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))
-      return false;
+  if (Attrs != B.Attrs)
+    return false;
 
   for (td_const_iterator I = TargetDepAttrs.begin(),
          E = TargetDepAttrs.end(); I != E; ++I)
@@ -1107,7 +1106,7 @@
   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);