Re: [PATCH 1/2] hash-table.h: support non-zero empty values in empty_slow (v2)

2020-01-14 Thread David Malcolm
On Tue, 2020-01-14 at 11:02 +0100, Jakub Jelinek wrote:
> On Mon, Jan 13, 2020 at 11:51:53PM -0500, David Malcolm wrote:
> > > * cfg.s correctly has a call to memset (even with no
> > > optimization)
> > > for
> > > hash_table::empty_slow
> 
> I have intestigated unpatched cc1plus and in the (usually inlined)
> alloc_entries I see in all the places the xcalloc or
> ggc_internal_cleared_alloc
> followed by either a loop storing some zeros or a memset, which is
> something
> I'd hope the patch also improves.

It does: I looked at tree-ssa.s, at the alloc_entries code generated
for:
   static hash_map > *edge_var_maps;

In an unoptimized build:
  Before the patch I see the loop in the .s calling mark_empty after
the calls to data_alloc and ggc_cleared_vec_alloc; 
  After the patch there's no longer that loop in the generated .s

With -O2 it's harder to follow as the ctor gets inlined into
redirect_edge_var_map_add, but:
  Before the patch there's a loop that's zeroing the keys after the
call to ggc_internal_cleared_alloc
  After the patch that loop isn't present.

> As for graphite.c, sure, empty_zero_p = false is a fallback value,
> the
> question was not directly related to this patch, but rather wondering
> how it
> can work at all.
> 
> > Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu (in
> > conjuction with the analyzer patch kit, which it fixes)
> > 
> > OK for master?
> 
> Yes to both patches, thanks.

Thanks.  I rebased and did another bootstrap®ression test with just
patch 1 to be sure.  I've pushed it to master as
7ca50de02cf12c759f4f8daf60913704782b7d45.


I've rebased and squashed the analyzer patch kit and squashed patch 2
into it, and am re-testing it now.

Dave



Re: [PATCH 1/2] hash-table.h: support non-zero empty values in empty_slow (v2)

2020-01-14 Thread Jakub Jelinek
On Mon, Jan 13, 2020 at 11:51:53PM -0500, David Malcolm wrote:
> > * cfg.s correctly has a call to memset (even with no optimization)
> > for
> > hash_table::empty_slow

I have intestigated unpatched cc1plus and in the (usually inlined)
alloc_entries I see in all the places the xcalloc or ggc_internal_cleared_alloc
followed by either a loop storing some zeros or a memset, which is something
I'd hope the patch also improves.

As for graphite.c, sure, empty_zero_p = false is a fallback value, the
question was not directly related to this patch, but rather wondering how it
can work at all.

> Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu (in
> conjuction with the analyzer patch kit, which it fixes)
> 
> OK for master?

Yes to both patches, thanks.

> gcc/cp/ChangeLog:  Jakub Jelinek  
>   * cp-gimplify.c (source_location_table_entry_hash::empty_zero_p):
>   New static constant.
>   * cp-tree.h (named_decl_hash::empty_zero_p): Likewise.
>   (struct named_label_hash::empty_zero_p): Likewise.
>   * decl2.c (mangled_decl_hash::empty_zero_p): Likewise.
> 
> gcc/ChangeLog:  Jakub Jelinek  ,
>   David Malcolm  
>   * attribs.c (excl_hash_traits::empty_zero_p): New static constant.
>   * gcov.c (function_start_pair_hash::empty_zero_p): Likewise.
>   * graphite.c (struct sese_scev_hash::empty_zero_p): Likewise.
>   * hash-map-tests.c (selftest::test_nonzero_empty_key): New selftest.
>   (selftest::hash_map_tests_c_tests): Call it.
>   * hash-map-traits.h (simple_hashmap_traits::empty_zero_p):
>   New static constant, using the value of = H::empty_zero_p.
>   (unbounded_hashmap_traits::empty_zero_p): Likewise, using the value
>   from default_hash_traits .
>   * hash-map.h (hash_map::empty_zero_p): Likewise, using the value
>   from Traits.
>   * hash-set-tests.c (value_hash_traits::empty_zero_p): Likewise.
>   * hash-table.h (hash_table::alloc_entries): Guard the loop of
>   calls to mark_empty with !Descriptor::empty_zero_p.
>   (hash_table::empty_slow): Conditionalize the memset call with a
>   check that Descriptor::empty_zero_p; otherwise, loop through the
>   entries calling mark_empty on them.
>   * hash-traits.h (int_hash::empty_zero_p): New static constant.
>   (pointer_hash::empty_zero_p): Likewise.
>   (pair_hash::empty_zero_p): Likewise.
>   * ipa-devirt.c (default_hash_traits ::empty_zero_p):
>   Likewise.
>   * ipa-prop.c (ipa_bit_ggc_hash_traits::empty_zero_p): Likewise.
>   (ipa_vr_ggc_hash_traits::empty_zero_p): Likewise.
>   * profile.c (location_triplet_hash::empty_zero_p): Likewise.
>   * sanopt.c (sanopt_tree_triplet_hash::empty_zero_p): Likewise.
>   (sanopt_tree_couple_hash::empty_zero_p): Likewise.
>   * tree-hasher.h (int_tree_hasher::empty_zero_p): Likewise.
>   * tree-ssa-sccvn.c (vn_ssa_aux_hasher::empty_zero_p): Likewise.
>   * tree-vect-slp.c (bst_traits::empty_zero_p): Likewise.
>   * tree-vectorizer.h
>   (default_hash_traits::empty_zero_p):
>   Likewise.

Jakub



[PATCH 1/2] hash-table.h: support non-zero empty values in empty_slow (v2)

2020-01-13 Thread David Malcolm
On Mon, 2020-01-13 at 21:58 -0500, David Malcolm wrote:
> On Tue, 2020-01-14 at 00:55 +0100, Jakub Jelinek wrote:
> > On Mon, Jan 13, 2020 at 06:42:06PM -0500, David Malcolm wrote:
> > > Thanks.  Does it have warnings, though?
> > > 
> > > My attempt was similar, but ran into warnings from -Wclass-
> > > memaccess in
> > > four places, like this:
> > > 
> > > ../../src/gcc/hash-map-traits.h:102:12: warning: ‘void*
> > > memset(void*,
> > > int, size_t)’ clearing an object of type ‘struct
> > > hash_map > > std::pair >::hash_entry’ with no trivial
> > > copy-
> > > assignment; use assignment or value-initialization instead [-
> > > Wclass-
> > > memaccess]
> > >102 | memset (entry, 0, sizeof (T) * count);
> > >| ~~~^~
> > > 
> > > where the types in question are:
> > > 
> > > (1)
> > >struct hash_map
> > > > ::hash_entry
> > >../../src/gcc/tree-data-ref.c:844:17:   required from here
> > 
> > I don't understand how there could be new warnings.
> > The patch doesn't add any new memsets, all it does is if (0) code
> > in
> > alloc_entries for certain traits and in empty_slow stops using
> > memset
> > for some traits and uses mark_empty loop there instead.
> 
> Your patch didn't add new memsets; mine did - clearly I misspoke when
> saying they were similar, mine had a somewhat different approach.
> 
> Sorry for the noise, and thanks for your patch.
> 
> I've extended your patch to cover the various hash traits in the
> analyzer and it passes the analyzer's tests.  I also added in the
> selftests from my older patch.
> 
> I examined the generated code, and it seems correct:
> 
> * cfg.s correctly has a call to memset (even with no optimization)
> for
> hash_table::empty_slow
> 
> * the hash_map example with nonzero empty for the analyzer:
> analyzer/program-state.s: sm_state_map::remap_svalue_ids:   hash_map
>  map_t; correctly shows a loop of calls to
> mark_empty
> 
> * a hash_map example with zero empty: tree-ssa.s edge_var_maps
> correctly has a memset in the empty_slow, even with no optimization.
> 
> ...which is promising.
> 
> 
> For the graphite case, I wondered what happens if both is_empty and
> is_deleted are true; looking at hash-table.h, sometimes one is
> checked
> first, sometimes the other, but I don't think it matters for this
> case:; you have empty_zero_p = false,so it uses mark_empty, rather
> than
> trying to memset, which is correct - empty_zero_p being true can be
> thought of as a "it is safe to optimize this hash_table/hash_map by
> treating empty slots as all zero", if you will.
> 
> 
> I'm trying a bootstrap build and full regression suite now, for all
> languages (with graphite enabled, I believe).  Will post the patches
> if
> it succeeds...
> 
> > This was non-bootstrapped build, but I didn't see new warnings in
> > there,
> > and for tree-data-ref.c which you've mentioned I've tried to
> > compile
> > with installed trunk compiler and didn't get any warnings either.
> > 
> >Jakub
> 
> Thanks!  Sorry again about getting this wrong.
> 
> Dave

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu (in
conjuction with the analyzer patch kit, which it fixes)

OK for master?

gcc/cp/ChangeLog:  Jakub Jelinek  
* cp-gimplify.c (source_location_table_entry_hash::empty_zero_p):
New static constant.
* cp-tree.h (named_decl_hash::empty_zero_p): Likewise.
(struct named_label_hash::empty_zero_p): Likewise.
* decl2.c (mangled_decl_hash::empty_zero_p): Likewise.

gcc/ChangeLog:  Jakub Jelinek  ,
David Malcolm  
* attribs.c (excl_hash_traits::empty_zero_p): New static constant.
* gcov.c (function_start_pair_hash::empty_zero_p): Likewise.
* graphite.c (struct sese_scev_hash::empty_zero_p): Likewise.
* hash-map-tests.c (selftest::test_nonzero_empty_key): New selftest.
(selftest::hash_map_tests_c_tests): Call it.
* hash-map-traits.h (simple_hashmap_traits::empty_zero_p):
New static constant, using the value of = H::empty_zero_p.
(unbounded_hashmap_traits::empty_zero_p): Likewise, using the value
from default_hash_traits .
* hash-map.h (hash_map::empty_zero_p): Likewise, using the value
from Traits.
* hash-set-tests.c (value_hash_traits::empty_zero_p): Likewise.
* hash-table.h (hash_table::alloc_entries): Guard the loop of
calls to mark_empty with !Descriptor::empty_zero_p.
(hash_table::empty_slow): Conditionalize the memset call with a
check that Descriptor::empty_zero_p; otherwise, loop through the
entries calling mark_empty on them.
* hash-traits.h (int_hash::empty_zero_p): New static constant.
(pointer_hash::empty_zero_p): Likewise.
(pair_hash::empty_zero_p): Likewise.
* ipa-devirt.c (default_hash_traits ::empty_zero_p):
Likewise.
* ipa-prop.c (ipa_bit_ggc_hash_traits::empty_zero_p): L