[lld] [lld-macho] Parallelize ObjFile::sourceFile() during STABS emission. (PR #222087)
Liza Burakova via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 8 10:56:08 PDT 2026
https://github.com/liza371 created https://github.com/llvm/llvm-project/pull/222087
This is part of the ld64.lld performance improvements tracked by #222068
Currently, SymtabSection::emitStabs() calls emitBeginSourceStab() it passes in file->sourceFile(), which will call
ObjFile::sourceFile(). This method reads the component's root DIE, which is a bottleneck when done serially as at this stage the DWARF sections have not been parsed yet.
This commit parallelizes the calls to ObjFile::sourceFile(), as we already have the file ids stable sorted.
AI tool use: this is one of the commits that was prototyped by AI. I rewrote this commit and ran the benchmarking myself.
**Benchmarks for mac_debug_component_sym_2**
Benchmark 1: Apple ld
Time (mean ± σ): 2.244 s ± 0.025 s [User: 9.294 s, System: 8.530 s]
Range (min … max): 2.204 s … 2.300 s 20 runs
Benchmark 2: LLD Baseline
Time (mean ± σ): 8.411 s ± 0.721 s [User: 7.080 s, System: 2.718 s]
Range (min … max): 7.821 s … 11.171 s 20 runs
Benchmark 3: LLD Optimized
Time (mean ± σ): 8.082 s ± 0.283 s [User: 7.597 s, System: 2.677 s]
Range (min … max): 7.617 s … 8.664 s 20 runs
**Benchmarks for mac_rel_component_sym_2**
Benchmark 1: Apple ld
Time (mean ± σ): 1.195 s ± 0.006 s [User: 2.621 s, System: 12.442 s]
Range (min … max): 1.186 s … 1.209 s 20 runs
Benchmark 2: LLD Baseline
Time (mean ± σ): 2.528 s ± 0.023 s [User: 1.971 s, System: 1.533 s]
Range (min … max): 2.489 s … 2.575 s 20 runs
Benchmark 3: LLD Optimized
Time (mean ± σ): 2.239 s ± 0.033 s [User: 2.356 s, System: 1.650 s]
Range (min … max): 2.190 s … 2.345 s 20 runs
We did not see notable improvements for Chromium release builds with symbol level 0 or 1, which is not super surprising as this change is targeting debug symbols.
>From 19fbd8af5c683288ce50c58f52de0e28b5c9a8bf Mon Sep 17 00:00:00 2001
From: Liza Burakova <liza at chromium.org>
Date: Fri, 4 Sep 2026 12:55:21 -0400
Subject: [PATCH] [lld-macho] Parallelize ObjFile::sourceFile() during STABS
emission.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is part of the lld performance improvements tracked by
Currently, SymtabSection::emitStabs() calls emitBeginSourceStab()
it passes in file->sourceFile(), which will call
ObjFile::sourceFile(). This method reads the component's root DIE,
which is a bottleneck when done serially as at this stage the
DWARF sections have not been parsed yet.
This commit parallelizes the calls to ObjFile::sourceFile(), as
we already have the file ids stabel sorted.
AI tool use: this is one of the commits that was prototyped by AI.
I rewrote this commit and ran the benchmarking myself.
Benchmark for mac_debug_component_sym_2
Benchmark 1: Apple ld
Time (mean ± σ): 2.244 s ± 0.025 s [User: 9.294 s, System: 8.530 s]
Range (min … max): 2.204 s … 2.300 s 20 runs
Benchmark 2: LLD Baseline
Time (mean ± σ): 8.411 s ± 0.721 s [User: 7.080 s, System: 2.718 s]
Range (min … max): 7.821 s … 11.171 s 20 runs
Benchmark 3: LLD Optimized
Time (mean ± σ): 8.082 s ± 0.283 s [User: 7.597 s, System: 2.677 s]
Range (min … max): 7.617 s … 8.664 s 20 runs
Benchmark for mac_rel_component_sym_2
Benchmark 1: Apple ld
Time (mean ± σ): 1.195 s ± 0.006 s [User: 2.621 s, System: 12.442 s]
Range (min … max): 1.186 s … 1.209 s 20 runs
Benchmark 2: LLD Baseline
Time (mean ± σ): 2.528 s ± 0.023 s [User: 1.971 s, System: 1.533 s]
Range (min … max): 2.489 s … 2.575 s 20 runs
Benchmark 3: LLD Optimized
Time (mean ± σ): 2.239 s ± 0.033 s [User: 2.356 s, System: 1.650 s]
Range (min … max): 2.190 s … 2.345 s 20 runs
We did not see notable improvements for Chromium release builds with
symbol level 0 or 1, which is not super surprising as this change is targeting
debug symbols.
---
lld/MachO/SyntheticSections.cpp | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index c4277d54edd38..a179f7edd10c0 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -1239,7 +1239,6 @@ void SymtabSection::emitStabs() {
if (auto *defined = dyn_cast<Defined>(sym)) {
// Excluded symbols should have been filtered out in finalizeContents().
assert(defined->includeInSymtab);
-
if (defined->isAbsolute())
continue;
@@ -1263,10 +1262,22 @@ void SymtabSection::emitStabs() {
llvm::stable_sort(symbolsNeedingStabs, llvm::less_second());
+ std::vector<ObjFile *> stabFiles;
+ for (const SortingPair &pair : symbolsNeedingStabs) {
+ ObjFile* file = cast<ObjFile>(pair.first->originalIsec->getFile());
+ if (stabFiles.empty() || stabFiles.back() != file)
+ stabFiles.push_back(file);
+ }
+ std::vector<std::string> stabSourceFiles(stabFiles.size());
+ parallelFor(0, stabFiles.size(), [&](size_t i) {
+ stabSourceFiles[i] = stabFiles[i]->sourceFile();
+ });
+
// Emit STABS symbols so that dsymutil and/or the debugger can map address
// regions in the final binary to the source and object files from which they
// originated.
InputFile *lastFile = nullptr;
+ size_t stabFileIdx = 0;
for (SortingPair &pair : symbolsNeedingStabs) {
Defined *defined = pair.first;
// When emitting STABS entries for a symbol, always use the original
@@ -1282,7 +1293,8 @@ void SymtabSection::emitStabs() {
emitEndSourceStab();
lastFile = file;
- emitBeginSourceStab(file->sourceFile());
+ assert(stabFiles[stabFileIdx] == file);
+ emitBeginSourceStab(stabSourceFiles[stabFileIdx++]);
emitObjectFileStab(file);
}
More information about the llvm-commits
mailing list