mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-14 23:48:56 +00:00
[CodeView] Eliminate redundant hashes and allocations.
When writing field list records, we would construct a temporary type serializer that shared a bump ptr allocator with the rest of the application, so anything allocated from here would live forever. Furthermore, this temporary serializer had all the properties of a full blown serializer including record hashing and de-duplication. These features are required when you're merging multiple type streams into each other, because different streams may contain identical records, but records from the same type stream will never collide with each other. So all of this hashing was unnecessary. To solve this, two fixes are made: 1) The temporary serializer keeps its own bump ptr allocator instead of sharing a global one. When it's finished, all of its memory is freed. 2) Instead of using the same temporary serializer for the life of an entire type stream, we use it only for the life of a single field list record and delete it when the field list record is completed. This way the hash table will not grow as other records from the same type stream get inserted. Further improvements could eliminate hashing entirely from this codepath. This reduces the link time by 85% in my test, from 1 minute to 9 seconds. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@303676 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
666fbb4259
commit
87fb2325ec
@ -82,12 +82,13 @@ public:
|
||||
|
||||
class FieldListRecordBuilder {
|
||||
TypeTableBuilder &TypeTable;
|
||||
BumpPtrAllocator Allocator;
|
||||
TypeSerializer TempSerializer;
|
||||
CVType Type;
|
||||
|
||||
public:
|
||||
explicit FieldListRecordBuilder(TypeTableBuilder &TypeTable)
|
||||
: TypeTable(TypeTable), TempSerializer(TypeTable.getAllocator()) {
|
||||
: TypeTable(TypeTable), TempSerializer(Allocator) {
|
||||
Type.Type = TypeLeafKind::LF_FIELDLIST;
|
||||
}
|
||||
|
||||
|
@ -416,6 +416,8 @@ Error TypeStreamMerger::visitKnownRecord(CVType &, FieldListRecord &R) {
|
||||
assert(DestTypeStream);
|
||||
// Visit the members inside the field list.
|
||||
HadUntranslatedMember = false;
|
||||
FieldListBuilder = llvm::make_unique<FieldListRecordBuilder>(*DestTypeStream);
|
||||
|
||||
FieldListBuilder->begin();
|
||||
if (auto EC = codeview::visitMemberRecordStream(R.Data, *this))
|
||||
return EC;
|
||||
@ -428,6 +430,7 @@ Error TypeStreamMerger::visitKnownRecord(CVType &, FieldListRecord &R) {
|
||||
FieldListBuilder->reset();
|
||||
addMapping(DestIdx);
|
||||
|
||||
FieldListBuilder.reset();
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
@ -496,7 +499,6 @@ Error TypeStreamMerger::visitUnknownType(CVType &Rec) {
|
||||
Error TypeStreamMerger::mergeTypeRecords(TypeTableBuilder &Dest,
|
||||
TypeCollection &Types) {
|
||||
DestTypeStream = &Dest;
|
||||
FieldListBuilder = llvm::make_unique<FieldListRecordBuilder>(Dest);
|
||||
|
||||
return doit(Types);
|
||||
}
|
||||
@ -515,7 +517,6 @@ Error TypeStreamMerger::mergeTypesAndIds(TypeTableBuilder &DestIds,
|
||||
TypeCollection &IdsAndTypes) {
|
||||
DestIdStream = &DestIds;
|
||||
DestTypeStream = &DestTypes;
|
||||
FieldListBuilder = llvm::make_unique<FieldListRecordBuilder>(DestTypes);
|
||||
|
||||
return doit(IdsAndTypes);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user