| author | Felix Salfelder <felix@salfelder.org> | 2025年11月19日 00:00:00 +0000 |
|---|---|---|
| committer | Felix Salfelder <felix@salfelder.org> | 2025年11月19日 00:00:00 +0000 |
| commit | 16ed1aded66f2567e2b2869387029f206f989d3f (patch) | |
| tree | 76d16648d1eedf79a3986b572fd9a14a29bc5e49 | |
| parent | 0db6ea70ec9c1a81e3d0e6c5636e803b15d7e31a (diff) | |
| download | gnucap-find_miss_cache.tar.gz | |
| -rw-r--r-- | include/e_cardlist.h | 26 | ||||
| -rw-r--r-- | include/patchlev.h | 2 | ||||
| -rw-r--r-- | lib/e_card.cc | 5 | ||||
| -rw-r--r-- | lib/e_cardlist.cc | 62 | ||||
| -rw-r--r-- | tests/==out/lang_verilog.dup.1.gc.out | 2 |
diff --git a/include/e_cardlist.h b/include/e_cardlist.h index fac46893..018a69f3 100644 --- a/include/e_cardlist.h +++ b/include/e_cardlist.h @@ -26,6 +26,7 @@ #define E_CARDLIST_H #include "md.h" #include "u_parameter.h" +#include <set> /*--------------------------------------------------------------------------*/ // defined here class CARD_LIST; @@ -39,14 +40,18 @@ struct TIME_PAIR; /*--------------------------------------------------------------------------*/ class INTERFACE CARD_LIST { public: // base types - typedef std::list<CARD*> list; + typedef CARD value_type; + typedef std::list<value_type*> list; typedef list::iterator iterator; typedef list::const_iterator const_iterator; typedef list::reverse_iterator reverse_iterator; + typedef list::const_reverse_iterator const_reverse_iterator; + typedef std::set<std::string> miss_cache_t; private: // data members const CARD_LIST* _parent; mutable NODE_MAP* _nm; mutable PARAM_LIST* _params; + mutable miss_cache_t* _misses{nullptr}; list _cl; public: // more types class fat_iterator { @@ -89,8 +94,7 @@ public: // more types iterator begin() {return _cl.begin();} iterator end() {return _cl.end();} iterator find_again(const std::string& short_name, iterator); - iterator find_(const std::string& short_name) - {return find_again(short_name, begin());} + iterator find_(const std::string& short_name); reverse_iterator rbegin() { return _cl.rbegin();} reverse_iterator rend() { return _cl.rend();} @@ -100,14 +104,18 @@ public: const_iterator begin()const {return _cl.begin();} const_iterator end()const {return _cl.end();} const_iterator find_again(const std::string& short_name, const_iterator)const; - const_iterator find_(const std::string& short_name)const - {return find_again(short_name, begin());} + const_iterator find_(const std::string& short_name) const + {return const_cast<CARD_LIST*>(this)->find_(short_name);} +private: // cache implementation + void clear_find_cache(); + void add_to_find_cache(CARD*); + void record_miss(std::string const&); - // add to it - CARD_LIST& push_front(CARD* c) {_cl.push_front(c); return *this;} - CARD_LIST& push_back(CARD* c) {_cl.push_back(c); return *this;} +public: // add to it + CARD_LIST& push_front(CARD* c) {clear_find_cache(); _cl.push_front(c); return *this;} + CARD_LIST& push_back(CARD* c) {add_to_find_cache(c); _cl.push_back(c); return *this;} CARD_LIST& insert(CARD_LIST::iterator i, CARD* c) - {_cl.insert(i, c); return *this;} + {clear_find_cache(); _cl.insert(i, c); return *this;} // take things out CARD_LIST& erase(iterator i); diff --git a/include/patchlev.h b/include/patchlev.h index e49e2f9d..40347c62 100644 --- a/include/patchlev.h +++ b/include/patchlev.h @@ -1 +1 @@ -#define PATCHLEVEL "parse_dump 2025年11月11日" +#define PATCHLEVEL "find_miss_cache 2025年11月19日" diff --git a/lib/e_card.cc b/lib/e_card.cc index 0ca75d4d..d6a11a35 100644 --- a/lib/e_card.cc +++ b/lib/e_card.cc @@ -221,7 +221,7 @@ const CARD* CARD::find_in_parent_scope(const std::string& name)const CARD_LIST::const_iterator j = i; if (i == p_scope->end()) { throw Exception_Cant_Find(long_label(), name); - }else if(p_scope->find_again(name, ++j) != p_scope->end()){ + }else if(p_scope->find_again(name, ++j) != p_scope->end()){ untested(); error(bWARNING, "duplicate match " + name + " in " + long_label() + "\n"); }else{ } @@ -241,7 +241,8 @@ const CARD* CARD::find_looking_out(const std::string& name)const return owner()->find_looking_out(name); }else if (makes_own_scope()) { // probably a subckt or "module" - CARD_LIST::const_iterator i = CARD_LIST::card_list.find_(name); + // BUG? why not "find_again?" + auto i = CARD_LIST::card_list.find_(name); if (i != CARD_LIST::card_list.end()) { return *i; }else{ diff --git a/lib/e_cardlist.cc b/lib/e_cardlist.cc index 5275b4d9..304ddd6c 100644 --- a/lib/e_cardlist.cc +++ b/lib/e_cardlist.cc @@ -116,8 +116,47 @@ CARD_LIST::const_iterator CARD_LIST::find_again(const std::string& short_name, return notstd::find_ptr(Begin, end(), short_name); } /*--------------------------------------------------------------------------*/ +CARD_LIST::iterator CARD_LIST::find_(const std::string& name) +{ + bool miss = false; + + if(!_misses) { + }else if(_misses->count(name)) { + miss = true; + }else if(OPT::case_insensitive) { + std::string low = name; + notstd::to_lower(&low); + if(_misses->count(low)) { + miss = true; + }else{ + } + }else{ + } + + if(miss){ + return end(); + }else{ + CARD_LIST::iterator r = find_again(name, begin()); + if(r == end()) { + record_miss(name); + }else{ + } + return r; + } +} +/*--------------------------------------------------------------------------*/ +void CARD_LIST::record_miss(std::string const& name) +{ + if(_misses){ + }else{ + _misses = new std::set<std::string>; + } + _misses->insert(name); +} +/*--------------------------------------------------------------------------*/ CARD_LIST& CARD_LIST::erase(iterator ci) { + clear_find_cache(); assert(ci != end()); if (*ci) { (*ci)->purge(); @@ -131,6 +170,7 @@ CARD_LIST& CARD_LIST::erase(iterator ci) CARD_LIST& CARD_LIST::erase(CARD* c) { if (c) { + clear_find_cache(); c->purge(); delete c; _cl.remove(c); @@ -144,6 +184,7 @@ CARD_LIST& CARD_LIST::erase(CARD* c) */ CARD_LIST& CARD_LIST::erase_all() { + clear_find_cache(); while (!_cl.empty()) { if (_cl.back()) { _cl.back()->purge(); @@ -557,6 +598,7 @@ void CARD_LIST::shallow_copy(const CARD_LIST* p) { assert(p); _parent = p; + clear_find_cache(); for (const_iterator ci = p->begin(); ci != p->end(); ++ci) { trace_func_comp(); if ((**ci).is_device() || dynamic_cast<MODEL_CARD*>(*ci)) { @@ -653,5 +695,25 @@ void CARD_LIST::set_verilog_math(bool m) _params->set_verilog(m); } /*--------------------------------------------------------------------------*/ +void CARD_LIST::add_to_find_cache(CARD* c) +{ + assert(c); + if(_misses){ itested(); + // this is really needed in repeat finds during sckt parse. + // (most calls are no-ops) + std::string name = c->short_label(); + _misses->erase(name); + notstd::to_lower(&name); + _misses->erase(name); + }else{ + } +} +/*--------------------------------------------------------------------------*/ +void CARD_LIST::clear_find_cache() +{ + delete _misses; + _misses = nullptr; +} +/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ // vim:ts=8:sw=2:noet: diff --git a/tests/==out/lang_verilog.dup.1.gc.out b/tests/==out/lang_verilog.dup.1.gc.out index ca9eb95a..b4ceadf0 100644 --- a/tests/==out/lang_verilog.dup.1.gc.out +++ b/tests/==out/lang_verilog.dup.1.gc.out @@ -12,4 +12,4 @@ module aaa (.a(a),.b(b)); endmodule // aaa # v(a) - 0. 1. + 0. 2. |