3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2026-07-15 03:35:40 +00:00

twine: avoid TwinePool::lookup

This commit is contained in:
Emil J. Tywoniak 2026-06-16 22:57:13 +02:00
parent 4061593ce5
commit 3a5f5c77bf
23 changed files with 277 additions and 259 deletions

View file

@ -209,7 +209,7 @@ struct IdStringCollector {
}
void trace(const RTLIL::Cell &cell) {
trace_named(cell);
trace(cell.type);
trace(cell.type_impl);
trace_keys(cell.connections_);
trace_keys(cell.parameters);
}
@ -1536,14 +1536,14 @@ const RTLIL::Module *RTLIL::Design::module(TwineRef id) const {
RTLIL::Module *RTLIL::Design::module(TwineRef id) {
return modules_.count(id) ? modules_.at(id) : NULL;
}
const RTLIL::Module *RTLIL::Design::module(IdString id) const {
TwineRef r = twines.lookup(id.str());
return r == Twine::Null ? NULL : module(r);
}
RTLIL::Module *RTLIL::Design::module(IdString id) {
TwineRef r = twines.lookup(id.str());
return r == Twine::Null ? NULL : module(r);
}
// const RTLIL::Module *RTLIL::Design::module(IdString id) const {
// TwineRef r = twines.lookup(id.str());
// return r == Twine::Null ? NULL : module(r);
// }
// RTLIL::Module *RTLIL::Design::module(IdString id) {
// TwineRef r = twines.lookup(id.str());
// return r == Twine::Null ? NULL : module(r);
// }
RTLIL::Module *RTLIL::Design::top_module() const
{
@ -5168,7 +5168,7 @@ bool RTLIL::Cell::input(TwineRef portname) const
if (yosys_celltypes.cell_known(type_impl))
return yosys_celltypes.cell_input(type_impl, portname);
if (module && module->design) {
RTLIL::Module *m = module->design->module(type);
RTLIL::Module *m = module->design->module(type_impl);
RTLIL::Wire *w = m ? m->wire(portname) : nullptr;
return w && w->port_input;
}
@ -5224,7 +5224,7 @@ const RTLIL::Const &RTLIL::Cell::getParam(IdString paramname) const
if (it != parameters.end())
return it->second;
if (module && module->design) {
RTLIL::Module *m = module->design->module(type);
RTLIL::Module *m = module->design->module(type_impl);
if (m)
return m->parameter_default_values.at(paramname);
}
@ -6586,6 +6586,9 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri
sigspec_parse_split(tokens, str, ',');
sig = RTLIL::SigSpec();
std::optional<TwineSearch> search;
if (module)
search.emplace(&module->design->twines);
for (int tokidx = int(tokens.size())-1; tokidx >= 0; tokidx--)
{
std::string netname = tokens[tokidx];
@ -6609,7 +6612,7 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri
if (netname[0] != '$' && netname[0] != '\\')
netname = "\\" + netname;
if (module->design->twines.lookup(netname) == Twine::Null) {
if (search->find(netname) == Twine::Null) {
size_t indices_pos = netname.size()-1;
if (indices_pos > 2 && netname[indices_pos] == ']')
{
@ -6627,12 +6630,12 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri
}
{
TwineRef wid = module->design->twines.lookup(netname);
TwineRef wid = search->find(netname);
if (wid == Twine::Null || module->wires_.count(wid) == 0)
return false;
}
RTLIL::Wire *wire = module->wire(module->design->twines.lookup(netname));
RTLIL::Wire *wire = module->wire(search->find(netname));
if (!indices.empty()) {
std::vector<std::string> index_tokens;
sigspec_parse_split(index_tokens, indices.substr(1, indices.size()-2), ':');

View file

@ -1357,31 +1357,30 @@ struct NameMasqBase {
return self().escaped();
}
bool isPublic() const { return twine_is_public(self().ref()); }
bool empty() const { return RTLIL::IdString(self()).empty(); }
bool empty() const { return self().ref() == Twine::Null; }
std::string str() const { return self().escaped(); }
std::string unescape() const { return self().unescaped(); }
bool begins_with(const char *s) const { return str().starts_with(s); }
bool ends_with(const char *s) const { return str().ends_with(s); }
template <typename... Ts> bool in(Ts &&...args) const {
return RTLIL::IdString(self()).in(std::forward<Ts>(args)...);
return self().ref().in(std::forward<Ts>(args)...);
}
std::string substr(size_t pos = 0, size_t len = std::string::npos) const {
return RTLIL::IdString(self()).substr(pos, len);
return self().escaped().substr(pos, len);
}
// TODO less IdString construction in masquerades
size_t size() const { return RTLIL::IdString(self()).size(); }
bool contains(const char *p) const { return RTLIL::IdString(self()).contains(p); }
char operator[](int n) const { return RTLIL::IdString(self()).str()[n]; }
bool lt_by_name(RTLIL::IdString rhs) const { return RTLIL::IdString(self()).lt_by_name(rhs); }
bool lt_by_name(const Derived &rhs) const { return RTLIL::IdString(self()).lt_by_name(RTLIL::IdString(rhs)); }
bool operator==(RTLIL::IdString rhs) const { return RTLIL::IdString(self()) == rhs; }
bool operator!=(RTLIL::IdString rhs) const { return RTLIL::IdString(self()) != rhs; }
bool operator<(RTLIL::IdString rhs) const { return RTLIL::IdString(self()) < rhs; }
bool operator==(const std::string &rhs) const { return RTLIL::IdString(self()) == rhs; }
bool operator!=(const std::string &rhs) const { return RTLIL::IdString(self()) != rhs; }
bool operator==(const Derived &rhs) const { return RTLIL::IdString(self()) == RTLIL::IdString(rhs); }
bool operator!=(const Derived &rhs) const { return RTLIL::IdString(self()) != RTLIL::IdString(rhs); }
bool operator<(const Derived &rhs) const { return RTLIL::IdString(self()) < RTLIL::IdString(rhs); }
size_t size() const { return self().escaped().size(); }
bool contains(const char *p) const { return self().escaped().find(p) != std::string::npos; }
char operator[](int n) const { return self().escaped()[n]; }
bool lt_by_name(RTLIL::IdString rhs) const { return self().escaped() < rhs.str(); }
bool lt_by_name(const Derived &rhs) const { return self().escaped() < rhs.escaped(); }
bool operator==(RTLIL::IdString rhs) const { return self().escaped() == rhs.str(); }
bool operator!=(RTLIL::IdString rhs) const { return self().escaped() != rhs.str(); }
bool operator<(RTLIL::IdString rhs) const { return self().escaped() < rhs.str(); }
bool operator==(const std::string &rhs) const { return self().escaped() == rhs; }
bool operator!=(const std::string &rhs) const { return self().escaped() != rhs; }
bool operator==(const Derived &rhs) const { return self().ref() == rhs.ref(); }
bool operator!=(const Derived &rhs) const { return self().ref() != rhs.ref(); }
bool operator<(const Derived &rhs) const { return self().escaped() < rhs.escaped(); }
[[nodiscard]] Hasher hash_into(Hasher h) const { return RTLIL::IdString(self()).hash_into(h); }
private:
const Derived &self() const { return *static_cast<const Derived *>(this); }
@ -1389,11 +1388,11 @@ private:
} // namespace RTLIL
template<typename Derived>
inline bool operator==(RTLIL::IdString lhs, const RTLIL::NameMasqBase<Derived> &rhs) {
return lhs == RTLIL::IdString(rhs);
return lhs.str() == static_cast<const Derived &>(rhs).escaped();
}
template<typename Derived>
inline bool operator!=(RTLIL::IdString lhs, const RTLIL::NameMasqBase<Derived> &rhs) {
return lhs != RTLIL::IdString(rhs);
return lhs.str() != static_cast<const Derived &>(rhs).escaped();
}
// Read-only masquerade for Wire::name. Reads materialise the TwineRef in
@ -1448,24 +1447,24 @@ struct RTLIL::CellTypeMasq {
return ref().in(std::forward<Ts>(args)...);
}
std::string substr(size_t pos = 0, size_t len = std::string::npos) const {
return RTLIL::IdString(*this).substr(pos, len);
return escaped().substr(pos, len);
}
size_t size() const { return str().size(); }
// bool contains(const char *p) const { return str().contains(p); }
bool contains(const char *p) const { return escaped().find(p) != std::string::npos; }
char operator[](int n) const { return str()[n]; }
bool operator==(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) == rhs; }
bool operator!=(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) != rhs; }
bool operator<(RTLIL::IdString rhs) const { return RTLIL::IdString(*this) < rhs; }
bool operator==(RTLIL::IdString rhs) const { return escaped() == rhs.str(); }
bool operator!=(RTLIL::IdString rhs) const { return escaped() != rhs.str(); }
bool operator<(RTLIL::IdString rhs) const { return escaped() < rhs.str(); }
bool operator==(TwineRef rhs) const { return ref() == rhs; }
bool operator!=(TwineRef rhs) const { return ref() != rhs; }
bool operator==(const std::string &rhs) const { return RTLIL::IdString(*this) == rhs; }
bool operator!=(const std::string &rhs) const { return RTLIL::IdString(*this) != rhs; }
bool operator==(const std::string &rhs) const { return escaped() == rhs; }
bool operator!=(const std::string &rhs) const { return escaped() != rhs; }
bool operator==(const CellTypeMasq &rhs) const { return ref() == rhs.ref(); }
bool operator!=(const CellTypeMasq &rhs) const { return ref() != rhs.ref(); }
[[nodiscard]] Hasher hash_into(Hasher h) const { return RTLIL::IdString(*this).hash_into(h); }
};
inline bool operator==(RTLIL::IdString lhs, const RTLIL::CellTypeMasq &rhs) { return lhs == RTLIL::IdString(rhs); }
inline bool operator!=(RTLIL::IdString lhs, const RTLIL::CellTypeMasq &rhs) { return lhs != RTLIL::IdString(rhs); }
inline bool operator==(RTLIL::IdString lhs, const RTLIL::CellTypeMasq &rhs) { return lhs.str() == rhs.escaped(); }
inline bool operator!=(RTLIL::IdString lhs, const RTLIL::CellTypeMasq &rhs) { return lhs.str() != rhs.escaped(); }
inline bool operator==(TwineRef lhs, const RTLIL::CellTypeMasq &rhs) { return lhs == rhs.ref(); }
inline bool operator!=(TwineRef lhs, const RTLIL::CellTypeMasq &rhs) { return lhs != rhs.ref(); }
@ -2156,8 +2155,8 @@ struct RTLIL::Design
~Design();
RTLIL::ObjRange<RTLIL::Module*, TwineRef> modules();
RTLIL::Module *module(IdString name);
const RTLIL::Module *module(IdString name) const;
// RTLIL::Module *module(IdString name);
// const RTLIL::Module *module(IdString name) const;
RTLIL::Module *module(TwineRef name);
const RTLIL::Module *module(TwineRef name) const;
RTLIL::Module *top_module() const;

View file

@ -258,7 +258,9 @@ static int tcl_get_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
obj_id = RTLIL::escape_id(argv[i++]);
attr_id = RTLIL::escape_id(argv[i++]);
RTLIL::Module *mod = yosys_design->module(mod_id);
TwineSearch search(&yosys_design->twines);
auto mod_twine = search.find(mod_id);
RTLIL::Module *mod = yosys_design->module(mod_twine);
if (!mod)
ERROR("module not found")
@ -266,7 +268,6 @@ static int tcl_get_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
if (mod_flag) {
obj = mod;
} else {
TwineSearch search(&yosys_design->twines);
auto obj_twine = search.find(obj_id);
obj = mod->wire(obj_twine);
if (!obj)
@ -323,7 +324,9 @@ static int tcl_has_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
obj_id = RTLIL::escape_id(argv[i++]);
attr_id = RTLIL::escape_id(argv[i++]);
RTLIL::Module *mod = yosys_design->module(mod_id);
TwineSearch search(&yosys_design->twines);
auto mod_twine = search.find(mod_id);
RTLIL::Module *mod = yosys_design->module(mod_twine);
if (!mod)
ERROR("module not found")
@ -331,7 +334,6 @@ static int tcl_has_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar
if (mod_flag) {
obj = mod;
} else {
TwineSearch search(&yosys_design->twines);
auto obj_twine = search.find(obj_id);
obj = mod->wire(obj_twine);
if (!obj)
@ -378,7 +380,9 @@ static int tcl_set_attr(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *const
obj_id = RTLIL::escape_id(Tcl_GetString(objv[i++]));
attr_id = RTLIL::escape_id(Tcl_GetString(objv[i++]));
RTLIL::Module *mod = yosys_design->module(mod_id);
TwineSearch search(&yosys_design->twines);
auto mod_twine = search.find(mod_id);
RTLIL::Module *mod = yosys_design->module(mod_twine);
if (!mod)
ERROR("module not found")
@ -386,7 +390,6 @@ static int tcl_set_attr(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *const
if (mod_flag) {
obj = mod;
} else {
TwineSearch search(&yosys_design->twines);
auto obj_twine = search.find(obj_id);
obj = mod->wire(obj_twine);
if (!obj)
@ -457,11 +460,12 @@ static int tcl_get_param(ClientData, Tcl_Interp *interp, int argc, const char *a
cell_id = RTLIL::escape_id(argv[i++]);
param_id = RTLIL::escape_id(argv[i++]);
RTLIL::Module *mod = yosys_design->module(mod_id);
TwineSearch search(&yosys_design->twines);
auto mod_twine = search.find(mod_id);
RTLIL::Module *mod = yosys_design->module(mod_twine);
if (!mod)
ERROR("module not found")
TwineSearch search(&yosys_design->twines);
auto cell_twine = search.find(cell_id);
Cell* cell = mod->cell(cell_twine);
if (!cell)
@ -505,11 +509,12 @@ static int tcl_set_param(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *cons
cell_id = RTLIL::escape_id(Tcl_GetString(objv[i++]));
param_id = RTLIL::escape_id(Tcl_GetString(objv[i++]));
RTLIL::Module *mod = yosys_design->module(mod_id);
TwineSearch search(&yosys_design->twines);
auto mod_twine = search.find(mod_id);
RTLIL::Module *mod = yosys_design->module(mod_twine);
if (!mod)
ERROR("module not found")
TwineSearch search(&yosys_design->twines);
auto cell_twine = search.find(cell_id);
RTLIL::Cell *cell = mod->cell(cell_twine);
if (!cell)

View file

@ -333,10 +333,10 @@ struct TwinePool {
return ref;
}
// Interns an object name and returns a publicity-tagged handle. Leaf
// strings follow the escaped convention: a leading '\' marks a public
// name (stripped from the stored content), '$' a private one. Suffix
// and concat names inherit the prefix/first-child handle's publicity.
// Interns a structural Twine verbatim and returns the handle. Leaf content
// is stored as-is — callers holding an escaped string must strip the '\'
// and tag publicity themselves (or use the add(std::string) overload).
// Suffix names inherit the prefix handle's publicity.
TwineRef add(Twine t) {
bool is_public = false;
if (auto *sfx = std::get_if<Twine::Suffix>(&t.data)) {
@ -392,11 +392,6 @@ struct TwinePool {
return Twine::Null;
}
// linear deep scan; only for rare by-string lookups. Accepts the
// escaped name convention: a leading '\' is stripped and the returned
// handle carries TWINE_PUBLIC_BIT.
TwineRef lookup(std::string_view sv) const;
// Erases every backing node not reachable from `roots`; refs to
// surviving nodes stay valid. Returns the number of erased nodes.
template<typename Pool>
@ -685,31 +680,19 @@ struct TwineChildPool {
}
};
inline TwineRef TwinePool::lookup(std::string_view sv) const {
bool is_public = !sv.empty() && sv[0] == '\\';
if (is_public)
sv.remove_prefix(1);
DeepTwineEq eq{this};
for (TwineRef ref = 0; ref < globals_.size(); ref++)
if (eq(ref, sv))
return twine_tag(ref, is_public);
for (auto it = backing.begin(); it != backing.end(); ++it) {
TwineRef ref = STATIC_TWINE_END + backing.get_index(it);
if (eq(ref, sv))
return twine_tag(ref, is_public);
}
return Twine::Null;
}
struct TwineSearch {
TwinePool* pool;
const TwinePool* pool;
std::unordered_set<TwineRef, DeepTwineHash, DeepTwineEq> index;
TwineSearch(TwinePool* pool) : pool(pool), index(0, DeepTwineHash{pool}, DeepTwineEq{pool}) {
TwineSearch(const TwinePool* pool) : pool(pool), index(0, DeepTwineHash{pool}, DeepTwineEq{pool}) {
for (TwineRef ref = 0; ref < STATIC_TWINE_END; ref++)
index.insert(ref);
for (auto it = pool->backing.begin(); it != pool->backing.end(); ++it) {
if (it->is_dead())
continue;
index.insert(STATIC_TWINE_END + pool->backing.get_index(it));
}
}
// Escaped-name aware, same contract as TwinePool::lookup.
// Escaped-name aware. Resolves both statics and locals by content.
TwineRef find(std::string_view sv) const {
bool is_public = !sv.empty() && sv[0] == '\\';
if (is_public)