From: Kyrylo Tkachov <[email protected]>
The automake SUBDIRS recursion in libsanitizer builds its
subdirectories strictly sequentially, but the bulk of the work is in
asan, tsan, hwasan and ubsan, which are independent of one another and
only have link-time dependencies on the convenience libraries built in
sanitizer_common, interception, libbacktrace and lsan. libsanitizer
is the last target library to be built during a bootstrap, so the
serial chain sits directly on the critical path. On an idle 144-core
aarch64 machine asan alone accounts for over half of the serial
subdirectory chain and tsan for another quarter.
Add per-subdirectory phony all-parallel-<subdir> targets whose
dependencies mirror the cross-subdirectory *_LIBADD link dependencies
and make all-recursive depend on them, so that a plain 'make all' (as
invoked by the top level) builds independent subdirectories
concurrently under the GNU make jobserver. The stock all-recursive
recipe still runs afterwards and no-ops through the already built
subdirectories. Install, check, clean, etc. keep the stock serial
recursion, and with -j1 the dependencies simply serialize the
sub-makes as before.
On the machine above, 'make -j96 all-target-libsanitizer' from a
freshly deleted libsanitizer build directory (including its configure
step) improves by about 30% in wall time.
libsanitizer/ChangeLog:
* Makefile.am: Build the SUBDIRS for 'all' in parallel through
per-subdirectory all-parallel-<subdir> targets with explicit
inter-subdirectory dependencies, hooked as prerequisites of
all-recursive.
* Makefile.in: Regenerate.
Signed-off-by: Kyrylo Tkachov <[email protected]>
---
libsanitizer/Makefile.am | 29 +++++++++++++++++++++++++++++
libsanitizer/Makefile.in | 25 +++++++++++++++++++++++++
2 files changed, 54 insertions(+)
diff --git a/libsanitizer/Makefile.am b/libsanitizer/Makefile.am
index 53e20bdac2c..a746ff5c865 100644
--- a/libsanitizer/Makefile.am
+++ b/libsanitizer/Makefile.am
@@ -31,6 +31,35 @@ endif
## Force DIST_SUBDIRS so that make distclean works
DIST_SUBDIRS = $(SUBDIRS)
+# Run independent subdirectory builds concurrently under the GNU make
+# jobserver. The prerequisites mirror cross-subdirectory link dependencies.
+# The stock all-recursive recipe then passes through the completed builds.
+# Other recursive targets retain Automake's serial ordering.
+if SANITIZER_SUPPORTED
+sanitizer_parallel_targets = $(SUBDIRS:%=all-parallel-%)
+.PHONY: $(sanitizer_parallel_targets)
+$(sanitizer_parallel_targets):
+ @cd $(@:all-parallel-%=%) && $(MAKE) $(AM_MAKEFLAGS) all
+
+# Cross-subdirectory link dependencies. Keep in sync with the
+# subdirectories' *_LIBADD variables.
+sanitizer_parallel_base_deps = all-parallel-sanitizer_common
+if !USING_MAC_INTERPOSE
+sanitizer_parallel_base_deps += all-parallel-interception
+endif
+if LIBBACKTRACE_SUPPORTED
+sanitizer_parallel_base_deps += all-parallel-libbacktrace
+endif
+all-parallel-lsan all-parallel-ubsan all-parallel-tsan: \
+ $(sanitizer_parallel_base_deps)
+# libasan and libhwasan also link in lsan's libsanitizer_lsan.la.
+all-parallel-asan all-parallel-hwasan: \
+ $(sanitizer_parallel_base_deps) all-parallel-lsan
+
+# Only the subdirectories configured into SUBDIRS are requested.
+all-recursive: $(sanitizer_parallel_targets)
+endif
+
## May be used by toolexeclibdir.
gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
diff --git a/libsanitizer/Makefile.in b/libsanitizer/Makefile.in
index fa6fe9e26a3..02fd38c121f 100644
--- a/libsanitizer/Makefile.in
+++ b/libsanitizer/Makefile.in
@@ -98,6 +98,8 @@ target_triplet = @target@
@LIBBACKTRACE_SUPPORTED_TRUE@@SANITIZER_SUPPORTED_TRUE@am__append_3 =
libbacktrace
@SANITIZER_SUPPORTED_TRUE@@TSAN_SUPPORTED_TRUE@am__append_4 = tsan
@HWASAN_SUPPORTED_TRUE@@SANITIZER_SUPPORTED_TRUE@am__append_5 = hwasan
+@SANITIZER_SUPPORTED_TRUE@@USING_MAC_INTERPOSE_FALSE@am__append_6 =
all-parallel-interception
+@LIBBACKTRACE_SUPPORTED_TRUE@@SANITIZER_SUPPORTED_TRUE@am__append_7 =
all-parallel-libbacktrace
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
@@ -371,6 +373,18 @@ nodist_saninclude_HEADERS = $(am__append_1)
@SANITIZER_SUPPORTED_TRUE@ $(am__append_3) lsan asan ubsan \
@SANITIZER_SUPPORTED_TRUE@ $(am__append_4) $(am__append_5)
DIST_SUBDIRS = $(SUBDIRS)
+
+# Run independent subdirectory builds concurrently under the GNU make
+# jobserver. The prerequisites mirror cross-subdirectory link dependencies.
+# The stock all-recursive recipe then passes through the completed builds.
+# Other recursive targets retain Automake's serial ordering.
+@SANITIZER_SUPPORTED_TRUE@sanitizer_parallel_targets =
$(SUBDIRS:%=all-parallel-%)
+
+# Cross-subdirectory link dependencies. Keep in sync with the
+# subdirectories' *_LIBADD variables.
+@SANITIZER_SUPPORTED_TRUE@sanitizer_parallel_base_deps = \
+@SANITIZER_SUPPORTED_TRUE@ all-parallel-sanitizer_common \
+@SANITIZER_SUPPORTED_TRUE@ $(am__append_6) $(am__append_7)
gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
# Work around what appears to be a GNU make bug handling MAKEFLAGS
@@ -764,6 +778,17 @@ uninstall-am: uninstall-nodist_sanincludeHEADERS \
.PRECIOUS: Makefile
+@[email protected]: $(sanitizer_parallel_targets)
+@SANITIZER_SUPPORTED_TRUE@$(sanitizer_parallel_targets):
+@SANITIZER_SUPPORTED_TRUE@ @cd $(@:all-parallel-%=%) && $(MAKE)
$(AM_MAKEFLAGS) all
+@SANITIZER_SUPPORTED_TRUE@all-parallel-lsan all-parallel-ubsan
all-parallel-tsan: \
+@SANITIZER_SUPPORTED_TRUE@ $(sanitizer_parallel_base_deps)
+# libasan and libhwasan also link in lsan's libsanitizer_lsan.la.
+@SANITIZER_SUPPORTED_TRUE@all-parallel-asan all-parallel-hwasan: \
+@SANITIZER_SUPPORTED_TRUE@ $(sanitizer_parallel_base_deps)
all-parallel-lsan
+
+# Only the subdirectories configured into SUBDIRS are requested.
+@SANITIZER_SUPPORTED_TRUE@all-recursive: $(sanitizer_parallel_targets)
# GNU Make needs to see an explicit $(MAKE) variable in the command it
# runs to enable its job server during parallel builds. Hence the
--
2.50.1 (Apple Git-155)