[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[patches] [patch] Add BIG_MACROS option group



Hello,

The attached patch adds new option group -- OPTION_EGLIBC_BIG_MACROS -- to EGLIBC. This option group does not enable or disable functionality, but rather specifies if certain pieces of code should expand inline (through macros) or use function calls instead.

This particular patch handles __libc_lock_* macros which tend to expand to rather significant portions of code (usually, around 0.5KB per instance). For example, on PowerPC wrapping this code into internal functions yields 1.5% smaller libc.so.

The patch describes a rather automatic way of converting such macros into functions, so it will be easy to use it as a reference for future similar conversions.

Tested by build on powerpc in default and uClibc configurations.

OK to apply?

Thanks,

--
Maxim K.
CodeSourcery
2009-07-22  Maxim Kuvyrkov  <maxim@xxxxxxxxxxxxxxxx>

	Add BIG_MACROS option group.

	* option-groups.def (OPTION_EGLIBC_BIG_MACROS): Define new option
	group.
	* option-groups.defaults (OPTION_EGLIBC_BIG_MACROS): Define default.
	* nptl/sysdeps/pthread/small-macros-fns.c: Define wrappers.
	* nptl/sysdeps/pthread/Makefile (nptl/sysdep_routines): Add
	small-macros-fns
	* nptl/sysdeps/pthread/bits/libc-lock.h
	(__libc_lock_lock, __libc_lock_lock_recursive),
	(__libc_lock_trylock, __libc_lock_trylock_recursive),
	(__libc_lock_unlock, __libc_lock_unlock_recursive):
	If OPTION_EGLIBC_BIG_MACROS, define to macro;
	define to function call	otherwise.
Index: option-groups.defaults
===================================================================
--- option-groups.defaults	(revision 8608)
+++ option-groups.defaults	(working copy)
@@ -10,6 +10,7 @@
 # By default, all option groups are enabled.
 OPTION_EGLIBC_ADVANCED_INET6 = y
 OPTION_EGLIBC_BACKTRACE = y
+OPTION_EGLIBC_BIG_MACROS = y
 OPTION_EGLIBC_BSD = y
 OPTION_EGLIBC_CXX_TESTS = y
 OPTION_EGLIBC_CATGETS = y
Index: nptl/sysdeps/pthread/small-macros-fns.c
===================================================================
--- nptl/sysdeps/pthread/small-macros-fns.c	(revision 0)
+++ nptl/sysdeps/pthread/small-macros-fns.c	(revision 0)
@@ -0,0 +1,70 @@
+/* EGLIBC: function wrappers for big macros.
+   Copyright (C) 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public License as
+   published by the Free Software Foundation; either version 2.1 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* Handle macros from ./bits/libc-lock.h.  */
+#if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+
+/* Get the macros for function bodies through a back door.  */
+# undef __OPTION_EGLIBC_BIG_MACROS__
+# define __OPTION_EGLIBC_BIG_MACROS__ 2
+# include <bits/libc-lock.h>
+
+void
+__libc_lock_lock_fn (__libc_lock_t *name)
+{
+  __libc_lock_lock (*name);
+}
+libc_hidden_def (__libc_lock_lock_fn);
+
+void
+__libc_lock_lock_recursive_fn (__libc_lock_recursive_t *name)
+{
+  __libc_lock_lock_recursive (*name);
+}
+libc_hidden_def (__libc_lock_lock_recursive_fn);
+
+int
+__libc_lock_trylock_fn (__libc_lock_t *name)
+{
+  return __libc_lock_trylock (*name);
+}
+libc_hidden_def (__libc_lock_trylock_fn);
+
+int
+__libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *name)
+{
+  return __libc_lock_trylock_recursive (*name);
+}
+libc_hidden_def (__libc_lock_trylock_recursive_fn);
+
+void
+__libc_lock_unlock_fn (__libc_lock_t *name)
+{
+  __libc_lock_unlock (*name);
+}
+libc_hidden_def (__libc_lock_unlock_fn);
+
+void
+__libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *name)
+{
+  __libc_lock_unlock_recursive (*name);
+}
+libc_hidden_def (__libc_lock_unlock_recursive_fn);
+
+#endif /*defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)*/
Index: nptl/sysdeps/pthread/Makefile
===================================================================
--- nptl/sysdeps/pthread/Makefile	(revision 8608)
+++ nptl/sysdeps/pthread/Makefile	(working copy)
@@ -25,6 +25,9 @@ endif
 
 ifeq ($(subdir),nptl)
 libpthread-sysdep_routines += errno-loc
+ifeq ($(OPTION_EGLIBC_BIG_MACROS),n)
+sysdep_routines += small-macros-fns
+endif
 endif
 
 ifeq ($(subdir),rt)
Index: nptl/sysdeps/pthread/bits/libc-lock.h
===================================================================
--- nptl/sysdeps/pthread/bits/libc-lock.h	(revision 8608)
+++ nptl/sysdeps/pthread/bits/libc-lock.h	(working copy)
@@ -238,8 +238,20 @@ typedef pthread_key_t __libc_key_t;
 
 /* Lock the named lock variable.  */
 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# if __OPTION_EGLIBC_BIG_MACROS__ != 1
+/* EGLIBC: Declare wrapper function for a big macro if either
+   !__OPTION_EGLIBC_BIG_MACROS__ or we are using a back door from
+   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS__ == 2).  */
+extern void __libc_lock_lock_fn (__libc_lock_t *);
+libc_hidden_proto (__libc_lock_lock_fn);
+# endif /* __OPTION_EGLIBC_BIG_MACROS__ != 1 */
+# if __OPTION_EGLIBC_BIG_MACROS__
 # define __libc_lock_lock(NAME) \
   ({ lll_lock (NAME, LLL_PRIVATE); 0; })
+# else
+#  define __libc_lock_lock(NAME)		\
+  __libc_lock_lock_fn (&(NAME))
+# endif /* __OPTION_EGLIBC_BIG_MACROS__ */
 #else
 # define __libc_lock_lock(NAME) \
   __libc_maybe_call (__pthread_mutex_lock, (&(NAME)), 0)
@@ -251,6 +263,14 @@ typedef pthread_key_t __libc_key_t;
 
 /* Lock the recursive named lock variable.  */
 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# if __OPTION_EGLIBC_BIG_MACROS__ != 1
+/* EGLIBC: Declare wrapper function for a big macro if either
+   !__OPTION_EGLIBC_BIG_MACROS__ or we are using a back door from
+   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS__ == 2).  */
+extern void __libc_lock_lock_recursive_fn (__libc_lock_recursive_t *);
+libc_hidden_proto (__libc_lock_lock_recursive_fn);
+# endif /* __OPTION_EGLIBC_BIG_MACROS__ != 1 */
+# if __OPTION_EGLIBC_BIG_MACROS__
 # define __libc_lock_lock_recursive(NAME) \
   do {									      \
     void *self = THREAD_SELF;						      \
@@ -261,6 +281,10 @@ typedef pthread_key_t __libc_key_t;
       }									      \
     ++(NAME).cnt;							      \
   } while (0)
+# else
+# define __libc_lock_lock_recursive(NAME)				\
+  __libc_lock_lock_recursive_fn (&(NAME))
+# endif /* __OPTION_EGLIBC_BIG_MACROS__ */
 #else
 # define __libc_lock_lock_recursive(NAME) \
   __libc_maybe_call (__pthread_mutex_lock, (&(NAME).mutex), 0)
@@ -268,8 +292,20 @@ typedef pthread_key_t __libc_key_t;
 
 /* Try to lock the named lock variable.  */
 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# if __OPTION_EGLIBC_BIG_MACROS__ != 1
+/* EGLIBC: Declare wrapper function for a big macro if either
+   !__OPTION_EGLIBC_BIG_MACROS__ or we are using a back door from
+   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS__ == 2).  */
+extern int __libc_lock_trylock_fn (__libc_lock_t *);
+libc_hidden_proto (__libc_lock_trylock_fn);
+# endif /* __OPTION_EGLIBC_BIG_MACROS__ != 1 */
+# if __OPTION_EGLIBC_BIG_MACROS__
 # define __libc_lock_trylock(NAME) \
   lll_trylock (NAME)
+# else
+# define __libc_lock_trylock(NAME) \
+  __libc_lock_trylock_fn (&(NAME))
+# endif /* __OPTION_EGLIBC_BIG_MACROS__ */
 #else
 # define __libc_lock_trylock(NAME) \
   __libc_maybe_call (__pthread_mutex_trylock, (&(NAME)), 0)
@@ -281,6 +317,14 @@ typedef pthread_key_t __libc_key_t;
 
 /* Try to lock the recursive named lock variable.  */
 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# if __OPTION_EGLIBC_BIG_MACROS__ != 1
+/* EGLIBC: Declare wrapper function for a big macro if either
+   !__OPTION_EGLIBC_BIG_MACROS__ or we are using a back door from
+   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS__ == 2).  */
+extern int __libc_lock_trylock_recursive_fn (__libc_lock_recursive_t *);
+libc_hidden_proto (__libc_lock_trylock_recursive_fn);
+# endif /* __OPTION_EGLIBC_BIG_MACROS__ != 1 */
+# if __OPTION_EGLIBC_BIG_MACROS__
 # define __libc_lock_trylock_recursive(NAME) \
   ({									      \
     int result = 0;							      \
@@ -299,6 +343,10 @@ typedef pthread_key_t __libc_key_t;
       ++(NAME).cnt;							      \
     result;								      \
   })
+# else
+# define __libc_lock_trylock_recursive(NAME) \
+  __libc_lock_trylock_recursive_fn (&(NAME))
+# endif /* __OPTION_EGLIBC_BIG_MACROS__ */
 #else
 # define __libc_lock_trylock_recursive(NAME) \
   __libc_maybe_call (__pthread_mutex_trylock, (&(NAME)), 0)
@@ -309,8 +357,20 @@ typedef pthread_key_t __libc_key_t;
 
 /* Unlock the named lock variable.  */
 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# if __OPTION_EGLIBC_BIG_MACROS__ != 1
+/* EGLIBC: Declare wrapper function for a big macro if either
+   !__OPTION_EGLIBC_BIG_MACROS__, or we are using a back door from
+   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS__ == 2).  */
+extern void __libc_lock_unlock_fn (__libc_lock_t *);
+libc_hidden_proto (__libc_lock_unlock_fn);
+# endif /* __OPTION_EGLIBC_BIG_MACROS__ != 1 */
+# if __OPTION_EGLIBC_BIG_MACROS__
 # define __libc_lock_unlock(NAME) \
   lll_unlock (NAME, LLL_PRIVATE)
+# else
+# define __libc_lock_unlock(NAME) \
+  __libc_lock_unlock_fn (&(NAME))
+# endif /* __OPTION_EGLIBC_BIG_MACROS__ */
 #else
 # define __libc_lock_unlock(NAME) \
   __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0)
@@ -320,6 +380,14 @@ typedef pthread_key_t __libc_key_t;
 
 /* Unlock the recursive named lock variable.  */
 #if defined _LIBC && (!defined NOT_IN_libc || defined IS_IN_libpthread)
+# if __OPTION_EGLIBC_BIG_MACROS__ != 1
+/* EGLIBC: Declare wrapper function for a big macro if either
+   !__OPTION_EGLIBC_BIG_MACROS__, or we are using a back door from
+   small-macros-fns.c (__OPTION_EGLIBC_BIG_MACROS__ == 2).  */
+extern void __libc_lock_unlock_recursive_fn (__libc_lock_recursive_t *);
+libc_hidden_proto (__libc_lock_unlock_recursive_fn);
+# endif /* __OPTION_EGLIBC_BIG_MACROS__ != 1 */
+# if __OPTION_EGLIBC_BIG_MACROS__
 /* We do no error checking here.  */
 # define __libc_lock_unlock_recursive(NAME) \
   do {									      \
@@ -329,6 +397,10 @@ typedef pthread_key_t __libc_key_t;
 	lll_unlock ((NAME).lock, LLL_PRIVATE);				      \
       }									      \
   } while (0)
+# else
+# define __libc_lock_unlock_recursive(NAME) \
+  __libc_lock_unlock_recursive_fn (&(NAME))
+# endif /* __OPTION_EGLIBC_BIG_MACROS__ */
 #else
 # define __libc_lock_unlock_recursive(NAME) \
   __libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0)
Index: option-groups.def
===================================================================
--- option-groups.def	(revision 8608)
+++ option-groups.def	(working copy)
@@ -85,6 +85,14 @@ config OPTION_EGLIBC_BACKTRACE
          backtrace_symbols
          backtrace_symbols_fd
 
+config OPTION_EGLIBC_BIG_MACROS
+   bool "Use extensive inline code"
+   help
+       This option group specifies whether certain pieces of code
+       should be inlined to achieve maximum speed.  If this option
+       group is not selected, function calls will be used instead,
+       hence reducing the library footprint.
+
 config OPTION_EGLIBC_BSD
    bool "BSD-specific functions, and their compatibility stubs"
    help