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++.

Reply via email to