On Sat, Jul 16, 2016 at 3:13 PM, Patrick Palka <patr...@parcs.ath.cx> wrote: > On Sat, 16 Jul 2016, Patrick Palka wrote: > >> This patch makes the 0.5GB libbackend.a get built via "ar rcs" instead >> of via "ar rc" + "ranlib", if possible. The problem with the latter is >> that it's about twice as slow as the former and it makes libbackend.a >> get written twice which is wasteful. On my machine this optimization >> reduces rebuild time in a --disable-bootstrap tree after touching tree.c >> by around 25%, from ~28s to ~21s. This optimization is only performed >> when the current ar is GNU ar where we can be reasonably sure that the >> "rcs" directive is supported. >> >> Does this change look reasonable? I am currently bootstrapping it on >> x86_64-pc-linux-gnu. >> >> gcc/ChangeLog: >> >> * configure.ac (ar_is_gnu): New variable. AC_SUBST it. >> * configure: Regenerate. >> * Makefile.in (AR_IS_GNU): New variable. >> (USE_AR_RCS): New variable. >> (libbackend.a): When building this archive, if USE_AR_RCS then >> just invoke "ar rcs" instead of invoking "ar rc" followed by >> "ranlib". >> --- >> gcc/Makefile.in | 18 ++++++++++++++++++ >> gcc/configure | 15 +++++++++++++-- >> gcc/configure.ac | 8 ++++++++ >> 3 files changed, 39 insertions(+), 2 deletions(-) >> >> diff --git a/gcc/Makefile.in b/gcc/Makefile.in >> index 0786fa3..5ae6100 100644 >> --- a/gcc/Makefile.in >> +++ b/gcc/Makefile.in >> @@ -237,10 +237,22 @@ FLEX = @FLEX@ >> FLEXFLAGS = >> AR = @AR@ >> AR_FLAGS = rc >> +AR_IS_GNU = @ar_is_gnu@ >> NM = @NM@ >> RANLIB = @RANLIB@ >> RANLIB_FLAGS = @ranlib_flags@ >> >> +# Whether invocations of ar + ranlib can be replaced by a single >> +# invocation of "ar rcs". >> +USE_AR_RCS = no >> +ifeq ($(AR_IS_GNU),yes) >> +ifeq ($(AR_FLAGS),rc) >> +ifeq ($(RANLIB_FLAGS),) >> +USE_AR_RCS = yes >> +endif >> +endif >> +endif >> + >> # Libraries to use on the host. >> HOST_LIBS = @HOST_LIBS@ >> >> @@ -1882,8 +1894,14 @@ compilations: $(BACKEND) >> # This archive is strictly for the host. >> libbackend.a: $(OBJS) >> -rm -rf libbackend.a >> + @# Elide the invocation of ranlib if possible, as doing so >> + @# significantly reduces the build time of this archive. >> +ifeq ($(USE_AR_RCS),yes) >> + $(AR) $(AR_FLAGS)s libbackend.a $(OBJS) >> +else >> $(AR) $(AR_FLAGS) libbackend.a $(OBJS) >> -$(RANLIB) $(RANLIB_FLAGS) libbackend.a >> +endif >> >> libcommon-target.a: $(OBJS-libcommon-target) >> -rm -rf libcommon-target.a >> diff --git a/gcc/configure b/gcc/configure >> index ed44472..db761c8 100755 >> --- a/gcc/configure >> +++ b/gcc/configure >> @@ -749,6 +749,7 @@ CXXDEPMODE >> DEPDIR >> am__leading_dot >> doc_build_sys >> +ar_is_gnu >> AR >> NM >> BISON >> @@ -8459,6 +8460,16 @@ fi >> >> fi >> >> +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ar is GNU ar" >&5 >> +$as_echo_n "checking whether ar is GNU ar... " >&6; } >> +ar_is_gnu=no >> +if $AR --version 2>/dev/null | sed 1q | grep "GNU ar" > /dev/null; then >> + ar_is_gnu=yes >> +fi >> +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ar_is_gnu" >&5 >> +$as_echo "$ar_is_gnu" >&6; } >> + >> + >> # The jit documentation looks better if built with sphinx, but can be >> # built with texinfo if sphinx is not available. >> # Set "doc_build_sys" to "sphinx" or "texinfo" accordingly. >> @@ -18475,7 +18486,7 @@ else >> lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 >> lt_status=$lt_dlunknown >> cat > conftest.$ac_ext <<_LT_EOF >> -#line 18478 "configure" >> +#line 18489 "configure" >> #include "confdefs.h" >> >> #if HAVE_DLFCN_H >> @@ -18581,7 +18592,7 @@ else >> lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 >> lt_status=$lt_dlunknown >> cat > conftest.$ac_ext <<_LT_EOF >> -#line 18584 "configure" >> +#line 18595 "configure" >> #include "confdefs.h" >> >> #if HAVE_DLFCN_H >> diff --git a/gcc/configure.ac b/gcc/configure.ac >> index 086d0fc..3749b21 100644 >> --- a/gcc/configure.ac >> +++ b/gcc/configure.ac >> @@ -1081,6 +1081,14 @@ else >> AC_CHECK_PROG(AR, ar, ar, ${CONFIG_SHELL-/bin/sh} ${srcdir}/../missing ar) >> fi >> >> +AC_MSG_CHECKING(whether ar is GNU ar) >> +ar_is_gnu=no >> +if $AR --version 2>/dev/null | sed 1q | grep "GNU ar" > /dev/null; then >> + ar_is_gnu=yes >> +fi >> +AC_MSG_RESULT($ar_is_gnu) >> +AC_SUBST(ar_is_gnu) >> + >> # The jit documentation looks better if built with sphinx, but can be >> # built with texinfo if sphinx is not available. >> # Set "doc_build_sys" to "sphinx" or "texinfo" accordingly. >> -- >> 2.9.2.321.g3e7e728 >> >> > > Even better, why build libbackend.a at all? Why not just pass the list > of object files directly to the linker instead of going through an > intermediate archive? The following patch cuts rebuild time by 50%, > from 28s to 14s by making libbackend.a no longer get built. (The > Make-lang.in hunk is apparently necessary to avoid duplicate-reference > link errors since incpath.o is already listed in $(OBJS)).
There is an issue with this in that the number of files in OBJS can increase to a large number. Really we should be testing if response files (@file) support exist and use that instead. Thanks, Andrew > > diff --git a/gcc/Makefile.in b/gcc/Makefile.in > index 5ae6100..7b8ec16 100644 > --- a/gcc/Makefile.in > +++ b/gcc/Makefile.in > @@ -1591,7 +1591,7 @@ endif > # compilation or not. > ALL_HOST_OBJS = $(ALL_HOST_FRONTEND_OBJS) $(ALL_HOST_BACKEND_OBJS) > > -BACKEND = libbackend.a main.o libcommon-target.a libcommon.a \ > +BACKEND = $(OBJS) main.o libcommon-target.a libcommon.a \ > $(CPPLIB) $(LIBDECNUMBER) > > # This is defined to "yes" if Tree checking is enabled, which roughly means > diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in > index cc3337d..d09b449 100644 > --- a/gcc/cp/Make-lang.in > +++ b/gcc/cp/Make-lang.in > @@ -67,7 +67,7 @@ g++-cross$(exeext): xg++$(exeext) > > # The compiler itself. > # Shared with C front end: > -CXX_C_OBJS = attribs.o incpath.o \ > +CXX_C_OBJS = attribs.o \ > $(C_COMMON_OBJS) $(CXX_TARGET_OBJS) > > # Language-specific object files for C++ and Objective C++.