This is an archive of the discontinued LLVM Phabricator instance.

[CodeView Type Merging] Make a Type Index Iterator that bypasses the visitor framework
ClosedPublic

Authored by zturner on May 25 2017, 1:43 PM.

Details

Summary

The visitor abstraction is useful for plugging lots of somewhat related components together, but with abstraction comes a cost in performance. Type Merging is easily the slowest part of a link, so it makes sense to consider whether it's worth sacrifcing abstractional purity in exchange for speed here.

This patch swings completely the opposite direction. It bypasses the TempSerializer, it bypasses the FieldListRecordBuilder, it bypasses the TypeRecordMapping, and it bypasses the visitation switch and instead re-implements the record deserialization switch in a hand rolled algorithm that doesn't care about deserializing at all, but only about knowing what offsets within a record's byte sequence contain type indices.

For field list records in particular, this algorithm also implements the logic of skipping a record to find the next record. This allows us to completely skip the process of deserializing field list records in order to determine what indices to remap, and then re-serializing them. Furthermore, computing "how many bytes is this field list member record" is somewhat faster than actually pulling out all the fields of the record.

The algorithm here simply gets as input a sequence of bytes, and returns as output a list of offsets that we need to remap.

Performance wise, this is a huge win. This is linking lld using clang-cl generated objects and library inputs (so /Z7) before this patch, after this patch, and using MSVC.

MSVC: 25.67s
Before Patch: 18.59s
After Patch: 8.92s

Diff Detail

Repository
rL LLVM

Event Timeline

zturner created this revision.May 25 2017, 1:43 PM
rnk edited edge metadata.May 25 2017, 1:57 PM

Sweet, the minimal thing. :)

llvm/include/llvm/DebugInfo/CodeView/TypeIndexIterator.h
1 ↗(On Diff #100289)

This basically builds a SmallVector. Its... sort of like an iterator. Do we still want to call it one? I feel like "Iterator" has a specific meaning in C++, and this isn't it. Maybe TypeIndexFinder.h to go with findTypeIndexOffsets or something?

Alternatively, do you want to just mush all this functionality into TypeSerializer.h/cpp?

llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
288 ↗(On Diff #100289)

How is this new constructor used? It's reasonable to not force the caller to construct a MemberPointerInfo and instead take both the Class type index and the member pointer representation, but defaulting unknown seems error-prone.

llvm/lib/DebugInfo/CodeView/TypeIndexIterator.cpp
1 ↗(On Diff #100289)

This should have one of those silly LLVM-style comment headers.

272 ↗(On Diff #100289)

If we still had those Layout struct types, we could use offsetof(FuncIdRecord::Layout, ParentScope) etc here to avoid the hardcoded offsets. It would save work when we add new type records. Probably not a change for today, but maybe worth a FIXME comment?

zturner added inline comments.May 25 2017, 2:04 PM
llvm/include/llvm/DebugInfo/CodeView/TypeIndexIterator.h
1 ↗(On Diff #100289)

Yea, I originally intended to give it an iterator like interface, but it was non-trivial and this was just easier. And then I forgot to change the file name. Anyway, yea I'll change it.

llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
288 ↗(On Diff #100289)

It's used in the unit test.

rnk added inline comments.May 25 2017, 2:09 PM
llvm/include/llvm/DebugInfo/CodeView/TypeRecord.h
288 ↗(On Diff #100289)

Got it, I searched for PointerRecord( and got no hits. I'd still prefer to make that constructor call build a MemberPointerInfo().

zturner updated this revision to Diff 100305.May 25 2017, 2:49 PM

Getting a crash with this in llvm-readobj, so I need to fix that and will upload a new version.

zturner updated this revision to Diff 100313.May 25 2017, 3:21 PM

Fix the crasher. It was because we were only handling LF_CLASS, but not LF_STRUCTURE which has the same format. Added a unit test for this.

rnk accepted this revision.May 25 2017, 4:15 PM

lgtm!

This revision is now accepted and ready to land.May 25 2017, 4:15 PM
This revision was automatically updated to reflect the committed changes.