[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
This commit is contained in:
Nikita Popov 2020-04-25 12:21:21 +02:00
parent b9de62c2b6
commit 8f4c78dcf8
2 changed files with 8 additions and 9 deletions

View File

@ -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 @@ 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:

View File

@ -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);
}
@ -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 {
@ -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 {