On Wed, 2019-12-11 at 17:00 +0100, Jakub Jelinek wrote:
> On Wed, Dec 11, 2019 at 10:44:58AM -0500, David Malcolm wrote:
> > Is it OK for a hash_map key to have a "empty" value that isn't
> > all-zeroes (and thus the same for a hash_table entry)?
> > 
> > Is the following patch OK for trunk?
> 
> I'd say that it is important to analyze the generated code for the
> common
> case where empty elt is all zeros (and perhaps POD only).
> Perhaps -ftree-loop-distribute-patterns can handle it in most cases?
> Perhaps only when built in C++14 or later mode, that would still
> affect
> bootstrapped compilers.  Like, could we conditionally constexpr
> evaluate
> what mark_empty does and determine at compile time if it is all zeros
> or
> not or something similar?
> 
>       Jakub

I did a release build with gcc 9 at -O2, and examined the generated
code for cfg.o's class hash_table<bb_copy_hasher>'s empty_slow (which
has such an all zeroes empty element).

The mark_empty loop there was converted to a memset (without needing
-ftree-loop-distribute-patterns), which is promising.

However, that only covers hash_table.

Our hash_map is built on top of hash_table, where the entries in the
hash_map are key/value pairs.  A memset to 0 of all of the entries in
such a hash_table is not the same as a per-entry mark_empty, as the
latter only touches the m_key part of each entry, not the m_value
part.  It doesn't matter that we don't preserve the m_value for my POD
value cases, but it means the optimizer could never replace a loop of
mark_empty of m_key of 0 with a memset to 0 of all entries, since it
doesn't "know" that m_value can be safely zeroed also.

Is that an issue?  Is it necessarily better to memset the whole of the
buffer, rather than zeroing just the keys?  Hacking out hash_map::empty
shows that it's used in 6 places in the code currently.

[Jeff approved the analyzer, but I realise that this issue is still
blocking it; bother]

Dave

Reply via email to