Fixed opt_clean performance bug

This commit is contained in:
Clifford Wolf 2015-02-04 16:34:06 +01:00
parent 853e949c0e
commit 8805c24640
1 changed files with 26 additions and 26 deletions

View File

@ -33,53 +33,53 @@ using RTLIL::id2cstr;
CellTypes ct, ct_reg, ct_all; CellTypes ct, ct_reg, ct_all;
int count_rm_cells, count_rm_wires; int count_rm_cells, count_rm_wires;
void rmunused_module_cells(RTLIL::Module *module, bool verbose) void rmunused_module_cells(Module *module, bool verbose)
{ {
SigMap sigmap(module); SigMap sigmap(module);
std::set<RTLIL::Cell*, RTLIL::sort_by_name_id<RTLIL::Cell>> queue, unused; pool<Cell*> queue, unused;
dict<SigBit, pool<Cell*>> wire2driver;
SigSet<RTLIL::Cell*> wire2driver;
for (auto &it : module->cells_) { for (auto &it : module->cells_) {
RTLIL::Cell *cell = it.second; Cell *cell = it.second;
for (auto &it2 : cell->connections()) { for (auto &it2 : cell->connections()) {
if (!ct.cell_input(cell->type, it2.first)) if (!ct.cell_input(cell->type, it2.first))
wire2driver.insert(sigmap(it2.second), cell); for (auto bit : sigmap(it2.second))
if (bit.wire != nullptr)
wire2driver[bit].insert(cell);
} }
if (cell->type == "$memwr" || cell->type == "$assert" || cell->has_keep_attr()) if (cell->type == "$memwr" || cell->type == "$assert" || cell->has_keep_attr())
queue.insert(cell); queue.insert(cell);
else
unused.insert(cell); unused.insert(cell);
} }
for (auto &it : module->wires_) { for (auto &it : module->wires_) {
RTLIL::Wire *wire = it.second; Wire *wire = it.second;
if (wire->port_output || wire->get_bool_attribute("\\keep")) { if (wire->port_output || wire->get_bool_attribute("\\keep")) {
pool<RTLIL::Cell*> cell_list; for (auto bit : sigmap(wire))
wire2driver.find(sigmap(wire), cell_list); for (auto c : wire2driver[bit])
for (auto cell : cell_list) queue.insert(c), unused.erase(c);
queue.insert(cell);
} }
} }
while (!queue.empty()) while (!queue.empty())
{ {
std::set<RTLIL::Cell*, RTLIL::sort_by_name_id<RTLIL::Cell>> new_queue; pool<SigBit> bits;
for (auto cell : queue) for (auto cell : queue)
unused.erase(cell); for (auto &it : cell->connections())
for (auto cell : queue) { if (!ct.cell_output(cell->type, it.first))
for (auto &it : cell->connections()) { for (auto bit : sigmap(it.second))
if (!ct.cell_output(cell->type, it.first)) { bits.insert(bit);
pool<RTLIL::Cell*> cell_list;
wire2driver.find(sigmap(it.second), cell_list); queue.clear();
for (auto c : cell_list) { for (auto bit : bits)
for (auto c : wire2driver[bit])
if (unused.count(c)) if (unused.count(c))
new_queue.insert(c); queue.insert(c), unused.erase(c);
}
}
}
}
queue.swap(new_queue);
} }
unused.sort(RTLIL::sort_by_name_id<RTLIL::Cell>());
for (auto cell : unused) { for (auto cell : unused) {
if (verbose) if (verbose)
log(" removing unused `%s' cell `%s'.\n", cell->type.c_str(), cell->name.c_str()); log(" removing unused `%s' cell `%s'.\n", cell->type.c_str(), cell->name.c_str());