From bce984fa60fed1b46a95383d0737eb620fb0c340 Mon Sep 17 00:00:00 2001 From: Rasmus Munk Larsen Date: Mon, 2 Oct 2023 15:57:18 -0700 Subject: [PATCH 1/5] Speed up OptMergePass by 1.7x. The main speedup comes from swithing from using a SHA1 hash to std::hash. There is no need to use an expensive cryptographic hash for fingerprinting in this context. --- kernel/celltypes.h | 10 +++++----- kernel/rtlil.h | 6 +++++- passes/opt/opt_merge.cc | 11 +++++------ 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index cad505d9afd..58c6907dc63 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -56,7 +56,7 @@ struct CellTypes setup_stdcells_mem(); } - void setup_type(RTLIL::IdString type, const pool &inputs, const pool &outputs, bool is_evaluable = false) + void setup_type(const RTLIL::IdString& type, const pool &inputs, const pool &outputs, bool is_evaluable = false) { CellType ct = {type, inputs, outputs, is_evaluable}; cell_types[ct.type] = ct; @@ -298,24 +298,24 @@ struct CellTypes cell_types.clear(); } - bool cell_known(RTLIL::IdString type) const + bool cell_known(const RTLIL::IdString& type) const { return cell_types.count(type) != 0; } - bool cell_output(RTLIL::IdString type, RTLIL::IdString port) const + bool cell_output(const RTLIL::IdString& type, const RTLIL::IdString& port) const { auto it = cell_types.find(type); return it != cell_types.end() && it->second.outputs.count(port) != 0; } - bool cell_input(RTLIL::IdString type, RTLIL::IdString port) const + bool cell_input(const RTLIL::IdString& type, const RTLIL::IdString& port) const { auto it = cell_types.find(type); return it != cell_types.end() && it->second.inputs.count(port) != 0; } - bool cell_evaluable(RTLIL::IdString type) const + bool cell_evaluable(const RTLIL::IdString& type) const { auto it = cell_types.find(type); return it != cell_types.end() && it->second.is_evaluable; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index c50d75e9087..f53d9df8c84 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -308,10 +308,14 @@ namespace RTLIL bool operator!=(const char *rhs) const { return strcmp(c_str(), rhs) != 0; } char operator[](size_t i) const { - const char *p = c_str(); + const char *p = c_str(); +#ifndef NDEBUG for (; i != 0; i--, p++) log_assert(*p != 0); return *p; +#else + return *(p + i); +#endif } std::string substr(size_t pos = 0, size_t len = std::string::npos) const { diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index e9d98cd4304..4bcd5a18947 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -41,7 +41,7 @@ struct OptMergeWorker CellTypes ct; int total_count; - SHA1 checksum; + using FingerPrint = std::hash::result_type; static void sort_pmux_conn(dict &conn) { @@ -78,7 +78,7 @@ struct OptMergeWorker return str; } - std::string hash_cell_parameters_and_connections(const RTLIL::Cell *cell) + FingerPrint hash_cell_parameters_and_connections(const RTLIL::Cell *cell) { vector hash_conn_strings; std::string hash_string = cell->type.str() + "\n"; @@ -149,8 +149,7 @@ struct OptMergeWorker for (auto it : hash_conn_strings) hash_string += it; - checksum.update(hash_string); - return checksum.final(); + return std::hash{}(hash_string); } bool compare_cell_parameters_and_connections(const RTLIL::Cell *cell1, const RTLIL::Cell *cell2) @@ -268,13 +267,13 @@ struct OptMergeWorker } did_something = false; - dict sharemap; + std::unordered_map sharemap; for (auto cell : cells) { if ((!mode_share_all && !ct.cell_known(cell->type)) || !cell->known()) continue; - auto hash = hash_cell_parameters_and_connections(cell); + FingerPrint hash = hash_cell_parameters_and_connections(cell); auto r = sharemap.insert(std::make_pair(hash, cell)); if (!r.second) { if (compare_cell_parameters_and_connections(cell, r.first->second)) { From 058973faee14b822d4b68444b0cc09eea099f6f1 Mon Sep 17 00:00:00 2001 From: Rasmus Munk Larsen Date: Mon, 2 Oct 2023 16:15:47 -0700 Subject: [PATCH 2/5] Undo formatting change. --- kernel/rtlil.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/rtlil.h b/kernel/rtlil.h index f53d9df8c84..ef33ab2d728 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -308,7 +308,7 @@ namespace RTLIL bool operator!=(const char *rhs) const { return strcmp(c_str(), rhs) != 0; } char operator[](size_t i) const { - const char *p = c_str(); + const char *p = c_str(); #ifndef NDEBUG for (; i != 0; i--, p++) log_assert(*p != 0); From 7b454d4633c12dd7ee55f52911116524a3a6da41 Mon Sep 17 00:00:00 2001 From: Rasmus Munk Larsen Date: Tue, 3 Oct 2023 14:06:41 -0700 Subject: [PATCH 3/5] Revert changes to celltypes.h. --- kernel/celltypes.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/celltypes.h b/kernel/celltypes.h index 58c6907dc63..cad505d9afd 100644 --- a/kernel/celltypes.h +++ b/kernel/celltypes.h @@ -56,7 +56,7 @@ struct CellTypes setup_stdcells_mem(); } - void setup_type(const RTLIL::IdString& type, const pool &inputs, const pool &outputs, bool is_evaluable = false) + void setup_type(RTLIL::IdString type, const pool &inputs, const pool &outputs, bool is_evaluable = false) { CellType ct = {type, inputs, outputs, is_evaluable}; cell_types[ct.type] = ct; @@ -298,24 +298,24 @@ struct CellTypes cell_types.clear(); } - bool cell_known(const RTLIL::IdString& type) const + bool cell_known(RTLIL::IdString type) const { return cell_types.count(type) != 0; } - bool cell_output(const RTLIL::IdString& type, const RTLIL::IdString& port) const + bool cell_output(RTLIL::IdString type, RTLIL::IdString port) const { auto it = cell_types.find(type); return it != cell_types.end() && it->second.outputs.count(port) != 0; } - bool cell_input(const RTLIL::IdString& type, const RTLIL::IdString& port) const + bool cell_input(RTLIL::IdString type, RTLIL::IdString port) const { auto it = cell_types.find(type); return it != cell_types.end() && it->second.inputs.count(port) != 0; } - bool cell_evaluable(const RTLIL::IdString& type) const + bool cell_evaluable(RTLIL::IdString type) const { auto it = cell_types.find(type); return it != cell_types.end() && it->second.is_evaluable; From 8e0308b5e7b0c0bbe10c072123d2e7b945f4b6b0 Mon Sep 17 00:00:00 2001 From: Rasmus Munk Larsen Date: Tue, 3 Oct 2023 14:25:59 -0700 Subject: [PATCH 4/5] Revert changes to celltypes.h. Use dict instead of std::unordered_map and most hash function for uint64_t to hashlib.h to support this. --- kernel/hashlib.h | 6 ++++++ passes/opt/opt_merge.cc | 2 +- passes/sat/recover_names.cc | 9 +-------- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/kernel/hashlib.h b/kernel/hashlib.h index be759fdf0a4..9cf43da6ca5 100644 --- a/kernel/hashlib.h +++ b/kernel/hashlib.h @@ -90,6 +90,12 @@ template<> struct hash_ops : hash_int_ops return a; } }; +template<> struct hash_ops : hash_int_ops +{ + static inline unsigned int hash(uint64_t a) { + return mkhash((unsigned int)(a), (unsigned int)(a >> 32)); + } +}; template<> struct hash_ops { static inline bool cmp(const std::string &a, const std::string &b) { diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index 4bcd5a18947..87ad01f00ec 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -267,7 +267,7 @@ struct OptMergeWorker } did_something = false; - std::unordered_map sharemap; + dict sharemap; for (auto cell : cells) { if ((!mode_share_all && !ct.cell_known(cell->type)) || !cell->known()) diff --git a/passes/sat/recover_names.cc b/passes/sat/recover_names.cc index 2d7e7f01cfa..4c30a363202 100644 --- a/passes/sat/recover_names.cc +++ b/passes/sat/recover_names.cc @@ -29,13 +29,6 @@ USING_YOSYS_NAMESPACE -template<> struct hashlib::hash_ops : hashlib::hash_int_ops -{ - static inline unsigned int hash(uint64_t a) { - return mkhash((unsigned int)(a), (unsigned int)(a >> 32)); - } -}; - PRIVATE_NAMESPACE_BEGIN // xorshift128 params @@ -453,7 +446,7 @@ struct RecoverNamesWorker { pool comb_whiteboxes, buffer_types; // class -> (gold, (gate, inverted)) - dict, dict>> cls2bits; + dict, dict>> cls2bits; void analyse_boxes() { From 57a2b4b0cd542f2053616bbc8ece614a28d72f3a Mon Sep 17 00:00:00 2001 From: Rasmus Munk Larsen Date: Tue, 3 Oct 2023 15:02:02 -0700 Subject: [PATCH 5/5] Explicitly use uint64_t as the type of fingerprint to avoid type mismatch with some compilers. --- passes/opt/opt_merge.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/passes/opt/opt_merge.cc b/passes/opt/opt_merge.cc index 87ad01f00ec..248ba80913b 100644 --- a/passes/opt/opt_merge.cc +++ b/passes/opt/opt_merge.cc @@ -41,7 +41,6 @@ struct OptMergeWorker CellTypes ct; int total_count; - using FingerPrint = std::hash::result_type; static void sort_pmux_conn(dict &conn) { @@ -78,7 +77,7 @@ struct OptMergeWorker return str; } - FingerPrint hash_cell_parameters_and_connections(const RTLIL::Cell *cell) + uint64_t hash_cell_parameters_and_connections(const RTLIL::Cell *cell) { vector hash_conn_strings; std::string hash_string = cell->type.str() + "\n"; @@ -267,13 +266,13 @@ struct OptMergeWorker } did_something = false; - dict sharemap; + dict sharemap; for (auto cell : cells) { if ((!mode_share_all && !ct.cell_known(cell->type)) || !cell->known()) continue; - FingerPrint hash = hash_cell_parameters_and_connections(cell); + uint64_t hash = hash_cell_parameters_and_connections(cell); auto r = sharemap.insert(std::make_pair(hash, cell)); if (!r.second) { if (compare_cell_parameters_and_connections(cell, r.first->second)) {