The following addresses the bad hash function of cselib which uses
integer plus for merging. This causes a huge number of collisions
for the testcase in the PR and thus very large compile-time.
The following rewrites it to use inchash, eliding duplicate mixing
of RTX code and mode in some cases and more consistently avoiding
a return value of zero as well as treating zero as fatal. An
important part is to preserve mixing of hashes of commutative
operators as commutative.
For cselib_hash_plus_const_int this removes the apparent attempt
of making sure to hash the same as a PLUS as cselib_hash_rtx makes
sure to dispatch to cselib_hash_plus_const_int consistently.
This reduces compile-time for the testcase in the PR from unknown
to 22s and for a reduced testcase from 73s to 9s. There's another
pending patchset to improve the speed of inchash mixing, but it's
not in the profile for this testcase (PTA pops up now).
The generated code is equal. I've also compared cc1 builds
with and without the patch and they are now commparing equal
after retaining commutative hashing for commutative operators.
PR rtl-optimization/116002
* cselib.cc (cselib_hash_rtx): Use inchash to get proper mixing.
Consistently avoid a zero return value when hashing successfully.
Consistently treat a zero hash value from recursing as fatal.
Use hashval_t where appropriate.
(cselib_hash_plus_const_int): Likewise.
(new_cselib_val): Use hashval_t.
(cselib_lookup_1): Likewise.