More hashtable finetuning
authorClifford Wolf <clifford@clifford.at>
Sat, 27 Dec 2014 02:04:50 +0000 (03:04 +0100)
committerClifford Wolf <clifford@clifford.at>
Sat, 27 Dec 2014 02:04:50 +0000 (03:04 +0100)
kernel/hashmap.h
kernel/rtlil.cc
kernel/rtlil.h
kernel/yosys.h
passes/cmds/delete.cc
passes/cmds/splitnets.cc
passes/opt/opt_clean.cc
passes/opt/opt_const.cc
passes/opt/opt_share.cc

index 91df68a71be5d99849f93c898c1f74e96153cf80..729b4916c17d5130e8538a4f32e3b8eecb1faad7 100644 (file)
@@ -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++;
index 8f65f52732fdbda350f1dfb5767f92faa9c22be3..0114cbd604d5dcb266f34003329125a00c2b979f 100644 (file)
@@ -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);
 
index ae37c350c8a7abbd5749f974d3ecb04e1c964866..c50a58619f4d08a78f807cfd928b916927ddcc79 100644 (file)
@@ -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);
index 012b40c1f18803d5d04276dceb91021650dfc3a7..d47f3a95864b76f8e8c62628a0ad0235041bea82 100644 (file)
@@ -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);
index 4c8f16f48653b5e4727a567ebe2447c2dfe65d31..5bf2a36b8d1fd0080d605d5a6f82d69076662632 100644 (file)
@@ -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;
 
index 3b3fc208ebc7ed266fec0ac2922e4790ce85c00d..2523c1660220363361135cad18e4e6fa19723ac1 100644 (file)
@@ -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);
index cb12b3922f686f2a801f3e51669c8fe113788995..b387e03813f8fac08cf6d25fb3119a59c134b485 100644 (file)
@@ -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)
index 9c1a18782f5cf66359633e51ce478f2b927bdc24..f78ea6cc39a0365eb7da07577b20b4b61adbf1ff 100644 (file)
@@ -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())
index 9bc30887302996688d03044f663de6a94fecfd0d..91bfd58ab2369736c2a324c89499dc124b091dd7 100644 (file)
@@ -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