-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[LLD][COFF] Make /summary
work when /debug
isn't provided
#157476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Previously, `/summary` was meant to print some PDB information. Now move handling of `/summary` to `Writer.cpp` so that the flag will have an effect when `/debug` isn't provided. This will also provide grounds for extending with more general information.
@llvm/pr-subscribers-platform-windows @llvm/pr-subscribers-lld Author: Alexandre Ganea (aganea) ChangesPreviously, Full diff: https://github.com/llvm/llvm-project/pull/157476.diff 7 Files Affected:
diff --git a/lld/COFF/COFFLinkerContext.h b/lld/COFF/COFFLinkerContext.h
index b44263b5a3390..0f8f2062b9f2e 100644
--- a/lld/COFF/COFFLinkerContext.h
+++ b/lld/COFF/COFFLinkerContext.h
@@ -14,6 +14,7 @@
#include "DebugTypes.h"
#include "Driver.h"
#include "InputFiles.h"
+#include "PDB.h"
#include "SymbolTable.h"
#include "Writer.h"
#include "lld/Common/CommonLinkerContext.h"
@@ -113,6 +114,8 @@ class COFFLinkerContext : public CommonLinkerContext {
Timer tpiStreamLayoutTimer;
Timer diskCommitTimer;
+ std::optional<PDBStats> pdbStats;
+
Configuration config;
DynamicRelocsChunk *dynamicRelocs = nullptr;
diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp
index e5c62af28fdd2..fd54d20da3ccd 100644
--- a/lld/COFF/PDB.cpp
+++ b/lld/COFF/PDB.cpp
@@ -44,7 +44,6 @@
#include "llvm/Object/CVDebugRecord.h"
#include "llvm/Support/CRC.h"
#include "llvm/Support/Endian.h"
-#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/ScopedPrinter.h"
@@ -133,8 +132,8 @@ class PDBLinker {
/// Write the PDB to disk and store the Guid generated for it in *Guid.
void commit(codeview::GUID *guid);
- // Print statistics regarding the final PDB
- void printStats();
+ // Collect some statistics regarding the final PDB
+ void collectStats();
private:
void pdbMakeAbsolute(SmallVectorImpl<char> &fileName);
@@ -154,13 +153,6 @@ class PDBLinker {
DebugStringTableSubsection pdbStrTab;
llvm::SmallString<128> nativePath;
-
- // For statistics
- uint64_t globalSymbols = 0;
- uint64_t moduleSymbols = 0;
- uint64_t publicSymbols = 0;
- uint64_t nbTypeRecords = 0;
- uint64_t nbTypeRecordsBytes = 0;
};
/// Represents an unrelocated DEBUG_S_FRAMEDATA subsection.
@@ -610,7 +602,9 @@ void PDBLinker::analyzeSymbolSubsection(
addGlobalSymbol(builder.getGsiBuilder(),
file->moduleDBI->getModuleIndex(), moduleSymOffset,
storage);
- ++globalSymbols;
+
+ if (ctx.pdbStats.has_value())
+ ++ctx.pdbStats->globalSymbols;
}
// Update the module stream offset and record any string table index
@@ -619,7 +613,9 @@ void PDBLinker::analyzeSymbolSubsection(
if (symbolGoesInModuleStream(sym, scopeLevel)) {
recordStringTableReferences(sym, moduleSymOffset, stringTableFixups);
moduleSymOffset += alignedSize;
- ++moduleSymbols;
+
+ if (ctx.pdbStats.has_value())
+ ++ctx.pdbStats->moduleSymbols;
}
return Error::success();
@@ -1192,10 +1188,10 @@ void PDBLinker::addObjectsToPDB() {
}
}
- if (ctx.config.showSummary) {
+ if (ctx.pdbStats.has_value()) {
for (TpiSource *source : ctx.tpiSourceList) {
- nbTypeRecords += source->nbTypeRecords;
- nbTypeRecordsBytes += source->nbTypeRecordsBytes;
+ ctx.pdbStats->nbTypeRecords += source->nbTypeRecords;
+ ctx.pdbStats->nbTypeRecordsBytes += source->nbTypeRecordsBytes;
}
}
}
@@ -1231,43 +1227,24 @@ void PDBLinker::addPublicsToPDB() {
}
});
- if (!publics.empty()) {
- publicSymbols = publics.size();
+ if (ctx.pdbStats.has_value())
+ ctx.pdbStats->publicSymbols = publics.size();
+
+ if (!publics.empty())
gsiBuilder.addPublicSymbols(std::move(publics));
- }
}
-void PDBLinker::printStats() {
+void PDBLinker::collectStats() {
if (!ctx.config.showSummary)
return;
+ ctx.pdbStats->nbTPIrecords = builder.getTpiBuilder().getRecordCount();
+ ctx.pdbStats->nbIPIrecords = builder.getIpiBuilder().getRecordCount();
+ ctx.pdbStats->strTabSize = pdbStrTab.size();
+
SmallString<256> buffer;
raw_svector_ostream stream(buffer);
- stream << center_justify("Summary", 80) << '\n'
- << std::string(80, '-') << '\n';
-
- auto print = [&](uint64_t v, StringRef s) {
- stream << formatv("{0}",
- fmt_align(formatv("{0:N}", v), AlignStyle::Right, 20))
- << " " << s << '\n';
- };
-
- print(ctx.objFileInstances.size(),
- "Input OBJ files (expanded from all cmd-line inputs)");
- print(ctx.consumedInputsSize,
- "Size of all consumed OBJ files (non-lazy), in bytes");
- print(ctx.typeServerSourceMappings.size(), "PDB type server dependencies");
- print(ctx.precompSourceMappings.size(), "Precomp OBJ dependencies");
- print(nbTypeRecords, "Input type records");
- print(nbTypeRecordsBytes, "Size of all input type records, in bytes");
- print(builder.getTpiBuilder().getRecordCount(), "Merged TPI records");
- print(builder.getIpiBuilder().getRecordCount(), "Merged IPI records");
- print(pdbStrTab.size(), "Output PDB strings");
- print(globalSymbols, "Global symbol records");
- print(moduleSymbols, "Module symbol records");
- print(publicSymbols, "Public symbol records");
-
auto printLargeInputTypeRecs = [&](StringRef name,
ArrayRef<uint32_t> recCounts,
TypeCollection &records) {
@@ -1318,9 +1295,9 @@ void PDBLinker::printStats() {
// FIXME: Reimplement for ghash.
printLargeInputTypeRecs("TPI", tMerger.tpiCounts, tMerger.getTypeTable());
printLargeInputTypeRecs("IPI", tMerger.ipiCounts, tMerger.getIDTable());
- }
- Msg(ctx) << buffer;
+ ctx.pdbStats->largeInputTypeRecs = buffer.str();
+ }
}
void PDBLinker::addNatvisFiles() {
@@ -1624,6 +1601,9 @@ void lld::coff::createPDB(COFFLinkerContext &ctx,
{
PDBLinker pdb(ctx);
+ if (ctx.config.showSummary)
+ ctx.pdbStats.emplace();
+
pdb.initialize(buildId);
pdb.addObjectsToPDB();
pdb.addImportFilesToPDB();
@@ -1640,8 +1620,8 @@ void lld::coff::createPDB(COFFLinkerContext &ctx,
memcpy(&buildId->PDB70.Signature, &guid, 16);
}
+ pdb.collectStats();
t1.stop();
- pdb.printStats();
// Manually start this profile point to measure ~PDBLinker().
if (getTimeTraceProfilerInstance() != nullptr)
diff --git a/lld/COFF/PDB.h b/lld/COFF/PDB.h
index 991805cc95b38..4a5df37c0fe6f 100644
--- a/lld/COFF/PDB.h
+++ b/lld/COFF/PDB.h
@@ -30,6 +30,19 @@ void createPDB(COFFLinkerContext &ctx, llvm::ArrayRef<uint8_t> sectionTable,
std::optional<std::pair<llvm::StringRef, uint32_t>>
getFileLineCodeView(const SectionChunk *c, uint32_t addr);
+// For statistics
+struct PDBStats {
+ uint64_t globalSymbols = 0;
+ uint64_t moduleSymbols = 0;
+ uint64_t publicSymbols = 0;
+ uint64_t nbTypeRecords = 0;
+ uint64_t nbTypeRecordsBytes = 0;
+ uint64_t nbTPIrecords = 0;
+ uint64_t nbIPIrecords = 0;
+ uint64_t strTabSize = 0;
+ std::string largeInputTypeRecs;
+};
+
} // namespace coff
} // namespace lld
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 37577e8dd93d9..e0d0ac18ea5d5 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -27,6 +27,8 @@
#include "llvm/MC/StringTableBuilder.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/FileOutputBuffer.h"
+#include "llvm/Support/FormatAdapters.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Parallel.h"
#include "llvm/Support/RandomNumberGenerator.h"
#include "llvm/Support/TimeProfiler.h"
@@ -282,6 +284,8 @@ class Writer {
template <typename T>
void prepareLoadConfig(SymbolTable &symtab, T *loadConfig);
+ void printSummary();
+
std::unique_ptr<FileOutputBuffer> &buffer;
std::map<PartialSectionKey, PartialSection *> partialSections;
StringTableBuilder strtab;
@@ -823,6 +827,8 @@ void Writer::run() {
writePEChecksum();
+ printSummary();
+
if (errorCount())
return;
@@ -3046,3 +3052,43 @@ void Writer::prepareLoadConfig(SymbolTable &symtab, T *loadConfig) {
#undef CHECK_VA
#undef CHECK_ABSOLUTE
}
+
+void Writer::printSummary() {
+ if (!ctx.config.showSummary)
+ return;
+
+ SmallString<256> buffer;
+ raw_svector_ostream stream(buffer);
+
+ stream << center_justify("Summary", 80) << '\n'
+ << std::string(80, '-') << '\n';
+
+ auto print = [&](uint64_t v, StringRef s) {
+ stream << formatv("{0}",
+ fmt_align(formatv("{0:N}", v), AlignStyle::Right, 20))
+ << " " << s << '\n';
+ };
+
+ bool hasStats = ctx.pdbStats.has_value();
+
+ print(ctx.objFileInstances.size(),
+ "Input OBJ files (expanded from all cmd-line inputs)");
+ print(ctx.consumedInputsSize,
+ "Size of all consumed OBJ files (non-lazy), in bytes");
+ print(ctx.typeServerSourceMappings.size(), "PDB type server dependencies");
+ print(ctx.precompSourceMappings.size(), "Precomp OBJ dependencies");
+ print(hasStats ? ctx.pdbStats->nbTypeRecords : 0, "Input debug type records");
+ print(hasStats ? ctx.pdbStats->nbTypeRecordsBytes : 0,
+ "Size of all input debug type records, in bytes");
+ print(hasStats ? ctx.pdbStats->nbTPIrecords : 0, "Merged TPI records");
+ print(hasStats ? ctx.pdbStats->nbIPIrecords : 0, "Merged IPI records");
+ print(hasStats ? ctx.pdbStats->strTabSize : 0, "Output PDB strings");
+ print(hasStats ? ctx.pdbStats->globalSymbols : 0, "Global symbol records");
+ print(hasStats ? ctx.pdbStats->moduleSymbols : 0, "Module symbol records");
+ print(hasStats ? ctx.pdbStats->publicSymbols : 0, "Public symbol records");
+
+ if (hasStats)
+ stream << ctx.pdbStats->largeInputTypeRecs;
+
+ Msg(ctx) << buffer;
+}
diff --git a/lld/test/COFF/pdb-type-server-simple.test b/lld/test/COFF/pdb-type-server-simple.test
index 5323a078ac432..693bd9b482dae 100644
--- a/lld/test/COFF/pdb-type-server-simple.test
+++ b/lld/test/COFF/pdb-type-server-simple.test
@@ -110,8 +110,8 @@ SUMMARY-NEXT: 2 Input OBJ files (expanded from all cmd-line i
SUMMARY-NEXT: Size of all consumed OBJ files (non-lazy), in bytes
SUMMARY-NEXT: 1 PDB type server dependencies
SUMMARY-NEXT: 0 Precomp OBJ dependencies
-SUMMARY-NEXT: 25 Input type records
-SUMMARY-NEXT: 868 Size of all input type records, in bytes
+SUMMARY-NEXT: 25 Input debug type records
+SUMMARY-NEXT: 868 Size of all input debug type records, in bytes
SUMMARY-NEXT: 9 Merged TPI records
SUMMARY-NEXT: 16 Merged IPI records
SUMMARY-NEXT: 3 Output PDB strings
diff --git a/lld/test/COFF/precomp-link.test b/lld/test/COFF/precomp-link.test
index 1c26042a44c33..389747920ffcf 100644
--- a/lld/test/COFF/precomp-link.test
+++ b/lld/test/COFF/precomp-link.test
@@ -3,6 +3,9 @@ RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s
RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /debug:ghash /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf /summary | FileCheck %s -check-prefix SUMMARY
RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s
+RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /out:%t.exe /opt:ref /opt:icf /summary | FileCheck %s -check-prefix SUMMARY-NODEBUG
+RUN: lld-link %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj %S/Inputs/precomp.obj /nodefaultlib /entry:main /out:%t.exe /opt:ref /opt:icf /summary | FileCheck %s -check-prefix SUMMARY-NODEBUG
+
RUN: lld-link %S/Inputs/precomp.obj %S/Inputs/precomp-a.obj %S/Inputs/precomp-b.obj /nodefaultlib /entry:main /debug /pdb:%t.pdb /out:%t.exe /opt:ref /opt:icf
RUN: llvm-pdbutil dump -types %t.pdb | FileCheck %s
@@ -63,8 +66,8 @@ SUMMARY-NEXT: 3 Input OBJ files (expanded from all cmd-line i
SUMMARY-NEXT: Size of all consumed OBJ files (non-lazy), in bytes
SUMMARY-NEXT: 0 PDB type server dependencies
SUMMARY-NEXT: 1 Precomp OBJ dependencies
-SUMMARY-NEXT: 1,066 Input type records
-SUMMARY-NEXT: 55,968 Size of all input type records, in bytes
+SUMMARY-NEXT: 1,066 Input debug type records
+SUMMARY-NEXT: 55,968 Size of all input debug type records, in bytes
SUMMARY-NEXT: 874 Merged TPI records
SUMMARY-NEXT: 170 Merged IPI records
SUMMARY-NEXT: 5 Output PDB strings
@@ -72,6 +75,21 @@ SUMMARY-NEXT: 167 Global symbol records
SUMMARY-NEXT: 20 Module symbol records
SUMMARY-NEXT: 3 Public symbol records
+SUMMARY-NODEBUG: Summary
+SUMMARY-NODEBUG-NEXT: --------------------------------------------------------------------------------
+SUMMARY-NODEBUG-NEXT: 3 Input OBJ files (expanded from all cmd-line inputs)
+SUMMARY-NODEBUG-NEXT: Size of all consumed OBJ files (non-lazy), in bytes
+SUMMARY-NODEBUG-NEXT: 0 PDB type server dependencies
+SUMMARY-NODEBUG-NEXT: 0 Precomp OBJ dependencies
+SUMMARY-NODEBUG-NEXT: 0 Input debug type records
+SUMMARY-NODEBUG-NEXT: 0 Size of all input debug type records, in bytes
+SUMMARY-NODEBUG-NEXT: 0 Merged TPI records
+SUMMARY-NODEBUG-NEXT: 0 Merged IPI records
+SUMMARY-NODEBUG-NEXT: 0 Output PDB strings
+SUMMARY-NODEBUG-NEXT: 0 Global symbol records
+SUMMARY-NODEBUG-NEXT: 0 Module symbol records
+SUMMARY-NODEBUG-NEXT: 0 Public symbol records
+
// precomp.h
#pragma once
int Function(char A);
diff --git a/lld/test/COFF/precomp-summary-fail.test b/lld/test/COFF/precomp-summary-fail.test
index 0d528c76c2180..5568316ff63c6 100644
--- a/lld/test/COFF/precomp-summary-fail.test
+++ b/lld/test/COFF/precomp-summary-fail.test
@@ -15,8 +15,8 @@ SUMMARY-NEXT: 2 Input OBJ files (expanded from all cmd-line i
SUMMARY-NEXT: Size of all consumed OBJ files (non-lazy), in bytes
SUMMARY-NEXT: 0 PDB type server dependencies
SUMMARY-NEXT: 1 Precomp OBJ dependencies
-SUMMARY-NEXT: 8 Input type records
-SUMMARY-NEXT: 232 Size of all input type records, in bytes
+SUMMARY-NEXT: 8 Input debug type records
+SUMMARY-NEXT: 232 Size of all input debug type records, in bytes
SUMMARY-NEXT: 3 Merged TPI records
SUMMARY-NEXT: 2 Merged IPI records
SUMMARY-NEXT: 1 Output PDB strings
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
Previously,
/summary
was meant to print some PDB information. Now move handling of/summary
toWriter.cpp
so that it can have an effect when/debug
isn't provided. This will also provide grounds for extending with more general information.