From 66ab88d7b0636c21d5df74f753ed379a799fd783 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 27 Dec 2014 03:04:50 +0100 Subject: [PATCH] More hashtable finetuning --- kernel/hashmap.h | 31 +++++++++++++++++++++++++------ kernel/rtlil.cc | 4 ++-- kernel/rtlil.h | 8 +++++--- kernel/yosys.h | 3 ++- passes/cmds/delete.cc | 4 ++-- passes/cmds/splitnets.cc | 2 +- passes/opt/opt_clean.cc | 2 +- passes/opt/opt_const.cc | 2 +- passes/opt/opt_share.cc | 2 +- 9 files changed, 40 insertions(+), 18 deletions(-) diff --git a/kernel/hashmap.h b/kernel/hashmap.h index 91df68a71..729b4916c 100644 --- a/kernel/hashmap.h +++ b/kernel/hashmap.h @@ -23,6 +23,8 @@ #include #include +#define YOSYS_HASHTABLE_SIZE_FACTOR 3 + inline unsigned int mkhash(unsigned int a, unsigned int b) { return ((a << 5) + a) ^ b; } @@ -81,8 +83,19 @@ struct hash_ptr_ops { } }; +struct hash_obj_ops { + bool cmp(const void *a, const void *b) const { + return a == b; + } + template + unsigned int hash(const T *a) const { + return a->name.hash(); + } +}; + inline int hashtable_size(int old_size) { + // prime numbers, approx. in powers of two if (old_size < 53) return 53; if (old_size < 113) return 113; if (old_size < 251) return 251; @@ -144,7 +157,9 @@ class dict entries.clear(); counter = other.size(); - int new_size = hashtable_size(counter); + int new_size = hashtable_size(YOSYS_HASHTABLE_SIZE_FACTOR * counter); + hashtable.resize(new_size); + new_size = new_size / YOSYS_HASHTABLE_SIZE_FACTOR + 1; entries.reserve(new_size); for (auto &it : other) @@ -165,7 +180,6 @@ class dict { free_list = -1; - hashtable.resize(entries.size()); for (auto &h : hashtable) h = -1; @@ -221,7 +235,9 @@ class dict if (free_list < 0) { int i = entries.size(); - entries.resize(hashtable_size(i)); + int new_size = hashtable_size(YOSYS_HASHTABLE_SIZE_FACTOR * entries.size()); + hashtable.resize(new_size); + entries.resize(new_size / YOSYS_HASHTABLE_SIZE_FACTOR + 1); entries[i].udata = value; entries[i].set_next_used(0); counter++; @@ -473,7 +489,9 @@ class pool entries.clear(); counter = other.size(); - int new_size = hashtable_size(counter); + int new_size = hashtable_size(YOSYS_HASHTABLE_SIZE_FACTOR * counter); + hashtable.resize(new_size); + new_size = new_size / YOSYS_HASHTABLE_SIZE_FACTOR + 1; entries.reserve(new_size); for (auto &it : other) @@ -494,7 +512,6 @@ class pool { free_list = -1; - hashtable.resize(entries.size()); for (auto &h : hashtable) h = -1; @@ -550,7 +567,9 @@ class pool if (free_list < 0) { int i = entries.size(); - entries.resize(hashtable_size(i)); + int new_size = hashtable_size(YOSYS_HASHTABLE_SIZE_FACTOR * entries.size()); + hashtable.resize(new_size); + entries.resize(new_size / YOSYS_HASHTABLE_SIZE_FACTOR + 1); entries[i].key = key; entries[i].set_next_used(0); counter++; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 8f65f5273..0114cbd60 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1132,7 +1132,7 @@ namespace { struct DeleteWireWorker { RTLIL::Module *module; - const pool *wires_p; + const pool *wires_p; void operator()(RTLIL::SigSpec &sig) { std::vector chunks = sig; @@ -1146,7 +1146,7 @@ namespace { }; } -void RTLIL::Module::remove(const pool &wires) +void RTLIL::Module::remove(const pool &wires) { log_assert(refcount_wires_ == 0); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index ae37c350c..c50a58619 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -708,6 +708,8 @@ struct RTLIL::Selection struct RTLIL::Monitor { + RTLIL::IdString name; + Monitor() { name = stringf("$%d", autoidx++); } virtual ~Monitor() { } virtual void notify_module_add(RTLIL::Module*) { } virtual void notify_module_del(RTLIL::Module*) { } @@ -719,7 +721,7 @@ struct RTLIL::Monitor struct RTLIL::Design { - pool monitors; + pool monitors; dict scratchpad; int refcount_modules_; @@ -806,7 +808,7 @@ protected: public: RTLIL::Design *design; - pool monitors; + pool monitors; int refcount_wires_; int refcount_cells_; @@ -860,7 +862,7 @@ public: RTLIL::ObjRange cells() { return RTLIL::ObjRange(&cells_, &refcount_cells_); } // Removing wires is expensive. If you have to remove wires, remove them all at once. - void remove(const pool &wires); + void remove(const pool &wires); void remove(RTLIL::Cell *cell); void rename(RTLIL::Wire *wire, RTLIL::IdString new_name); diff --git a/kernel/yosys.h b/kernel/yosys.h index 012b40c1f..d47f3a958 100644 --- a/kernel/yosys.h +++ b/kernel/yosys.h @@ -149,6 +149,8 @@ void remove_directory(std::string dirname); template int GetSize(const T &obj) { return obj.size(); } int GetSize(RTLIL::Wire *wire); +extern int autoidx; + YOSYS_NAMESPACE_END #include "kernel/log.h" @@ -164,7 +166,6 @@ void yosys_shutdown(); Tcl_Interp *yosys_get_tcl_interp(); #endif -extern int autoidx; extern RTLIL::Design *yosys_design; RTLIL::IdString new_id(std::string file, int line, std::string func); diff --git a/passes/cmds/delete.cc b/passes/cmds/delete.cc index 4c8f16f48..5bf2a36b8 100644 --- a/passes/cmds/delete.cc +++ b/passes/cmds/delete.cc @@ -91,8 +91,8 @@ struct DeletePass : public Pass { continue; } - pool delete_wires; - pool delete_cells; + pool delete_wires; + pool delete_cells; pool delete_procs; pool delete_mems; diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc index 3b3fc208e..2523c1660 100644 --- a/passes/cmds/splitnets.cc +++ b/passes/cmds/splitnets.cc @@ -176,7 +176,7 @@ struct SplitnetsPass : public Pass { module->rewrite_sigspecs(worker); - pool delete_wires; + pool delete_wires; for (auto &it : worker.splitmap) delete_wires.insert(it.first); module->remove(delete_wires); diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index cb12b3922..b387e0381 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -262,7 +262,7 @@ void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos } - pool del_wires; + pool del_wires; int del_wires_count = 0; for (auto wire : maybe_del_wires) diff --git a/passes/opt/opt_const.cc b/passes/opt/opt_const.cc index 9c1a18782..f78ea6cc3 100644 --- a/passes/opt/opt_const.cc +++ b/passes/opt/opt_const.cc @@ -199,7 +199,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons dict invert_map; TopoSort> cells; - dict, hash_ptr_ops> cell_to_inbit; + dict, hash_obj_ops> cell_to_inbit; dict> outbit_to_cell; for (auto cell : module->cells()) diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc index 9bc308873..91bfd58ab 100644 --- a/passes/opt/opt_share.cc +++ b/passes/opt/opt_share.cc @@ -41,7 +41,7 @@ struct OptShareWorker CellTypes ct; int total_count; #ifdef USE_CELL_HASH_CACHE - dict cell_hash_cache; + dict cell_hash_cache; #endif #ifdef USE_CELL_HASH_CACHE -- 2.30.2