forked from OSchip/llvm-project
[IR] Since AttributeSets are sorted, binary search them.
Not likely to make a big difference, but there's a fair bit of pointer chasing in large sets.
This commit is contained in:
parent
a3c964a278
commit
e3306c56b3
|
@ -188,6 +188,7 @@ class AttributeSetNode final
|
|||
|
||||
static AttributeSetNode *getSorted(LLVMContext &C,
|
||||
ArrayRef<Attribute> SortedAttrs);
|
||||
Optional<Attribute> findEnumAttribute(Attribute::AttrKind Kind) const;
|
||||
|
||||
public:
|
||||
// AttributesSetNode is uniqued, these should not be available.
|
||||
|
|
|
@ -867,12 +867,26 @@ bool AttributeSetNode::hasAttribute(StringRef Kind) const {
|
|||
return StringAttrs.count(Kind);
|
||||
}
|
||||
|
||||
Optional<Attribute>
|
||||
AttributeSetNode::findEnumAttribute(Attribute::AttrKind Kind) const {
|
||||
// Do a quick presence check.
|
||||
if (!hasAttribute(Kind))
|
||||
return None;
|
||||
|
||||
// Attributes in a set are sorted by enum value, followed by string
|
||||
// attributes. Binary search the one we want.
|
||||
const Attribute *I =
|
||||
std::lower_bound(begin(), end() - StringAttrs.size(), Kind,
|
||||
[](Attribute A, Attribute::AttrKind Kind) {
|
||||
return A.getKindAsEnum() < Kind;
|
||||
});
|
||||
assert(I != end() && I->hasAttribute(Kind) && "Presence check failed?");
|
||||
return *I;
|
||||
}
|
||||
|
||||
Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
|
||||
if (hasAttribute(Kind)) {
|
||||
for (const auto &I : *this)
|
||||
if (I.hasAttribute(Kind))
|
||||
return I;
|
||||
}
|
||||
if (auto A = findEnumAttribute(Kind))
|
||||
return *A;
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -881,45 +895,39 @@ Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
|
|||
}
|
||||
|
||||
MaybeAlign AttributeSetNode::getAlignment() const {
|
||||
for (const auto &I : *this)
|
||||
if (I.hasAttribute(Attribute::Alignment))
|
||||
return I.getAlignment();
|
||||
if (auto A = findEnumAttribute(Attribute::Alignment))
|
||||
return A->getAlignment();
|
||||
return None;
|
||||
}
|
||||
|
||||
MaybeAlign AttributeSetNode::getStackAlignment() const {
|
||||
for (const auto &I : *this)
|
||||
if (I.hasAttribute(Attribute::StackAlignment))
|
||||
return I.getStackAlignment();
|
||||
if (auto A = findEnumAttribute(Attribute::StackAlignment))
|
||||
return A->getStackAlignment();
|
||||
return None;
|
||||
}
|
||||
|
||||
Type *AttributeSetNode::getByValType() const {
|
||||
for (const auto &I : *this)
|
||||
if (I.hasAttribute(Attribute::ByVal))
|
||||
return I.getValueAsType();
|
||||
if (auto A = findEnumAttribute(Attribute::ByVal))
|
||||
return A->getValueAsType();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t AttributeSetNode::getDereferenceableBytes() const {
|
||||
for (const auto &I : *this)
|
||||
if (I.hasAttribute(Attribute::Dereferenceable))
|
||||
return I.getDereferenceableBytes();
|
||||
if (auto A = findEnumAttribute(Attribute::Dereferenceable))
|
||||
return A->getDereferenceableBytes();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
|
||||
for (const auto &I : *this)
|
||||
if (I.hasAttribute(Attribute::DereferenceableOrNull))
|
||||
return I.getDereferenceableOrNullBytes();
|
||||
if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
|
||||
return A->getDereferenceableOrNullBytes();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::pair<unsigned, Optional<unsigned>>
|
||||
AttributeSetNode::getAllocSizeArgs() const {
|
||||
for (const auto &I : *this)
|
||||
if (I.hasAttribute(Attribute::AllocSize))
|
||||
return I.getAllocSizeArgs();
|
||||
if (auto A = findEnumAttribute(Attribute::AllocSize))
|
||||
return A->getAllocSizeArgs();
|
||||
return std::make_pair(0, 0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue