summaryrefslogtreecommitdiff
path: root/gcc/pointer-set.c
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2004-10-17 07:15:53 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2004-10-17 07:15:53 +0000
commit9558ae0e83db4f9253bfa7e8956a50e198e65fcc (patch)
tree6f2f989163a99d91fc204c81b3ce32acb271350f /gcc/pointer-set.c
parent4e16cce345a6de31d6b95a3c3995c71758c411be (diff)
downloadgcc-9558ae0e83db4f9253bfa7e8956a50e198e65fcc.tar.gz
* pointer-set.c (hash1): Use integer part of 2^64 / phi
instead 2^32 / phi if long is 64-bit. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@89165 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/pointer-set.c')
-rw-r--r--gcc/pointer-set.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/gcc/pointer-set.c b/gcc/pointer-set.c
index 06592d741a6..f8023c7fc6c 100644
--- a/gcc/pointer-set.c
+++ b/gcc/pointer-set.c
@@ -46,8 +46,8 @@ struct pointer_set_t
relatively prime to 2^sizeof(size_t). The result is two words.
Discard the most significant word, and return the most significant
N bits of the least significant word. As suggested by Knuth, our
- choice for A is the integer part of 2^32 / phi, where phi is the
- golden ratio.
+ choice for A is the integer part of (ULONG_MAX + 1.0) / phi, where phi
+ is the golden ratio.
We don't need to do anything special for full-width multiplication
because we're only interested in the least significant word of the
@@ -56,8 +56,16 @@ struct pointer_set_t
static inline size_t
hash1 (const void *p, unsigned long max, unsigned long logmax)
{
+#if HOST_BITS_PER_LONG == 32
const unsigned long A = 0x9e3779b9u;
- const unsigned long shift = sizeof(unsigned long) * CHAR_BIT - logmax;
+#elif HOST_BITS_PER_LONG == 64
+ const unsigned long A = 0x9e3779b97f4a7c16ul;
+#else
+ const double M = (ULONG_MAX + 1.0);
+ const double B = M / ((sqrt (5) - 1) / 2.0);
+ const unsigned long A = B - (floor (B / M) * M);
+#endif
+ const unsigned long shift = sizeof (unsigned long) * CHAR_BIT - logmax;
return ((A * (unsigned long) p) >> shift) & (max - 1);
}