From a87ec9e6555785cfc21dfbf8078fa0728f4a0030 Mon Sep 17 00:00:00 2001 From: Mark Mitchell Date: Tue, 17 Nov 1998 11:50:24 +0000 Subject: [PATCH] hash.h (hash_table_key): New type. * hash.h (hash_table_key): New type. (hash_entry): Change `string' field to generic `key'. (hash_table): Add `comp' and `hash' functions. (hash_table_init): Take them as input. (hash_table_init_n): Likewise. (hash_lookup): Modify for generic keys. (hash_newfunc): Likewise. (hash_traverse): Likewise. (string_hash): New function. (string_compare): Likewise. (string_copy): Likewise. * hash.c (hash_table_init_n): Modify for generic keys. (hash_table_init): Likewise. (hash_lookup): Likewise. (hash_newfunc): Likewise. (hash_traverse): Likewise. (string_hash): Split out from hash_lookup. (string_compare): New function. (string_copy): Split out from hash_lookup. * tlink.c (symbol_hash_newfunc): Modify for new interfaces to hash tables. (symbol_hash_lookup): Likewise. (file_hash_newfunc): Likewise. (file_hash_lookup): Likewise. (demangled_hash_newfunc): Likewise. (demangled_hash_lookup): Likewise. (tlink_int): Likewise. (read_repo_file): Likewise. (recompile_files): Likewise. (demangle_new_symbols): Likewise. (scan_linker_output): Likewise. From-SVN: r23683 --- gcc/ChangeLog | 34 +++++++++++++ gcc/hash.c | 129 +++++++++++++++++++++++++++++++++----------------- gcc/hash.h | 52 ++++++++++++++------ gcc/tlink.c | 45 +++++++++++------- 4 files changed, 185 insertions(+), 75 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 521f3e842a6..42e8abd6a2d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,37 @@ +Tue Nov 17 11:51:16 1998 Mark Mitchell + + * hash.h (hash_table_key): New type. + (hash_entry): Change `string' field to generic `key'. + (hash_table): Add `comp' and `hash' functions. + (hash_table_init): Take them as input. + (hash_table_init_n): Likewise. + (hash_lookup): Modify for generic keys. + (hash_newfunc): Likewise. + (hash_traverse): Likewise. + (string_hash): New function. + (string_compare): Likewise. + (string_copy): Likewise. + * hash.c (hash_table_init_n): Modify for generic keys. + (hash_table_init): Likewise. + (hash_lookup): Likewise. + (hash_newfunc): Likewise. + (hash_traverse): Likewise. + (string_hash): Split out from hash_lookup. + (string_compare): New function. + (string_copy): Split out from hash_lookup. + * tlink.c (symbol_hash_newfunc): Modify for new interfaces to hash + tables. + (symbol_hash_lookup): Likewise. + (file_hash_newfunc): Likewise. + (file_hash_lookup): Likewise. + (demangled_hash_newfunc): Likewise. + (demangled_hash_lookup): Likewise. + (tlink_int): Likewise. + (read_repo_file): Likewise. + (recompile_files): Likewise. + (demangle_new_symbols): Likewise. + (scan_linker_output): Likewise. + Tue Nov 17 17:13:53 1998 J"orn Rennecke * flow.c (insn_dead_p): New argument NOTES. Changed all callers. diff --git a/gcc/hash.c b/gcc/hash.c index f367fc07314..473d0ffbd93 100644 --- a/gcc/hash.c +++ b/gcc/hash.c @@ -36,11 +36,13 @@ extern char * xmalloc (); /* Create a new hash table, given a number of entries. */ boolean -hash_table_init_n (table, newfunc, size) +hash_table_init_n (table, newfunc, hash, comp, size) struct hash_table *table; struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *, - struct hash_table *, - const char *)); + struct hash_table *, + hash_table_key)); + unsigned long (*hash) (hash_table_key); + boolean (*comp) (hash_table_key, hash_table_key); unsigned int size; { unsigned int alloc; @@ -61,19 +63,23 @@ hash_table_init_n (table, newfunc, size) memset ((PTR) table->table, 0, alloc); table->size = size; table->newfunc = newfunc; + table->hash = hash; + table->comp = comp; return true; } /* Create a new hash table with the default number of entries. */ boolean -hash_table_init (table, newfunc) +hash_table_init (table, newfunc, hash, comp) struct hash_table *table; struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *, - struct hash_table *, - const char *)); + struct hash_table *, + hash_table_key)); + unsigned long (*hash) PARAMS ((hash_table_key)); + boolean (*comp) PARAMS ((hash_table_key, hash_table_key)); { - return hash_table_init_n (table, newfunc, DEFAULT_SIZE); + return hash_table_init_n (table, newfunc, hash, comp, DEFAULT_SIZE); } /* Free a hash table. */ @@ -85,33 +91,22 @@ hash_table_free (table) obstack_free (&table->memory, (PTR) NULL); } -/* Look up a string in a hash table. */ +/* Look up KEY in TABLE. If CREATE is non-NULL a new entry is + created if one does not previously exist. */ struct hash_entry * -hash_lookup (table, string, create, copy) +hash_lookup (table, key, create, copy) struct hash_table *table; - const char *string; + hash_table_key key; boolean create; - boolean copy; + hash_table_key (*copy) PARAMS ((struct obstack* memory, + hash_table_key key)); { - register const unsigned char *s; register unsigned long hash; - register unsigned int c; struct hash_entry *hashp; - unsigned int len; unsigned int index; - hash = 0; - len = 0; - s = (const unsigned char *) string; - while ((c = *s++) != '\0') - { - hash += c + (c << 17); - hash ^= hash >> 2; - ++len; - } - hash += len + (len << 17); - hash ^= hash >> 2; + hash = (*table->hash)(key); index = hash % table->size; for (hashp = table->table[index]; @@ -119,30 +114,19 @@ hash_lookup (table, string, create, copy) hashp = hashp->next) { if (hashp->hash == hash - && strcmp (hashp->string, string) == 0) + && (*table->comp)(hashp->key, key)) return hashp; } if (! create) return (struct hash_entry *) NULL; - hashp = (*table->newfunc) ((struct hash_entry *) NULL, table, string); + hashp = (*table->newfunc) ((struct hash_entry *) NULL, table, key); if (hashp == (struct hash_entry *) NULL) return (struct hash_entry *) NULL; if (copy) - { - char *new; - - new = (char *) obstack_alloc (&table->memory, len + 1); - if (!new) - { - error ("no memory"); - return (struct hash_entry *) NULL; - } - strcpy (new, string); - string = new; - } - hashp->string = string; + key = (*copy) (&table->memory, key); + hashp->key = key; hashp->hash = hash; hashp->next = table->table[index]; table->table[index] = hashp; @@ -154,10 +138,10 @@ hash_lookup (table, string, create, copy) /*ARGSUSED*/ struct hash_entry * -hash_newfunc (entry, table, string) +hash_newfunc (entry, table, p) struct hash_entry *entry; struct hash_table *table; - const char *string; + hash_table_key p; { if (entry == (struct hash_entry *) NULL) entry = ((struct hash_entry *) @@ -185,7 +169,7 @@ hash_allocate (table, size) void hash_traverse (table, func, info) struct hash_table *table; - boolean (*func) PARAMS ((struct hash_entry *, PTR)); + boolean (*func) PARAMS ((struct hash_entry *, hash_table_key)); PTR info; { unsigned int i; @@ -201,3 +185,62 @@ hash_traverse (table, func, info) } } } + +/* Hash a string. Return a hash-code for the string. */ + +unsigned long +string_hash (k) + hash_table_key k; +{ + const unsigned char *s; + unsigned long hash; + unsigned char c; + unsigned int len; + + s = (const unsigned char *) k; + hash = 0; + len = 0; + + while ((c = *s++) != '\0') + { + hash += c + (c << 17); + hash ^= hash >> 2; + ++len; + } + hash += len + (len << 17); + hash ^= hash >> 2; + + return hash; +} + +/* Compare two strings. Return non-zero iff the two strings are + the same. */ + +boolean +string_compare (k1, k2) + hash_table_key k1; + hash_table_key k2; +{ + return (strcmp ((char*) k1, (char*) k2) == 0); +} + +/* Copy K to OBSTACK. */ + +hash_table_key +string_copy (memory, k) + struct obstack* memory; + hash_table_key k; +{ + char *new; + char *string = (char*) k; + + new = (char *) obstack_alloc (memory, strlen (string) + 1); + if (!new) + { + error ("no memory"); + return NULL; + } + strcpy (new, string); + + return new; +} diff --git a/gcc/hash.h b/gcc/hash.h index 5733daadab4..bf64af789df 100644 --- a/gcc/hash.h +++ b/gcc/hash.h @@ -26,6 +26,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ typedef enum {false, true} boolean; +typedef PTR hash_table_key; + /* Hash table routines. There is no way to free up a hash table. */ /* An element in the hash table. Most uses will actually use a larger @@ -35,8 +37,8 @@ struct hash_entry { /* Next entry for this hash code. */ struct hash_entry *next; - /* String being hashed. */ - const char *string; + /* The thing being hashed. */ + hash_table_key key; /* Hash code. This is the full hash code, not the index into the table. */ unsigned long hash; @@ -59,7 +61,11 @@ struct hash_table only if the argument is NULL. */ struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *, struct hash_table *, - const char *)); + hash_table_key)); + /* A function to compute the hash code for a key in the hash table. */ + unsigned long (*hash) PARAMS ((hash_table_key)); + /* A function to compare two keys. */ + boolean (*comp) PARAMS ((hash_table_key, hash_table_key)); /* An obstack for this hash table. */ struct obstack memory; }; @@ -69,31 +75,35 @@ extern boolean hash_table_init PARAMS ((struct hash_table *, struct hash_entry *(*) (struct hash_entry *, struct hash_table *, - const char *))); + hash_table_key), + unsigned long (*hash) (hash_table_key), + boolean (*comp) (hash_table_key, hash_table_key))); /* Initialize a hash table specifying a size. */ extern boolean hash_table_init_n PARAMS ((struct hash_table *, struct hash_entry *(*) (struct hash_entry *, struct hash_table *, - const char *), + hash_table_key), + unsigned long (*hash) (hash_table_key), + boolean (*comp) (hash_table_key, hash_table_key), unsigned int size)); /* Free up a hash table. */ extern void hash_table_free PARAMS ((struct hash_table *)); -/* Look up a string in a hash table. If CREATE is true, a new entry - will be created for this string if one does not already exist. The - COPY argument must be true if this routine should copy the string - into newly allocated memory when adding an entry. */ +/* Look up KEY in a hash table. If CREATE is true, a new entry + will be created for this KEY if one does not already exist. If + COPY is non-NULL, it is used to copy the KEY before storing it in + the hash table. */ extern struct hash_entry *hash_lookup - PARAMS ((struct hash_table *, const char *, boolean create, - boolean copy)); + PARAMS ((struct hash_table *, hash_table_key key, boolean create, + hash_table_key (*copy)(struct obstack*, hash_table_key))); /* Base method for creating a hash table entry. */ extern struct hash_entry *hash_newfunc - PARAMS ((struct hash_entry *, struct hash_table *, - const char *)); + PARAMS ((struct hash_entry *, struct hash_table *, + hash_table_key key)); /* Grab some space for a hash table entry. */ extern PTR hash_allocate PARAMS ((struct hash_table *, @@ -104,5 +114,17 @@ extern PTR hash_allocate PARAMS ((struct hash_table *, INFO argument is passed to the function. */ extern void hash_traverse PARAMS ((struct hash_table *, boolean (*) (struct hash_entry *, - PTR), - PTR info)); + hash_table_key), + hash_table_key info)); + +/* Hash a string K, which is really of type `char*'. */ +extern unsigned long string_hash PARAMS ((hash_table_key k)); + +/* Compare two strings K1, K2 which are really of type `char*'. */ +extern boolean string_compare PARAMS ((hash_table_key k1, + hash_table_key k2)); + +/* Copy a string K, which is really of type `char*'. */ +extern hash_table_key string_copy PARAMS ((struct obstack* memory, + hash_table_key k)); + diff --git a/gcc/tlink.c b/gcc/tlink.c index 0ec3f9a1064..ec308c045f2 100644 --- a/gcc/tlink.c +++ b/gcc/tlink.c @@ -90,7 +90,8 @@ symbol_hash_newfunc (entry, table, string) return NULL; } ret = ((struct symbol_hash_entry *) - hash_newfunc ((struct hash_entry *) ret, table, string)); + hash_newfunc ((struct hash_entry *) ret, table, + (hash_table_key) string)); ret->file = NULL; ret->chosen = 0; ret->tweaking = 0; @@ -104,7 +105,8 @@ symbol_hash_lookup (string, create) boolean create; { return ((struct symbol_hash_entry *) - hash_lookup (&symbol_table, string, create, true)); + hash_lookup (&symbol_table, (hash_table_key) string, + create, &string_copy)); } static struct hash_table file_table; @@ -124,7 +126,8 @@ file_hash_newfunc (entry, table, string) return NULL; } ret = ((struct file_hash_entry *) - hash_newfunc ((struct hash_entry *) ret, table, string)); + hash_newfunc ((struct hash_entry *) ret, table, + (hash_table_key) string)); ret->args = NULL; ret->dir = NULL; ret->main = NULL; @@ -137,7 +140,8 @@ file_hash_lookup (string) const char *string; { return ((struct file_hash_entry *) - hash_lookup (&file_table, string, true, true)); + hash_lookup (&file_table, (hash_table_key) string, true, + &string_copy)); } static struct hash_table demangled_table; @@ -157,7 +161,8 @@ demangled_hash_newfunc (entry, table, string) return NULL; } ret = ((struct demangled_hash_entry *) - hash_newfunc ((struct hash_entry *) ret, table, string)); + hash_newfunc ((struct hash_entry *) ret, table, + (hash_table_key) string)); ret->mangled = NULL; return (struct hash_entry *) ret; } @@ -168,7 +173,8 @@ demangled_hash_lookup (string, create) boolean create; { return ((struct demangled_hash_entry *) - hash_lookup (&demangled_table, string, create, true)); + hash_lookup (&demangled_table, (hash_table_key) string, + create, &string_copy)); } /* Stack code. */ @@ -251,9 +257,12 @@ tlink_init () { char *p; - hash_table_init (&symbol_table, symbol_hash_newfunc); - hash_table_init (&file_table, file_hash_newfunc); - hash_table_init (&demangled_table, demangled_hash_newfunc); + hash_table_init (&symbol_table, symbol_hash_newfunc, &string_hash, + &string_compare); + hash_table_init (&file_table, file_hash_newfunc, &string_hash, + &string_compare); + hash_table_init (&demangled_table, demangled_hash_newfunc, + &string_hash, &string_compare); obstack_begin (&symbol_stack_obstack, 0); obstack_begin (&file_stack_obstack, 0); @@ -367,10 +376,11 @@ read_repo_file (f) file *f; { char c; - FILE *stream = fopen (f->root.string, "r"); + FILE *stream = fopen ((char*) f->root.key, "r"); if (tlink_verbose >= 2) - fprintf (stderr, "collect: reading %s\n", f->root.string); + fprintf (stderr, "collect: reading %s\n", + (char*) f->root.key); while (fscanf (stream, "%c ", &c) == 1) { @@ -432,8 +442,8 @@ recompile_files () while ((f = file_pop ()) != NULL) { char *line, *command; - FILE *stream = fopen (f->root.string, "r"); - char *outname = frob_extension (f->root.string, ".rnw"); + FILE *stream = fopen ((char*) f->root.key, "r"); + char *outname = frob_extension ((char*) f->root.key, ".rnw"); FILE *output = fopen (outname, "w"); while ((line = tfgets (stream)) != NULL) @@ -448,7 +458,7 @@ recompile_files () } fclose (stream); fclose (output); - rename (outname, f->root.string); + rename (outname, (char*) f->root.key); obstack_grow (&temporary_obstack, "cd ", 3); obstack_grow (&temporary_obstack, f->dir, strlen (f->dir)); @@ -507,13 +517,14 @@ demangle_new_symbols () while ((sym = symbol_pop ()) != NULL) { demangled *dem; - char *p = cplus_demangle (sym->root.string, DMGL_PARAMS | DMGL_ANSI); + char *p = cplus_demangle ((char*) sym->root.key, + DMGL_PARAMS | DMGL_ANSI); if (! p) continue; dem = demangled_hash_lookup (p, true); - dem->mangled = sym->root.string; + dem->mangled = (char*) sym->root.key; } } @@ -584,7 +595,7 @@ scan_linker_output (fname) { if (tlink_verbose >= 2) fprintf (stderr, "collect: tweaking %s in %s\n", - sym->root.string, sym->file->root.string); + (char*) sym->root.key, (char*) sym->file->root.key); sym->tweaking = 1; file_push (sym->file); }