/*
 *  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/register.h"
#include "kernel/sigtools.h"
#include "kernel/log.h"
#include "libs/subcircuit/subcircuit.h"
#include <algorithm>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

using RTLIL::id2cstr;

class SubCircuitSolver : public SubCircuit::Solver
{
public:
	bool ignore_parameters;
	std::set<std::pair<RTLIL::IdString, RTLIL::IdString>> ignored_parameters;
	std::set<RTLIL::IdString> cell_attr, wire_attr;

	SubCircuitSolver() : ignore_parameters(false)
	{
	}

	bool compareAttributes(const std::set<RTLIL::IdString> &attr, const dict<RTLIL::IdString, RTLIL::Const> &needleAttr, const dict<RTLIL::IdString, RTLIL::Const> &haystackAttr)
	{
		for (auto &it : attr) {
			size_t nc = needleAttr.count(it), hc = haystackAttr.count(it);
			if (nc != hc || (nc > 0 && needleAttr.at(it) != haystackAttr.at(it)))
				return false;
		}
		return true;
	}

	RTLIL::Const unified_param(RTLIL::IdString cell_type, RTLIL::IdString param, RTLIL::Const value)
	{
		if (!cell_type.begins_with("$") || cell_type.begins_with("$_"))
			return value;

	#define param_bool(_n) if (param == _n) return value.as_bool();
		param_bool(ID(ARST_POLARITY));
		param_bool(ID(A_SIGNED));
		param_bool(ID(B_SIGNED));
		param_bool(ID(CLK_ENABLE));
		param_bool(ID(CLK_POLARITY));
		param_bool(ID(CLR_POLARITY));
		param_bool(ID(EN_POLARITY));
		param_bool(ID(SET_POLARITY));
		param_bool(ID(TRANSPARENT));
	#undef param_bool

	#define param_int(_n) if (param == _n) return value.as_int();
		param_int(ID(ABITS))
		param_int(ID(A_WIDTH))
		param_int(ID(B_WIDTH))
		param_int(ID(CTRL_IN_WIDTH))
		param_int(ID(CTRL_OUT_WIDTH))
		param_int(ID(OFFSET))
		param_int(ID(PRIORITY))
		param_int(ID(RD_PORTS))
		param_int(ID(SIZE))
		param_int(ID(STATE_BITS))
		param_int(ID(STATE_NUM))
		param_int(ID(STATE_NUM_LOG2))
		param_int(ID(STATE_RST))
		param_int(ID(S_WIDTH))
		param_int(ID(TRANS_NUM))
		param_int(ID(WIDTH))
		param_int(ID(WR_PORTS))
		param_int(ID(Y_WIDTH))
	#undef param_int

		return value;
	}

	virtual bool userCompareNodes(const std::string &, const std::string &, void *needleUserData,
			const std::string &, const std::string &, void *haystackUserData, const std::map<std::string, std::string> &portMapping)
	{
		RTLIL::Cell *needleCell = (RTLIL::Cell*) needleUserData;
		RTLIL::Cell *haystackCell = (RTLIL::Cell*) haystackUserData;

		if (!needleCell || !haystackCell) {
			log_assert(!needleCell && !haystackCell);
			return true;
		}

		if (!ignore_parameters) {
			std::map<RTLIL::IdString, RTLIL::Const> needle_param, haystack_param;
			for (auto &it : needleCell->parameters)
				if (!ignored_parameters.count(std::pair<RTLIL::IdString, RTLIL::IdString>(needleCell->type, it.first)))
					needle_param[it.first] = unified_param(needleCell->type, it.first, it.second);
			for (auto &it : haystackCell->parameters)
				if (!ignored_parameters.count(std::pair<RTLIL::IdString, RTLIL::IdString>(haystackCell->type, it.first)))
					haystack_param[it.first] = unified_param(haystackCell->type, it.first, it.second);
			if (needle_param != haystack_param)
				return false;
		}

		if (cell_attr.size() > 0 && !compareAttributes(cell_attr, needleCell->attributes, haystackCell->attributes))
			return false;

		if (wire_attr.size() > 0)
		{
			RTLIL::Wire *lastNeedleWire = NULL;
			RTLIL::Wire *lastHaystackWire = NULL;
			dict<RTLIL::IdString, RTLIL::Const> emptyAttr;

			for (auto &conn : needleCell->connections())
			{
				RTLIL::SigSpec needleSig = conn.second;
				RTLIL::SigSpec haystackSig = haystackCell->getPort(portMapping.at(conn.first.str()));

				for (int i = 0; i < min(needleSig.size(), haystackSig.size()); i++) {
					RTLIL::Wire *needleWire = needleSig[i].wire, *haystackWire = haystackSig[i].wire;
					if (needleWire != lastNeedleWire || haystackWire != lastHaystackWire)
						if (!compareAttributes(wire_attr, needleWire ? needleWire->attributes : emptyAttr, haystackWire ? haystackWire->attributes : emptyAttr))
							return false;
					lastNeedleWire = needleWire, lastHaystackWire = haystackWire;
				}
			}
		}

		return true;
	}
};

struct bit_ref_t {
	std::string cell, port;
	int bit;
};

bool module2graph(SubCircuit::Graph &graph, RTLIL::Module *mod, bool constports, RTLIL::Design *sel = NULL,
		int max_fanout = -1, std::set<std::pair<RTLIL::IdString, RTLIL::IdString>> *split = NULL)
{
	SigMap sigmap(mod);
	std::map<RTLIL::SigBit, bit_ref_t> sig_bit_ref;

	if (sel && !sel->selected(mod)) {
		log("  Skipping module %s as it is not selected.\n", id2cstr(mod->name));
		return false;
	}

	if (mod->processes.size() > 0) {
		log("  Skipping module %s as it contains unprocessed processes.\n", id2cstr(mod->name));
		return false;
	}

	if (constports) {
		graph.createNode("$const$0", "$const$0", NULL, true);
		graph.createNode("$const$1", "$const$1", NULL, true);
		graph.createNode("$const$x", "$const$x", NULL, true);
		graph.createNode("$const$z", "$const$z", NULL, true);
		graph.createPort("$const$0", "\\Y", 1);
		graph.createPort("$const$1", "\\Y", 1);
		graph.createPort("$const$x", "\\Y", 1);
		graph.createPort("$const$z", "\\Y", 1);
		graph.markExtern("$const$0", "\\Y", 0);
		graph.markExtern("$const$1", "\\Y", 0);
		graph.markExtern("$const$x", "\\Y", 0);
		graph.markExtern("$const$z", "\\Y", 0);
	}

	std::map<std::pair<RTLIL::Wire*, int>, int> sig_use_count;
	if (max_fanout > 0)
		for (auto &cell_it : mod->cells_)
		{
			RTLIL::Cell *cell = cell_it.second;
			if (!sel || sel->selected(mod, cell))
				for (auto &conn : cell->connections()) {
					RTLIL::SigSpec conn_sig = conn.second;
					sigmap.apply(conn_sig);
					for (auto &bit : conn_sig)
						if (bit.wire != NULL)
							sig_use_count[std::pair<RTLIL::Wire*, int>(bit.wire, bit.offset)]++;
				}
		}

	// create graph nodes from cells
	for (auto &cell_it : mod->cells_)
	{
		RTLIL::Cell *cell = cell_it.second;
		if (sel && !sel->selected(mod, cell))
			continue;

		std::string type = cell->type.str();
		if (sel == NULL && type.compare(0, 2, "\\$") == 0)
			type = type.substr(1);
		graph.createNode(cell->name.str(), type, (void*)cell);

		for (auto &conn : cell->connections())
		{
			graph.createPort(cell->name.str(), conn.first.str(), conn.second.size());

			if (split && split->count(std::pair<RTLIL::IdString, RTLIL::IdString>(cell->type, conn.first)) > 0)
				continue;

			RTLIL::SigSpec conn_sig = conn.second;
			sigmap.apply(conn_sig);

			for (int i = 0; i < conn_sig.size(); i++)
			{
				auto &bit = conn_sig[i];

				if (bit.wire == NULL) {
					if (constports) {
						std::string node = "$const$x";
						if (bit == RTLIL::State::S0) node = "$const$0";
						if (bit == RTLIL::State::S1) node = "$const$1";
						if (bit == RTLIL::State::Sz) node = "$const$z";
						graph.createConnection(cell->name.str(), conn.first.str(), i, node, "\\Y", 0);
					} else
						graph.createConstant(cell->name.str(), conn.first.str(), i, int(bit.data));
					continue;
				}

				if (max_fanout > 0 && sig_use_count[std::pair<RTLIL::Wire*, int>(bit.wire, bit.offset)] > max_fanout)
					continue;

				if (sel && !sel->selected(mod, bit.wire))
					continue;

				if (sig_bit_ref.count(bit) == 0) {
					bit_ref_t &bit_ref = sig_bit_ref[bit];
					bit_ref.cell = cell->name.str();
					bit_ref.port = conn.first.str();
					bit_ref.bit = i;
				}

				bit_ref_t &bit_ref = sig_bit_ref[bit];
				graph.createConnection(bit_ref.cell, bit_ref.port, bit_ref.bit, cell->name.str(), conn.first.str(), i);
			}
		}
	}

	// mark external signals (used in non-selected cells)
	for (auto &cell_it : mod->cells_)
	{
		RTLIL::Cell *cell = cell_it.second;
		if (sel && !sel->selected(mod, cell))
			for (auto &conn : cell->connections())
			{
				RTLIL::SigSpec conn_sig = conn.second;
				sigmap.apply(conn_sig);

				for (auto &bit : conn_sig)
					if (sig_bit_ref.count(bit) != 0) {
						bit_ref_t &bit_ref = sig_bit_ref[bit];
						graph.markExtern(bit_ref.cell, bit_ref.port, bit_ref.bit);
					}
			}
	}

	// mark external signals (used in module ports)
	for (auto &wire_it : mod->wires_)
	{
		RTLIL::Wire *wire = wire_it.second;
		if (wire->port_id > 0)
		{
			RTLIL::SigSpec conn_sig(wire);
			sigmap.apply(conn_sig);

			for (auto &bit : conn_sig)
				if (sig_bit_ref.count(bit) != 0) {
					bit_ref_t &bit_ref = sig_bit_ref[bit];
					graph.markExtern(bit_ref.cell, bit_ref.port, bit_ref.bit);
				}
		}
	}

	// graph.print();
	return true;
}

RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit::Solver::Result &match)
{
	SigMap sigmap(needle);
	SigSet<std::pair<RTLIL::IdString, int>> sig2port;

	// create new cell
	RTLIL::Cell *cell = haystack->addCell(stringf("$extract$%s$%d", needle->name.c_str(), autoidx++), needle->name);

	// create cell ports
	for (auto &it : needle->wires_) {
		RTLIL::Wire *wire = it.second;
		if (wire->port_id > 0) {
			for (int i = 0; i < wire->width; i++)
				sig2port.insert(sigmap(RTLIL::SigSpec(wire, i)), std::pair<RTLIL::IdString, int>(wire->name, i));
			cell->setPort(wire->name, RTLIL::SigSpec(RTLIL::State::Sz, wire->width));
		}
	}

	// delete replaced cells and connect new ports
	for (auto &it : match.mappings)
	{
		auto &mapping = it.second;
		RTLIL::Cell *needle_cell = (RTLIL::Cell*)mapping.needleUserData;
		RTLIL::Cell *haystack_cell = (RTLIL::Cell*)mapping.haystackUserData;

		if (needle_cell == NULL)
			continue;

		for (auto &conn : needle_cell->connections()) {
			RTLIL::SigSpec sig = sigmap(conn.second);
			if (mapping.portMapping.count(conn.first.str()) > 0 && sig2port.has(sigmap(sig))) {
				for (int i = 0; i < sig.size(); i++)
				for (auto &port : sig2port.find(sig[i])) {
					RTLIL::SigSpec bitsig = haystack_cell->getPort(mapping.portMapping[conn.first.str()]).extract(i, 1);
					RTLIL::SigSpec new_sig = cell->getPort(port.first);
					new_sig.replace(port.second, bitsig);
					cell->setPort(port.first, new_sig);
				}
			}
		}

		haystack->remove(haystack_cell);
	}

	return cell;
}

bool compareSortNeedleList(RTLIL::Module *left, RTLIL::Module *right)
{
	int left_idx = 0, right_idx = 0;
	if (left->attributes.count(ID(extract_order)) > 0)
		left_idx = left->attributes.at(ID(extract_order)).as_int();
	if (right->attributes.count(ID(extract_order)) > 0)
		right_idx = right->attributes.at(ID(extract_order)).as_int();
	if (left_idx != right_idx)
		return left_idx < right_idx;
	return left->name < right->name;
}

struct ExtractPass : public Pass {
	ExtractPass() : Pass("extract", "find subcircuits and replace them with cells") { }
	void help() YS_OVERRIDE
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    extract -map <map_file> [options] [selection]\n");
		log("    extract -mine <out_file> [options] [selection]\n");
		log("\n");
		log("This pass looks for subcircuits that are isomorphic to any of the modules\n");
		log("in the given map file and replaces them with instances of this modules. The\n");
		log("map file can be a Verilog source file (*.v) or an ilang file (*.il).\n");
		log("\n");
		log("    -map <map_file>\n");
		log("        use the modules in this file as reference. This option can be used\n");
		log("        multiple times.\n");
		log("\n");
		log("    -map %%<design-name>\n");
		log("        use the modules in this in-memory design as reference. This option can\n");
		log("        be used multiple times.\n");
		log("\n");
		log("    -verbose\n");
		log("        print debug output while analyzing\n");
		log("\n");
		log("    -constports\n");
		log("        also find instances with constant drivers. this may be much\n");
		log("        slower than the normal operation.\n");
		log("\n");
		log("    -nodefaultswaps\n");
		log("        normally builtin port swapping rules for internal cells are used per\n");
		log("        default. This turns that off, so e.g. 'a^b' does not match 'b^a'\n");
		log("        when this option is used.\n");
		log("\n");
		log("    -compat <needle_type> <haystack_type>\n");
		log("        Per default, the cells in the map file (needle) must have the\n");
		log("        type as the cells in the active design (haystack). This option\n");
		log("        can be used to register additional pairs of types that should\n");
		log("        match. This option can be used multiple times.\n");
		log("\n");
		log("    -swap <needle_type> <port1>,<port2>[,...]\n");
		log("        Register a set of swappable ports for a needle cell type.\n");
		log("        This option can be used multiple times.\n");
		log("\n");
		log("    -perm <needle_type> <port1>,<port2>[,...] <portA>,<portB>[,...]\n");
		log("        Register a valid permutation of swappable ports for a needle\n");
		log("        cell type. This option can be used multiple times.\n");
		log("\n");
		log("    -cell_attr <attribute_name>\n");
		log("        Attributes on cells with the given name must match.\n");
		log("\n");
		log("    -wire_attr <attribute_name>\n");
		log("        Attributes on wires with the given name must match.\n");
		log("\n");
		log("    -ignore_parameters\n");
		log("        Do not use parameters when matching cells.\n");
		log("\n");
		log("    -ignore_param <cell_type> <parameter_name>\n");
		log("        Do not use this parameter when matching cells.\n");
		log("\n");
		log("This pass does not operate on modules with unprocessed processes in it.\n");
		log("(I.e. the 'proc' pass should be used first to convert processes to netlists.)\n");
		log("\n");
		log("This pass can also be used for mining for frequent subcircuits. In this mode\n");
		log("the following options are to be used instead of the -map option.\n");
		log("\n");
		log("    -mine <out_file>\n");
		log("        mine for frequent subcircuits and write them to the given ilang file\n");
		log("\n");
		log("    -mine_cells_span <min> <max>\n");
		log("        only mine for subcircuits with the specified number of cells\n");
		log("        default value: 3 5\n");
		log("\n");
		log("    -mine_min_freq <num>\n");
		log("        only mine for subcircuits with at least the specified number of matches\n");
		log("        default value: 10\n");
		log("\n");
		log("    -mine_limit_matches_per_module <num>\n");
		log("        when calculating the number of matches for a subcircuit, don't count\n");
		log("        more than the specified number of matches per module\n");
		log("\n");
		log("    -mine_max_fanout <num>\n");
		log("        don't consider internal signals with more than <num> connections\n");
		log("\n");
		log("The modules in the map file may have the attribute 'extract_order' set to an\n");
		log("integer value. Then this value is used to determine the order in which the pass\n");
		log("tries to map the modules to the design (ascending, default value is 0).\n");
		log("\n");
		log("See 'help techmap' for a pass that does the opposite thing.\n");
		log("\n");
	}
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
	{
		log_header(design, "Executing EXTRACT pass (map subcircuits to cells).\n");
		log_push();

		SubCircuitSolver solver;

		std::vector<std::string> map_filenames;
		std::string mine_outfile;
		bool constports = false;
		bool nodefaultswaps = false;

		bool mine_mode = false;
		int mine_cells_min = 3;
		int mine_cells_max = 5;
		int mine_min_freq = 10;
		int mine_limit_mod = -1;
		int mine_max_fanout = -1;
		std::set<std::pair<RTLIL::IdString, RTLIL::IdString>> mine_split;

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++) {
			if (args[argidx] == "-map" && argidx+1 < args.size()) {
				if (mine_mode)
					log_cmd_error("You cannot mix -map and -mine.\n");
				map_filenames.push_back(args[++argidx]);
				continue;
			}
			if (args[argidx] == "-mine" && argidx+1 < args.size()) {
				if (!map_filenames.empty())
					log_cmd_error("You cannot mix -map and -mine.\n");
				mine_outfile = args[++argidx];
				mine_mode = true;
				continue;
			}
			if (args[argidx] == "-mine_cells_span" && argidx+2 < args.size()) {
				mine_cells_min = atoi(args[++argidx].c_str());
				mine_cells_max = atoi(args[++argidx].c_str());
				continue;
			}
			if (args[argidx] == "-mine_min_freq" && argidx+1 < args.size()) {
				mine_min_freq = atoi(args[++argidx].c_str());
				continue;
			}
			if (args[argidx] == "-mine_limit_matches_per_module" && argidx+1 < args.size()) {
				mine_limit_mod = atoi(args[++argidx].c_str());
				continue;
			}
			if (args[argidx] == "-mine_split" && argidx+2 < args.size()) {
				mine_split.insert(std::pair<RTLIL::IdString, RTLIL::IdString>(RTLIL::escape_id(args[argidx+1]), RTLIL::escape_id(args[argidx+2])));
				argidx += 2;
				continue;
			}
			if (args[argidx] == "-mine_max_fanout" && argidx+1 < args.size()) {
				mine_max_fanout = atoi(args[++argidx].c_str());
				continue;
			}
			if (args[argidx] == "-verbose") {
				solver.setVerbose();
				continue;
			}
			if (args[argidx] == "-constports") {
				constports = true;
				continue;
			}
			if (args[argidx] == "-nodefaultswaps") {
				nodefaultswaps = true;
				continue;
			}
			if (args[argidx] == "-compat" && argidx+2 < args.size()) {
				std::string needle_type = RTLIL::escape_id(args[++argidx]);
				std::string haystack_type = RTLIL::escape_id(args[++argidx]);
				solver.addCompatibleTypes(needle_type, haystack_type);
				continue;
			}
			if (args[argidx] == "-swap" && argidx+2 < args.size()) {
				std::string type = RTLIL::escape_id(args[++argidx]);
				std::set<std::string> ports;
				std::string ports_str = args[++argidx], p;
				while (!(p = next_token(ports_str, ",\t\r\n ")).empty())
					ports.insert(RTLIL::escape_id(p));
				solver.addSwappablePorts(type, ports);
				continue;
			}
			if (args[argidx] == "-perm" && argidx+3 < args.size()) {
				std::string type = RTLIL::escape_id(args[++argidx]);
				std::vector<std::string> map_left, map_right;
				std::string left_str = args[++argidx];
				std::string right_str = args[++argidx], p;
				while (!(p = next_token(left_str, ",\t\r\n ")).empty())
					map_left.push_back(RTLIL::escape_id(p));
				while (!(p = next_token(right_str, ",\t\r\n ")).empty())
					map_right.push_back(RTLIL::escape_id(p));
				if (map_left.size() != map_right.size())
					log_cmd_error("Arguments to -perm are not a valid permutation!\n");
				std::map<std::string, std::string> map;
				for (size_t i = 0; i < map_left.size(); i++)
					map[map_left[i]] = map_right[i];
				std::sort(map_left.begin(), map_left.end());
				std::sort(map_right.begin(), map_right.end());
				if (map_left != map_right)
					log_cmd_error("Arguments to -perm are not a valid permutation!\n");
				solver.addSwappablePortsPermutation(type, map);
				continue;
			}
			if (args[argidx] == "-cell_attr" && argidx+1 < args.size()) {
				solver.cell_attr.insert(RTLIL::escape_id(args[++argidx]));
				continue;
			}
			if (args[argidx] == "-wire_attr" && argidx+1 < args.size()) {
				solver.wire_attr.insert(RTLIL::escape_id(args[++argidx]));
				continue;
			}
			if (args[argidx] == "-ignore_parameters") {
				solver.ignore_parameters = true;
				continue;
			}
			if (args[argidx] == "-ignore_param" && argidx+2 < args.size()) {
				solver.ignored_parameters.insert(std::pair<RTLIL::IdString, RTLIL::IdString>(RTLIL::escape_id(args[argidx+1]), RTLIL::escape_id(args[argidx+2])));
				argidx += 2;
				continue;
			}
			break;
		}
		extra_args(args, argidx, design);

		if (!nodefaultswaps) {
			solver.addSwappablePorts("$and",       "\\A", "\\B");
			solver.addSwappablePorts("$or",        "\\A", "\\B");
			solver.addSwappablePorts("$xor",       "\\A", "\\B");
			solver.addSwappablePorts("$xnor",      "\\A", "\\B");
			solver.addSwappablePorts("$eq",        "\\A", "\\B");
			solver.addSwappablePorts("$ne",        "\\A", "\\B");
			solver.addSwappablePorts("$eqx",       "\\A", "\\B");
			solver.addSwappablePorts("$nex",       "\\A", "\\B");
			solver.addSwappablePorts("$add",       "\\A", "\\B");
			solver.addSwappablePorts("$mul",       "\\A", "\\B");
			solver.addSwappablePorts("$logic_and", "\\A", "\\B");
			solver.addSwappablePorts("$logic_or",  "\\A", "\\B");
			solver.addSwappablePorts("$_AND_",     "\\A", "\\B");
			solver.addSwappablePorts("$_OR_",      "\\A", "\\B");
			solver.addSwappablePorts("$_XOR_",     "\\A", "\\B");
		}

		if (map_filenames.empty() && mine_outfile.empty())
			log_cmd_error("Missing option -map <verilog_or_ilang_file> or -mine <output_ilang_file>.\n");

		RTLIL::Design *map = NULL;

		if (!mine_mode)
		{
			map = new RTLIL::Design;
			for (auto &filename : map_filenames)
			{
				if (filename.compare(0, 1, "%") == 0)
				{
					if (!saved_designs.count(filename.substr(1))) {
						delete map;
						log_cmd_error("Can't saved design `%s'.\n", filename.c_str()+1);
					}
					for (auto mod : saved_designs.at(filename.substr(1))->modules())
						if (!map->has(mod->name))
							map->add(mod->clone());
				}
				else
				{
					std::ifstream f;
					rewrite_filename(filename);
					f.open(filename.c_str());
					if (f.fail()) {
						delete map;
						log_cmd_error("Can't open map file `%s'.\n", filename.c_str());
					}
					Frontend::frontend_call(map, &f, filename, (filename.size() > 3 && filename.compare(filename.size()-3, std::string::npos, ".il") == 0 ? "ilang" : "verilog"));
					f.close();

					if (filename.size() <= 3 || filename.compare(filename.size()-3, std::string::npos, ".il") != 0) {
						Pass::call(map, "proc");
						Pass::call(map, "opt_clean");
					}
				}
			}
		}

		std::map<std::string, RTLIL::Module*> needle_map, haystack_map;
		std::vector<RTLIL::Module*> needle_list;

		log_header(design, "Creating graphs for SubCircuit library.\n");

		if (!mine_mode)
			for (auto &mod_it : map->modules_) {
				SubCircuit::Graph mod_graph;
				std::string graph_name = "needle_" + RTLIL::unescape_id(mod_it.first);
				log("Creating needle graph %s.\n", graph_name.c_str());
				if (module2graph(mod_graph, mod_it.second, constports)) {
					solver.addGraph(graph_name, mod_graph);
					needle_map[graph_name] = mod_it.second;
					needle_list.push_back(mod_it.second);
				}
			}

		for (auto &mod_it : design->modules_) {
			SubCircuit::Graph mod_graph;
			std::string graph_name = "haystack_" + RTLIL::unescape_id(mod_it.first);
			log("Creating haystack graph %s.\n", graph_name.c_str());
			if (module2graph(mod_graph, mod_it.second, constports, design, mine_mode ? mine_max_fanout : -1, mine_mode ? &mine_split : NULL)) {
				solver.addGraph(graph_name, mod_graph);
				haystack_map[graph_name] = mod_it.second;
			}
		}

		if (!mine_mode)
		{
			std::vector<SubCircuit::Solver::Result> results;
			log_header(design, "Running solver from SubCircuit library.\n");

			std::sort(needle_list.begin(), needle_list.end(), compareSortNeedleList);

			for (auto needle : needle_list)
			for (auto &haystack_it : haystack_map) {
				log("Solving for %s in %s.\n", ("needle_" + RTLIL::unescape_id(needle->name)).c_str(), haystack_it.first.c_str());
				solver.solve(results, "needle_" + RTLIL::unescape_id(needle->name), haystack_it.first, false);
			}
			log("Found %d matches.\n", GetSize(results));

			if (results.size() > 0)
			{
				log_header(design, "Substitute SubCircuits with cells.\n");

				for (int i = 0; i < int(results.size()); i++) {
					auto &result = results[i];
					log("\nMatch #%d: (%s in %s)\n", i, result.needleGraphId.c_str(), result.haystackGraphId.c_str());
					for (const auto &it : result.mappings) {
						log("  %s -> %s", it.first.c_str(), it.second.haystackNodeId.c_str());
						for (const auto & it2 : it.second.portMapping)
							log(" %s:%s", it2.first.c_str(), it2.second.c_str());
						log("\n");
					}
					RTLIL::Cell *new_cell = replace(needle_map.at(result.needleGraphId), haystack_map.at(result.haystackGraphId), result);
					design->select(haystack_map.at(result.haystackGraphId), new_cell);
					log("  new cell: %s\n", id2cstr(new_cell->name));
				}
			}
		}
		else
		{
			std::vector<SubCircuit::Solver::MineResult> results;

			log_header(design, "Running miner from SubCircuit library.\n");
			solver.mine(results, mine_cells_min, mine_cells_max, mine_min_freq, mine_limit_mod);

			map = new RTLIL::Design;

			int needleCounter = 0;
			for (auto &result: results)
			{
				log("\nFrequent SubCircuit with %d nodes and %d matches:\n", int(result.nodes.size()), result.totalMatchesAfterLimits);
				log("  primary match in %s:", id2cstr(haystack_map.at(result.graphId)->name));
				for (auto &node : result.nodes)
					log(" %s", RTLIL::unescape_id(node.nodeId).c_str());
				log("\n");
				for (auto &it : result.matchesPerGraph)
					log("  matches in %s: %d\n", id2cstr(haystack_map.at(it.first)->name), it.second);

				RTLIL::Module *mod = haystack_map.at(result.graphId);
				std::set<RTLIL::Cell*> cells;
				std::set<RTLIL::Wire*> wires;

				SigMap sigmap(mod);

				for (auto &node : result.nodes)
					cells.insert((RTLIL::Cell*)node.userData);

				for (auto cell : cells)
				for (auto &conn : cell->connections()) {
					RTLIL::SigSpec sig = sigmap(conn.second);
					for (auto &chunk : sig.chunks())
						if (chunk.wire != NULL)
							wires.insert(chunk.wire);
				}

				RTLIL::Module *newMod = new RTLIL::Module;
				newMod->name = stringf("\\needle%05d_%s_%dx", needleCounter++, id2cstr(haystack_map.at(result.graphId)->name), result.totalMatchesAfterLimits);
				map->add(newMod);

				for (auto wire : wires) {
					RTLIL::Wire *newWire = newMod->addWire(wire->name, wire->width);
					newWire->port_input = true;
					newWire->port_output = true;
				}

				newMod->fixup_ports();

				for (auto cell : cells) {
					RTLIL::Cell *newCell = newMod->addCell(cell->name, cell->type);
					newCell->parameters = cell->parameters;
					for (auto &conn : cell->connections()) {
						std::vector<SigChunk> chunks = sigmap(conn.second);
						for (auto &chunk : chunks)
							if (chunk.wire != NULL)
								chunk.wire = newMod->wires_.at(chunk.wire->name);
						newCell->setPort(conn.first, chunks);
					}
				}
			}

			std::ofstream f;
			rewrite_filename(mine_outfile);
			f.open(mine_outfile.c_str(), std::ofstream::trunc);
			if (f.fail())
				log_error("Can't open output file `%s'.\n", mine_outfile.c_str());
			Backend::backend_call(map, &f, mine_outfile, "ilang");
			f.close();
		}

		delete map;
		log_pop();
	}
} ExtractPass;

PRIVATE_NAMESPACE_END
