/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/yosys.h"
#include "kernel/satgen.h"
#include "kernel/sigtools.h"
#include "kernel/modtools.h"
#include "kernel/utils.h"
#include "kernel/macc.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

typedef RTLIL::IdString::compare_ptr_by_name<RTLIL::Cell> cell_ptr_cmp;
typedef std::pair<RTLIL::SigSpec, RTLIL::Const> ssc_pair_t;

struct ShareWorkerConfig
{
	int limit;
	bool opt_force;
	bool opt_aggressive;
	bool opt_fast;
	pool<RTLIL::IdString> generic_uni_ops, generic_bin_ops, generic_cbin_ops, generic_other_ops;
};

struct ShareWorker
{
	ShareWorkerConfig config;
	pool<RTLIL::IdString> generic_ops;

	RTLIL::Design *design;
	RTLIL::Module *module;

	CellTypes fwd_ct, cone_ct;
	ModWalker modwalker;
	ModIndex mi;

	pool<RTLIL::Cell*> cells_to_remove;
	pool<RTLIL::Cell*> recursion_state;

	SigMap topo_sigmap;
	std::map<RTLIL::Cell*, std::set<RTLIL::Cell*, cell_ptr_cmp>, cell_ptr_cmp> topo_cell_drivers;
	std::map<RTLIL::SigBit, std::set<RTLIL::Cell*, cell_ptr_cmp>> topo_bit_drivers;

	std::vector<std::pair<RTLIL::SigBit, RTLIL::SigBit>> exclusive_ctrls;


	// ------------------------------------------------------------------------------
	// Find terminal bits -- i.e. bits that do not (exclusively) feed into a mux tree
	// ------------------------------------------------------------------------------

	pool<RTLIL::SigBit> terminal_bits;

	void find_terminal_bits()
	{
		pool<RTLIL::SigBit> queue_bits;
		pool<RTLIL::Cell*> visited_cells;

		queue_bits.insert(modwalker.signal_outputs.begin(), modwalker.signal_outputs.end());

		for (auto &it : module->cells_)
			if (!fwd_ct.cell_known(it.second->type)) {
				pool<RTLIL::SigBit> &bits = modwalker.cell_inputs[it.second];
				queue_bits.insert(bits.begin(), bits.end());
			}

		terminal_bits.insert(queue_bits.begin(), queue_bits.end());

		while (!queue_bits.empty())
		{
			pool<ModWalker::PortBit> portbits;
			modwalker.get_drivers(portbits, queue_bits);
			queue_bits.clear();

			for (auto &pbit : portbits) {
				if (pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) {
					pool<RTLIL::SigBit> bits = modwalker.sigmap(pbit.cell->getPort(ID(S))).to_sigbit_pool();
					terminal_bits.insert(bits.begin(), bits.end());
					queue_bits.insert(bits.begin(), bits.end());
					visited_cells.insert(pbit.cell);
				}
				if (fwd_ct.cell_known(pbit.cell->type) && visited_cells.count(pbit.cell) == 0) {
					pool<RTLIL::SigBit> &bits = modwalker.cell_inputs[pbit.cell];
					terminal_bits.insert(bits.begin(), bits.end());
					queue_bits.insert(bits.begin(), bits.end());
					visited_cells.insert(pbit.cell);
				}
			}
		}
	}


	// ---------------------------------------------------
	// Code for sharing and comparing MACC cells
	// ---------------------------------------------------

	static int bits_macc_port(const Macc::port_t &p, int width)
	{
		if (GetSize(p.in_a) == 0 || GetSize(p.in_b) == 0)
			return min(max(GetSize(p.in_a), GetSize(p.in_b)), width);
		return min(GetSize(p.in_a), width) * min(GetSize(p.in_b), width) / 2;
	}

	static int bits_macc(const Macc &m, int width)
	{
		int bits = GetSize(m.bit_ports);
		for (auto &p : m.ports)
			bits += bits_macc_port(p, width);
		return bits;
	}

	static int bits_macc(RTLIL::Cell *c)
	{
		Macc m(c);
		int width = GetSize(c->getPort(ID::Y));
		return bits_macc(m, width);
	}

	static bool cmp_macc_ports(const Macc::port_t &p1, const Macc::port_t &p2)
	{
		bool mul1 = GetSize(p1.in_a) && GetSize(p1.in_b);
		bool mul2 = GetSize(p2.in_a) && GetSize(p2.in_b);

		int w1 = mul1 ? GetSize(p1.in_a) * GetSize(p1.in_b) : GetSize(p1.in_a) + GetSize(p1.in_b);
		int w2 = mul2 ? GetSize(p2.in_a) * GetSize(p2.in_b) : GetSize(p2.in_a) + GetSize(p2.in_b);

		if (mul1 != mul2)
			return mul1;

		if (w1 != w2)
			return w1 > w2;

		if (p1.is_signed != p2.is_signed)
			return p1.is_signed < p2.is_signed;

		if (p1.do_subtract != p2.do_subtract)
			return p1.do_subtract < p2.do_subtract;

		if (p1.in_a != p2.in_a)
			return p1.in_a < p2.in_a;

		if (p1.in_b != p2.in_b)
			return p1.in_b < p2.in_b;

		return false;
	}

	int share_macc_ports(Macc::port_t &p1, Macc::port_t &p2, int w1, int w2,
			RTLIL::SigSpec act = RTLIL::SigSpec(), Macc *supermacc = nullptr, pool<RTLIL::Cell*> *supercell_aux = nullptr)
	{
		if (p1.do_subtract != p2.do_subtract)
			return -1;

		bool mul1 = GetSize(p1.in_a) && GetSize(p1.in_b);
		bool mul2 = GetSize(p2.in_a) && GetSize(p2.in_b);

		if (mul1 != mul2)
			return -1;

		bool force_signed = false, force_not_signed = false;

		if ((GetSize(p1.in_a) && GetSize(p1.in_a) < w1) || (GetSize(p1.in_b) && GetSize(p1.in_b) < w1)) {
			if (p1.is_signed)
				force_signed = true;
			else
				force_not_signed = true;
		}

		if ((GetSize(p2.in_a) && GetSize(p2.in_a) < w2) || (GetSize(p2.in_b) && GetSize(p2.in_b) < w2)) {
			if (p2.is_signed)
				force_signed = true;
			else
				force_not_signed = true;
		}

		if (force_signed && force_not_signed)
			return -1;

		if (supermacc)
		{
			RTLIL::SigSpec sig_a1 = p1.in_a, sig_b1 = p1.in_b;
			RTLIL::SigSpec sig_a2 = p2.in_a, sig_b2 = p2.in_b;

			RTLIL::SigSpec sig_a = GetSize(sig_a1) > GetSize(sig_a2) ? sig_a1 : sig_a2;
			RTLIL::SigSpec sig_b = GetSize(sig_b1) > GetSize(sig_b2) ? sig_b1 : sig_b2;

			sig_a1.extend_u0(GetSize(sig_a), p1.is_signed);
			sig_b1.extend_u0(GetSize(sig_b), p1.is_signed);

			sig_a2.extend_u0(GetSize(sig_a), p2.is_signed);
			sig_b2.extend_u0(GetSize(sig_b), p2.is_signed);

			if (supercell_aux && GetSize(sig_a)) {
				sig_a = module->addWire(NEW_ID, GetSize(sig_a));
				supercell_aux->insert(module->addMux(NEW_ID, sig_a2, sig_a1, act, sig_a));
			}

			if (supercell_aux && GetSize(sig_b)) {
				sig_b = module->addWire(NEW_ID, GetSize(sig_b));
				supercell_aux->insert(module->addMux(NEW_ID, sig_b2, sig_b1, act, sig_b));
			}

			Macc::port_t p;
			p.in_a = sig_a;
			p.in_b = sig_b;
			p.is_signed = force_signed;
			p.do_subtract = p1.do_subtract;
			supermacc->ports.push_back(p);
		}

		int score = 1000 + abs(GetSize(p1.in_a) - GetSize(p2.in_a)) * max(abs(GetSize(p1.in_b) - GetSize(p2.in_b)), 1);

		for (int i = 0; i < min(GetSize(p1.in_a), GetSize(p2.in_a)); i++)
			if (p1.in_a[i] == p2.in_a[i] && score > 0)
				score--;

		for (int i = 0; i < min(GetSize(p1.in_b), GetSize(p2.in_b)); i++)
			if (p1.in_b[i] == p2.in_b[i] && score > 0)
				score--;

		return score;
	}

	int share_macc(RTLIL::Cell *c1, RTLIL::Cell *c2,
			RTLIL::SigSpec act = RTLIL::SigSpec(), RTLIL::Cell *supercell = nullptr, pool<RTLIL::Cell*> *supercell_aux = nullptr)
	{
		Macc m1(c1), m2(c2), supermacc;

		int w1 = GetSize(c1->getPort(ID::Y)), w2 = GetSize(c2->getPort(ID::Y));
		int width = max(w1, w2);

		m1.optimize(w1);
		m2.optimize(w2);

		std::sort(m1.ports.begin(), m1.ports.end(), cmp_macc_ports);
		std::sort(m2.ports.begin(), m2.ports.end(), cmp_macc_ports);

		std::set<int> m1_unmapped, m2_unmapped;

		for (int i = 0; i < GetSize(m1.ports); i++)
			m1_unmapped.insert(i);

		for (int i = 0; i < GetSize(m2.ports); i++)
			m2_unmapped.insert(i);

		while (1)
		{
			int best_i = -1, best_j = -1, best_score = 0;

			for (int i : m1_unmapped)
			for (int j : m2_unmapped) {
				int score = share_macc_ports(m1.ports[i], m2.ports[j], w1, w2);
				if (score >= 0 && (best_i < 0 || best_score > score))
					best_i = i, best_j = j, best_score = score;
			}

			if (best_i >= 0) {
				m1_unmapped.erase(best_i);
				m2_unmapped.erase(best_j);
				share_macc_ports(m1.ports[best_i], m2.ports[best_j], w1, w2, act, &supermacc, supercell_aux);
			} else
				break;
		}

		for (int i : m1_unmapped)
		{
			RTLIL::SigSpec sig_a = m1.ports[i].in_a;
			RTLIL::SigSpec sig_b = m1.ports[i].in_b;

			if (supercell_aux && GetSize(sig_a)) {
				sig_a = module->addWire(NEW_ID, GetSize(sig_a));
				supercell_aux->insert(module->addMux(NEW_ID, RTLIL::SigSpec(0, GetSize(sig_a)), m1.ports[i].in_a, act, sig_a));
			}

			if (supercell_aux && GetSize(sig_b)) {
				sig_b = module->addWire(NEW_ID, GetSize(sig_b));
				supercell_aux->insert(module->addMux(NEW_ID, RTLIL::SigSpec(0, GetSize(sig_b)), m1.ports[i].in_b, act, sig_b));
			}

			Macc::port_t p;
			p.in_a = sig_a;
			p.in_b = sig_b;
			p.is_signed = m1.ports[i].is_signed;
			p.do_subtract = m1.ports[i].do_subtract;
			supermacc.ports.push_back(p);
		}

		for (int i : m2_unmapped)
		{
			RTLIL::SigSpec sig_a = m2.ports[i].in_a;
			RTLIL::SigSpec sig_b = m2.ports[i].in_b;

			if (supercell_aux && GetSize(sig_a)) {
				sig_a = module->addWire(NEW_ID, GetSize(sig_a));
				supercell_aux->insert(module->addMux(NEW_ID, m2.ports[i].in_a, RTLIL::SigSpec(0, GetSize(sig_a)), act, sig_a));
			}

			if (supercell_aux && GetSize(sig_b)) {
				sig_b = module->addWire(NEW_ID, GetSize(sig_b));
				supercell_aux->insert(module->addMux(NEW_ID, m2.ports[i].in_b, RTLIL::SigSpec(0, GetSize(sig_b)), act, sig_b));
			}

			Macc::port_t p;
			p.in_a = sig_a;
			p.in_b = sig_b;
			p.is_signed = m2.ports[i].is_signed;
			p.do_subtract = m2.ports[i].do_subtract;
			supermacc.ports.push_back(p);
		}

		if (supercell)
		{
			RTLIL::SigSpec sig_y = module->addWire(NEW_ID, width);

			supercell_aux->insert(module->addPos(NEW_ID, sig_y, c1->getPort(ID::Y)));
			supercell_aux->insert(module->addPos(NEW_ID, sig_y, c2->getPort(ID::Y)));

			supercell->setParam(ID(Y_WIDTH), width);
			supercell->setPort(ID::Y, sig_y);

			supermacc.optimize(width);
			supermacc.to_cell(supercell);
		}

		return bits_macc(supermacc, width);
	}


	// ---------------------------------------------------
	// Find shareable cells and compatible groups of cells
	// ---------------------------------------------------

	pool<RTLIL::Cell*> shareable_cells;

	void find_shareable_cells()
	{
		for (auto cell : module->cells())
		{
			if (!design->selected(module, cell) || !modwalker.ct.cell_known(cell->type))
				continue;

			for (auto &bit : modwalker.cell_outputs[cell])
				if (terminal_bits.count(bit))
					goto not_a_muxed_cell;

			if (0)
		not_a_muxed_cell:
				continue;

			if (config.opt_force) {
				shareable_cells.insert(cell);
				continue;
			}

			if (cell->type == ID($memrd)) {
				if (cell->parameters.at(ID(CLK_ENABLE)).as_bool())
					continue;
				if (config.opt_aggressive || !modwalker.sigmap(cell->getPort(ID(ADDR))).is_fully_const())
					shareable_cells.insert(cell);
				continue;
			}

			if (cell->type.in(ID($mul), ID($div), ID($mod))) {
				if (config.opt_aggressive || cell->parameters.at(ID(Y_WIDTH)).as_int() >= 4)
					shareable_cells.insert(cell);
				continue;
			}

			if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr))) {
				if (config.opt_aggressive || cell->parameters.at(ID(Y_WIDTH)).as_int() >= 8)
					shareable_cells.insert(cell);
				continue;
			}

			if (generic_ops.count(cell->type)) {
				if (config.opt_aggressive)
					shareable_cells.insert(cell);
				continue;
			}
		}
	}

	bool is_shareable_pair(RTLIL::Cell *c1, RTLIL::Cell *c2)
	{
		if (c1->type != c2->type)
			return false;

		if (c1->type == ID($memrd))
		{
			if (c1->parameters.at(ID(MEMID)).decode_string() != c2->parameters.at(ID(MEMID)).decode_string())
				return false;

			return true;
		}

		if (config.generic_uni_ops.count(c1->type))
		{
			if (!config.opt_aggressive)
			{
				int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int();
				int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int();

				int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int();
				int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int();

				if (max(a1_width, a2_width) > 2 * min(a1_width, a2_width)) return false;
				if (max(y1_width, y2_width) > 2 * min(y1_width, y2_width)) return false;
			}

			return true;
		}

		if (config.generic_bin_ops.count(c1->type) || c1->type == ID($alu))
		{
			if (!config.opt_aggressive)
			{
				int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int();
				int b1_width = c1->parameters.at(ID(B_WIDTH)).as_int();
				int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int();

				int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int();
				int b2_width = c2->parameters.at(ID(B_WIDTH)).as_int();
				int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int();

				if (max(a1_width, a2_width) > 2 * min(a1_width, a2_width)) return false;
				if (max(b1_width, b2_width) > 2 * min(b1_width, b2_width)) return false;
				if (max(y1_width, y2_width) > 2 * min(y1_width, y2_width)) return false;
			}

			return true;
		}

		if (config.generic_cbin_ops.count(c1->type))
		{
			if (!config.opt_aggressive)
			{
				int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int();
				int b1_width = c1->parameters.at(ID(B_WIDTH)).as_int();
				int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int();

				int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int();
				int b2_width = c2->parameters.at(ID(B_WIDTH)).as_int();
				int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int();

				int min1_width = min(a1_width, b1_width);
				int max1_width = max(a1_width, b1_width);

				int min2_width = min(a2_width, b2_width);
				int max2_width = max(a2_width, b2_width);

				if (max(min1_width, min2_width) > 2 * min(min1_width, min2_width)) return false;
				if (max(max1_width, max2_width) > 2 * min(max1_width, max2_width)) return false;
				if (max(y1_width, y2_width) > 2 * min(y1_width, y2_width)) return false;
			}

			return true;
		}

		if (c1->type == ID($macc))
		{
			if (!config.opt_aggressive)
				if (share_macc(c1, c2) > 2 * min(bits_macc(c1), bits_macc(c2))) return false;

			return true;
		}

		for (auto &it : c1->parameters)
			if (c2->parameters.count(it.first) == 0 || c2->parameters.at(it.first) != it.second)
				return false;

		for (auto &it : c2->parameters)
			if (c1->parameters.count(it.first) == 0 || c1->parameters.at(it.first) != it.second)
				return false;

		return true;
	}

	void find_shareable_partners(std::vector<RTLIL::Cell*> &results, RTLIL::Cell *cell)
	{
		results.clear();
		for (auto c : shareable_cells)
			if (c != cell && is_shareable_pair(c, cell))
				results.push_back(c);
	}


	// -----------------------
	// Create replacement cell
	// -----------------------

	RTLIL::Cell *make_supercell(RTLIL::Cell *c1, RTLIL::Cell *c2, RTLIL::SigSpec act, pool<RTLIL::Cell*> &supercell_aux)
	{
		log_assert(c1->type == c2->type);

		if (config.generic_uni_ops.count(c1->type))
		{
			if (c1->parameters.at(ID(A_SIGNED)).as_bool() != c2->parameters.at(ID(A_SIGNED)).as_bool())
			{
				RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1;
				if (unsigned_cell->getPort(ID::A).to_sigbit_vector().back() != RTLIL::State::S0) {
					unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1;
					RTLIL::SigSpec new_a = unsigned_cell->getPort(ID::A);
					new_a.append_bit(RTLIL::State::S0);
					unsigned_cell->setPort(ID::A, new_a);
				}
				unsigned_cell->parameters.at(ID(A_SIGNED)) = true;
				unsigned_cell->check();
			}

			bool a_signed = c1->parameters.at(ID(A_SIGNED)).as_bool();
			log_assert(a_signed == c2->parameters.at(ID(A_SIGNED)).as_bool());

			RTLIL::SigSpec a1 = c1->getPort(ID::A);
			RTLIL::SigSpec y1 = c1->getPort(ID::Y);

			RTLIL::SigSpec a2 = c2->getPort(ID::A);
			RTLIL::SigSpec y2 = c2->getPort(ID::Y);

			int a_width = max(a1.size(), a2.size());
			int y_width = max(y1.size(), y2.size());

			a1.extend_u0(a_width, a_signed);
			a2.extend_u0(a_width, a_signed);

			RTLIL::SigSpec a = module->addWire(NEW_ID, a_width);
			supercell_aux.insert(module->addMux(NEW_ID, a2, a1, act, a));

			RTLIL::Wire *y = module->addWire(NEW_ID, y_width);

			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type);
			supercell->parameters[ID(A_SIGNED)] = a_signed;
			supercell->parameters[ID(A_WIDTH)] = a_width;
			supercell->parameters[ID(Y_WIDTH)] = y_width;
			supercell->setPort(ID::A, a);
			supercell->setPort(ID::Y, y);

			supercell_aux.insert(module->addPos(NEW_ID, y, y1));
			supercell_aux.insert(module->addPos(NEW_ID, y, y2));

			supercell_aux.insert(supercell);
			return supercell;
		}

		if (config.generic_bin_ops.count(c1->type) || config.generic_cbin_ops.count(c1->type) || c1->type == ID($alu))
		{
			bool modified_src_cells = false;

			if (config.generic_cbin_ops.count(c1->type))
			{
				int score_unflipped = max(c1->parameters.at(ID(A_WIDTH)).as_int(), c2->parameters.at(ID(A_WIDTH)).as_int()) +
						max(c1->parameters.at(ID(B_WIDTH)).as_int(), c2->parameters.at(ID(B_WIDTH)).as_int());

				int score_flipped = max(c1->parameters.at(ID(A_WIDTH)).as_int(), c2->parameters.at(ID(B_WIDTH)).as_int()) +
						max(c1->parameters.at(ID(B_WIDTH)).as_int(), c2->parameters.at(ID(A_WIDTH)).as_int());

				if (score_flipped < score_unflipped)
				{
					RTLIL::SigSpec tmp = c2->getPort(ID::A);
					c2->setPort(ID::A, c2->getPort(ID::B));
					c2->setPort(ID::B, tmp);

					std::swap(c2->parameters.at(ID(A_WIDTH)), c2->parameters.at(ID(B_WIDTH)));
					std::swap(c2->parameters.at(ID(A_SIGNED)), c2->parameters.at(ID(B_SIGNED)));
					modified_src_cells = true;
				}
			}

			if (c1->parameters.at(ID(A_SIGNED)).as_bool() != c2->parameters.at(ID(A_SIGNED)).as_bool())

			{
				RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1;
				if (unsigned_cell->getPort(ID::A).to_sigbit_vector().back() != RTLIL::State::S0) {
					unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1;
					RTLIL::SigSpec new_a = unsigned_cell->getPort(ID::A);
					new_a.append_bit(RTLIL::State::S0);
					unsigned_cell->setPort(ID::A, new_a);
				}
				unsigned_cell->parameters.at(ID(A_SIGNED)) = true;
				modified_src_cells = true;
			}

			if (c1->parameters.at(ID(B_SIGNED)).as_bool() != c2->parameters.at(ID(B_SIGNED)).as_bool())
			{
				RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(B_SIGNED)).as_bool() ? c2 : c1;
				if (unsigned_cell->getPort(ID::B).to_sigbit_vector().back() != RTLIL::State::S0) {
					unsigned_cell->parameters.at(ID(B_WIDTH)) = unsigned_cell->parameters.at(ID(B_WIDTH)).as_int() + 1;
					RTLIL::SigSpec new_b = unsigned_cell->getPort(ID::B);
					new_b.append_bit(RTLIL::State::S0);
					unsigned_cell->setPort(ID::B, new_b);
				}
				unsigned_cell->parameters.at(ID(B_SIGNED)) = true;
				modified_src_cells = true;
			}

			if (modified_src_cells) {
				c1->check();
				c2->check();
			}

			bool a_signed = c1->parameters.at(ID(A_SIGNED)).as_bool();
			bool b_signed = c1->parameters.at(ID(B_SIGNED)).as_bool();

			log_assert(a_signed == c2->parameters.at(ID(A_SIGNED)).as_bool());
			log_assert(b_signed == c2->parameters.at(ID(B_SIGNED)).as_bool());

			if (c1->type == ID($shl) || c1->type == ID($shr) || c1->type == ID($sshl) || c1->type == ID($sshr))
				b_signed = false;

			RTLIL::SigSpec a1 = c1->getPort(ID::A);
			RTLIL::SigSpec b1 = c1->getPort(ID::B);
			RTLIL::SigSpec y1 = c1->getPort(ID::Y);

			RTLIL::SigSpec a2 = c2->getPort(ID::A);
			RTLIL::SigSpec b2 = c2->getPort(ID::B);
			RTLIL::SigSpec y2 = c2->getPort(ID::Y);

			int a_width = max(a1.size(), a2.size());
			int b_width = max(b1.size(), b2.size());
			int y_width = max(y1.size(), y2.size());

			if (c1->type == ID($shr) && a_signed)
			{
				a_width = max(y_width, a_width);

				if (a1.size() < y1.size()) a1.extend_u0(y1.size(), true);
				if (a2.size() < y2.size()) a2.extend_u0(y2.size(), true);

				a1.extend_u0(a_width, false);
				a2.extend_u0(a_width, false);
			}
			else
			{
				a1.extend_u0(a_width, a_signed);
				a2.extend_u0(a_width, a_signed);
			}

			b1.extend_u0(b_width, b_signed);
			b2.extend_u0(b_width, b_signed);

			RTLIL::SigSpec a = module->addWire(NEW_ID, a_width);
			RTLIL::SigSpec b = module->addWire(NEW_ID, b_width);

			supercell_aux.insert(module->addMux(NEW_ID, a2, a1, act, a));
			supercell_aux.insert(module->addMux(NEW_ID, b2, b1, act, b));

			RTLIL::Wire *y = module->addWire(NEW_ID, y_width);
			RTLIL::Wire *x = c1->type == ID($alu) ? module->addWire(NEW_ID, y_width) : nullptr;
			RTLIL::Wire *co = c1->type == ID($alu) ? module->addWire(NEW_ID, y_width) : nullptr;

			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type);
			supercell->parameters[ID(A_SIGNED)] = a_signed;
			supercell->parameters[ID(B_SIGNED)] = b_signed;
			supercell->parameters[ID(A_WIDTH)] = a_width;
			supercell->parameters[ID(B_WIDTH)] = b_width;
			supercell->parameters[ID(Y_WIDTH)] = y_width;
			supercell->setPort(ID::A, a);
			supercell->setPort(ID::B, b);
			supercell->setPort(ID::Y, y);
			if (c1->type == ID($alu)) {
				RTLIL::Wire *ci = module->addWire(NEW_ID), *bi = module->addWire(NEW_ID);
				supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID(CI)), c1->getPort(ID(CI)), act, ci));
				supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID(BI)), c1->getPort(ID(BI)), act, bi));
				supercell->setPort(ID(CI), ci);
				supercell->setPort(ID(BI), bi);
				supercell->setPort(ID(CO), co);
				supercell->setPort(ID(X), x);
			}
			supercell->check();

			supercell_aux.insert(module->addPos(NEW_ID, y, y1));
			supercell_aux.insert(module->addPos(NEW_ID, y, y2));
			if (c1->type == ID($alu)) {
				supercell_aux.insert(module->addPos(NEW_ID, co, c1->getPort(ID(CO))));
				supercell_aux.insert(module->addPos(NEW_ID, co, c2->getPort(ID(CO))));
				supercell_aux.insert(module->addPos(NEW_ID, x, c1->getPort(ID(X))));
				supercell_aux.insert(module->addPos(NEW_ID, x, c2->getPort(ID(X))));
			}

			supercell_aux.insert(supercell);
			return supercell;
		}

		if (c1->type == ID($macc))
		{
			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type);
			supercell_aux.insert(supercell);
			share_macc(c1, c2, act, supercell, &supercell_aux);
			supercell->check();
			return supercell;
		}

		if (c1->type == ID($memrd))
		{
			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1);
			RTLIL::SigSpec addr1 = c1->getPort(ID(ADDR));
			RTLIL::SigSpec addr2 = c2->getPort(ID(ADDR));
			if (GetSize(addr1) < GetSize(addr2))
				addr1.extend_u0(GetSize(addr2));
			else
				addr2.extend_u0(GetSize(addr1));
			supercell->setPort(ID(ADDR), addr1 != addr2 ? module->Mux(NEW_ID, addr2, addr1, act) : addr1);
			supercell->parameters[ID(ABITS)] = RTLIL::Const(GetSize(addr1));
			supercell_aux.insert(module->addPos(NEW_ID, supercell->getPort(ID(DATA)), c2->getPort(ID(DATA))));
			supercell_aux.insert(supercell);
			return supercell;
		}

		log_abort();
	}


	// -------------------------------------------
	// Finding forbidden control inputs for a cell
	// -------------------------------------------

	std::map<RTLIL::Cell*, pool<RTLIL::SigBit>, cell_ptr_cmp> forbidden_controls_cache;

	const pool<RTLIL::SigBit> &find_forbidden_controls(RTLIL::Cell *cell)
	{
		if (recursion_state.count(cell)) {
			static pool<RTLIL::SigBit> empty_controls_set;
			return empty_controls_set;
		}

		if (forbidden_controls_cache.count(cell))
			return forbidden_controls_cache.at(cell);

		pool<ModWalker::PortBit> pbits;
		pool<RTLIL::Cell*> consumer_cells;

		modwalker.get_consumers(pbits, modwalker.cell_outputs[cell]);

		for (auto &bit : pbits) {
			if ((bit.cell->type == ID($mux) || bit.cell->type == ID($pmux)) && bit.port == ID(S))
				forbidden_controls_cache[cell].insert(bit.cell->getPort(ID(S)).extract(bit.offset, 1));
			consumer_cells.insert(bit.cell);
		}

		recursion_state.insert(cell);

		for (auto c : consumer_cells)
			if (fwd_ct.cell_known(c->type)) {
				const pool<RTLIL::SigBit> &bits = find_forbidden_controls(c);
				forbidden_controls_cache[cell].insert(bits.begin(), bits.end());
			}

		log_assert(recursion_state.count(cell) != 0);
		recursion_state.erase(cell);

		return forbidden_controls_cache[cell];
	}


	// --------------------------------------------------------
	// Finding control inputs and activation pattern for a cell
	// --------------------------------------------------------

	std::map<RTLIL::Cell*, pool<ssc_pair_t>, cell_ptr_cmp> activation_patterns_cache;

	bool sort_check_activation_pattern(ssc_pair_t &p)
	{
		std::map<RTLIL::SigBit, RTLIL::State> p_bits;

		std::vector<RTLIL::SigBit> p_first_bits = p.first;
		for (int i = 0; i < GetSize(p_first_bits); i++) {
			RTLIL::SigBit b = p_first_bits[i];
			RTLIL::State v = p.second.bits[i];
			if (p_bits.count(b) && p_bits.at(b) != v)
				return false;
			p_bits[b] = v;
		}

		p.first = RTLIL::SigSpec();
		p.second.bits.clear();

		for (auto &it : p_bits) {
			p.first.append_bit(it.first);
			p.second.bits.push_back(it.second);
		}

		return true;
	}

	void optimize_activation_patterns(pool<ssc_pair_t> &patterns)
	{
		// TODO: Remove patterns that are contained in other patterns

		dict<SigSpec, pool<Const>> db;
		bool did_something = false;

		for (auto const &p : patterns)
		{
			auto &sig = p.first;
			auto &val = p.second;
			int len = GetSize(sig);

			for (int i = 0; i < len; i++)
			{
				auto otherval = val;

				if (otherval.bits[i] == State::S0)
					otherval.bits[i] = State::S1;
				else if (otherval.bits[i] == State::S1)
					otherval.bits[i] = State::S0;
				else
					continue;

				if (db[sig].count(otherval))
				{
					auto newsig = sig;
					newsig.remove(i);

					auto newval = val;
					newval.bits.erase(newval.bits.begin() + i);

					db[newsig].insert(newval);
					db[sig].erase(otherval);

					did_something = true;
					goto next_pattern;
				}
			}

			db[sig].insert(val);
		next_pattern:;
		}

		if (!did_something)
			return;

		patterns.clear();
		for (auto &it : db)
		for (auto &val : it.second)
			patterns.insert(make_pair(it.first, val));

		optimize_activation_patterns(patterns);
	}

	const pool<ssc_pair_t> &find_cell_activation_patterns(RTLIL::Cell *cell, const char *indent)
	{
		if (recursion_state.count(cell)) {
			static pool<ssc_pair_t> empty_patterns_set;
			return empty_patterns_set;
		}

		if (activation_patterns_cache.count(cell))
			return activation_patterns_cache.at(cell);

		const pool<RTLIL::SigBit> &cell_out_bits = modwalker.cell_outputs[cell];
		pool<RTLIL::Cell*> driven_cells, driven_data_muxes;

		for (auto &bit : cell_out_bits)
		{
			if (terminal_bits.count(bit)) {
				// Terminal cells are always active: unconditional activation pattern
				activation_patterns_cache[cell].insert(ssc_pair_t());
				return activation_patterns_cache.at(cell);
			}
			for (auto &pbit : modwalker.signal_consumers[bit]) {
				log_assert(fwd_ct.cell_known(pbit.cell->type));
				if ((pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) && (pbit.port == ID::A || pbit.port == ID::B))
					driven_data_muxes.insert(pbit.cell);
				else
					driven_cells.insert(pbit.cell);
			}
		}

		recursion_state.insert(cell);

		for (auto c : driven_data_muxes)
		{
			const pool<ssc_pair_t> &c_patterns = find_cell_activation_patterns(c, indent);

			bool used_in_a = false;
			std::set<int> used_in_b_parts;

			int width = c->parameters.at(ID(WIDTH)).as_int();
			std::vector<RTLIL::SigBit> sig_a = modwalker.sigmap(c->getPort(ID::A));
			std::vector<RTLIL::SigBit> sig_b = modwalker.sigmap(c->getPort(ID::B));
			std::vector<RTLIL::SigBit> sig_s = modwalker.sigmap(c->getPort(ID(S)));

			for (auto &bit : sig_a)
				if (cell_out_bits.count(bit))
					used_in_a = true;

			for (int i = 0; i < GetSize(sig_b); i++)
				if (cell_out_bits.count(sig_b[i]))
					used_in_b_parts.insert(i / width);

			if (used_in_a)
				for (auto p : c_patterns) {
					for (int i = 0; i < GetSize(sig_s); i++)
						p.first.append_bit(sig_s[i]), p.second.bits.push_back(RTLIL::State::S0);
					if (sort_check_activation_pattern(p))
						activation_patterns_cache[cell].insert(p);
				}

			for (int idx : used_in_b_parts)
				for (auto p : c_patterns) {
					p.first.append_bit(sig_s[idx]), p.second.bits.push_back(RTLIL::State::S1);
					if (sort_check_activation_pattern(p))
						activation_patterns_cache[cell].insert(p);
				}
		}

		for (auto c : driven_cells) {
			const pool<ssc_pair_t> &c_patterns = find_cell_activation_patterns(c, indent);
			activation_patterns_cache[cell].insert(c_patterns.begin(), c_patterns.end());
		}

		log_assert(recursion_state.count(cell) != 0);
		recursion_state.erase(cell);

		optimize_activation_patterns(activation_patterns_cache[cell]);
		if (activation_patterns_cache[cell].empty()) {
			log("%sFound cell that is never activated: %s\n", indent, log_id(cell));
			RTLIL::SigSpec cell_outputs = modwalker.cell_outputs[cell];
			module->connect(RTLIL::SigSig(cell_outputs, RTLIL::SigSpec(RTLIL::State::Sx, cell_outputs.size())));
			cells_to_remove.insert(cell);
		}

		return activation_patterns_cache[cell];
	}

	RTLIL::SigSpec bits_from_activation_patterns(const pool<ssc_pair_t> &activation_patterns)
	{
		std::set<RTLIL::SigBit> all_bits;
		for (auto &it : activation_patterns) {
			std::vector<RTLIL::SigBit> bits = it.first;
			all_bits.insert(bits.begin(), bits.end());
		}

		RTLIL::SigSpec signal;
		for (auto &bit : all_bits)
			signal.append_bit(bit);

		return signal;
	}

	void filter_activation_patterns(pool<ssc_pair_t> &out,
			const pool<ssc_pair_t> &in, const std::set<RTLIL::SigBit> &filter_bits)
	{
		for (auto &p : in)
		{
			std::vector<RTLIL::SigBit> p_first = p.first;
			ssc_pair_t new_p;

			for (int i = 0; i < GetSize(p_first); i++)
				if (filter_bits.count(p_first[i]) == 0) {
					new_p.first.append_bit(p_first[i]);
					new_p.second.bits.push_back(p.second.bits.at(i));
				}

			out.insert(new_p);
		}
	}

	RTLIL::SigSpec make_cell_activation_logic(const pool<ssc_pair_t> &activation_patterns, pool<RTLIL::Cell*> &supercell_aux)
	{
		RTLIL::Wire *all_cases_wire = module->addWire(NEW_ID, 0);

		for (auto &p : activation_patterns) {
			all_cases_wire->width++;
			supercell_aux.insert(module->addEq(NEW_ID, p.first, p.second, RTLIL::SigSpec(all_cases_wire, all_cases_wire->width - 1)));
		}

		if (all_cases_wire->width == 1)
			return all_cases_wire;

		RTLIL::Wire *result_wire = module->addWire(NEW_ID);
		supercell_aux.insert(module->addReduceOr(NEW_ID, all_cases_wire, result_wire));
		return result_wire;
	}


	// -------------------------------------------------------------------------------------
	// Helper functions used to make sure that this pass does not introduce new logic loops.
	// -------------------------------------------------------------------------------------

	bool module_has_scc()
	{
		CellTypes ct;
		ct.setup_internals();
		ct.setup_stdcells();

		TopoSort<RTLIL::Cell*, cell_ptr_cmp> toposort;
		toposort.analyze_loops = false;

		topo_sigmap.set(module);
		topo_bit_drivers.clear();

		dict<RTLIL::Cell*, pool<RTLIL::SigBit>> cell_to_bits;
		dict<RTLIL::SigBit, pool<RTLIL::Cell*>> bit_to_cells;

		for (auto cell : module->cells())
			if (ct.cell_known(cell->type))
				for (auto &conn : cell->connections()) {
					if (ct.cell_output(cell->type, conn.first))
						for (auto bit : topo_sigmap(conn.second)) {
							cell_to_bits[cell].insert(bit);
							topo_bit_drivers[bit].insert(cell);
						}
					else
						for (auto bit : topo_sigmap(conn.second))
							bit_to_cells[bit].insert(cell);
				}

		for (auto &it : cell_to_bits)
		{
			RTLIL::Cell *c1 = it.first;

			for (auto bit : it.second)
			for (auto c2 : bit_to_cells[bit])
				toposort.edge(c1, c2);
		}

		bool found_scc = !toposort.sort();
		topo_cell_drivers = std::move(toposort.database);

		if (found_scc && toposort.analyze_loops)
			for (auto &loop : toposort.loops) {
				log("### loop ###\n");
				for (auto &c : loop)
					log("%s (%s)\n", log_id(c), log_id(c->type));
			}

		return found_scc;
	}

	bool find_in_input_cone_worker(RTLIL::Cell *root, RTLIL::Cell *needle, pool<RTLIL::Cell*> &stop)
	{
		if (root == needle)
			return true;

		if (stop.count(root))
			return false;

		stop.insert(root);

		for (auto c : topo_cell_drivers[root])
			if (find_in_input_cone_worker(c, needle, stop))
				return true;
		return false;
	}

	bool find_in_input_cone(RTLIL::Cell *root, RTLIL::Cell *needle)
	{
		pool<RTLIL::Cell*> stop;
		return find_in_input_cone_worker(root, needle, stop);
	}

	bool is_part_of_scc(RTLIL::Cell *cell)
	{
		CellTypes ct;
		ct.setup_internals();
		ct.setup_stdcells();

		pool<RTLIL::Cell*> queue, covered;
		queue.insert(cell);

		while (!queue.empty())
		{
			pool<RTLIL::Cell*> new_queue;

			for (auto c : queue) {
				if (!ct.cell_known(c->type))
					continue;
				for (auto &conn : c->connections())
					if (ct.cell_input(c->type, conn.first))
						for (auto bit : conn.second)
							for (auto &pi : mi.query_ports(bit))
								if (ct.cell_known(pi.cell->type) && ct.cell_output(pi.cell->type, pi.port))
									new_queue.insert(pi.cell);
				covered.insert(c);
			}

			queue.clear();
			for (auto c : new_queue) {
				if (cells_to_remove.count(c))
					continue;
				if (c == cell)
					return true;
				if (!covered.count(c))
					queue.insert(c);
			}
		}

		return false;
	}


	// -------------
	// Setup and run
	// -------------

	void remove_cell(Cell *cell)
	{
		shareable_cells.erase(cell);
		forbidden_controls_cache.erase(cell);
		activation_patterns_cache.erase(cell);
		module->remove(cell);
	}

	ShareWorker(ShareWorkerConfig config, RTLIL::Design *design, RTLIL::Module *module) :
			config(config), design(design), module(module), mi(module)
	{
	#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());
		generic_ops.insert(config.generic_other_ops.begin(), config.generic_other_ops.end());

		fwd_ct.setup_internals();

		cone_ct.setup_internals();
		cone_ct.cell_types.erase(ID($mul));
		cone_ct.cell_types.erase(ID($mod));
		cone_ct.cell_types.erase(ID($div));
		cone_ct.cell_types.erase(ID($pow));
		cone_ct.cell_types.erase(ID($shl));
		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);

		find_terminal_bits();
		find_shareable_cells();

		if (shareable_cells.size() < 2)
			return;

		log("Found %d cells in module %s that may be considered for resource sharing.\n",
				GetSize(shareable_cells), log_id(module));

		for (auto cell : module->cells())
			if (cell->type == ID($pmux))
				for (auto bit : cell->getPort(ID(S)))
				for (auto other_bit : cell->getPort(ID(S)))
					if (bit < other_bit)
						exclusive_ctrls.push_back(std::pair<RTLIL::SigBit, RTLIL::SigBit>(bit, other_bit));

		while (!shareable_cells.empty() && config.limit != 0)
		{
			RTLIL::Cell *cell = *shareable_cells.begin();
			shareable_cells.erase(cell);

			log("  Analyzing resource sharing options for %s (%s):\n", log_id(cell), log_id(cell->type));

			const pool<ssc_pair_t> &cell_activation_patterns = find_cell_activation_patterns(cell, "    ");
			RTLIL::SigSpec cell_activation_signals = bits_from_activation_patterns(cell_activation_patterns);

			if (cell_activation_patterns.empty()) {
				log("    Cell is never active. Sharing is pointless, we simply remove it.\n");
				cells_to_remove.insert(cell);
				continue;
			}

			if (cell_activation_patterns.count(ssc_pair_t())) {
				log("    Cell is always active. Therefore no sharing is possible.\n");
				continue;
			}

			log("    Found %d activation_patterns using ctrl signal %s.\n", GetSize(cell_activation_patterns), log_signal(cell_activation_signals));

			std::vector<RTLIL::Cell*> candidates;
			find_shareable_partners(candidates, cell);

			if (candidates.empty()) {
				log("    No candidates found.\n");
				continue;
			}

			log("    Found %d candidates:", GetSize(candidates));
			for (auto c : candidates)
				log(" %s", log_id(c));
			log("\n");

			for (auto other_cell : candidates)
			{
				log("    Analyzing resource sharing with %s (%s):\n", log_id(other_cell), log_id(other_cell->type));

				const pool<ssc_pair_t> &other_cell_activation_patterns = find_cell_activation_patterns(other_cell, "      ");
				RTLIL::SigSpec other_cell_activation_signals = bits_from_activation_patterns(other_cell_activation_patterns);

				if (other_cell_activation_patterns.empty()) {
					log("      Cell is never active. Sharing is pointless, we simply remove it.\n");
					shareable_cells.erase(other_cell);
					cells_to_remove.insert(other_cell);
					continue;
				}

				if (other_cell_activation_patterns.count(ssc_pair_t())) {
					log("      Cell is always active. Therefore no sharing is possible.\n");
					shareable_cells.erase(other_cell);
					continue;
				}

				log("      Found %d activation_patterns using ctrl signal %s.\n",
						GetSize(other_cell_activation_patterns), log_signal(other_cell_activation_signals));

				const pool<RTLIL::SigBit> &cell_forbidden_controls = find_forbidden_controls(cell);
				const pool<RTLIL::SigBit> &other_cell_forbidden_controls = find_forbidden_controls(other_cell);

				std::set<RTLIL::SigBit> union_forbidden_controls;
				union_forbidden_controls.insert(cell_forbidden_controls.begin(), cell_forbidden_controls.end());
				union_forbidden_controls.insert(other_cell_forbidden_controls.begin(), other_cell_forbidden_controls.end());

				if (!union_forbidden_controls.empty())
					log("      Forbidden control signals for this pair of cells: %s\n", log_signal(union_forbidden_controls));

				pool<ssc_pair_t> filtered_cell_activation_patterns;
				pool<ssc_pair_t> filtered_other_cell_activation_patterns;

				filter_activation_patterns(filtered_cell_activation_patterns, cell_activation_patterns, union_forbidden_controls);
				filter_activation_patterns(filtered_other_cell_activation_patterns, other_cell_activation_patterns, union_forbidden_controls);

				optimize_activation_patterns(filtered_cell_activation_patterns);
				optimize_activation_patterns(filtered_other_cell_activation_patterns);

				ezSatPtr ez;
				SatGen satgen(ez.get(), &modwalker.sigmap);

				pool<RTLIL::Cell*> sat_cells;
				std::set<RTLIL::SigBit> bits_queue;

				std::vector<int> cell_active, other_cell_active;
				RTLIL::SigSpec all_ctrl_signals;

				for (auto &p : filtered_cell_activation_patterns) {
					log("      Activation pattern for cell %s: %s = %s\n", log_id(cell), log_signal(p.first), log_signal(p.second));
					cell_active.push_back(ez->vec_eq(satgen.importSigSpec(p.first), satgen.importSigSpec(p.second)));
					all_ctrl_signals.append(p.first);
				}

				for (auto &p : filtered_other_cell_activation_patterns) {
					log("      Activation pattern for cell %s: %s = %s\n", log_id(other_cell), log_signal(p.first), log_signal(p.second));
					other_cell_active.push_back(ez->vec_eq(satgen.importSigSpec(p.first), satgen.importSigSpec(p.second)));
					all_ctrl_signals.append(p.first);
				}

				for (auto &bit : cell_activation_signals.to_sigbit_vector())
					bits_queue.insert(bit);

				for (auto &bit : other_cell_activation_signals.to_sigbit_vector())
					bits_queue.insert(bit);

				while (!bits_queue.empty())
				{
					pool<ModWalker::PortBit> portbits;
					modwalker.get_drivers(portbits, bits_queue);
					bits_queue.clear();

					for (auto &pbit : portbits)
						if (sat_cells.count(pbit.cell) == 0 && cone_ct.cell_known(pbit.cell->type)) {
							if (config.opt_fast && modwalker.cell_outputs[pbit.cell].size() >= 4)
								continue;
							// log("      Adding cell %s (%s) to SAT problem.\n", log_id(pbit.cell), log_id(pbit.cell->type));
							bits_queue.insert(modwalker.cell_inputs[pbit.cell].begin(), modwalker.cell_inputs[pbit.cell].end());
							satgen.importCell(pbit.cell);
							sat_cells.insert(pbit.cell);
						}

					if (config.opt_fast && sat_cells.size() > 100)
						break;
				}

				for (auto it : exclusive_ctrls)
					if (satgen.importedSigBit(it.first) && satgen.importedSigBit(it.second)) {
						log("      Adding exclusive control bits: %s vs. %s\n", log_signal(it.first), log_signal(it.second));
						int sub1 = satgen.importSigBit(it.first);
						int sub2 = satgen.importSigBit(it.second);
						ez->assume(ez->NOT(ez->AND(sub1, sub2)));
					}

				if (!ez->solve(ez->expression(ez->OpOr, cell_active))) {
					log("      According to the SAT solver the cell %s is never active. Sharing is pointless, we simply remove it.\n", log_id(cell));
					cells_to_remove.insert(cell);
					break;
				}

				if (!ez->solve(ez->expression(ez->OpOr, other_cell_active))) {
					log("      According to the SAT solver the cell %s is never active. Sharing is pointless, we simply remove it.\n", log_id(other_cell));
					cells_to_remove.insert(other_cell);
					shareable_cells.erase(other_cell);
					continue;
				}

				ez->non_incremental();

				all_ctrl_signals.sort_and_unify();
				std::vector<int> sat_model = satgen.importSigSpec(all_ctrl_signals);
				std::vector<bool> sat_model_values;

				int sub1 = ez->expression(ez->OpOr, cell_active);
				int sub2 = ez->expression(ez->OpOr, other_cell_active);
				ez->assume(ez->AND(sub1, sub2));

				log("      Size of SAT problem: %d cells, %d variables, %d clauses\n",
						GetSize(sat_cells), ez->numCnfVariables(), ez->numCnfClauses());

				if (ez->solve(sat_model, sat_model_values)) {
					log("      According to the SAT solver this pair of cells can not be shared.\n");
					log("      Model from SAT solver: %s = %d'", log_signal(all_ctrl_signals), GetSize(sat_model_values));
					for (int i = GetSize(sat_model_values)-1; i >= 0; i--)
						log("%c", sat_model_values[i] ? '1' : '0');
					log("\n");
					continue;
				}

				log("      According to the SAT solver this pair of cells can be shared.\n");

				if (find_in_input_cone(cell, other_cell)) {
					log("      Sharing not possible: %s is in input cone of %s.\n", log_id(other_cell), log_id(cell));
					continue;
				}

				if (find_in_input_cone(other_cell, cell)) {
					log("      Sharing not possible: %s is in input cone of %s.\n", log_id(cell), log_id(other_cell));
					continue;
				}

				shareable_cells.erase(other_cell);

				int cell_select_score = 0;
				int other_cell_select_score = 0;

				for (auto &p : filtered_cell_activation_patterns)
					cell_select_score += p.first.size();

				for (auto &p : filtered_other_cell_activation_patterns)
					other_cell_select_score += p.first.size();

				RTLIL::Cell *supercell;
				pool<RTLIL::Cell*> supercell_aux;
				if (cell_select_score <= other_cell_select_score) {
					RTLIL::SigSpec act = make_cell_activation_logic(filtered_cell_activation_patterns, supercell_aux);
					supercell = make_supercell(cell, other_cell, act, supercell_aux);
					log("      Activation signal for %s: %s\n", log_id(cell), log_signal(act));
				} else {
					RTLIL::SigSpec act = make_cell_activation_logic(filtered_other_cell_activation_patterns, supercell_aux);
					supercell = make_supercell(other_cell, cell, act, supercell_aux);
					log("      Activation signal for %s: %s\n", log_id(other_cell), log_signal(act));
				}

				log("      New cell: %s (%s)\n", log_id(supercell), log_id(supercell->type));

				cells_to_remove.insert(cell);
				cells_to_remove.insert(other_cell);

				for (auto c : supercell_aux)
					if (is_part_of_scc(c))
						goto do_rollback;

				if (0) {
			do_rollback:
					log("      New topology contains loops! Rolling back..\n");
					cells_to_remove.erase(cell);
					cells_to_remove.erase(other_cell);
					shareable_cells.insert(other_cell);
					for (auto cc : supercell_aux)
						remove_cell(cc);
					continue;
				}

				pool<ssc_pair_t> supercell_activation_patterns;
				supercell_activation_patterns.insert(filtered_cell_activation_patterns.begin(), filtered_cell_activation_patterns.end());
				supercell_activation_patterns.insert(filtered_other_cell_activation_patterns.begin(), filtered_other_cell_activation_patterns.end());
				optimize_activation_patterns(supercell_activation_patterns);
				activation_patterns_cache[supercell] = supercell_activation_patterns;
				shareable_cells.insert(supercell);

				for (auto bit : topo_sigmap(all_ctrl_signals))
					for (auto c : topo_bit_drivers[bit])
						topo_cell_drivers[supercell].insert(c);

				topo_cell_drivers[supercell].insert(topo_cell_drivers[cell].begin(), topo_cell_drivers[cell].end());
				topo_cell_drivers[supercell].insert(topo_cell_drivers[other_cell].begin(), topo_cell_drivers[other_cell].end());

				topo_cell_drivers[cell] = { supercell };
				topo_cell_drivers[other_cell] = { supercell };

				if (config.limit > 0)
					config.limit--;

				break;
			}
		}

		if (!cells_to_remove.empty()) {
			log("Removing %d cells in module %s:\n", GetSize(cells_to_remove), log_id(module));
			for (auto c : cells_to_remove) {
				log("  Removing cell %s (%s).\n", log_id(c), log_id(c->type));
				remove_cell(c);
			}
		}

		log_assert(recursion_state.empty());

	#ifndef NDEBUG
		bool after_scc = before_scc || module_has_scc();
		log_assert(before_scc == after_scc);
	#endif
	}
};

struct SharePass : public Pass {
	SharePass() : Pass("share", "perform sat-based resource sharing") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    share [options] [selection]\n");
		log("\n");
		log("This pass merges shareable resources into a single resource. A SAT solver\n");
		log("is used to determine if two resources are share-able.\n");
		log("\n");
		log("  -force\n");
		log("    Per default the selection of cells that is considered for sharing is\n");
		log("    narrowed using a list of cell types. With this option all selected\n");
		log("    cells are considered for resource sharing.\n");
		log("\n");
		log("    IMPORTANT NOTE: If the -all option is used then no cells with internal\n");
		log("    state must be selected!\n");
		log("\n");
		log("  -aggressive\n");
		log("    Per default some heuristics are used to reduce the number of cells\n");
		log("    considered for resource sharing to only large resources. This options\n");
		log("    turns this heuristics off, resulting in much more cells being considered\n");
		log("    for resource sharing.\n");
		log("\n");
		log("  -fast\n");
		log("    Only consider the simple part of the control logic in SAT solving, resulting\n");
		log("    in much easier SAT problems at the cost of maybe missing some opportunities\n");
		log("    for resource sharing.\n");
		log("\n");
		log("  -limit N\n");
		log("    Only perform the first N merges, then stop. This is useful for debugging.\n");
		log("\n");
	}
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		ShareWorkerConfig config;

		config.limit = -1;
		config.opt_force = false;
		config.opt_aggressive = false;
		config.opt_fast = false;

		config.generic_uni_ops.insert(ID($not));
		// config.generic_uni_ops.insert(ID($pos));
		config.generic_uni_ops.insert(ID($neg));

		config.generic_cbin_ops.insert(ID($and));
		config.generic_cbin_ops.insert(ID($or));
		config.generic_cbin_ops.insert(ID($xor));
		config.generic_cbin_ops.insert(ID($xnor));

		config.generic_bin_ops.insert(ID($shl));
		config.generic_bin_ops.insert(ID($shr));
		config.generic_bin_ops.insert(ID($sshl));
		config.generic_bin_ops.insert(ID($sshr));

		config.generic_bin_ops.insert(ID($lt));
		config.generic_bin_ops.insert(ID($le));
		config.generic_bin_ops.insert(ID($eq));
		config.generic_bin_ops.insert(ID($ne));
		config.generic_bin_ops.insert(ID($eqx));
		config.generic_bin_ops.insert(ID($nex));
		config.generic_bin_ops.insert(ID($ge));
		config.generic_bin_ops.insert(ID($gt));

		config.generic_cbin_ops.insert(ID($add));
		config.generic_cbin_ops.insert(ID($mul));

		config.generic_bin_ops.insert(ID($sub));
		config.generic_bin_ops.insert(ID($div));
		config.generic_bin_ops.insert(ID($mod));
		// config.generic_bin_ops.insert(ID($pow));

		config.generic_uni_ops.insert(ID($logic_not));
		config.generic_cbin_ops.insert(ID($logic_and));
		config.generic_cbin_ops.insert(ID($logic_or));

		config.generic_other_ops.insert(ID($alu));
		config.generic_other_ops.insert(ID($macc));

		log_header(design, "Executing SHARE pass (SAT-based resource sharing).\n");

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++) {
			if (args[argidx] == "-force") {
				config.opt_force = true;
				continue;
			}
			if (args[argidx] == "-aggressive") {
				config.opt_aggressive = true;
				continue;
			}
			if (args[argidx] == "-fast") {
				config.opt_fast = true;
				continue;
			}
			if (args[argidx] == "-limit" && argidx+1 < args.size()) {
				config.limit = atoi(args[++argidx].c_str());
				continue;
			}
			break;
		}
		extra_args(args, argidx, design);

		for (auto &mod_it : design->modules_)
			if (design->selected(mod_it.second))
				ShareWorker(config, design, mod_it.second);
	}
} SharePass;

PRIVATE_NAMESPACE_END
