[IR] Make Attributes and AttributeLists trivially destructible and BumpPtrAllocate them

This commit is contained in:
Benjamin Kramer 2020-05-01 14:12:17 +02:00
parent 1428f86cf9
commit 1c3fe86f0f
3 changed files with 45 additions and 50 deletions

View File

@ -54,8 +54,6 @@ public:
AttributeImpl(const AttributeImpl &) = delete; AttributeImpl(const AttributeImpl &) = delete;
AttributeImpl &operator=(const AttributeImpl &) = delete; AttributeImpl &operator=(const AttributeImpl &) = delete;
virtual ~AttributeImpl();
bool isEnumAttribute() const { return KindID == EnumAttrEntry; } bool isEnumAttribute() const { return KindID == EnumAttrEntry; }
bool isIntAttribute() const { return KindID == IntAttrEntry; } bool isIntAttribute() const { return KindID == IntAttrEntry; }
bool isStringAttribute() const { return KindID == StringAttrEntry; } bool isStringAttribute() const { return KindID == StringAttrEntry; }
@ -104,6 +102,9 @@ public:
} }
}; };
static_assert(std::is_trivially_destructible<AttributeImpl>::value,
"AttributeImpl should be trivially destructible");
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// \class /// \class
/// A set of classes that contain the value of the /// A set of classes that contain the value of the
@ -112,8 +113,6 @@ public:
/// attribute enties, which are for target-dependent attributes. /// attribute enties, which are for target-dependent attributes.
class EnumAttributeImpl : public AttributeImpl { class EnumAttributeImpl : public AttributeImpl {
virtual void anchor();
Attribute::AttrKind Kind; Attribute::AttrKind Kind;
protected: protected:
@ -130,8 +129,6 @@ public:
class IntAttributeImpl : public EnumAttributeImpl { class IntAttributeImpl : public EnumAttributeImpl {
uint64_t Val; uint64_t Val;
void anchor() override;
public: public:
IntAttributeImpl(Attribute::AttrKind Kind, uint64_t Val) IntAttributeImpl(Attribute::AttrKind Kind, uint64_t Val)
: EnumAttributeImpl(IntAttrEntry, Kind), Val(Val) { : EnumAttributeImpl(IntAttrEntry, Kind), Val(Val) {
@ -142,24 +139,43 @@ public:
uint64_t getValue() const { return Val; } uint64_t getValue() const { return Val; }
}; };
class StringAttributeImpl : public AttributeImpl { class StringAttributeImpl final
virtual void anchor(); : public AttributeImpl,
private TrailingObjects<StringAttributeImpl, char> {
friend TrailingObjects;
std::string Kind; unsigned KindSize;
std::string Val; unsigned ValSize;
size_t numTrailingObjects(OverloadToken<char>) const {
return KindSize + 1 + ValSize + 1;
}
public: public:
StringAttributeImpl(StringRef Kind, StringRef Val = StringRef()) StringAttributeImpl(StringRef Kind, StringRef Val = StringRef())
: AttributeImpl(StringAttrEntry), Kind(std::string(Kind)), : AttributeImpl(StringAttrEntry), KindSize(Kind.size()),
Val(std::string(Val)) {} ValSize(Val.size()) {
char *TrailingString = getTrailingObjects<char>();
// Some users rely on zero-termination.
llvm::copy(Kind, TrailingString);
TrailingString[KindSize] = '\0';
llvm::copy(Val, &TrailingString[KindSize + 1]);
TrailingString[KindSize + 1 + ValSize] = '\0';
}
StringRef getStringKind() const { return Kind; } StringRef getStringKind() const {
StringRef getStringValue() const { return Val; } return StringRef(getTrailingObjects<char>(), KindSize);
}
StringRef getStringValue() const {
return StringRef(getTrailingObjects<char>() + KindSize + 1, ValSize);
}
static size_t totalSizeToAlloc(StringRef Kind, StringRef Val) {
return TrailingObjects::totalSizeToAlloc<char>(Kind.size() + 1 +
Val.size() + 1);
}
}; };
class TypeAttributeImpl : public EnumAttributeImpl { class TypeAttributeImpl : public EnumAttributeImpl {
void anchor() override;
Type *Ty; Type *Ty;
public: public:
@ -265,8 +281,6 @@ public:
AttributeListImpl(const AttributeListImpl &) = delete; AttributeListImpl(const AttributeListImpl &) = delete;
AttributeListImpl &operator=(const AttributeListImpl &) = delete; AttributeListImpl &operator=(const AttributeListImpl &) = delete;
void operator delete(void *p) { ::operator delete(p); }
/// Get the context that created this AttributeListImpl. /// Get the context that created this AttributeListImpl.
LLVMContext &getContext() { return Context; } LLVMContext &getContext() { return Context; }
@ -287,6 +301,9 @@ public:
void dump() const; void dump() const;
}; };
static_assert(std::is_trivially_destructible<AttributeListImpl>::value,
"AttributeListImpl should be trivially destructible");
} // end namespace llvm } // end namespace llvm
#endif // LLVM_LIB_IR_ATTRIBUTEIMPL_H #endif // LLVM_LIB_IR_ATTRIBUTEIMPL_H

View File

@ -92,9 +92,9 @@ Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
// If we didn't find any existing attributes of the same shape then create a // If we didn't find any existing attributes of the same shape then create a
// new one and insert it. // new one and insert it.
if (!Val) if (!Val)
PA = new EnumAttributeImpl(Kind); PA = new (pImpl->Alloc) EnumAttributeImpl(Kind);
else else
PA = new IntAttributeImpl(Kind, Val); PA = new (pImpl->Alloc) IntAttributeImpl(Kind, Val);
pImpl->AttrsSet.InsertNode(PA, InsertPoint); pImpl->AttrsSet.InsertNode(PA, InsertPoint);
} }
@ -114,7 +114,10 @@ Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
if (!PA) { if (!PA) {
// If we didn't find any existing attributes of the same shape then create a // If we didn't find any existing attributes of the same shape then create a
// new one and insert it. // new one and insert it.
PA = new StringAttributeImpl(Kind, Val); void *Mem =
pImpl->Alloc.Allocate(StringAttributeImpl::totalSizeToAlloc(Kind, Val),
alignof(StringAttributeImpl));
PA = new (Mem) StringAttributeImpl(Kind, Val);
pImpl->AttrsSet.InsertNode(PA, InsertPoint); pImpl->AttrsSet.InsertNode(PA, InsertPoint);
} }
@ -135,7 +138,7 @@ Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
if (!PA) { if (!PA) {
// If we didn't find any existing attributes of the same shape then create a // If we didn't find any existing attributes of the same shape then create a
// new one and insert it. // new one and insert it.
PA = new TypeAttributeImpl(Kind, Ty); PA = new (pImpl->Alloc) TypeAttributeImpl(Kind, Ty);
pImpl->AttrsSet.InsertNode(PA, InsertPoint); pImpl->AttrsSet.InsertNode(PA, InsertPoint);
} }
@ -554,17 +557,6 @@ void Attribute::Profile(FoldingSetNodeID &ID) const {
// AttributeImpl Definition // AttributeImpl Definition
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Pin the vtables to this file.
AttributeImpl::~AttributeImpl() = default;
void EnumAttributeImpl::anchor() {}
void IntAttributeImpl::anchor() {}
void StringAttributeImpl::anchor() {}
void TypeAttributeImpl::anchor() {}
bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const { bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
if (isStringAttribute()) return false; if (isStringAttribute()) return false;
return getKindAsEnum() == A; return getKindAsEnum() == A;
@ -1040,8 +1032,9 @@ AttributeList AttributeList::getImpl(LLVMContext &C,
// create a new one and insert it. // create a new one and insert it.
if (!PA) { if (!PA) {
// Coallocate entries after the AttributeListImpl itself. // Coallocate entries after the AttributeListImpl itself.
void *Mem = ::operator new( void *Mem = pImpl->Alloc.Allocate(
AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size())); AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()),
alignof(AttributeListImpl));
PA = new (Mem) AttributeListImpl(C, AttrSets); PA = new (Mem) AttributeListImpl(C, AttrSets);
pImpl->AttrsLists.InsertNode(PA, InsertPoint); pImpl->AttrsLists.InsertNode(PA, InsertPoint);
} }

View File

@ -104,21 +104,6 @@ LLVMContextImpl::~LLVMContextImpl() {
delete CDSConstant.second; delete CDSConstant.second;
CDSConstants.clear(); CDSConstants.clear();
// Destroy attributes.
for (FoldingSetIterator<AttributeImpl> I = AttrsSet.begin(),
E = AttrsSet.end(); I != E; ) {
FoldingSetIterator<AttributeImpl> Elem = I++;
delete &*Elem;
}
// Destroy attribute lists.
for (FoldingSetIterator<AttributeListImpl> I = AttrsLists.begin(),
E = AttrsLists.end();
I != E;) {
FoldingSetIterator<AttributeListImpl> Elem = I++;
delete &*Elem;
}
// Destroy attribute node lists. // Destroy attribute node lists.
for (FoldingSetIterator<AttributeSetNode> I = AttrsSetNodes.begin(), for (FoldingSetIterator<AttributeSetNode> I = AttrsSetNodes.begin(),
E = AttrsSetNodes.end(); I != E; ) { E = AttrsSetNodes.end(); I != E; ) {