forked from OSchip/llvm-project
[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:
parent
b9de62c2b6
commit
8f4c78dcf8
|
@ -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:
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue