Add specialized `hash()` for type `dict` and use a `dict` instead of a `std::map...
authorAlberto Gonzalez <boqwxp@airmail.cc>
Tue, 14 Apr 2020 18:09:05 +0000 (18:09 +0000)
committerAlberto Gonzalez <boqwxp@airmail.cc>
Thu, 14 May 2020 20:06:53 +0000 (20:06 +0000)
kernel/hashlib.h
kernel/rtlil.h
passes/techmap/techmap.cc

index 592d6e5775dd6f48b7ea5826dcb59d88f25a91b4..cdbad87c41e49b40f1bdb51154132338f47ce84c 100644 (file)
 
 namespace hashlib {
 
+template<typename T> struct hash_ops;
+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;
+
 const int hashtable_size_trigger = 2;
 const int hashtable_size_factor = 3;
 
@@ -100,6 +106,20 @@ template<typename P, typename Q> struct hash_ops<std::pair<P, Q>> {
        }
 };
 
+template<typename P, typename Q> struct hash_ops<dict<P, Q>> {
+       static inline bool cmp(dict<P, Q> a, dict<P, Q> b) {
+               return a == b;
+       }
+       static inline unsigned int hash(dict<P, Q> a) {
+               unsigned int h = mkhash_init;
+               for (auto &it : a) {
+                       h = mkhash(h, hash_ops<P>::hash(it.first));
+                       h = mkhash(h, hash_ops<Q>::hash(it.second));
+               }
+               return h;
+       }
+};
+
 template<typename... T> struct hash_ops<std::tuple<T...>> {
        static inline bool cmp(std::tuple<T...> a, std::tuple<T...> b) {
                return a == b;
@@ -191,11 +211,6 @@ inline int hashtable_size(int min_size)
        throw std::length_error("hash table exceeded maximum size.");
 }
 
-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
 {
index 11c45bbec77904615e85d669cfd5b2a181fb1bcb..dad8508c37e467d001195481f90eb604b76eb66c 100644 (file)
@@ -150,7 +150,7 @@ namespace RTLIL
                        if (!p[0])
                                return 0;
 
-                       log_assert(p[0] == '$' || p[0] == '\\');
+                       log_assert(p[0] == '$' || p[0] == '\\' || strncmp(p, "_TECHMAP_", strlen("_TECHMAP_")) == 0);
                        log_assert(p[1] != 0);
 
                        auto it = global_id_index_.find((char*)p);
index bd7cc14a9846f43657affcd3e4fc23ae78eb3997..9779ecae9f1e8b60cd022aa54e30ca76de9b428c 100644 (file)
@@ -63,8 +63,8 @@ void apply_prefix(IdString prefix, RTLIL::SigSpec &sig, RTLIL::Module *module)
 struct TechmapWorker
 {
        dict<IdString, void(*)(RTLIL::Module*, RTLIL::Cell*)> simplemap_mappers;
-       std::map<std::pair<IdString, std::map<IdString, RTLIL::Const>>, RTLIL::Module*> techmap_cache;
-       std::map<RTLIL::Module*, bool> techmap_do_cache;
+       dict<std::pair<IdString, dict<IdString, RTLIL::Const>>, RTLIL::Module*> techmap_cache;
+       dict<RTLIL::Module*, bool> techmap_do_cache;
        std::set<RTLIL::Module*, IdString::compare_ptr_by_name<RTLIL::Module>> module_queue;
        dict<Module*, SigMap> sigmaps;
 
@@ -568,7 +568,7 @@ struct TechmapWorker
                        {
                                IdString derived_name = tpl_name;
                                RTLIL::Module *tpl = map->module(tpl_name);
-                               std::map<IdString, RTLIL::Const> parameters(cell->parameters.begin(), cell->parameters.end());
+                               dict<IdString, RTLIL::Const> parameters(cell->parameters.begin(), cell->parameters.end());
 
                                if (tpl->get_blackbox_attribute(ignore_wb))
                                        continue;
@@ -778,7 +778,7 @@ struct TechmapWorker
                        use_wrapper_tpl:;
                                        // do not register techmap_wrap modules with techmap_cache
                                } else {
-                                       std::pair<IdString, std::map<IdString, RTLIL::Const>> key(tpl_name, parameters);
+                                       std::pair<IdString, dict<IdString, RTLIL::Const>> key(tpl_name, parameters);
                                        if (techmap_cache.count(key) > 0) {
                                                tpl = techmap_cache[key];
                                        } else {