1
0
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:
Nikita Popov 2020-06-14 23:46:18 +02:00
parent 3bda78713b
commit 322957d5ba
2 changed files with 26 additions and 22 deletions

View File

@ -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 *;

View File

@ -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);
}
} }
} }