aboutsummaryrefslogtreecommitdiffstats
path: root/passes/opt/opt_clean.cc
diff options
context:
space:
mode:
Diffstat (limited to 'passes/opt/opt_clean.cc')
-rw-r--r--passes/opt/opt_clean.cc66
1 files changed, 54 insertions, 12 deletions
diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc
index f7de02164..883374cf6 100644
--- a/passes/opt/opt_clean.cc
+++ b/passes/opt/opt_clean.cc
@@ -59,6 +59,11 @@ struct keep_cache_t
found_keep = true;
break;
}
+ for (auto wire : module->wires())
+ if (wire->get_bool_attribute(ID::keep)) {
+ found_keep = true;
+ break;
+ }
cache[module] = found_keep;
}
@@ -67,7 +72,7 @@ struct keep_cache_t
bool query(Cell *cell, bool ignore_specify = false)
{
- if (cell->type.in(ID($memwr), ID($meminit), ID($assert), ID($assume), ID($live), ID($fair), ID($cover)))
+ if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover)))
return true;
if (!ignore_specify && cell->type.in(ID($specify2), ID($specify3), ID($specrule)))
@@ -90,6 +95,8 @@ int count_rm_cells, count_rm_wires;
void rmunused_module_cells(Module *module, bool verbose)
{
SigMap sigmap(module);
+ dict<IdString, pool<Cell*>> mem2cells;
+ pool<IdString> mem_unused;
pool<Cell*> queue, unused;
pool<SigBit> used_raw_bits;
dict<SigBit, pool<Cell*>> wire2driver;
@@ -103,6 +110,17 @@ void rmunused_module_cells(Module *module, bool verbose)
}
}
+ for (auto &it : module->memories) {
+ mem_unused.insert(it.first);
+ }
+
+ for (Cell *cell : module->cells()) {
+ if (cell->type.in(ID($memwr), ID($meminit))) {
+ IdString mem_id = cell->getParam(ID::MEMID).decode_string();
+ mem2cells[mem_id].insert(cell);
+ }
+ }
+
for (auto &it : module->cells_) {
Cell *cell = it.second;
for (auto &it2 : cell->connections()) {
@@ -140,17 +158,33 @@ void rmunused_module_cells(Module *module, bool verbose)
while (!queue.empty())
{
pool<SigBit> bits;
- for (auto cell : queue)
- for (auto &it : cell->connections())
- if (!ct_all.cell_known(cell->type) || ct_all.cell_input(cell->type, it.first))
- for (auto bit : sigmap(it.second))
- bits.insert(bit);
+ pool<IdString> mems;
+ for (auto cell : queue) {
+ for (auto &it : cell->connections())
+ if (!ct_all.cell_known(cell->type) || ct_all.cell_input(cell->type, it.first))
+ for (auto bit : sigmap(it.second))
+ bits.insert(bit);
+
+ if (cell->type == ID($memrd)) {
+ IdString mem_id = cell->getParam(ID::MEMID).decode_string();
+ if (mem_unused.count(mem_id)) {
+ mem_unused.erase(mem_id);
+ mems.insert(mem_id);
+ }
+ }
+ }
queue.clear();
+
for (auto bit : bits)
for (auto c : wire2driver[bit])
if (unused.count(c))
queue.insert(c), unused.erase(c);
+
+ for (auto mem : mems)
+ for (auto c : mem2cells[mem])
+ if (unused.count(c))
+ queue.insert(c), unused.erase(c);
}
unused.sort(RTLIL::sort_by_name_id<RTLIL::Cell>());
@@ -163,6 +197,14 @@ void rmunused_module_cells(Module *module, bool verbose)
count_rm_cells++;
}
+ for (auto it : mem_unused)
+ {
+ if (verbose)
+ log_debug(" removing unused memory `%s'.\n", it.c_str());
+ delete module->memories.at(it);
+ module->memories.erase(it);
+ }
+
for (auto &it : module->cells_) {
Cell *cell = it.second;
for (auto &it2 : cell->connections()) {
@@ -202,7 +244,7 @@ bool compare_signals(RTLIL::SigBit &s1, RTLIL::SigBit &s2, SigPool &regs, SigPoo
if ((w1->port_input && w1->port_output) != (w2->port_input && w2->port_output))
return !(w2->port_input && w2->port_output);
- if (w1->name[0] == '\\' && w2->name[0] == '\\') {
+ if (w1->name.isPublic() && w2->name.isPublic()) {
if (regs.check(s1) != regs.check(s2))
return regs.check(s2);
if (direct_wires.count(w1) != direct_wires.count(w2))
@@ -215,7 +257,7 @@ bool compare_signals(RTLIL::SigBit &s1, RTLIL::SigBit &s2, SigPool &regs, SigPoo
return w2->port_output;
if (w1->name[0] != w2->name[0])
- return w2->name[0] == '\\';
+ return w2->name.isPublic();
int attrs1 = count_nontrivial_wire_attrs(w1);
int attrs2 = count_nontrivial_wire_attrs(w2);
@@ -526,7 +568,7 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool
struct OptCleanPass : public Pass {
OptCleanPass() : Pass("opt_clean", "remove unused cells and wires") { }
- void help() YS_OVERRIDE
+ void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
@@ -543,7 +585,7 @@ struct OptCleanPass : public Pass {
log(" also remove internal nets if they have a public name\n");
log("\n");
}
- void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
bool purge_mode = false;
@@ -592,7 +634,7 @@ struct OptCleanPass : public Pass {
struct CleanPass : public Pass {
CleanPass() : Pass("clean", "remove unused cells and wires") { }
- void help() YS_OVERRIDE
+ void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
@@ -607,7 +649,7 @@ struct CleanPass : public Pass {
log("in -purge mode between the commands.\n");
log("\n");
}
- void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
+ void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
bool purge_mode = false;