For the testcase in PR113910 we spend a lot of time in PTA comparing
bitmaps for looking up equivalence class members.  This points to
the very weak bitmap_hash function which effectively hashes set
and a subset of not set bits.  The following improves it by mixing
that weak result with the population count of the bitmap, reducing
the number of collisions significantly.  It's still by no means
a good hash function.

One major problem with it was that it simply truncated the
BITMAP_WORD sized intermediate hash to hashval_t which is
unsigned int, effectively not hashing half of the bits.  That solves
most of the slowness.  Mixing in the population count improves
compile-time by another 30% though.

This reduces the compile-time for the testcase from tens of minutes
to 30 seconds and PTA time from 99% to 25%.  bitmap_equal_p is gone
from the profile.

Bootstrap and regtest running on x86_64-unknown-linux-gnu, will
push to trunk and branches.

        PR tree-optimization/113910
        * bitmap.cc (bitmap_hash): Mix the full element "hash" with
        the bitmap population count.
---
 gcc/bitmap.cc | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/gcc/bitmap.cc b/gcc/bitmap.cc
index 6cf326bca5a..33aa0beb2b0 100644
--- a/gcc/bitmap.cc
+++ b/gcc/bitmap.cc
@@ -2696,6 +2696,7 @@ bitmap_hash (const_bitmap head)
 {
   const bitmap_element *ptr;
   BITMAP_WORD hash = 0;
+  unsigned long count = 0;
   int ix;
 
   gcc_checking_assert (!head->tree_form);
@@ -2704,9 +2705,12 @@ bitmap_hash (const_bitmap head)
     {
       hash ^= ptr->indx;
       for (ix = 0; ix != BITMAP_ELEMENT_WORDS; ix++)
-       hash ^= ptr->bits[ix];
+       {
+         hash ^= ptr->bits[ix];
+         count += bitmap_count_bits_in_word (&ptr->bits[ix]);
+       }
     }
-  return (hashval_t)hash;
+  return iterative_hash (&hash, sizeof (hash), count);
 }
 
 
-- 
2.35.3

Reply via email to