This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: RFA: Remove alias usage from libgcc/sync.c
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>, Richard Sandiford <rdsandiford at googlemail dot com>
- Date: Fri, 11 Oct 2013 10:17:41 +0200
- Subject: Re: RFA: Remove alias usage from libgcc/sync.c
- Authentication-results: sourceware.org; auth=none
- References: <87ob6wp8oh dot fsf at talisman dot default>
On Fri, Oct 11, 2013 at 9:29 AM, Richard Sandiford
<rdsandiford@googlemail.com> wrote:
> This is a follow-up to:
>
> http://gcc.gnu.org/ml/gcc/2013-10/msg00075.html
>
> The outcome on IRC was that __asm ought to behave like aliases eventually,
> so we should abandom the renaming-in-C thing. One way would be to code
> the functions directly as asm files, or use inline asm, but it seems a
> shame to do that when GCC already knows how to generate the function
> body we want.
>
> This patch instead compiles the functions under a different name
> and postprocesses the asm output. See the comment in the patch
> for more details.
>
> It would be possible to do the whole compilation using pipes,
> but that wouldn't pick up failures in earlier commands (at least
> not without relying on bashisms).
>
> Tested on mips64-linux-gnu. OK to install?
Btw, one other way of deliberately and forever get around GCC getting
what you are after is using a toplevel asm to build the alias manually.
Like
asm(".alias __sync_synchronize sync_synchronize");
at least unless Honza starts to implement a (toplevel) asm parser
to catch symbol definitions and uses (something we need a way
for). Don't forget to mark sync_synchronize with the used attribute.
Richard.
> Thanks,
> Richard
>
>
> libgcc/
> * Makefile.in (sync_compile): New macro.
> ($(libgcc-sync-size-funcs-o), $(libgcc-sync-funcs-o))
> ($(libgcc-sync-size-funcs-s-o), $(libgcc-sync-funcs-s-o)): Use it.
> * sync.c: Remove aliases. Rename all functions to the_function.
>
> Index: libgcc/Makefile.in
> ===================================================================
> --- libgcc/Makefile.in 2013-10-11 08:18:40.309571904 +0100
> +++ libgcc/Makefile.in 2013-10-11 08:25:26.513967865 +0100
> @@ -718,38 +718,49 @@ libgcc-sync-size-funcs := $(foreach pref
> $(foreach suffix, 1 2 4 8 16, \
> $(prefix)_$(suffix)))
>
> +# sync.c uses GCC's expansion of built-in functions to define out-of-line
> +# versions of those same functions. This cannot be expressed directly in C,
> +# even with GNU extensions, so instead sync.c calls the out-of-line function
> +# "the_function" and we postprocess the assembly code to rename it.
> +#
> +# This code is morally assembly code rather than C code (and so cannot
> +# be included in LTO, for example). However, having GCC do most of the
> +# work saves recoding the functions as inline asm or .S files.
> +sync_compile = $(gcc_compile_bare) $(compile_deps) $(SYNC_CFLAGS) -S \
> + -Wno-missing-prototypes $(1) -o $@.s.in && \
> + sed 's/the_function/__$*/g' < $@.s.in > $@.s && \
> + $(gcc_compile_bare) -c $@.s -o $@ && \
> + rm $@.s.in $@.s
> +
> libgcc-sync-size-funcs-o = $(patsubst %,%$(objext),$(libgcc-sync-size-funcs))
> $(libgcc-sync-size-funcs-o): %$(objext): $(srcdir)/sync.c
> - $(gcc_compile) $(SYNC_CFLAGS) \
> + $(call sync_compile, \
> -DFN=`echo "$*" | sed 's/_[^_]*$$//'` \
> -DSIZE=`echo "$*" | sed 's/.*_//'` \
> - -c $< $(vis_hide)
> + $< $(vis_hide))
> +
> libgcc-objects += $(libgcc-sync-size-funcs-o)
>
> libgcc-sync-funcs := sync_synchronize
>
> libgcc-sync-funcs-o = $(patsubst %,%$(objext),$(libgcc-sync-funcs))
> $(libgcc-sync-funcs-o): %$(objext): $(srcdir)/sync.c
> - $(gcc_compile) $(SYNC_CFLAGS) \
> - -DL$* \
> - -c $< $(vis_hide)
> + $(call sync_compile, -DL$* $< $(vis_hide))
> libgcc-objects += $(libgcc-sync-funcs-o)
>
> ifeq ($(enable_shared),yes)
> libgcc-sync-size-funcs-s-o = $(patsubst %,%_s$(objext), \
> $(libgcc-sync-size-funcs))
> $(libgcc-sync-size-funcs-s-o): %_s$(objext): $(srcdir)/sync.c
> - $(gcc_s_compile) $(SYNC_CFLAGS) \
> + $(call sync_compile, \
> -DFN=`echo "$*" | sed 's/_[^_]*$$//'` \
> -DSIZE=`echo "$*" | sed 's/.*_//'` \
> - -c $<
> + $< -DSHARED)
> libgcc-s-objects += $(libgcc-sync-size-funcs-s-o)
>
> libgcc-sync-funcs-s-o = $(patsubst %,%_s$(objext),$(libgcc-sync-funcs))
> $(libgcc-sync-funcs-s-o): %_s$(objext): $(srcdir)/sync.c
> - $(gcc_s_compile) $(SYNC_CFLAGS) \
> - -DL$* \
> - -c $<
> + $(call sync_compile, -DL$* $< -DSHARED)
> libgcc-s-objects += $(libgcc-sync-funcs-s-o)
> endif
> endif
> Index: libgcc/sync.c
> ===================================================================
> --- libgcc/sync.c 2013-10-11 08:18:40.321572005 +0100
> +++ libgcc/sync.c 2013-10-11 08:18:40.664574880 +0100
> @@ -72,22 +72,22 @@ Software Foundation; either version 3, o
> TYPE is a type that has UNITS bytes. */
>
> #define DEFINE_V_PV(NAME, UNITS, TYPE) \
> - static TYPE \
> - NAME##_##UNITS (TYPE *ptr, TYPE value) \
> + TYPE \
> + the_function (TYPE *ptr, TYPE value) \
> { \
> return __##NAME (ptr, value); \
> }
>
> -#define DEFINE_V_PVV(NAME, UNITS, TYPE) \
> - static TYPE \
> - NAME##_##UNITS (TYPE *ptr, TYPE value1, TYPE value2) \
> +#define DEFINE_V_PVV(NAME, UNITS, TYPE) \
> + TYPE \
> + the_function (TYPE *ptr, TYPE value1, TYPE value2) \
> { \
> return __##NAME (ptr, value1, value2); \
> }
>
> #define DEFINE_BOOL_PVV(NAME, UNITS, TYPE) \
> - static _Bool \
> - NAME##_##UNITS (TYPE *ptr, TYPE value1, TYPE value2) \
> + _Bool \
> + the_function (TYPE *ptr, TYPE value1, TYPE value2) \
> { \
> return __##NAME (ptr, value1, value2); \
> }
> @@ -118,9 +118,7 @@ #define local_sync_lock_test_and_set DEF
> #define DEFINE1(NAME, UNITS, TYPE) \
> static int unused[sizeof (TYPE) == UNITS ? 1 : -1] \
> __attribute__((unused)); \
> - local_##NAME (NAME, UNITS, TYPE); \
> - typeof (NAME##_##UNITS) __##NAME##_##UNITS \
> - __attribute__((alias (#NAME "_" #UNITS)));
> + local_##NAME (NAME, UNITS, TYPE)
>
> /* As above, but performing macro expansion on the arguments. */
> #define DEFINE(NAME, UNITS, TYPE) DEFINE1 (NAME, UNITS, TYPE)
> @@ -167,13 +165,11 @@ DEFINE (FN, 8, UOItype)
>
> #if defined Lsync_synchronize
>
> -static void
> -sync_synchronize (void)
> +void
> +the_function (void)
> {
> __sync_synchronize ();
> }
> -typeof (sync_synchronize) __sync_synchronize \
> - __attribute__((alias ("sync_synchronize")));
>
> #endif
>