| /* An expandable hash tables datatype. | 
 |    Copyright (C) 1999-2020 Free Software Foundation, Inc. | 
 |    Contributed by Vladimir Makarov <vmakarov@cygnus.com>. | 
 |  | 
 |    This file is part of the GNU Offloading and Multi Processing Library | 
 |    (libgomp). | 
 |  | 
 |    Libgomp is free software; you can redistribute it and/or modify it | 
 |    under the terms of the GNU General Public License as published by | 
 |    the Free Software Foundation; either version 3, or (at your option) | 
 |    any later version. | 
 |  | 
 |    Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY | 
 |    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | 
 |    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | 
 |    more details. | 
 |  | 
 |    Under Section 7 of GPL version 3, you are granted additional | 
 |    permissions described in the GCC Runtime Library Exception, version | 
 |    3.1, as published by the Free Software Foundation. | 
 |  | 
 |    You should have received a copy of the GNU General Public License and | 
 |    a copy of the GCC Runtime Library Exception along with this program; | 
 |    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see | 
 |    <http://www.gnu.org/licenses/>.  */ | 
 |  | 
 | /* The hash table code copied from include/hashtab.[hc] and adjusted, | 
 |    so that the hash table entries are in the flexible array at the end | 
 |    of the control structure, no callbacks are used and the elements in the | 
 |    table are of the hash_entry_type type. | 
 |    Before including this file, define hash_entry_type type and | 
 |    htab_alloc and htab_free functions.  After including it, define | 
 |    htab_hash and htab_eq inline functions.   */ | 
 |  | 
 | /* This package implements basic hash table functionality.  It is possible | 
 |    to search for an entry, create an entry and destroy an entry. | 
 |  | 
 |    Elements in the table are generic pointers. | 
 |  | 
 |    The size of the table is not fixed; if the occupancy of the table | 
 |    grows too high the hash table will be expanded. | 
 |  | 
 |    The abstract data implementation is based on generalized Algorithm D | 
 |    from Knuth's book "The art of computer programming".  Hash table is | 
 |    expanded by creation of new hash table and transferring elements from | 
 |    the old table to the new table.  */ | 
 |  | 
 | /* The type for a hash code.  */ | 
 | typedef unsigned int hashval_t; | 
 |  | 
 | static inline hashval_t htab_hash (hash_entry_type); | 
 | static inline bool htab_eq (hash_entry_type, hash_entry_type); | 
 |  | 
 | /* This macro defines reserved value for empty table entry.  */ | 
 |  | 
 | #define HTAB_EMPTY_ENTRY    ((hash_entry_type) 0) | 
 |  | 
 | /* This macro defines reserved value for table entry which contained | 
 |    a deleted element. */ | 
 |  | 
 | #define HTAB_DELETED_ENTRY  ((hash_entry_type) 1) | 
 |  | 
 | /* Hash tables are of the following type.  The structure | 
 |    (implementation) of this type is not needed for using the hash | 
 |    tables.  All work with hash table should be executed only through | 
 |    functions mentioned below.  The size of this structure is subject to | 
 |    change.  */ | 
 |  | 
 | struct htab { | 
 |   /* Current size (in entries) of the hash table.  */ | 
 |   size_t size; | 
 |  | 
 |   /* Current number of elements including also deleted elements.  */ | 
 |   size_t n_elements; | 
 |  | 
 |   /* Current number of deleted elements in the table.  */ | 
 |   size_t n_deleted; | 
 |  | 
 |   /* Current size (in entries) of the hash table, as an index into the | 
 |      table of primes.  */ | 
 |   unsigned int size_prime_index; | 
 |  | 
 |   /* Table itself.  */ | 
 |   hash_entry_type entries[]; | 
 | }; | 
 |  | 
 | typedef struct htab *htab_t; | 
 |  | 
 | /* An enum saying whether we insert into the hash table or not.  */ | 
 | enum insert_option {NO_INSERT, INSERT}; | 
 |  | 
 | /* Table of primes and multiplicative inverses. | 
 |  | 
 |    Note that these are not minimally reduced inverses.  Unlike when generating | 
 |    code to divide by a constant, we want to be able to use the same algorithm | 
 |    all the time.  All of these inverses (are implied to) have bit 32 set. | 
 |  | 
 |    For the record, the function that computed the table is in | 
 |    libiberty/hashtab.c.  */ | 
 |  | 
 | struct prime_ent | 
 | { | 
 |   hashval_t prime; | 
 |   hashval_t inv; | 
 |   hashval_t inv_m2;	/* inverse of prime-2 */ | 
 |   hashval_t shift; | 
 | }; | 
 |  | 
 | static struct prime_ent const prime_tab[] = { | 
 |   {          7, 0x24924925, 0x9999999b, 2 }, | 
 |   {         13, 0x3b13b13c, 0x745d1747, 3 }, | 
 |   {         31, 0x08421085, 0x1a7b9612, 4 }, | 
 |   {         61, 0x0c9714fc, 0x15b1e5f8, 5 }, | 
 |   {        127, 0x02040811, 0x0624dd30, 6 }, | 
 |   {        251, 0x05197f7e, 0x073260a5, 7 }, | 
 |   {        509, 0x01824366, 0x02864fc8, 8 }, | 
 |   {       1021, 0x00c0906d, 0x014191f7, 9 }, | 
 |   {       2039, 0x0121456f, 0x0161e69e, 10 }, | 
 |   {       4093, 0x00300902, 0x00501908, 11 }, | 
 |   {       8191, 0x00080041, 0x00180241, 12 }, | 
 |   {      16381, 0x000c0091, 0x00140191, 13 }, | 
 |   {      32749, 0x002605a5, 0x002a06e6, 14 }, | 
 |   {      65521, 0x000f00e2, 0x00110122, 15 }, | 
 |   {     131071, 0x00008001, 0x00018003, 16 }, | 
 |   {     262139, 0x00014002, 0x0001c004, 17 }, | 
 |   {     524287, 0x00002001, 0x00006001, 18 }, | 
 |   {    1048573, 0x00003001, 0x00005001, 19 }, | 
 |   {    2097143, 0x00004801, 0x00005801, 20 }, | 
 |   {    4194301, 0x00000c01, 0x00001401, 21 }, | 
 |   {    8388593, 0x00001e01, 0x00002201, 22 }, | 
 |   {   16777213, 0x00000301, 0x00000501, 23 }, | 
 |   {   33554393, 0x00001381, 0x00001481, 24 }, | 
 |   {   67108859, 0x00000141, 0x000001c1, 25 }, | 
 |   {  134217689, 0x000004e1, 0x00000521, 26 }, | 
 |   {  268435399, 0x00000391, 0x000003b1, 27 }, | 
 |   {  536870909, 0x00000019, 0x00000029, 28 }, | 
 |   { 1073741789, 0x0000008d, 0x00000095, 29 }, | 
 |   { 2147483647, 0x00000003, 0x00000007, 30 }, | 
 |   /* Avoid "decimal constant so large it is unsigned" for 4294967291.  */ | 
 |   { 0xfffffffb, 0x00000006, 0x00000008, 31 } | 
 | }; | 
 |  | 
 | /* The following function returns an index into the above table of the | 
 |    nearest prime number which is greater than N, and near a power of two. */ | 
 |  | 
 | static unsigned int | 
 | higher_prime_index (unsigned long n) | 
 | { | 
 |   unsigned int low = 0; | 
 |   unsigned int high = sizeof(prime_tab) / sizeof(prime_tab[0]); | 
 |  | 
 |   while (low != high) | 
 |     { | 
 |       unsigned int mid = low + (high - low) / 2; | 
 |       if (n > prime_tab[mid].prime) | 
 | 	low = mid + 1; | 
 |       else | 
 | 	high = mid; | 
 |     } | 
 |  | 
 |   /* If we've run out of primes, abort.  */ | 
 |   if (n > prime_tab[low].prime) | 
 |     abort (); | 
 |  | 
 |   return low; | 
 | } | 
 |  | 
 | /* Return the current size of given hash table.  */ | 
 |  | 
 | static inline size_t | 
 | htab_size (htab_t htab) | 
 | { | 
 |   return htab->size; | 
 | } | 
 |  | 
 | /* Return the current number of elements in given hash table. */ | 
 |  | 
 | static inline size_t | 
 | htab_elements (htab_t htab) | 
 | { | 
 |   return htab->n_elements - htab->n_deleted; | 
 | } | 
 |  | 
 | /* Return X % Y.  */ | 
 |  | 
 | static inline hashval_t | 
 | htab_mod_1 (hashval_t x, hashval_t y, hashval_t inv, int shift) | 
 | { | 
 |   /* The multiplicative inverses computed above are for 32-bit types, and | 
 |      requires that we be able to compute a highpart multiply.  */ | 
 |   if (sizeof (hashval_t) * __CHAR_BIT__ <= 32) | 
 |     { | 
 |       hashval_t t1, t2, t3, t4, q, r; | 
 |  | 
 |       t1 = ((unsigned long long)x * inv) >> 32; | 
 |       t2 = x - t1; | 
 |       t3 = t2 >> 1; | 
 |       t4 = t1 + t3; | 
 |       q  = t4 >> shift; | 
 |       r  = x - (q * y); | 
 |  | 
 |       return r; | 
 |     } | 
 |  | 
 |   /* Otherwise just use the native division routines.  */ | 
 |   return x % y; | 
 | } | 
 |  | 
 | /* Compute the primary hash for HASH given HTAB's current size.  */ | 
 |  | 
 | static inline hashval_t | 
 | htab_mod (hashval_t hash, htab_t htab) | 
 | { | 
 |   const struct prime_ent *p = &prime_tab[htab->size_prime_index]; | 
 |   return htab_mod_1 (hash, p->prime, p->inv, p->shift); | 
 | } | 
 |  | 
 | /* Compute the secondary hash for HASH given HTAB's current size.  */ | 
 |  | 
 | static inline hashval_t | 
 | htab_mod_m2 (hashval_t hash, htab_t htab) | 
 | { | 
 |   const struct prime_ent *p = &prime_tab[htab->size_prime_index]; | 
 |   return 1 + htab_mod_1 (hash, p->prime - 2, p->inv_m2, p->shift); | 
 | } | 
 |  | 
 | /* Create hash table of size SIZE.  */ | 
 |  | 
 | static htab_t | 
 | htab_create (size_t size) | 
 | { | 
 |   htab_t result; | 
 |   unsigned int size_prime_index; | 
 |  | 
 |   size_prime_index = higher_prime_index (size); | 
 |   size = prime_tab[size_prime_index].prime; | 
 |  | 
 |   result = (htab_t) htab_alloc (sizeof (struct htab) | 
 | 				+ size * sizeof (hash_entry_type)); | 
 |   result->size = size; | 
 |   result->n_elements = 0; | 
 |   result->n_deleted = 0; | 
 |   result->size_prime_index = size_prime_index; | 
 |   memset (result->entries, 0, size * sizeof (hash_entry_type)); | 
 |   return result; | 
 | } | 
 |  | 
 | /* Similar to htab_find_slot, but without several unwanted side effects: | 
 |     - Does not call htab_eq when it finds an existing entry. | 
 |     - Does not change the count of elements in the hash table. | 
 |    This function also assumes there are no deleted entries in the table. | 
 |    HASH is the hash value for the element to be inserted.  */ | 
 |  | 
 | static hash_entry_type * | 
 | find_empty_slot_for_expand (htab_t htab, hashval_t hash) | 
 | { | 
 |   hashval_t index = htab_mod (hash, htab); | 
 |   size_t size = htab_size (htab); | 
 |   hash_entry_type *slot = htab->entries + index; | 
 |   hashval_t hash2; | 
 |  | 
 |   if (*slot == HTAB_EMPTY_ENTRY) | 
 |     return slot; | 
 |   else if (*slot == HTAB_DELETED_ENTRY) | 
 |     abort (); | 
 |  | 
 |   hash2 = htab_mod_m2 (hash, htab); | 
 |   for (;;) | 
 |     { | 
 |       index += hash2; | 
 |       if (index >= size) | 
 | 	index -= size; | 
 |  | 
 |       slot = htab->entries + index; | 
 |       if (*slot == HTAB_EMPTY_ENTRY) | 
 | 	return slot; | 
 |       else if (*slot == HTAB_DELETED_ENTRY) | 
 | 	abort (); | 
 |     } | 
 | } | 
 |  | 
 | /* The following function changes size of memory allocated for the | 
 |    entries and repeatedly inserts the table elements.  The occupancy | 
 |    of the table after the call will be about 50%.  Naturally the hash | 
 |    table must already exist.  Remember also that the place of the | 
 |    table entries is changed.  */ | 
 |  | 
 | static htab_t | 
 | htab_expand (htab_t htab) | 
 | { | 
 |   htab_t nhtab; | 
 |   hash_entry_type *olimit; | 
 |   hash_entry_type *p; | 
 |   size_t osize, elts; | 
 |  | 
 |   osize = htab->size; | 
 |   olimit = htab->entries + osize; | 
 |   elts = htab_elements (htab); | 
 |  | 
 |   /* Resize only when table after removal of unused elements is either | 
 |      too full or too empty.  */ | 
 |   if (elts * 2 > osize || (elts * 8 < osize && osize > 32)) | 
 |     nhtab = htab_create (elts * 2); | 
 |   else | 
 |     nhtab = htab_create (osize - 1); | 
 |   nhtab->n_elements = htab->n_elements - htab->n_deleted; | 
 |  | 
 |   p = htab->entries; | 
 |   do | 
 |     { | 
 |       hash_entry_type x = *p; | 
 |  | 
 |       if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY) | 
 | 	*find_empty_slot_for_expand (nhtab, htab_hash (x)) = x; | 
 |  | 
 |       p++; | 
 |     } | 
 |   while (p < olimit); | 
 |  | 
 |   htab_free (htab); | 
 |   return nhtab; | 
 | } | 
 |  | 
 | /* This function searches for a hash table entry equal to the given | 
 |    element.  It cannot be used to insert or delete an element.  */ | 
 |  | 
 | static hash_entry_type | 
 | htab_find (htab_t htab, const hash_entry_type element) | 
 | { | 
 |   hashval_t index, hash2, hash = htab_hash (element); | 
 |   size_t size; | 
 |   hash_entry_type entry; | 
 |  | 
 |   size = htab_size (htab); | 
 |   index = htab_mod (hash, htab); | 
 |  | 
 |   entry = htab->entries[index]; | 
 |   if (entry == HTAB_EMPTY_ENTRY | 
 |       || (entry != HTAB_DELETED_ENTRY && htab_eq (entry, element))) | 
 |     return entry; | 
 |  | 
 |   hash2 = htab_mod_m2 (hash, htab); | 
 |   for (;;) | 
 |     { | 
 |       index += hash2; | 
 |       if (index >= size) | 
 | 	index -= size; | 
 |  | 
 |       entry = htab->entries[index]; | 
 |       if (entry == HTAB_EMPTY_ENTRY | 
 | 	  || (entry != HTAB_DELETED_ENTRY && htab_eq (entry, element))) | 
 | 	return entry; | 
 |     } | 
 | } | 
 |  | 
 | /* This function searches for a hash table slot containing an entry | 
 |    equal to the given element.  To delete an entry, call this with | 
 |    insert=NO_INSERT, then call htab_clear_slot on the slot returned | 
 |    (possibly after doing some checks).  To insert an entry, call this | 
 |    with insert=INSERT, then write the value you want into the returned | 
 |    slot.  */ | 
 |  | 
 | static hash_entry_type * | 
 | htab_find_slot (htab_t *htabp, const hash_entry_type element, | 
 | 		enum insert_option insert) | 
 | { | 
 |   hash_entry_type *first_deleted_slot; | 
 |   hashval_t index, hash2, hash = htab_hash (element); | 
 |   size_t size; | 
 |   hash_entry_type entry; | 
 |   htab_t htab = *htabp; | 
 |  | 
 |   size = htab_size (htab); | 
 |   if (insert == INSERT && size * 3 <= htab->n_elements * 4) | 
 |     { | 
 |       htab = *htabp = htab_expand (htab); | 
 |       size = htab_size (htab); | 
 |     } | 
 |  | 
 |   index = htab_mod (hash, htab); | 
 |  | 
 |   first_deleted_slot = NULL; | 
 |  | 
 |   entry = htab->entries[index]; | 
 |   if (entry == HTAB_EMPTY_ENTRY) | 
 |     goto empty_entry; | 
 |   else if (entry == HTAB_DELETED_ENTRY) | 
 |     first_deleted_slot = &htab->entries[index]; | 
 |   else if (htab_eq (entry, element)) | 
 |     return &htab->entries[index]; | 
 |  | 
 |   hash2 = htab_mod_m2 (hash, htab); | 
 |   for (;;) | 
 |     { | 
 |       index += hash2; | 
 |       if (index >= size) | 
 | 	index -= size; | 
 |  | 
 |       entry = htab->entries[index]; | 
 |       if (entry == HTAB_EMPTY_ENTRY) | 
 | 	goto empty_entry; | 
 |       else if (entry == HTAB_DELETED_ENTRY) | 
 | 	{ | 
 | 	  if (!first_deleted_slot) | 
 | 	    first_deleted_slot = &htab->entries[index]; | 
 | 	} | 
 |       else if (htab_eq (entry, element)) | 
 | 	return &htab->entries[index]; | 
 |     } | 
 |  | 
 |  empty_entry: | 
 |   if (insert == NO_INSERT) | 
 |     return NULL; | 
 |  | 
 |   if (first_deleted_slot) | 
 |     { | 
 |       htab->n_deleted--; | 
 |       *first_deleted_slot = HTAB_EMPTY_ENTRY; | 
 |       return first_deleted_slot; | 
 |     } | 
 |  | 
 |   htab->n_elements++; | 
 |   return &htab->entries[index]; | 
 | } | 
 |  | 
 | /* This function clears a specified slot in a hash table.  It is | 
 |    useful when you've already done the lookup and don't want to do it | 
 |    again.  */ | 
 |  | 
 | static inline void | 
 | htab_clear_slot (htab_t htab, hash_entry_type *slot) | 
 | { | 
 |   if (slot < htab->entries || slot >= htab->entries + htab_size (htab) | 
 |       || *slot == HTAB_EMPTY_ENTRY || *slot == HTAB_DELETED_ENTRY) | 
 |     abort (); | 
 |  | 
 |   *slot = HTAB_DELETED_ENTRY; | 
 |   htab->n_deleted++; | 
 | } | 
 |  | 
 | /* Returns a hash code for pointer P. Simplified version of evahash */ | 
 |  | 
 | static inline hashval_t | 
 | hash_pointer (const void *p) | 
 | { | 
 |   uintptr_t v = (uintptr_t) p; | 
 |   if (sizeof (v) > sizeof (hashval_t)) | 
 |     v ^= v >> (sizeof (uintptr_t) / 2 * __CHAR_BIT__); | 
 |   return v; | 
 | } |