Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[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
  • Loading branch information
nikic committed Apr 26, 2020
1 parent b9de62c commit 8f4c78d
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 9 deletions.
3 changes: 3 additions & 0 deletions llvm/lib/IR/AttributeImpl.h
Expand Up @@ -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"
Expand Down Expand Up @@ -181,6 +182,8 @@ class AttributeSetNode final
/// Bitset with a bit for each available attribute Attribute::AttrKind.
uint8_t AvailableAttrs[12] = {};

DenseMap<StringRef, Attribute> StringAttrs;

AttributeSetNode(ArrayRef<Attribute> Attrs);

public:
Expand Down
14 changes: 5 additions & 9 deletions llvm/lib/IR/Attributes.cpp
Expand Up @@ -770,7 +770,9 @@ AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
"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);
}
Expand Down Expand Up @@ -857,10 +859,7 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
}

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 {
Expand All @@ -873,10 +872,7 @@ Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
}

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 {
Expand Down

0 comments on commit 8f4c78d

Please sign in to comment.