Hi. As seen in r265663 having htab_hash_string accepting const char * would report a compilation error. The void * argument is needed for old C-style htab used in libiberty. I'm suggesting to come up with htab_hash_string_vptr and change signature of the old one (htab_hash_string). And putting these into hashtab.h will make it inlinable in C++-style hash table.
Patch survives regression tests on ppc64le-linux-gnu. Total cc1 change with the patch: +0.0% +2.09Ki Hope it's acceptable. Thanks, Martin gcc/ChangeLog: 2018-10-31 Martin Liska <mli...@suse.cz> * gengtype-state.c (read_state): Use newly added htab_hash_string_vptr. * gensupport.c (gen_mnemonic_attr): Likewise. (check_define_attr_duplicates): Likewise. * godump.c (go_finish): Likewise. include/ChangeLog: 2018-10-31 Martin Liska <mli...@suse.cz> * hashtab.h (htab_hash_string): Change signature to const char * and make it static inline. (htab_hash_string_vptr): Likewise. libcpp/ChangeLog: 2018-10-31 Martin Liska <mli...@suse.cz> * files.c (_cpp_init_files): Use htab_hash_string_vptr. libiberty/ChangeLog: 2018-10-31 Martin Liska <mli...@suse.cz> * hashtab.c: (htab_hash_string): Move to header file. --- gcc/gengtype-state.c | 2 +- gcc/gensupport.c | 4 ++-- gcc/godump.c | 6 +++--- include/hashtab.h | 47 ++++++++++++++++++++++++++++++++++++++++++-- libcpp/files.c | 2 +- libiberty/hashtab.c | 38 ----------------------------------- 6 files changed, 52 insertions(+), 47 deletions(-)
diff --git a/gcc/gengtype-state.c b/gcc/gengtype-state.c index 6a3b981eedc..facff4a29d7 100644 --- a/gcc/gengtype-state.c +++ b/gcc/gengtype-state.c @@ -2588,7 +2588,7 @@ read_state (const char *path) state_seen_types = htab_create (2017, hash_type_number, equals_type_number, NULL); state_ident_tab = - htab_create (4027, htab_hash_string, string_eq, NULL); + htab_create (4027, htab_hash_string_vptr, string_eq, NULL); read_state_version (version_string); read_state_srcdir (); read_state_languages (); diff --git a/gcc/gensupport.c b/gcc/gensupport.c index 1d76af7ce5c..2f865d918f3 100644 --- a/gcc/gensupport.c +++ b/gcc/gensupport.c @@ -2434,7 +2434,7 @@ gen_mnemonic_attr (void) if (!mnemonic_attr) return; - mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string, + mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string_vptr, htab_eq_string, 0, xcalloc, free); for (elem = define_insn_queue; elem; elem = elem->next) @@ -2492,7 +2492,7 @@ check_define_attr_duplicates () char * attr_name; void **slot; - attr_htab = htab_create (500, htab_hash_string, htab_eq_string, NULL); + attr_htab = htab_create (500, htab_hash_string_vptr, htab_eq_string, NULL); for (elem = define_attr_queue; elem; elem = elem->next) { diff --git a/gcc/godump.c b/gcc/godump.c index baf21e27eec..7098ac80a91 100644 --- a/gcc/godump.c +++ b/gcc/godump.c @@ -1377,11 +1377,11 @@ go_finish (const char *filename) real_debug_hooks->finish (filename); - container.type_hash = htab_create (100, htab_hash_string, + container.type_hash = htab_create (100, htab_hash_string_vptr, string_hash_eq, NULL); - container.invalid_hash = htab_create (10, htab_hash_string, + container.invalid_hash = htab_create (10, htab_hash_string_vptr, string_hash_eq, NULL); - container.keyword_hash = htab_create (50, htab_hash_string, + container.keyword_hash = htab_create (50, htab_hash_string_vptr, string_hash_eq, NULL); obstack_init (&container.type_obstack); diff --git a/include/hashtab.h b/include/hashtab.h index 531eb101ff7..44bce8c2a6b 100644 --- a/include/hashtab.h +++ b/include/hashtab.h @@ -189,8 +189,51 @@ extern htab_hash htab_hash_pointer; /* An equality function for pointers. */ extern htab_eq htab_eq_pointer; -/* A hash function for null-terminated strings. */ -extern hashval_t htab_hash_string (const void *); +/* Hash STR as a null-terminated string. + + Copied from gcc/hashtable.c. Zack had the following to say with respect + to applicability, though note that unlike hashtable.c, this hash table + implementation re-hashes rather than chain buckets. + + http://gcc.gnu.org/ml/gcc-patches/2001-08/msg01021.html + From: Zack Weinberg <za...@panix.com> + Date: Fri, 17 Aug 2001 02:15:56 -0400 + + I got it by extracting all the identifiers from all the source code + I had lying around in mid-1999, and testing many recurrences of + the form "H_n = H_{n-1} * K + c_n * L + M" where K, L, M were either + prime numbers or the appropriate identity. This was the best one. + I don't remember exactly what constituted "best", except I was + looking at bucket-length distributions mostly. + + So it should be very good at hashing identifiers, but might not be + as good at arbitrary strings. + + I'll add that it thoroughly trounces the hash functions recommended + for this use at http://burtleburtle.net/bob/hash/index.html, both + on speed and bucket distribution. I haven't tried it against the + function they just started using for Perl's hashes. */ + +static inline hashval_t +htab_hash_string (const char *str) +{ + hashval_t r = 0; + unsigned char c; + + while ((c = *str++) != 0) + r = r * 67 + c - 113; + + return r; +} + +/* Hash P as a null-terminated string. */ + +static inline hashval_t +htab_hash_string_vptr (const PTR p) +{ + return htab_hash_string ((const char *)p); +} + /* An iterative hash function for arbitrary data. */ extern hashval_t iterative_hash (const void *, size_t, hashval_t); diff --git a/libcpp/files.c b/libcpp/files.c index 08b7c647c91..e4eb34e7d55 100644 --- a/libcpp/files.c +++ b/libcpp/files.c @@ -1311,7 +1311,7 @@ _cpp_init_files (cpp_reader *pfile) pfile->dir_hash = htab_create_alloc (127, file_hash_hash, file_hash_eq, NULL, xcalloc, free); allocate_file_hash_entries (pfile); - pfile->nonexistent_file_hash = htab_create_alloc (127, htab_hash_string, + pfile->nonexistent_file_hash = htab_create_alloc (127, htab_hash_string_vptr, nonexistent_file_hash_eq, NULL, xcalloc, free); obstack_specify_allocation (&pfile->nonexistent_file_ob, 0, 0, diff --git a/libiberty/hashtab.c b/libiberty/hashtab.c index ca392647d4a..b6821502d15 100644 --- a/libiberty/hashtab.c +++ b/libiberty/hashtab.c @@ -803,44 +803,6 @@ htab_collisions (htab_t htab) return (double) htab->collisions / (double) htab->searches; } -/* Hash P as a null-terminated string. - - Copied from gcc/hashtable.c. Zack had the following to say with respect - to applicability, though note that unlike hashtable.c, this hash table - implementation re-hashes rather than chain buckets. - - http://gcc.gnu.org/ml/gcc-patches/2001-08/msg01021.html - From: Zack Weinberg <za...@panix.com> - Date: Fri, 17 Aug 2001 02:15:56 -0400 - - I got it by extracting all the identifiers from all the source code - I had lying around in mid-1999, and testing many recurrences of - the form "H_n = H_{n-1} * K + c_n * L + M" where K, L, M were either - prime numbers or the appropriate identity. This was the best one. - I don't remember exactly what constituted "best", except I was - looking at bucket-length distributions mostly. - - So it should be very good at hashing identifiers, but might not be - as good at arbitrary strings. - - I'll add that it thoroughly trounces the hash functions recommended - for this use at http://burtleburtle.net/bob/hash/index.html, both - on speed and bucket distribution. I haven't tried it against the - function they just started using for Perl's hashes. */ - -hashval_t -htab_hash_string (const PTR p) -{ - const unsigned char *str = (const unsigned char *) p; - hashval_t r = 0; - unsigned char c; - - while ((c = *str++) != 0) - r = r * 67 + c - 113; - - return r; -} - /* DERIVED FROM: -------------------------------------------------------------------- lookup2.c, by Bob Jenkins, December 1996, Public Domain.