[lld] eb4663d - [lld][COFF][ELF][WebAssembly] Replace --[no-]threads /threads[:no] with --threads={1,2,...} /threads:{1,2,...}
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 31 08:46:35 PDT 2020
Author: Fangrui Song
Date: 2020-03-31T08:46:12-07:00
New Revision: eb4663d8c6add351d758748383f1a9fc231e5e64
URL: https://github.com/llvm/llvm-project/commit/eb4663d8c6add351d758748383f1a9fc231e5e64
DIFF: https://github.com/llvm/llvm-project/commit/eb4663d8c6add351d758748383f1a9fc231e5e64.diff
LOG: [lld][COFF][ELF][WebAssembly] Replace --[no-]threads /threads[:no] with --threads={1,2,...} /threads:{1,2,...}
--no-threads is a name copied from gold.
gold has --no-thread, --thread-count and several other --thread-count-*.
There are needs to customize the number of threads (running several lld
processes concurrently or customizing the number of LTO threads).
Having a single --threads=N is a straightforward replacement of gold's
--no-threads + --thread-count.
--no-threads is used rarely. So just delete --no-threads instead of
keeping it for compatibility for a while.
If --threads= is specified (ELF,wasm; COFF /threads: is similar),
--thinlto-jobs= defaults to --threads=,
otherwise all available hardware threads are used.
There is currently no way to override a --threads={1,2,...}. It is still
a debate whether we should use --threads=all.
Reviewed By: rnk, aganea
Differential Revision: https://reviews.llvm.org/D76885
Added:
lld/test/ELF/threads.s
lld/test/wasm/threads.s
Modified:
lld/COFF/Driver.cpp
lld/COFF/Options.td
lld/Common/CMakeLists.txt
lld/Common/Filesystem.cpp
lld/ELF/Driver.cpp
lld/ELF/ICF.cpp
lld/ELF/Options.td
lld/ELF/SyntheticSections.cpp
lld/docs/ld.lld.1
lld/include/lld/Common/Threads.h
lld/test/COFF/pdb-globals.test
lld/test/ELF/build-id.s
lld/test/ELF/lto/thinlto.ll
lld/test/wasm/lto/thinlto.ll
lld/wasm/Driver.cpp
lld/wasm/Options.td
llvm/include/llvm/Support/Parallel.h
llvm/lib/Support/Parallel.cpp
llvm/utils/gn/secondary/lld/Common/BUILD.gn
Removed:
lld/Common/Threads.cpp
################################################################################
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 7d99f798a322..931b8cf601a7 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -1144,7 +1144,17 @@ void LinkerDriver::link(ArrayRef<const char *> argsArr) {
return;
}
- lld::threadsEnabled = args.hasFlag(OPT_threads, OPT_threads_no, true);
+ // /threads: takes a positive integer and provides the default value for
+ // /opt:lldltojobs=.
+ if (auto *arg = args.getLastArg(OPT_threads)) {
+ StringRef v(arg->getValue());
+ unsigned threads = 0;
+ if (!llvm::to_integer(v, threads, 0) || threads == 0)
+ error(arg->getSpelling() + ": expected a positive integer, but got '" +
+ arg->getValue() + "'");
+ parallel::strategy = hardware_concurrency(threads);
+ config->thinLTOJobs = v.str();
+ }
if (args.hasArg(OPT_show_timing))
config->showTiming = true;
diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td
index 72fe9ce8c118..f8fe6f9efc19 100644
--- a/lld/COFF/Options.td
+++ b/lld/COFF/Options.td
@@ -219,9 +219,9 @@ def lto_obj_path : P<
"output native object for merged LTO unit to this path">;
def dash_dash_version : Flag<["--"], "version">,
HelpText<"Print version information">;
-defm threads: B<"threads",
- "Run the linker multi-threaded (default)",
- "Do not run the linker multi-threaded">;
+def threads
+ : P<"threads", "Number of threads. '1' disables multi-threading. By "
+ "default all available hardware threads are used">;
// Flags for debugging
def lldmap : F<"lldmap">;
diff --git a/lld/Common/CMakeLists.txt b/lld/Common/CMakeLists.txt
index 7d5ad654925e..53649032bd98 100644
--- a/lld/Common/CMakeLists.txt
+++ b/lld/Common/CMakeLists.txt
@@ -36,7 +36,6 @@ add_lld_library(lldCommon
Reproduce.cpp
Strings.cpp
TargetOptionsCommandFlags.cpp
- Threads.cpp
Timer.cpp
VCSVersion.inc
Version.cpp
diff --git a/lld/Common/Filesystem.cpp b/lld/Common/Filesystem.cpp
index 75e88dbce1ab..d75c462d244d 100644
--- a/lld/Common/Filesystem.cpp
+++ b/lld/Common/Filesystem.cpp
@@ -43,7 +43,7 @@ void lld::unlinkAsync(StringRef path) {
#if defined(_WIN32)
sys::fs::remove(path);
#else
- if (!threadsEnabled || !sys::fs::exists(path) ||
+ if (parallel::strategy.ThreadsRequested == 1 || !sys::fs::exists(path) ||
!sys::fs::is_regular_file(path))
return;
diff --git a/lld/Common/Threads.cpp b/lld/Common/Threads.cpp
deleted file mode 100644
index af04972a3760..000000000000
--- a/lld/Common/Threads.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-//===- Threads.cpp --------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "lld/Common/Threads.h"
-
-bool lld::threadsEnabled = true;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 95276cd33420..c31cbcc8a54d 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -860,7 +860,6 @@ static void readConfigs(opt::InputArgList &args) {
args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
errorHandler().vsDiagnostics =
args.hasArg(OPT_visual_studio_diagnostics_format, false);
- threadsEnabled = args.hasFlag(OPT_threads, OPT_no_threads, true);
config->allowMultipleDefinition =
args.hasFlag(OPT_allow_multiple_definition,
@@ -974,7 +973,6 @@ static void readConfigs(opt::InputArgList &args) {
config->thinLTOIndexOnly = args.hasArg(OPT_thinlto_index_only) ||
args.hasArg(OPT_thinlto_index_only_eq);
config->thinLTOIndexOnlyArg = args.getLastArgValue(OPT_thinlto_index_only_eq);
- config->thinLTOJobs = args.getLastArgValue(OPT_thinlto_jobs);
config->thinLTOObjectSuffixReplace =
getOldNewOptions(args, OPT_thinlto_object_suffix_replace_eq);
config->thinLTOPrefixReplace =
@@ -1036,6 +1034,20 @@ static void readConfigs(opt::InputArgList &args) {
for (auto *arg : args.filtered(OPT_mllvm))
parseClangOption(arg->getValue(), arg->getSpelling());
+ // --threads= takes a positive integer and provides the default value for
+ // --thinlto-jobs=.
+ if (auto *arg = args.getLastArg(OPT_threads)) {
+ StringRef v(arg->getValue());
+ unsigned threads = 0;
+ if (!llvm::to_integer(v, threads, 0) || threads == 0)
+ error(arg->getSpelling() + ": expected a positive integer, but got '" +
+ arg->getValue() + "'");
+ parallel::strategy = hardware_concurrency(threads);
+ config->thinLTOJobs = v;
+ }
+ if (auto *arg = args.getLastArg(OPT_thinlto_jobs))
+ config->thinLTOJobs = arg->getValue();
+
if (config->ltoo > 3)
error("invalid optimization level for LTO: " + Twine(config->ltoo));
if (config->ltoPartitions == 0)
diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp
index cdc4a15ea691..4b1ecadde5ab 100644
--- a/lld/ELF/ICF.cpp
+++ b/lld/ELF/ICF.cpp
@@ -400,7 +400,7 @@ template <class ELFT>
void ICF<ELFT>::forEachClass(llvm::function_ref<void(size_t, size_t)> fn) {
// If threading is disabled or the number of sections are
// too small to use threading, call Fn sequentially.
- if (!threadsEnabled || sections.size() < 1024) {
+ if (parallel::strategy.ThreadsRequested == 1 || sections.size() < 1024) {
forEachClassRange(0, sections.size(), fn);
++cnt;
return;
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index e1c489c4a1e3..47210b6ac122 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -350,9 +350,10 @@ defm target2:
Eq<"target2", "Interpret R_ARM_TARGET2 as <type>, where <type> is one of rel, abs, or got-rel">,
MetaVarName<"<type>">;
-defm threads: B<"threads",
- "Run the linker multi-threaded (default)",
- "Do not run the linker multi-threaded">;
+defm threads
+ : Eq<"threads",
+ "Number of threads. '1' disables multi-threading. By default all "
+ "available hardware threads are used">;
def time_trace: F<"time-trace">, HelpText<"Record time trace">;
def time_trace_file_eq: J<"time-trace-file=">, HelpText<"Specify time trace output file">;
@@ -509,7 +510,8 @@ defm thinlto_cache_policy: Eq<"thinlto-cache-policy", "Pruning policy for the Th
def thinlto_emit_imports_files: F<"thinlto-emit-imports-files">;
def thinlto_index_only: F<"thinlto-index-only">;
def thinlto_index_only_eq: J<"thinlto-index-only=">;
-def thinlto_jobs: J<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs">;
+def thinlto_jobs: J<"thinlto-jobs=">,
+ HelpText<"Number of ThinLTO jobs. Default to --threads=">;
def thinlto_object_suffix_replace_eq: J<"thinlto-object-suffix-replace=">;
def thinlto_prefix_replace_eq: J<"thinlto-prefix-replace=">;
diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index 2388b08dd20b..48339099dc27 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -2746,12 +2746,11 @@ createSymbols(ArrayRef<std::vector<GdbIndexSection::NameAttrEntry>> nameAttrs,
// The number of symbols we will handle in this function is of the order
// of millions for very large executables, so we use multi-threading to
// speed it up.
- size_t numShards = 32;
- size_t concurrency = 1;
- if (threadsEnabled)
- concurrency = std::min<size_t>(
- PowerOf2Floor(hardware_concurrency().compute_thread_count()),
- numShards);
+ constexpr size_t numShards = 32;
+ size_t concurrency = PowerOf2Floor(
+ std::min<size_t>(hardware_concurrency(parallel::strategy.ThreadsRequested)
+ .compute_thread_count(),
+ numShards));
// A sharded map to uniquify symbols by name.
std::vector<DenseMap<CachedHashStringRef, size_t>> map(numShards);
@@ -3194,11 +3193,10 @@ void MergeNoTailSection::finalizeContents() {
// Concurrency level. Must be a power of 2 to avoid expensive modulo
// operations in the following tight loop.
- size_t concurrency = 1;
- if (threadsEnabled)
- concurrency = std::min<size_t>(
- PowerOf2Floor(hardware_concurrency().compute_thread_count()),
- numShards);
+ size_t concurrency = PowerOf2Floor(
+ std::min<size_t>(hardware_concurrency(parallel::strategy.ThreadsRequested)
+ .compute_thread_count(),
+ numShards));
// Add section pieces to the builders.
parallelForEachN(0, concurrency, [&](size_t threadId) {
diff --git a/lld/docs/ld.lld.1 b/lld/docs/ld.lld.1
index 238ac28a599c..7af9a16e83f9 100644
--- a/lld/docs/ld.lld.1
+++ b/lld/docs/ld.lld.1
@@ -302,8 +302,6 @@ Page align sections.
Do not set the text data sections to be writable, page align sections.
.It Fl -no-rosegment
Do not put read-only non-executable sections in their own segment.
-.It Fl -no-threads
-Do not run the linker multi-threaded.
.It Fl -no-undefined-version
Report version scripts that refer undefined symbols.
.It Fl -no-undefined
@@ -525,9 +523,12 @@ Path to ThinLTO cached object file directory.
Pruning policy for the ThinLTO cache.
.It Fl -thinlto-jobs Ns = Ns Ar value
Number of ThinLTO jobs.
-.It Fl -threads
-Run the linker multi-threaded.
-This option is enabled by default.
+.It Fl -threads Ns = Ns Ar N
+Number of threads.
+.Cm all
+(default) means all of concurrent threads supported.
+.Cm 1
+disables multi-threading.
.It Fl -trace
Print the names of the input files.
.It Fl -trace-symbol Ns = Ns Ar symbol , Fl y Ar symbol
diff --git a/lld/include/lld/Common/Threads.h b/lld/include/lld/Common/Threads.h
index 7834130fdf72..1090961b18cd 100644
--- a/lld/include/lld/Common/Threads.h
+++ b/lld/include/lld/Common/Threads.h
@@ -63,10 +63,8 @@
namespace lld {
-extern bool threadsEnabled;
-
template <typename R, class FuncTy> void parallelForEach(R &&range, FuncTy fn) {
- if (threadsEnabled)
+ if (llvm::parallel::strategy.ThreadsRequested != 1)
for_each(llvm::parallel::par, std::begin(range), std::end(range), fn);
else
for_each(llvm::parallel::seq, std::begin(range), std::end(range), fn);
@@ -74,14 +72,14 @@ template <typename R, class FuncTy> void parallelForEach(R &&range, FuncTy fn) {
inline void parallelForEachN(size_t begin, size_t end,
llvm::function_ref<void(size_t)> fn) {
- if (threadsEnabled)
+ if (llvm::parallel::strategy.ThreadsRequested != 1)
for_each_n(llvm::parallel::par, begin, end, fn);
else
for_each_n(llvm::parallel::seq, begin, end, fn);
}
template <typename R, class FuncTy> void parallelSort(R &&range, FuncTy fn) {
- if (threadsEnabled)
+ if (llvm::parallel::strategy.ThreadsRequested != 1)
sort(llvm::parallel::par, std::begin(range), std::end(range), fn);
else
sort(llvm::parallel::seq, std::begin(range), std::end(range), fn);
diff --git a/lld/test/COFF/pdb-globals.test b/lld/test/COFF/pdb-globals.test
index 00909fa317bb..169a16907633 100644
--- a/lld/test/COFF/pdb-globals.test
+++ b/lld/test/COFF/pdb-globals.test
@@ -2,9 +2,9 @@ RUN: yaml2obj %S/Inputs/pdb-globals.yaml > %t.obj
RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe /pdb:%t.pdb %t.obj
RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s
-RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe /pdb:%t.pdb %t.obj /threads
+RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe /pdb:%t.pdb %t.obj /threads:1
RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s
-RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe /pdb:%t.pdb %t.obj /threads:no
+RUN: lld-link /debug /nodefaultlib /entry:main /out:%t.exe /pdb:%t.pdb %t.obj /threads:2
RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s
# Test that we correctly distribute symbols between the globals and module
diff --git a/lld/test/ELF/build-id.s b/lld/test/ELF/build-id.s
index 32966b8a378b..b693a088a266 100644
--- a/lld/test/ELF/build-id.s
+++ b/lld/test/ELF/build-id.s
@@ -5,26 +5,26 @@
# RUN: ld.lld --build-id %t -o %t2
# RUN: llvm-readobj -S %t2 | FileCheck -check-prefix=ALIGN %s
-# RUN: ld.lld --build-id %t -o %t2 -threads
+# RUN: ld.lld --build-id %t -o %t2
# RUN: llvm-objdump -s %t2 | FileCheck --check-prefix=DEFAULT %s
-# RUN: ld.lld --build-id=fast %t -o %t2 -threads
+# RUN: ld.lld --build-id=fast %t -o %t2
# RUN: llvm-objdump -s %t2 | FileCheck --check-prefix=DEFAULT %s
-# RUN: ld.lld --build-id %t -o %t2 -no-threads
+# RUN: ld.lld --build-id %t -o %t2 --threads=1
# RUN: llvm-objdump -s %t2 | FileCheck --check-prefix=DEFAULT %s
-# RUN: ld.lld --build-id=md5 %t -o %t2 -threads
+# RUN: ld.lld --build-id=md5 %t -o %t2
# RUN: llvm-objdump -s %t2 | FileCheck --check-prefix=MD5 %s
-# RUN: ld.lld --build-id=md5 %t -o %t2 -no-threads
+# RUN: ld.lld --build-id=md5 %t -o %t2 --threads=1
# RUN: llvm-objdump -s %t2 | FileCheck --check-prefix=MD5 %s
-# RUN: ld.lld --build-id=sha1 %t -o %t2 -threads
+# RUN: ld.lld --build-id=sha1 %t -o %t2
# RUN: llvm-objdump -s %t2 | FileCheck --check-prefix=SHA1 %s
-# RUN: ld.lld --build-id=sha1 %t -o %t2 -no-threads
+# RUN: ld.lld --build-id=sha1 %t -o %t2 --threads=1
# RUN: llvm-objdump -s %t2 | FileCheck --check-prefix=SHA1 %s
-# RUN: ld.lld --build-id=tree %t -o %t2 -threads
+# RUN: ld.lld --build-id=tree %t -o %t2
# RUN: llvm-objdump -s %t2 | FileCheck --check-prefix=SHA1 %s
-# RUN: ld.lld --build-id=tree %t -o %t2 -no-threads
+# RUN: ld.lld --build-id=tree %t -o %t2 --threads=1
# RUN: llvm-objdump -s %t2 | FileCheck --check-prefix=SHA1 %s
# RUN: ld.lld --build-id=uuid %t -o %t2
diff --git a/lld/test/ELF/lto/thinlto.ll b/lld/test/ELF/lto/thinlto.ll
index bf9062be7c10..50e31d1e6232 100644
--- a/lld/test/ELF/lto/thinlto.ll
+++ b/lld/test/ELF/lto/thinlto.ll
@@ -22,6 +22,18 @@
; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1
; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2
+;; --thinlto-jobs= defaults to --threads=.
+; RUN: rm -f %t31.lto.o %t32.lto.o
+; RUN: ld.lld -save-temps --threads=2 -shared %t1.o %t2.o -o %t3
+; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1
+; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2
+
+;; --thinlto-jobs= overrides --threads=.
+; RUN: rm -f %t31.lto.o %t32.lto.o
+; RUN: ld.lld -save-temps --threads=1 --plugin-opt=jobs=2 -shared %t1.o %t2.o -o %t3
+; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1
+; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2
+
; Test with all threads, on all cores, on all CPU sockets
; RUN: rm -f %t31.lto.o %t32.lto.o
; RUN: ld.lld -save-temps --thinlto-jobs=all -shared %t1.o %t2.o -o %t3
diff --git a/lld/test/ELF/threads.s b/lld/test/ELF/threads.s
new file mode 100644
index 000000000000..6d4b36924031
--- /dev/null
+++ b/lld/test/ELF/threads.s
@@ -0,0 +1,11 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
+
+## A positive integer is allowed.
+# RUN: ld.lld --threads=1 %t.o -o /dev/null
+# RUN: ld.lld --threads=2 %t.o -o /dev/null
+
+# RUN: not ld.lld --threads=all %t.o -o /dev/null 2>&1 | FileCheck %s -DN=all
+# RUN: not ld.lld --threads=0 %t.o -o /dev/null 2>&1 | FileCheck %s -DN=0
+# RUN: not ld.lld --threads=-1 %t.o -o /dev/null 2>&1 | FileCheck %s -DN=-1
+
+# CHECK: error: --threads: expected a positive integer, but got '[[N]]'
diff --git a/lld/test/wasm/lto/thinlto.ll b/lld/test/wasm/lto/thinlto.ll
index 460452905597..da42469f2deb 100644
--- a/lld/test/wasm/lto/thinlto.ll
+++ b/lld/test/wasm/lto/thinlto.ll
@@ -14,6 +14,18 @@
; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1
; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2
+;; --thinlto-jobs= defaults to --threads=.
+; RUN: rm -f %t31.lto.o %t32.lto.o
+; RUN: wasm-ld -r -save-temps --threads=2 %t1.o %t2.o -o %t3
+; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1
+; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2
+
+;; --thinlto-jobs= overrides --threads=.
+; RUN: rm -f %t31.lto.o %t32.lto.o
+; RUN: wasm-ld -r -save-temps --threads=1 --thinlto-jobs=2 %t1.o %t2.o -o %t3
+; RUN: llvm-nm %t31.lto.o | FileCheck %s --check-prefix=NM1
+; RUN: llvm-nm %t32.lto.o | FileCheck %s --check-prefix=NM2
+
; Test with all threads, on all cores, on all CPU sockets
; RUN: rm -f %t31.lto.o %t32.lto.o
; RUN: wasm-ld -r -save-temps --thinlto-jobs=all %t1.o %t2.o -o %t3
diff --git a/lld/test/wasm/threads.s b/lld/test/wasm/threads.s
new file mode 100644
index 000000000000..e02f5e620805
--- /dev/null
+++ b/lld/test/wasm/threads.s
@@ -0,0 +1,12 @@
+# RUN: llvm-mc -filetype=obj -triple=wasm32 %s -o %t.o
+
+## A positive integer is allowed.
+# RUN: wasm-ld --no-entry %t.o -o /dev/null
+# RUN: wasm-ld --no-entry --threads=1 %t.o -o /dev/null
+# RUN: wasm-ld --no-entry --threads=2 %t.o -o /dev/null
+
+# RUN: not wasm-ld --threads=all %t.o -o /dev/null 2>&1 | FileCheck %s -DN=all
+# RUN: not wasm-ld --threads=0 %t.o -o /dev/null 2>&1 | FileCheck %s -DN=0
+# RUN: not wasm-ld --threads=-1 %t.o -o /dev/null 2>&1 | FileCheck %s -DN=-1
+
+# CHECK: error: --threads: expected a positive integer, but got '[[N]]'
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index b38e980004ad..d0b01d5ccef0 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -362,10 +362,8 @@ static void readConfigs(opt::InputArgList &args) {
config->thinLTOCachePolicy = CHECK(
parseCachePruningPolicy(args.getLastArgValue(OPT_thinlto_cache_policy)),
"--thinlto-cache-policy: invalid cache policy");
- config->thinLTOJobs = args.getLastArgValue(OPT_thinlto_jobs);
errorHandler().verbose = args.hasArg(OPT_verbose);
LLVM_DEBUG(errorHandler().verbose = true);
- threadsEnabled = args.hasFlag(OPT_threads, OPT_no_threads, true);
config->initialMemory = args::getInteger(args, OPT_initial_memory, 0);
config->globalBase = args::getInteger(args, OPT_global_base, 1024);
@@ -377,6 +375,20 @@ static void readConfigs(opt::InputArgList &args) {
config->exportDynamic =
args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, config->shared);
+ // --threads= takes a positive integer and provides the default value for
+ // --thinlto-jobs=.
+ if (auto *arg = args.getLastArg(OPT_threads)) {
+ StringRef v(arg->getValue());
+ unsigned threads = 0;
+ if (!llvm::to_integer(v, threads, 0) || threads == 0)
+ error(arg->getSpelling() + ": expected a positive integer, but got '" +
+ arg->getValue() + "'");
+ parallel::strategy = hardware_concurrency(threads);
+ config->thinLTOJobs = v;
+ }
+ if (auto *arg = args.getLastArg(OPT_thinlto_jobs))
+ config->thinLTOJobs = arg->getValue();
+
if (auto *arg = args.getLastArg(OPT_features)) {
config->features =
llvm::Optional<std::vector<std::string>>(std::vector<std::string>());
diff --git a/lld/wasm/Options.td b/lld/wasm/Options.td
index d0275cf5cd49..0910a74660f3 100644
--- a/lld/wasm/Options.td
+++ b/lld/wasm/Options.td
@@ -64,9 +64,6 @@ def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">,
def mllvm: S<"mllvm">, HelpText<"Options to pass to LLVM">;
-def no_threads: F<"no-threads">,
- HelpText<"Do not run the linker multi-threaded">;
-
def no_color_diagnostics: F<"no-color-diagnostics">,
HelpText<"Do not use colors in diagnostics">;
@@ -98,7 +95,9 @@ def strip_all: F<"strip-all">, HelpText<"Strip all symbols">;
def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">;
-def threads: F<"threads">, HelpText<"Run the linker multi-threaded">;
+defm threads
+ : Eq<"threads", "Number of threads. '1' disables multi-threading. By "
+ "default all available hardware threads are used">;
def trace: F<"trace">, HelpText<"Print the names of the input files">;
@@ -198,4 +197,5 @@ def save_temps: F<"save-temps">;
def thinlto_cache_dir: J<"thinlto-cache-dir=">,
HelpText<"Path to ThinLTO cached object file directory">;
defm thinlto_cache_policy: Eq<"thinlto-cache-policy", "Pruning policy for the ThinLTO cache">;
-def thinlto_jobs: J<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs">;
+def thinlto_jobs: J<"thinlto-jobs=">,
+ HelpText<"Number of ThinLTO jobs. Default to --threads=">;
diff --git a/llvm/include/llvm/Support/Parallel.h b/llvm/include/llvm/Support/Parallel.h
index 3c0ed2c11127..e9d04bfb279f 100644
--- a/llvm/include/llvm/Support/Parallel.h
+++ b/llvm/include/llvm/Support/Parallel.h
@@ -12,6 +12,7 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Threading.h"
#include <algorithm>
#include <condition_variable>
@@ -33,6 +34,11 @@ struct is_execution_policy
constexpr sequential_execution_policy seq{};
constexpr parallel_execution_policy par{};
+// Strategy for the default executor used by the parallel routines provided by
+// this file. It defaults to using all hardware threads and should be
+// initialized before the first use of parallel routines.
+extern ThreadPoolStrategy strategy;
+
namespace detail {
#if LLVM_ENABLE_THREADS
diff --git a/llvm/lib/Support/Parallel.cpp b/llvm/lib/Support/Parallel.cpp
index 0272a53beb39..7f6ce82763d6 100644
--- a/llvm/lib/Support/Parallel.cpp
+++ b/llvm/lib/Support/Parallel.cpp
@@ -20,6 +20,8 @@
#include <thread>
#include <vector>
+llvm::ThreadPoolStrategy llvm::parallel::strategy;
+
namespace llvm {
namespace parallel {
namespace detail {
@@ -78,6 +80,9 @@ class ThreadPoolExecutor : public Executor {
T.join();
}
+ struct Creator {
+ static void *call() { return new ThreadPoolExecutor(strategy); }
+ };
struct Deleter {
static void call(void *Ptr) { ((ThreadPoolExecutor *)Ptr)->stop(); }
};
@@ -131,7 +136,8 @@ Executor *Executor::getDefaultExecutor() {
// are more frequent with the debug static runtime.
//
// This also prevents intermittent deadlocks on exit with the MinGW runtime.
- static ManagedStatic<ThreadPoolExecutor, object_creator<ThreadPoolExecutor>,
+
+ static ManagedStatic<ThreadPoolExecutor, ThreadPoolExecutor::Creator,
ThreadPoolExecutor::Deleter>
ManagedExec;
static std::unique_ptr<ThreadPoolExecutor> Exec(&(*ManagedExec));
diff --git a/llvm/utils/gn/secondary/lld/Common/BUILD.gn b/llvm/utils/gn/secondary/lld/Common/BUILD.gn
index 02f91cde6745..125cad30a32e 100644
--- a/llvm/utils/gn/secondary/lld/Common/BUILD.gn
+++ b/llvm/utils/gn/secondary/lld/Common/BUILD.gn
@@ -39,7 +39,6 @@ static_library("Common") {
"Reproduce.cpp",
"Strings.cpp",
"TargetOptionsCommandFlags.cpp",
- "Threads.cpp",
"Timer.cpp",
"Version.cpp",
]
More information about the llvm-commits
mailing list