diff options
author | Clifford Wolf <clifford@clifford.at> | 2019-05-15 21:00:56 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-15 21:00:56 +0200 |
commit | c9def5407cd59e8542201217c890bbe4c89fff5c (patch) | |
tree | 8bcd4e44241c57766114f826e5c5fe7790dda85a | |
parent | f67ec1b2350c3bd88edacba7ad799bf60b33da61 (diff) | |
parent | a21a84b3b45d252ff050d3ae7e738d157b0b2be8 (diff) | |
download | yosys-c9def5407cd59e8542201217c890bbe4c89fff5c.tar.gz yosys-c9def5407cd59e8542201217c890bbe4c89fff5c.tar.bz2 yosys-c9def5407cd59e8542201217c890bbe4c89fff5c.zip |
Merge pull request #1012 from YosysHQ/clifford/sigspecrw
Another rounds of opt_clean improvements
-rw-r--r-- | kernel/rtlil.cc | 29 | ||||
-rw-r--r-- | kernel/rtlil.h | 60 | ||||
-rw-r--r-- | passes/opt/opt_clean.cc | 20 |
3 files changed, 92 insertions, 17 deletions
diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 79ff4a6a6..790ba52a3 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -1514,7 +1514,10 @@ void RTLIL::Module::add(RTLIL::Cell *cell) cell->module = this; } -namespace { +void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires) +{ + log_assert(refcount_wires_ == 0); + struct DeleteWireWorker { RTLIL::Module *module; @@ -1529,17 +1532,29 @@ namespace { } sig = chunks; } - }; -} -void RTLIL::Module::remove(const pool<RTLIL::Wire*> &wires) -{ - log_assert(refcount_wires_ == 0); + void operator()(RTLIL::SigSpec &lhs, RTLIL::SigSpec &rhs) { + log_assert(GetSize(lhs) == GetSize(rhs)); + RTLIL::SigSpec new_lhs, new_rhs; + for (int i = 0; i < GetSize(lhs); i++) { + RTLIL::SigBit lhs_bit = lhs[i]; + if (lhs_bit.wire != nullptr && wires_p->count(lhs_bit.wire)) + continue; + RTLIL::SigBit rhs_bit = rhs[i]; + if (rhs_bit.wire != nullptr && wires_p->count(rhs_bit.wire)) + continue; + new_lhs.append(lhs_bit); + new_rhs.append(rhs_bit); + } + lhs = new_lhs; + rhs = new_rhs; + } + }; DeleteWireWorker delete_wire_worker; delete_wire_worker.module = this; delete_wire_worker.wires_p = &wires; - rewrite_sigspecs(delete_wire_worker); + rewrite_sigspecs2(delete_wire_worker); for (auto &it : wires) { log_assert(wires_.count(it->name) != 0); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index a0270bd1c..81ca93dce 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -1001,6 +1001,7 @@ public: void fixup_ports(); template<typename T> void rewrite_sigspecs(T &functor); + template<typename T> void rewrite_sigspecs2(T &functor); void cloneInto(RTLIL::Module *new_mod) const; virtual RTLIL::Module *clone() const; @@ -1306,6 +1307,7 @@ public: } template<typename T> void rewrite_sigspecs(T &functor); + template<typename T> void rewrite_sigspecs2(T &functor); #ifdef WITH_PYTHON static std::map<unsigned int, RTLIL::Cell*> *get_all_cells(void); @@ -1324,6 +1326,7 @@ struct RTLIL::CaseRule bool empty() const; template<typename T> void rewrite_sigspecs(T &functor); + template<typename T> void rewrite_sigspecs2(T &functor); RTLIL::CaseRule *clone() const; }; @@ -1337,6 +1340,7 @@ struct RTLIL::SwitchRule : public RTLIL::AttrObject bool empty() const; template<typename T> void rewrite_sigspecs(T &functor); + template<typename T> void rewrite_sigspecs2(T &functor); RTLIL::SwitchRule *clone() const; }; @@ -1347,6 +1351,7 @@ struct RTLIL::SyncRule std::vector<RTLIL::SigSig> actions; template<typename T> void rewrite_sigspecs(T &functor); + template<typename T> void rewrite_sigspecs2(T &functor); RTLIL::SyncRule *clone() const; }; @@ -1359,6 +1364,7 @@ struct RTLIL::Process : public RTLIL::AttrObject ~Process(); template<typename T> void rewrite_sigspecs(T &functor); + template<typename T> void rewrite_sigspecs2(T &functor); RTLIL::Process *clone() const; }; @@ -1421,12 +1427,30 @@ void RTLIL::Module::rewrite_sigspecs(T &functor) } template<typename T> +void RTLIL::Module::rewrite_sigspecs2(T &functor) +{ + for (auto &it : cells_) + it.second->rewrite_sigspecs2(functor); + for (auto &it : processes) + it.second->rewrite_sigspecs2(functor); + for (auto &it : connections_) { + functor(it.first, it.second); + } +} + +template<typename T> void RTLIL::Cell::rewrite_sigspecs(T &functor) { for (auto &it : connections_) functor(it.second); } template<typename T> +void RTLIL::Cell::rewrite_sigspecs2(T &functor) { + for (auto &it : connections_) + functor(it.second); +} + +template<typename T> void RTLIL::CaseRule::rewrite_sigspecs(T &functor) { for (auto &it : compare) functor(it); @@ -1439,6 +1463,17 @@ void RTLIL::CaseRule::rewrite_sigspecs(T &functor) { } template<typename T> +void RTLIL::CaseRule::rewrite_sigspecs2(T &functor) { + for (auto &it : compare) + functor(it); + for (auto &it : actions) { + functor(it.first, it.second); + } + for (auto it : switches) + it->rewrite_sigspecs2(functor); +} + +template<typename T> void RTLIL::SwitchRule::rewrite_sigspecs(T &functor) { functor(signal); @@ -1447,6 +1482,14 @@ void RTLIL::SwitchRule::rewrite_sigspecs(T &functor) } template<typename T> +void RTLIL::SwitchRule::rewrite_sigspecs2(T &functor) +{ + functor(signal); + for (auto it : cases) + it->rewrite_sigspecs2(functor); +} + +template<typename T> void RTLIL::SyncRule::rewrite_sigspecs(T &functor) { functor(signal); @@ -1457,6 +1500,15 @@ void RTLIL::SyncRule::rewrite_sigspecs(T &functor) } template<typename T> +void RTLIL::SyncRule::rewrite_sigspecs2(T &functor) +{ + functor(signal); + for (auto &it : actions) { + functor(it.first, it.second); + } +} + +template<typename T> void RTLIL::Process::rewrite_sigspecs(T &functor) { root_case.rewrite_sigspecs(functor); @@ -1464,6 +1516,14 @@ void RTLIL::Process::rewrite_sigspecs(T &functor) it->rewrite_sigspecs(functor); } +template<typename T> +void RTLIL::Process::rewrite_sigspecs2(T &functor) +{ + root_case.rewrite_sigspecs2(functor); + for (auto it : syncs) + it->rewrite_sigspecs2(functor); +} + YOSYS_NAMESPACE_END #endif diff --git a/passes/opt/opt_clean.cc b/passes/opt/opt_clean.cc index 6ca6ac820..bf8020169 100644 --- a/passes/opt/opt_clean.cc +++ b/passes/opt/opt_clean.cc @@ -232,7 +232,7 @@ bool check_public_name(RTLIL::IdString id) return true; } -void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbose) +bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbose) { SigPool register_signals; SigPool connected_signals; @@ -272,20 +272,17 @@ void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos } } - SigPool raw_used_signals_noaliases; - for (auto &it : module->connections_) - raw_used_signals_noaliases.add(it.second); - module->connections_.clear(); SigPool used_signals; + SigPool raw_used_signals; SigPool used_signals_nodrivers; for (auto &it : module->cells_) { RTLIL::Cell *cell = it.second; for (auto &it2 : cell->connections_) { assign_map.apply(it2.second); + raw_used_signals.add(it2.second); used_signals.add(it2.second); - raw_used_signals_noaliases.add(it2.second); if (!ct_all.cell_output(cell->type, it2.first)) used_signals_nodrivers.add(it2.second); } @@ -294,6 +291,7 @@ void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos RTLIL::Wire *wire = it.second; if (wire->port_id > 0) { RTLIL::SigSpec sig = RTLIL::SigSpec(wire); + raw_used_signals.add(sig); assign_map.apply(sig); used_signals.add(sig); if (!wire->port_input) @@ -330,11 +328,11 @@ void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos if (!purge_mode && check_public_name(wire->name)) { // do not get rid of public names unless in purge mode } else - if (!raw_used_signals_noaliases.check_any(s1)) { + if (!raw_used_signals.check_any(s1)) { // delete wires that aren't used by anything directly goto delete_this_wire; } else - if (!used_signals_nodrivers.check_any(s2)) { + if (!used_signals.check_any(s2)) { // delete wires that aren't used by anything indirectly, even though other wires may alias it goto delete_this_wire; } @@ -400,6 +398,8 @@ void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos if (verbose && del_temp_wires_count) log_debug(" removed %d unused temporary wires.\n", del_temp_wires_count); + + return !del_wires_queue.empty(); } bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose) @@ -497,10 +497,10 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool module->design->scratchpad_set_bool("opt.did_something", true); rmunused_module_cells(module, verbose); - rmunused_module_signals(module, purge_mode, verbose); + while (rmunused_module_signals(module, purge_mode, verbose)) { } if (rminit && rmunused_module_init(module, purge_mode, verbose)) - rmunused_module_signals(module, purge_mode, verbose); + while (rmunused_module_signals(module, purge_mode, verbose)) { } } struct OptCleanPass : public Pass { |