diff options
author | Matthew Krupcale <mkrupcale@matthewkrupcale.com> | 2020-08-09 09:45:15 -0400 |
---|---|---|
committer | Matthew Krupcale <mkrupcale@matthewkrupcale.com> | 2020-08-10 23:11:26 -0400 |
commit | c55c3335c5e86777137c8dcca504af9c1d2cadf1 (patch) | |
tree | efcfce351cc754034ba30201d2a3857cb8f6a050 | |
parent | 1276a28b88295caf27c5df97d2e61b28feed3999 (diff) |
Adjust linker arguments for LTO parallelization
GCC 10+ and Clang 4+ support controlling the number of LTO threads/jobs used
during linking. Use the build2 scheduler to allocate up to the number of
hardware threads to the GCC or Clang linker processes when -flto=auto or
-flto=thin is specified, respectively. Otherwise, GCC or Clang will attempt to
spawn the number of hardware threads detected for each linker process, which
could result in up to n^2 linker threads on a CPU with n hardware threads.
-rw-r--r-- | libbuild2/cc/link-rule.cxx | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/libbuild2/cc/link-rule.cxx b/libbuild2/cc/link-rule.cxx index e94f538..fd5f284 100644 --- a/libbuild2/cc/link-rule.cxx +++ b/libbuild2/cc/link-rule.cxx @@ -6,6 +6,7 @@ #include <map> #include <cstdlib> // exit() #include <cstring> // strlen() +#include <string> // to_string() #include <libbutl/filesystem.mxx> // file_exists(), path_search() @@ -2991,6 +2992,47 @@ namespace build2 try_rmfile (relt, true); } + // Adjust args for LTO parallelization + scheduler::alloc_guard ag; + if (!lt.static_library ()) + { + switch (ctype) + { + case compiler_type::gcc: + { + cstrings::reverse_iterator args_it; + if (cmaj >= 10 && + (args_it = find_option ("-flto=auto", args.rbegin () + 1, args.rend ())) + != args.rend ()) + { + ag = scheduler::alloc_guard (ctx.sched, 0); + arg1 = "-flto=" + std::to_string (1 + ag.n); + *args_it = arg1.c_str (); + } + + break; + } + case compiler_type::clang: + { + if (cmaj >= 4 && find_option ("-flto=thin", args)) + { + cstrings::reverse_iterator args_it; + if ((args_it = find_option_prefix ("-flto-jobs=", args.rbegin () + 1, args.rend ())) + == args.rend ()) + { + ag = scheduler::alloc_guard (ctx.sched, 0); + arg1 = "-flto-jobs=" + std::to_string (1 + ag.n); + args.push_back (arg1.c_str ()); + } + } + break; + } + case compiler_type::msvc: + case compiler_type::icc: + break; + } + } + if (verb == 1) text << (lt.static_library () ? "ar " : "ld ") << t; else if (verb == 2) @@ -3162,6 +3204,7 @@ namespace build2 } run_finish (args, pr); + ag.deallocate (); } catch (const process_error& e) { |