Skip to content

Commit f18fd6e

Browse files
authored
[lld-macho] Use parallel algorithms in favor of ThreadPool (llvm#99471)
In https://reviews.llvm.org/D115416, it was decided that an explicit thread pool should be used instead of the simpler fork-join model of the `parallelFor*` family of functions. Since then, more parallelism has been added to LLD, but these changes always used the latter strategy, similarly to other ports of LLD. This meant that we ended up spawning twice the requested amount of threads; one set for the `llvm/Support/Parallel.h` executor, and one for the thread pool. Since that decision, 3b4d800 has landed, which allows us to explicitly enqueue jobs on the executor pool of the parallel algorithms, which should be enough to achieve sharded output writing and parallelized input file parsing. Now only the construction of the map file is left that should be done *concurrently* with different linking steps, this commit proposes explicitly spawning a dedicated worker thread for it.
1 parent 58854fa commit f18fd6e

File tree

1 file changed

+17
-18
lines changed

1 file changed

+17
-18
lines changed

lld/MachO/Writer.cpp

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
#include "llvm/Support/LEB128.h"
2929
#include "llvm/Support/Parallel.h"
3030
#include "llvm/Support/Path.h"
31-
#include "llvm/Support/ThreadPool.h"
3231
#include "llvm/Support/TimeProfiler.h"
32+
#include "llvm/Support/thread.h"
3333
#include "llvm/Support/xxhash.h"
3434

3535
#include <algorithm>
@@ -66,7 +66,6 @@ class Writer {
6666

6767
template <class LP> void run();
6868

69-
DefaultThreadPool threadPool;
7069
std::unique_ptr<FileOutputBuffer> &buffer;
7170
uint64_t addr = 0;
7271
uint64_t fileOff = 0;
@@ -1121,14 +1120,12 @@ void Writer::finalizeLinkEditSegment() {
11211120
symtabSection, indirectSymtabSection,
11221121
dataInCodeSection, functionStartsSection,
11231122
};
1124-
SmallVector<std::shared_future<void>> threadFutures;
1125-
threadFutures.reserve(linkEditSections.size());
1126-
for (LinkEditSection *osec : linkEditSections)
1127-
if (osec)
1128-
threadFutures.emplace_back(threadPool.async(
1129-
[](LinkEditSection *osec) { osec->finalizeContents(); }, osec));
1130-
for (std::shared_future<void> &future : threadFutures)
1131-
future.wait();
1123+
1124+
parallelForEach(linkEditSections.begin(), linkEditSections.end(),
1125+
[](LinkEditSection *osec) {
1126+
if (osec)
1127+
osec->finalizeContents();
1128+
});
11321129

11331130
// Now that __LINKEDIT is filled out, do a proper calculation of its
11341131
// addresses and offsets.
@@ -1170,6 +1167,8 @@ void Writer::openFile() {
11701167
}
11711168

11721169
void Writer::writeSections() {
1170+
TimeTraceScope timeScope("Write output sections");
1171+
11731172
uint8_t *buf = buffer->getBufferStart();
11741173
std::vector<const OutputSection *> osecs;
11751174
for (const OutputSegment *seg : outputSegments)
@@ -1200,18 +1199,15 @@ void Writer::writeUuid() {
12001199

12011200
ArrayRef<uint8_t> data{buffer->getBufferStart(), buffer->getBufferEnd()};
12021201
std::vector<ArrayRef<uint8_t>> chunks = split(data, 1024 * 1024);
1202+
12031203
// Leave one slot for filename
12041204
std::vector<uint64_t> hashes(chunks.size() + 1);
1205-
SmallVector<std::shared_future<void>> threadFutures;
1206-
threadFutures.reserve(chunks.size());
1207-
for (size_t i = 0; i < chunks.size(); ++i)
1208-
threadFutures.emplace_back(threadPool.async(
1209-
[&](size_t j) { hashes[j] = xxh3_64bits(chunks[j]); }, i));
1210-
for (std::shared_future<void> &future : threadFutures)
1211-
future.wait();
1205+
parallelFor(0, chunks.size(),
1206+
[&](size_t i) { hashes[i] = xxh3_64bits(chunks[i]); });
12121207
// Append the output filename so that identical binaries with different names
12131208
// don't get the same UUID.
12141209
hashes[chunks.size()] = xxh3_64bits(sys::path::filename(config->finalOutput));
1210+
12151211
uint64_t digest = xxh3_64bits({reinterpret_cast<uint8_t *>(hashes.data()),
12161212
hashes.size() * sizeof(uint64_t)});
12171213
uuidCommand->writeUuid(digest);
@@ -1330,15 +1326,18 @@ template <class LP> void Writer::run() {
13301326
sortSegmentsAndSections();
13311327
createLoadCommands<LP>();
13321328
finalizeAddresses();
1333-
threadPool.async([&] {
1329+
1330+
llvm::thread mapFileWriter([&] {
13341331
if (LLVM_ENABLE_THREADS && config->timeTraceEnabled)
13351332
timeTraceProfilerInitialize(config->timeTraceGranularity, "writeMapFile");
13361333
writeMapFile();
13371334
if (LLVM_ENABLE_THREADS && config->timeTraceEnabled)
13381335
timeTraceProfilerFinishThread();
13391336
});
1337+
13401338
finalizeLinkEditSegment();
13411339
writeOutputFile();
1340+
mapFileWriter.join();
13421341
}
13431342

13441343
template <class LP> void macho::writeResult() { Writer().run<LP>(); }

0 commit comments

Comments
 (0)