Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lld/COFF/COFFLinkerContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -113,6 +114,8 @@ class COFFLinkerContext : public CommonLinkerContext {
Timer tpiStreamLayoutTimer;
Timer diskCommitTimer;

std::optional<PDBStats> pdbStats;

Configuration config;

DynamicRelocsChunk *dynamicRelocs = nullptr;
Expand Down
72 changes: 26 additions & 46 deletions lld/COFF/PDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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);
Expand All @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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();
Expand Down Expand Up @@ -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;
}
}
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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();
Expand All @@ -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)
Expand Down
13 changes: 13 additions & 0 deletions lld/COFF/PDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
46 changes: 46 additions & 0 deletions lld/COFF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -823,6 +827,8 @@ void Writer::run() {

writePEChecksum();

printSummary();

if (errorCount())
return;

Expand Down Expand Up @@ -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;
}
4 changes: 2 additions & 2 deletions lld/test/COFF/pdb-type-server-simple.test
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 20 additions & 2 deletions lld/test/COFF/precomp-link.test
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -63,15 +66,30 @@ 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
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);
Expand Down
4 changes: 2 additions & 2 deletions lld/test/COFF/precomp-summary-fail.test
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading