mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[IR] Add AttributeBitSet wrapper (NFC)
This wraps the uint8_t[12] type used in two places, because I plan to introduce a third use of the same pattern.
This commit is contained in:
parent
3bda78713b
commit
322957d5ba
@ -185,6 +185,22 @@ public:
|
|||||||
Type *getTypeValue() const { return Ty; }
|
Type *getTypeValue() const { return Ty; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class AttributeBitSet {
|
||||||
|
/// Bitset with a bit for each available attribute Attribute::AttrKind.
|
||||||
|
uint8_t AvailableAttrs[12] = {};
|
||||||
|
static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) * CHAR_BIT,
|
||||||
|
"Too many attributes");
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool hasAttribute(Attribute::AttrKind Kind) const {
|
||||||
|
return AvailableAttrs[Kind / 8] & ((uint64_t)1) << (Kind % 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addAttribute(Attribute::AttrKind Kind) {
|
||||||
|
AvailableAttrs[Kind / 8] |= 1ULL << (Kind % 8);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
/// \class
|
/// \class
|
||||||
/// This class represents a group of attributes that apply to one
|
/// This class represents a group of attributes that apply to one
|
||||||
@ -195,8 +211,7 @@ class AttributeSetNode final
|
|||||||
friend TrailingObjects;
|
friend TrailingObjects;
|
||||||
|
|
||||||
unsigned NumAttrs; ///< Number of attributes in this node.
|
unsigned NumAttrs; ///< Number of attributes in this node.
|
||||||
/// Bitset with a bit for each available attribute Attribute::AttrKind.
|
AttributeBitSet AvailableAttrs; ///< Available enum attributes.
|
||||||
uint8_t AvailableAttrs[12] = {};
|
|
||||||
|
|
||||||
DenseMap<StringRef, Attribute> StringAttrs;
|
DenseMap<StringRef, Attribute> StringAttrs;
|
||||||
|
|
||||||
@ -221,7 +236,7 @@ public:
|
|||||||
unsigned getNumAttributes() const { return NumAttrs; }
|
unsigned getNumAttributes() const { return NumAttrs; }
|
||||||
|
|
||||||
bool hasAttribute(Attribute::AttrKind Kind) const {
|
bool hasAttribute(Attribute::AttrKind Kind) const {
|
||||||
return AvailableAttrs[Kind / 8] & ((uint64_t)1) << (Kind % 8);
|
return AvailableAttrs.hasAttribute(Kind);
|
||||||
}
|
}
|
||||||
bool hasAttribute(StringRef Kind) const;
|
bool hasAttribute(StringRef Kind) const;
|
||||||
bool hasAttributes() const { return NumAttrs != 0; }
|
bool hasAttributes() const { return NumAttrs != 0; }
|
||||||
@ -265,8 +280,8 @@ class AttributeListImpl final
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned NumAttrSets; ///< Number of entries in this set.
|
unsigned NumAttrSets; ///< Number of entries in this set.
|
||||||
/// Bitset with a bit for each available attribute Attribute::AttrKind.
|
/// Available enum function attributes.
|
||||||
uint8_t AvailableFunctionAttrs[12] = {};
|
AttributeBitSet AvailableFunctionAttrs;
|
||||||
|
|
||||||
// Helper fn for TrailingObjects class.
|
// Helper fn for TrailingObjects class.
|
||||||
size_t numTrailingObjects(OverloadToken<AttributeSet>) { return NumAttrSets; }
|
size_t numTrailingObjects(OverloadToken<AttributeSet>) { return NumAttrSets; }
|
||||||
@ -281,7 +296,7 @@ public:
|
|||||||
/// Return true if the AttributeSet or the FunctionIndex has an
|
/// Return true if the AttributeSet or the FunctionIndex has an
|
||||||
/// enum attribute of the given kind.
|
/// enum attribute of the given kind.
|
||||||
bool hasFnAttribute(Attribute::AttrKind Kind) const {
|
bool hasFnAttribute(Attribute::AttrKind Kind) const {
|
||||||
return AvailableFunctionAttrs[Kind / 8] & ((uint64_t)1) << (Kind % 8);
|
return AvailableFunctionAttrs.hasAttribute(Kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
using iterator = const AttributeSet *;
|
using iterator = const AttributeSet *;
|
||||||
|
@ -780,17 +780,11 @@ AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
|
|||||||
// There's memory after the node where we can store the entries in.
|
// There's memory after the node where we can store the entries in.
|
||||||
llvm::copy(Attrs, getTrailingObjects<Attribute>());
|
llvm::copy(Attrs, getTrailingObjects<Attribute>());
|
||||||
|
|
||||||
static_assert(Attribute::EndAttrKinds <=
|
|
||||||
sizeof(AvailableAttrs) * CHAR_BIT,
|
|
||||||
"Too many attributes");
|
|
||||||
|
|
||||||
for (const auto &I : *this) {
|
for (const auto &I : *this) {
|
||||||
if (I.isStringAttribute()) {
|
if (I.isStringAttribute())
|
||||||
StringAttrs.insert({ I.getKindAsString(), I });
|
StringAttrs.insert({ I.getKindAsString(), I });
|
||||||
} else {
|
else
|
||||||
Attribute::AttrKind Kind = I.getKindAsEnum();
|
AvailableAttrs.addAttribute(I.getKindAsEnum());
|
||||||
AvailableAttrs[Kind / 8] |= 1ULL << (Kind % 8);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -986,16 +980,11 @@ AttributeListImpl::AttributeListImpl(ArrayRef<AttributeSet> Sets)
|
|||||||
llvm::copy(Sets, getTrailingObjects<AttributeSet>());
|
llvm::copy(Sets, getTrailingObjects<AttributeSet>());
|
||||||
|
|
||||||
// Initialize AvailableFunctionAttrs summary bitset.
|
// Initialize AvailableFunctionAttrs summary bitset.
|
||||||
static_assert(Attribute::EndAttrKinds <=
|
|
||||||
sizeof(AvailableFunctionAttrs) * CHAR_BIT,
|
|
||||||
"Too many attributes");
|
|
||||||
static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U,
|
static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U,
|
||||||
"function should be stored in slot 0");
|
"function should be stored in slot 0");
|
||||||
for (const auto &I : Sets[0]) {
|
for (const auto &I : Sets[0]) {
|
||||||
if (!I.isStringAttribute()) {
|
if (!I.isStringAttribute())
|
||||||
Attribute::AttrKind Kind = I.getKindAsEnum();
|
AvailableFunctionAttrs.addAttribute(I.getKindAsEnum());
|
||||||
AvailableFunctionAttrs[Kind / 8] |= 1ULL << (Kind % 8);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user