diff --git a/llvm/lib/IR/AttributeImpl.h b/llvm/lib/IR/AttributeImpl.h --- a/llvm/lib/IR/AttributeImpl.h +++ b/llvm/lib/IR/AttributeImpl.h @@ -16,6 +16,7 @@ #define LLVM_LIB_IR_ATTRIBUTEIMPL_H #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/Attributes.h" @@ -181,6 +182,8 @@ /// Bitset with a bit for each available attribute Attribute::AttrKind. uint8_t AvailableAttrs[12] = {}; + DenseMap StringAttrs; + AttributeSetNode(ArrayRef Attrs); public: diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -770,7 +770,9 @@ "Too many attributes"); for (const auto &I : *this) { - if (!I.isStringAttribute()) { + if (I.isStringAttribute()) { + StringAttrs.insert({ I.getKindAsString(), I }); + } else { Attribute::AttrKind Kind = I.getKindAsEnum(); AvailableAttrs[Kind / 8] |= 1ULL << (Kind % 8); } @@ -857,10 +859,7 @@ } bool AttributeSetNode::hasAttribute(StringRef Kind) const { - for (const auto &I : *this) - if (I.hasAttribute(Kind)) - return true; - return false; + return StringAttrs.count(Kind); } Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const { @@ -873,10 +872,7 @@ } Attribute AttributeSetNode::getAttribute(StringRef Kind) const { - for (const auto &I : *this) - if (I.hasAttribute(Kind)) - return I; - return {}; + return StringAttrs.lookup(Kind); } MaybeAlign AttributeSetNode::getAlignment() const {