diff --git a/passes/proc/proc_dff.cc b/passes/proc/proc_dff.cc index fd56786f28b..9ead5825a23 100644 --- a/passes/proc/proc_dff.cc +++ b/passes/proc/proc_dff.cc @@ -53,8 +53,32 @@ RTLIL::SigSpec find_any_lvalue(const RTLIL::Process *proc) return lvalue; } +/** + * Container storing key,std::set(value) pairs in reverse insertion order + * and provides a linear search. + */ +template +class InsertOrderedSetMap { + using entry = std::pair>; + std::vector backing; +public: + std::set& operator[] (Key key) { + auto entry_has_key = [key](entry e) { return e.first == key; }; + if (auto it = std::find_if(backing.begin(), backing.end(), entry_has_key); it != std::end(backing)) { + return (*it).second; + } else { + backing.push_back(entry(key, std::set{})); + return backing.back().second; + } + } + typename std::vector::reverse_iterator begin() { return backing.rbegin(); } + typename std::vector::reverse_iterator end() { return backing.rend(); } + typename std::vector::size_type size() { return backing.size(); } + void clear() { return backing.clear(); } +}; + void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::SigSpec sig_q, RTLIL::SigSpec clk, bool clk_polarity, - std::map> &async_rules, RTLIL::Process *proc) + InsertOrderedSetMap &async_rules, RTLIL::Process *proc) { RTLIL::SigSpec sig_sr_set = RTLIL::SigSpec(0, sig_d.size()); RTLIL::SigSpec sig_sr_clr = RTLIL::SigSpec(0, sig_d.size()); @@ -219,7 +243,7 @@ void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce) RTLIL::SyncRule *sync_always = NULL; bool global_clock = false; - std::map> many_async_rules; + InsertOrderedSetMap many_async_rules; for (auto sync : proc->syncs) for (auto &action : sync->actions)