Skip to content

Commit 1c3fe86

Browse files
committed
[IR] Make Attributes and AttributeLists trivially destructible and BumpPtrAllocate them
1 parent 1428f86 commit 1c3fe86

File tree

3 files changed

+45
-50
lines changed

3 files changed

+45
-50
lines changed

llvm/lib/IR/AttributeImpl.h

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ class AttributeImpl : public FoldingSetNode {
5454
AttributeImpl(const AttributeImpl &) = delete;
5555
AttributeImpl &operator=(const AttributeImpl &) = delete;
5656

57-
virtual ~AttributeImpl();
58-
5957
bool isEnumAttribute() const { return KindID == EnumAttrEntry; }
6058
bool isIntAttribute() const { return KindID == IntAttrEntry; }
6159
bool isStringAttribute() const { return KindID == StringAttrEntry; }
@@ -104,6 +102,9 @@ class AttributeImpl : public FoldingSetNode {
104102
}
105103
};
106104

105+
static_assert(std::is_trivially_destructible<AttributeImpl>::value,
106+
"AttributeImpl should be trivially destructible");
107+
107108
//===----------------------------------------------------------------------===//
108109
/// \class
109110
/// A set of classes that contain the value of the
@@ -112,8 +113,6 @@ class AttributeImpl : public FoldingSetNode {
112113
/// attribute enties, which are for target-dependent attributes.
113114

114115
class EnumAttributeImpl : public AttributeImpl {
115-
virtual void anchor();
116-
117116
Attribute::AttrKind Kind;
118117

119118
protected:
@@ -130,8 +129,6 @@ class EnumAttributeImpl : public AttributeImpl {
130129
class IntAttributeImpl : public EnumAttributeImpl {
131130
uint64_t Val;
132131

133-
void anchor() override;
134-
135132
public:
136133
IntAttributeImpl(Attribute::AttrKind Kind, uint64_t Val)
137134
: EnumAttributeImpl(IntAttrEntry, Kind), Val(Val) {
@@ -142,24 +139,43 @@ class IntAttributeImpl : public EnumAttributeImpl {
142139
uint64_t getValue() const { return Val; }
143140
};
144141

145-
class StringAttributeImpl : public AttributeImpl {
146-
virtual void anchor();
142+
class StringAttributeImpl final
143+
: public AttributeImpl,
144+
private TrailingObjects<StringAttributeImpl, char> {
145+
friend TrailingObjects;
147146

148-
std::string Kind;
149-
std::string Val;
147+
unsigned KindSize;
148+
unsigned ValSize;
149+
size_t numTrailingObjects(OverloadToken<char>) const {
150+
return KindSize + 1 + ValSize + 1;
151+
}
150152

151153
public:
152154
StringAttributeImpl(StringRef Kind, StringRef Val = StringRef())
153-
: AttributeImpl(StringAttrEntry), Kind(std::string(Kind)),
154-
Val(std::string(Val)) {}
155+
: AttributeImpl(StringAttrEntry), KindSize(Kind.size()),
156+
ValSize(Val.size()) {
157+
char *TrailingString = getTrailingObjects<char>();
158+
// Some users rely on zero-termination.
159+
llvm::copy(Kind, TrailingString);
160+
TrailingString[KindSize] = '\0';
161+
llvm::copy(Val, &TrailingString[KindSize + 1]);
162+
TrailingString[KindSize + 1 + ValSize] = '\0';
163+
}
155164

156-
StringRef getStringKind() const { return Kind; }
157-
StringRef getStringValue() const { return Val; }
165+
StringRef getStringKind() const {
166+
return StringRef(getTrailingObjects<char>(), KindSize);
167+
}
168+
StringRef getStringValue() const {
169+
return StringRef(getTrailingObjects<char>() + KindSize + 1, ValSize);
170+
}
171+
172+
static size_t totalSizeToAlloc(StringRef Kind, StringRef Val) {
173+
return TrailingObjects::totalSizeToAlloc<char>(Kind.size() + 1 +
174+
Val.size() + 1);
175+
}
158176
};
159177

160178
class TypeAttributeImpl : public EnumAttributeImpl {
161-
void anchor() override;
162-
163179
Type *Ty;
164180

165181
public:
@@ -265,8 +281,6 @@ class AttributeListImpl final
265281
AttributeListImpl(const AttributeListImpl &) = delete;
266282
AttributeListImpl &operator=(const AttributeListImpl &) = delete;
267283

268-
void operator delete(void *p) { ::operator delete(p); }
269-
270284
/// Get the context that created this AttributeListImpl.
271285
LLVMContext &getContext() { return Context; }
272286

@@ -287,6 +301,9 @@ class AttributeListImpl final
287301
void dump() const;
288302
};
289303

304+
static_assert(std::is_trivially_destructible<AttributeListImpl>::value,
305+
"AttributeListImpl should be trivially destructible");
306+
290307
} // end namespace llvm
291308

292309
#endif // LLVM_LIB_IR_ATTRIBUTEIMPL_H

llvm/lib/IR/Attributes.cpp

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,9 @@ Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
9292
// If we didn't find any existing attributes of the same shape then create a
9393
// new one and insert it.
9494
if (!Val)
95-
PA = new EnumAttributeImpl(Kind);
95+
PA = new (pImpl->Alloc) EnumAttributeImpl(Kind);
9696
else
97-
PA = new IntAttributeImpl(Kind, Val);
97+
PA = new (pImpl->Alloc) IntAttributeImpl(Kind, Val);
9898
pImpl->AttrsSet.InsertNode(PA, InsertPoint);
9999
}
100100

@@ -114,7 +114,10 @@ Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
114114
if (!PA) {
115115
// If we didn't find any existing attributes of the same shape then create a
116116
// new one and insert it.
117-
PA = new StringAttributeImpl(Kind, Val);
117+
void *Mem =
118+
pImpl->Alloc.Allocate(StringAttributeImpl::totalSizeToAlloc(Kind, Val),
119+
alignof(StringAttributeImpl));
120+
PA = new (Mem) StringAttributeImpl(Kind, Val);
118121
pImpl->AttrsSet.InsertNode(PA, InsertPoint);
119122
}
120123

@@ -135,7 +138,7 @@ Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
135138
if (!PA) {
136139
// If we didn't find any existing attributes of the same shape then create a
137140
// new one and insert it.
138-
PA = new TypeAttributeImpl(Kind, Ty);
141+
PA = new (pImpl->Alloc) TypeAttributeImpl(Kind, Ty);
139142
pImpl->AttrsSet.InsertNode(PA, InsertPoint);
140143
}
141144

@@ -554,17 +557,6 @@ void Attribute::Profile(FoldingSetNodeID &ID) const {
554557
// AttributeImpl Definition
555558
//===----------------------------------------------------------------------===//
556559

557-
// Pin the vtables to this file.
558-
AttributeImpl::~AttributeImpl() = default;
559-
560-
void EnumAttributeImpl::anchor() {}
561-
562-
void IntAttributeImpl::anchor() {}
563-
564-
void StringAttributeImpl::anchor() {}
565-
566-
void TypeAttributeImpl::anchor() {}
567-
568560
bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
569561
if (isStringAttribute()) return false;
570562
return getKindAsEnum() == A;
@@ -1040,8 +1032,9 @@ AttributeList AttributeList::getImpl(LLVMContext &C,
10401032
// create a new one and insert it.
10411033
if (!PA) {
10421034
// Coallocate entries after the AttributeListImpl itself.
1043-
void *Mem = ::operator new(
1044-
AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()));
1035+
void *Mem = pImpl->Alloc.Allocate(
1036+
AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()),
1037+
alignof(AttributeListImpl));
10451038
PA = new (Mem) AttributeListImpl(C, AttrSets);
10461039
pImpl->AttrsLists.InsertNode(PA, InsertPoint);
10471040
}

llvm/lib/IR/LLVMContextImpl.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -104,21 +104,6 @@ LLVMContextImpl::~LLVMContextImpl() {
104104
delete CDSConstant.second;
105105
CDSConstants.clear();
106106

107-
// Destroy attributes.
108-
for (FoldingSetIterator<AttributeImpl> I = AttrsSet.begin(),
109-
E = AttrsSet.end(); I != E; ) {
110-
FoldingSetIterator<AttributeImpl> Elem = I++;
111-
delete &*Elem;
112-
}
113-
114-
// Destroy attribute lists.
115-
for (FoldingSetIterator<AttributeListImpl> I = AttrsLists.begin(),
116-
E = AttrsLists.end();
117-
I != E;) {
118-
FoldingSetIterator<AttributeListImpl> Elem = I++;
119-
delete &*Elem;
120-
}
121-
122107
// Destroy attribute node lists.
123108
for (FoldingSetIterator<AttributeSetNode> I = AttrsSetNodes.begin(),
124109
E = AttrsSetNodes.end(); I != E; ) {

0 commit comments

Comments
 (0)