This is the mail archive of the libc-hacker@sourceware.cygnus.com mailing list for the glibc project.


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

Re: ar speed: sixfold improvement [PATCH]


On Thu, 30 Apr 1998 14:13:47 -0400, Roland McGrath wrote:
>> On Thu, 30 Apr 1998 13:16:04 -0400, Roland McGrath wrote:
>> >I thought you were going to use simple variable refs in the o-iterator-doit
>> >rule commands, to ease readability.
>> 
>> It didn't work; the automatic variables came out null unless I used $$
>> escaping.  Since we seem stuck with $$ escapes I figured it was easier
>> to read if the rules were right there with the dependencies.
>
>Are you sure you know what I meant and did it right?
>
>I mean where you now have `.. $$(foo) ... blah blah' (multiple lines of
>hairy commands), instead you put `$$(ar-commands)' and then do:

I missed the need for $$ escaping on ar-commands.  Duh.

Here's a revised patch.  This version also fixes a critical bug and
streamlines the dependencies for libc*.a inside Makerules.  I can't
complete a build as CVS is inconsistent right now, but it gets far
enough along (halfway through `make others') that I'm fairly sure it
works.

Uli, please ignore the previous patch and use this one instead.

zw

Thu Apr 30 16:23:31 1998  Zack Weinberg  <zack@rabi.phys.columbia.edu>

	Performance improvements: make ar less of a bottleneck.

	* Makerules (stamp.o): Just record the objects to be added to
	the archive.
	(libc_foo.a): Depend directly on the stamp files.  Construct
	the archive and ranlib it in one step.
	(subdirs-stamps): Define also if subdir == elf.  (FIXME: kludge)
	(subdirs-stamp-o): Likewise.

	(ar-symtab-name): Delete variable.
	(CREATE_ARFLAGS): Delete `ar S' hack.
	(libobjs): Delete target.
	(lib%.a): Delete target.
	(libc.a(foo.%)): Delete target.

	* config.make.in (have-ar-S): Deleted.
	* configure.in: Don't check for `ar S'; instead, check whether
	ranlib is necessary.

Index: Makerules
===================================================================
RCS file: /egcs/carton/cvsfiles/libc/Makerules,v
retrieving revision 1.288
diff -u -r1.288 Makerules
--- Makerules	1998/04/23 22:43:34	1.288
+++ Makerules	1998/04/30 20:21:47
@@ -72,15 +72,6 @@
 # `+includes' in Makeconfig references $(+sysdep-includes).
 +sysdep-includes := $(addprefix -I,$(+sysdep_dirs))
 
-# The name of the symbol table archive member.  The default is suitable for
-# BSD style archives.  It can be overridden in sysdep Makefiles when SYSV
-# style archive are used.
-ifeq (no,$(elf))
-ar-symtab-name = __.SYMDEF
-else
-ar-symtab-name = # The null name is used in ELF archives.
-endif
-
 # This variable is used in ``include $(o-iterator)'' after defining
 # $(o-iterator-doit) to produce some desired rule using $o for the object
 # suffix, and setting $(object-suffixes-left) to $(object-suffixes); a copy
@@ -510,30 +501,19 @@
 endif						# not -s
 
 ARFLAGS := r$(verbose)
-ifeq ($(have-ar-S),yes)
-CREATE_ARFLAGS := Scru$(verbose)
-else
 CREATE_ARFLAGS := cru$(verbose)
-endif
 
 # This makes all the object files in the parent library archive.
 
-.PHONY: lib libobjs lib-noranlib
+.PHONY: lib lib-noranlib
 lib: lib-noranlib $(foreach l,$(libtypes),$(patsubst %,$(common-objpfx)$l,c))
 
-# Pattern rule for libraries: depend on the __.SYMDEF member updated by ranlib.
-lib%.a: lib%.a($(ar-symtab-name)) ;
-
 # For object-suffix $o, the list of objects with that suffix.
 # Makefiles can define `elide-routines.so = foo' to leave foo.so out.
 o-objects = $(patsubst %.o,%$o,$(filter-out $(patsubst %,$(objpfx)%.o,\
 						       $(elide-routines$o)),\
 					    $(objects)))
-
-libobjs: $(foreach o,$(object-suffixes-for-libc),\
-		   $(common-objpfx)$(patsubst %,$(libtype$o),c)(\
-		   $(notdir $(o-objects))))
-lib-noranlib: libobjs
+lib-noranlib:
 others: $(addprefix $(objpfx),$(install-lib))
 
 ifndef objects
@@ -544,43 +524,25 @@
 	$(make-target-directory)
 	rm -f $@; > $@
 else
-
-# Define a pattern rule that will match many targets libc.a(foo.%), for
-# each foo.o in $(objects) (% will just happen always to match `o').  This is
-# the only way to define a rule that updates many targets at once with one
-# sequence of commands.
-define o-iterator-doit
-$(common-objpfx)$(patsubst %,$(libtype$o),c)(\
-$(addsuffix .%,$(filter-out $(elide-routines$o),$(notdir $(objects:.o=))))): \
-  $(objpfx)stamp.% ;
-endef
-object-suffixes-left := $(object-suffixes-for-libc)
-include $(o-iterator)
 
-# The pattern rule tells Make to remake $(objpfx)stamp.% as
-# the way to update all the foo.% object files in $(objects).  Now we
-# define explicit rules to update each $(objpfx)stamp.SUFFIX
+# Define explicit rules to update each $(objpfx)stamp.SUFFIX
 # timestamp file; these rules (one explicit rule is generated for each
-# object suffix) will update the parent archive with ar.  Use a static
-# pattern rule so $* is set to the object type during the commands.
+# object suffix) write a list of objects to update in the stamp file.
+# The parent will then actually add them all to the archive in the
+# archive rule, below.
 define o-iterator-doit
-$(objpfx)stamp$o: $(objpfx)stamp%: $(o-objects); $$(do-ar)
+$(objpfx)stamp$o: $(o-objects); $$(do-stamp)
 endef
+define do-stamp
+	echo '$(patsubst $(common-objpfx)%,%,$^)' > $@T
+	mv -f $@T $@
+endef
 ifdef static-only-routines
 object-suffixes-left := $(object-suffixes-for-libc)
 else
 object-suffixes-left := $(object-suffixes)
 endif
 include $(o-iterator)
-define do-ar
-topdir=`cd $(..). && pwd`; \
-$(patsubst %/,cd % &&,$(objpfx)) \
-$(SHELL) $$topdir/autolock.sh ${O%-lib}.lck $(AR) $(CREATE_ARFLAGS) ${O%-lib} \
-						  $(patsubst $(objpfx)%,%,$?)
-rm -f $@
-touch $@
-endef
-O%-lib = $(..)$(patsubst %,$(libtype$*),c)
 
 ifndef static-only-routines
 subdir_lib: $(objpfx)stamp.oS
@@ -591,21 +553,33 @@
 
 endif
 
-# Rules to update the $(ar-symtab-name) member with ranlib,
-# one for each object flavor.
+# Now define explicit rules to build the library archives; these depend
+# on the stamp files built above.  The rule always destroys and recreates
+# the library from scratch; it's faster (!) that way.
 define o-iterator-doit
-$(common-objpfx)$(patsubst %,$(libtype$o),c)($(ar-symtab-name)): \
-	  $(common-objpfx)$(patsubst %,$(libtype$o),c)(\
-	    $(patsubst $(objpfx)%,%,$(o-objects))) $(subdirs-stamp-o); \
-	$(SHELL) $$(..)./autolock.sh \
-	  $$(common-objpfx)$$(patsubst %,$$(libtype$o),c).lck \
-	  $$(RANLIB) $$(common-objpfx)$$(patsubst %,$$(libtype$o),c)
+$(common-objpfx)$(patsubst %,$(libtype$o),c): \
+		$(subdirs-stamp-o) $(common-objpfx)stamp$o; $$(do-makelib)
 endef
+define do-makelib
+	(set -e; cd $(common-objdir); 			  \
+	$(AR) $(CREATE_ARFLAGS) $(@F)T			  \
+		`cat $(patsubst $(common-objpfx)%,%,$^)`; \
+	$(RANLIB) $(@F)T;				  \
+	mv -f $(@F)T $(@F))
+endef
 ifndef subdir
 subdirs-stamps := $(foreach d,$(subdirs),$(common-objpfx)$d/stamp%)
 subdirs-stamp-o = $(subst %,$o,$(subdirs-stamps))
 $(subdirs-stamps): subdir_lib;
 endif
+# The elf directory needs to know subdirs-stamp-o; otherwise libc_pic.a
+# is mangled. FIXME: It would be cleaner to move the final construction
+# of ld.so to top level.
+ifeq ($(subdir),elf)
+subdirs-stamps := $(foreach d,$(subdirs),$(common-objpfx)$d/stamp%)
+subdirs-stamp-o = $(subst %,$o,$(subdirs-stamps))
+endif
+
 object-suffixes-left = $(object-suffixes-for-libc)
 include $(o-iterator)
 
Index: config.make.in
===================================================================
RCS file: /egcs/carton/cvsfiles/libc/config.make.in,v
retrieving revision 1.52
diff -u -r1.52 config.make.in
--- config.make.in	1998/04/21 17:58:51	1.52
+++ config.make.in	1998/04/30 20:21:47
@@ -35,7 +35,6 @@
 
 versioning = @VERSIONING@
 
-have-ar-S=@libc_cv_ar_S@
 have-no-whole-archive = @libc_cv_ld_no_whole_archive@
 have-no-exceptions = @libc_cv_gcc_no_exceptions@
 have-bash2 = @libc_cv_have_bash2@
Index: configure.in
===================================================================
RCS file: /egcs/carton/cvsfiles/libc/configure.in,v
retrieving revision 1.210
diff -u -r1.210 configure.in
--- configure.in	1998/04/21 17:59:02	1.210
+++ configure.in	1998/04/30 20:21:48
@@ -492,19 +492,26 @@
 fi
 AC_SUBST(SYSINCLUDES)
 
-# check if ar takes S
-AC_CACHE_CHECK(for ar S, libc_cv_ar_S, [dnl
-tmpo=$$.o
-tmplib=lib$$.a
-rm -f $tmpo $tmplib
-touch $tmpo
-if AC_TRY_COMMAND([${AR-ar} rcuS $tmplib $tmpo > /dev/null 2>&1]); then
-  libc_cv_ar_S=yes
+# check if ranlib is necessary
+AC_CACHE_CHECK(whether ranlib is necessary, libc_cv_ranlib_necessary, [dnl
+cat > conftest.c <<EOF
+int a;
+char b;
+void c(void) {}
+EOF
+$CC $CFLAGS -c conftest.c
+$AR cr conftest.a conftest.c
+cp conftest.a conftest2.a
+$RANLIB conftest.a
+if cmp -s conftest.a conftest2.a; then
+  libc_cv_ranlib_necessary=no
 else
-  libc_cv_ar_S=no
+  libc_cv_ranlib_necessary=yes
 fi
-rm -f $tmpo $tmplib])
-AC_SUBST(libc_cv_ar_S)dnl
+rm -rf conftest*])
+if test "$libc_cv_ranlib_necessary" = no; then
+ RANLIB=:
+fi
 
 # Test if LD_LIBRARY_PATH contains the notation for the current directory
 # since this would lead to problems installing/building glibc.


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