diff options
author | Marcelina KoĆcielnicka <mwk@0x04.net> | 2020-10-08 13:33:47 +0200 |
---|---|---|
committer | Marcelina KoĆcielnicka <mwk@0x04.net> | 2020-10-08 18:05:51 +0200 |
commit | 7670a89e1fde7d0774695ab81031a90fafdf56b9 (patch) | |
tree | 063e90c411b1e76e395460c27402a9a504b7f00d /passes/opt | |
parent | fd306b0520ac42323cbfacfa3a41e7a7a9379ec0 (diff) | |
download | yosys-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.cc | 53 |
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()) { |