Skip to content

Commit 8f4c78d

Browse files
committed
[IR] Use map for string attributes (NFC)
Attributes are currently stored as a simple list. Enum attributes additionally use a bitset to allow quickly determining whether an attribute is set. String attributes on the other hand require a full scan of the list. As functions tend to have a lot of string attributes (at least when clang is used), this is a noticeable performance issue. This patch adds an additional name => attribute map to the AttributeSetNode, which allows querying string attributes quickly. This results in a 3% reduction in instructions retired on CTMark. Changes to memory usage seem to be in the noise (attribute sets are uniqued, and we don't tend to have more than a few dozen or hundred unique attribute sets, so adding an extra map does not have a noticeable cost.) Differential Revision: https://reviews.llvm.org/D78859
1 parent b9de62c commit 8f4c78d

File tree

2 files changed

+8
-9
lines changed

2 files changed

+8
-9
lines changed

llvm/lib/IR/AttributeImpl.h

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define LLVM_LIB_IR_ATTRIBUTEIMPL_H
1717

1818
#include "llvm/ADT/ArrayRef.h"
19+
#include "llvm/ADT/DenseMap.h"
1920
#include "llvm/ADT/FoldingSet.h"
2021
#include "llvm/ADT/StringRef.h"
2122
#include "llvm/IR/Attributes.h"
@@ -181,6 +182,8 @@ class AttributeSetNode final
181182
/// Bitset with a bit for each available attribute Attribute::AttrKind.
182183
uint8_t AvailableAttrs[12] = {};
183184

185+
DenseMap<StringRef, Attribute> StringAttrs;
186+
184187
AttributeSetNode(ArrayRef<Attribute> Attrs);
185188

186189
public:

llvm/lib/IR/Attributes.cpp

+5-9
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,9 @@ AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
770770
"Too many attributes");
771771

772772
for (const auto &I : *this) {
773-
if (!I.isStringAttribute()) {
773+
if (I.isStringAttribute()) {
774+
StringAttrs.insert({ I.getKindAsString(), I });
775+
} else {
774776
Attribute::AttrKind Kind = I.getKindAsEnum();
775777
AvailableAttrs[Kind / 8] |= 1ULL << (Kind % 8);
776778
}
@@ -857,10 +859,7 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
857859
}
858860

859861
bool AttributeSetNode::hasAttribute(StringRef Kind) const {
860-
for (const auto &I : *this)
861-
if (I.hasAttribute(Kind))
862-
return true;
863-
return false;
862+
return StringAttrs.count(Kind);
864863
}
865864

866865
Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
@@ -873,10 +872,7 @@ Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
873872
}
874873

875874
Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
876-
for (const auto &I : *this)
877-
if (I.hasAttribute(Kind))
878-
return I;
879-
return {};
875+
return StringAttrs.lookup(Kind);
880876
}
881877

882878
MaybeAlign AttributeSetNode::getAlignment() const {

0 commit comments

Comments
 (0)