summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClifford Wolf <clifford@clifford.at>2014-12-27 03:04:50 +0100
committerClifford Wolf <clifford@clifford.at>2014-12-27 03:04:50 +0100
commit66ab88d7b0636c21d5df74f753ed379a799fd783 (patch)
treec8f96817b4926e4e938e0c732e240363b89d4bec
parent88d08e8f24cb2d43907a9d28d65fedc9638554ca (diff)
More hashtable finetuning
-rw-r--r--kernel/hashmap.h31
-rw-r--r--kernel/rtlil.cc4
-rw-r--r--kernel/rtlil.h8
-rw-r--r--kernel/yosys.h3
-rw-r--r--passes/cmds/delete.cc4
-rw-r--r--passes/cmds/splitnets.cc2
-rw-r--r--passes/opt/opt_clean.cc2
-rw-r--r--passes/opt/opt_const.cc2
-rw-r--r--passes/opt/opt_share.cc2
9 files changed, 40 insertions, 18 deletions
diff --git a/kernel/hashmap.h b/kernel/hashmap.h
index 91df68a7..729b4916 100644
--- a/kernel/hashmap.h
+++ b/kernel/hashmap.h
@@ -23,6 +23,8 @@
#include <string>
#include <vector>
+#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<typename T>
+ 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 8f65f527..0114cbd6 100644
--- a/kernel/rtlil.cc
+++ b/kernel/rtlil.cc
@@ -1132,7 +1132,7 @@ namespace {
struct DeleteWireWorker
{
RTLIL::Module *module;
- const pool<RTLIL::Wire*, hash_ptr_ops> *wires_p;
+ const pool<RTLIL::Wire*, hash_obj_ops> *wires_p;
void operator()(RTLIL::SigSpec &sig) {
std::vector<RTLIL::SigChunk> chunks = sig;
@@ -1146,7 +1146,7 @@ namespace {
};
}
-void RTLIL::Module::remove(const pool<RTLIL::Wire*, hash_ptr_ops> &wires)
+void RTLIL::Module::remove(const pool<RTLIL::Wire*, hash_obj_ops> &wires)
{
log_assert(refcount_wires_ == 0);
diff --git a/kernel/rtlil.h b/kernel/rtlil.h
index ae37c350..c50a5861 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<RTLIL::Monitor*, hash_ptr_ops> monitors;
+ pool<RTLIL::Monitor*, hash_obj_ops> monitors;
dict<std::string, std::string> scratchpad;
int refcount_modules_;
@@ -806,7 +808,7 @@ protected:
public:
RTLIL::Design *design;
- pool<RTLIL::Monitor*, hash_ptr_ops> monitors;
+ pool<RTLIL::Monitor*, hash_obj_ops> monitors;
int refcount_wires_;
int refcount_cells_;
@@ -860,7 +862,7 @@ public:
RTLIL::ObjRange<RTLIL::Cell*> cells() { return RTLIL::ObjRange<RTLIL::Cell*>(&cells_, &refcount_cells_); }
// Removing wires is expensive. If you have to remove wires, remove them all at once.
- void remove(const pool<RTLIL::Wire*, hash_ptr_ops> &wires);
+ void remove(const pool<RTLIL::Wire*, hash_obj_ops> &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 012b40c1..d47f3a95 100644
--- a/kernel/yosys.h
+++ b/kernel/yosys.h
@@ -149,6 +149,8 @@ void remove_directory(std::string dirname);
template<typename T> 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 4c8f16f4..5bf2a36b 100644
--- a/passes/cmds/delete.cc
+++ b/passes/cmds/delete.cc
@@ -91,8 +91,8 @@ struct DeletePass : public Pass {
continue;
}
- pool<RTLIL::Wire*, hash_ptr_ops> delete_wires;
- pool<RTLIL::Cell*, hash_ptr_ops> delete_cells;
+ pool<RTLIL::Wire*, hash_obj_ops> delete_wires;
+ pool<RTLIL::Cell*, hash_obj_ops> delete_cells;
pool<RTLIL::IdString> delete_procs;
pool<RTLIL::IdString> delete_mems;
diff --git a/passes/cmds/splitnets.cc b/passes/cmds/splitnets.cc
index 3b3fc208..2523c166 100644
--- a/passes/cmds/splitnets.cc
+++ b/passes/cmds/splitnets.cc
@@ -176,7 +176,7 @@ struct SplitnetsPass : public Pass {
module->rewrite_sigspecs(worker);
- pool<RTLIL::Wire*, hash_ptr_ops> delete_wires;
+ pool<RTLIL::Wire*, hash_obj_ops> 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 cb12b392..b387e038 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<RTLIL::Wire*, hash_ptr_ops> del_wires;
+ pool<RTLIL::Wire*, hash_obj_ops> 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 9c1a1878..f78ea6cc 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<RTLIL::SigSpec, RTLIL::SigSpec> invert_map;
TopoSort<RTLIL::Cell*, RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell>> cells;
- dict<RTLIL::Cell*, std::set<RTLIL::SigBit>, hash_ptr_ops> cell_to_inbit;
+ dict<RTLIL::Cell*, std::set<RTLIL::SigBit>, hash_obj_ops> cell_to_inbit;
dict<RTLIL::SigBit, std::set<RTLIL::Cell*>> outbit_to_cell;
for (auto cell : module->cells())
diff --git a/passes/opt/opt_share.cc b/passes/opt/opt_share.cc
index 9bc30887..91bfd58a 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<const RTLIL::Cell*, std::string, hash_ptr_ops> cell_hash_cache;
+ dict<const RTLIL::Cell*, std::string, hash_obj_ops> cell_hash_cache;
#endif
#ifdef USE_CELL_HASH_CACHE