diff --git a/llvm/lib/IR/AttributeImpl.h b/llvm/lib/IR/AttributeImpl.h index 659f9568b7c6..59d09c3d4065 100644 --- a/llvm/lib/IR/AttributeImpl.h +++ b/llvm/lib/IR/AttributeImpl.h @@ -148,10 +148,21 @@ class AttributeSetNode final friend TrailingObjects; unsigned NumAttrs; ///< Number of attributes in this node. + /// Bitset with a bit for each available attribute Attribute::AttrKind. + uint64_t AvailableAttrs; + static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs)*CHAR_BIT, + "Too many attributes for AvailableAttrs"); - AttributeSetNode(ArrayRef Attrs) : NumAttrs(Attrs.size()) { + AttributeSetNode(ArrayRef Attrs) + : NumAttrs(Attrs.size()), AvailableAttrs(0) { // There's memory after the node where we can store the entries in. std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects()); + + for (iterator I = begin(), E = end(); I != E; ++I) { + if (!I->isStringAttribute()) { + AvailableAttrs |= ((uint64_t)1) << I->getKindAsEnum(); + } + } } // AttributesSetNode is uniqued, these should not be publicly available. @@ -160,7 +171,9 @@ class AttributeSetNode final public: static AttributeSetNode *get(LLVMContext &C, ArrayRef Attrs); - bool hasAttribute(Attribute::AttrKind Kind) const; + bool hasAttribute(Attribute::AttrKind Kind) const { + return AvailableAttrs & ((uint64_t)1) << Kind; + } bool hasAttribute(StringRef Kind) const; bool hasAttributes() const { return NumAttrs != 0; } diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index ee5a23469708..af5fe85c5c58 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -498,13 +498,6 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, return PA; } -bool AttributeSetNode::hasAttribute(Attribute::AttrKind Kind) const { - for (iterator I = begin(), E = end(); I != E; ++I) - if (I->hasAttribute(Kind)) - return true; - return false; -} - bool AttributeSetNode::hasAttribute(StringRef Kind) const { for (iterator I = begin(), E = end(); I != E; ++I) if (I->hasAttribute(Kind)) @@ -513,9 +506,11 @@ bool AttributeSetNode::hasAttribute(StringRef Kind) const { } Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const { - for (iterator I = begin(), E = end(); I != E; ++I) - if (I->hasAttribute(Kind)) - return *I; + if (hasAttribute(Kind)) { + for (iterator I = begin(), E = end(); I != E; ++I) + if (I->hasAttribute(Kind)) + return *I; + } return Attribute(); }