Skip to content

Conversation

rocallahan
Copy link
Contributor

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.

@Ravenslofty
Copy link
Collaborator

Ravenslofty commented Sep 16, 2025

(Wondering how much of these changes can be ported to nextpnr, which has a similar but not identical infrastructure for this...)

@widlarizer widlarizer self-assigned this Sep 16, 2025
@widlarizer widlarizer self-requested a review September 16, 2025 12:46
kernel/hashlib.h Outdated
buckets[index] += v;
}
template <typename T, typename U>
void eat_pair(const T &v, const U &u) {
Copy link
Collaborator

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

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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.

Copy link
Collaborator

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)}));

Copy link
Contributor Author

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));
Copy link
Collaborator

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

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));
Copy link
Collaborator

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

Copy link
Collaborator

@widlarizer widlarizer left a 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants