Skip to content

Commit 9a334a4

Browse files
committed
[IR] Store attributes that are available "somewhere" (NFC)
I noticed that for some benchmarks we spend quite a bit of time inside AttributeList::hasAttrSomewhere(), mainly when checking for the "returned" attribute. Most of the time the attribute will not be present, in which case this function has to walk through the whole attribute list and check for the attribute at each index. This patch adds a cache of all "available somewhere" attributes inside AttributeListImpl. This makes the structure 12 bytes larger, but I don't think that's problematic, as attribute lists are uniqued. Compile-time in terms of instructions retired improves by 0.4% on average, but >1% for sqlite. Differential Revision: https://reviews.llvm.org/D81867
1 parent ba2ac68 commit 9a334a4

File tree

2 files changed

+35
-14
lines changed

2 files changed

+35
-14
lines changed

llvm/lib/IR/AttributeImpl.h

+8
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@ class AttributeListImpl final
282282
unsigned NumAttrSets; ///< Number of entries in this set.
283283
/// Available enum function attributes.
284284
AttributeBitSet AvailableFunctionAttrs;
285+
/// Union of enum attributes available at any index.
286+
AttributeBitSet AvailableSomewhereAttrs;
285287

286288
// Helper fn for TrailingObjects class.
287289
size_t numTrailingObjects(OverloadToken<AttributeSet>) { return NumAttrSets; }
@@ -299,6 +301,12 @@ class AttributeListImpl final
299301
return AvailableFunctionAttrs.hasAttribute(Kind);
300302
}
301303

304+
/// Return true if the specified attribute is set for at least one
305+
/// parameter or for the return value. If Index is not nullptr, the index
306+
/// of a parameter with the specified attribute is provided.
307+
bool hasAttrSomewhere(Attribute::AttrKind Kind,
308+
unsigned *Index = nullptr) const;
309+
302310
using iterator = const AttributeSet *;
303311

304312
iterator begin() const { return getTrailingObjects<AttributeSet>(); }

llvm/lib/IR/Attributes.cpp

+27-14
Original file line numberDiff line numberDiff line change
@@ -977,13 +977,18 @@ AttributeListImpl::AttributeListImpl(ArrayRef<AttributeSet> Sets)
977977
// There's memory after the node where we can store the entries in.
978978
llvm::copy(Sets, getTrailingObjects<AttributeSet>());
979979

980-
// Initialize AvailableFunctionAttrs summary bitset.
980+
// Initialize AvailableFunctionAttrs and AvailableSomewhereAttrs
981+
// summary bitsets.
981982
static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U,
982983
"function should be stored in slot 0");
983-
for (const auto &I : Sets[0]) {
984+
for (const auto &I : Sets[0])
984985
if (!I.isStringAttribute())
985986
AvailableFunctionAttrs.addAttribute(I.getKindAsEnum());
986-
}
987+
988+
for (const auto &Set : Sets)
989+
for (const auto &I : Set)
990+
if (!I.isStringAttribute())
991+
AvailableSomewhereAttrs.addAttribute(I.getKindAsEnum());
987992
}
988993

989994
void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
@@ -996,6 +1001,24 @@ void AttributeListImpl::Profile(FoldingSetNodeID &ID,
9961001
ID.AddPointer(Set.SetNode);
9971002
}
9981003

1004+
bool AttributeListImpl::hasAttrSomewhere(Attribute::AttrKind Kind,
1005+
unsigned *Index) const {
1006+
if (!AvailableSomewhereAttrs.hasAttribute(Kind))
1007+
return false;
1008+
1009+
if (Index) {
1010+
for (unsigned I = 0, E = NumAttrSets; I != E; ++I) {
1011+
if (begin()[I].hasAttribute(Kind)) {
1012+
*Index = I - 1;
1013+
break;
1014+
}
1015+
}
1016+
}
1017+
1018+
return true;
1019+
}
1020+
1021+
9991022
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
10001023
LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
10011024
AttributeList(const_cast<AttributeListImpl *>(this)).dump();
@@ -1401,17 +1424,7 @@ bool AttributeList::hasParamAttribute(unsigned ArgNo,
14011424

14021425
bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
14031426
unsigned *Index) const {
1404-
if (!pImpl) return false;
1405-
1406-
for (unsigned I = index_begin(), E = index_end(); I != E; ++I) {
1407-
if (hasAttribute(I, Attr)) {
1408-
if (Index)
1409-
*Index = I;
1410-
return true;
1411-
}
1412-
}
1413-
1414-
return false;
1427+
return pImpl && pImpl->hasAttrSomewhere(Attr, Index);
14151428
}
14161429

14171430
Attribute AttributeList::getAttribute(unsigned Index,

0 commit comments

Comments
 (0)