aboutsummaryrefslogtreecommitdiff
path: root/gcc/inchash.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2014-07-25 13:39:05 +0000
committerAndi Kleen <ak@gcc.gnu.org>2014-07-25 13:39:05 +0000
commit6d8eb96b448df0073941f48e8d0c6ded834b5da6 (patch)
tree4511c17b40b5c5e380fd3e722d314ee3a4201b6c /gcc/inchash.c
parentf54860ea9624d03dbcf06b5f804159f8d8bc536d (diff)
downloadgcc-6d8eb96b448df0073941f48e8d0c6ded834b5da6.zip
gcc-6d8eb96b448df0073941f48e8d0c6ded834b5da6.tar.gz
gcc-6d8eb96b448df0073941f48e8d0c6ded834b5da6.tar.bz2
Add an abstract incremental hash data type
Some files in gcc, like lto or tree, do large scale incremential hashing. The current jhash implementation of this could be likely improved by using an incremential hash that does not do a full rehashing for every new value added. This patch adds a new "inchash" class that abstracts the internal state of the hash. This makes it easier to plug in new hashes and also cleans up the code a bit. Right now it is just implemented in the same way as the old iterative hash in tree.c. The previous iterative hash code from tree.c moved into a new separate file. Also I fixed up all users to include the new header. It should not really significantly change any hashing by itself, it's mostly a cleanup at this point. v2: Remove begin. Add commutative interface. Add merge hash interface. Add add_flag. gcc/: 2014-07-25 Andi Kleen <ak@linux.intel.com> * Makefile.in (OBJS): Add inchash.o. (PLUGIN_HEADERS): Add inchash.h. * ipa-devirt.c: Include inchash.h. * lto-streamer-out.c: Dito. * tree-ssa-dom.c: Dito. * tree-ssa-pre.c: Dito. * tree-ssa-sccvn.c: Dito. * tree-ssa-tail-merge.c: Dito. * asan.c: Dito. * tree.c (iterative_hash_hashval_t): Move to ... (iterative_hash_host_wide_int): Move to ... * inchash.c: Here. New file. * tree.h (iterative_hash_hashval_t): Move to ... (iterative_hash_host_wide_int): Move to ... * inchash.h: Here. New file. gcc/lto/: 2014-07-25 Andi Kleen <ak@linux.intel.com> * lto.c: Include inchash.h From-SVN: r213054
Diffstat (limited to 'gcc/inchash.c')
-rw-r--r--gcc/inchash.c75
1 files changed, 75 insertions, 0 deletions
diff --git a/gcc/inchash.c b/gcc/inchash.c
new file mode 100644
index 0000000..0f8583e
--- /dev/null
+++ b/gcc/inchash.c
@@ -0,0 +1,75 @@
+/* Incremential hashing for jhash.
+ Copyright (C) 2014 Free Software Foundation, Inc.
+
+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/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "hashtab.h"
+#include "inchash.h"
+
+/* 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. */
+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. */
+
+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;
+ }
+}