[llvm] 8f4c78d - [IR] Use map for string attributes (NFC)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 26 00:41:14 PDT 2020


Author: Nikita Popov
Date: 2020-04-26T09:38:05+02:00
New Revision: 8f4c78dcf8a454a2a8a0fa04fe34e2162efd4a5c

URL: https://github.com/llvm/llvm-project/commit/8f4c78dcf8a454a2a8a0fa04fe34e2162efd4a5c
DIFF: https://github.com/llvm/llvm-project/commit/8f4c78dcf8a454a2a8a0fa04fe34e2162efd4a5c.diff

LOG: [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

Added: 
    

Modified: 
    llvm/lib/IR/AttributeImpl.h
    llvm/lib/IR/Attributes.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/IR/AttributeImpl.h b/llvm/lib/IR/AttributeImpl.h
index 8741c0ca9b3d..875b71bcfe23 100644
--- 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 @@ 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:

diff  --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index f7e42510dc4f..2d9910419bf7 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -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 {


        


More information about the llvm-commits mailing list