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,
|
static AttributeSetNode *getSorted(LLVMContext &C,
|
||||||
ArrayRef<Attribute> SortedAttrs);
|
ArrayRef<Attribute> SortedAttrs);
|
||||||
|
Optional<Attribute> findEnumAttribute(Attribute::AttrKind Kind) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// AttributesSetNode is uniqued, these should not be available.
|
// AttributesSetNode is uniqued, these should not be available.
|
||||||
|
|
|
@ -867,12 +867,26 @@ bool AttributeSetNode::hasAttribute(StringRef Kind) const {
|
||||||
return StringAttrs.count(Kind);
|
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 {
|
Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
|
||||||
if (hasAttribute(Kind)) {
|
if (auto A = findEnumAttribute(Kind))
|
||||||
for (const auto &I : *this)
|
return *A;
|
||||||
if (I.hasAttribute(Kind))
|
|
||||||
return I;
|
|
||||||
}
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -881,45 +895,39 @@ Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeAlign AttributeSetNode::getAlignment() const {
|
MaybeAlign AttributeSetNode::getAlignment() const {
|
||||||
for (const auto &I : *this)
|
if (auto A = findEnumAttribute(Attribute::Alignment))
|
||||||
if (I.hasAttribute(Attribute::Alignment))
|
return A->getAlignment();
|
||||||
return I.getAlignment();
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeAlign AttributeSetNode::getStackAlignment() const {
|
MaybeAlign AttributeSetNode::getStackAlignment() const {
|
||||||
for (const auto &I : *this)
|
if (auto A = findEnumAttribute(Attribute::StackAlignment))
|
||||||
if (I.hasAttribute(Attribute::StackAlignment))
|
return A->getStackAlignment();
|
||||||
return I.getStackAlignment();
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type *AttributeSetNode::getByValType() const {
|
Type *AttributeSetNode::getByValType() const {
|
||||||
for (const auto &I : *this)
|
if (auto A = findEnumAttribute(Attribute::ByVal))
|
||||||
if (I.hasAttribute(Attribute::ByVal))
|
return A->getValueAsType();
|
||||||
return I.getValueAsType();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t AttributeSetNode::getDereferenceableBytes() const {
|
uint64_t AttributeSetNode::getDereferenceableBytes() const {
|
||||||
for (const auto &I : *this)
|
if (auto A = findEnumAttribute(Attribute::Dereferenceable))
|
||||||
if (I.hasAttribute(Attribute::Dereferenceable))
|
return A->getDereferenceableBytes();
|
||||||
return I.getDereferenceableBytes();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
|
uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
|
||||||
for (const auto &I : *this)
|
if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
|
||||||
if (I.hasAttribute(Attribute::DereferenceableOrNull))
|
return A->getDereferenceableOrNullBytes();
|
||||||
return I.getDereferenceableOrNullBytes();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<unsigned, Optional<unsigned>>
|
std::pair<unsigned, Optional<unsigned>>
|
||||||
AttributeSetNode::getAllocSizeArgs() const {
|
AttributeSetNode::getAllocSizeArgs() const {
|
||||||
for (const auto &I : *this)
|
if (auto A = findEnumAttribute(Attribute::AllocSize))
|
||||||
if (I.hasAttribute(Attribute::AllocSize))
|
return A->getAllocSizeArgs();
|
||||||
return I.getAllocSizeArgs();
|
|
||||||
return std::make_pair(0, 0);
|
return std::make_pair(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue