From 12dd8df38b5da0e7bbbcc842308a251ce11800d5 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 13 May 2021 14:42:18 -0700 Subject: [PATCH] [PDB] Do not record PGO or coverage public symbols These symbols are long, and they tend to cause the PDB file size to overflow. They are generally not necessary when debugging problems in user code. This change reduces the size of chrome.dll.pdb with coverage from 6,937,108,480 bytes to 4,690,210,816 bytes. Differential Revision: https://reviews.llvm.org/D102719 --- lld/COFF/PDB.cpp | 19 ++++++++++- lld/test/COFF/pgo-pubs.s | 71 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 lld/test/COFF/pgo-pubs.s diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp index 6791d523da37..cb8b27b6f485 100644 --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -1185,8 +1185,25 @@ void PDBLinker::addPublicsToPDB() { // Only emit external, defined, live symbols that have a chunk. Static, // non-external symbols do not appear in the symbol table. auto *def = dyn_cast(s); - if (def && def->isLive() && def->getChunk()) + if (def && def->isLive() && def->getChunk()) { + // Don't emit a public symbol for coverage data symbols. LLVM code + // coverage (and PGO) create a __profd_ and __profc_ symbol for every + // function. C++ mangled names are long, and tend to dominate symbol size. + // Including these names triples the size of the public stream, which + // results in bloated PDB files. These symbols generally are not helpful + // for debugging, so suppress them. + StringRef name = def->getName(); + if (name.data()[0] == '_' && name.data()[1] == '_') { + // Drop the '_' prefix for x86. + if (config->machine == I386) + name = name.drop_front(1); + if (name.startswith("__profd_") || name.startswith("__profc_") || + name.startswith("__covrec_")) { + return; + } + } publics.push_back(createPublic(def)); + } }); if (!publics.empty()) { diff --git a/lld/test/COFF/pgo-pubs.s b/lld/test/COFF/pgo-pubs.s new file mode 100644 index 000000000000..c72ee2468f3c --- /dev/null +++ b/lld/test/COFF/pgo-pubs.s @@ -0,0 +1,71 @@ +# REQUIRES: x86 +# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s +# RUN: lld-link %t.obj -out:%t.exe -pdb:%t.pdb -debug -entry:main -subsystem:console +# RUN: llvm-pdbutil dump -publics %t.pdb | FileCheck %s + +# Check that there are no __prof[dc] or __covrec public symbols. + +# CHECK-NOT: __profd +# CHECK-NOT: __profc +# CHECK-NOT: __covrec +# CHECK: S_PUB32 {{.*}} `main` +# CHECK-NOT: __profd +# CHECK-NOT: __profc +# CHECK-NOT: __covrec + + +# The following assembly is simplified from this C code: +# int main() { +# return 0; +# } + +# Compiled like so: +# clang-cl -c pgo-pubs.c -fprofile-instr-generate -fcoverage-mapping -clang:-save-temps + + + .text + .intel_syntax noprefix + .globl main # -- Begin function main +main: # @main +# %bb.0: # %entry + xor eax, eax + ret + + .section .lcovfun$M,"dr",discard,__covrec_DB956436E78DD5FAu + .globl __covrec_DB956436E78DD5FAu # @__covrec_DB956436E78DD5FAu + .p2align 3 +__covrec_DB956436E78DD5FAu: + .quad -2624081020897602054 # 0xdb956436e78dd5fa + .long 9 # 0x9 + .quad 24 # 0x18 + .quad 2164039332547799183 # 0x1e08364eb07c288f + .ascii "\001\001\000\001\001\b\f\002\002" + + .section .lcovmap$M,"dr" + .p2align 3 # @__llvm_coverage_mapping +.L__llvm_coverage_mapping: + .long 0 # 0x0 + .long 40 # 0x28 + .long 0 # 0x0 + .long 5 # 0x5 + .ascii "\002%\000\031C:\\src\\llvm-project\\build\npgo-pubs.i" + + .section .lprfc$M,"dw" + .p2align 3 # @__profc_main +__profc_main: + .zero 8 + + .section .lprfd$M,"dw" + .p2align 3 # @__profd_main +__profd_main: + .quad -2624081020897602054 # 0xdb956436e78dd5fa + .quad 24 # 0x18 + .quad __profc_main + .quad main + .quad 0 + .long 1 # 0x1 + .zero 4 + + .section .lprfn$M,"dr" +.L__llvm_prf_nm: # @__llvm_prf_nm + .ascii "\004\000main"