From e20a57b09ed3efd79fd893035c8f70747e5b3efa Mon Sep 17 00:00:00 2001 From: Mike Inouye Date: Wed, 13 May 2026 10:57:18 -0700 Subject: [PATCH] Reuse knowledge_t and pass by reference --- passes/opt/opt_muxtree.cc | 56 ++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/passes/opt/opt_muxtree.cc b/passes/opt/opt_muxtree.cc index 8bf151e71..4c07f61d8 100644 --- a/passes/opt/opt_muxtree.cc +++ b/passes/opt/opt_muxtree.cc @@ -200,6 +200,29 @@ struct OptMuxtreeWorker root_muxes.at(driving_mux) = true; } + struct knowledge_t + { + // Known inactive signals + // The payload is a reference counter used to manage the list + // When it is non-zero, the signal in known to be inactive + // When it reaches zero, the map element is removed + std::vector known_inactive; + + // database of known active signals + std::vector known_active; + + // this is just used to keep track of visited muxes in order to prohibit + // endless recursion in mux loops + std::vector visited_muxes; + + // Initialize with the maximum possible sizes + knowledge_t(int num_bits, int num_muxes) { + known_inactive.assign(num_bits, 0); + known_active.assign(num_bits, 0); + visited_muxes.assign(num_muxes, false); + } + }; + OptMuxtreeWorker(RTLIL::Design *design, RTLIL::Module *module) : design(design), module(module), assign_map(module), removed_count(0) { @@ -227,11 +250,13 @@ struct OptMuxtreeWorker populate_roots(); + knowledge_t shared_knowledge(GetSize(bit2info), GetSize(mux2info)); + for (int mux_idx = 0; mux_idx < GetSize(root_muxes); mux_idx++) if (root_muxes.at(mux_idx)) { log_debug(" Root of a mux tree: %s%s\n", log_id(mux2info[mux_idx].cell), root_enable_muxes.at(mux_idx) ? " (pure)" : ""); root_mux_rerun.erase(mux_idx); - eval_root_mux(mux_idx); + eval_root_mux(shared_knowledge, mux_idx); if (glob_evals_left == 0) { log(" Giving up (too many iterations)\n"); return; @@ -243,7 +268,7 @@ struct OptMuxtreeWorker log_debug(" Root of a mux tree: %s (rerun as non-pure)\n", log_id(mux2info[mux_idx].cell)); log_assert(root_enable_muxes.at(mux_idx)); root_mux_rerun.erase(mux_idx); - eval_root_mux(mux_idx); + eval_root_mux(shared_knowledge, mux_idx); if (glob_evals_left == 0) { log(" Giving up (too many iterations)\n"); return; @@ -334,29 +359,6 @@ struct OptMuxtreeWorker return results; } - struct knowledge_t - { - // Known inactive signals - // The payload is a reference counter used to manage the list - // When it is non-zero, the signal in known to be inactive - // When it reaches zero, the map element is removed - std::vector known_inactive; - - // database of known active signals - std::vector known_active; - - // this is just used to keep track of visited muxes in order to prohibit - // endless recursion in mux loops - std::vector visited_muxes; - - // Initialize with the maximum possible sizes - knowledge_t(int num_bits, int num_muxes) { - known_inactive.assign(num_bits, 0); - known_active.assign(num_bits, 0); - visited_muxes.assign(num_muxes, false); - } - }; - static void activate_port(knowledge_t &knowledge, int port_idx, const muxinfo_t &muxinfo) { // First, mark all other ports inactive for (int i = 0; i < GetSize(muxinfo.ports); i++) { @@ -579,14 +581,14 @@ struct OptMuxtreeWorker } } - void eval_root_mux(int mux_idx) + void eval_root_mux(knowledge_t &knowledge, int mux_idx) { log_assert(glob_evals_left > 0); - knowledge_t knowledge(GetSize(bit2info), GetSize(mux2info)); knowledge.visited_muxes[mux_idx] = true; limits_t limits = {}; limits.do_mark_ports_observable = root_enable_muxes.at(mux_idx); eval_mux(knowledge, mux_idx, limits); + knowledge.visited_muxes[mux_idx] = false; } };