This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
[patch] ld speedup 2/3 (wildcardp call reduction)
- From: Michael Matz <matz at suse dot de>
- To: binutils at sources dot redhat dot com
- Cc: Lars Knoll <lars at trolltech dot com>
- Date: Wed, 10 Sep 2003 16:32:01 +0200 (CEST)
- Subject: [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);
}