aboutsummaryrefslogtreecommitdiffstats
path: root/passes/opt
diff options
context:
space:
mode:
authorMarcelina Koƛcielnicka <mwk@0x04.net>2020-10-08 13:33:47 +0200
committerMarcelina Koƛcielnicka <mwk@0x04.net>2020-10-08 18:05:51 +0200
commit7670a89e1fde7d0774695ab81031a90fafdf56b9 (patch)
tree063e90c411b1e76e395460c27402a9a504b7f00d /passes/opt
parentfd306b0520ac42323cbfacfa3a41e7a7a9379ec0 (diff)
downloadyosys-7670a89e1fde7d0774695ab81031a90fafdf56b9.tar.gz
yosys-7670a89e1fde7d0774695ab81031a90fafdf56b9.tar.bz2
yosys-7670a89e1fde7d0774695ab81031a90fafdf56b9.zip
opt_clean: Better memory handling.
Previously, `$memwr` and `$meminit` cells were always preserved (along with the memory itself). With this change, they are instead part of the main cell mark-and-sweep pass: a memory (and its `$meminit` and `$memwr` cells) is only preserved iff any associated `$memrd` cell needs to be preserved.
Diffstat (limited to 'passes/opt')
-rw-r--r--passes/opt/opt_clean.cc53
1 files changed, 45 insertions, 8 deletions
diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc
index bd9856e81..883374cf6 100644
--- a/passes/opt/opt_clean.cc
+++ b/passes/opt/opt_clean.cc
@@ -55,7 +55,7 @@ struct keep_cache_t
if (!module->get_bool_attribute(ID::keep)) {
bool found_keep = false;
for (auto cell : module->cells())
- if (query(cell, true /* ignore_specify_mem */)) {
+ if (query(cell, true /* ignore_specify */)) {
found_keep = true;
break;
}
@@ -70,12 +70,12 @@ struct keep_cache_t
return cache[module];
}
- bool query(Cell *cell, bool ignore_specify_mem = false)
+ bool query(Cell *cell, bool ignore_specify = false)
{
if (cell->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover)))
return true;
- if (!ignore_specify_mem && cell->type.in(ID($memwr), ID($meminit), ID($specify2), ID($specify3), ID($specrule)))
+ if (!ignore_specify && cell->type.in(ID($specify2), ID($specify3), ID($specrule)))
return true;
if (cell->has_keep_attr())
@@ -95,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;
@@ -108,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()) {
@@ -145,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>());
@@ -168,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()) {