This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils 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]

[patch] ld speedup 2/3 (wildcardp call reduction)


Hi,

the second thing we did was to reduce the number of potentially expensive
wildcardp() calls which happen when there are is a big number of sections,
by simply caching the result of the call.

For instance in designer with debug infos we have:
                0.00    0.00       2/1843589     walk_wild [7]
                0.00    0.00       2/1843589     open_input_bfds [61]
                0.00    0.00       2/1843589     lang_add_wild [63]
                0.15    0.00 1843583/1843589     walk_wild_section [11]
[15]     0.8    0.15    0.00 1843589         wildcardp [15]

With the patch it is:
                0.00    0.00       2/55946       walk_wild [10]
                0.00    0.00       2/55946       open_input_bfds [68]
                0.00    0.00     216/55946       yyparse [166]
                0.00    0.00   55726/55946       walk_wild_section [9]
[70]     0.0    0.00    0.00   55946         wildcardp [70]

which is, well ... less.

It didn't do much difference, just something which stood out in the
profiles.  Results are like so (non-debug objects):

ld.cvs
libqt-mt.so  real    0m2.409s user    0m2.190s sys     0m0.220s
assistant    real    0m2.649s user    0m2.600s sys     0m0.050s
designer     real    0m3.425s user    0m3.350s sys     0m0.080s

ld.wildcard
libqt-mt.so  real    0m2.338s user    0m2.070s sys     0m0.270s
assistant    real    0m2.635s user    0m2.610s sys     0m0.030s
designer     real    0m3.391s user    0m3.270s sys     0m0.120s

and debug objects:
ld.cvs
libqt-mt.so  real    1m12.083s user    1m2.280s sys     0m1.650s
assistant    real    0m4.854s user    0m4.050s sys     0m0.200s
designer     real    0m26.252s user    0m19.830s sys     0m0.910s

ld.wildcard
libqt-mt.so  real    1m12.628s user    1m2.010s sys     0m1.740s
assistant    real    0m4.819s user    0m4.040s sys     0m0.160s
designer     real    0m23.067s user    0m19.770s sys     0m1.010s

So, it's a bit inconclusive but I think it does no harm, and avoiding
function calls should be a worthwhile goal.  Maybe it makes a bigger
difference on other platforms.  One could also think about making the
'sorted' and 'wildcard_p' members be 1bit bitfields to avoid the memory
overhead, but it didn't make much difference, as anyway there are not
_that_ many instances of that struct.


Ciao,
Michael.

2003-09-10  Lars Knoll  <lars@trolltech.com>
            Michael Matz  <matz@suse.de>

        * ld.h (struct wildcard_spec): Add wildcard_p member.
        * ldgram.y (wildcard_spec, input_section_spec_no_keep): Initialize it.
        * ldlang.h (wildcardp): Declare.
        * ldlang.c (wildcardp): Globalize.
        (walk_wild_section, lang_add_wild): Use new member instead calling
        wildcardp.
        (lang_add_wild): Reset new member when resetting name.
        * mri.c (mri_draw_tree): Initialize wildcard_p member.

Index: ld.h
===================================================================
RCS file: /cvs/src/src/ld/ld.h,v
retrieving revision 1.21
diff -u -p -r1.21 ld.h
--- ld.h	28 Jun 2003 05:28:54 -0000	1.21
+++ ld.h	10 Sep 2003 14:27:59 -0000
@@ -71,6 +71,7 @@ struct wildcard_spec {
   const char *name;
   struct name_list *exclude_name_list;
   bfd_boolean sorted;
+  bfd_boolean wildcard_p;
 };

 struct wildcard_list {
Index: ldgram.y
===================================================================
RCS file: /cvs/src/src/ld/ldgram.y,v
retrieving revision 1.27
diff -u -p -r1.27 ldgram.y
--- ldgram.y	27 Jul 2003 11:58:28 -0000	1.27
+++ ldgram.y	10 Sep 2003 14:27:59 -0000
@@ -411,24 +411,28 @@ wildcard_spec:
 			  $$.name = $1;
 			  $$.sorted = FALSE;
 			  $$.exclude_name_list = NULL;
+			  $$.wildcard_p = wildcardp($1);
 			}
 	| 	EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name
 			{
 			  $$.name = $5;
 			  $$.sorted = FALSE;
 			  $$.exclude_name_list = $3;
+			  $$.wildcard_p = wildcardp($5);
 			}
 	|	SORT '(' wildcard_name ')'
 			{
 			  $$.name = $3;
 			  $$.sorted = TRUE;
 			  $$.exclude_name_list = NULL;
+			  $$.wildcard_p = wildcardp($3);
 			}
 	|	SORT '(' EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name ')'
 			{
 			  $$.name = $7;
 			  $$.sorted = TRUE;
 			  $$.exclude_name_list = $5;
+			  $$.wildcard_p = wildcardp($7);
 			}
 	;

@@ -479,6 +483,7 @@ input_section_spec_no_keep:
 			  tmp.name = $1;
 			  tmp.exclude_name_list = NULL;
 			  tmp.sorted = FALSE;
+			  tmp.wildcard_p = wildcardp($1);
 			  lang_add_wild (&tmp, NULL, ldgram_had_keep);
 			}
         |	'[' file_NAME_list ']'
Index: ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.117
diff -u -p -r1.117 ldlang.c
--- ldlang.c	27 Jul 2003 11:58:28 -0000	1.117
+++ ldlang.c	10 Sep 2003 14:28:00 -0000
@@ -63,7 +63,6 @@ static struct lang_phdr *lang_phdr_list;

 /* Forward declarations.  */
 static void exp_init_os (etree_type *);
-static bfd_boolean wildcardp (const char *);
 static lang_input_statement_type *lookup_name (const char *);
 static bfd_boolean load_symbols (lang_input_statement_type *,
 				 lang_statement_list_type *);
@@ -191,7 +190,7 @@ walk_wild_section (lang_wild_statement_t
 	    {
 	      const char *sname = bfd_get_section_name (file->the_bfd, s);

-	      if (wildcardp (sec->spec.name))
+	      if (sec->spec.wildcard_p)
 		skip = fnmatch (sec->spec.name, sname, 0) != 0;
 	      else
 		skip = strcmp (sec->spec.name, sname) != 0;
@@ -954,7 +953,7 @@ already_linked_table_free (void)
    be enough to cause the pattern to be treated as a wildcard.
    That lets us handle DOS filenames more naturally.  */

-static bfd_boolean
+bfd_boolean
 wildcardp (const char *pattern)
 {
   const char *s;
@@ -4183,8 +4182,11 @@ lang_add_wild (struct wildcard_spec *fil
   if (filespec != NULL && filespec->name != NULL)
     {
       if (strcmp (filespec->name, "*") == 0)
-	filespec->name = NULL;
-      else if (! wildcardp (filespec->name))
+	{
+	  filespec->wildcard_p = FALSE;
+	  filespec->name = NULL;
+	}
+      else if (!filespec->wildcard_p)
 	lang_has_input_file = TRUE;
     }

Index: ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.29
diff -u -p -r1.29 ldlang.h
--- ldlang.h	27 Jul 2003 11:58:28 -0000	1.29
+++ ldlang.h	10 Sep 2003 14:28:00 -0000
@@ -407,6 +407,8 @@ extern void lang_add_target
   (const char *);
 extern void lang_add_wild
   (struct wildcard_spec *, struct wildcard_list *, bfd_boolean);
+extern bfd_boolean wildcardp
+  (const char *);
 extern void lang_add_map
   (const char *);
 extern void lang_add_fill
Index: mri.c
===================================================================
RCS file: /cvs/src/src/ld/mri.c,v
retrieving revision 1.13
diff -u -p -r1.13 mri.c
--- mri.c	28 Jun 2003 05:28:54 -0000	1.13
+++ mri.c	10 Sep 2003 14:28:00 -0000
@@ -227,6 +227,7 @@ mri_draw_tree (void)
 	  tmp->spec.name = p->name;
 	  tmp->spec.exclude_name_list = NULL;
 	  tmp->spec.sorted = FALSE;
+	  tmp->spec.wildcard_p = wildcardp (p->name);
 	  lang_add_wild (NULL, tmp, FALSE);

 	  /* If there is an alias for this section, add it too.  */
@@ -238,6 +239,7 @@ mri_draw_tree (void)
 		tmp->spec.name = aptr->name;
 		tmp->spec.exclude_name_list = NULL;
 		tmp->spec.sorted = FALSE;
+		tmp->spec.wildcard_p = wildcardp (aptr->name);
 		lang_add_wild (NULL, tmp, FALSE);
 	      }



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