From d9065fe8ea643bd889821c0dc4c7dbec0469c28e Mon Sep 17 00:00:00 2001 From: Jez Ng Date: Wed, 7 Apr 2021 19:55:45 -0400 Subject: [PATCH] [lld-macho] Parallelize __LINKEDIT generation Benchmarking chromium_framework on a 3.2 GHz 16-Core Intel Xeon W Mac Pro: N Min Max Median Avg Stddev x 20 4.33 4.42 4.37 4.37 0.021026299 + 20 4.12 4.23 4.18 4.175 0.035318103 Difference at 95.0% confidence -0.195 +/- 0.0186025 -4.46224% +/- 0.425686% (Student's t, pooled s = 0.0290644) Reviewed By: #lld-macho, gkm Differential Revision: https://reviews.llvm.org/D99998 --- lld/MachO/SyntheticSections.h | 18 ++++++++++-------- lld/MachO/Writer.cpp | 24 +++++++++++------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h index cf9e2ca..eaad8aa 100644 --- a/lld/MachO/SyntheticSections.h +++ b/lld/MachO/SyntheticSections.h @@ -56,6 +56,8 @@ public: align = target->wordSize; } + virtual void finalizeContents() {} + // Sections in __LINKEDIT are special: their offsets are recorded in the // load commands like LC_DYLD_INFO_ONLY and LC_SYMTAB, instead of in section // headers. @@ -155,7 +157,7 @@ struct Location { class RebaseSection : public LinkEditSection { public: RebaseSection(); - void finalizeContents(); + void finalizeContents() override; uint64_t getRawSize() const override { return contents.size(); } bool isNeeded() const override { return !locations.empty(); } void writeTo(uint8_t *buf) const override; @@ -182,7 +184,7 @@ struct BindingEntry { class BindingSection : public LinkEditSection { public: BindingSection(); - void finalizeContents(); + void finalizeContents() override; uint64_t getRawSize() const override { return contents.size(); } bool isNeeded() const override { return !bindings.empty(); } void writeTo(uint8_t *buf) const override; @@ -218,7 +220,7 @@ struct WeakBindingEntry { class WeakBindingSection : public LinkEditSection { public: WeakBindingSection(); - void finalizeContents(); + void finalizeContents() override; uint64_t getRawSize() const override { return contents.size(); } bool isNeeded() const override { return !bindings.empty() || !definitions.empty(); @@ -327,7 +329,7 @@ public: class LazyBindingSection : public LinkEditSection { public: LazyBindingSection(); - void finalizeContents(); + void finalizeContents() override; uint64_t getRawSize() const override { return contents.size(); } bool isNeeded() const override { return !entries.empty(); } void writeTo(uint8_t *buf) const override; @@ -348,7 +350,7 @@ private: class ExportSection : public LinkEditSection { public: ExportSection(); - void finalizeContents(); + void finalizeContents() override; uint64_t getRawSize() const override { return size; } void writeTo(uint8_t *buf) const override; @@ -362,7 +364,7 @@ private: class FunctionStartsSection : public LinkEditSection { public: FunctionStartsSection(); - void finalizeContents(); + void finalizeContents() override; uint64_t getRawSize() const override { return contents.size(); } void writeTo(uint8_t *buf) const override; @@ -411,7 +413,7 @@ struct StabsEntry { // range (start index and total number) of those symbols in the symbol table. class SymtabSection : public LinkEditSection { public: - void finalizeContents(); + void finalizeContents() override; uint32_t getNumSymbols() const; uint32_t getNumLocalSymbols() const { return stabs.size() + localSymbols.size(); @@ -453,7 +455,7 @@ template SymtabSection *makeSymtabSection(StringTableSection &); class IndirectSymtabSection : public LinkEditSection { public: IndirectSymtabSection(); - void finalizeContents(); + void finalizeContents() override; uint32_t getNumSymbols() const; uint64_t getRawSize() const override { return getNumSymbols() * sizeof(uint32_t); diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp index f37322b..8b10e17 100644 --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -51,7 +51,7 @@ public: void scanSymbols(); template void createOutputSections(); template void createLoadCommands(); - void finalizeAddressses(); + void finalizeAddresses(); void finalizeLinkEditSegment(); void assignAddresses(OutputSegment *); @@ -852,7 +852,7 @@ template void Writer::createOutputSections() { linkEditSegment = getOrCreateOutputSegment(segment_names::linkEdit); } -void Writer::finalizeAddressses() { +void Writer::finalizeAddresses() { TimeTraceScope timeScope("Finalize addresses"); // Ensure that segments (and the sections they contain) are allocated // addresses in ascending order, which dyld requires. @@ -870,16 +870,14 @@ void Writer::finalizeAddressses() { void Writer::finalizeLinkEditSegment() { TimeTraceScope timeScope("Finalize __LINKEDIT segment"); // Fill __LINKEDIT contents. - in.rebase->finalizeContents(); - in.binding->finalizeContents(); - in.weakBinding->finalizeContents(); - in.lazyBinding->finalizeContents(); - in.exports->finalizeContents(); - symtabSection->finalizeContents(); - indirectSymtabSection->finalizeContents(); - - if (functionStartsSection) - functionStartsSection->finalizeContents(); + std::vector linkEditSections{ + in.rebase, in.binding, in.weakBinding, in.lazyBinding, + in.exports, symtabSection, indirectSymtabSection, functionStartsSection, + }; + parallelForEach(linkEditSections, [](LinkEditSection *osec) { + if (osec) + osec->finalizeContents(); + }); // Now that __LINKEDIT is filled out, do a proper calculation of its // addresses and offsets. @@ -972,7 +970,7 @@ template void Writer::run() { // No more sections nor segments are created beyond this point. sortSegmentsAndSections(); createLoadCommands(); - finalizeAddressses(); + finalizeAddresses(); finalizeLinkEditSegment(); writeMapFile(); writeOutputFile(); -- 2.7.4