This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: Remove alias usage from libgcc/sync.c


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?

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
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]