From 7ad7f41bc555d7fc77a2201cdc485702505df637 Mon Sep 17 00:00:00 2001
From: Eddie Hung <eddie@fpgeh.com>
Date: Wed, 18 Mar 2020 12:21:40 -0700
Subject: [PATCH] kernel: share a single CellTypes within a pass

---
 kernel/modtools.h             | 13 +++--------
 passes/memory/memory_share.cc | 20 ++++++++++++----
 passes/opt/opt_expr.cc        |  6 ++---
 passes/opt/share.cc           | 43 +++++++++++++++++++++++------------
 4 files changed, 51 insertions(+), 31 deletions(-)

diff --git a/kernel/modtools.h b/kernel/modtools.h
index 409562eb9..383b37589 100644
--- a/kernel/modtools.h
+++ b/kernel/modtools.h
@@ -380,22 +380,15 @@ struct ModWalker
 		}
 	}
 
-	ModWalker() : design(NULL), module(NULL)
+	ModWalker(RTLIL::Design *design) : design(design), module(NULL)
 	{
+            ct.setup(design);
 	}
 
-	ModWalker(RTLIL::Design *design, RTLIL::Module *module, CellTypes *filter_ct = NULL)
+	void setup(RTLIL::Module *module, CellTypes *filter_ct = NULL)
 	{
-		setup(design, module, filter_ct);
-	}
-
-	void setup(RTLIL::Design *design, RTLIL::Module *module, CellTypes *filter_ct = NULL)
-	{
-		this->design = design;
 		this->module = module;
 
-		ct.clear();
-		ct.setup(design);
 		sigmap.set(module);
 
 		signal_drivers.clear();
diff --git a/passes/memory/memory_share.cc b/passes/memory/memory_share.cc
index eb912cfd4..236c3c99c 100644
--- a/passes/memory/memory_share.cc
+++ b/passes/memory/memory_share.cc
@@ -665,9 +665,18 @@ struct MemoryShareWorker
 	// Setup and run
 	// -------------
 
-	MemoryShareWorker(RTLIL::Design *design, RTLIL::Module *module) :
-			design(design), module(module), sigmap(module)
+	MemoryShareWorker(RTLIL::Design *design) :
+			design(design), modwalker(design)
 	{
+	}
+
+	void operator()(RTLIL::Module* module)
+	{
+		this->module = module;
+		sigmap.set(module);
+		sig_to_mux.clear();
+		conditions_logic_cache.clear();
+
 		std::map<std::string, std::pair<std::vector<RTLIL::Cell*>, std::vector<RTLIL::Cell*>>> memindex;
 
 		sigmap_xmux = sigmap;
@@ -717,7 +726,7 @@ struct MemoryShareWorker
 		cone_ct.cell_types.erase("$shift");
 		cone_ct.cell_types.erase("$shiftx");
 
-		modwalker.setup(design, module, &cone_ct);
+		modwalker.setup(module, &cone_ct);
 
 		for (auto &it : memindex)
 			consolidate_wr_using_sat(it.first, it.second.second);
@@ -755,8 +764,11 @@ struct MemorySharePass : public Pass {
 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE {
 		log_header(design, "Executing MEMORY_SHARE pass (consolidating $memrd/$memwr cells).\n");
 		extra_args(args, 1, design);
+
+		MemoryShareWorker msw(design);
+
 		for (auto module : design->selected_modules())
-			MemoryShareWorker(design, module);
+			msw(module);
 	}
 } MemorySharePass;
 
diff --git a/passes/opt/opt_expr.cc b/passes/opt/opt_expr.cc
index 4a2f170b8..c13184025 100644
--- a/passes/opt/opt_expr.cc
+++ b/passes/opt/opt_expr.cc
@@ -31,9 +31,8 @@ PRIVATE_NAMESPACE_BEGIN
 
 bool did_something;
 
-void replace_undriven(RTLIL::Design *design, RTLIL::Module *module)
+void replace_undriven(RTLIL::Module *module, const CellTypes& ct)
 {
-	CellTypes ct(design);
 	SigMap sigmap(module);
 	SigPool driven_signals;
 	SigPool used_signals;
@@ -1737,13 +1736,14 @@ struct OptExprPass : public Pass {
 		}
 		extra_args(args, argidx, design);
 
+		CellTypes ct(design);
 		for (auto module : design->selected_modules())
 		{
 			log("Optimizing module %s.\n", log_id(module));
 
 			if (undriven) {
 				did_something = false;
-				replace_undriven(design, module);
+				replace_undriven(module, ct);
 				if (did_something)
 					design->scratchpad_set_bool("opt.did_something", true);
 			}
diff --git a/passes/opt/share.cc b/passes/opt/share.cc
index 92ce3fd11..0dea500dd 100644
--- a/passes/opt/share.cc
+++ b/passes/opt/share.cc
@@ -41,7 +41,8 @@ struct ShareWorkerConfig
 
 struct ShareWorker
 {
-	ShareWorkerConfig config;
+	const ShareWorkerConfig config;
+	int limit;
 	pool<RTLIL::IdString> generic_ops;
 
 	RTLIL::Design *design;
@@ -49,7 +50,6 @@ struct ShareWorker
 
 	CellTypes fwd_ct, cone_ct;
 	ModWalker modwalker;
-	ModIndex mi;
 
 	pool<RTLIL::Cell*> cells_to_remove;
 	pool<RTLIL::Cell*> recursion_state;
@@ -1071,6 +1071,8 @@ struct ShareWorker
 		ct.setup_internals();
 		ct.setup_stdcells();
 
+		ModIndex mi(module);
+
 		pool<RTLIL::Cell*> queue, covered;
 		queue.insert(cell);
 
@@ -1117,13 +1119,9 @@ struct ShareWorker
 		module->remove(cell);
 	}
 
-	ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) :
-			config(config), design(design), module(module), mi(module)
+	ShareWorker(ShareWorkerConfig config, RTLIL::Design* design) :
+			config(config), design(design), modwalker(design)
 	{
-	#ifndef NDEBUG
-		bool before_scc = module_has_scc();
-	#endif
-
 		generic_ops.insert(config.generic_uni_ops.begin(), config.generic_uni_ops.end());
 		generic_ops.insert(config.generic_bin_ops.begin(), config.generic_bin_ops.end());
 		generic_ops.insert(config.generic_cbin_ops.begin(), config.generic_cbin_ops.end());
@@ -1140,8 +1138,24 @@ struct ShareWorker
 		cone_ct.cell_types.erase(ID($shr));
 		cone_ct.cell_types.erase(ID($sshl));
 		cone_ct.cell_types.erase(ID($sshr));
+	}
 
-		modwalker.setup(design, module);
+	void operator()(RTLIL::Module *module) {
+		this->module = module;
+
+	#ifndef NDEBUG
+		bool before_scc = module_has_scc();
+	#endif
+
+		limit = config.limit;
+
+		modwalker.setup(module);
+
+		cells_to_remove.clear();
+		recursion_state.clear();;
+		topo_cell_drivers.clear();
+		topo_bit_drivers.clear();
+		exclusive_ctrls.clear();
 
 		find_terminal_bits();
 		find_shareable_cells();
@@ -1399,8 +1413,8 @@ struct ShareWorker
 				topo_cell_drivers[cell] = { supercell };
 				topo_cell_drivers[other_cell] = { supercell };
 
-				if (config.limit > 0)
-					config.limit--;
+				if (limit > 0)
+					limit--;
 
 				break;
 			}
@@ -1528,9 +1542,10 @@ struct SharePass : public Pass {
 		}
 		extra_args(args, argidx, design);
 
-		for (auto &mod_it : design->modules_)
-			if (design->selected(mod_it.second))
-				ShareWorker(config, design, mod_it.second);
+		ShareWorker sw(config, design);
+
+		for (auto module : design->selected_modules())
+			sw(module);
 	}
 } SharePass;