aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Attributes.cpp
diff options
context:
space:
mode:
authorSerge Guelton <sguelton@redhat.com>2022-01-03 13:32:19 -0500
committerserge-sans-paille <sguelton@redhat.com>2022-01-10 14:49:53 +0100
commitd2cc6c2d0c2f8a6e272110416a3fd579ed5a3ac1 (patch)
tree37a792a98dc78783341b383ac0808ac227327511 /llvm/lib/IR/Attributes.cpp
parent2c0fb96254fef2509b66d75290fedafd4adede95 (diff)
downloadllvm-d2cc6c2d0c2f8a6e272110416a3fd579ed5a3ac1.zip
llvm-d2cc6c2d0c2f8a6e272110416a3fd579ed5a3ac1.tar.gz
llvm-d2cc6c2d0c2f8a6e272110416a3fd579ed5a3ac1.tar.bz2
Use a sorted array instead of a map to store AttrBuilder string attributes
Using and std::map<SmallString, SmallString> for target dependent attributes is inefficient: it makes its constructor slightly heavier, and involves extra allocation for each new string attribute. Storing the attribute key/value as strings implies extra allocation/copy step. Use a sorted vector instead. Given the low number of attributes generally involved, this is cheaper, as showcased by https://llvm-compile-time-tracker.com/compare.php?from=5de322295f4ade692dc4f1823ae4450ad3c48af2&to=05bc480bf641a9e3b466619af43a2d123ee3f71d&stat=instructions Differential Revision: https://reviews.llvm.org/D116599
Diffstat (limited to 'llvm/lib/IR/Attributes.cpp')
-rw-r--r--llvm/lib/IR/Attributes.cpp84
1 files changed, 47 insertions, 37 deletions
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index c1b63c0..9726397 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -607,14 +607,14 @@ AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
AttributeSet AttributeSet::addAttribute(LLVMContext &C,
Attribute::AttrKind Kind) const {
if (hasAttribute(Kind)) return *this;
- AttrBuilder B;
+ AttrBuilder B(C);
B.addAttribute(Kind);
return addAttributes(C, AttributeSet::get(C, B));
}
AttributeSet AttributeSet::addAttribute(LLVMContext &C, StringRef Kind,
StringRef Value) const {
- AttrBuilder B;
+ AttrBuilder B(C);
B.addAttribute(Kind, Value);
return addAttributes(C, AttributeSet::get(C, B));
}
@@ -627,7 +627,7 @@ AttributeSet AttributeSet::addAttributes(LLVMContext &C,
if (!AS.hasAttributes())
return *this;
- AttrBuilder B(AS);
+ AttrBuilder B(C, AS);
for (const auto &I : *this)
B.addAttribute(I);
@@ -637,7 +637,7 @@ AttributeSet AttributeSet::addAttributes(LLVMContext &C,
AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
Attribute::AttrKind Kind) const {
if (!hasAttribute(Kind)) return *this;
- AttrBuilder B(*this);
+ AttrBuilder B(C, *this);
B.removeAttribute(Kind);
return get(C, B);
}
@@ -645,14 +645,14 @@ AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
StringRef Kind) const {
if (!hasAttribute(Kind)) return *this;
- AttrBuilder B(*this);
+ AttrBuilder B(C, *this);
B.removeAttribute(Kind);
return get(C, B);
}
AttributeSet AttributeSet::removeAttributes(LLVMContext &C,
const AttributeMask &Attrs) const {
- AttrBuilder B(*this);
+ AttrBuilder B(C, *this);
// If there is nothing to remove, directly return the original set.
if (!B.overlaps(Attrs))
return *this;
@@ -836,7 +836,7 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
// Add target-dependent (string) attributes.
for (const auto &TDA : B.td_attrs())
- Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second));
+ Attrs.push_back(TDA);
return getSorted(C, Attrs);
}
@@ -1194,9 +1194,9 @@ AttributeList AttributeList::get(LLVMContext &C,
SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
for (unsigned I = 0; I < MaxSize; ++I) {
- AttrBuilder CurBuilder;
+ AttrBuilder CurBuilder(C);
for (const auto &List : Attrs)
- CurBuilder.merge(List.getAttributes(I - 1));
+ CurBuilder.merge(AttrBuilder(C, List.getAttributes(I - 1)));
NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
}
@@ -1218,14 +1218,14 @@ AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
AttributeList AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
StringRef Kind,
StringRef Value) const {
- AttrBuilder B;
+ AttrBuilder B(C);
B.addAttribute(Kind, Value);
return addAttributesAtIndex(C, Index, B);
}
AttributeList AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
Attribute A) const {
- AttrBuilder B;
+ AttrBuilder B(C);
B.addAttribute(A);
return addAttributesAtIndex(C, Index, B);
}
@@ -1259,7 +1259,7 @@ AttributeList AttributeList::addAttributesAtIndex(LLVMContext &C,
"Attempt to change alignment!");
#endif
- AttrBuilder Merged(getAttributes(Index));
+ AttrBuilder Merged(C, getAttributes(Index));
Merged.merge(B);
return setAttributesAtIndex(C, Index, AttributeSet::get(C, Merged));
}
@@ -1276,7 +1276,7 @@ AttributeList AttributeList::addParamAttribute(LLVMContext &C,
for (unsigned ArgNo : ArgNos) {
unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
- AttrBuilder B(AttrSets[Index]);
+ AttrBuilder B(C, AttrSets[Index]);
B.addAttribute(A);
AttrSets[Index] = AttributeSet::get(C, B);
}
@@ -1339,7 +1339,7 @@ AttributeList::removeAttributesAtIndex(LLVMContext &C,
AttributeList AttributeList::addDereferenceableRetAttr(LLVMContext &C,
uint64_t Bytes) const {
- AttrBuilder B;
+ AttrBuilder B(C);
B.addDereferenceableAttr(Bytes);
return addRetAttributes(C, B);
}
@@ -1347,7 +1347,7 @@ AttributeList AttributeList::addDereferenceableRetAttr(LLVMContext &C,
AttributeList AttributeList::addDereferenceableParamAttr(LLVMContext &C,
unsigned Index,
uint64_t Bytes) const {
- AttrBuilder B;
+ AttrBuilder B(C);
B.addDereferenceableAttr(Bytes);
return addParamAttributes(C, Index, B);
}
@@ -1355,7 +1355,7 @@ AttributeList AttributeList::addDereferenceableParamAttr(LLVMContext &C,
AttributeList
AttributeList::addDereferenceableOrNullParamAttr(LLVMContext &C, unsigned Index,
uint64_t Bytes) const {
- AttrBuilder B;
+ AttrBuilder B(C);
B.addDereferenceableOrNullAttr(Bytes);
return addParamAttributes(C, Index, B);
}
@@ -1364,7 +1364,7 @@ AttributeList
AttributeList::addAllocSizeParamAttr(LLVMContext &C, unsigned Index,
unsigned ElemSizeArg,
const Optional<unsigned> &NumElemsArg) {
- AttrBuilder B;
+ AttrBuilder B(C);
B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
return addParamAttributes(C, Index, B);
}
@@ -1549,13 +1549,14 @@ LLVM_DUMP_METHOD void AttributeList::dump() const { print(dbgs()); }
//===----------------------------------------------------------------------===//
// FIXME: Remove this ctor, use AttributeSet.
-AttrBuilder::AttrBuilder(AttributeList AL, unsigned Index) {
+AttrBuilder::AttrBuilder(LLVMContext &Ctx, AttributeList AL, unsigned Index)
+ : Ctx(Ctx) {
AttributeSet AS = AL.getAttributes(Index);
for (const auto &A : AS)
addAttribute(A);
}
-AttrBuilder::AttrBuilder(AttributeSet AS) {
+AttrBuilder::AttrBuilder(LLVMContext &Ctx, AttributeSet AS) : Ctx(Ctx) {
for (const auto &A : AS)
addAttribute(A);
}
@@ -1581,9 +1582,22 @@ AttrBuilder::kindToTypeIndex(Attribute::AttrKind Kind) const {
return None;
}
+struct StringAttributeComparator {
+ bool operator()(Attribute A0, Attribute A1) const {
+ return A0.getKindAsString() < A1.getKindAsString();
+ }
+ bool operator()(Attribute A0, StringRef Kind) const {
+ return A0.getKindAsString() < Kind;
+ }
+};
+
AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
if (Attr.isStringAttribute()) {
- addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
+ auto It = lower_bound(TargetDepAttrs, Attr, StringAttributeComparator());
+ if (It != TargetDepAttrs.end() && It->hasAttribute(Attr.getKindAsString()))
+ std::swap(*It, Attr);
+ else
+ TargetDepAttrs.insert(It, Attr);
return *this;
}
@@ -1599,8 +1613,7 @@ AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
}
AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
- TargetDepAttrs[A] = V;
- return *this;
+ return addAttribute(Attribute::get(Ctx, A, V));
}
AttrBuilder &AttrBuilder::removeAttributes(AttributeList AL, uint64_t Index) {
@@ -1621,7 +1634,9 @@ AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
}
AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
- TargetDepAttrs.erase(A);
+ auto It = lower_bound(TargetDepAttrs, A, StringAttributeComparator());
+ if (It != TargetDepAttrs.end() && It->hasAttribute(A))
+ TargetDepAttrs.erase(It);
return *this;
}
@@ -1753,14 +1768,14 @@ AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
Attrs |= B.Attrs;
+ // TODO: could merge both lists in one loop
for (const auto &I : B.td_attrs())
- TargetDepAttrs[I.first] = I.second;
+ addAttribute(I);
return *this;
}
AttrBuilder &AttrBuilder::remove(const AttributeMask &AM) {
- // FIXME: What if both have an int/type attribute, but they don't match?!
for (unsigned Index = 0; Index < Attribute::NumIntAttrKinds; ++Index)
if (AM.contains((Attribute::AttrKind)Index))
IntAttrs[Index] = 0;
@@ -1771,8 +1786,8 @@ AttrBuilder &AttrBuilder::remove(const AttributeMask &AM) {
Attrs &= ~AM.attrs();
- for (const auto &I : AM.td_attrs())
- TargetDepAttrs.erase(I);
+ erase_if(TargetDepAttrs,
+ [&AM](Attribute A) { return AM.contains(A.getKindAsString()); });
return *this;
}
@@ -1784,13 +1799,14 @@ bool AttrBuilder::overlaps(const AttributeMask &AM) const {
// Then check if any target dependent ones do.
for (const auto &I : td_attrs())
- if (AM.contains(I.first))
+ if (AM.contains(I.getKindAsString()))
return true;
return false;
}
bool AttrBuilder::contains(StringRef A) const {
- return TargetDepAttrs.find(A) != TargetDepAttrs.end();
+ auto It = lower_bound(TargetDepAttrs, A, StringAttributeComparator());
+ return It != TargetDepAttrs.end() && It->hasAttribute(A);
}
bool AttrBuilder::hasAttributes() const {
@@ -1818,14 +1834,8 @@ bool AttrBuilder::hasAlignmentAttr() const {
}
bool AttrBuilder::operator==(const AttrBuilder &B) const {
- if (Attrs != B.Attrs)
- return false;
-
- for (const auto &TDA : TargetDepAttrs)
- if (B.TargetDepAttrs.find(TDA.first) == B.TargetDepAttrs.end())
- return false;
-
- return IntAttrs == B.IntAttrs && TypeAttrs == B.TypeAttrs;
+ return Attrs == B.Attrs && IntAttrs == B.IntAttrs &&
+ TypeAttrs == B.TypeAttrs && TargetDepAttrs == B.TargetDepAttrs;
}
//===----------------------------------------------------------------------===//