Skip to content

Commit

Permalink
hashlib: merge hash_ops with hash_top_ops for plugin compat
Browse files Browse the repository at this point in the history
  • Loading branch information
widlarizer committed Jan 13, 2025
1 parent 6225abe commit cb0d7aa
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 26 deletions.
58 changes: 34 additions & 24 deletions kernel/hashlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,9 @@ namespace legacy {
}
};

/**
* Hash a type with an accumulator in a record or array context
*/
template<typename T>
struct hash_ops;

/**
* Hash a single instance in isolation.
* Can have explicit specialization, but the default redirects to hash_ops
*/
template<typename T>
struct hash_top_ops;

inline unsigned int mkhash_xorshift(unsigned int a) {
if (sizeof(a) == 4) {
a ^= a << 13;
Expand Down Expand Up @@ -147,15 +137,14 @@ class HasherDJB32 {

using Hasher = HasherDJB32;

template<typename T>
struct hash_top_ops {
static inline bool cmp(const T &a, const T &b) {
return hash_ops<T>::cmp(a, b);
}
static inline Hasher hash(const T &a) {
return hash_ops<T>::hash_into(a, Hasher());
}
};
// Boilerplate compressor for trivially implementing
// top-level hash method with hash_into
#define HASH_TOP_LOOP_FST static inline Hasher hash
#define HASH_TOP_LOOP_SND { \
Hasher h; \
h.eat(a); \
return h; \
}

template<typename T>
struct hash_ops {
Expand Down Expand Up @@ -183,6 +172,7 @@ struct hash_ops {
return a.hash_into(h);
}
}
HASH_TOP_LOOP_FST (const T &a) HASH_TOP_LOOP_SND
};

template<typename P, typename Q> struct hash_ops<std::pair<P, Q>> {
Expand All @@ -194,6 +184,7 @@ template<typename P, typename Q> struct hash_ops<std::pair<P, Q>> {
h = hash_ops<Q>::hash_into(a.second, h);
return h;
}
HASH_TOP_LOOP_FST (std::pair<P, Q> a) HASH_TOP_LOOP_SND
};

template<typename... T> struct hash_ops<std::tuple<T...>> {
Expand All @@ -211,6 +202,7 @@ template<typename... T> struct hash_ops<std::tuple<T...>> {
h = element_ops_t::hash_into(std::get<I>(a), h);
return h;
}
HASH_TOP_LOOP_FST (std::tuple<T...> a) HASH_TOP_LOOP_SND
};

template<typename T> struct hash_ops<std::vector<T>> {
Expand All @@ -223,6 +215,7 @@ template<typename T> struct hash_ops<std::vector<T>> {
h.eat(k);
return h;
}
HASH_TOP_LOOP_FST (std::vector<T> a) HASH_TOP_LOOP_SND
};

template<typename T, size_t N> struct hash_ops<std::array<T, N>> {
Expand All @@ -234,6 +227,7 @@ template<typename T, size_t N> struct hash_ops<std::array<T, N>> {
h = hash_ops<T>::hash_into(k, h);
return h;
}
HASH_TOP_LOOP_FST (std::array<T, N> a) HASH_TOP_LOOP_SND
};

struct hash_cstr_ops {
Expand All @@ -245,6 +239,11 @@ struct hash_cstr_ops {
h.hash32(*(a++));
return h;
}
static inline Hasher hash(const char *a) {
Hasher h;
hash_cstr_ops::hash_into(a, h);
return h;
}
};

template <> struct hash_ops<char*> : hash_cstr_ops {};
Expand All @@ -256,6 +255,11 @@ struct hash_ptr_ops {
static inline Hasher hash_into(const void *a, Hasher h) {
return hash_ops<uintptr_t>::hash_into((uintptr_t)a, h);
}
static inline Hasher hash(const void *a) {
Hasher h;
hash_ptr_ops::hash_into(a, h);
return h;
}
};

struct hash_obj_ops {
Expand All @@ -270,6 +274,12 @@ struct hash_obj_ops {
h.eat(0);
return h;
}
template<typename T>
static inline Hasher hash(const T *a) {
Hasher h;
hash_obj_ops::hash_into(a, h);
return h;
}
};
/**
* If you find yourself using this function, think hard
Expand All @@ -280,7 +290,7 @@ struct hash_obj_ops {
template<typename T>
[[nodiscard]]
Hasher::hash_t run_hash(const T& obj) {
return hash_top_ops<T>::hash(obj).yield();
return hash_ops<T>::hash(obj).yield();
}

/** Refer to docs/source/yosys_internals/hashing.rst */
Expand Down Expand Up @@ -352,10 +362,10 @@ inline unsigned int hashtable_size(unsigned int min_size)
throw std::length_error("hash table exceeded maximum size.");
}

template<typename K, typename T, typename OPS = hash_top_ops<K>> class dict;
template<typename K, int offset = 0, typename OPS = hash_top_ops<K>> class idict;
template<typename K, typename OPS = hash_top_ops<K>> class pool;
template<typename K, typename OPS = hash_top_ops<K>> class mfp;
template<typename K, typename T, typename OPS = hash_ops<K>> class dict;
template<typename K, int offset = 0, typename OPS = hash_ops<K>> class idict;
template<typename K, typename OPS = hash_ops<K>> class pool;
template<typename K, typename OPS = hash_ops<K>> class mfp;

template<typename K, typename T, typename OPS>
class dict {
Expand Down
10 changes: 8 additions & 2 deletions kernel/rtlil.h
Original file line number Diff line number Diff line change
Expand Up @@ -398,13 +398,16 @@ struct RTLIL::IdString

namespace hashlib {
template <>
struct hash_top_ops<RTLIL::IdString> {
struct hash_ops<RTLIL::IdString> {
static inline bool cmp(const RTLIL::IdString &a, const RTLIL::IdString &b) {
return a == b;
}
static inline Hasher hash(const RTLIL::IdString id) {
return id.hash_top();
}
static inline Hasher hash_into(const RTLIL::IdString id, Hasher h) {
return id.hash_into(h);
}
};
};

Expand Down Expand Up @@ -920,13 +923,16 @@ struct RTLIL::SigBit

namespace hashlib {
template <>
struct hash_top_ops<RTLIL::SigBit> {
struct hash_ops<RTLIL::SigBit> {
static inline bool cmp(const RTLIL::SigBit &a, const RTLIL::SigBit &b) {
return a == b;
}
static inline Hasher hash(const RTLIL::SigBit sb) {
return sb.hash_top();
}
static inline Hasher hash_into(const RTLIL::SigBit sb, Hasher h) {
return sb.hash_into(h);
}
};
};

Expand Down

0 comments on commit cb0d7aa

Please sign in to comment.