190 lines
5.4 KiB
C
190 lines
5.4 KiB
C
/* A type-safe hash table template.
|
|
Copyright (C) 2012-2014 Free Software Foundation, Inc.
|
|
Contributed by Lawrence Crowl <crowl@google.com>
|
|
|
|
This file is part of GCC.
|
|
|
|
GCC 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.
|
|
|
|
GCC 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.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with GCC; see the file COPYING3. If not see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
|
|
/* This file implements a typed hash table.
|
|
The implementation borrows from libiberty's hashtab. */
|
|
|
|
#include "config.h"
|
|
#include "system.h"
|
|
#include "coretypes.h"
|
|
#include "hash-table.h"
|
|
|
|
|
|
/* 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, here's the function that computed the table; it's a
|
|
vastly simplified version of the function of the same name from gcc. */
|
|
|
|
#if 0
|
|
unsigned int
|
|
ceil_log2 (unsigned int x)
|
|
{
|
|
int i;
|
|
for (i = 31; i >= 0 ; --i)
|
|
if (x > (1u << i))
|
|
return i+1;
|
|
abort ();
|
|
}
|
|
|
|
unsigned int
|
|
choose_multiplier (unsigned int d, unsigned int *mlp, unsigned char *shiftp)
|
|
{
|
|
unsigned long long mhigh;
|
|
double nx;
|
|
int lgup, post_shift;
|
|
int pow, pow2;
|
|
int n = 32, precision = 32;
|
|
|
|
lgup = ceil_log2 (d);
|
|
pow = n + lgup;
|
|
pow2 = n + lgup - precision;
|
|
|
|
nx = ldexp (1.0, pow) + ldexp (1.0, pow2);
|
|
mhigh = nx / d;
|
|
|
|
*shiftp = lgup - 1;
|
|
*mlp = mhigh;
|
|
return mhigh >> 32;
|
|
}
|
|
#endif
|
|
|
|
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. */
|
|
|
|
unsigned int
|
|
hash_table_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)
|
|
{
|
|
fprintf (stderr, "Cannot find prime bigger than %lu\n", n);
|
|
abort ();
|
|
}
|
|
|
|
return low;
|
|
}
|
|
|
|
/* Return X % Y using multiplicative inverse values INV and SHIFT.
|
|
|
|
The multiplicative inverses computed above are for 32-bit types,
|
|
and requires that we be able to compute a highpart multiply.
|
|
|
|
FIX: I am not at all convinced that
|
|
3 loads, 2 multiplications, 3 shifts, and 3 additions
|
|
will be faster than
|
|
1 load and 1 modulus
|
|
on modern systems running a compiler. */
|
|
|
|
#ifdef UNSIGNED_64BIT_TYPE
|
|
static inline hashval_t
|
|
mul_mod (hashval_t x, hashval_t y, hashval_t inv, int shift)
|
|
{
|
|
__extension__ typedef UNSIGNED_64BIT_TYPE ull;
|
|
hashval_t t1, t2, t3, t4, q, r;
|
|
|
|
t1 = ((ull)x * inv) >> 32;
|
|
t2 = x - t1;
|
|
t3 = t2 >> 1;
|
|
t4 = t1 + t3;
|
|
q = t4 >> shift;
|
|
r = x - (q * y);
|
|
|
|
return r;
|
|
}
|
|
#endif
|
|
|
|
/* Compute the primary table index for HASH given current prime index. */
|
|
|
|
hashval_t
|
|
hash_table_mod1 (hashval_t hash, unsigned int index)
|
|
{
|
|
const struct prime_ent *p = &prime_tab[index];
|
|
#ifdef UNSIGNED_64BIT_TYPE
|
|
if (sizeof (hashval_t) * CHAR_BIT <= 32)
|
|
return mul_mod (hash, p->prime, p->inv, p->shift);
|
|
#endif
|
|
return hash % p->prime;
|
|
}
|
|
|
|
|
|
/* Compute the secondary table index for HASH given current prime index. */
|
|
|
|
hashval_t
|
|
hash_table_mod2 (hashval_t hash, unsigned int index)
|
|
{
|
|
const struct prime_ent *p = &prime_tab[index];
|
|
#ifdef UNSIGNED_64BIT_TYPE
|
|
if (sizeof (hashval_t) * CHAR_BIT <= 32)
|
|
return 1 + mul_mod (hash, p->prime - 2, p->inv_m2, p->shift);
|
|
#endif
|
|
return 1 + hash % (p->prime - 2);
|
|
}
|