dwarf2 directory table fix and improvement
Ulrich Drepper
drepper@redhat.com
Wed Jan 24 15:05:00 GMT 2001
The following patch fixes a problem in the dwarf2 directory table
generation reported by Mark Kettenis and it improves the table
generation a bit in that it generates possible candidates
artificially. This happens without changing the asymptotic runtime.
I initially thought this wasn't doable so I left it out. OK to install?
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/dwarf2out.c,v
retrieving revision 1.233
diff -u -u -r1.233 dwarf2out.c
--- dwarf2out.c 2001/01/19 17:11:15 1.233
+++ dwarf2out.c 2001/01/23 17:39:07
@@ -6499,6 +6499,33 @@
}
}
+/* Compute the maximum prefix of P2 appearing also in P1. Entire
+ directory names must match. */
+static int prefix_of PARAMS ((struct dir_info *, struct dir_info *));
+static int
+prefix_of (p1, p2)
+ struct dir_info *p1;
+ struct dir_info *p2;
+{
+ char *s1 = p1->path;
+ char *s2 = p2->path;
+ int len = p1->length < p2->length ? p1->length : p2->length;
+
+ while (*s1 == *s2 && s1 < p1->path + len)
+ ++s1, ++s2;
+
+ if (*s1 == '/' && *s2 == '/')
+ /* The whole of P1 is the prefix. */
+ return p1->length;
+
+ /* Go back to the last directory component. */
+ while (s1 > p1->path)
+ if (*--s1 == '/')
+ return s1 - p1->path + 1;
+
+ return 0;
+}
+
/* Output the directory table and the file name table. We try to minimize
the total amount of memory needed. A heuristic is used to avoid large
slowdowns with many input files. */
@@ -6518,7 +6545,7 @@
/* Allocate the various arrays we need. */
files = (struct file_info *) alloca (line_file_table.in_use
* sizeof (struct file_info));
- dirs = (struct dir_info *) alloca (line_file_table.in_use
+ dirs = (struct dir_info *) alloca (line_file_table.in_use * 2
* sizeof (struct dir_info));
/* Sort the file names. */
@@ -6567,6 +6594,8 @@
else
{
int j;
+ int max_idx;
+ int max_len;
/* This is a new directory. */
dirs[ndirs].path = files[i].path;
@@ -6578,13 +6607,47 @@
files[i].dir_idx = ndirs;
/* Search for a prefix. */
- dirs[ndirs].prefix = -1;
+ max_len = 0;
+ max_idx = 0;
for (j = 0; j < ndirs; ++j)
- if (dirs[j].length < dirs[ndirs].length
- && dirs[j].length != 0
- && memcmp (dirs[j].path, dirs[ndirs].path, dirs[j].length) == 0)
- dirs[ndirs].prefix = j;
+ if (dirs[j].length > max_len)
+ {
+ int this_len = prefix_of (&dirs[j], &dirs[ndirs]);
+
+ if (this_len > max_len)
+ {
+ max_len = this_len;
+ max_idx = j;
+ }
+ }
+
+ /* Remember the prefix. If this is a known prefix simply
+ remember the index. Otherwise we will have to create an
+ artificial entry. */
+ if (max_len == dirs[max_idx].length)
+ /* This is our prefix. */
+ dirs[ndirs].prefix = max_idx;
+ else if (max_len > 0)
+ {
+ /* Create an entry without associated file. Since we have
+ to keep the dirs array sorted (means, entries with paths
+ which come first) we have to move the new entry in the
+ place of the old one. */
+ dirs[++ndirs] = dirs[max_idx];
+
+ /* We don't have to set .path. */
+ dirs[max_idx].length = max_len;
+ dirs[max_idx].nbytes = 0;
+ dirs[max_idx].count = 0;
+ dirs[max_idx].dir_idx = ndirs;
+ dirs[max_idx].used = 0;
+ dirs[max_idx].prefix = dirs[ndirs].prefix;
+ dirs[ndirs - 1].prefix = dirs[ndirs].prefix = max_idx;
+ }
+ else
+ dirs[ndirs].prefix = -1;
+
++ndirs;
}
@@ -6671,7 +6734,7 @@
confuse these indices with the one for the constructed table
(even though most of the time they are identical). */
idx = 1;
- idx_offset = dirs[0].path[0] == '/' ? 1 : 0;
+ idx_offset = dirs[0].length > 0 ? 1 : 0;
for (i = 1 - idx_offset; i < ndirs; ++i)
if (dirs[i].used != 0)
{
--
---------------. ,-. 1325 Chesapeake Terrace
Ulrich Drepper \ ,-------------------' \ Sunnyvale, CA 94089 USA
Red Hat `--' drepper at redhat.com `------------------------
More information about the Gcc-patches
mailing list