[llvm] 2edd897 - Make WriteIndexesThinBackend multi threaded (#109847)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 7 08:16:51 PDT 2024
Author: Nuri Amari
Date: 2024-10-07T08:16:46-07:00
New Revision: 2edd897a4227e481af33e8e43090ab088cd9d953
URL: https://github.com/llvm/llvm-project/commit/2edd897a4227e481af33e8e43090ab088cd9d953
DIFF: https://github.com/llvm/llvm-project/commit/2edd897a4227e481af33e8e43090ab088cd9d953.diff
LOG: Make WriteIndexesThinBackend multi threaded (#109847)
We've noticed that for large builds executing thin-link can take on the
order of 10s of minutes. We are only using a single thread to write the
sharded indices and import files for each input bitcode file. While we
need to ensure the index file produced lists modules in a deterministic
order, that doesn't prevent us from executing the rest of the work in
parallel.
In this change we use a thread pool to execute as much of the backend's
work as possible in parallel. In local testing on a machine with 80
cores, this change makes a thin-link for ~100,000 input files run in ~2
minutes. Without this change it takes upwards of 10 minutes.
---------
Co-authored-by: Nuri Amari <nuriamari at fb.com>
Added:
Modified:
lld/COFF/LTO.cpp
lld/ELF/LTO.cpp
lld/MachO/LTO.cpp
lld/test/COFF/thinlto-emit-imports.ll
lld/test/ELF/lto/thinlto-cant-write-index.ll
lld/test/ELF/lto/thinlto-emit-imports.ll
lld/test/MachO/thinlto-emit-imports.ll
llvm/include/llvm/LTO/LTO.h
llvm/include/llvm/Support/Threading.h
llvm/include/llvm/Transforms/IPO/FunctionImport.h
llvm/lib/LTO/LTO.cpp
llvm/lib/LTO/ThinLTOCodeGenerator.cpp
llvm/lib/Transforms/IPO/FunctionImport.cpp
llvm/tools/gold/gold-plugin.cpp
llvm/tools/llvm-lto2/llvm-lto2.cpp
Removed:
################################################################################
diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp
index 5c881bc01c663d..da73fe7763ceea 100644
--- a/lld/COFF/LTO.cpp
+++ b/lld/COFF/LTO.cpp
@@ -118,6 +118,7 @@ BitcodeCompiler::BitcodeCompiler(COFFLinkerContext &c) : ctx(c) {
if (ctx.config.thinLTOIndexOnly) {
auto OnIndexWrite = [&](StringRef S) { thinIndices.erase(S); };
backend = lto::createWriteIndexesThinBackend(
+ llvm::hardware_concurrency(ctx.config.thinLTOJobs),
std::string(ctx.config.thinLTOPrefixReplaceOld),
std::string(ctx.config.thinLTOPrefixReplaceNew),
std::string(ctx.config.thinLTOPrefixReplaceNativeObject),
diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp
index 02b5c09150c65c..ef9d9bb49db856 100644
--- a/lld/ELF/LTO.cpp
+++ b/lld/ELF/LTO.cpp
@@ -179,6 +179,7 @@ BitcodeCompiler::BitcodeCompiler(Ctx &ctx) : ctx(ctx) {
auto onIndexWrite = [&](StringRef s) { thinIndices.erase(s); };
if (ctx.arg.thinLTOIndexOnly) {
backend = lto::createWriteIndexesThinBackend(
+ llvm::hardware_concurrency(ctx.arg.thinLTOJobs),
std::string(ctx.arg.thinLTOPrefixReplaceOld),
std::string(ctx.arg.thinLTOPrefixReplaceNew),
std::string(ctx.arg.thinLTOPrefixReplaceNativeObject),
diff --git a/lld/MachO/LTO.cpp b/lld/MachO/LTO.cpp
index 6527cbb68f2498..28f5290edb58e3 100644
--- a/lld/MachO/LTO.cpp
+++ b/lld/MachO/LTO.cpp
@@ -87,6 +87,7 @@ BitcodeCompiler::BitcodeCompiler() {
auto onIndexWrite = [&](StringRef S) { thinIndices.erase(S); };
if (config->thinLTOIndexOnly) {
backend = lto::createWriteIndexesThinBackend(
+ llvm::hardware_concurrency(config->thinLTOJobs),
std::string(config->thinLTOPrefixReplaceOld),
std::string(config->thinLTOPrefixReplaceNew),
std::string(config->thinLTOPrefixReplaceNativeObject),
diff --git a/lld/test/COFF/thinlto-emit-imports.ll b/lld/test/COFF/thinlto-emit-imports.ll
index b47a6cea4eb7df..26af017b17b2c5 100644
--- a/lld/test/COFF/thinlto-emit-imports.ll
+++ b/lld/test/COFF/thinlto-emit-imports.ll
@@ -35,7 +35,7 @@
; RUN: not lld-link -entry:main -thinlto-index-only \
; RUN: -thinlto-emit-imports-files %t1.obj %t2.obj %t3.obj \
; RUN: -out:%t4.exe 2>&1 | FileCheck -DMSG=%errc_EACCES %s --check-prefix=ERR
-; ERR: cannot open {{.*}}3.obj.imports: [[MSG]]
+; ERR: 'cannot open {{.*}}3.obj.imports': [[MSG]]
; Ensure lld doesn't generate import files when thinlto-index-only is not enabled
; RUN: rm -f %t1.obj.imports
diff --git a/lld/test/ELF/lto/thinlto-cant-write-index.ll b/lld/test/ELF/lto/thinlto-cant-write-index.ll
index 286fcddd4238a1..550305986ecd5b 100644
--- a/lld/test/ELF/lto/thinlto-cant-write-index.ll
+++ b/lld/test/ELF/lto/thinlto-cant-write-index.ll
@@ -10,7 +10,7 @@
; RUN: chmod u-w %t2.o.thinlto.bc
; RUN: not ld.lld --plugin-opt=thinlto-index-only -shared %t1.o %t2.o -o /dev/null 2>&1 | FileCheck -DMSG=%errc_EACCES %s
; RUN: chmod u+w %t2.o.thinlto.bc
-; CHECK: cannot open {{.*}}2.o.thinlto.bc: [[MSG]]
+; CHECK: 'cannot open {{.*}}2.o.thinlto.bc': [[MSG]]
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
diff --git a/lld/test/ELF/lto/thinlto-emit-imports.ll b/lld/test/ELF/lto/thinlto-emit-imports.ll
index 253ec08619c982..1807a3b59d81cb 100644
--- a/lld/test/ELF/lto/thinlto-emit-imports.ll
+++ b/lld/test/ELF/lto/thinlto-emit-imports.ll
@@ -10,7 +10,7 @@
; RUN: touch %t3.o.imports
; RUN: chmod 400 %t3.o.imports
; RUN: not ld.lld --plugin-opt=thinlto-index-only --plugin-opt=thinlto-emit-imports-files -shared %t1.o %t2.o %t3.o -o /dev/null 2>&1 | FileCheck -DMSG=%errc_EACCES %s --check-prefix=ERR
-; ERR: cannot open {{.*}}3.o.imports: [[MSG]]
+; ERR: 'cannot open {{.*}}3.o.imports': [[MSG]]
; RUN: rm -f %t1.o.imports %t2.o.imports rm -f %t3.o.imports
; RUN: ld.lld --plugin-opt=thinlto-emit-imports-files -shared %t1.o %t2.o %t3.o -o %t4
diff --git a/lld/test/MachO/thinlto-emit-imports.ll b/lld/test/MachO/thinlto-emit-imports.ll
index 88f766f59c8877..90ee6a56b93b8f 100644
--- a/lld/test/MachO/thinlto-emit-imports.ll
+++ b/lld/test/MachO/thinlto-emit-imports.ll
@@ -33,7 +33,7 @@
; RUN: chmod 400 %t3.o.imports
; RUN: not %lld --thinlto-index-only --thinlto-emit-imports-files -dylib %t1.o %t2.o %t3.o -o /dev/null 2>&1 \
; RUN: | FileCheck -DMSG=%errc_EACCES %s --check-prefix=ERR
-; ERR: cannot open {{.*}}3.o.imports: [[MSG]]
+; ERR: 'cannot open {{.*}}3.o.imports': [[MSG]]
; Ensure lld doesn't generate import files when thinlto-index-only is not enabled
; RUN: rm -f %t1.o.imports
diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h
index a281c377f2601d..5c47c4df7f6a38 100644
--- a/llvm/include/llvm/LTO/LTO.h
+++ b/llvm/include/llvm/LTO/LTO.h
@@ -231,7 +231,8 @@ ThinBackend createInProcessThinBackend(ThreadPoolStrategy Parallelism,
/// the objects with NativeObjectPrefix instead of NewPrefix. OnWrite is
/// callback which receives module identifier and notifies LTO user that index
/// file for the module (and optionally imports file) was created.
-ThinBackend createWriteIndexesThinBackend(std::string OldPrefix,
+ThinBackend createWriteIndexesThinBackend(ThreadPoolStrategy Parallelism,
+ std::string OldPrefix,
std::string NewPrefix,
std::string NativeObjectPrefix,
bool ShouldEmitImportsFiles,
diff --git a/llvm/include/llvm/Support/Threading.h b/llvm/include/llvm/Support/Threading.h
index ba6c531ab4db21..d8e2cb0514ddd7 100644
--- a/llvm/include/llvm/Support/Threading.h
+++ b/llvm/include/llvm/Support/Threading.h
@@ -188,6 +188,18 @@ constexpr bool llvm_is_multithreaded() { return LLVM_ENABLE_THREADS; }
return S;
}
+ /// Like hardware_concurrency() above, but builds a strategy
+ /// based on the rules described for get_threadpool_strategy().
+ /// If \p Num is invalid, returns a default strategy where one thread per
+ /// hardware core is used.
+ inline ThreadPoolStrategy hardware_concurrency(StringRef Num) {
+ std::optional<ThreadPoolStrategy> S =
+ get_threadpool_strategy(Num, hardware_concurrency());
+ if (S)
+ return *S;
+ return hardware_concurrency();
+ }
+
/// Returns an optimal thread strategy to execute specified amount of tasks.
/// This strategy should prevent us from creating too many threads if we
/// occasionaly have an unexpectedly small amount of tasks.
diff --git a/llvm/include/llvm/Transforms/IPO/FunctionImport.h b/llvm/include/llvm/Transforms/IPO/FunctionImport.h
index 4b29d3f40ab7b5..3623f9194d4d13 100644
--- a/llvm/include/llvm/Transforms/IPO/FunctionImport.h
+++ b/llvm/include/llvm/Transforms/IPO/FunctionImport.h
@@ -417,9 +417,9 @@ void gatherImportedSummariesForModule(
GVSummaryPtrSet &DecSummaries);
/// Emit into \p OutputFilename the files module \p ModulePath will import from.
-std::error_code
-EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename,
- const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex);
+Error EmitImportsFiles(
+ StringRef ModulePath, StringRef OutputFilename,
+ const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex);
/// Based on the information recorded in the summaries during global
/// summary-based analysis:
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index b5eb7953f23b09..ccf1139c037353 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -1376,15 +1376,20 @@ class lto::ThinBackendProc {
const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries;
lto::IndexWriteCallback OnWrite;
bool ShouldEmitImportsFiles;
+ DefaultThreadPool BackendThreadPool;
+ std::optional<Error> Err;
+ std::mutex ErrMu;
public:
ThinBackendProc(
const Config &Conf, ModuleSummaryIndex &CombinedIndex,
const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
- lto::IndexWriteCallback OnWrite, bool ShouldEmitImportsFiles)
+ lto::IndexWriteCallback OnWrite, bool ShouldEmitImportsFiles,
+ ThreadPoolStrategy ThinLTOParallelism)
: Conf(Conf), CombinedIndex(CombinedIndex),
ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries),
- OnWrite(OnWrite), ShouldEmitImportsFiles(ShouldEmitImportsFiles) {}
+ OnWrite(OnWrite), ShouldEmitImportsFiles(ShouldEmitImportsFiles),
+ BackendThreadPool(ThinLTOParallelism) {}
virtual ~ThinBackendProc() = default;
virtual Error start(
@@ -1393,13 +1398,19 @@ class lto::ThinBackendProc {
const FunctionImporter::ExportSetTy &ExportList,
const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
MapVector<StringRef, BitcodeModule> &ModuleMap) = 0;
- virtual Error wait() = 0;
- virtual unsigned getThreadCount() = 0;
+ Error wait() {
+ BackendThreadPool.wait();
+ if (Err)
+ return std::move(*Err);
+ return Error::success();
+ }
+ unsigned getThreadCount() { return BackendThreadPool.getMaxConcurrency(); }
+ virtual bool isSensitiveToInputOrder() { return false; }
// Write sharded indices and (optionally) imports to disk
Error emitFiles(const FunctionImporter::ImportMapTy &ImportList,
llvm::StringRef ModulePath,
- const std::string &NewModulePath) {
+ const std::string &NewModulePath) const {
ModuleToSummariesForIndexTy ModuleToSummariesForIndex;
GVSummaryPtrSet DeclarationSummaries;
@@ -1411,16 +1422,17 @@ class lto::ThinBackendProc {
raw_fd_ostream OS(NewModulePath + ".thinlto.bc", EC,
sys::fs::OpenFlags::OF_None);
if (EC)
- return errorCodeToError(EC);
+ return createFileError("cannot open " + NewModulePath + ".thinlto.bc",
+ EC);
writeIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex,
&DeclarationSummaries);
if (ShouldEmitImportsFiles) {
- EC = EmitImportsFiles(ModulePath, NewModulePath + ".imports",
- ModuleToSummariesForIndex);
- if (EC)
- return errorCodeToError(EC);
+ Error ImportFilesError = EmitImportsFiles(
+ ModulePath, NewModulePath + ".imports", ModuleToSummariesForIndex);
+ if (ImportFilesError)
+ return ImportFilesError;
}
return Error::success();
}
@@ -1428,15 +1440,11 @@ class lto::ThinBackendProc {
namespace {
class InProcessThinBackend : public ThinBackendProc {
- DefaultThreadPool BackendThreadPool;
AddStreamFn AddStream;
FileCache Cache;
DenseSet<GlobalValue::GUID> CfiFunctionDefs;
DenseSet<GlobalValue::GUID> CfiFunctionDecls;
- std::optional<Error> Err;
- std::mutex ErrMu;
-
bool ShouldEmitIndexFiles;
public:
@@ -1447,9 +1455,9 @@ class InProcessThinBackend : public ThinBackendProc {
AddStreamFn AddStream, FileCache Cache, lto::IndexWriteCallback OnWrite,
bool ShouldEmitIndexFiles, bool ShouldEmitImportsFiles)
: ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
- OnWrite, ShouldEmitImportsFiles),
- BackendThreadPool(ThinLTOParallelism), AddStream(std::move(AddStream)),
- Cache(std::move(Cache)), ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
+ OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
+ AddStream(std::move(AddStream)), Cache(std::move(Cache)),
+ ShouldEmitIndexFiles(ShouldEmitIndexFiles) {
for (auto &Name : CombinedIndex.cfiFunctionDefs())
CfiFunctionDefs.insert(
GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
@@ -1546,18 +1554,6 @@ class InProcessThinBackend : public ThinBackendProc {
OnWrite(std::string(ModulePath));
return Error::success();
}
-
- Error wait() override {
- BackendThreadPool.wait();
- if (Err)
- return std::move(*Err);
- else
- return Error::success();
- }
-
- unsigned getThreadCount() override {
- return BackendThreadPool.getMaxConcurrency();
- }
};
} // end anonymous namespace
@@ -1618,12 +1614,13 @@ class WriteIndexesThinBackend : public ThinBackendProc {
public:
WriteIndexesThinBackend(
const Config &Conf, ModuleSummaryIndex &CombinedIndex,
+ ThreadPoolStrategy ThinLTOParallelism,
const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
std::string OldPrefix, std::string NewPrefix,
std::string NativeObjectPrefix, bool ShouldEmitImportsFiles,
raw_fd_ostream *LinkedObjectsFile, lto::IndexWriteCallback OnWrite)
: ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries,
- OnWrite, ShouldEmitImportsFiles),
+ OnWrite, ShouldEmitImportsFiles, ThinLTOParallelism),
OldPrefix(OldPrefix), NewPrefix(NewPrefix),
NativeObjectPrefix(NativeObjectPrefix),
LinkedObjectsFile(LinkedObjectsFile) {}
@@ -1635,9 +1632,11 @@ class WriteIndexesThinBackend : public ThinBackendProc {
const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR,
MapVector<StringRef, BitcodeModule> &ModuleMap) override {
StringRef ModulePath = BM.getModuleIdentifier();
- std::string NewModulePath =
- getThinLTOOutputFile(ModulePath, OldPrefix, NewPrefix);
+ // The contents of this file may be used as input to a native link, and must
+ // therefore contain the processed modules in a determinstic order that
+ // match the order they are provided on the command line. For that reason,
+ // we cannot include this in the asynchronously executed lambda below.
if (LinkedObjectsFile) {
std::string ObjectPrefix =
NativeObjectPrefix.empty() ? NewPrefix : NativeObjectPrefix;
@@ -1646,33 +1645,49 @@ class WriteIndexesThinBackend : public ThinBackendProc {
*LinkedObjectsFile << LinkedObjectsFilePath << '\n';
}
- if (auto E = emitFiles(ImportList, ModulePath, NewModulePath))
- return E;
+ BackendThreadPool.async(
+ [this](const StringRef ModulePath,
+ const FunctionImporter::ImportMapTy &ImportList,
+ const std::string &OldPrefix, const std::string &NewPrefix) {
+ std::string NewModulePath =
+ getThinLTOOutputFile(ModulePath, OldPrefix, NewPrefix);
+ auto E = emitFiles(ImportList, ModulePath, NewModulePath);
+ if (E) {
+ std::unique_lock<std::mutex> L(ErrMu);
+ if (Err)
+ Err = joinErrors(std::move(*Err), std::move(E));
+ else
+ Err = std::move(E);
+ return;
+ }
+ },
+ ModulePath, ImportList, OldPrefix, NewPrefix);
if (OnWrite)
OnWrite(std::string(ModulePath));
return Error::success();
}
- Error wait() override { return Error::success(); }
-
- // WriteIndexesThinBackend should always return 1 to prevent module
- // re-ordering and avoid non-determinism in the final link.
- unsigned getThreadCount() override { return 1; }
+ bool isSensitiveToInputOrder() override {
+ // The order which modules are written to LinkedObjectsFile should be
+ // deterministic and match the order they are passed on the command line.
+ return true;
+ }
};
} // end anonymous namespace
ThinBackend lto::createWriteIndexesThinBackend(
- std::string OldPrefix, std::string NewPrefix,
- std::string NativeObjectPrefix, bool ShouldEmitImportsFiles,
- raw_fd_ostream *LinkedObjectsFile, IndexWriteCallback OnWrite) {
+ ThreadPoolStrategy Parallelism, std::string OldPrefix,
+ std::string NewPrefix, std::string NativeObjectPrefix,
+ bool ShouldEmitImportsFiles, raw_fd_ostream *LinkedObjectsFile,
+ IndexWriteCallback OnWrite) {
return
[=](const Config &Conf, ModuleSummaryIndex &CombinedIndex,
const DenseMap<StringRef, GVSummaryMapTy> &ModuleToDefinedGVSummaries,
AddStreamFn AddStream, FileCache Cache) {
return std::make_unique<WriteIndexesThinBackend>(
- Conf, CombinedIndex, ModuleToDefinedGVSummaries, OldPrefix,
- NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
+ Conf, CombinedIndex, Parallelism, ModuleToDefinedGVSummaries,
+ OldPrefix, NewPrefix, NativeObjectPrefix, ShouldEmitImportsFiles,
LinkedObjectsFile, OnWrite);
};
}
@@ -1854,7 +1869,8 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache,
ResolvedODR[Mod.first], ThinLTO.ModuleMap);
};
- if (BackendProcess->getThreadCount() == 1) {
+ if (BackendProcess->getThreadCount() == 1 ||
+ BackendProcess->isSensitiveToInputOrder()) {
// Process the modules in the order they were provided on the
// command-line. It is important for this codepath to be used for
// WriteIndexesThinBackend, to ensure the emitted LinkedObjectsFile lists
diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
index 76268c950cf581..8074f8690cc1ce 100644
--- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
@@ -837,9 +837,8 @@ void ThinLTOCodeGenerator::emitImports(Module &TheModule, StringRef OutputName,
ModuleIdentifier, ModuleToDefinedGVSummaries,
ImportLists[ModuleIdentifier], ModuleToSummariesForIndex, DecSummaries);
- std::error_code EC;
- if ((EC = EmitImportsFiles(ModuleIdentifier, OutputName,
- ModuleToSummariesForIndex)))
+ if (Error EC = EmitImportsFiles(ModuleIdentifier, OutputName,
+ ModuleToSummariesForIndex))
report_fatal_error(Twine("Failed to open ") + OutputName +
" to save imports lists\n");
}
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp
index 261731fd565b02..fee27f72f208b0 100644
--- a/llvm/lib/Transforms/IPO/FunctionImport.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp
@@ -1553,20 +1553,21 @@ void llvm::gatherImportedSummariesForModule(
}
/// Emit the files \p ModulePath will import from into \p OutputFilename.
-std::error_code llvm::EmitImportsFiles(
+Error llvm::EmitImportsFiles(
StringRef ModulePath, StringRef OutputFilename,
const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex) {
std::error_code EC;
raw_fd_ostream ImportsOS(OutputFilename, EC, sys::fs::OpenFlags::OF_Text);
if (EC)
- return EC;
+ return createFileError("cannot open " + OutputFilename,
+ errorCodeToError(EC));
for (const auto &ILI : ModuleToSummariesForIndex)
// The ModuleToSummariesForIndex map includes an entry for the current
// Module (needed for writing out the index files). We don't want to
// include it in the imports file, however, so filter it out.
if (ILI.first != ModulePath)
ImportsOS << ILI.first << "\n";
- return std::error_code();
+ return Error::success();
}
bool llvm::convertToDeclaration(GlobalValue &GV) {
diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp
index 0377791d85b3f8..9304bd4188d9ed 100644
--- a/llvm/tools/gold/gold-plugin.cpp
+++ b/llvm/tools/gold/gold-plugin.cpp
@@ -899,7 +899,7 @@ static std::unique_ptr<LTO> createLTO(IndexWriteCallback OnIndexWrite,
std::string OldPrefix, NewPrefix;
getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix);
Backend = createWriteIndexesThinBackend(
- OldPrefix, NewPrefix,
+ llvm::hardware_concurrency(options::Parallelism) OldPrefix, NewPrefix,
// TODO: Add support for optional native object path in
// thinlto_prefix_replace option to match lld.
/*NativeObjectPrefix=*/"", options::thinlto_emit_imports_files,
diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp
index 5dd961a603c9e8..d4f022ef021a44 100644
--- a/llvm/tools/llvm-lto2/llvm-lto2.cpp
+++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp
@@ -346,7 +346,8 @@ static int run(int argc, char **argv) {
ThinBackend Backend;
if (ThinLTODistributedIndexes)
- Backend = createWriteIndexesThinBackend(/*OldPrefix=*/"",
+ Backend = createWriteIndexesThinBackend(llvm::hardware_concurrency(Threads),
+ /*OldPrefix=*/"",
/*NewPrefix=*/"",
/*NativeObjectPrefix=*/"",
ThinLTOEmitImports,
More information about the llvm-commits
mailing list