Index: llvm/trunk/lib/IR/AttributeImpl.h =================================================================== --- llvm/trunk/lib/IR/AttributeImpl.h +++ llvm/trunk/lib/IR/AttributeImpl.h @@ -179,9 +179,9 @@ private TrailingObjects { friend TrailingObjects; - /// Bitset with a bit for each available attribute Attribute::AttrKind. - uint64_t AvailableAttrs; unsigned NumAttrs; ///< Number of attributes in this node. + /// Bitset with a bit for each available attribute Attribute::AttrKind. + uint8_t AvailableAttrs[12] = {}; AttributeSetNode(ArrayRef Attrs); @@ -200,7 +200,7 @@ unsigned getNumAttributes() const { return NumAttrs; } bool hasAttribute(Attribute::AttrKind Kind) const { - return AvailableAttrs & ((uint64_t)1) << Kind; + return AvailableAttrs[Kind / 8] & ((uint64_t)1) << (Kind % 8); } bool hasAttribute(StringRef Kind) const; bool hasAttributes() const { return NumAttrs != 0; } @@ -244,10 +244,10 @@ friend TrailingObjects; private: - /// Bitset with a bit for each available attribute Attribute::AttrKind. - uint64_t AvailableFunctionAttrs; LLVMContext &Context; unsigned NumAttrSets; ///< Number of entries in this set. + /// Bitset with a bit for each available attribute Attribute::AttrKind. + uint8_t AvailableFunctionAttrs[12] = {}; // Helper fn for TrailingObjects class. size_t numTrailingObjects(OverloadToken) { return NumAttrSets; } @@ -267,7 +267,7 @@ /// Return true if the AttributeSet or the FunctionIndex has an /// enum attribute of the given kind. bool hasFnAttribute(Attribute::AttrKind Kind) const { - return AvailableFunctionAttrs & ((uint64_t)1) << Kind; + return AvailableFunctionAttrs[Kind / 8] & ((uint64_t)1) << (Kind % 8); } using iterator = const AttributeSet *; Index: llvm/trunk/lib/IR/Attributes.cpp =================================================================== --- llvm/trunk/lib/IR/Attributes.cpp +++ llvm/trunk/lib/IR/Attributes.cpp @@ -718,13 +718,18 @@ //===----------------------------------------------------------------------===// AttributeSetNode::AttributeSetNode(ArrayRef Attrs) - : AvailableAttrs(0), NumAttrs(Attrs.size()) { + : NumAttrs(Attrs.size()) { // There's memory after the node where we can store the entries in. llvm::copy(Attrs, getTrailingObjects()); + static_assert(Attribute::EndAttrKinds <= + sizeof(AvailableAttrs) * CHAR_BIT, + "Too many attributes"); + for (const auto I : *this) { if (!I.isStringAttribute()) { - AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum(); + Attribute::AttrKind Kind = I.getKindAsEnum(); + AvailableAttrs[Kind / 8] |= 1ULL << (Kind % 8); } } } @@ -896,7 +901,7 @@ AttributeListImpl::AttributeListImpl(LLVMContext &C, ArrayRef Sets) - : AvailableFunctionAttrs(0), Context(C), NumAttrSets(Sets.size()) { + : Context(C), NumAttrSets(Sets.size()) { assert(!Sets.empty() && "pointless AttributeListImpl"); // There's memory after the node where we can store the entries in. @@ -909,8 +914,10 @@ static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U, "function should be stored in slot 0"); for (const auto I : Sets[0]) { - if (!I.isStringAttribute()) - AvailableFunctionAttrs |= 1ULL << I.getKindAsEnum(); + if (!I.isStringAttribute()) { + Attribute::AttrKind Kind = I.getKindAsEnum(); + AvailableFunctionAttrs[Kind / 8] |= 1ULL << (Kind % 8); + } } }