[CodeView Type Merging] Don't keep re-allocating temp serializer.
Previously, every time we wanted to serialize a field list record, we would create a new copy of FieldListRecordBuilder, which would in turn create a temporary instance of TypeSerializer, which itself had a std::vector<> that was about 128K in size. So this 128K allocation was happening every time. We can re-use the same instance over and over, we just have to clear its internal hash table and seen records list between each run. This saves us from the constant re-allocations. This is worth an ~18.5% speed increase (3.75s -> 3.05s) in my tests. Differential Revision: https://reviews.llvm.org/D33506 llvm-svn: 303919
This commit is contained in:
parent
95c625ecc9
commit
7f97c362a4
|
@ -84,6 +84,8 @@ public:
|
|||
explicit TypeSerializer(BumpPtrAllocator &Storage, bool Hash = true);
|
||||
~TypeSerializer();
|
||||
|
||||
void reset();
|
||||
|
||||
ArrayRef<ArrayRef<uint8_t>> records() const;
|
||||
TypeIndex insertRecordBytes(ArrayRef<uint8_t> &Record);
|
||||
TypeIndex insertRecord(const RemappedType &Record);
|
||||
|
|
|
@ -97,6 +97,8 @@ public:
|
|||
}
|
||||
|
||||
void begin() {
|
||||
TempSerializer.reset();
|
||||
|
||||
if (auto EC = TempSerializer.visitTypeBegin(Type))
|
||||
consumeError(std::move(EC));
|
||||
}
|
||||
|
@ -112,23 +114,19 @@ public:
|
|||
consumeError(std::move(EC));
|
||||
}
|
||||
|
||||
TypeIndex end() {
|
||||
TypeIndex end(bool Write) {
|
||||
TypeIndex Index;
|
||||
if (auto EC = TempSerializer.visitTypeEnd(Type)) {
|
||||
consumeError(std::move(EC));
|
||||
return TypeIndex();
|
||||
}
|
||||
|
||||
TypeIndex Index;
|
||||
for (auto Record : TempSerializer.records()) {
|
||||
Index = TypeTable.writeSerializedRecord(Record);
|
||||
if (Write) {
|
||||
for (auto Record : TempSerializer.records())
|
||||
Index = TypeTable.writeSerializedRecord(Record);
|
||||
}
|
||||
return Index;
|
||||
}
|
||||
|
||||
/// Stop building the record.
|
||||
void reset() {
|
||||
if (auto EC = TempSerializer.visitTypeEnd(Type))
|
||||
consumeError(std::move(EC));
|
||||
return Index;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1562,7 +1562,7 @@ TypeIndex CodeViewDebug::lowerTypeEnum(const DICompositeType *Ty) {
|
|||
EnumeratorCount++;
|
||||
}
|
||||
}
|
||||
FTI = FLRB.end();
|
||||
FTI = FLRB.end(true);
|
||||
}
|
||||
|
||||
std::string FullName = getFullyQualifiedName(Ty);
|
||||
|
@ -1869,7 +1869,7 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
|
|||
MemberCount++;
|
||||
}
|
||||
|
||||
TypeIndex FieldTI = FLBR.end();
|
||||
TypeIndex FieldTI = FLBR.end(true);
|
||||
return std::make_tuple(FieldTI, Info.VShapeTI, MemberCount,
|
||||
!Info.NestedClasses.empty());
|
||||
}
|
||||
|
|
|
@ -78,6 +78,8 @@ private:
|
|||
public:
|
||||
TypeHasher(BumpPtrAllocator &RecordStorage) : RecordStorage(RecordStorage) {}
|
||||
|
||||
void reset() { HashedRecords.clear(); }
|
||||
|
||||
/// Takes the bytes of type record, inserts them into the hash table, saves
|
||||
/// them, and returns a pointer to an identical stable type record along with
|
||||
/// its type index in the destination stream.
|
||||
|
@ -172,6 +174,17 @@ ArrayRef<ArrayRef<uint8_t>> TypeSerializer::records() const {
|
|||
return SeenRecords;
|
||||
}
|
||||
|
||||
void TypeSerializer::reset() {
|
||||
if (Hasher)
|
||||
Hasher->reset();
|
||||
Writer.setOffset(0);
|
||||
CurrentSegment = RecordSegment();
|
||||
FieldListSegments.clear();
|
||||
TypeKind.reset();
|
||||
MemberKind.reset();
|
||||
SeenRecords.clear();
|
||||
}
|
||||
|
||||
TypeIndex TypeSerializer::insertRecordBytes(ArrayRef<uint8_t> &Record) {
|
||||
assert(!TypeKind.hasValue() && "Already in a type mapping!");
|
||||
assert(Writer.getOffset() == 0 && "Stream has data already!");
|
||||
|
|
|
@ -490,21 +490,18 @@ Error TypeStreamMerger::visitKnownRecord(CVType &CVR, FieldListRecord &R) {
|
|||
assert(DestTypeStream);
|
||||
// Visit the members inside the field list.
|
||||
HadUntranslatedMember = false;
|
||||
FieldListBuilder = llvm::make_unique<FieldListRecordBuilder>(*DestTypeStream);
|
||||
if (!FieldListBuilder)
|
||||
FieldListBuilder =
|
||||
llvm::make_unique<FieldListRecordBuilder>(*DestTypeStream);
|
||||
|
||||
FieldListBuilder->begin();
|
||||
if (auto EC = codeview::visitMemberRecordStream(CVR.content(), *this))
|
||||
return EC;
|
||||
|
||||
// Write the record if we translated all field list members.
|
||||
TypeIndex DestIdx = Untranslated;
|
||||
if (!HadUntranslatedMember)
|
||||
DestIdx = FieldListBuilder->end();
|
||||
else
|
||||
FieldListBuilder->reset();
|
||||
addMapping(DestIdx);
|
||||
TypeIndex DestIdx = FieldListBuilder->end(!HadUntranslatedMember);
|
||||
addMapping(HadUntranslatedMember ? Untranslated : DestIdx);
|
||||
|
||||
FieldListBuilder.reset();
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue