summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Ganea <alexandre.ganea@ubisoft.com>2021-01-13 14:34:43 -0500
committerAlexandre Ganea <alexandre.ganea@ubisoft.com>2021-01-13 14:35:03 -0500
commite7a371f9fd0076c187f4cd1a9c7546867faeb19b (patch)
tree5c42e005f995cbd3ff4b5b52cc340aaf2f1a7ce8
parent3bd620d4504915615b8368b20eb9e5c34f3fb779 (diff)
downloadllvm-e7a371f9fd0076c187f4cd1a9c7546867faeb19b.tar.gz
[LLD][COFF] Avoid std::vector resizes during type merging
Consistently saves approx. 0.6 sec (out of 18 sec) on a large output (400 MB EXE, 2 GB PDB). Differential Revision: https://reviews.llvm.org/D94555
-rw-r--r--lld/COFF/DebugTypes.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/lld/COFF/DebugTypes.cpp b/lld/COFF/DebugTypes.cpp
index 52c24aaf214f..fedcb054540f 100644
--- a/lld/COFF/DebugTypes.cpp
+++ b/lld/COFF/DebugTypes.cpp
@@ -679,6 +679,26 @@ void TpiSource::mergeUniqueTypeRecords(ArrayRef<uint8_t> typeRecords,
auto nextUniqueIndex = uniqueTypes.begin();
assert(mergedTpi.recs.empty());
assert(mergedIpi.recs.empty());
+
+ // Pre-compute the number of elements in advance to avoid std::vector resizes.
+ unsigned nbTpiRecs = 0;
+ unsigned nbIpiRecs = 0;
+ forEachTypeChecked(typeRecords, [&](const CVType &ty) {
+ if (nextUniqueIndex != uniqueTypes.end() &&
+ *nextUniqueIndex == ghashIndex) {
+ assert(ty.length() <= codeview::MaxRecordLength);
+ size_t newSize = alignTo(ty.length(), 4);
+ (isIdRecord(ty.kind()) ? nbIpiRecs : nbTpiRecs) += newSize;
+ ++nextUniqueIndex;
+ }
+ ++ghashIndex;
+ });
+ mergedTpi.recs.reserve(nbTpiRecs);
+ mergedIpi.recs.reserve(nbIpiRecs);
+
+ // Do the actual type merge.
+ ghashIndex = 0;
+ nextUniqueIndex = uniqueTypes.begin();
forEachTypeChecked(typeRecords, [&](const CVType &ty) {
if (nextUniqueIndex != uniqueTypes.end() &&
*nextUniqueIndex == ghashIndex) {