-
Notifications
You must be signed in to change notification settings - Fork 990
Reduce hashops verbiage in OptMergePass
#5349
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
(Wondering how much of these changes can be ported to nextpnr, which has a similar but not identical infrastructure for this...) |
f580f02
to
ea077e7
Compare
kernel/hashlib.h
Outdated
buckets[index] += v; | ||
} | ||
template <typename T, typename U> | ||
void eat_pair(const T &v, const U &u) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Surely there is no need for adding eat_pair? There is a way to have support for eating any sort of hashable container (pair, tuple, vector, array, what have you) and that is not adding eat_pair, eat_tuple, etc, it's what we're doing already
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is, if you have a reference to a T and a U separately, and you want to compute the hash of the pair (T, U), building a std::pair<T, U>
requires copying the T and U into the std::pair
, which is unnecessarily expensive when T and U are complex (e.g. contain an IdString
or std::vector
). In OptMergePass
this situation occurs here and here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The latter case might not be important because the result of the extract()
call should (or could) be moved into the std::pair
so there's no extra copy there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The former case is definitely an issue, which is why I already added an extra method to hashops<std::pair>
to compute the hash without constructing the pair.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, that's an important thing to know about the purposes of the PR, I thought you were only going for clean code here. How do you feel about this approach?
+ using pair_hasher = hash_ops<std::pair<const SigBit&, const SigSpec&>>;
for (int i = 0; i < s_width; i++)
- comm.eat(hash_ops<std::pair<SigBit, SigSpec>>::hash({sig_s[i], sig_b.extract(i*width, width)}));
+ comm.eat(pair_hasher::hash({sig_s[i], sig_b.extract(i*width, width)}));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd still prefer to infer the type names. What do you think about my latest attempt?
void eat(Hasher h) { | ||
template <typename T> | ||
void eat(const T &obj) { | ||
eat(hash_ops<T>::hash(obj)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this bit is fine
passes/opt/opt_merge.cc
Outdated
hashlib::commutative_hash comm; | ||
for (int i = 0; i < s_width; i++) | ||
comm.eat(hash_ops<std::pair<SigBit, SigSpec>>::hash({sig_s[i], sig_b.extract(i*width, width)})); | ||
comm.eat_pair(sig_s[i], sig_b.extract(i*width, width)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this hash_ops<pair<...>>::hash
pattern repeated you could simplify it with a using
or deduplicate it with a lambda, but it's used twice with pairs of different things
ea077e7
to
4fe21dd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. I'd say you can even add hash_pair
to kernel/hashlib.h
now that the solution isn't complicating commutative_hash
but adding a pair-of-crefs adapter
What are the reasons/motivation for this change?
Trivial change to avoid repeating type names unnecessarily. This might be useful if we change the types for parallelism.