re PR debug/66691 (ICE on valid code at -O3 with -g enabled in simplify_subreg, at...
[gcc.git] / gcc / inchash.h
index a1db9587bebfbf7abc43148e165cfc4e4be40603..e0dfdffa85b0b1b616261b284d7f6e5a0c1deda4 100644 (file)
@@ -20,10 +20,6 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef INCHASH_H
 #define INCHASH_H 1
 
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "hashtab.h"
 
 /* This file implements an incremential hash function ADT, to be used
    by code that incrementially hashes a lot of unrelated data
@@ -32,8 +28,8 @@ along with GCC; see the file COPYING3.  If not see
    Currently it just implements the plain old jhash based
    incremental hash from gcc's tree.c.  */
 
-extern hashval_t iterative_hash_host_wide_int (HOST_WIDE_INT, hashval_t);
-extern hashval_t iterative_hash_hashval_t (hashval_t, hashval_t);
+hashval_t iterative_hash_host_wide_int (HOST_WIDE_INT, hashval_t);
+hashval_t iterative_hash_hashval_t (hashval_t, hashval_t);
 
 namespace inchash
 {
@@ -68,7 +64,7 @@ class hash
   }
 
   /* Hash in pointer PTR.  */
-  void add_ptr (void *ptr)
+  void add_ptr (const void *ptr)
   {
     add (&ptr, sizeof (ptr));
   }
@@ -117,13 +113,13 @@ class hash
   {
     if (a.end() > b.end())
       {
-        merge (b);
+       merge (b);
        merge (a);
       }
     else
       {
-        merge (a);
-        merge (b);
+       merge (a);
+       merge (b);
       }
   }
 
@@ -134,4 +130,57 @@ class hash
 
 }
 
+/* Borrowed from hashtab.c iterative_hash implementation.  */
+#define mix(a,b,c) \
+{ \
+  a -= b; a -= c; a ^= (c>>13); \
+  b -= c; b -= a; b ^= (a<< 8); \
+  c -= a; c -= b; c ^= ((b&0xffffffff)>>13); \
+  a -= b; a -= c; a ^= ((c&0xffffffff)>>12); \
+  b -= c; b -= a; b = (b ^ (a<<16)) & 0xffffffff; \
+  c -= a; c -= b; c = (c ^ (b>> 5)) & 0xffffffff; \
+  a -= b; a -= c; a = (a ^ (c>> 3)) & 0xffffffff; \
+  b -= c; b -= a; b = (b ^ (a<<10)) & 0xffffffff; \
+  c -= a; c -= b; c = (c ^ (b>>15)) & 0xffffffff; \
+}
+
+
+/* Produce good hash value combining VAL and VAL2.  */
+inline
+hashval_t
+iterative_hash_hashval_t (hashval_t val, hashval_t val2)
+{
+  /* the golden ratio; an arbitrary value.  */
+  hashval_t a = 0x9e3779b9;
+
+  mix (a, val, val2);
+  return val2;
+}
+
+/* Produce good hash value combining VAL and VAL2.  */
+
+inline
+hashval_t
+iterative_hash_host_wide_int (HOST_WIDE_INT val, hashval_t val2)
+{
+  if (sizeof (HOST_WIDE_INT) == sizeof (hashval_t))
+    return iterative_hash_hashval_t (val, val2);
+  else
+    {
+      hashval_t a = (hashval_t) val;
+      /* Avoid warnings about shifting of more than the width of the type on
+         hosts that won't execute this path.  */
+      int zero = 0;
+      hashval_t b = (hashval_t) (val >> (sizeof (hashval_t) * 8 + zero));
+      mix (a, b, val2);
+      if (sizeof (HOST_WIDE_INT) > 2 * sizeof (hashval_t))
+       {
+         hashval_t a = (hashval_t) (val >> (sizeof (hashval_t) * 16 + zero));
+         hashval_t b = (hashval_t) (val >> (sizeof (hashval_t) * 24 + zero));
+         mix (a, b, val2);
+       }
+      return val2;
+    }
+}
+
 #endif