Fix up ipa_vr_ggc_hash_traits::hash

Message ID 20180223170651.GE5867@tucnak
State New
Headers show
  • Fix up ipa_vr_ggc_hash_traits::hash
Related show

Commit Message

Jakub Jelinek Feb. 23, 2018, 5:06 p.m.

ipa_vr_ggc_hash_traits::equal does
  return a->type == b->type && a->min == b->min && a->max == b->max;
so it requires pointer identical type (5 value enum) and min/max,
hopefully only INTEGER_CSTs.  Honza complained on IRC that during
firefox a lot of time is spent in this hash table, probably because
the hash function was poor, it hashes any ranges with the same
min/max values but different TREE_TYPE (p->min) the same.

The following patch adjusts the hash method to match the equal
method, bootstrapped/regtested on x86_64-linux and i686-linux,
ok for trunk?

In theory we could get bigger savings by e.g. using operand_equal_p
on p->min and p->max instead of pointer comparison, but not really sure
if the VRP code is prepared for that.  E.g. VRP cares whether min
or max are the minimum or maximum of the corresponding type, but if we
ignore the type completely, it could be any other integral type.
We'd use the same value_range memory struct for unsigned char [5, 255]
range, where it is [5, +INF] and for int, where it is just [5, 255].
Does LTO canonicalize INTEGER_TYPEs using type_hash_canon?  In any case,
I think further optimizations should be postponed for GCC9.

2018-02-23  Jakub Jelinek  <>

	* ipa-prop.c (ipa_vr_ggc_hash_traits::hash): Hash p->min and
	p->max as pointers rather than using iterative_hash_expr.



--- gcc/ipa-prop.c.jj	2018-01-03 10:19:54.617533871 +0100
+++ gcc/ipa-prop.c	2018-02-23 14:43:08.983733102 +0100
@@ -111,12 +111,13 @@  struct ipa_vr_ggc_hash_traits : public g
   typedef value_range *compare_type;
   static hashval_t
   hash (const value_range *p)
-  {
-    gcc_checking_assert (!p->equiv);
-    hashval_t t = (hashval_t) p->type;
-    t = iterative_hash_expr (p->min, t);
-    return iterative_hash_expr (p->max, t);
-  }
+    {
+      gcc_checking_assert (!p->equiv);
+      inchash::hash hstate (p->type);
+      hstate.add_ptr (p->min);
+      hstate.add_ptr (p->max);
+      return hstate.end ();
+    }
   static bool
   equal (const value_range *a, const value_range *b)