From c55c3335c5e86777137c8dcca504af9c1d2cadf1 Mon Sep 17 00:00:00 2001 From: Matthew Krupcale Date: Sun, 9 Aug 2020 09:45:15 -0400 Subject: 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. --- libbuild2/cc/link-rule.cxx | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) 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 #include // exit() #include // strlen() +#include // to_string() #include // 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) { -- cgit v1.1