aboutsummaryrefslogtreecommitdiff
path: root/lib/DebugInfo
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2018-11-27 19:00:23 +0000
committerReid Kleckner <rnk@google.com>2018-11-27 19:00:23 +0000
commit36cff6306ac698d5bb1941aa5a0ec23c04de120a (patch)
tree27bf49cfdc143579a1eff5976faa0da28f905388 /lib/DebugInfo
parent6c99d2be100317539e2e462be96b3acd2c56e60b (diff)
downloadllvm-36cff6306ac698d5bb1941aa5a0ec23c04de120a.tar.gz
[PDB] Add symbol records in bulk
Summary: This speeds up linking clang.exe/pdb with /DEBUG:GHASH by 31%, from 12.9s to 9.8s. Symbol records are typically small (16.7 bytes on average), but we processed them one at a time. CVSymbol is a relatively "large" type. It wraps an ArrayRef<uint8_t> with a kind an optional 32-bit hash, which we don't need. Before this change, each DbiModuleDescriptorBuilder would maintain an array of CVSymbols, and would write them individually with a BinaryItemStream. With this change, we now add symbols that happen to appear contiguously in bulk. For each .debug$S section (roughly one per function), we allocate two copies, one for relocation, and one for realignment purposes. For runs of symbols that go in the module stream, which is most symbols, we now add them as a single ArrayRef<uint8_t>, so the vector DbiModuleDescriptorBuilder is roughly linear in the number of .debug$S sections (O(# funcs)) instead of the number of symbol records (very large). Some stats on symbol sizes for the curious: PDB size: 507M sym bytes: 316,508,016 sym count: 18,954,971 sym byte avg: 16.7 As future work, we may be able to skip copying symbol records in the linker for realignment purposes if we make LLVM write them aligned into the object file. We need to double check that such symbol records are still compatible with link.exe, but if so, it's definitely worth doing, since my profile shows we spend 500ms in memcpy in the symbol merging code. We could potentially cut that in half by saving a copy. Alternatively, we could apply the relocations *after* we iterate the symbols. This would require some careful re-engineering of the relocation processing code, though. Reviewers: zturner, aganea, ruiu Subscribers: hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D54554 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@347687 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/DebugInfo')
-rw-r--r--lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp30
1 files changed, 17 insertions, 13 deletions
diff --git a/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
index b97f1e90bcf..12df042c4eb 100644
--- a/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
+++ b/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
@@ -19,7 +19,6 @@
#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/Support/BinaryItemStream.h"
#include "llvm/Support/BinaryStreamWriter.h"
using namespace llvm;
@@ -66,12 +65,22 @@ void DbiModuleDescriptorBuilder::setFirstSectionContrib(
}
void DbiModuleDescriptorBuilder::addSymbol(CVSymbol Symbol) {
- Symbols.push_back(Symbol);
- // Symbols written to a PDB file are required to be 4 byte aligned. The same
+ // Defer to the bulk API. It does the same thing.
+ addSymbolsInBulk(Symbol.data());
+}
+
+void DbiModuleDescriptorBuilder::addSymbolsInBulk(
+ ArrayRef<uint8_t> BulkSymbols) {
+ // Do nothing for empty runs of symbols.
+ if (BulkSymbols.empty())
+ return;
+
+ Symbols.push_back(BulkSymbols);
+ // Symbols written to a PDB file are required to be 4 byte aligned. The same
// is not true of object files.
- assert(Symbol.length() % alignOf(CodeViewContainer::Pdb) == 0 &&
+ assert(BulkSymbols.size() % alignOf(CodeViewContainer::Pdb) == 0 &&
"Invalid Symbol alignment!");
- SymbolByteSize += Symbol.length();
+ SymbolByteSize += BulkSymbols.size();
}
void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) {
@@ -145,16 +154,11 @@ Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter,
if (auto EC =
SymbolWriter.writeInteger<uint32_t>(COFF::DEBUG_SECTION_MAGIC))
return EC;
- BinaryItemStream<CVSymbol> Records(llvm::support::endianness::little);
- Records.setItems(Symbols);
- BinaryStreamRef RecordsRef(Records);
- if (auto EC = SymbolWriter.writeStreamRef(RecordsRef))
- return EC;
- if (auto EC = SymbolWriter.padToAlignment(4))
- return EC;
- // TODO: Write C11 Line data
+ for (ArrayRef<uint8_t> Syms : Symbols)
+ SymbolWriter.writeBytes(Syms);
assert(SymbolWriter.getOffset() % alignOf(CodeViewContainer::Pdb) == 0 &&
"Invalid debug section alignment!");
+ // TODO: Write C11 Line data
for (const auto &Builder : C13Builders) {
assert(Builder && "Empty C13 Fragment Builder!");
if (auto EC = Builder->commit(SymbolWriter))