mirror of https://github.com/YosysHQ/yosys.git
hashlib: remove is_new from HasherDJB32, implement hash_top for IdString
This commit is contained in:
parent
8513021e0b
commit
60c1e41557
|
@ -48,14 +48,9 @@ namespace hashlib {
|
||||||
* instead of pointers.
|
* instead of pointers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO describe how comparison hashes are special
|
|
||||||
// TODO draw the line between generic and hash function specific code
|
|
||||||
|
|
||||||
const int hashtable_size_trigger = 2;
|
const int hashtable_size_trigger = 2;
|
||||||
const int hashtable_size_factor = 3;
|
const int hashtable_size_factor = 3;
|
||||||
|
|
||||||
#define DJB2_32
|
|
||||||
|
|
||||||
namespace legacy {
|
namespace legacy {
|
||||||
inline uint32_t mkhash_add(uint32_t a, uint32_t b) {
|
inline uint32_t mkhash_add(uint32_t a, uint32_t b) {
|
||||||
return ((a << 5) + a) + b;
|
return ((a << 5) + a) + b;
|
||||||
|
@ -89,16 +84,11 @@ inline unsigned int mkhash_xorshift(unsigned int a) {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Hasher {
|
class HasherDJB32 {
|
||||||
public:
|
public:
|
||||||
#ifdef DJB2_32
|
|
||||||
using hash_t = uint32_t;
|
using hash_t = uint32_t;
|
||||||
#endif
|
|
||||||
#ifdef DJB2_64
|
|
||||||
using hash_t = uint64_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Hasher() {
|
HasherDJB32() {
|
||||||
// traditionally 5381 is used as starting value for the djb2 hash
|
// traditionally 5381 is used as starting value for the djb2 hash
|
||||||
state = 5381;
|
state = 5381;
|
||||||
}
|
}
|
||||||
|
@ -106,7 +96,7 @@ class Hasher {
|
||||||
fudge = f;
|
fudge = f;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t state;
|
uint32_t state;
|
||||||
static uint32_t fudge;
|
static uint32_t fudge;
|
||||||
// The XOR version of DJB2
|
// The XOR version of DJB2
|
||||||
|
@ -142,19 +132,17 @@ class Hasher {
|
||||||
*this = hash_ops<T>::hash_acc(t, *this);
|
*this = hash_ops<T>::hash_acc(t, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void commutative_acc(uint32_t t) {
|
void commutative_acc(hash_t t) {
|
||||||
state ^= t;
|
state ^= t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void force(hash_t new_state) {
|
void force(hash_t new_state) {
|
||||||
state = new_state;
|
state = new_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_new() const {
|
|
||||||
return state == Hasher().state;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using Hasher = HasherDJB32;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct hash_top_ops {
|
struct hash_top_ops {
|
||||||
static inline bool cmp(const T &a, const T &b) {
|
static inline bool cmp(const T &a, const T &b) {
|
||||||
|
|
|
@ -76,11 +76,13 @@ namespace RTLIL
|
||||||
struct SyncRule;
|
struct SyncRule;
|
||||||
struct Process;
|
struct Process;
|
||||||
struct Binding;
|
struct Binding;
|
||||||
|
struct IdString;
|
||||||
|
|
||||||
typedef std::pair<SigSpec, SigSpec> SigSig;
|
typedef std::pair<SigSpec, SigSpec> SigSig;
|
||||||
|
};
|
||||||
|
|
||||||
struct IdString
|
struct RTLIL::IdString
|
||||||
{
|
{
|
||||||
#undef YOSYS_XTRACE_GET_PUT
|
#undef YOSYS_XTRACE_GET_PUT
|
||||||
#undef YOSYS_SORT_ID_FREE_LIST
|
#undef YOSYS_SORT_ID_FREE_LIST
|
||||||
#undef YOSYS_USE_STICKY_IDS
|
#undef YOSYS_USE_STICKY_IDS
|
||||||
|
@ -96,15 +98,15 @@ namespace RTLIL
|
||||||
|
|
||||||
static std::vector<char*> global_id_storage_;
|
static std::vector<char*> global_id_storage_;
|
||||||
static dict<char*, int> global_id_index_;
|
static dict<char*, int> global_id_index_;
|
||||||
#ifndef YOSYS_NO_IDS_REFCNT
|
#ifndef YOSYS_NO_IDS_REFCNT
|
||||||
static std::vector<int> global_refcount_storage_;
|
static std::vector<int> global_refcount_storage_;
|
||||||
static std::vector<int> global_free_idx_list_;
|
static std::vector<int> global_free_idx_list_;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef YOSYS_USE_STICKY_IDS
|
#ifdef YOSYS_USE_STICKY_IDS
|
||||||
static int last_created_idx_ptr_;
|
static int last_created_idx_ptr_;
|
||||||
static int last_created_idx_[8];
|
static int last_created_idx_[8];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void xtrace_db_dump()
|
static inline void xtrace_db_dump()
|
||||||
{
|
{
|
||||||
|
@ -223,7 +225,7 @@ namespace RTLIL
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef YOSYS_NO_IDS_REFCNT
|
#ifndef YOSYS_NO_IDS_REFCNT
|
||||||
static inline void put_reference(int idx)
|
static inline void put_reference(int idx)
|
||||||
{
|
{
|
||||||
// put_reference() may be called from destructors after the destructor of
|
// put_reference() may be called from destructors after the destructor of
|
||||||
|
@ -257,9 +259,9 @@ namespace RTLIL
|
||||||
global_id_storage_.at(idx) = nullptr;
|
global_id_storage_.at(idx) = nullptr;
|
||||||
global_free_idx_list_.push_back(idx);
|
global_free_idx_list_.push_back(idx);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static inline void put_reference(int) { }
|
static inline void put_reference(int) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// the actual IdString object is just is a single int
|
// the actual IdString object is just is a single int
|
||||||
|
|
||||||
|
@ -360,16 +362,14 @@ namespace RTLIL
|
||||||
*this = IdString();
|
*this = IdString();
|
||||||
}
|
}
|
||||||
|
|
||||||
Hasher hash_acc(Hasher h) const {
|
Hasher hash_acc(Hasher h) const { return hash_ops<int>::hash_acc(index_, h); }
|
||||||
// If we're starting a hashing sequence, simply start with unhashed ID
|
|
||||||
if (h.is_new()) {
|
Hasher hash_top() const {
|
||||||
|
Hasher h;
|
||||||
h.force((Hasher::hash_t) index_);
|
h.force((Hasher::hash_t) index_);
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
return hash_ops<int>::hash_acc(index_, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The following is a helper key_compare class. Instead of for example std::set<Cell*>
|
// The following is a helper key_compare class. Instead of for example std::set<Cell*>
|
||||||
// use std::set<Cell*, IdString::compare_ptr_by_name<Cell>> if the order of cells in the
|
// use std::set<Cell*, IdString::compare_ptr_by_name<Cell>> if the order of cells in the
|
||||||
// set has an influence on the algorithm.
|
// set has an influence on the algorithm.
|
||||||
|
@ -382,29 +382,42 @@ namespace RTLIL
|
||||||
|
|
||||||
// often one needs to check if a given IdString is part of a list (for example a list
|
// often one needs to check if a given IdString is part of a list (for example a list
|
||||||
// of cell types). the following functions helps with that.
|
// of cell types). the following functions helps with that.
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
bool in(Args... args) const {
|
bool in(Args... args) const {
|
||||||
// Credit: https://articles.emptycrate.com/2016/05/14/folds_in_cpp11_ish.html
|
return (... || in(args));
|
||||||
bool result = false;
|
|
||||||
(void) std::initializer_list<int>{ (result = result || in(args), 0)... };
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool in(const IdString &rhs) const { return *this == rhs; }
|
bool in(const IdString &rhs) const { return *this == rhs; }
|
||||||
bool in(const char *rhs) const { return *this == rhs; }
|
bool in(const char *rhs) const { return *this == rhs; }
|
||||||
bool in(const std::string &rhs) const { return *this == rhs; }
|
bool in(const std::string &rhs) const { return *this == rhs; }
|
||||||
bool in(const pool<IdString> &rhs) const { return rhs.count(*this) != 0; }
|
inline bool in(const pool<IdString> &rhs) const;
|
||||||
|
inline bool in(const pool<IdString> &&rhs) const;
|
||||||
|
|
||||||
bool isPublic() const { return begins_with("\\"); }
|
bool isPublic() const { return begins_with("\\"); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace hashlib {
|
||||||
|
template <>
|
||||||
|
struct hash_top_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();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO deprecate this
|
||||||
|
inline bool RTLIL::IdString::in(const pool<IdString> &rhs) const { return rhs.count(*this) != 0; }
|
||||||
|
inline bool RTLIL::IdString::in(const pool<IdString> &&rhs) const { return rhs.count(*this) != 0; }
|
||||||
|
|
||||||
|
namespace RTLIL {
|
||||||
namespace ID {
|
namespace ID {
|
||||||
#define X(_id) extern IdString _id;
|
#define X(_id) extern IdString _id;
|
||||||
#include "kernel/constids.inc"
|
#include "kernel/constids.inc"
|
||||||
#undef X
|
#undef X
|
||||||
};
|
};
|
||||||
|
|
||||||
extern dict<std::string, std::string> constpad;
|
extern dict<std::string, std::string> constpad;
|
||||||
|
|
||||||
const pool<IdString> &builtin_ff_cell_types();
|
const pool<IdString> &builtin_ff_cell_types();
|
||||||
|
|
Loading…
Reference in New Issue