diff --git a/backends/firrtl/firrtl.cc b/backends/firrtl/firrtl.cc index e9e33a1f4..e3812aa57 100644 --- a/backends/firrtl/firrtl.cc +++ b/backends/firrtl/firrtl.cc @@ -52,7 +52,7 @@ std::string getFileinfo(const RTLIL::AttrObject *design_entity, const RTLIL::Des // Get a port direction with respect to a specific module. FDirection getPortFDirection(IdString id, Module *module) { - Wire *wire = module->wires_.at(id); + Wire *wire = module->wire(id); FDirection direction = FD_NODIRECTION; if (wire && wire->port_id) { diff --git a/backends/rtlil/rtlil_backend.cc b/backends/rtlil/rtlil_backend.cc index f4bbfb1c4..d44c9a380 100644 --- a/backends/rtlil/rtlil_backend.cc +++ b/backends/rtlil/rtlil_backend.cc @@ -41,9 +41,9 @@ void RTLIL_BACKEND::dump_attributes(std::ostream &f, std::string indent, const R Twine::Id id = design->obj_src_id(obj); f << stringf("%s" "attribute \\src ", indent); if (resolve_src) { - dump_const(f, RTLIL::Const(design->src_twines.flatten(id))); + dump_const(f, RTLIL::Const(design->twines.flatten(id))); } else { - dump_const(f, RTLIL::Const(TwinePool::format_ref(id))); + dump_const(f, RTLIL::Const(design->twines.format_ref(id))); } f << stringf("\n"); } @@ -56,10 +56,10 @@ void RTLIL_BACKEND::dump_attributes(std::ostream &f, std::string indent, const R void RTLIL_BACKEND::dump_twines(std::ostream &f, const RTLIL::Design *design) { - if (!design || design->src_twines.size() == 0) + if (!design || design->twines.size() == 0) return; f << stringf("twines\n"); - design->src_twines.for_each_live([&](Twine::Id id, const Twine &n) { + design->twines.for_each_live([&](Twine::Id id, const Twine &n) { if (n.is_leaf()) { f << stringf(" leaf %u ", id); dump_const(f, RTLIL::Const(n.leaf())); diff --git a/backends/rtlil/rtlil_backend.h b/backends/rtlil/rtlil_backend.h index 4e20b3da5..83cd7dd92 100644 --- a/backends/rtlil/rtlil_backend.h +++ b/backends/rtlil/rtlil_backend.h @@ -32,7 +32,7 @@ YOSYS_NAMESPACE_BEGIN namespace RTLIL_BACKEND { // If `design` is non-null AND `resolve_src` is true, the ID::src - // attribute is expanded through design->src_twines so the emitted + // attribute is expanded through design->twines so the emitted // value is the flat path:line.col string. Otherwise the stored value // is written verbatim — including any "@N" twine references, which // the matching `twines` header block emitted by dump_design lets the diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 941f13a9b..9663405e6 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1122,7 +1122,7 @@ void AST::set_src_attr(RTLIL::AttrObject *obj, const AstNode *ast) // carrying only ":line.col-line.col". For a typical large design with // thousands of objects in one file this collapses N copies of a long // path into 1 Leaf + N short Suffix tails. - TwinePool *pool = ¤t_module->design->src_twines; + TwinePool *pool = ¤t_module->design->twines; Twine::Id file_id = pool->intern(*loc.begin.filename); std::string tail = stringf(":%d.%d-%d.%d", loc.begin.line, loc.begin.column, @@ -1155,7 +1155,7 @@ static RTLIL::Module *process_module(RTLIL::Design *design, AstNode *ast, bool d AstModule *module = new AstModule; current_module = module; // Set design backpointer early — every set_src_attr in genrtlil.cc - // resolves the pool via current_module->design->src_twines. The + // resolves the pool via current_module->design->twines. The // final design->add(current_module) at end-of-process_module hooks // the module into the design's modules_ dict; we just need design // reachable as a backpointer for src interning meanwhile. diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc index a8391b6e1..e8547f963 100644 --- a/frontends/ast/genrtlil.cc +++ b/frontends/ast/genrtlil.cc @@ -503,7 +503,7 @@ struct AST_INTERNAL::ProcessGenerator chunk.wire->name.c_str(), chunk.width+chunk.offset-1, chunk.offset);; if (chunk.wire->name.str().find('$') != std::string::npos) wire_name += stringf("$%d", autoidx++); - } while (current_module->wires_.count(wire_name) > 0); + } while (current_module->wire(RTLIL::IdString(wire_name)) != nullptr); RTLIL::Wire *wire = current_module->addWire(wire_name, chunk.width); set_src_attr(wire, always.get()); @@ -1629,10 +1629,9 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) log_assert(id2ast != nullptr); - if (id2ast->type == AST_AUTOWIRE && current_module->wires_.count(str) == 0) { + if (id2ast->type == AST_AUTOWIRE && current_module->wire(RTLIL::IdString(str)) == nullptr) { RTLIL::Wire *wire = current_module->addWire(str); set_src_attr(wire, this); - wire->name = str; // If we are currently processing a bind directive which wires up // signals or parameters explicitly, rather than with .*, then @@ -1652,7 +1651,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) chunk = RTLIL::Const(id2ast->children[0]->bits); goto use_const_chunk; } - else if ((id2ast->type == AST_WIRE || id2ast->type == AST_AUTOWIRE || id2ast->type == AST_MEMORY) && current_module->wires_.count(str) != 0) { + else if ((id2ast->type == AST_WIRE || id2ast->type == AST_AUTOWIRE || id2ast->type == AST_MEMORY) && current_module->wire(RTLIL::IdString(str)) != nullptr) { RTLIL::Wire *current_wire = current_module->wire(str); if (current_wire->get_bool_attribute(ID::is_interface)) is_interface = true; @@ -1682,7 +1681,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint) return dummy_wire; } - wire = current_module->wires_[str]; + wire = current_module->wire(RTLIL::IdString(str)); chunk.wire = wire; chunk.width = wire->width; chunk.offset = 0; diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc index ff63f7f8f..c5f9ca274 100644 --- a/frontends/liberty/liberty.cc +++ b/frontends/liberty/liberty.cc @@ -47,11 +47,12 @@ static RTLIL::SigSpec parse_func_identifier(RTLIL::Module *module, const char *& return *(expr++) == '0' ? RTLIL::State::S0 : RTLIL::State::S1; std::string id = RTLIL::escape_id(std::string(expr, id_len)); - if (!module->wires_.count(id)) + RTLIL::Wire *w = module->wire(RTLIL::IdString(id)); + if (!w) log_error("Can't resolve wire name %s in %s.\n", RTLIL::unescape_id(id), module); expr += id_len; - return module->wires_.at(id); + return w; } static bool parse_func_reduce(RTLIL::Module *module, std::vector &stack, token_t next_token) @@ -728,7 +729,7 @@ struct LibertyFrontend : public Frontend { if (flag_lib && dir->value == "internal") continue; - RTLIL::Wire *wire = module->wires_.at(RTLIL::escape_id(node->args.at(0))); + RTLIL::Wire *wire = module->wire(RTLIL::IdString(RTLIL::escape_id(node->args.at(0)))); log_assert(wire); const LibertyAst *capacitance = node->find("capacitance"); diff --git a/frontends/rtlil/rtlil_frontend.cc b/frontends/rtlil/rtlil_frontend.cc index fe69f6de0..f963c655a 100644 --- a/frontends/rtlil/rtlil_frontend.cc +++ b/frontends/rtlil/rtlil_frontend.cc @@ -54,11 +54,11 @@ struct RTLILFrontendWorker { std::vector case_stack; // Remap from file-local twine ids (as they appear in the `twines` block - // and on cell/wire src attrs) to ids in design->src_twines. Filled by + // and on cell/wire src attrs) to ids in design->twines. Filled by // parse_twines; consumed by parse_attribute. Parser-side ids retained // during parse_twines are tracked here so they can be released at // end-of-parse — only the cell/wire references should survive. - dict twine_remap; + dict twine_remap; std::vector twine_parser_holds; template @@ -171,7 +171,7 @@ struct RTLILFrontendWorker { error("Expected EOL, got `%s'.", error_token()); } - std::optional try_parse_id() + std::optional try_parse_id() { char ch = line[0]; if (ch != '\\' && ch != '$') @@ -183,15 +183,15 @@ struct RTLILFrontendWorker { break; ++idx; } - IdString result(line.substr(0, idx)); + std::string result(line.substr(0, idx)); line = line.substr(idx); consume_whitespace_and_comments(); return result; } - RTLIL::IdString parse_id() + std::string parse_id() { - std::optional id = try_parse_id(); + std::optional id = try_parse_id(); if (!id.has_value()) error("Expected ID, got `%s'.", error_token()); return std::move(*id); @@ -423,7 +423,7 @@ struct RTLILFrontendWorker { void parse_module() { - RTLIL::IdString module_name = parse_id(); + Twine::Id module_name = design->twines.lookup(parse_id()); expect_eol(); bool delete_current_module = false; @@ -445,7 +445,7 @@ struct RTLILFrontendWorker { current_module = new RTLIL::Module; current_module->design = design; - current_module->name = std::move(module_name); + current_module->meta_->name_id = module_name; if (delete_current_module) { // Module is about to be discarded — drop its src attribute // rather than push it into a pool we'll never reach. @@ -515,15 +515,16 @@ struct RTLILFrontendWorker { // is wrong and silently interning it would hide that. if (id == RTLIL::ID::src && (c.flags & RTLIL::CONST_FLAG_STRING)) { std::string raw = c.decode_string(); - Twine::Id file_id = TwinePool::parse_ref(raw); - if (file_id != Twine::Null) { + // TODO error handling + auto file_id = design->twines.parse_ref(raw); + if (file_id) { // Translate the file-local twine id to the destination // design's pool id via twine_remap. If the file had no // `twines` block (legacy) the remap is empty — accept the // ref verbatim and let downstream code intern it. - auto it = twine_remap.find(file_id); + auto it = twine_remap.find(*file_id); if (it != twine_remap.end()) - c = RTLIL::Const(TwinePool::format_ref(it->second)); + c = RTLIL::Const(design->twines.format_ref(it->second)); } else if (raw.find('|') != std::string::npos) { log_warning("line %d: src attribute %s contains '|' separators. " "That convention is Yosys-internal; the producing tool " @@ -538,61 +539,47 @@ struct RTLILFrontendWorker { // Parses a `twines` ... `end` block. Builds twine_remap so subsequent // cell/wire src "@N" references (which use file-local ids) translate - // to ids in design->src_twines. The destination pool may already be + // to ids in design->twines. The destination pool may already be // non-empty (multi-file load) — interned/concated nodes are dedup'd // against the existing pool by the pool itself. Each parser-side // retain is tracked in twine_parser_holds and released at end-of-parse // so only cell/wire references survive. void parse_twines() { + TwinePoolExtender extender(design->twines, design->twines.size()); expect_eol(); while (true) { if (try_parse_keyword("end")) break; if (try_parse_keyword("leaf")) { - int file_id = static_cast(parse_integer()); + size_t file_id = parse_integer(); std::string text = parse_string(); expect_eol(); - Twine::Id local_id = design->src_twines.intern(text); - twine_parser_holds.push_back(local_id); - twine_remap[static_cast(file_id)] = local_id; + extender.extend_leaf(text, file_id); continue; } if (try_parse_keyword("suffix")) { - int file_id = static_cast(parse_integer()); - Twine::Id file_parent = static_cast(parse_integer()); + size_t file_id = parse_integer(); + size_t file_parent = parse_integer(); std::string tail = parse_string(); expect_eol(); - auto it = twine_remap.find(file_parent); - if (it == twine_remap.end()) - error("twines: suffix %d references undefined parent %u.", - file_id, file_parent); - Twine::Id local_id = design->src_twines.intern_suffix(it->second, tail); - twine_parser_holds.push_back(local_id); - twine_remap[static_cast(file_id)] = local_id; + extender.extend_suffix(file_parent, tail, file_id); continue; } if (try_parse_keyword("concat")) { - int file_id = static_cast(parse_integer()); - std::vector children; + size_t file_id = parse_integer(); + std::vector children; while (!try_parse_eol()) { - Twine::Id file_child = static_cast(parse_integer()); - auto it = twine_remap.find(file_child); - if (it == twine_remap.end()) - error("twines: concat %d references undefined leaf/concat %u.", - file_id, file_child); - children.push_back(it->second); + children.push_back(parse_integer()); } - Twine::Id local_id = design->src_twines.concat( - std::span{children}); - twine_parser_holds.push_back(local_id); - twine_remap[static_cast(file_id)] = local_id; + extender.extend_concat(children, file_id); continue; } error("Expected `leaf`, `suffix` or `concat` inside twines block, got `%s'.", error_token()); } expect_eol(); + extender.finish(); } // Release the per-file parser refs gathered during parse_twines. Call @@ -601,7 +588,7 @@ struct RTLILFrontendWorker { void release_twine_parser_holds() { for (Twine::Id id : twine_parser_holds) - design->src_twines.release(id); + design->twines.release(id); twine_parser_holds.clear(); twine_remap.clear(); } diff --git a/kernel/ff.cc b/kernel/ff.cc index d60e440f7..146b5253e 100644 --- a/kernel/ff.cc +++ b/kernel/ff.cc @@ -46,8 +46,7 @@ void manufacture_info(InputType flop, OutputType& info, FfInitVals *initvals) { // id verbatim into the new cell — no flatten/re-intern, no // pipe-leaf risk for cells whose src is a Concat. if (cell->src_id() != Twine::Null && cell->module && cell->module->design) - info.src_twine = OwnedTwine(&cell->module->design->src_twines, - cell->src_id()); + info.src_twine = cell->src_id(); if (initvals) info.val_init = (*initvals)(info.sig_q); } @@ -768,7 +767,7 @@ Cell *FfData::emit() { // FfData is destroyed; set_src_id retains on the cell's behalf. cell->attributes = attributes; if (!src_twine.empty() && cell->module && cell->module->design) { - TwinePool *dst_pool = &cell->module->design->src_twines; + TwinePool *dst_pool = &cell->module->design->twines; if (src_twine.pool() == dst_pool) { cell->set_src_id(src_twine.id()); } else { diff --git a/kernel/ff.h b/kernel/ff.h index 71c836790..3e7c24534 100644 --- a/kernel/ff.h +++ b/kernel/ff.h @@ -173,7 +173,7 @@ struct FfData : FfTypeData { // Stashed src across construction → emit. Refcount-managed so the // source cell's pool slot survives if the cell itself is removed // before emit() runs. Empty when the source cell had no src. - OwnedTwine src_twine; + Twine::Id src_twine; FfData(Module *module = nullptr, FfInitVals *initvals = nullptr, IdString name = IdString()) : module(module), initvals(initvals), cell(nullptr), name(name) { width = 0; diff --git a/kernel/mem.cc b/kernel/mem.cc index 4bf345cac..499f5d36c 100644 --- a/kernel/mem.cc +++ b/kernel/mem.cc @@ -894,10 +894,10 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { // below adopts the same slot as Mem itself (via set_src_attribute's // "@N" parse_ref path), and there's no flatten → re-intern → pipe- // leaf round-trip on cells whose src is a Concat node. - TwinePool *src_pool = (module && module->design) ? &module->design->src_twines : nullptr; - Twine::Id mem_src_id = (module && module->design) ? module->design->obj_src_id(this) : Twine::Null; - std::string mem_src = (src_pool && mem_src_id != Twine::Null) ? - TwinePool::format_ref(mem_src_id) : std::string(); + log_assert(module && module->design); + Twine::Id mem_src_id = module->design->obj_src_id(this); + std::string mem_src = (mem_src_id != Twine::Null) ? + module->design->twines.format_ref(mem_src_id) : std::string(); Cell *c; @@ -1005,8 +1005,7 @@ Cell *Mem::extract_rdff(int idx, FfInitVals *initvals) { FfData ff(module, initvals, name); // Carry mem's src into the ff via the OwnedTwine handle — same // pool, direct id retain. emit() transfers verbatim. - if (src_pool && mem_src_id != Twine::Null) - ff.src_twine = OwnedTwine(src_pool, mem_src_id); + ff.src_twine = mem_src_id; ff.width = GetSize(port.data); ff.has_clk = true; ff.sig_clk = port.clk; diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index bc10c820f..252a2bd14 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -37,13 +37,13 @@ YOSYS_NAMESPACE_BEGIN -bool RTLIL::IdString::destruct_guard_ok = false; -RTLIL::IdString::destruct_guard_t RTLIL::IdString::destruct_guard; -std::vector RTLIL::IdString::global_id_storage_; -std::unordered_map RTLIL::IdString::global_id_index_; -std::unordered_map RTLIL::IdString::global_autoidx_id_storage_; -std::unordered_map RTLIL::IdString::global_refcount_storage_; -std::vector RTLIL::IdString::global_free_idx_list_; +bool IdString::destruct_guard_ok = false; +IdString::destruct_guard_t IdString::destruct_guard; +std::vector IdString::global_id_storage_; +std::unordered_map IdString::global_id_index_; +std::unordered_map IdString::global_autoidx_id_storage_; +std::unordered_map IdString::global_refcount_storage_; +std::vector IdString::global_free_idx_list_; static void populate(std::string_view name) { @@ -51,17 +51,17 @@ static void populate(std::string_view name) // Skip prepended '\' name = name.substr(1); } - RTLIL::IdString::global_id_index_.insert({name, GetSize(RTLIL::IdString::global_id_storage_)}); - RTLIL::IdString::global_id_storage_.push_back({const_cast(name.data()), GetSize(name)}); + IdString::global_id_index_.insert({name, GetSize(IdString::global_id_storage_)}); + IdString::global_id_storage_.push_back({const_cast(name.data()), GetSize(name)}); } -void RTLIL::IdString::prepopulate() +void IdString::prepopulate() { int size = static_cast(RTLIL::StaticId::STATIC_ID_END); global_id_storage_.reserve(size); global_id_index_.reserve(size); - RTLIL::IdString::global_id_index_.insert({"", 0}); - RTLIL::IdString::global_id_storage_.push_back({const_cast(""), 0}); + IdString::global_id_index_.insert({"", 0}); + IdString::global_id_storage_.push_back({const_cast(""), 0}); #define X(N) populate("\\" #N); #include "kernel/constids.inc" #undef X @@ -82,7 +82,7 @@ static std::optional parse_autoidx(std::string_view v) return p_autoidx; } -int RTLIL::IdString::really_insert(std::string_view p, std::unordered_map::iterator &it) +int IdString::really_insert(std::string_view p, std::unordered_map::iterator &it) { ensure_prepopulated(); @@ -150,6 +150,10 @@ struct IdStringCollector { IdStringCollector(std::vector &live_ids) : live_ids(live_ids) {} + void trace(Twine::Id id) { + // live_twines.push_back(id ); + // TODO + } void trace(IdString id) { if (id.index_ >= STATIC_ID_END) live_ids[id.index_ - STATIC_ID_END].set(); @@ -232,6 +236,7 @@ struct IdStringCollector { } std::vector &live_ids; + // std::vector &live_twines; std::vector live_autoidx_ids; }; @@ -256,10 +261,12 @@ void RTLIL::OwningIdString::collect_garbage() for (int i = 0; i < num_threads; ++i) collectors.emplace_back(live_ids); + // TODO for (auto &[idx, design] : *RTLIL::Design::get_all_designs()) { for (RTLIL::Module *module : design->modules()) { collectors[0].trace_keys(module->attributes); - collectors[0].trace(RTLIL::IdString(module->name)); + // collectors[0].trace(Twine::Id(module->name)); + // TODO ParallelDispatchThreadPool::Subpool subpool(thread_pool, ThreadPool::work_pool_size(0, module->cells_size(), 1000)); subpool.run([&collectors, module](const ParallelDispatchThreadPool::RunCtx &ctx) { for (int i : ctx.item_range(module->cells_size())) @@ -279,7 +286,7 @@ void RTLIL::OwningIdString::collect_garbage() thread_pool.run([&live_ids, size, &free_ids](const ParallelDispatchThreadPool::RunCtx &ctx) { for (int i : ctx.item_range(size - STATIC_ID_END)) { int index = i + STATIC_ID_END; - RTLIL::IdString::Storage &storage = global_id_storage_.at(index); + IdString::Storage &storage = global_id_storage_.at(index); if (storage.buf == nullptr) continue; if (live_ids[i].load()) @@ -290,7 +297,7 @@ void RTLIL::OwningIdString::collect_garbage() } }); for (int i : free_ids) { - RTLIL::IdString::Storage &storage = global_id_storage_.at(i); + IdString::Storage &storage = global_id_storage_.at(i); if (yosys_xtrace) { log("#X# Removed IdString '%s' with index %d.\n", storage.buf, i); log_backtrace("-X- ", yosys_xtrace-1); @@ -915,14 +922,14 @@ RTLIL::Const RTLIL::Const::extract(int offset, int len, RTLIL::State padding) co } #undef check /* check(condition) for Const */ -bool RTLIL::AttrObject::has_attribute(RTLIL::IdString id) const +bool RTLIL::AttrObject::has_attribute(IdString id) const { if (id == ID::src) return meta_ != nullptr && meta_->src != Twine::Null; return attributes.count(id); } -void RTLIL::AttrObject::set_bool_attribute(RTLIL::IdString id, bool value) +void RTLIL::AttrObject::set_bool_attribute(IdString id, bool value) { log_assert(id != ID::src); if (value) @@ -931,7 +938,7 @@ void RTLIL::AttrObject::set_bool_attribute(RTLIL::IdString id, bool value) attributes.erase(id); } -bool RTLIL::AttrObject::get_bool_attribute(RTLIL::IdString id) const +bool RTLIL::AttrObject::get_bool_attribute(IdString id) const { if (id == ID::src) return meta_ != nullptr && meta_->src != Twine::Null; @@ -941,7 +948,7 @@ bool RTLIL::AttrObject::get_bool_attribute(RTLIL::IdString id) const return it->second.as_bool(); } -void RTLIL::AttrObject::set_string_attribute(RTLIL::IdString id, string value) +void RTLIL::AttrObject::set_string_attribute(IdString id, string value) { // ID::src on the base AttrObject is not routable here because the base // has no Design context — callers needing string-form src must go @@ -954,7 +961,7 @@ void RTLIL::AttrObject::set_string_attribute(RTLIL::IdString id, string value) attributes[id] = value; } -string RTLIL::AttrObject::get_string_attribute(RTLIL::IdString id) const +string RTLIL::AttrObject::get_string_attribute(IdString id) const { // ID::src is not in the dict — callers must use the subtype helper. log_assert(id != ID::src && "get_string_attribute(ID::src) on AttrObject base; use the subtype helper"); @@ -976,11 +983,11 @@ void RTLIL::Design::obj_set_src_id(RTLIL::AttrObject *obj, Twine::Id id) if (m.src == id) return; if (m.src != Twine::Null) - src_twines.release(m.src); + twines.release(m.src); m.src = id; if (m.src != Twine::Null) - src_twines.retain(m.src); - if (m.src == Twine::Null && m.name.empty()) { + twines.retain(m.src); + if (m.src == Twine::Null && m.name_id == Twine::Null) { free_obj_meta(obj->meta_); obj->meta_ = nullptr; } @@ -992,37 +999,73 @@ void RTLIL::Design::obj_release_src(RTLIL::AttrObject *obj) return; ObjMeta &m = *obj->meta_; if (m.src != Twine::Null) { - src_twines.release(m.src); + twines.release(m.src); m.src = Twine::Null; } - if (m.name.empty()) { + if (m.name_id == Twine::Null) { free_obj_meta(obj->meta_); obj->meta_ = nullptr; } } -void RTLIL::Design::obj_set_name(RTLIL::AttrObject *obj, RTLIL::IdString name) -{ - if (obj->meta_ == nullptr) { - if (name.empty()) - return; - obj->meta_ = alloc_obj_meta(); - } - ObjMeta &m = *obj->meta_; - m.name = name; - if (m.name.empty() && m.src == Twine::Null) { - free_obj_meta(obj->meta_); - obj->meta_ = nullptr; - } -} +// void RTLIL::Design::obj_set_name(RTLIL::AttrObject *obj, Twine::Id name) +// { +// if (obj->meta_ == nullptr) { +// if (name.empty()) +// return; +// obj->meta_ = alloc_obj_meta(); +// } +// ObjMeta &m = *obj->meta_; +// m.name = name; +// if (m.name.empty() && m.src == Twine::Null && m.name_id == Twine::Null) { +// free_obj_meta(obj->meta_); +// obj->meta_ = nullptr; +// } +// } void RTLIL::Design::obj_release_name(RTLIL::AttrObject *obj) { if (obj->meta_ == nullptr) return; ObjMeta &m = *obj->meta_; - m.name = RTLIL::IdString(); - if (m.src == Twine::Null) { + m.name_id = Twine::Id(); + if (m.src == Twine::Null && m.name_id == Twine::Null) { + free_obj_meta(obj->meta_); + obj->meta_ = nullptr; + } +} + +void RTLIL::Design::obj_set_name_id(RTLIL::AttrObject *obj, Twine::Id id) +{ + if (obj->meta_ == nullptr) { + if (id == Twine::Null) + return; + obj->meta_ = alloc_obj_meta(); + } + ObjMeta &m = *obj->meta_; + if (m.name_id == id) + return; + if (m.name_id != Twine::Null) + twines.release(m.name_id); + m.name_id = id; + if (m.name_id != Twine::Null) + twines.retain(m.name_id); + if (m.name_id == Twine::Null && m.src == Twine::Null) { + free_obj_meta(obj->meta_); + obj->meta_ = nullptr; + } +} + +void RTLIL::Design::obj_release_name_id(RTLIL::AttrObject *obj) +{ + if (obj->meta_ == nullptr) + return; + ObjMeta &m = *obj->meta_; + if (m.name_id != Twine::Null) { + twines.release(m.name_id); + m.name_id = Twine::Null; + } + if (m.src == Twine::Null && m.name_id == Twine::Null) { free_obj_meta(obj->meta_); obj->meta_ = nullptr; } @@ -1038,33 +1081,33 @@ void RTLIL::Design::set_src_attribute(RTLIL::AttrObject *obj, const RTLIL::SrcAt if (src.id != Twine::Null) { // Direct id form — the caller is responsible for keeping the // slot alive while we retain. obj_set_src_id handles retain. - log_assert(src_twines.is_alive(src.id) && "set_src_attribute: SrcAttr id points to dead slot"); + log_assert(twines.is_alive(src.id) && "set_src_attribute: SrcAttr id points to dead slot"); new_id = src.id; obj_set_src_id(obj, new_id); } else { // Literal-string form. "@N" → adopt slot directly. Anything else // → intern as leaf (returns +1, which we release after the retain // inside obj_set_src_id balances). - new_id = TwinePool::parse_ref(src.literal); + new_id = twines.get_ref(src.literal); if (new_id != Twine::Null) { - log_assert(src_twines.is_alive(new_id) && "set_src_attribute: @N ref points to dead slot"); + log_assert(twines.is_alive(new_id) && "set_src_attribute: @N ref points to dead slot"); obj_set_src_id(obj, new_id); } else { - new_id = src_twines.intern(src.literal); + new_id = twines.intern(src.literal); obj_set_src_id(obj, new_id); - src_twines.release(new_id); + twines.release(new_id); } } } std::string RTLIL::Design::get_src_attribute(const RTLIL::AttrObject *obj) const { - return src_twines.flatten(obj_src_id(obj)); + return twines.flatten(obj_src_id(obj)); } void RTLIL::Design::adopt_src_from(RTLIL::AttrObject *obj, const RTLIL::AttrObject *source) { - adopt_src_from(obj, source, &src_twines); + adopt_src_from(obj, source, &twines); } void RTLIL::Design::adopt_src_from(RTLIL::AttrObject *obj, @@ -1083,7 +1126,7 @@ void RTLIL::Design::adopt_src_from(RTLIL::AttrObject *obj, obj_set_src_id(obj, source_id); } -void RTLIL::Design::absorb_attrs(RTLIL::AttrObject *obj, dict &&buf) +void RTLIL::Design::absorb_attrs(RTLIL::AttrObject *obj, dict &&buf) { auto it = buf.find(ID::src); if (it != buf.end()) { @@ -1112,9 +1155,9 @@ namespace { dst_design->obj_set_src_id(dst, src_id); return; } - Twine::Id new_id = dst_design->src_twines.copy_from(src_design->src_twines, src_id); + Twine::Id new_id = dst_design->twines.copy_from(src_design->twines, src_id); dst_design->obj_set_src_id(dst, new_id); - dst_design->src_twines.release(new_id); + dst_design->twines.release(new_id); } } @@ -1134,7 +1177,7 @@ void RTLIL::Design::free_obj_meta(RTLIL::ObjMeta *m) { log_assert(m != nullptr); log_assert(m->src == Twine::Null); - log_assert(m->name.empty()); + log_assert(m->name_id == Twine::Null); obj_meta_free_.push_back(m); } @@ -1151,9 +1194,9 @@ void RTLIL::Design::merge_src(RTLIL::AttrObject *target, const RTLIL::AttrObject } if (ids.empty()) return; - Twine::Id merged = src_twines.concat(std::span{ids}); + Twine::Id merged = twines.concat(std::span{ids}); obj_set_src_id(target, merged); - src_twines.release(merged); + twines.release(merged); } void RTLIL::Design::merge_src(RTLIL::AttrObject *target, const pool &leaves) @@ -1166,20 +1209,20 @@ void RTLIL::Design::merge_src(RTLIL::AttrObject *target, const pool for (const auto &leaf : leaves) { if (leaf.empty()) continue; - Twine::Id leaf_id = TwinePool::parse_ref(leaf); + Twine::Id leaf_id = twines.get_ref(leaf); if (leaf_id == Twine::Null) { - leaf_id = src_twines.intern(leaf); + leaf_id = twines.intern(leaf); temp_interns.push_back(leaf_id); } ids.push_back(leaf_id); } if (ids.empty()) return; - Twine::Id merged = src_twines.concat(std::span{ids}); + Twine::Id merged = twines.concat(std::span{ids}); obj_set_src_id(target, merged); - src_twines.release(merged); + twines.release(merged); for (Twine::Id id : temp_interns) - src_twines.release(id); + twines.release(id); } namespace { @@ -1218,7 +1261,7 @@ namespace { size_t RTLIL::Design::gc_twines() { - size_t before = src_twines.size(); + size_t before = twines.size(); if (before == 0) return 0; @@ -1232,7 +1275,7 @@ size_t RTLIL::Design::gc_twines() // Sweep + compact: rebuild the pool keeping only reachable nodes, // receiving an old-id -> new-id remap. - dict remap = src_twines.gc(live); + dict remap = twines.gc(live); // Rewrite every meta-vector src_id through the remap. The pool was // rebuilt, so the old ids no longer mean anything — we update the @@ -1247,7 +1290,7 @@ size_t RTLIL::Design::gc_twines() auto it = remap.find(m.src); if (it == remap.end()) { m.src = Twine::Null; - if (m.name.empty()) { + if (m.name_id->is_dead()) { free_obj_meta(obj->meta_); obj->meta_ = nullptr; } @@ -1256,7 +1299,7 @@ size_t RTLIL::Design::gc_twines() m.src = it->second; }); - return before - src_twines.size(); + return before - twines.size(); } pool RTLIL::Design::src_leaves(const RTLIL::AttrObject *obj) const @@ -1265,7 +1308,7 @@ pool RTLIL::Design::src_leaves(const RTLIL::AttrObject *obj) const Twine::Id id = obj_src_id(obj); if (id == Twine::Null) return result; - const TwinePool *pool = &src_twines; + const TwinePool *pool = &twines; const Twine &n = (*pool)[id]; if (n.is_flat()) { result.insert(pool->flat_string(id)); @@ -1277,38 +1320,38 @@ pool RTLIL::Design::src_leaves(const RTLIL::AttrObject *obj) const return result; } -std::string RTLIL::AttrObject::strpool_attribute_to_str(const pool &data) -{ - string attrval; - for (const auto &s : data) { - if (!attrval.empty()) - attrval += "|"; - attrval += s; - } - return attrval; -} +// std::string RTLIL::AttrObject::strpool_attribute_to_str(const pool &data) +// { +// string attrval; +// for (const auto &s : data) { +// if (!attrval.empty()) +// attrval += "|"; +// attrval += s; +// } +// return attrval; +// } -void RTLIL::AttrObject::set_strpool_attribute(RTLIL::IdString id, const pool &data) -{ - set_string_attribute(id, strpool_attribute_to_str(data)); -} +// void RTLIL::AttrObject::set_strpool_attribute(IdString id, const pool &data) +// { +// set_string_attribute(id, strpool_attribute_to_str(data)); +// } -void RTLIL::AttrObject::add_strpool_attribute(RTLIL::IdString id, const pool &data) -{ - pool union_data = get_strpool_attribute(id); - union_data.insert(data.begin(), data.end()); - if (!union_data.empty()) - set_strpool_attribute(id, union_data); -} +// void RTLIL::AttrObject::add_strpool_attribute(IdString id, const pool &data) +// { +// pool union_data = get_strpool_attribute(id); +// union_data.insert(data.begin(), data.end()); +// if (!union_data.empty()) +// set_strpool_attribute(id, union_data); +// } -pool RTLIL::AttrObject::get_strpool_attribute(RTLIL::IdString id) const -{ - pool data; - if (attributes.count(id) != 0) - for (auto s : split_tokens(get_string_attribute(id), "|")) - data.insert(s); - return data; -} +// pool RTLIL::AttrObject::get_strpool_attribute(IdString id) const +// { +// pool data; +// if (attributes.count(id) != 0) +// for (auto s : split_tokens(get_string_attribute(id), "|")) +// data.insert(s); +// return data; +// } void RTLIL::AttrObject::set_hdlname_attribute(const vector &hierarchy) { @@ -1326,7 +1369,7 @@ vector RTLIL::AttrObject::get_hdlname_attribute() const return split_tokens(get_string_attribute(ID::hdlname), " "); } -void RTLIL::AttrObject::set_intvec_attribute(RTLIL::IdString id, const vector &data) +void RTLIL::AttrObject::set_intvec_attribute(IdString id, const vector &data) { std::stringstream attrval; for (auto &i : data) { @@ -1337,7 +1380,7 @@ void RTLIL::AttrObject::set_intvec_attribute(RTLIL::IdString id, const vector RTLIL::AttrObject::get_intvec_attribute(RTLIL::IdString id) const +vector RTLIL::AttrObject::get_intvec_attribute(IdString id) const { vector data; auto it = attributes.find(id); @@ -1355,10 +1398,11 @@ vector RTLIL::AttrObject::get_intvec_attribute(RTLIL::IdString id) const return data; } -bool RTLIL::Selection::boxed_module(RTLIL::IdString mod_name) const +bool RTLIL::Selection::boxed_module(Twine::Id mod_name) const { if (current_design != nullptr) { auto module = current_design->module(mod_name); + // auto module = current_design->module(mod_name); return module && module->get_blackbox_attribute(); } else { log_warning("Unable to check if module is boxed for null design.\n"); @@ -1366,7 +1410,7 @@ bool RTLIL::Selection::boxed_module(RTLIL::IdString mod_name) const } } -bool RTLIL::Selection::selected_module(RTLIL::IdString mod_name) const +bool RTLIL::Selection::selected_module(Twine::Id mod_name) const { if (complete_selection) return true; @@ -1381,7 +1425,7 @@ bool RTLIL::Selection::selected_module(RTLIL::IdString mod_name) const return false; } -bool RTLIL::Selection::selected_whole_module(RTLIL::IdString mod_name) const +bool RTLIL::Selection::selected_whole_module(Twine::Id mod_name) const { if (complete_selection) return true; @@ -1394,7 +1438,7 @@ bool RTLIL::Selection::selected_whole_module(RTLIL::IdString mod_name) const return false; } -bool RTLIL::Selection::selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const +bool RTLIL::Selection::selected_member(Twine::Id mod_name, Twine::Id memb_name) const { if (complete_selection) return true; @@ -1428,7 +1472,7 @@ void RTLIL::Selection::optimize(RTLIL::Design *design) return; } - std::vector del_list, add_list; + std::vector del_list, add_list; del_list.clear(); for (auto mod_name : selected_modules) { @@ -1516,20 +1560,33 @@ std::map *RTLIL::Design::get_all_designs(void) return &all_designs; } -RTLIL::ObjRange RTLIL::Design::modules() +RTLIL::ObjRange RTLIL::Design::modules() { - return RTLIL::ObjRange(&modules_, &refcount_modules_); + return RTLIL::ObjRange(&modules_, &refcount_modules_); } -RTLIL::Module *RTLIL::Design::module(RTLIL::IdString name) -{ - return modules_.count(name) ? modules_.at(name) : NULL; +RTLIL::Module *RTLIL::Design::module(IdString id) { + auto t = twines.lookup(id.c_str()); + if (t) + return module(t); + return nullptr; } -const RTLIL::Module *RTLIL::Design::module(RTLIL::IdString name) const -{ - return modules_.count(name) ? modules_.at(name) : NULL; +const RTLIL::Module *RTLIL::Design::module(Twine::Id id) const { + return modules_.count(id) ? modules_.at(id) : NULL; } +RTLIL::Module *RTLIL::Design::module(Twine::Id id) { + return modules_.count(id) ? modules_.at(id) : NULL; +} +// RTLIL::Module *RTLIL::Design::module(Twine::Id name) +// { +// return modules_.count(name) ? modules_.at(name) : NULL; +// } + +// const RTLIL::Module *RTLIL::Design::module(Twine::Id name) const +// { +// return modules_.count(name) ? modules_.at(name) : NULL; +// } RTLIL::Module *RTLIL::Design::top_module() const { @@ -1552,7 +1609,7 @@ void RTLIL::Design::add(RTLIL::Binding *binding) bindings_.push_back(binding); } -RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name) +RTLIL::Module *RTLIL::Design::addModule(Twine::Id name) { if (modules_.count(name) != 0) log_error("Attempted to add new module named '%s', but a module by that name already exists\n", name); @@ -1561,7 +1618,7 @@ RTLIL::Module *RTLIL::Design::addModule(RTLIL::IdString name) RTLIL::Module *module = new RTLIL::Module; modules_[name] = module; module->design = this; - module->name = name; + module->meta_->name_id = name; for (auto mon : monitors) mon->notify_module_add(module); @@ -1655,10 +1712,10 @@ void RTLIL::Design::remove(RTLIL::Module *module) delete module; } -void RTLIL::Design::rename(RTLIL::Module *module, RTLIL::IdString new_name) +void RTLIL::Design::rename(RTLIL::Module *module, Twine::Id new_name) { modules_.erase(module->name); - module->name = new_name; + module->meta_->name_id = new_name; add(module); } @@ -1689,7 +1746,7 @@ void RTLIL::Design::check() for (auto &it : modules_) { log_assert(this == it.second->design); log_assert(it.first == it.second->name); - log_assert(!it.first.empty()); + // log_assert(!it.first.empty()); check_module(it.second, thread_pool); } #endif @@ -1708,28 +1765,28 @@ void RTLIL::Design::optimize() void RTLIL::Design::clone_into(RTLIL::Design *dst) const { log_assert(dst->modules_.empty()); - dst->src_twines = src_twines; + dst->twines = twines; for (auto it = modules_.rbegin(); it != modules_.rend(); ++it) it->second->clone(dst, /*src_id_verbatim=*/true); } -bool RTLIL::Design::selected_module(RTLIL::IdString mod_name) const +bool RTLIL::Design::selected_module(Twine::Id mod_name) const { - if (!selected_active_module.empty() && mod_name != selected_active_module) + if (selected_active_module && mod_name != selected_active_module) return false; return selection().selected_module(mod_name); } -bool RTLIL::Design::selected_whole_module(RTLIL::IdString mod_name) const +bool RTLIL::Design::selected_whole_module(Twine::Id mod_name) const { - if (!selected_active_module.empty() && mod_name != selected_active_module) + if (selected_active_module && mod_name != selected_active_module) return false; return selection().selected_whole_module(mod_name); } -bool RTLIL::Design::selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const +bool RTLIL::Design::selected_member(Twine::Id mod_name, Twine::Id memb_name) const { - if (!selected_active_module.empty() && mod_name != selected_active_module) + if (selected_active_module && mod_name != selected_active_module) return false; return selection().selected_member(mod_name, memb_name); } @@ -1795,22 +1852,22 @@ std::vector RTLIL::Design::selected_modules(RTLIL::SelectPartial switch (boxes) { case RTLIL::SB_UNBOXED_WARN: - log_warning("Ignoring boxed module %s.\n", it.first.unescape()); + log_warning("Ignoring boxed module %s.\n", it.first->unescape()); break; case RTLIL::SB_EXCL_BB_WARN: - log_warning("Ignoring blackbox module %s.\n", it.first.unescape()); + log_warning("Ignoring blackbox module %s.\n", it.first->unescape()); break; case RTLIL::SB_UNBOXED_ERR: - log_error("Unsupported boxed module %s.\n", it.first.unescape()); + log_error("Unsupported boxed module %s.\n", it.first->unescape()); break; case RTLIL::SB_EXCL_BB_ERR: - log_error("Unsupported blackbox module %s.\n", it.first.unescape()); + log_error("Unsupported blackbox module %s.\n", it.first->unescape()); break; case RTLIL::SB_UNBOXED_CMDERR: - log_cmd_error("Unsupported boxed module %s.\n", it.first.unescape()); + log_cmd_error("Unsupported boxed module %s.\n", it.first->unescape()); break; case RTLIL::SB_EXCL_BB_CMDERR: - log_cmd_error("Unsupported blackbox module %s.\n", it.first.unescape()); + log_cmd_error("Unsupported blackbox module %s.\n", it.first->unescape()); break; default: break; @@ -1819,13 +1876,13 @@ std::vector RTLIL::Design::selected_modules(RTLIL::SelectPartial switch(partials) { case RTLIL::SELECT_WHOLE_WARN: - log_warning("Ignoring partially selected module %s.\n", it.first.unescape()); + log_warning("Ignoring partially selected module %s.\n", it.first->unescape()); break; case RTLIL::SELECT_WHOLE_ERR: - log_error("Unsupported partially selected module %s.\n", it.first.unescape()); + log_error("Unsupported partially selected module %s.\n", it.first->unescape()); break; case RTLIL::SELECT_WHOLE_CMDERR: - log_cmd_error("Unsupported partially selected module %s.\n", it.first.unescape()); + log_cmd_error("Unsupported partially selected module %s.\n", it.first->unescape()); break; default: break; @@ -1843,6 +1900,7 @@ RTLIL::Module::Module() design = nullptr; refcount_wires_ = 0; refcount_cells_ = 0; + meta_ = ObjMeta(); #ifdef YOSYS_ENABLE_PYTHON RTLIL::Module::get_all_modules()->insert(std::pair(hashidx_, this)); @@ -1907,7 +1965,7 @@ std::string RTLIL::Module::get_src_attribute() const return design->get_src_attribute(this); } -void RTLIL::Module::absorb_attrs(dict &&buf) +void RTLIL::Module::absorb_attrs(dict &&buf) { log_assert(design && "Module::absorb_attrs requires the module to be attached to a design"); design->absorb_attrs(this, std::move(buf)); @@ -1947,7 +2005,7 @@ void RTLIL::Module::makeblackbox() set_bool_attribute(ID::blackbox); } -void RTLIL::Module::expand_interfaces(RTLIL::Design *, const dict &) +void RTLIL::Module::expand_interfaces(RTLIL::Design *, const dict &) { log_error("Class doesn't support expand_interfaces (module: `%s')!\n", name.unescape()); } @@ -1957,24 +2015,28 @@ bool RTLIL::Module::reprocess_if_necessary(RTLIL::Design *) return false; } -RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict &, bool mayfail) +Twine::Id RTLIL::Module::derive(RTLIL::Design*, const dict &, bool mayfail) { if (mayfail) - return RTLIL::IdString(); + return Twine::Id(); log_error("Module `%s' is used with parameters but is not parametric!\n", name.unescape()); } -RTLIL::IdString RTLIL::Module::derive(RTLIL::Design*, const dict &, const dict &, const dict &, bool mayfail) +Twine::Id RTLIL::Module::derive(RTLIL::Design*, const dict &, const dict &, const dict &, bool mayfail) { if (mayfail) - return RTLIL::IdString(); + return Twine::Id(); log_error("Module `%s' is used with parameters but is not parametric!\n", name.unescape()); } -size_t RTLIL::Module::count_id(RTLIL::IdString id) +size_t RTLIL::Module::count_id(Twine::Id id) { - return wires_.count(id) + memories.count(id) + cells_.count(id) + processes.count(id); + Twine::Id tid = design->twines.lookup(id.str()); + size_t n = memories.count(id) + processes.count(id); + if (tid != Twine::Null) + n += wires_.count(tid) + cells_.count(tid); + return n; } #ifndef NDEBUG @@ -1983,7 +2045,7 @@ namespace { { const RTLIL::Module *module; RTLIL::Cell *cell; - pool expected_params, expected_ports; + pool expected_params, expected_ports; InternalCellChecker(const RTLIL::Module *module, RTLIL::Cell *cell) : module(module), cell(cell) { } @@ -1997,7 +2059,7 @@ namespace { cell->name.c_str(), cell->type.c_str(), __FILE__, linenr, buf.str().c_str()); } - int param(RTLIL::IdString name) + int param(Twine::Id name) { auto it = cell->parameters.find(name); if (it == cell->parameters.end()) @@ -2006,7 +2068,7 @@ namespace { return it->second.as_int(); } - int param_bool(RTLIL::IdString name) + int param_bool(Twine::Id name) { int v = param(name); if (GetSize(cell->parameters.at(name)) > 32) @@ -2016,7 +2078,7 @@ namespace { return v; } - int param_bool(RTLIL::IdString name, bool expected) + int param_bool(Twine::Id name, bool expected) { int v = param_bool(name); if (v != expected) @@ -2024,20 +2086,20 @@ namespace { return v; } - void param_bits(RTLIL::IdString name, int width) + void param_bits(Twine::Id name, int width) { param(name); if (GetSize(cell->parameters.at(name)) != width) error(__LINE__); } - std::string param_string(RTLIL::IdString name) + std::string param_string(Twine::Id name) { param(name); return cell->parameters.at(name).decode_string(); } - void port(RTLIL::IdString name, int width) + void port(Twine::Id name, int width) { auto it = cell->connections_.find(name); if (it == cell->connections_.end()) @@ -2954,8 +3016,11 @@ namespace { void RTLIL::Module::sort() { - wires_.sort(sort_by_id_str()); - cells_.sort(sort_by_id_str()); + auto sort_twine_by_str = [this](Twine::Id a, Twine::Id b) { + return design->twines.flat_string(a) < design->twines.flat_string(b); + }; + wires_.sort(sort_twine_by_str); + cells_.sort(sort_twine_by_str); parameter_default_values.sort(sort_by_id_str()); memories.sort(sort_by_id_str()); processes.sort(sort_by_id_str()); @@ -2990,8 +3055,8 @@ void check_module(RTLIL::Module *module, ParallelDispatchThreadPool &thread_pool for (int i : ctx.item_range(const_module->cells_size())) { auto it = *const_module->cells_.element(i); log_assert(const_module == it.second->module); - log_assert(it.first == it.second->name); - log_assert(!it.first.empty()); + log_assert(it.second->meta_ && it.first == it.second->meta_->name_id); + log_assert(it.first != Twine::Null); log_assert(!it.second->type.empty()); for (auto &it2 : it.second->connections()) { log_assert(!it2.first.empty()); @@ -3010,7 +3075,7 @@ void check_module(RTLIL::Module *module, ParallelDispatchThreadPool &thread_pool log_assert(!memory_strings.count(memid)); memids.insert(ctx, std::move(memid)); } - auto cell_mod = const_module->design->module(it.first); + auto cell_mod = const_module->design->module(Twine::Id(it.second->name)); if (cell_mod != nullptr) { // assertion check below to make sure that there are no // cases where a cell has a blackbox attribute since @@ -3029,15 +3094,15 @@ void check_module(RTLIL::Module *module, ParallelDispatchThreadPool &thread_pool for (int i : ctx.item_range(const_module->wires_size())) { auto it = *const_module->wires_.element(i); log_assert(const_module == it.second->module); - log_assert(it.first == it.second->name); - log_assert(!it.first.empty()); + log_assert(it.second->meta_ && it.first == it.second->meta_->name_id); + log_assert(it.first != Twine::Null); log_assert(it.second->width >= 0); log_assert(it.second->port_id >= 0); for (auto &it2 : it.second->attributes) log_assert(!it2.first.empty()); if (it.second->port_id) { log_assert(GetSize(const_module->ports) >= it.second->port_id); - log_assert(const_module->ports.at(it.second->port_id-1) == it.first); + log_assert(const_module->ports.at(it.second->port_id-1) == Twine::Id(it.second->name)); log_assert(it.second->port_input || it.second->port_output); log_assert(it.second->port_id <= GetSize(ports_declared)); bool previously_declared = ports_declared[it.second->port_id-1].set_and_return_old(); @@ -3122,7 +3187,7 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons for (auto &attr : attributes) new_mod->attributes[attr.first] = attr.second; if (src_id_verbatim) { - // Caller (Design::clone_into) copied src_twines wholesale, so + // Caller (Design::clone_into) copied twines wholesale, so // Twine::Ids preserve their meaning. Allocate per-AttrObject // meta in dst's pool and copy the fields. dst's twine refcounts // were inherited via the wholesale copy and already account for @@ -3146,17 +3211,28 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons } if (src_id_verbatim) { - // Per-AttrObject meta clone via dst design's pool. Twine::Ids - // transfer verbatim because the src_twines copy is wholesale. - auto copy_meta = [&](const RTLIL::AttrObject *src, RTLIL::AttrObject *dst) { - if (src->meta_ && new_mod->design) { - dst->meta_ = new_mod->design->alloc_obj_meta(); - *dst->meta_ = *src->meta_; - } + // Per-AttrObject meta clone via dst design's pool. Twine::Ids for + // src attributes transfer verbatim (twines was wholesale-copied). + // name_id is re-interned by addWire/addCell; copy_meta restores it. + auto copy_meta = [&](const RTLIL::AttrObject *src_obj, RTLIL::AttrObject *dst_obj) { + if (!src_obj->meta_ || !new_mod->design) + return; + // Preserve name_id already set by addWire/addCell (in dst's pool). + Twine::Id saved_name_id = dst_obj->meta_ ? dst_obj->meta_->name_id : Twine::Null; + // Recycle old meta slot (no field releases — name_id's retain lives on). + if (dst_obj->meta_) + new_mod->design->free_obj_meta(dst_obj->meta_); + // Alloc new meta and struct-copy (src field is valid; name_id from + // src pool is stale and will be overwritten). + dst_obj->meta_ = new_mod->design->alloc_obj_meta(); + *dst_obj->meta_ = *src_obj->meta_; + dst_obj->meta_->name_id = saved_name_id; }; for (auto it = wires_.rbegin(); it != wires_.rend(); ++it) { const RTLIL::Wire *o = it->second; - RTLIL::Wire *w = new_mod->addWire(it->first, o->width); + Twine::Id dst_name_id = new_mod->design->twines.copy_from(design->twines, it->first); + RTLIL::Wire *w = new_mod->addWire(dst_name_id, o->width); + new_mod->design->twines.release(dst_name_id); w->start_offset = o->start_offset; w->port_id = o->port_id; w->port_input = o->port_input; @@ -3177,7 +3253,9 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons } for (auto it = cells_.rbegin(); it != cells_.rend(); ++it) { const RTLIL::Cell *o = it->second; - RTLIL::Cell *c = new_mod->addCell(it->first, o->type); + Twine::Id dst_name_id = new_mod->design->twines.copy_from(design->twines, it->first); + RTLIL::Cell *c = new_mod->addCell(dst_name_id, o->type); + new_mod->design->twines.release(dst_name_id); c->connections_ = o->connections_; c->parameters = o->parameters; c->attributes = o->attributes; @@ -3223,14 +3301,23 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons // originally interned them — that lets write_rtlil emit // byte-equal "@N" refs across single-module clones into an // existing destination design. - for (auto it = wires_.rbegin(); it != wires_.rend(); ++it) - new_mod->addWire(it->first, it->second); + // Re-intern each wire/cell name from the source design's pool into + // the destination design's pool. copy_from is a no-op if both + // designs share the same pool (same-design clone). + for (auto it = wires_.rbegin(); it != wires_.rend(); ++it) { + Twine::Id dst_id = new_mod->design->twines.copy_from(design->twines, it->first); + new_mod->addWire(dst_id, it->second); + new_mod->design->twines.release(dst_id); + } for (auto it = memories.rbegin(); it != memories.rend(); ++it) new_mod->addMemory(it->first, it->second); - for (auto it = cells_.rbegin(); it != cells_.rend(); ++it) - new_mod->addCell(it->first, it->second); + for (auto it = cells_.rbegin(); it != cells_.rend(); ++it) { + Twine::Id dst_id = new_mod->design->twines.copy_from(design->twines, it->first); + new_mod->addCell(dst_id, it->second); + new_mod->design->twines.release(dst_id); + } for (auto it = processes.rbegin(); it != processes.rend(); ++it) new_mod->addProcess(it->first, it->second); @@ -3242,7 +3329,10 @@ void RTLIL::Module::cloneInto(RTLIL::Module *new_mod, bool src_id_verbatim) cons void operator()(RTLIL::SigSpec &sig) { sig.rewrite_wires([this](RTLIL::Wire *&wire) { - wire = mod->wires_.at(wire->name); + // wire points to original module; look up by name in new module. + // Use the IdString materialisation path: works for both same-design + // and cross-design clones without assuming pool identity. + wire = mod->wire(Twine::Id(wire->name)); }); } }; @@ -3272,7 +3362,7 @@ RTLIL::Module *RTLIL::Module::clone(RTLIL::Design *dst, bool src_id_verbatim) co return new_mod; } -RTLIL::Module *RTLIL::Module::clone(RTLIL::Design *dst, RTLIL::IdString target_name, bool src_id_verbatim) const +RTLIL::Module *RTLIL::Module::clone(RTLIL::Design *dst, Twine::Id target_name, bool src_id_verbatim) const { RTLIL::Module *new_mod = new RTLIL::Module; new_mod->design = dst; @@ -3372,19 +3462,21 @@ std::vector RTLIL::Module::selected_members() const void RTLIL::Module::add(RTLIL::Wire *wire) { - log_assert(!wire->name.empty()); - log_assert(count_id(wire->name) == 0); + log_assert(wire->meta_ && wire->meta_->name_id != Twine::Null); + Twine::Id id = wire->meta_->name_id; + log_assert(wires_.count(id) == 0); log_assert(refcount_wires_ == 0); - wires_[wire->name] = wire; + wires_[id] = wire; wire->module = this; } void RTLIL::Module::add(RTLIL::Cell *cell) { - log_assert(!cell->name.empty()); - log_assert(count_id(cell->name) == 0); + log_assert(cell->meta_ && cell->meta_->name_id != Twine::Null); + Twine::Id id = cell->meta_->name_id; + log_assert(cells_.count(id) == 0); log_assert(refcount_cells_ == 0); - cells_[cell->name] = cell; + cells_[id] = cell; cell->module = this; } @@ -3449,9 +3541,11 @@ void RTLIL::Module::remove(const pool &wires) } for (auto &it : wires) { - log_assert(wires_.count(it->name) != 0); - wires_.erase(it->name); - delete it; + log_assert(it->meta_ && it->meta_->name_id != Twine::Null); + Twine::Id id = it->meta_->name_id; + log_assert(wires_.count(id) != 0); + wires_.erase(id); + delete it; // Wire::~Wire releases src and name_id } } @@ -3469,72 +3563,82 @@ void RTLIL::Module::remove(RTLIL::Process *process) delete process; } -void RTLIL::Module::rename(RTLIL::Wire *wire, RTLIL::IdString new_name) +void RTLIL::Module::rename(RTLIL::Wire *wire, Twine::Id new_name) { - log_assert(wires_[wire->name] == wire); + log_assert(wire->meta_ && wire->meta_->name_id != Twine::Null); + Twine::Id old_id = wire->meta_->name_id; + log_assert(wires_[old_id] == wire); log_assert(refcount_wires_ == 0); - wires_.erase(wire->name); - wire->name = new_name; + wires_.erase(old_id); + Twine::Id new_id = design->twines.intern(new_name.str()); + design->obj_set_name_id(wire, new_id); + design->twines.release(new_id); add(wire); } -void RTLIL::Module::rename(RTLIL::Cell *cell, RTLIL::IdString new_name) +void RTLIL::Module::rename(RTLIL::Cell *cell, Twine::Id new_name) { - log_assert(cells_[cell->name] == cell); - log_assert(refcount_wires_ == 0); - cells_.erase(cell->name); - cell->name = new_name; + log_assert(cell->meta_ && cell->meta_->name_id != Twine::Null); + Twine::Id old_id = cell->meta_->name_id; + log_assert(cells_[old_id] == cell); + log_assert(refcount_cells_ == 0); + cells_.erase(old_id); + Twine::Id new_id = design->twines.intern(new_name.str()); + design->obj_set_name_id(cell, new_id); + design->twines.release(new_id); add(cell); } -void RTLIL::Module::rename(RTLIL::IdString old_name, RTLIL::IdString new_name) +void RTLIL::Module::rename(Twine::Id old_name, Twine::Id new_name) { - log_assert(count_id(old_name) != 0); - if (wires_.count(old_name)) - rename(wires_.at(old_name), new_name); - else if (cells_.count(old_name)) - rename(cells_.at(old_name), new_name); + Twine::Id old_id = design->twines.lookup(old_name.str()); + if (old_id != Twine::Null && wires_.count(old_id)) + rename(wires_.at(old_id), new_name); + else if (old_id != Twine::Null && cells_.count(old_id)) + rename(cells_.at(old_id), new_name); else log_abort(); } void RTLIL::Module::swap_names(RTLIL::Wire *w1, RTLIL::Wire *w2) { - log_assert(wires_[w1->name] == w1); - log_assert(wires_[w2->name] == w2); + log_assert(w1->meta_ && w1->meta_->name_id != Twine::Null); + log_assert(w2->meta_ && w2->meta_->name_id != Twine::Null); + Twine::Id id1 = w1->meta_->name_id; + Twine::Id id2 = w2->meta_->name_id; + log_assert(wires_[id1] == w1); + log_assert(wires_[id2] == w2); log_assert(refcount_wires_ == 0); - wires_.erase(w1->name); - wires_.erase(w2->name); - - std::swap(w1->name, w2->name); - - wires_[w1->name] = w1; - wires_[w2->name] = w2; + // Swap dict entries and name_ids; refcounts don't change. + wires_[id1] = w2; + wires_[id2] = w1; + std::swap(w1->meta_->name_id, w2->meta_->name_id); } void RTLIL::Module::swap_names(RTLIL::Cell *c1, RTLIL::Cell *c2) { - log_assert(cells_[c1->name] == c1); - log_assert(cells_[c2->name] == c2); + log_assert(c1->meta_ && c1->meta_->name_id != Twine::Null); + log_assert(c2->meta_ && c2->meta_->name_id != Twine::Null); + Twine::Id id1 = c1->meta_->name_id; + Twine::Id id2 = c2->meta_->name_id; + log_assert(cells_[id1] == c1); + log_assert(cells_[id2] == c2); log_assert(refcount_cells_ == 0); - cells_.erase(c1->name); - cells_.erase(c2->name); - - std::swap(c1->name, c2->name); - - cells_[c1->name] = c1; - cells_[c2->name] = c2; + // Swap dict entries and name_ids; refcounts don't change. + cells_[id1] = c2; + cells_[id2] = c1; + std::swap(c1->meta_->name_id, c2->meta_->name_id); } -RTLIL::IdString RTLIL::Module::uniquify(RTLIL::IdString name) +Twine::Id RTLIL::Module::uniquify(Twine::Id name) { int index = 0; return uniquify(name, index); } -RTLIL::IdString RTLIL::Module::uniquify(RTLIL::IdString name, int &index) +Twine::Id RTLIL::Module::uniquify(Twine::Id name, int &index) { if (index == 0) { if (count_id(name) == 0) @@ -3543,7 +3647,7 @@ RTLIL::IdString RTLIL::Module::uniquify(RTLIL::IdString name, int &index) } while (1) { - RTLIL::IdString new_name = stringf("%s_%d", name, index); + Twine::Id new_name = stringf("%s_%d", name, index); if (count_id(new_name) == 0) return new_name; index++; @@ -3626,18 +3730,28 @@ void RTLIL::Module::fixup_ports() } } -RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, int width) +RTLIL::Wire *RTLIL::Module::addWire(Twine::Id name, int width) { + log_assert(design); RTLIL::Wire *wire = new RTLIL::Wire(Wire::ConstructToken{}); - wire->name = std::move(name); wire->width = width; + design->obj_set_name_id(wire, name); add(wire); return wire; } -RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, const RTLIL::Wire *other) +RTLIL::Wire *RTLIL::Module::addWire(Twine::Id name, int width) { - RTLIL::Wire *wire = addWire(std::move(name)); + log_assert(design); + Twine::Id id = design->twines.intern(name.str()); + RTLIL::Wire *wire = addWire(id, width); + design->twines.release(id); + return wire; +} + +RTLIL::Wire *RTLIL::Module::addWire(Twine::Id name, const RTLIL::Wire *other) +{ + RTLIL::Wire *wire = addWire(name); wire->width = other->width; wire->start_offset = other->start_offset; wire->port_id = other->port_id; @@ -3654,18 +3768,37 @@ RTLIL::Wire *RTLIL::Module::addWire(RTLIL::IdString name, const RTLIL::Wire *oth return wire; } -RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, RTLIL::IdString type) +RTLIL::Wire *RTLIL::Module::addWire(Twine::Id name, const RTLIL::Wire *other) { + log_assert(design); + Twine::Id id = design->twines.intern(name.str()); + RTLIL::Wire *wire = addWire(id, other); + design->twines.release(id); + return wire; +} + +RTLIL::Cell *RTLIL::Module::addCell(Twine::Id name, Twine::Id type) +{ + log_assert(design); RTLIL::Cell *cell = new RTLIL::Cell(Cell::ConstructToken{}); - cell->name = std::move(name); cell->type = type; + design->obj_set_name_id(cell, name); add(cell); return cell; } -RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *other) +RTLIL::Cell *RTLIL::Module::addCell(Twine::Id name, Twine::Id type) { - RTLIL::Cell *cell = addCell(std::move(name), other->type); + log_assert(design); + Twine::Id id = design->twines.intern(name.str()); + RTLIL::Cell *cell = addCell(id, type); + design->twines.release(id); + return cell; +} + +RTLIL::Cell *RTLIL::Module::addCell(Twine::Id name, const RTLIL::Cell *other) +{ + RTLIL::Cell *cell = addCell(name, other->type); cell->connections_ = other->connections_; cell->parameters = other->parameters; cell->attributes = other->attributes; @@ -3677,7 +3810,16 @@ RTLIL::Cell *RTLIL::Module::addCell(RTLIL::IdString name, const RTLIL::Cell *oth return cell; } -RTLIL::Memory *RTLIL::Module::addMemory(RTLIL::IdString name) +RTLIL::Cell *RTLIL::Module::addCell(Twine::Id name, const RTLIL::Cell *other) +{ + log_assert(design); + Twine::Id id = design->twines.intern(name.str()); + RTLIL::Cell *cell = addCell(id, other); + design->twines.release(id); + return cell; +} + +RTLIL::Memory *RTLIL::Module::addMemory(Twine::Id name) { RTLIL::Memory *mem = new RTLIL::Memory; mem->name = std::move(name); @@ -3686,7 +3828,7 @@ RTLIL::Memory *RTLIL::Module::addMemory(RTLIL::IdString name) return mem; } -RTLIL::Memory *RTLIL::Module::addMemory(RTLIL::IdString name, const RTLIL::Memory *other) +RTLIL::Memory *RTLIL::Module::addMemory(Twine::Id name, const RTLIL::Memory *other) { RTLIL::Memory *mem = new RTLIL::Memory; mem->name = std::move(name); @@ -3705,7 +3847,7 @@ RTLIL::Memory *RTLIL::Module::addMemory(RTLIL::IdString name, const RTLIL::Memor return mem; } -RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name) +RTLIL::Process *RTLIL::Module::addProcess(Twine::Id name) { RTLIL::Process *proc = new RTLIL::Process; proc->name = std::move(name); @@ -3754,7 +3896,7 @@ namespace { } } -RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Process *other) +RTLIL::Process *RTLIL::Module::addProcess(Twine::Id name, const RTLIL::Process *other) { RTLIL::Process *proc = other->clone(); proc->name = std::move(name); @@ -3776,7 +3918,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro } #define DEF_METHOD(_func, _y_size, _type) \ - template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed, const RTLIL::SrcAttr &src) { \ + template RTLIL::Cell* CellAdderMixin::add ## _func(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool is_signed, const RTLIL::SrcAttr &src) { \ RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ cell->parameters[ID::A_SIGNED] = is_signed; \ cell->parameters[ID::A_WIDTH] = sig_a.size(); \ @@ -3786,7 +3928,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro cell->set_src_attribute(src); \ return cell; \ } \ - template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed, const RTLIL::SrcAttr &src) { \ + template RTLIL::SigSpec CellAdderMixin::_func(Twine::Id name, const RTLIL::SigSpec &sig_a, bool is_signed, const RTLIL::SrcAttr &src) { \ RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, _y_size); \ add ## _func(name, sig_a, sig_y, is_signed, src); \ return sig_y; \ @@ -3803,7 +3945,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro #undef DEF_METHOD #define DEF_METHOD(_func, _y_size, _type) \ - template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool /* is_signed */, const RTLIL::SrcAttr &src) { \ + template RTLIL::Cell* CellAdderMixin::add ## _func(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, bool /* is_signed */, const RTLIL::SrcAttr &src) { \ RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ cell->parameters[ID::WIDTH] = sig_a.size(); \ cell->setPort(ID::A, sig_a); \ @@ -3811,7 +3953,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro cell->set_src_attribute(src); \ return cell; \ } \ - template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, bool is_signed, const RTLIL::SrcAttr &src) { \ + template RTLIL::SigSpec CellAdderMixin::_func(Twine::Id name, const RTLIL::SigSpec &sig_a, bool is_signed, const RTLIL::SrcAttr &src) { \ RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, _y_size); \ add ## _func(name, sig_a, sig_y, is_signed, src); \ return sig_y; \ @@ -3820,7 +3962,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro #undef DEF_METHOD #define DEF_METHOD(_func, _y_size, _type) \ - template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const RTLIL::SrcAttr &src) { \ + template RTLIL::Cell* CellAdderMixin::add ## _func(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const RTLIL::SrcAttr &src) { \ RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ cell->parameters[ID::A_SIGNED] = is_signed; \ cell->parameters[ID::B_SIGNED] = is_signed; \ @@ -3833,7 +3975,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro cell->set_src_attribute(src); \ return cell; \ } \ - template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const RTLIL::SrcAttr &src) { \ + template RTLIL::SigSpec CellAdderMixin::_func(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const RTLIL::SrcAttr &src) { \ RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, _y_size); \ add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \ return sig_y; \ @@ -3863,7 +4005,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro #undef DEF_METHOD #define DEF_METHOD(_func, _y_size, _type) \ - template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const RTLIL::SrcAttr &src) { \ + template RTLIL::Cell* CellAdderMixin::add ## _func(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const RTLIL::SrcAttr &src) { \ RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ cell->parameters[ID::A_SIGNED] = is_signed; \ cell->parameters[ID::B_SIGNED] = false; \ @@ -3876,7 +4018,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro cell->set_src_attribute(src); \ return cell; \ } \ - template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const RTLIL::SrcAttr &src) { \ + template RTLIL::SigSpec CellAdderMixin::_func(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const RTLIL::SrcAttr &src) { \ RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, _y_size); \ add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \ return sig_y; \ @@ -3888,7 +4030,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro #undef DEF_METHOD #define DEF_METHOD(_func, _y_size, _type) \ - template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const RTLIL::SrcAttr &src) { \ + template RTLIL::Cell* CellAdderMixin::add ## _func(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool is_signed, const RTLIL::SrcAttr &src) { \ RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ cell->parameters[ID::A_SIGNED] = false; \ cell->parameters[ID::B_SIGNED] = is_signed; \ @@ -3901,7 +4043,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro cell->set_src_attribute(src); \ return cell; \ } \ - template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const RTLIL::SrcAttr &src) { \ + template RTLIL::SigSpec CellAdderMixin::_func(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, bool is_signed, const RTLIL::SrcAttr &src) { \ RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, _y_size); \ add ## _func(name, sig_a, sig_b, sig_y, is_signed, src); \ return sig_y; \ @@ -3910,7 +4052,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro #undef DEF_METHOD #define DEF_METHOD(_func, _type, _pmux) \ - template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) { \ + template RTLIL::Cell* CellAdderMixin::add ## _func(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) { \ RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ cell->parameters[ID::WIDTH] = sig_a.size(); \ if (_pmux) cell->parameters[ID::S_WIDTH] = sig_s.size(); \ @@ -3921,7 +4063,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro cell->set_src_attribute(src); \ return cell; \ } \ - template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SrcAttr &src) { \ + template RTLIL::SigSpec CellAdderMixin::_func(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_s, const RTLIL::SrcAttr &src) { \ RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, sig_a.size()); \ add ## _func(name, sig_a, sig_b, sig_s, sig_y, src); \ return sig_y; \ @@ -3932,7 +4074,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro #undef DEF_METHOD #define DEF_METHOD(_func, _type, _demux) \ - template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) { \ + template RTLIL::Cell* CellAdderMixin::add ## _func(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) { \ RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ cell->parameters[ID::WIDTH] = _demux ? sig_a.size() : sig_y.size(); \ cell->parameters[ID::S_WIDTH] = sig_s.size(); \ @@ -3942,7 +4084,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro cell->set_src_attribute(src); \ return cell; \ } \ - template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SrcAttr &src) { \ + template RTLIL::SigSpec CellAdderMixin::_func(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SrcAttr &src) { \ RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, _demux ? sig_a.size() << sig_s.size() : sig_a.size() >> sig_s.size()); \ add ## _func(name, sig_a, sig_s, sig_y, src); \ return sig_y; \ @@ -3952,7 +4094,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro #undef DEF_METHOD #define DEF_METHOD(_func, _type) \ - template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) { \ + template RTLIL::Cell* CellAdderMixin::add ## _func(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) { \ RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ cell->parameters[ID::WIDTH] = sig_a.size(); \ cell->setPort(ID::A, sig_a); \ @@ -3961,7 +4103,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro cell->set_src_attribute(src); \ return cell; \ } \ - template RTLIL::SigSpec CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SrcAttr &src) { \ + template RTLIL::SigSpec CellAdderMixin::_func(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SrcAttr &src) { \ RTLIL::SigSpec sig_y = static_cast(this)->addWire(NEW_ID, sig_a.size()); \ add ## _func(name, sig_a, sig_s, sig_y, src); \ return sig_y; \ @@ -3970,20 +4112,20 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro #undef DEF_METHOD #define DEF_METHOD_2(_func, _type, _P1, _P2) \ - template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SrcAttr &src) { \ + template RTLIL::Cell* CellAdderMixin::add ## _func(Twine::Id name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SrcAttr &src) { \ RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ cell->setPort("\\" #_P1, sig1); \ cell->setPort("\\" #_P2, sig2); \ cell->set_src_attribute(src); \ return cell; \ } \ - template RTLIL::SigBit CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SrcAttr &src) { \ + template RTLIL::SigBit CellAdderMixin::_func(Twine::Id name, const RTLIL::SigBit &sig1, const RTLIL::SrcAttr &src) { \ RTLIL::SigBit sig2 = static_cast(this)->addWire(NEW_ID); \ add ## _func(name, sig1, sig2, src); \ return sig2; \ } #define DEF_METHOD_3(_func, _type, _P1, _P2, _P3) \ - template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SrcAttr &src) { \ + template RTLIL::Cell* CellAdderMixin::add ## _func(Twine::Id name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SrcAttr &src) { \ RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ cell->setPort("\\" #_P1, sig1); \ cell->setPort("\\" #_P2, sig2); \ @@ -3991,13 +4133,13 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro cell->set_src_attribute(src); \ return cell; \ } \ - template RTLIL::SigBit CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SrcAttr &src) { \ + template RTLIL::SigBit CellAdderMixin::_func(Twine::Id name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SrcAttr &src) { \ RTLIL::SigBit sig3 = static_cast(this)->addWire(NEW_ID); \ add ## _func(name, sig1, sig2, sig3, src); \ return sig3; \ } #define DEF_METHOD_4(_func, _type, _P1, _P2, _P3, _P4) \ - template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const RTLIL::SrcAttr &src) { \ + template RTLIL::Cell* CellAdderMixin::add ## _func(Twine::Id name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const RTLIL::SrcAttr &src) { \ RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ cell->setPort("\\" #_P1, sig1); \ cell->setPort("\\" #_P2, sig2); \ @@ -4006,13 +4148,13 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro cell->set_src_attribute(src); \ return cell; \ } \ - template RTLIL::SigBit CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SrcAttr &src) { \ + template RTLIL::SigBit CellAdderMixin::_func(Twine::Id name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SrcAttr &src) { \ RTLIL::SigBit sig4 = static_cast(this)->addWire(NEW_ID); \ add ## _func(name, sig1, sig2, sig3, sig4, src); \ return sig4; \ } #define DEF_METHOD_5(_func, _type, _P1, _P2, _P3, _P4, _P5) \ - template RTLIL::Cell* CellAdderMixin::add ## _func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const RTLIL::SigBit &sig5, const RTLIL::SrcAttr &src) { \ + template RTLIL::Cell* CellAdderMixin::add ## _func(Twine::Id name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const RTLIL::SigBit &sig5, const RTLIL::SrcAttr &src) { \ RTLIL::Cell *cell = static_cast(this)->addCell(name, _type); \ cell->setPort("\\" #_P1, sig1); \ cell->setPort("\\" #_P2, sig2); \ @@ -4022,7 +4164,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro cell->set_src_attribute(src); \ return cell; \ } \ - template RTLIL::SigBit CellAdderMixin::_func(RTLIL::IdString name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const RTLIL::SrcAttr &src) { \ + template RTLIL::SigBit CellAdderMixin::_func(Twine::Id name, const RTLIL::SigBit &sig1, const RTLIL::SigBit &sig2, const RTLIL::SigBit &sig3, const RTLIL::SigBit &sig4, const RTLIL::SrcAttr &src) { \ RTLIL::SigBit sig5 = static_cast(this)->addWire(NEW_ID); \ add ## _func(name, sig1, sig2, sig3, sig4, sig5, src); \ return sig5; \ @@ -4048,7 +4190,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro #undef DEF_METHOD_4 #undef DEF_METHOD_5 - template RTLIL::Cell* CellAdderMixin::addPow(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool a_signed, bool b_signed, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addPow(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, bool a_signed, bool b_signed, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($pow)); cell->parameters[ID::A_SIGNED] = a_signed; @@ -4063,7 +4205,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addFa(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_x, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addFa(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_x, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($fa)); cell->parameters[ID::WIDTH] = sig_a.size(); @@ -4076,7 +4218,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addSlice(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const offset, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addSlice(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const offset, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($slice)); cell->parameters[ID::A_WIDTH] = sig_a.size(); @@ -4088,7 +4230,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addConcat(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addConcat(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($concat)); cell->parameters[ID::A_WIDTH] = sig_a.size(); @@ -4100,7 +4242,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addLut(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const lut, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addLut(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_y, RTLIL::Const lut, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($lut)); cell->parameters[ID::LUT] = lut; @@ -4111,7 +4253,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addTribuf(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addTribuf(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($tribuf)); cell->parameters[ID::WIDTH] = sig_a.size(); @@ -4122,7 +4264,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addAssert(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addAssert(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($assert)); cell->setPort(ID::A, sig_a); @@ -4131,7 +4273,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addAssume(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addAssume(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($assume)); cell->setPort(ID::A, sig_a); @@ -4140,7 +4282,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addLive(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addLive(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($live)); cell->setPort(ID::A, sig_a); @@ -4149,7 +4291,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addFair(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addFair(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($fair)); cell->setPort(ID::A, sig_a); @@ -4158,7 +4300,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addCover(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addCover(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_en, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($cover)); cell->setPort(ID::A, sig_a); @@ -4167,7 +4309,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addEquiv(RTLIL::IdString name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addEquiv(Twine::Id name, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_b, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($equiv)); cell->setPort(ID::A, sig_a); @@ -4177,7 +4319,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addSr(RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addSr(Twine::Id name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($sr)); cell->parameters[ID::SET_POLARITY] = set_polarity; @@ -4190,7 +4332,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addFf(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addFf(Twine::Id name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($ff)); cell->parameters[ID::WIDTH] = sig_q.size(); @@ -4200,7 +4342,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addDff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addDff(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($dff)); cell->parameters[ID::CLK_POLARITY] = clk_polarity; @@ -4212,7 +4354,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addDffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addDffe(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($dffe)); cell->parameters[ID::CLK_POLARITY] = clk_polarity; @@ -4226,7 +4368,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addDffsr(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + template RTLIL::Cell* CellAdderMixin::addDffsr(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($dffsr)); @@ -4243,7 +4385,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addDffsre(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + template RTLIL::Cell* CellAdderMixin::addDffsre(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, bool set_polarity, bool clr_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($dffsre)); @@ -4262,7 +4404,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addAdff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addAdff(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity, bool arst_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($adff)); @@ -4278,7 +4420,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addAdffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addAdffe(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool clk_polarity, bool en_polarity, bool arst_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($adffe)); @@ -4296,7 +4438,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addAldff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addAldff(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool aload_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($aldff)); @@ -4312,7 +4454,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addAldffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addAldffe(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool en_polarity, bool aload_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($aldffe)); @@ -4330,7 +4472,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addSdff(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addSdff(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity, bool srst_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($sdff)); @@ -4346,7 +4488,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addSdffe(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addSdffe(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($sdffe)); @@ -4364,7 +4506,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addSdffce(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addSdffce(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($sdffce)); @@ -4382,7 +4524,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addDlatch(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addDlatch(Twine::Id name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($dlatch)); cell->parameters[ID::EN_POLARITY] = en_polarity; @@ -4394,7 +4536,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addAdlatch(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addAdlatch(Twine::Id name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, RTLIL::Const arst_value, bool en_polarity, bool arst_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($adlatch)); @@ -4410,7 +4552,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addDlatchsr(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + template RTLIL::Cell* CellAdderMixin::addDlatchsr(Twine::Id name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($dlatchsr)); @@ -4427,7 +4569,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addSrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + template RTLIL::Cell* CellAdderMixin::addSrGate(Twine::Id name, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, const RTLIL::SigSpec &sig_q, bool set_polarity, bool clr_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_SR_%c%c_", set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); @@ -4438,7 +4580,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addFfGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addFfGate(Twine::Id name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, ID($_FF_)); cell->setPort(ID::D, sig_d); @@ -4447,7 +4589,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addDffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addDffGate(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DFF_%c_", clk_polarity ? 'P' : 'N')); cell->setPort(ID::C, sig_clk); @@ -4457,7 +4599,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addDffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addDffeGate(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); cell->setPort(ID::C, sig_clk); @@ -4468,7 +4610,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addDffsrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + template RTLIL::Cell* CellAdderMixin::addDffsrGate(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool set_polarity, bool clr_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DFFSR_%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); @@ -4481,7 +4623,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addDffsreGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + template RTLIL::Cell* CellAdderMixin::addDffsreGate(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool clk_polarity, bool en_polarity, bool set_polarity, bool clr_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DFFSRE_%c%c%c%c_", clk_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); @@ -4495,7 +4637,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addAdffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addAdffGate(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool arst_value, bool clk_polarity, bool arst_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DFF_%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')); @@ -4507,7 +4649,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addAdffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addAdffeGate(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool arst_value, bool clk_polarity, bool en_polarity, bool arst_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0', en_polarity ? 'P' : 'N')); @@ -4520,7 +4662,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addAldffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addAldffGate(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool aload_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_ALDFF_%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N')); @@ -4533,7 +4675,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addAldffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addAldffeGate(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_aload, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SigSpec &sig_ad, bool clk_polarity, bool en_polarity, bool aload_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_ALDFFE_%c%c%c_", clk_polarity ? 'P' : 'N', aload_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N')); @@ -4547,7 +4689,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addSdffGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addSdffGate(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool srst_value, bool clk_polarity, bool srst_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_SDFF_%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0')); @@ -4559,7 +4701,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addSdffeGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addSdffeGate(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_SDFFE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')); @@ -4572,7 +4714,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addSdffceGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addSdffceGate(Twine::Id name, const RTLIL::SigSpec &sig_clk, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_srst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool srst_value, bool clk_polarity, bool en_polarity, bool srst_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_SDFFCE_%c%c%c%c_", clk_polarity ? 'P' : 'N', srst_polarity ? 'P' : 'N', srst_value ? '1' : '0', en_polarity ? 'P' : 'N')); @@ -4585,7 +4727,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addDlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const RTLIL::SrcAttr &src) + template RTLIL::Cell* CellAdderMixin::addDlatchGate(Twine::Id name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DLATCH_%c_", en_polarity ? 'P' : 'N')); cell->setPort(ID::E, sig_en); @@ -4595,7 +4737,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addAdlatchGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, + template RTLIL::Cell* CellAdderMixin::addAdlatchGate(Twine::Id name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_arst, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, bool arst_value, bool en_polarity, bool arst_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DLATCH_%c%c%c_", en_polarity ? 'P' : 'N', arst_polarity ? 'P' : 'N', arst_value ? '1' : '0')); @@ -4607,7 +4749,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } - template RTLIL::Cell* CellAdderMixin::addDlatchsrGate(RTLIL::IdString name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, + template RTLIL::Cell* CellAdderMixin::addDlatchsrGate(Twine::Id name, const RTLIL::SigSpec &sig_en, const RTLIL::SigSpec &sig_set, const RTLIL::SigSpec &sig_clr, RTLIL::SigSpec sig_d, const RTLIL::SigSpec &sig_q, bool en_polarity, bool set_polarity, bool clr_polarity, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = static_cast(this)->addCell(name, stringf("$_DLATCHSR_%c%c%c_", en_polarity ? 'P' : 'N', set_polarity ? 'P' : 'N', clr_polarity ? 'P' : 'N')); @@ -4620,7 +4762,7 @@ RTLIL::Process *RTLIL::Module::addProcess(RTLIL::IdString name, const RTLIL::Pro return cell; } -RTLIL::Cell* RTLIL::Module::addAnyinit(RTLIL::IdString name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SrcAttr &src) +RTLIL::Cell* RTLIL::Module::addAnyinit(Twine::Id name, const RTLIL::SigSpec &sig_d, const RTLIL::SigSpec &sig_q, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = addCell(name, ID($anyinit)); cell->parameters[ID::WIDTH] = sig_q.size(); @@ -4630,7 +4772,7 @@ RTLIL::Cell* RTLIL::Module::addAnyinit(RTLIL::IdString name, const RTLIL::SigSpe return cell; } -RTLIL::SigSpec RTLIL::Module::Anyconst(RTLIL::IdString name, int width, const RTLIL::SrcAttr &src) +RTLIL::SigSpec RTLIL::Module::Anyconst(Twine::Id name, int width, const RTLIL::SrcAttr &src) { RTLIL::SigSpec sig = addWire(NEW_ID, width); Cell *cell = addCell(name, ID($anyconst)); @@ -4640,7 +4782,7 @@ RTLIL::SigSpec RTLIL::Module::Anyconst(RTLIL::IdString name, int width, const RT return sig; } -RTLIL::SigSpec RTLIL::Module::Anyseq(RTLIL::IdString name, int width, const RTLIL::SrcAttr &src) +RTLIL::SigSpec RTLIL::Module::Anyseq(Twine::Id name, int width, const RTLIL::SrcAttr &src) { RTLIL::SigSpec sig = addWire(NEW_ID, width); Cell *cell = addCell(name, ID($anyseq)); @@ -4650,7 +4792,7 @@ RTLIL::SigSpec RTLIL::Module::Anyseq(RTLIL::IdString name, int width, const RTLI return sig; } -RTLIL::SigSpec RTLIL::Module::Allconst(RTLIL::IdString name, int width, const RTLIL::SrcAttr &src) +RTLIL::SigSpec RTLIL::Module::Allconst(Twine::Id name, int width, const RTLIL::SrcAttr &src) { RTLIL::SigSpec sig = addWire(NEW_ID, width); Cell *cell = addCell(name, ID($allconst)); @@ -4660,7 +4802,7 @@ RTLIL::SigSpec RTLIL::Module::Allconst(RTLIL::IdString name, int width, const RT return sig; } -RTLIL::SigSpec RTLIL::Module::Allseq(RTLIL::IdString name, int width, const RTLIL::SrcAttr &src) +RTLIL::SigSpec RTLIL::Module::Allseq(Twine::Id name, int width, const RTLIL::SrcAttr &src) { RTLIL::SigSpec sig = addWire(NEW_ID, width); Cell *cell = addCell(name, ID($allseq)); @@ -4670,7 +4812,7 @@ RTLIL::SigSpec RTLIL::Module::Allseq(RTLIL::IdString name, int width, const RTLI return sig; } -RTLIL::SigSpec RTLIL::Module::Initstate(RTLIL::IdString name, const RTLIL::SrcAttr &src) +RTLIL::SigSpec RTLIL::Module::Initstate(Twine::Id name, const RTLIL::SrcAttr &src) { RTLIL::SigSpec sig = addWire(NEW_ID); Cell *cell = addCell(name, ID($initstate)); @@ -4679,7 +4821,7 @@ RTLIL::SigSpec RTLIL::Module::Initstate(RTLIL::IdString name, const RTLIL::SrcAt return sig; } -RTLIL::SigSpec RTLIL::Module::SetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SrcAttr &src) +RTLIL::SigSpec RTLIL::Module::SetTag(Twine::Id name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SrcAttr &src) { RTLIL::SigSpec sig = addWire(NEW_ID, sig_a.size()); Cell *cell = addCell(name, ID($set_tag)); @@ -4693,7 +4835,7 @@ RTLIL::SigSpec RTLIL::Module::SetTag(RTLIL::IdString name, const std::string &ta return sig; } -RTLIL::Cell* RTLIL::Module::addSetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) +RTLIL::Cell* RTLIL::Module::addSetTag(Twine::Id name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SigSpec &sig_y, const RTLIL::SrcAttr &src) { Cell *cell = addCell(name, ID($set_tag)); cell->parameters[ID::WIDTH] = sig_a.size(); @@ -4706,7 +4848,7 @@ RTLIL::Cell* RTLIL::Module::addSetTag(RTLIL::IdString name, const std::string &t return cell; } -RTLIL::SigSpec RTLIL::Module::GetTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SrcAttr &src) +RTLIL::SigSpec RTLIL::Module::GetTag(Twine::Id name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SrcAttr &src) { RTLIL::SigSpec sig = addWire(NEW_ID, sig_a.size()); Cell *cell = addCell(name, ID($get_tag)); @@ -4718,7 +4860,7 @@ RTLIL::SigSpec RTLIL::Module::GetTag(RTLIL::IdString name, const std::string &ta return sig; } -RTLIL::Cell* RTLIL::Module::addOverwriteTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SrcAttr &src) +RTLIL::Cell* RTLIL::Module::addOverwriteTag(Twine::Id name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SigSpec &sig_s, const RTLIL::SigSpec &sig_c, const RTLIL::SrcAttr &src) { RTLIL::Cell *cell = addCell(name, ID($overwrite_tag)); cell->parameters[ID::WIDTH] = sig_a.size(); @@ -4730,7 +4872,7 @@ RTLIL::Cell* RTLIL::Module::addOverwriteTag(RTLIL::IdString name, const std::str return cell; } -RTLIL::SigSpec RTLIL::Module::OriginalTag(RTLIL::IdString name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SrcAttr &src) +RTLIL::SigSpec RTLIL::Module::OriginalTag(Twine::Id name, const std::string &tag, const RTLIL::SigSpec &sig_a, const RTLIL::SrcAttr &src) { RTLIL::SigSpec sig = addWire(NEW_ID, sig_a.size()); Cell *cell = addCell(name, ID($original_tag)); @@ -4742,7 +4884,7 @@ RTLIL::SigSpec RTLIL::Module::OriginalTag(RTLIL::IdString name, const std::strin return sig; } -RTLIL::SigSpec RTLIL::Module::FutureFF(RTLIL::IdString name, const RTLIL::SigSpec &sig_e, const RTLIL::SrcAttr &src) +RTLIL::SigSpec RTLIL::Module::FutureFF(Twine::Id name, const RTLIL::SigSpec &sig_e, const RTLIL::SrcAttr &src) { RTLIL::SigSpec sig = addWire(NEW_ID, sig_e.size()); Cell *cell = addCell(name, ID($future_ff)); @@ -4782,8 +4924,10 @@ RTLIL::Wire::Wire(ConstructToken) RTLIL::Wire::~Wire() { - if (module && module->design) + if (module && module->design) { module->design->obj_release_src(this); + module->design->obj_release_name_id(this); + } #ifdef YOSYS_ENABLE_PYTHON RTLIL::Wire::get_all_wires()->erase(hashidx_); #endif @@ -4823,7 +4967,7 @@ void RTLIL::Wire::adopt_src_from(const RTLIL::AttrObject *source) module->design->adopt_src_from(this, source); } -void RTLIL::Wire::absorb_attrs(dict &&buf) +void RTLIL::Wire::absorb_attrs(dict &&buf) { log_assert(module && module->design && "Wire::absorb_attrs requires the wire to be attached to a module in a design"); module->design->absorb_attrs(this, std::move(buf)); @@ -4895,8 +5039,10 @@ RTLIL::Cell::Cell(ConstructToken) : module(nullptr) RTLIL::Cell::~Cell() { - if (module && module->design) + if (module && module->design) { module->design->obj_release_src(this); + module->design->obj_release_name_id(this); + } #ifdef YOSYS_ENABLE_PYTHON RTLIL::Cell::get_all_cells()->erase(hashidx_); #endif @@ -4936,7 +5082,7 @@ void RTLIL::Cell::adopt_src_from(const RTLIL::AttrObject *source) module->design->adopt_src_from(this, source); } -void RTLIL::Cell::absorb_attrs(dict &&buf) +void RTLIL::Cell::absorb_attrs(dict &&buf) { log_assert(module && module->design && "Cell::absorb_attrs requires the cell to be attached to a module in a design"); module->design->absorb_attrs(this, std::move(buf)); @@ -4957,19 +5103,19 @@ std::map *RTLIL::Cell::get_all_cells(void) } #endif -bool RTLIL::Cell::hasPort(RTLIL::IdString portname) const +bool RTLIL::Cell::hasPort(Twine::Id portname) const { return connections_.count(portname) != 0; } // bufnorm -const RTLIL::SigSpec &RTLIL::Cell::getPort(RTLIL::IdString portname) const +const RTLIL::SigSpec &RTLIL::Cell::getPort(Twine::Id portname) const { return connections_.at(portname); } -const dict &RTLIL::Cell::connections() const +const dict &RTLIL::Cell::connections() const { return connections_; } @@ -4983,7 +5129,7 @@ bool RTLIL::Cell::known() const return false; } -bool RTLIL::Cell::input(RTLIL::IdString portname) const +bool RTLIL::Cell::input(Twine::Id portname) const { if (yosys_celltypes.cell_known(type)) return yosys_celltypes.cell_input(type, portname); @@ -4995,7 +5141,7 @@ bool RTLIL::Cell::input(RTLIL::IdString portname) const return false; } -bool RTLIL::Cell::output(RTLIL::IdString portname) const +bool RTLIL::Cell::output(Twine::Id portname) const { if (yosys_celltypes.cell_known(type)) return yosys_celltypes.cell_output(type, portname); @@ -5007,7 +5153,7 @@ bool RTLIL::Cell::output(RTLIL::IdString portname) const return false; } -RTLIL::PortDir RTLIL::Cell::port_dir(RTLIL::IdString portname) const +RTLIL::PortDir RTLIL::Cell::port_dir(Twine::Id portname) const { if (yosys_celltypes.cell_known(type)) return yosys_celltypes.cell_port_dir(type, portname); @@ -5023,22 +5169,22 @@ RTLIL::PortDir RTLIL::Cell::port_dir(RTLIL::IdString portname) const return PortDir::PD_UNKNOWN; } -bool RTLIL::Cell::hasParam(RTLIL::IdString paramname) const +bool RTLIL::Cell::hasParam(Twine::Id paramname) const { return parameters.count(paramname) != 0; } -void RTLIL::Cell::unsetParam(RTLIL::IdString paramname) +void RTLIL::Cell::unsetParam(Twine::Id paramname) { parameters.erase(paramname); } -void RTLIL::Cell::setParam(RTLIL::IdString paramname, RTLIL::Const value) +void RTLIL::Cell::setParam(Twine::Id paramname, RTLIL::Const value) { parameters[paramname] = std::move(value); } -const RTLIL::Const &RTLIL::Cell::getParam(RTLIL::IdString paramname) const +const RTLIL::Const &RTLIL::Cell::getParam(Twine::Id paramname) const { const auto &it = parameters.find(paramname); if (it != parameters.end()) @@ -5475,7 +5621,7 @@ Hasher::hash_t RTLIL::SigSpec::updhash() const for (auto &v : c.data) h.eat(v); } else { - h.eat(c.wire->name.index_); + h.eat(c.wire->meta_ ? c.wire->meta_->name_id : Twine::Null); h.eat(c.offset); h.eat(c.width); } @@ -6429,7 +6575,7 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri if (netname[0] != '$' && netname[0] != '\\') netname = "\\" + netname; - if (module->wires_.count(netname) == 0) { + if (module->design->twines.lookup(netname) == Twine::Null) { size_t indices_pos = netname.size()-1; if (indices_pos > 2 && netname[indices_pos] == ']') { @@ -6446,10 +6592,13 @@ bool RTLIL::SigSpec::parse(RTLIL::SigSpec &sig, RTLIL::Module *module, std::stri } } - if (module->wires_.count(netname) == 0) - return false; + { + Twine::Id wid = module->design->twines.lookup(netname); + if (wid == Twine::Null || module->wires_.count(wid) == 0) + return false; + } - RTLIL::Wire *wire = module->wires_.at(netname); + RTLIL::Wire *wire = module->wire(Twine::Id(netname)); if (!indices.empty()) { std::vector index_tokens; sigspec_parse_split(index_tokens, indices.substr(1, indices.size()-2), ':'); @@ -6490,7 +6639,7 @@ bool RTLIL::SigSpec::parse_sel(RTLIL::SigSpec &sig, RTLIL::Design *design, RTLIL sig = RTLIL::SigSpec(); RTLIL::Selection &sel = design->selection_vars.at(str); for (auto &it : module->wires_) - if (sel.selected_member(module->name, it.first)) + if (sel.selected_member(module->name, Twine::Id(it.second->name))) sig.append(it.second); return true; @@ -6680,7 +6829,7 @@ void RTLIL::Process::adopt_src_from(const RTLIL::AttrObject *source) module->design->adopt_src_from(this, source); } -void RTLIL::Process::absorb_attrs(dict &&buf) +void RTLIL::Process::absorb_attrs(dict &&buf) { log_assert(module && module->design && "Process::absorb_attrs requires the process to be attached to a module in a design"); module->design->absorb_attrs(this, std::move(buf)); @@ -6749,7 +6898,7 @@ void RTLIL::Memory::adopt_src_from(const RTLIL::AttrObject *source) module->design->adopt_src_from(this, source); } -void RTLIL::Memory::absorb_attrs(dict &&buf) +void RTLIL::Memory::absorb_attrs(dict &&buf) { log_assert(module && module->design && "Memory::absorb_attrs requires the memory to be attached to a module in a design"); module->design->absorb_attrs(this, std::move(buf)); @@ -6786,7 +6935,7 @@ void RTLIL::CaseRule::adopt_src_from(const RTLIL::AttrObject *source) log_assert(module && module->design && "CaseRule::adopt_src_from requires the case to belong to a module in a design"); module->design->adopt_src_from(this, source); } -void RTLIL::CaseRule::absorb_attrs(dict &&buf) +void RTLIL::CaseRule::absorb_attrs(dict &&buf) { log_assert(module && module->design && "CaseRule::absorb_attrs requires the case to belong to a module in a design"); module->design->absorb_attrs(this, std::move(buf)); @@ -6821,7 +6970,7 @@ void RTLIL::SwitchRule::adopt_src_from(const RTLIL::AttrObject *source) log_assert(module && module->design && "SwitchRule::adopt_src_from requires the switch to belong to a module in a design"); module->design->adopt_src_from(this, source); } -void RTLIL::SwitchRule::absorb_attrs(dict &&buf) +void RTLIL::SwitchRule::absorb_attrs(dict &&buf) { log_assert(module && module->design && "SwitchRule::absorb_attrs requires the switch to belong to a module in a design"); module->design->absorb_attrs(this, std::move(buf)); @@ -6856,7 +7005,7 @@ void RTLIL::MemWriteAction::adopt_src_from(const RTLIL::AttrObject *source) log_assert(module && module->design && "MemWriteAction::adopt_src_from requires the action to belong to a module in a design"); module->design->adopt_src_from(this, source); } -void RTLIL::MemWriteAction::absorb_attrs(dict &&buf) +void RTLIL::MemWriteAction::absorb_attrs(dict &&buf) { log_assert(module && module->design && "MemWriteAction::absorb_attrs requires the action to belong to a module in a design"); module->design->absorb_attrs(this, std::move(buf)); diff --git a/kernel/rtlil.h b/kernel/rtlil.h index b7e950726..594a38b7b 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -130,6 +130,8 @@ namespace RTLIL struct SrcAttr; struct ObjMeta; struct ModuleNameMasq; + struct WireNameMasq; + struct CellNameMasq; typedef std::pair SigSig; struct PortBit; @@ -603,6 +605,14 @@ public: if (global_id_index_.empty()) prepopulate(); } + + // Thread-safe read-only pool lookup for use while Multithreading::active(). + // global_id_index_ is stable (no writes) during parallel passes, so + // concurrent find() calls are safe. Returns empty IdString if not found. + static IdString lookup_threadsafe(std::string_view p) { + auto it = global_id_index_.find(p); + return from_index(it != global_id_index_.end() ? it->second : 0); + } }; struct RTLIL::OwningIdString : public RTLIL::IdString { @@ -910,15 +920,15 @@ namespace RTLIL { // This iterator-range-pair is used for Design::modules(), Module::wires() and Module::cells(). // It maintains a reference counter that is used to make sure that the container is not modified while being iterated over. - template + template struct ObjIterator { using iterator_category = std::forward_iterator_tag; using value_type = T; using difference_type = ptrdiff_t; using pointer = T*; using reference = T&; - typename dict::iterator it; - dict *list_p; + typename dict::iterator it; + dict *list_p; int *refcount_p; ObjIterator() : list_p(nullptr), refcount_p(nullptr) { @@ -934,7 +944,7 @@ namespace RTLIL { } } - ObjIterator(const RTLIL::ObjIterator &other) { + ObjIterator(const RTLIL::ObjIterator &other) { it = other.it; list_p = other.list_p; refcount_p = other.refcount_p; @@ -942,7 +952,7 @@ namespace RTLIL { (*refcount_p)++; } - ObjIterator &operator=(const RTLIL::ObjIterator &other) { + ObjIterator &operator=(const RTLIL::ObjIterator &other) { if (refcount_p) (*refcount_p)--; it = other.it; @@ -963,18 +973,18 @@ namespace RTLIL { return it->second; } - inline bool operator!=(const RTLIL::ObjIterator &other) const { + inline bool operator!=(const RTLIL::ObjIterator &other) const { if (list_p == nullptr || other.list_p == nullptr) return list_p != other.list_p; return it != other.it; } - inline bool operator==(const RTLIL::ObjIterator &other) const { + inline bool operator==(const RTLIL::ObjIterator &other) const { return !(*this != other); } - inline ObjIterator& operator++() { + inline ObjIterator& operator++() { log_assert(list_p != nullptr); if (++it == list_p->end()) { (*refcount_p)--; @@ -984,7 +994,7 @@ namespace RTLIL { return *this; } - inline ObjIterator& operator+=(int amt) { + inline ObjIterator& operator+=(int amt) { log_assert(list_p != nullptr); it += amt; if (it == list_p->end()) { @@ -995,9 +1005,9 @@ namespace RTLIL { return *this; } - inline ObjIterator operator+(int amt) { + inline ObjIterator operator+(int amt) { log_assert(list_p != nullptr); - ObjIterator new_obj(*this); + ObjIterator new_obj(*this); new_obj.it += amt; if (new_obj.it == list_p->end()) { (*(new_obj.refcount_p))--; @@ -1007,22 +1017,22 @@ namespace RTLIL { return new_obj; } - inline const ObjIterator operator++(int) { - ObjIterator result(*this); + inline const ObjIterator operator++(int) { + ObjIterator result(*this); ++(*this); return result; } }; - template + template struct ObjRange { - dict *list_p; + dict *list_p; int *refcount_p; ObjRange(decltype(list_p) list_p, int *refcount_p) : list_p(list_p), refcount_p(refcount_p) { } - RTLIL::ObjIterator begin() { return RTLIL::ObjIterator(list_p, refcount_p); } - RTLIL::ObjIterator end() { return RTLIL::ObjIterator(); } + RTLIL::ObjIterator begin() { return RTLIL::ObjIterator(list_p, refcount_p); } + RTLIL::ObjIterator end() { return RTLIL::ObjIterator(); } size_t size() const { return list_p->size(); @@ -1297,7 +1307,8 @@ public: struct RTLIL::ObjMeta { Twine::Id src = Twine::Null; - RTLIL::IdString name; + // RTLIL::IdString name; // used by Module names + Twine::Id name_id = Twine::Null; // used by Wire/Cell names (per-Design twines) }; struct RTLIL::AttrObject @@ -1322,10 +1333,10 @@ struct RTLIL::AttrObject void set_string_attribute(RTLIL::IdString id, string value); string get_string_attribute(RTLIL::IdString id) const; - static std::string strpool_attribute_to_str(const pool &data); - void set_strpool_attribute(RTLIL::IdString id, const pool &data); - void add_strpool_attribute(RTLIL::IdString id, const pool &data); - pool get_strpool_attribute(RTLIL::IdString id) const; + // static std::string strpool_attribute_to_str(const pool &data); + // void set_strpool_attribute(IdString id, const pool &data); + // void add_strpool_attribute(IdString id, const pool &data); + // pool get_strpool_attribute(RTLIL::IdString id) const; void set_hdlname_attribute(const vector &hierarchy); vector get_hdlname_attribute() const; @@ -1339,6 +1350,88 @@ struct RTLIL::NamedObject : public RTLIL::AttrObject RTLIL::IdString name; }; +// Read-only masquerade for Wire::name. Reads materialise the Twine::Id in +// the owning Design's twines pool into a temporary IdString. Writes are +// intentionally unsupported — use Module::rename(wire, new_name) instead. +// Defined before Wire so it can be used as a [[no_unique_address]] member. +struct RTLIL::WireNameMasq { + WireNameMasq() = default; + WireNameMasq(const WireNameMasq &) = delete; + WireNameMasq(WireNameMasq &&) = delete; + WireNameMasq &operator=(const WireNameMasq &) = delete; + WireNameMasq &operator=(WireNameMasq &&) = delete; + // Materialise → IdString. Slow path; intended for plugin code. + operator RTLIL::IdString() const; + bool empty() const { return RTLIL::IdString(*this).empty(); } + std::string str() const { return RTLIL::IdString(*this).str(); } + const char *c_str() const { return RTLIL::IdString(*this).c_str(); } + bool isPublic() const { return RTLIL::IdString(*this).isPublic(); } + std::string unescape() const { return RTLIL::IdString(*this).unescape(); } + bool begins_with(const char *s) const { return RTLIL::IdString(*this).begins_with(s); } + bool ends_with(const char *s) const { return RTLIL::IdString(*this).ends_with(s); } + template bool in(Ts &&...args) const { + return RTLIL::IdString(*this).in(std::forward(args)...); + } + std::string substr(size_t pos = 0, size_t len = std::string::npos) const { + return RTLIL::IdString(*this).substr(pos, len); + } + size_t size() const { return RTLIL::IdString(*this).size(); } + bool contains(const char *p) const { return RTLIL::IdString(*this).contains(p); } + char operator[](int n) const { return RTLIL::IdString(*this).str()[n]; } + bool lt_by_name(RTLIL::IdString rhs) const { return RTLIL::IdString(*this).lt_by_name(rhs); } + bool lt_by_name(const WireNameMasq &rhs) const { return RTLIL::IdString(*this).lt_by_name(RTLIL::IdString(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 RTLIL::IdString(*this) < 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 WireNameMasq &rhs) const { return RTLIL::IdString(*this) == RTLIL::IdString(rhs); } + bool operator!=(const WireNameMasq &rhs) const { return RTLIL::IdString(*this) != RTLIL::IdString(rhs); } + bool operator<(const WireNameMasq &rhs) const { return RTLIL::IdString(*this) < RTLIL::IdString(rhs); } + [[nodiscard]] Hasher hash_into(Hasher h) const { return RTLIL::IdString(*this).hash_into(h); } +}; +inline bool operator==(RTLIL::IdString lhs, const RTLIL::WireNameMasq &rhs) { return lhs == RTLIL::IdString(rhs); } +inline bool operator!=(RTLIL::IdString lhs, const RTLIL::WireNameMasq &rhs) { return lhs != RTLIL::IdString(rhs); } + +// Read-only masquerade for Cell::name. Same contract as WireNameMasq. +struct RTLIL::CellNameMasq { + CellNameMasq() = default; + CellNameMasq(const CellNameMasq &) = delete; + CellNameMasq(CellNameMasq &&) = delete; + CellNameMasq &operator=(const CellNameMasq &) = delete; + CellNameMasq &operator=(CellNameMasq &&) = delete; + operator RTLIL::IdString() const; + bool empty() const { return RTLIL::IdString(*this).empty(); } + std::string str() const { return RTLIL::IdString(*this).str(); } + const char *c_str() const { return RTLIL::IdString(*this).c_str(); } + bool isPublic() const { return RTLIL::IdString(*this).isPublic(); } + std::string unescape() const { return RTLIL::IdString(*this).unescape(); } + bool begins_with(const char *s) const { return RTLIL::IdString(*this).begins_with(s); } + bool ends_with(const char *s) const { return RTLIL::IdString(*this).ends_with(s); } + template bool in(Ts &&...args) const { + return RTLIL::IdString(*this).in(std::forward(args)...); + } + std::string substr(size_t pos = 0, size_t len = std::string::npos) const { + return RTLIL::IdString(*this).substr(pos, len); + } + size_t size() const { return RTLIL::IdString(*this).size(); } + bool contains(const char *p) const { return RTLIL::IdString(*this).contains(p); } + char operator[](int n) const { return RTLIL::IdString(*this).str()[n]; } + bool lt_by_name(RTLIL::IdString rhs) const { return RTLIL::IdString(*this).lt_by_name(rhs); } + bool lt_by_name(const CellNameMasq &rhs) const { return RTLIL::IdString(*this).lt_by_name(RTLIL::IdString(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 RTLIL::IdString(*this) < 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 CellNameMasq &rhs) const { return RTLIL::IdString(*this) == RTLIL::IdString(rhs); } + bool operator!=(const CellNameMasq &rhs) const { return RTLIL::IdString(*this) != RTLIL::IdString(rhs); } + bool operator<(const CellNameMasq &rhs) const { return RTLIL::IdString(*this) < RTLIL::IdString(rhs); } + [[nodiscard]] Hasher hash_into(Hasher h) const { return RTLIL::IdString(*this).hash_into(h); } +}; +inline bool operator==(RTLIL::IdString lhs, const RTLIL::CellNameMasq &rhs) { return lhs == RTLIL::IdString(rhs); } +inline bool operator!=(RTLIL::IdString lhs, const RTLIL::CellNameMasq &rhs) { return lhs != RTLIL::IdString(rhs); } + struct RTLIL::SigChunk { RTLIL::Wire *wire; @@ -1823,8 +1916,8 @@ struct RTLIL::Selection bool complete_selection; // selection covers full design, not including boxed modules bool full_selection; - pool selected_modules; - dict> selected_members; + pool selected_modules; + dict> selected_members; RTLIL::Design *current_design; // create a new selection @@ -1840,18 +1933,18 @@ struct RTLIL::Selection // checks if the given module exists in the current design and is a // boxed module, warning the user if the current design is not set - bool boxed_module(RTLIL::IdString mod_name) const; + bool boxed_module(Twine::Id mod_name) const; // checks if the given module is included in this selection - bool selected_module(RTLIL::IdString mod_name) const; + bool selected_module(Twine::Id mod_name) const; // checks if the given module is wholly included in this selection, // i.e. not partially selected - bool selected_whole_module(RTLIL::IdString mod_name) const; + bool selected_whole_module(Twine::Id mod_name) const; // checks if the given member from the given module is included in this // selection - bool selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const; + bool selected_member(Twine::Id mod_name, Twine::Id memb_name) const; // optimizes this selection for the given design by: // - removing non-existent modules and members, any boxed modules and @@ -1872,9 +1965,10 @@ struct RTLIL::Selection // add whole module to this selection template void select(T1 *module) { - if (!selects_all() && selected_modules.count(module->name) == 0) { - selected_modules.insert(module->name); - selected_members.erase(module->name); + if (!selects_all() && selected_modules.count(module->meta_->name_id) == 0) { + Twine::Id name = module->meta_->name_id; + selected_modules.insert(name); + selected_members.erase(name); if (module->get_blackbox_attribute()) selects_boxes = true; } @@ -1944,12 +2038,10 @@ struct RTLIL::Design void sigNormalize(bool enable=true); int refcount_modules_; - dict modules_; + dict modules_; std::vector bindings_; - // Interns src-attribute strings and concats thereof. Cells reach this - // via cell->module->design->src_twines. - TwinePool src_twines; + TwinePool twines; // Per-Design ObjMeta pool: stable storage (deque) + LIFO freelist of // returned slots. AttrObject::meta_ points into obj_meta_storage_. @@ -1965,15 +2057,22 @@ struct RTLIL::Design void obj_set_src_id(RTLIL::AttrObject *obj, Twine::Id id); void obj_release_src(RTLIL::AttrObject *obj); - RTLIL::IdString obj_name(const RTLIL::AttrObject *obj) const { - return (obj->meta_ ? obj->meta_->name : RTLIL::IdString()); + std::string obj_name(const RTLIL::AttrObject *obj) const { + return (obj->meta_ ? twines.flat_string(obj->meta_->name_id) : std::string()); } void obj_set_name(RTLIL::AttrObject *obj, RTLIL::IdString name); void obj_release_name(RTLIL::AttrObject *obj); + // Wire/Cell names: stored as Twine::Id in twines. + Twine::Id obj_name_id(const RTLIL::AttrObject *obj) const { + return (obj->meta_ ? obj->meta_->name_id : Twine::Null); + } + void obj_set_name_id(RTLIL::AttrObject *obj, Twine::Id id); + void obj_release_name_id(RTLIL::AttrObject *obj); + // Replacements for the methods that used to live on AttrObject and // took an explicit TwinePool*. Same semantics; the pool resolves - // to this->src_twines internally. + // to this->twines internally. void set_src_attribute(RTLIL::AttrObject *obj, const RTLIL::SrcAttr &src); std::string get_src_attribute(const RTLIL::AttrObject *obj) const; void adopt_src_from(RTLIL::AttrObject *obj, const RTLIL::AttrObject *source); @@ -1983,13 +2082,13 @@ struct RTLIL::Design // Resolve a stored src-attribute string to its flat path:line.col // representation. If `raw` is a twine reference ("@N") returns - // src_twines.flatten(N); otherwise returns `raw` unchanged. Backends + // twines.flatten(N); otherwise returns `raw` unchanged. Backends // must call this whenever they emit src to a user-facing format. - std::string resolve_src(std::string_view raw) const { - Twine::Id id = TwinePool::parse_ref(raw); - if (id == Twine::Null) + std::string resolve_src(std::string_view raw) { + Twine* id = twines.get_ref(raw); + if (id == nullptr) return std::string(raw); - return src_twines.flatten(id); + return twines.flatten(id); } // Merge `source`'s src attribute into `target`'s src attribute via the @@ -2012,7 +2111,7 @@ struct RTLIL::Design pool src_leaves(const RTLIL::AttrObject *obj) const; // Walk the design, collect the set of "@N" ids actually referenced by - // any AttrObject's src, then compact src_twines to contain only those + // any AttrObject's src, then compact twines to contain only those // nodes plus their transitive leaf children, and rewrite every cell // src attribute through the resulting old-id -> new-id remap. // Intermediate concats produced by successive merges become unreferenced @@ -2025,26 +2124,27 @@ struct RTLIL::Design std::vector selection_stack; dict selection_vars; - std::string selected_active_module; + Twine::Id selected_active_module; Design(); ~Design(); - RTLIL::ObjRange modules(); - RTLIL::Module *module(RTLIL::IdString name); - const RTLIL::Module *module(RTLIL::IdString name) const; + RTLIL::ObjRange modules(); + RTLIL::Module *module(IdString name); + RTLIL::Module *module(Twine::Id name); + const RTLIL::Module *module(Twine::Id name) const; RTLIL::Module *top_module() const; - bool has(RTLIL::IdString id) const { + bool has(Twine::Id id) const { return modules_.count(id) != 0; } void add(RTLIL::Module *module); void add(RTLIL::Binding *binding); - RTLIL::Module *addModule(RTLIL::IdString name); + RTLIL::Module *addModule(Twine::Id name); void remove(RTLIL::Module *module); - void rename(RTLIL::Module *module, RTLIL::IdString new_name); + void rename(RTLIL::Module *module, Twine::Id new_name); void scratchpad_unset(const std::string &varname); @@ -2062,22 +2162,22 @@ struct RTLIL::Design void optimize(); // Wholesale-copy this design into `dst`. `dst` must be empty (no - // modules). Copies src_twines verbatim and clones each module + // modules). Copies twines verbatim and clones each module // preserving src_id_ values directly — avoids the per-module // copy_from pool rebuild and yields byte-identical RTLIL output // across design -push/-pop, -save/-load, etc. void clone_into(RTLIL::Design *dst) const; // checks if the given module is included in the current selection - bool selected_module(RTLIL::IdString mod_name) const; + bool selected_module(Twine::Id mod_name) const; // checks if the given module is wholly included in the current // selection, i.e. not partially selected - bool selected_whole_module(RTLIL::IdString mod_name) const; + bool selected_whole_module(Twine::Id mod_name) const; // checks if the given member from the given module is included in the // current selection - bool selected_member(RTLIL::IdString mod_name, RTLIL::IdString memb_name) const; + bool selected_member(Twine::Id mod_name, Twine::Id memb_name) const; // checks if the given module is included in the current selection bool selected_module(RTLIL::Module *mod) const; @@ -2193,6 +2293,10 @@ private: friend struct RTLIL::Module; friend struct RTLIL::Patch; public: + // Shadows NamedObject::name. Reads materialise via twines; writes + // are a compile error — use Module::rename(wire, new_name) instead. + [[no_unique_address]] RTLIL::WireNameMasq name; + Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } // use module->addWire() and module->remove() to create or destroy wires @@ -2300,6 +2404,10 @@ private: void signorm_index_add(RTLIL::IdString portname, const RTLIL::SigSpec &new_signal, bool is_input); bool bufnorm_handle_setPort(RTLIL::IdString portname, RTLIL::SigSpec &signal, dict::iterator conn_it); public: + // Shadows NamedObject::name. Reads materialise via twines; writes + // are a compile error — use Module::rename(cell, new_name) instead. + [[no_unique_address]] RTLIL::CellNameMasq name; + Hasher::hash_t hashidx_; [[nodiscard]] Hasher hash_into(Hasher h) const { h.eat(hashidx_); return h; } @@ -2566,7 +2674,10 @@ inline Hasher RTLIL::SigBit::hash_into(Hasher h) const { inline Hasher RTLIL::SigBit::hash_top() const { Hasher h; if (wire) { - h.force(hashlib::legacy::djb2_add(wire->name.index_, offset)); + // Use the wire's name_id (Twine::Id) directly — avoids IdString materialisation. + Twine::Id name_id = wire->meta_ ? wire->meta_->name_id : Twine::Null; + h.eat(name_id); + h.eat(offset); return h; } h.force(data); @@ -2815,6 +2926,7 @@ struct RTLIL::ModuleNameMasq { ModuleNameMasq(const ModuleNameMasq&) = delete; ModuleNameMasq(ModuleNameMasq&&) = delete; operator RTLIL::IdString() const; + operator Twine::Id() const; ModuleNameMasq& operator=(RTLIL::IdString id); // Without this, `new_mod->name = src_mod->name` invokes the implicit // copy-assign (no-op) instead of operator=(IdString), so the meta @@ -2867,8 +2979,8 @@ public: int refcount_wires_; int refcount_cells_; - dict wires_; - dict cells_; + dict wires_; + dict cells_; std::vector connections_; std::vector bindings_; @@ -2892,7 +3004,7 @@ public: virtual ~Module(); virtual RTLIL::IdString derive(RTLIL::Design *design, const dict ¶meters, bool mayfail = false); virtual RTLIL::IdString derive(RTLIL::Design *design, const dict ¶meters, const dict &interfaces, const dict &modports, bool mayfail = false); - virtual size_t count_id(RTLIL::IdString id); + virtual size_t count_id(Twine* id); virtual void expand_interfaces(RTLIL::Design *design, const dict &local_interfaces); virtual bool reprocess_if_necessary(RTLIL::Design *design); @@ -2944,8 +3056,8 @@ public: template void rewrite_sigspecs(T &functor); template void rewrite_sigspecs2(T &functor); // `src_id_verbatim`: when true, the caller guarantees that - // `new_mod->design->src_twines` is a verbatim copy of - // `this->design->src_twines`, so src_id_ values can be transferred + // `new_mod->design->twines` is a verbatim copy of + // `this->design->twines`, so src_id_ values can be transferred // without retain/release on the destination pool (the copied refcounts // already account for the new AttrObject references). Used by // Design::clone_into for wholesale design copies. @@ -2982,28 +3094,42 @@ public: return design->selected_member(name, member->name); } - RTLIL::Wire* wire(const RTLIL::IdString &id) { + // Primary (fast) overloads — key directly into the dict. + RTLIL::Wire* wire(Twine::Id id) { auto it = wires_.find(id); return it == wires_.end() ? nullptr : it->second; } + RTLIL::Cell* cell(Twine::Id id) { + auto it = cells_.find(id); + return it == cells_.end() ? nullptr : it->second; + } + const RTLIL::Wire* wire(Twine::Id id) const { + auto it = wires_.find(id); + return it == wires_.end() ? nullptr : it->second; + } + const RTLIL::Cell* cell(Twine::Id id) const { + auto it = cells_.find(id); + return it == cells_.end() ? nullptr : it->second; + } + + // IdString compatibility shims: look up via twines, then dispatch. + RTLIL::Wire* wire(const RTLIL::IdString &id) { + return wire(design->twines.lookup(id.str())); + } RTLIL::Cell* cell(const RTLIL::IdString &id) { - auto it = cells_.find(id); - return it == cells_.end() ? nullptr : it->second; + return cell(design->twines.lookup(id.str())); } - - const RTLIL::Wire* wire(const RTLIL::IdString &id) const{ - auto it = wires_.find(id); - return it == wires_.end() ? nullptr : it->second; + const RTLIL::Wire* wire(const RTLIL::IdString &id) const { + return wire(design->twines.lookup(id.str())); } const RTLIL::Cell* cell(const RTLIL::IdString &id) const { - auto it = cells_.find(id); - return it == cells_.end() ? nullptr : it->second; + return cell(design->twines.lookup(id.str())); } - RTLIL::ObjRange wires() { return RTLIL::ObjRange(&wires_, &refcount_wires_); } + RTLIL::ObjRange wires() { return RTLIL::ObjRange(&wires_, &refcount_wires_); } int wires_size() const { return wires_.size(); } RTLIL::Wire* wire_at(int index) const { return wires_.element(index)->second; } - RTLIL::ObjRange cells() { return RTLIL::ObjRange(&cells_, &refcount_cells_); } + RTLIL::ObjRange cells() { return RTLIL::ObjRange(&cells_, &refcount_cells_); } int cells_size() const { return cells_.size(); } RTLIL::Cell* cell_at(int index) const { return cells_.element(index)->second; } @@ -3025,9 +3151,17 @@ public: RTLIL::IdString uniquify(RTLIL::IdString name); RTLIL::IdString uniquify(RTLIL::IdString name, int &index); + // Primary overloads: name already interned in design->twines. + RTLIL::Wire *addWire(Twine::Id name, int width = 1); + RTLIL::Wire *addWire(Twine::Id name, const RTLIL::Wire *other); + // IdString compatibility: interns name into twines, then dispatches. RTLIL::Wire *addWire(RTLIL::IdString name, int width = 1); RTLIL::Wire *addWire(RTLIL::IdString name, const RTLIL::Wire *other); + // Primary overloads. + RTLIL::Cell *addCell(Twine::Id name, RTLIL::IdString type); + RTLIL::Cell *addCell(Twine::Id name, const RTLIL::Cell *other); + // IdString compatibility. RTLIL::Cell *addCell(RTLIL::IdString name, RTLIL::IdString type); RTLIL::Cell *addCell(RTLIL::IdString name, const RTLIL::Cell *other); @@ -3185,20 +3319,48 @@ void RTLIL::Process::rewrite_sigspecs2(T &functor) it->rewrite_sigspecs2(functor); } +inline RTLIL::WireNameMasq::operator RTLIL::IdString() const { + const RTLIL::Wire *w = reinterpret_cast( + reinterpret_cast(this) - offsetof(RTLIL::Wire, name)); + if (!w->module || !w->module->design || !w->meta_) + return RTLIL::IdString{}; + Twine::Id id = w->meta_->name_id; + if (id == Twine::Null) + return RTLIL::IdString{}; + return RTLIL::IdString(w->module->design->twines.flat_string(id)); +} + +inline RTLIL::CellNameMasq::operator RTLIL::IdString() const { + const RTLIL::Cell *c = reinterpret_cast( + reinterpret_cast(this) - offsetof(RTLIL::Cell, name)); + if (!c->module || !c->module->design || !c->meta_) + return RTLIL::IdString{}; + Twine::Id id = c->meta_->name_id; + if (id == Twine::Null) + return RTLIL::IdString{}; + return RTLIL::IdString(c->module->design->twines.flat_string(id)); +} + inline RTLIL::ModuleNameMasq::operator RTLIL::IdString() const { const RTLIL::Module *m = reinterpret_cast( reinterpret_cast(this) - offsetof(RTLIL::Module, name)); - return m->design ? m->design->obj_name(m) : RTLIL::IdString{}; + return m->design ? m->design->obj_name(m) : std::string(); } -inline RTLIL::ModuleNameMasq& RTLIL::ModuleNameMasq::operator=(RTLIL::IdString id) { - RTLIL::Module *m = reinterpret_cast( - reinterpret_cast(this) - offsetof(RTLIL::Module, name)); - log_assert(m->design && "assignment to Module::name requires the module to be attached to a design"); - m->design->obj_set_name(m, id); - return *this; +inline RTLIL::ModuleNameMasq::operator Twine::Id() const { + const RTLIL::Module *m = reinterpret_cast( + reinterpret_cast(this) - offsetof(RTLIL::Module, name)); + return m->design ? m->design->obj_src_id(m) : nullptr; } +// inline RTLIL::ModuleNameMasq& RTLIL::ModuleNameMasq::operator=(RTLIL::IdString id) { +// RTLIL::Module *m = reinterpret_cast( +// reinterpret_cast(this) - offsetof(RTLIL::Module, name)); +// log_assert(m->design && "assignment to Module::name requires the module to be attached to a design"); +// m->design->obj_set_name(m, id); +// return *this; +// } + YOSYS_NAMESPACE_END #endif diff --git a/kernel/rtlil_bufnorm.cc b/kernel/rtlil_bufnorm.cc index 871500bf8..9312e7249 100644 --- a/kernel/rtlil_bufnorm.cc +++ b/kernel/rtlil_bufnorm.cc @@ -520,12 +520,14 @@ void RTLIL::Module::remove(RTLIL::Cell *cell) while (!cell->connections_.empty()) cell->unsetPort(cell->connections_.begin()->first); - log_assert(cells_.count(cell->name) != 0); + log_assert(cell->meta_ && cell->meta_->name_id != Twine::Null); + Twine::Id cell_id = cell->meta_->name_id; + log_assert(cells_.count(cell_id) != 0); log_assert(refcount_cells_ == 0); - cells_.erase(cell->name); + cells_.erase(cell_id); if (design && design->flagBufferedNormalized && buf_norm_cell_queue.count(cell)) { cell->type.clear(); - cell->name.clear(); + design->obj_release_name_id(cell); pending_deleted_cells.insert(cell); } else { if (sig_norm_index != nullptr) { diff --git a/kernel/tclapi.cc b/kernel/tclapi.cc index 9866f5c98..7554d70b9 100644 --- a/kernel/tclapi.cc +++ b/kernel/tclapi.cc @@ -252,13 +252,13 @@ static int tcl_get_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar ERROR("bad usage: expected \"get_attr -mod [-string|-int|-sint|-uint|-bool] \"" " or \"get_attr [-string|-int|-sint|-uint|-bool] \"") - IdString mod_id, obj_id, attr_id; + std::string mod_id, obj_id, attr_id; mod_id = RTLIL::escape_id(argv[i++]); if (!mod_flag) obj_id = RTLIL::escape_id(argv[i++]); attr_id = RTLIL::escape_id(argv[i++]); - RTLIL::Module *mod = yosys_design->module(mod_id); + RTLIL::Module *mod = yosys_design->module(yosys_design->twines.lookup(mod_id)); if (!mod) ERROR("module not found") @@ -315,13 +315,13 @@ static int tcl_has_attr(ClientData, Tcl_Interp *interp, int argc, const char *ar ERROR("bad usage: expected \"has_attr -mod \"" " or \"has_attr \"") - IdString mod_id, obj_id, attr_id; + std::string mod_id, obj_id, attr_id; mod_id = RTLIL::escape_id(argv[i++]); if (!mod_flag) obj_id = RTLIL::escape_id(argv[i++]); attr_id = RTLIL::escape_id(argv[i++]); - RTLIL::Module *mod = yosys_design->module(mod_id); + RTLIL::Module *mod = yosys_design->module(yosys_design->twines.lookup(mod_id)); if (!mod) ERROR("module not found") @@ -368,13 +368,13 @@ static int tcl_set_attr(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *const " or \"set_attr [-true|-false] \"" " or \"set_attr -mod [-true|-false| \"") - IdString mod_id, obj_id, attr_id; + std::string mod_id, obj_id, attr_id; mod_id = RTLIL::escape_id(Tcl_GetString(objv[i++])); if (!mod_flag) 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); + RTLIL::Module *mod = yosys_design->module(yosys_design->twines.lookup(mod_id)); if (!mod) ERROR("module not found") @@ -446,12 +446,12 @@ static int tcl_get_param(ClientData, Tcl_Interp *interp, int argc, const char *a (string_flag + int_flag > 1)) ERROR("bad usage: expected \"get_param [-string|-int|-sint|-uint] ") - IdString mod_id, cell_id, param_id; + std::string mod_id, cell_id, param_id; mod_id = RTLIL::escape_id(argv[i++]); cell_id = RTLIL::escape_id(argv[i++]); param_id = RTLIL::escape_id(argv[i++]); - RTLIL::Module *mod = yosys_design->module(mod_id); + RTLIL::Module *mod = yosys_design->module(yosys_design->twines.lookup(mod_id)); if (!mod) ERROR("module not found") @@ -492,12 +492,12 @@ static int tcl_set_param(ClientData, Tcl_Interp *interp, int objc, Tcl_Obj *cons (string_flag + sint_flag + uint_flag > 1)) ERROR("bad usage: expected \"set_param [-string|-sint|-uint] ") - IdString mod_id, cell_id, param_id; + std::string mod_id, cell_id, param_id; mod_id = RTLIL::escape_id(Tcl_GetString(objv[i++])); 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); + RTLIL::Module *mod = yosys_design->module(yosys_design->twines.lookup(mod_id)); if (!mod) ERROR("module not found") diff --git a/kernel/twine.cc b/kernel/twine.cc index 47f9d18c6..c899e3d55 100644 --- a/kernel/twine.cc +++ b/kernel/twine.cc @@ -3,6 +3,52 @@ YOSYS_NAMESPACE_BEGIN +TwinePool::TwinePool() + : leaf_index_(0, LeafHash{this}, LeafEq{this}) + , suffix_index_(0, SuffixHash{this}, SuffixEq{this}) + , concat_index_(0, ConcatHash{this}, ConcatEq{this}) +{} + +TwinePool::TwinePool(const TwinePool &other) + : nodes_(other.nodes_) + , refcount_(other.refcount_) + , free_list_(other.free_list_) + , leaf_index_(0, LeafHash{this}, LeafEq{this}) + , suffix_index_(0, SuffixHash{this}, SuffixEq{this}) + , concat_index_(0, ConcatHash{this}, ConcatEq{this}) +{ + rebuild_indexes_(); +} + +TwinePool &TwinePool::operator=(const TwinePool &other) +{ + if (this == &other) + return *this; + nodes_ = other.nodes_; + refcount_ = other.refcount_; + free_list_ = other.free_list_; + // Re-create the index sets with functors pointing to *this, + // then rebuild their contents from the (now-copied) nodes_. + leaf_index_ = std::unordered_set( + 0, LeafHash{this}, LeafEq{this}); + suffix_index_ = std::unordered_set( + 0, SuffixHash{this}, SuffixEq{this}); + concat_index_ = std::unordered_set( + 0, ConcatHash{this}, ConcatEq{this}); + rebuild_indexes_(); + return *this; +} + +void TwinePool::rebuild_indexes_() +{ + for (auto& n : nodes_) { + if (n.is_dead()) continue; + if (n.is_leaf()) leaf_index_.insert(&n); + else if (n.is_suffix()) suffix_index_.insert(&n); + else if (n.is_concat()) concat_index_.insert(&n); + } +} + Twine::Id TwinePool::alloc_slot_(Twine &&node) { if (!free_list_.empty()) { @@ -12,40 +58,59 @@ Twine::Id TwinePool::alloc_slot_(Twine &&node) // "@N" refs across design -push;-pop and similar wholesale-clone // cycles, even though the in-memory pool got renumbered through // the free list. - auto it = std::min_element(free_list_.begin(), free_list_.end()); - Twine::Id id = *it; - free_list_.erase(it); - nodes_[id] = std::move(node); - refcount_[id] = 0; + // TODO nevermind, inefficient, solve in RTLIL frontend and backend + // auto it = std::min_element(free_list_.begin(), free_list_.end()); + // Twine::Id id = *it; + // free_list_.erase(it); + Twine* id = free_list_.back(); + *id = std::move(node); + // size_t idx = id - &nodes_.front(); + // log_assert(idx > 0 && idx < refcount_.size()); + // refcount_[idx] = 0; + refcount(id) = 0; return id; } - Twine::Id id = static_cast(nodes_.size()); + // Twine::Id id = static_cast(nodes_.size()); nodes_.push_back(std::move(node)); + Twine* id = &nodes_.back(); refcount_.push_back(0); return id; } -Twine::Id TwinePool::intern(std::string_view leaf) +Twine::Id TwinePool::intern(std::string_view str) { - if (leaf.empty()) + if (str.empty()) return Twine::Null; - std::string key{leaf}; - if (auto it = leaf_index_.find(key); it != leaf_index_.end()) { - retain(it->second); - return it->second; + // Transparent find: probes with string_view, no string allocation. + // TODO why are they split like this? Is this called on a hot path somewhere? + if (auto it = leaf_index_.find(str); it != leaf_index_.end()) { + retain(*it); + return *it; } - Twine::Id id = alloc_slot_(Twine{std::move(key)}); - leaf_index_[std::get(nodes_[id].data)] = id; - refcount_[id] = 1; + if (auto it = suffix_index_.find(str); it != suffix_index_.end()) { + retain(*it); + return *it; + } + if (auto it = concat_index_.find(str); it != concat_index_.end()) { + retain(*it); + return *it; + } + Twine::Id id = alloc_slot_(Twine{std::string{str}}); + leaf_index_.insert(id); + + // size_t idx = id - &nodes_.front(); + // log_assert(idx > 0 && idx < refcount_.size()); + // refcount_[idx] = 1; + refcount(id) = 1; return id; } -Twine::Id TwinePool::intern_suffix(Twine::Id parent, std::string_view tail) +Twine* TwinePool::intern_suffix(Twine* parent, std::string_view tail) { if (parent == Twine::Null) return intern(tail); - log_assert(parent < nodes_.size() && !nodes_[parent].is_dead()); - log_assert(nodes_[parent].is_flat() && "Suffix parent must be a flat node (Leaf or Suffix)"); + log_assert(parent > &nodes_.front() && parent <= &nodes_.back() && !parent->is_dead()); + log_assert(parent->is_flat() && "Suffix parent must be a flat node (Leaf or Suffix)"); if (tail.empty()) { // No tail means "the same string as parent". Hand back a fresh // owning ref on parent — semantically equivalent to a degenerate @@ -54,18 +119,18 @@ Twine::Id TwinePool::intern_suffix(Twine::Id parent, std::string_view tail) return parent; } - std::pair key{parent, std::string{tail}}; + // Transparent find: probes with (parent, string_view), no allocation. + SuffixKey key{parent, tail}; if (auto it = suffix_index_.find(key); it != suffix_index_.end()) { - retain(it->second); - return it->second; + retain(*it); + return *it; } // Internal child ref: the suffix node owns one ref on its parent. retain(parent); Twine::Id id = alloc_slot_(Twine{Twine::Suffix{parent, std::string{tail}}}); - const auto &stored = std::get(nodes_[id].data); - suffix_index_[std::make_pair(stored.parent, stored.tail)] = id; - refcount_[id] = 1; + suffix_index_.insert(id); + refcount(id) = 1; return id; } @@ -85,8 +150,8 @@ Twine::Id TwinePool::concat(std::span parts) for (Twine::Id p : parts) { if (p == Twine::Null) continue; - log_assert(p < nodes_.size() && !nodes_[p].is_dead()); - const Twine &n = nodes_[p]; + // log_assert(p < nodes_.size() && !nodes_[p].is_dead()); + const Twine &n = *p; if (n.is_flat()) { push_flat(p); } else { @@ -102,17 +167,19 @@ Twine::Id TwinePool::concat(std::span parts) return children.front(); } - if (auto it = concat_index_.find(children); it != concat_index_.end()) { - retain(it->second); - return it->second; + // Transparent find: probes with span, no vector allocation. + std::span child_span{children}; + if (auto it = concat_index_.find(child_span); it != concat_index_.end()) { + retain(*it); + return *it; } // Internal child refs: the concat node owns one ref on each child. for (Twine::Id c : children) retain(c); Twine::Id id = alloc_slot_(Twine{std::move(children)}); - concat_index_[std::get>(nodes_[id].data)] = id; - refcount_[id] = 1; + concat_index_.insert(id); + refcount(id) = 1; return id; } @@ -126,55 +193,68 @@ void TwinePool::retain(Twine::Id id) { if (id == Twine::Null) return; - log_assert(id < nodes_.size() && !nodes_[id].is_dead()); - refcount_[id]++; + refcount(id)++; } void TwinePool::release(Twine::Id id) { if (id == Twine::Null) return; - log_assert(id < nodes_.size() && !nodes_[id].is_dead()); - log_assert(refcount_[id] > 0); - if (--refcount_[id] == 0) + // log_assert(id < nodes_.size() && !nodes_[id].is_dead()); + log_assert(refcount(id) > 0); + if (--refcount(id) == 0) destroy_slot_(id); } +size_t TwinePool::index(Twine::Id p) const +{ + return p - &nodes_.front(); +} + +uint32_t& TwinePool::refcount(Twine::Id id) +{ + log_assert(id != Twine::Null); + size_t idx = index(id); + log_assert(idx > 0 && idx < refcount_.size()); + return refcount_[idx]; +} + uint32_t TwinePool::refcount(Twine::Id id) const { - if (id == Twine::Null) - return 0; - return refcount_.at(id); + log_assert(id != Twine::Null); + size_t idx = id - &nodes_.front(); + log_assert(idx > 0 && idx < refcount_.size()); + return refcount_[idx]; } bool TwinePool::is_alive(Twine::Id id) const { if (id == Twine::Null) return false; - return id < nodes_.size() && !nodes_[id].is_dead(); + return id >= &nodes_.front() && id <= &nodes_.back() && !id->is_dead(); } void TwinePool::destroy_slot_(Twine::Id id) { - Twine &n = nodes_[id]; + Twine &n = *id; if (n.is_leaf()) { - leaf_index_.erase(n.leaf()); + // Erase by id: functor reads nodes_[id].leaf() before we tombstone. + leaf_index_.erase(id); } else if (n.is_concat()) { - // Release internal child refs. Capture by move so iteration is - // stable across child destroy_slot_ side effects. - std::vector children = std::move(std::get>(n.data)); - concat_index_.erase(children); + // Erase by id first (while data is still readable), then capture + // children by move so iteration is stable across recursive release. + concat_index_.erase(id); + std::vector children = + std::move(std::get>(n.data)); n.data = std::monostate{}; free_list_.push_back(id); for (Twine::Id c : children) release(c); return; } else if (n.is_suffix()) { - // Capture parent by move and release after dropping the slot, - // since releasing may recursively destroy the parent and we - // want this slot's tombstone to be visible by then. + // Same pattern: erase first, then move data for deferred release. + suffix_index_.erase(id); Twine::Suffix s = std::move(std::get(n.data)); - suffix_index_.erase(std::make_pair(s.parent, s.tail)); n.data = std::monostate{}; free_list_.push_back(id); release(s.parent); @@ -184,11 +264,30 @@ void TwinePool::destroy_slot_(Twine::Id id) free_list_.push_back(id); } +Twine::Id TwinePool::lookup(std::string_view sv) const +{ + if (sv.empty()) + return Twine::Null; + auto it = leaf_index_.find(sv); + return (it != leaf_index_.end()) ? *it : Twine::Null; +} + +char TwinePool::first_char(Twine::Id id) const +{ + log_assert(id != Twine::Null && id > &nodes_.front() && id <= &nodes_.back() && !id->is_dead()); + // Walk suffix parents to reach the root leaf, then return its first char. + while (id->is_suffix()) + id = id->suffix().parent; + const std::string &s = id->leaf(); + // TODO seems wrong for concate + return s.empty() ? '\0' : s.front(); +} + void TwinePool::collect_leaves(Twine::Id id, pool &out) const { if (id == Twine::Null) return; - const Twine &n = nodes_.at(id); + const Twine &n = *id; if (n.is_dead()) return; if (n.is_leaf()) { @@ -213,7 +312,7 @@ std::string TwinePool::flat_string_(Twine::Id id) const log_assert(id != Twine::Null); std::vector parts; while (true) { - const Twine &n = nodes_.at(id); + const Twine &n = *id; if (n.is_leaf()) { parts.push_back(n.leaf()); break; @@ -249,27 +348,32 @@ std::string TwinePool::flatten(Twine::Id id, char sep) const return out; } -std::string TwinePool::format_ref(Twine::Id id) +std::string TwinePool::format_ref(Twine::Id id) const { if (id == Twine::Null) return {}; - return "@" + std::to_string(id); + size_t i = index(id); + return "@" + std::to_string(i); } -Twine::Id TwinePool::parse_ref(std::string_view s) +std::optional TwinePool::parse_ref(std::string_view s) { if (s.size() < 2 || s[0] != '@') - return Twine::Null; + return std::nullopt; uint64_t v = 0; for (size_t i = 1; i < s.size(); i++) { char c = s[i]; if (c < '0' || c > '9') - return Twine::Null; + return std::nullopt; v = v * 10 + static_cast(c - '0'); - if (v >= std::numeric_limits::max()) - return Twine::Null; } - return static_cast(v); + return v; +} +Twine::Id TwinePool::get_ref(std::string_view s) +{ + if (auto idx = parse_ref(s)) + return &nodes_.front() + *idx; + return nullptr; } void TwinePool::dump(const char *banner) const @@ -281,18 +385,18 @@ void TwinePool::dump(const char *banner) const concat_index_.size(), free_list_.size()); for_each_live([&](Twine::Id id, const Twine &n) { if (n.is_leaf()) { - log(" @%u leaf rc=%u %s\n", id, refcount_[id], n.leaf().c_str()); + log(" @%u leaf rc=%u %s\n", id, refcount(id), n.leaf().c_str()); } else if (n.is_suffix()) { - log(" @%u suffix rc=%u @%u + %s\n", id, refcount_[id], + log(" @%u suffix rc=%u @%u + %s\n", id, refcount(id), n.suffix().parent, n.suffix().tail.c_str()); } else { std::string children; for (Twine::Id c : n.children()) { if (!children.empty()) children += ", "; - children += "@" + std::to_string(c); + children += format_ref(c); } - log(" @%u concat rc=%u [%s]\n", id, refcount_[id], children.c_str()); + log(" @%u concat rc=%u [%s]\n", id, refcount(id), children.c_str()); } }); } @@ -306,7 +410,7 @@ dict TwinePool::gc(const pool &live) pool reachable; std::vector work; for (Twine::Id id : live) { - if (id == Twine::Null || id >= nodes_.size() || nodes_[id].is_dead()) + if (!id || id->is_dead()) continue; if (reachable.insert(id).second) work.push_back(id); @@ -314,7 +418,7 @@ dict TwinePool::gc(const pool &live) while (!work.empty()) { Twine::Id id = work.back(); work.pop_back(); - const Twine &n = nodes_[id]; + const Twine &n = *id; if (n.is_concat()) { for (Twine::Id c : n.children()) if (reachable.insert(c).second) @@ -326,101 +430,101 @@ dict TwinePool::gc(const pool &live) } } - // Rebuild the pool from scratch. Process flats (Leaf, then Suffix) - // before Concats so concat-child lookups can resolve, and process - // suffixes parent-before-child via a recursive helper that memoizes - // into `remap`. + // Rebuild the pool from scratch using temporary storage; process flats + // before concats so child lookups can resolve. std::vector new_nodes; std::vector new_refcount; - dict new_leaf_index; - dict, Twine::Id> new_concat_index; - dict, Twine::Id> new_suffix_index; dict remap; - auto intern_leaf = [&](const std::string &text) -> Twine::Id { - if (auto it = new_leaf_index.find(text); it != new_leaf_index.end()) - return it->second; - Twine::Id id = static_cast(new_nodes.size()); - new_nodes.push_back(Twine{text}); - new_refcount.push_back(0); - new_leaf_index[std::get(new_nodes.back().data)] = id; - return id; - }; - + // Helper: insert a leaf into new_nodes, dedup by string. + // dict new_leaf_map; for (Twine::Id old_id : reachable) { - const Twine &n = nodes_[old_id]; + const Twine &n = *old_id; if (n.is_leaf()) - remap[old_id] = intern_leaf(n.leaf()); + remap[old_id] = intern(n.leaf()); } std::function remap_flat = [&](Twine::Id old_id) -> Twine::Id { if (auto it = remap.find(old_id); it != remap.end()) return it->second; - const Twine &n = nodes_[old_id]; + const Twine &n = *old_id; log_assert(n.is_suffix()); Twine::Id new_parent = remap_flat(n.suffix().parent); - std::pair key{new_parent, n.suffix().tail}; - if (auto sit = new_suffix_index.find(key); sit != new_suffix_index.end()) { - remap[old_id] = sit->second; - return sit->second; + // Dedup suffix nodes in the new pool. + for (auto& i : new_nodes) { + if (i.is_suffix()) { + const auto &s = i.suffix(); + if (s.parent == new_parent && s.tail == n.suffix().tail) { + remap[old_id] = &i; + return &i; + } + } } - Twine::Id new_id = static_cast(new_nodes.size()); + // Twine::Id new_id = static_cast(new_nodes.size()); new_nodes.push_back(Twine{Twine::Suffix{new_parent, n.suffix().tail}}); + Twine::Id new_id = &new_nodes.back(); new_refcount.push_back(0); - const auto &stored = std::get(new_nodes.back().data); - new_suffix_index[std::make_pair(stored.parent, stored.tail)] = new_id; remap[old_id] = new_id; return new_id; }; for (Twine::Id old_id : reachable) { - const Twine &n = nodes_[old_id]; + const Twine &n = *old_id; if (n.is_suffix() && remap.find(old_id) == remap.end()) remap_flat(old_id); } + // Dedup concat nodes by child vector. + dict, Twine::Id> new_concat_map; for (Twine::Id old_id : reachable) { - const Twine &n = nodes_[old_id]; + const Twine &n = *old_id; if (!n.is_concat()) continue; std::vector children; children.reserve(n.children().size()); for (Twine::Id c : n.children()) children.push_back(remap.at(c)); - if (auto it = new_concat_index.find(children); it != new_concat_index.end()) { + if (auto it = new_concat_map.find(children); it != new_concat_map.end()) { remap[old_id] = it->second; } else { - Twine::Id new_id = static_cast(new_nodes.size()); - new_nodes.push_back(Twine{std::move(children)}); + // Twine::Id new_id = static_cast(new_nodes.size()); + new_nodes.push_back(Twine{children}); + Twine::Id new_id = &new_nodes.back(); new_refcount.push_back(0); - new_concat_index[std::get>(new_nodes.back().data)] = new_id; + new_concat_map[std::get>(new_nodes.back().data)] = new_id; remap[old_id] = new_id; } } - // Refcounts in the rebuilt pool: every external "live" id passed in by - // the caller corresponds to one external owner reference; concats - // hold one ref per stored child; suffixes hold one ref on their parent. + + + // Swap in the new storage and rebuild the intrusive indexes. + nodes_ = std::move(new_nodes); + refcount_ = std::move(new_refcount); + + // Refcounts in the rebuilt pool. for (Twine::Id old_id : live) { auto it = remap.find(old_id); if (it != remap.end()) - new_refcount[it->second]++; + refcount(it->second)++; } - for (size_t i = 0; i < new_nodes.size(); i++) { - if (new_nodes[i].is_concat()) { - for (Twine::Id c : new_nodes[i].children()) - new_refcount[c]++; - } else if (new_nodes[i].is_suffix()) { - new_refcount[new_nodes[i].suffix().parent]++; + for (size_t i = 0; i < nodes_.size(); i++) { + if (nodes_[i].is_concat()) { + for (Twine::Id c : nodes_[i].children()) + refcount(c)++; + } else if (nodes_[i].is_suffix()) { + refcount(nodes_[i].suffix().parent)++; } } - nodes_ = std::move(new_nodes); - refcount_ = std::move(new_refcount); free_list_.clear(); - leaf_index_ = std::move(new_leaf_index); - concat_index_ = std::move(new_concat_index); - suffix_index_ = std::move(new_suffix_index); + leaf_index_ = std::unordered_set( + 0, LeafHash{this}, LeafEq{this}); + suffix_index_ = std::unordered_set( + 0, SuffixHash{this}, SuffixEq{this}); + concat_index_ = std::unordered_set( + 0, ConcatHash{this}, ConcatEq{this}); + rebuild_indexes_(); return remap; } @@ -428,8 +532,8 @@ Twine::Id TwinePool::copy_from(const TwinePool &src, Twine::Id src_id) { if (src_id == Twine::Null) return Twine::Null; - log_assert(src_id < src.nodes_.size() && !src.nodes_[src_id].is_dead()); - const Twine &n = src.nodes_[src_id]; + // log_assert(src_id < src.nodes_.size() && !src.nodes_[src_id].is_dead()); + const Twine &n = *src_id; if (n.is_leaf()) return intern(n.leaf()); if (n.is_suffix()) { diff --git a/kernel/twine.h b/kernel/twine.h index 0239f89fe..cf786be3f 100644 --- a/kernel/twine.h +++ b/kernel/twine.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include @@ -20,24 +22,24 @@ YOSYS_NAMESPACE_BEGIN // the total path-string length the materialized result would have. // // Twines are valid only relative to the TwinePool that minted them. The pool -// lives on RTLIL::Design (design->src_twines). +// lives on RTLIL::Design (design->twines). struct Twine { - using Id = uint32_t; - static constexpr Id Null = std::numeric_limits::max(); + using Id = Twine*; + static constexpr Id Null = nullptr; - // Suffix shares a `parent` prefix with other suffixes and contributes + // Suffix shares a `prefix` prefix with other suffixes and contributes // its own `tail` string. The materialized leaf string is - // flat_string(parent) + tail, i.e. suffixes form trees whose leaves + // flat_string(prefix) + tail, i.e. suffixes form trees whose leaves // (string variant) are the roots — like a reverse-trie of common - // prefixes. The parent is itself flat (Leaf or Suffix), never a + // prefixes. The prefix is itself flat (Leaf or Suffix), never a // Concat. struct Suffix { - Id parent; + Id prefix; std::string tail; }; - // Leaf holds the literal path:line.col string. Suffix holds a parent + // Leaf holds the literal path:line.col string. Suffix holds a prefix // id + own tail (see above). Concat holds the ordered children. // Concats are kept flat by TwinePool::concat — children are always // flat (Leaf or Suffix), never other Concats. monostate is the @@ -54,10 +56,21 @@ struct Twine const Suffix &suffix() const { return std::get(data); } }; +struct TwinePoolExtender; class TwinePool { +private: + friend struct TwinePoolExtender; + uint32_t& refcount(Twine::Id id); public: - TwinePool() = default; + TwinePool(); + // Custom copy: functor pointers must target the NEW pool's nodes_. + TwinePool(const TwinePool &other); + TwinePool &operator=(const TwinePool &other); + // Move is deleted; the intrusive functors hold `this`, so a move would + // silently leave them pointing at the old (now-empty) pool. + TwinePool(TwinePool &&) = delete; + TwinePool &operator=(TwinePool &&) = delete; // Intern a leaf string. Returns the same Id for byte-equal inputs. The // returned Id carries one reference for the caller — release it when @@ -65,14 +78,14 @@ public: Twine::Id intern(std::string_view leaf); // Intern a Suffix node. The resulting flat string is - // flat_string(parent) + tail. `parent` must be a flat node (Leaf or + // flat_string(prefix) + tail. `prefix` must be a flat node (Leaf or // Suffix) — pass Twine::Null with a non-empty `tail` to fall back to - // intern(tail). Suffixes with the same (parent, tail) dedup. The + // intern(tail). Suffixes with the same (prefix, tail) dedup. The // returned Id carries one reference for the caller. Internally the - // new suffix retains a reference on `parent`; releasing the suffix - // releases that internal parent ref. Empty `tail` returns `parent` + // new suffix retains a reference on `prefix`; releasing the suffix + // releases that internal prefix ref. Empty `tail` returns `prefix` // (with +1 ref for the caller). - Twine::Id intern_suffix(Twine::Id parent, std::string_view tail); + Twine::Id intern_suffix(Twine::Id prefix, std::string_view tail); // Build a Concat node referencing `parts` in order. Concat children are // always leaves (flat-leaf invariant): any Concat passed in `parts` has @@ -85,15 +98,26 @@ public: Twine::Id concat(std::span parts); Twine::Id concat(Twine::Id a, Twine::Id b); + // Non-interning lookup: return the Id of the leaf whose string equals + // `sv`, or Twine::Null if no such leaf exists. Does not allocate. + Twine::Id lookup(std::string_view sv) const; + // Refcount control. retain bumps; release decrements and, on reaching // zero, marks the slot dead, drops it from the dedup indexes, releases // any child refs the slot owned, and pushes the slot id onto the free // list for reuse by the next intern/concat. Both no-op on Twine::Null. + + size_t index(Twine* p) const; void retain(Twine::Id id); void release(Twine::Id id); uint32_t refcount(Twine::Id id) const; bool is_alive(Twine::Id id) const; + // Quick character queries on any flat node — avoids materializing the + // full string for the common `name[0] == '$'` / `.isPublic()` tests. + char first_char(Twine::Id id) const; + bool is_public(Twine::Id id) const { return first_char(id) == '\\'; } + // Materialize a Twine to the pipe-separated flat string used by the // existing src attribute convention. Leaves visit in left-to-right DFS // order; duplicate leaves are skipped to match `pool`-style semantics. @@ -105,16 +129,13 @@ public: // Format an interned Id as the canonical src-attribute reference "@N". // Twine::Null formats as the empty string. - static std::string format_ref(Twine::Id id); + std::string format_ref(Twine::Id id) const; - // Parse an "@N" reference back to an Id. Returns Twine::Null if `s` is - // not exactly "@" followed by one or more decimal digits — so legacy - // literal src strings (which always contain ':' separators and have no - // reason to start with '@') are passed through unrecognized. - static Twine::Id parse_ref(std::string_view s); + // Parse an "@N" reference back to an Id + static std::optional parse_ref(std::string_view s); + Twine::Id get_ref(std::string_view s); - // Lookup. Bounds-checked: out-of-range Id triggers log_assert via op. - const Twine &operator[](Twine::Id id) const { return nodes_.at(id); } + const Twine &operator[](Twine::Id id) const { return *id; } size_t size() const { return nodes_.size(); } size_t leaf_count() const { return leaf_index_.size(); } @@ -143,101 +164,243 @@ public: // Iterate every live (non-tombstoned) node. fn is `void(Twine::Id, const Twine&)`. template void for_each_live(Fn fn) const { - for (size_t i = 0; i < nodes_.size(); i++) { - const Twine &n = nodes_[i]; + for (auto& n : nodes_) { if (n.is_dead()) continue; - fn(static_cast(i), n); + fn(&n, n); // TODO de-stupid this } } private: std::vector nodes_; std::vector refcount_; - std::vector free_list_; - dict leaf_index_; - dict, Twine::Id> concat_index_; - dict, Twine::Id> suffix_index_; + std::list free_list_; + + // --- Intrusive dedup indexes (Step 0) ----------------------------------- + // Each set stores only the Twine::Id; hash/eq functors reach into + // nodes_[id] for the keying data. This avoids the duplicate-string cost + // of the old dict approach. + // All functors hold a raw pointer to *this; TwinePool is non-movable + // and copy-assignment rebuilds the sets from scratch so the pointer + // always stays valid. + + using SuffixKey = std::pair; + + struct LeafHash { + using is_transparent = void; + const TwinePool *pool; + size_t operator()(Twine::Id id) const noexcept { + return std::hash{}(id->leaf()); + } + size_t operator()(std::string_view sv) const noexcept { + return std::hash{}(sv); + } + }; + struct LeafEq { + using is_transparent = void; + const TwinePool *pool; + bool operator()(Twine::Id a, Twine::Id b) const noexcept { + return a->leaf() == b->leaf(); + } + bool operator()(Twine::Id id, std::string_view sv) const noexcept { + return id->leaf() == sv; + } + bool operator()(std::string_view sv, Twine::Id id) const noexcept { + return sv == id->leaf(); + } + }; + struct SuffixHash { + using is_transparent = void; + const TwinePool *pool; + static size_t combine(size_t a, size_t b) noexcept { + return a ^ (b + 0x9e3779b9u + (a << 6) + (a >> 2)); + } + size_t operator()(Twine::Id id) const noexcept { + const auto &s = id->suffix(); + return combine(std::hash{}(s.prefix), + std::hash{}(s.tail)); + } + size_t operator()(SuffixKey k) const noexcept { + return combine(std::hash{}(k.first), + std::hash{}(k.second)); + } + }; + struct SuffixEq { + using is_transparent = void; + const TwinePool *pool; + bool operator()(Twine::Id a, Twine::Id b) const noexcept { + const auto &sa = a->suffix(); + const auto &sb = b->suffix(); + return sa.prefix == sb.prefix && sa.tail == sb.tail; + } + bool operator()(Twine::Id id, SuffixKey k) const noexcept { + const auto &s = id->suffix(); + return s.prefix == k.first && s.tail == k.second; + } + bool operator()(SuffixKey k, Twine::Id id) const noexcept { + return (*this)(id, k); + } + }; + struct ConcatHash { + using is_transparent = void; + const TwinePool *pool; + static size_t hash_ids(std::span v) noexcept { + size_t h = 0; + for (Twine::Id c : v) + h ^= std::hash{}(c) + 0x9e3779b9u + (h << 6) + (h >> 2); + return h; + } + size_t operator()(Twine::Id id) const noexcept { + return hash_ids(id->children()); + } + size_t operator()(std::span v) const noexcept { + return hash_ids(v); + } + }; + struct ConcatEq { + using is_transparent = void; + const TwinePool *pool; + bool operator()(Twine::Id a, Twine::Id b) const noexcept { + return a->children() == b->children(); + } + bool operator()(Twine::Id id, std::span v) const noexcept { + const auto &ch = id->children(); + return ch.size() == v.size() && + std::equal(ch.begin(), ch.end(), v.begin()); + } + bool operator()(std::span v, Twine::Id id) const noexcept { + return (*this)(id, v); + } + }; + + std::unordered_set leaf_index_; + std::unordered_set suffix_index_; + std::unordered_set concat_index_; + // ------------------------------------------------------------------------- Twine::Id alloc_slot_(Twine &&node); void destroy_slot_(Twine::Id id); void collect_leaves(Twine::Id id, pool &out) const; // Materialize a flat node (Leaf or Suffix) into its full string. std::string flat_string_(Twine::Id id) const; + // Populate the three indexes from the current nodes_ vector (used by + // the copy constructor/assignment and by gc()). + void rebuild_indexes_(); }; -// Owning reference to a Twine slot. Retains on construction (and on copy -// of a non-empty ref), releases on destruction. Use this in transient -// container types — FfData, Mem helpers — that need to keep a src_id_ -// alive across destruction of the original AttrObject that minted it, -// without having to fall back to a flattened path-string stash. -// -// Empty (no pool/no id) by default. A non-empty ref always carries a -// non-null pool and a live id. -class OwnedTwine -{ -public: - OwnedTwine() = default; +// // Owning reference to a Twine slot. Retains on construction (and on copy +// // of a non-empty ref), releases on destruction. Use this in transient +// // container types — FfData, Mem helpers — that need to keep a src_id_ +// // alive across destruction of the original AttrObject that minted it, +// // without having to fall back to a flattened path-string stash. +// // +// // Empty (no pool/no id) by default. A non-empty ref always carries a +// // non-null pool and a live id. +// class OwnedTwine +// { +// public: +// OwnedTwine() = default; - // Adopt the +1 reference returned by `intern` / `concat` / `intern_suffix` - // / `copy_from`. Use OwnedTwine(pool, id, retain=true) when copying an - // id already held elsewhere (e.g. another AttrObject's src_id_). - OwnedTwine(TwinePool *pool, Twine::Id id, bool retain = true) : pool_(pool), id_(id) { - if (retain && pool_ && id_ != Twine::Null) - pool_->retain(id_); - } +// // Adopt the +1 reference returned by `intern` / `concat` / `intern_suffix` +// // / `copy_from`. Use OwnedTwine(pool, id, retain=true) when copying an +// // id already held elsewhere (e.g. another AttrObject's src_id_). +// OwnedTwine(TwinePool *pool, Twine::Id id, bool retain = true) : pool_(pool), id_(id) { +// if (retain && pool_ && id_ != Twine::Null) +// pool_->retain(id_); +// } - OwnedTwine(const OwnedTwine &other) : pool_(other.pool_), id_(other.id_) { - if (pool_ && id_ != Twine::Null) - pool_->retain(id_); - } +// OwnedTwine(const OwnedTwine &other) : pool_(other.pool_), id_(other.id_) { +// if (pool_ && id_ != Twine::Null) +// pool_->retain(id_); +// } - OwnedTwine(OwnedTwine &&other) noexcept : pool_(other.pool_), id_(other.id_) { - other.pool_ = nullptr; - other.id_ = Twine::Null; - } +// OwnedTwine(OwnedTwine &&other) noexcept : pool_(other.pool_), id_(other.id_) { +// other.pool_ = nullptr; +// other.id_ = Twine::Null; +// } - OwnedTwine &operator=(const OwnedTwine &other) { - if (this == &other) - return *this; - release_(); - pool_ = other.pool_; - id_ = other.id_; - if (pool_ && id_ != Twine::Null) - pool_->retain(id_); - return *this; - } +// OwnedTwine &operator=(const OwnedTwine &other) { +// if (this == &other) +// return *this; +// release_(); +// pool_ = other.pool_; +// id_ = other.id_; +// if (pool_ && id_ != Twine::Null) +// pool_->retain(id_); +// return *this; +// } - OwnedTwine &operator=(OwnedTwine &&other) noexcept { - if (this == &other) - return *this; - release_(); - pool_ = other.pool_; - id_ = other.id_; - other.pool_ = nullptr; - other.id_ = Twine::Null; - return *this; - } +// OwnedTwine &operator=(OwnedTwine &&other) noexcept { +// if (this == &other) +// return *this; +// release_(); +// pool_ = other.pool_; +// id_ = other.id_; +// other.pool_ = nullptr; +// other.id_ = Twine::Null; +// return *this; +// } - ~OwnedTwine() { release_(); } +// ~OwnedTwine() { release_(); } - void reset() { - release_(); - pool_ = nullptr; - id_ = Twine::Null; - } +// void reset() { +// release_(); +// pool_ = nullptr; +// id_ = Twine::Null; +// } - TwinePool *pool() const { return pool_; } - Twine::Id id() const { return id_; } - bool empty() const { return id_ == Twine::Null; } +// TwinePool *pool() const { return pool_; } +// Twine::Id id() const { return id_; } +// bool empty() const { return id_ == Twine::Null; } +// private: +// TwinePool *pool_ = nullptr; +// Twine::Id id_ = Twine::Null; + +// void release_() { +// if (pool_ && id_ != Twine::Null) +// pool_->release(id_); +// } +// }; + +struct TwinePoolExtender { + TwinePool& pool; + size_t offset; private: - TwinePool *pool_ = nullptr; - Twine::Id id_ = Twine::Null; - - void release_() { - if (pool_ && id_ != Twine::Null) - pool_->release(id_); + size_t resize_for_idx(size_t idx) { + auto real_idx = offset + idx; + pool.nodes_.resize(std::max(pool.nodes_.size(), real_idx + 1)); + return real_idx; + } + void commit(Twine&& twine, size_t idx) { + pool.nodes_[idx] = std::move(twine); + pool.leaf_index_.insert(&pool.nodes_[idx]); + } +public: + // TwinePoolExtender(Design* design) : pool(design->twines), offset(design->twines.size()) {} + void extend_leaf(std::string leaf, size_t idx) { + auto real_idx = resize_for_idx(idx); + commit(Twine(leaf), real_idx); + } + void extend_concat(std::vector children, size_t idx) { + auto real_idx = resize_for_idx(idx); + Twine* first = &pool.nodes_.front() + offset; + std::vector real_children; + real_children.reserve(children.size()); + for (auto child : children) + real_children.push_back(first + child); + commit(Twine(std::move(real_children)), real_idx); + } + void extend_suffix(size_t prefix, std::string tail, size_t idx) { + auto real_idx = resize_for_idx(idx); + Twine* first = &pool.nodes_.front() + offset; + Twine* real_prefix = first + prefix; + commit(Twine(Twine::Suffix(real_prefix, std::move(tail))), real_idx); + } + void finish() { + for (size_t i = offset; i < pool.nodes_.size(); i++) + if (pool.nodes_[i].is_dead()) + pool.free_list_.push_back(&pool.nodes_[i]); } }; diff --git a/kernel/unstable/patch.cc b/kernel/unstable/patch.cc index bec4136bb..0ad08ea2b 100644 --- a/kernel/unstable/patch.cc +++ b/kernel/unstable/patch.cc @@ -24,7 +24,7 @@ Wire* Patch::addWire(IdString name, int width) { wires_.push_back(std::make_unique(Wire::ConstructToken{})); Wire* wire = wires_.back().get(); - wire->name = name; + staged_wire_names_[wire] = name; wire->width = width; wire->module = nullptr; return wire; @@ -48,7 +48,12 @@ RTLIL::Wire *RTLIL::Patch::addWire(RTLIL::IdString name, const RTLIL::Wire *othe Wire* Patch::commit_wire(std::unique_ptr wire) { Wire* raw = wire.release(); - mod->wires_[raw->name] = raw; + IdString name = staged_wire_names_.at(raw); + staged_wire_names_.erase(raw); + Twine::Id id = mod->design->twines.intern(name.str()); + mod->design->obj_set_name_id(raw, id); + mod->design->twines.release(id); + mod->wires_[raw->meta_->name_id] = raw; raw->module = mod; return raw; } @@ -57,9 +62,11 @@ Cell* Patch::commit_cell(std::unique_ptr cell) { Cell* raw = cell.release(); IdString name = staged_cell_names_.at(raw); staged_cell_names_.erase(raw); - raw->name = name; + Twine::Id id = mod->design->twines.intern(name.str()); + mod->design->obj_set_name_id(raw, id); + mod->design->twines.release(id); raw->module = mod; - mod->cells_[name] = raw; + mod->cells_[raw->meta_->name_id] = raw; raw->initIndex(); return raw; } @@ -87,7 +94,7 @@ namespace { if (!mod || !mod->design) return; - TwinePool& pool = mod->design->src_twines; + TwinePool& pool = mod->design->twines; std::vector ids; ids.reserve(2 + extras.size()); auto push = [&](Cell *c) { @@ -103,7 +110,7 @@ namespace { Twine::Id merged = pool.concat(std::span{ids}); if (ys_debug()) { log_debug("twine: merge yields %s (pool size %zu)\n", - TwinePool::format_ref(merged).c_str(), pool.size()); + pool.format_ref(merged).c_str(), pool.size()); if (ys_debug(2)) pool.dump("twine pool state"); } diff --git a/kernel/unstable/patch.h b/kernel/unstable/patch.h index 8eebe2975..b0c4e8e53 100644 --- a/kernel/unstable/patch.h +++ b/kernel/unstable/patch.h @@ -27,6 +27,7 @@ public: vector> wires_ = {}; vector> cells_ = {}; dict staged_cell_names_; + dict staged_wire_names_; void connect(const RTLIL::SigSig &conn); void connect(const RTLIL::SigSpec &lhs, const RTLIL::SigSpec &rhs); diff --git a/kernel/yosys.cc b/kernel/yosys.cc index de5baaee8..d4bdd0922 100644 --- a/kernel/yosys.cc +++ b/kernel/yosys.cc @@ -369,7 +369,7 @@ const char *create_prompt(RTLIL::Design *design, int recursion_counter) if (design->selected_active_module.empty()) str += "*"; else if (design->selection().selected_modules.size() != 1 || design->selection().selected_members.size() != 0 || - design->selection().selected_modules.count(design->selected_active_module) == 0) + design->selection().selected_modules.count(design->twines.intern(design->selected_active_module)) == 0) str += "*"; } snprintf(buffer, 100, "%s> ", str.c_str()); diff --git a/passes/cmds/check.cc b/passes/cmds/check.cc index 9fb648748..fd0d91aac 100644 --- a/passes/cmds/check.cc +++ b/passes/cmds/check.cc @@ -288,7 +288,7 @@ struct CheckPass : public Pass { SigBit to = sigmap(to_portsig[to_bit]); if (from.wire && to.wire) - topo.edge(std::make_pair(from.wire->name, from.offset), std::make_pair(to.wire->name, to.offset)); + topo.edge(std::make_pair(RTLIL::IdString(from.wire->name), from.offset), std::make_pair(RTLIL::IdString(to.wire->name), to.offset)); } bool detail_costly(Cell *cell) { @@ -338,14 +338,14 @@ struct CheckPass : public Pass { if (cell->input(conn.first)) for (auto bit : sigmap(conn.second)) if (bit.wire) - topo.edge(std::make_pair(bit.wire->name, bit.offset), - std::make_pair(cell->name, -1)); + topo.edge(std::make_pair(RTLIL::IdString(bit.wire->name), bit.offset), + std::make_pair(RTLIL::IdString(cell->name), -1)); if (cell->output(conn.first)) for (auto bit : sigmap(conn.second)) if (bit.wire) - topo.edge(std::make_pair(cell->name, -1), - std::make_pair(bit.wire->name, bit.offset)); + topo.edge(std::make_pair(RTLIL::IdString(cell->name), -1), + std::make_pair(RTLIL::IdString(bit.wire->name), bit.offset)); } // Return false to signify the fallback diff --git a/passes/cmds/design_equal.cc b/passes/cmds/design_equal.cc index 1912a823e..9db43c3e2 100644 --- a/passes/cmds/design_equal.cc +++ b/passes/cmds/design_equal.cc @@ -104,14 +104,18 @@ public: void check_wires() { for (const auto &it : mod_a->wires_) { - if (mod_b->wires_.count(it.first) == 0) - error("Module %s missing wire %s in second design.\n", mod_a->name.unescape(), it.first.unescape()); - if (std::string mismatch = compare_wires(it.second, mod_b->wires_.at(it.first)); !mismatch.empty()) - error("Module %s wire %s %s.\n", mod_a->name.unescape(), it.first.unescape(), mismatch); + RTLIL::IdString wname(it.second->name); + RTLIL::Wire *wb = mod_b->wire(wname); + if (!wb) + error("Module %s missing wire %s in second design.\n", mod_a->name.unescape(), wname.unescape()); + else if (std::string mismatch = compare_wires(it.second, wb); !mismatch.empty()) + error("Module %s wire %s %s.\n", mod_a->name.unescape(), wname.unescape(), mismatch); + } + for (const auto &it : mod_b->wires_) { + RTLIL::IdString wname(it.second->name); + if (!mod_a->wire(wname)) + error("Module %s missing wire %s in first design.\n", mod_b->name.unescape(), wname.unescape()); } - for (const auto &it : mod_b->wires_) - if (mod_a->wires_.count(it.first) == 0) - error("Module %s missing wire %s in first design.\n", mod_b->name.unescape(), it.first.unescape()); } std::string compare_memories(const RTLIL::Memory *a, const RTLIL::Memory *b) @@ -164,14 +168,18 @@ public: void check_cells() { for (const auto &it : mod_a->cells_) { - if (mod_b->cells_.count(it.first) == 0) - error("Module %s missing cell %s in second design.\n", mod_a->name.unescape(), it.first.unescape()); - if (std::string mismatch = compare_cells(it.second, mod_b->cells_.at(it.first)); !mismatch.empty()) - error("Module %s cell %s %s.\n", mod_a->name.unescape(), it.first.unescape(), mismatch); + RTLIL::IdString cname(it.second->name); + RTLIL::Cell *cb = mod_b->cell(cname); + if (!cb) + error("Module %s missing cell %s in second design.\n", mod_a->name.unescape(), cname.unescape()); + else if (std::string mismatch = compare_cells(it.second, cb); !mismatch.empty()) + error("Module %s cell %s %s.\n", mod_a->name.unescape(), cname.unescape(), mismatch); + } + for (const auto &it : mod_b->cells_) { + RTLIL::IdString cname(it.second->name); + if (!mod_a->cell(cname)) + error("Module %s missing cell %s in first design.\n", mod_b->name.unescape(), cname.unescape()); } - for (const auto &it : mod_b->cells_) - if (mod_a->cells_.count(it.first) == 0) - error("Module %s missing cell %s in first design.\n", mod_b->name.unescape(), it.first.unescape()); } void check_memories() diff --git a/passes/cmds/dump_twines.cc b/passes/cmds/dump_twines.cc index 06a012849..a067f3c02 100644 --- a/passes/cmds/dump_twines.cc +++ b/passes/cmds/dump_twines.cc @@ -19,7 +19,7 @@ struct DumpTwinesPass : public Pass { log("\n"); log(" dump_twines [-flat]\n"); log("\n"); - log("Print every node in design->src_twines. Leaves show the literal\n"); + log("Print every node in design->twines. Leaves show the literal\n"); log("path:line.col string, concats show their child id list. With\n"); log("-flat each concat is additionally rendered as the pipe-joined\n"); log("flat string a backend would emit.\n"); @@ -39,7 +39,7 @@ struct DumpTwinesPass : public Pass { } extra_args(args, argidx, design); - const TwinePool &pool = design->src_twines; + const TwinePool &pool = design->twines; log("twine pool: %zu nodes (%zu leaves, %zu suffixes, %zu concats)\n", pool.size(), pool.leaf_count(), pool.suffix_count(), pool.concat_count()); pool.for_each_live([&](Twine::Id id, const Twine &n) { @@ -82,7 +82,7 @@ struct GcTwinesPass : public Pass { log(" gc_twines\n"); log("\n"); log("Walk the design, collect every \"@N\" referenced by any cell, wire,\n"); - log("module, memory, or process attribute, and rebuild design->src_twines\n"); + log("module, memory, or process attribute, and rebuild design->twines\n"); log("to contain only those entries plus their transitive leaf children.\n"); log("Cell src attributes are rewritten in place via the resulting id\n"); log("remap, so the design is unchanged at the path:line.col layer.\n"); @@ -98,10 +98,10 @@ struct GcTwinesPass : public Pass { void execute(std::vector args, RTLIL::Design *design) override { extra_args(args, 1, design); - size_t before = design->src_twines.size(); + size_t before = design->twines.size(); size_t freed = design->gc_twines(); log("twine gc: %zu nodes -> %zu (%zu freed)\n", - before, design->src_twines.size(), freed); + before, design->twines.size(), freed); } } GcTwinesPass; diff --git a/passes/cmds/select.cc b/passes/cmds/select.cc index 6f7c55ad6..98ae7adae 100644 --- a/passes/cmds/select.cc +++ b/passes/cmds/select.cc @@ -239,12 +239,12 @@ static void select_op_random(RTLIL::Design *design, RTLIL::Selection &lhs, int c for (auto cell : mod->cells()) { if (lhs.selected_member(mod->name, cell->name)) - objects.push_back(make_pair(RTLIL::IdString(mod->name), cell->name)); + objects.push_back(make_pair(RTLIL::IdString(mod->name), RTLIL::IdString(cell->name))); } for (auto wire : mod->wires()) { if (lhs.selected_member(mod->name, wire->name)) - objects.push_back(make_pair(RTLIL::IdString(mod->name), wire->name)); + objects.push_back(make_pair(RTLIL::IdString(mod->name), RTLIL::IdString(wire->name))); } } @@ -1792,7 +1792,7 @@ static void log_matches(const char *title, Module *module, const T &list) for (auto &it : list) if (module->selected(it.second)) - matches.push_back(it.first); + matches.push_back(RTLIL::IdString(it.second->name)); if (!matches.empty()) { log("\n%d %s:\n", int(matches.size()), title); diff --git a/passes/cmds/xprop.cc b/passes/cmds/xprop.cc index 25c1a7320..cc11040c2 100644 --- a/passes/cmds/xprop.cc +++ b/passes/cmds/xprop.cc @@ -486,7 +486,7 @@ struct XpropWorker auto sig_a = cell->getPort(ID::A); auto sig_b = cell->getPort(ID::B); - auto name = cell->name; + RTLIL::IdString name(cell->name); module->remove(cell); module->addXnor(name, sig_a, sig_b, sig_y); return; @@ -497,7 +497,7 @@ struct XpropWorker auto sig_a = cell->getPort(ID::A); auto sig_b = cell->getPort(ID::B); - auto name = cell->name; + RTLIL::IdString name(cell->name); auto type = cell->type; module->remove(cell); if (type == ID($eqx)) diff --git a/passes/equiv/equiv_miter.cc b/passes/equiv/equiv_miter.cc index c0b96e199..95eaac33d 100644 --- a/passes/equiv/equiv_miter.cc +++ b/passes/equiv/equiv_miter.cc @@ -160,7 +160,7 @@ struct EquivMiterWorker vector chunks = sig.chunks(); for (auto &c : chunks) if (c.wire != NULL) - c.wire = mod->wires_.at(c.wire->name); + c.wire = mod->wire(RTLIL::IdString(c.wire->name)); sig = chunks; } }; diff --git a/passes/fsm/fsm_extract.cc b/passes/fsm/fsm_extract.cc index 43a797ff4..bed58bc40 100644 --- a/passes/fsm/fsm_extract.cc +++ b/passes/fsm/fsm_extract.cc @@ -69,7 +69,7 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL for (auto &cellport : cellport_list) { - RTLIL::Cell *cell = module->cells_.at(cellport.first); + RTLIL::Cell *cell = module->cell(cellport.first); if ((cell->type != ID($mux) && cell->type != ID($pmux)) || cellport.second != ID::Y) { log(" unexpected cell type %s (%s) found in state selection tree.\n", cell->type, cell->name); return false; @@ -271,7 +271,7 @@ static void extract_fsm(RTLIL::Wire *wire) std::set cellport_list; sig2driver.find(dff_out, cellport_list); for (auto &cellport : cellport_list) { - RTLIL::Cell *cell = module->cells_.at(cellport.first); + RTLIL::Cell *cell = module->cell(cellport.first); if ((cell->type != ID($dff) && cell->type != ID($adff)) || cellport.second != ID::Q) continue; log(" found %s cell for state register: %s\n", cell->type, cell->name); @@ -319,7 +319,7 @@ static void extract_fsm(RTLIL::Wire *wire) cellport_list.clear(); sig2trigger.find(dff_out, cellport_list); for (auto &cellport : cellport_list) { - RTLIL::Cell *cell = module->cells_.at(cellport.first); + RTLIL::Cell *cell = module->cell(cellport.first); RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A)); RTLIL::SigSpec sig_b; if (cell->hasPort(ID::B)) @@ -388,10 +388,8 @@ static void extract_fsm(RTLIL::Wire *wire) // rename original state wire - module->wires_.erase(wire->name); wire->attributes.erase(ID::fsm_encoding); - wire->name = stringf("$fsm$oldstate%s", wire->name); - module->wires_[wire->name] = wire; + module->rename(wire, stringf("$fsm$oldstate%s", wire->name.c_str())); if(wire->attributes.count(ID::hdlname)) { auto hdlname = wire->get_hdlname_attribute(); hdlname.pop_back(); @@ -405,7 +403,7 @@ static void extract_fsm(RTLIL::Wire *wire) cellport_list.clear(); sig2driver.find(ctrl_out, cellport_list); for (auto &cellport : cellport_list) { - RTLIL::Cell *cell = module->cells_.at(cellport.first); + RTLIL::Cell *cell = module->cell(cellport.first); RTLIL::SigSpec port_sig = assign_map(cell->getPort(cellport.second)); RTLIL::SigSpec unconn_sig = port_sig.extract(ctrl_out); RTLIL::Wire *unconn_wire = module->addWire(stringf("$fsm_unconnect$%d", autoidx++), unconn_sig.size()); diff --git a/passes/memory/memory_map.cc b/passes/memory/memory_map.cc index 314a62175..d96f3803a 100644 --- a/passes/memory/memory_map.cc +++ b/passes/memory/memory_map.cc @@ -259,7 +259,7 @@ struct MemoryMapWorker c->setPort(ID::D, w_in); std::string w_out_name = stringf("%s[%d]", mem.memid, addr); - if (module->wires_.count(w_out_name) > 0) + if (module->wire(RTLIL::IdString(w_out_name)) != nullptr) w_out_name = genid(mem.memid, "", addr, "$q"); RTLIL::Wire *w_out = module->addWire(w_out_name, mem.width); diff --git a/passes/sat/cutpoint.cc b/passes/sat/cutpoint.cc index f36b04a2b..f0582dc69 100644 --- a/passes/sat/cutpoint.cc +++ b/passes/sat/cutpoint.cc @@ -152,7 +152,7 @@ struct CutpointPass : public Pass { } RTLIL::Cell *scopeinfo = nullptr; - auto cell_name = cell->name; + RTLIL::IdString cell_name(cell->name); if (flag_scopeinfo && cell_name.isPublic()) { auto scopeinfo = module->addCell(NEW_ID, ID($scopeinfo)); scopeinfo->setParam(ID::TYPE, RTLIL::Const("blackbox")); diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 259bf4155..0dd208307 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -1298,8 +1298,8 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) SigBit D = mapped_cell->getPort(ID::D); SigBit Q = mapped_cell->getPort(ID::Q); if (D.wire) - D.wire = module->wires_.at(remap_name(D.wire->name)); - Q.wire = module->wires_.at(remap_name(Q.wire->name)); + D.wire = module->wire(remap_name(D.wire->name)); + Q.wire = module->wire(remap_name(Q.wire->name)); module->connect(Q, D); continue; } @@ -1341,8 +1341,8 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) // If a driver couldn't be found (could be from PI or box CI) // then implement using a LUT RTLIL::Cell *cell = module->addLut(remap_name(stringf("$lut%s", mapped_cell->name)), - RTLIL::SigBit(module->wires_.at(remap_name(a_bit.wire->name)), a_bit.offset), - RTLIL::SigBit(module->wires_.at(remap_name(y_bit.wire->name)), y_bit.offset), + RTLIL::SigBit(module->wire(remap_name(a_bit.wire->name)), a_bit.offset), + RTLIL::SigBit(module->wire(remap_name(y_bit.wire->name)), y_bit.offset), RTLIL::Const::from_string("01")); bit2sinks[cell->getPort(ID::A)].push_back(cell); cell_stats[ID($lut)]++; @@ -1365,7 +1365,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) continue; //log_assert(c.width == 1); if (c.wire) - c.wire = module->wires_.at(remap_name(c.wire->name)); + c.wire = module->wire(remap_name(c.wire->name)); newsig.append(c); } cell->setPort(mapped_conn.first, newsig); @@ -1392,9 +1392,9 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) SigBit I = mapped_cell->getPort(ID(i)); SigBit O = mapped_cell->getPort(ID(o)); if (I.wire) - I.wire = module->wires_.at(remap_name(I.wire->name)); + I.wire = module->wire(remap_name(I.wire->name)); log_assert(O.wire); - O.wire = module->wires_.at(remap_name(O.wire->name)); + O.wire = module->wire(remap_name(O.wire->name)); module->connect(O, I); continue; } @@ -1434,7 +1434,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) old_q = existing_cell->getPort(port_name); } auto new_q = outputs[0]; - new_q.wire = module->wires_.at(remap_name(new_q.wire->name)); + new_q.wire = module->wire(remap_name(new_q.wire->name)); module->connect(old_q, new_q); } else { @@ -1467,7 +1467,7 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) continue; //log_assert(c.width == 1); if (c.wire) - c.wire = module->wires_.at(remap_name(c.wire->name)); + c.wire = module->wire(remap_name(c.wire->name)); newsig.append(c); } @@ -1490,14 +1490,14 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) if (!conn.first.is_fully_const()) { std::vector chunks = conn.first.chunks(); for (auto &c : chunks) - c.wire = module->wires_.at(remap_name(c.wire->name)); + c.wire = module->wire(remap_name(c.wire->name)); conn.first = std::move(chunks); } if (!conn.second.is_fully_const()) { std::vector chunks = conn.second.chunks(); for (auto &c : chunks) if (c.wire) - c.wire = module->wires_.at(remap_name(c.wire->name)); + c.wire = module->wire(remap_name(c.wire->name)); conn.second = std::move(chunks); } module->connect(conn); @@ -1564,8 +1564,8 @@ void reintegrate(RTLIL::Module *module, bool dff_mode) RTLIL::SigBit y_bit = not_cell->getPort(ID::Y); RTLIL::Const driver_mask; - a_bit.wire = module->wires_.at(remap_name(a_bit.wire->name)); - y_bit.wire = module->wires_.at(remap_name(y_bit.wire->name)); + a_bit.wire = module->wire(remap_name(a_bit.wire->name)); + y_bit.wire = module->wire(remap_name(y_bit.wire->name)); auto jt = bit2sinks.find(a_bit); if (jt == bit2sinks.end()) @@ -1614,7 +1614,7 @@ clone_lut: y_bit, driver_mask); for (auto &bit : cell->connections_.at(ID::A)) { - bit.wire = module->wires_.at(remap_name(bit.wire->name)); + bit.wire = module->wire(remap_name(bit.wire->name)); bit2sinks[bit].push_back(cell); } } diff --git a/passes/techmap/clkbufmap.cc b/passes/techmap/clkbufmap.cc index 36ee9c898..46cf528da 100644 --- a/passes/techmap/clkbufmap.cc +++ b/passes/techmap/clkbufmap.cc @@ -145,16 +145,16 @@ struct ClkbufmapPass : public Pass { auto wire = module->wire(port); if (wire->get_bool_attribute(ID::clkbuf_driver)) for (int i = 0; i < GetSize(wire); i++) - buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i))); + buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i))); if (wire->get_bool_attribute(ID::clkbuf_sink)) for (int i = 0; i < GetSize(wire); i++) - sink_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i))); + sink_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i))); auto it = wire->attributes.find(ID::clkbuf_inv); if (it != wire->attributes.end()) { IdString in_name = RTLIL::escape_id(it->second.decode_string()); for (int i = 0; i < GetSize(wire); i++) { - inv_ports_out[make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i))] = make_pair(in_name, i); - inv_ports_in[make_pair(RTLIL::IdString(module->name), make_pair(in_name, i))] = make_pair(wire->name, i); + inv_ports_out[make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i))] = make_pair(in_name, i); + inv_ports_in[make_pair(RTLIL::IdString(module->name), make_pair(in_name, i))] = make_pair(RTLIL::IdString(wire->name), i); } } } @@ -236,7 +236,7 @@ struct ClkbufmapPass : public Pass { // some buffer higher up in the hierarchy. if (wire->port_output) for (int i = 0; i < GetSize(wire); i++) - buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i))); + buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i))); continue; } @@ -249,7 +249,7 @@ struct ClkbufmapPass : public Pass { if (buf_wire_bits.count(mapped_wire_bit)) { // Already buffered downstream. If this is an output, mark it. if (wire->port_output) - buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i))); + buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i))); } else if (!sink_wire_bits.count(mapped_wire_bit)) { // Nothing to do. } else if (driven_wire_bits.count(wire_bit) || (wire->port_input && module->get_bool_attribute(ID::top))) { @@ -288,7 +288,7 @@ struct ClkbufmapPass : public Pass { // A clock input in a submodule -- mark it, let higher level // worry about it. if (wire->port_input) - sink_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i))); + sink_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i))); } } if (!input_bits.empty()) { @@ -320,7 +320,7 @@ struct ClkbufmapPass : public Pass { SigBit wire_bit(wire, i); SigBit mapped_wire_bit = sigmap(wire_bit); if (buffered_bits.count(mapped_wire_bit)) - buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i))); + buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i))); } } diff --git a/passes/techmap/dfflibmap.cc b/passes/techmap/dfflibmap.cc index e8fc6fc12..aee627113 100644 --- a/passes/techmap/dfflibmap.cc +++ b/passes/techmap/dfflibmap.cc @@ -512,7 +512,7 @@ static void dfflibmap(RTLIL::Design *design, RTLIL::Module *module) for (auto cell : cell_list) { auto cell_type = cell->type; - auto cell_name = cell->name; + RTLIL::IdString cell_name(cell->name); auto cell_connections = cell->connections(); std::string src = cell->get_src_attribute(); diff --git a/passes/techmap/iopadmap.cc b/passes/techmap/iopadmap.cc index ba29d257a..80130f0fb 100644 --- a/passes/techmap/iopadmap.cc +++ b/passes/techmap/iopadmap.cc @@ -217,7 +217,7 @@ struct IopadmapPass : public Pass { // Collect explicitly-marked already-buffered SigBits. for (auto wire : module->wires()) - if (wire->get_bool_attribute(ID::iopad_external_pin) || ignore.count(make_pair(RTLIL::IdString(module->name), wire->name))) + if (wire->get_bool_attribute(ID::iopad_external_pin) || ignore.count(make_pair(RTLIL::IdString(module->name), RTLIL::IdString(wire->name)))) for (int i = 0; i < GetSize(wire); i++) buf_bits.insert(sigmap(SigBit(wire, i))); @@ -233,7 +233,7 @@ struct IopadmapPass : public Pass { if (wire->port_input || wire->port_output) for (int i = 0; i < GetSize(wire); i++) if (buf_bits.count(sigmap(SigBit(wire, i)))) { - buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i))); + buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i))); log("Marking already mapped port: %s.%s[%d].\n", module, wire, i); } } @@ -293,7 +293,7 @@ struct IopadmapPass : public Pass { SigBit wire_bit(wire, i); Cell *tbuf_cell = nullptr; - if (buf_ports.count(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i)))) + if (buf_ports.count(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i)))) continue; if (tbuf_bits.count(wire_bit)) @@ -370,7 +370,7 @@ struct IopadmapPass : public Pass { if (!toutpad_portname_pad.empty()) rewrite_bits[wire][i] = make_pair(cell, RTLIL::escape_id(toutpad_portname_pad)); } - buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i))); + buf_ports.insert(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i))); } } } @@ -384,7 +384,7 @@ struct IopadmapPass : public Pass { pool skip_bit_indices; for (int i = 0; i < GetSize(wire); i++) - if (buf_ports.count(make_pair(RTLIL::IdString(module->name), make_pair(wire->name, i)))) + if (buf_ports.count(make_pair(RTLIL::IdString(module->name), make_pair(RTLIL::IdString(wire->name), i)))) skip_bit_indices.insert(i); if (GetSize(wire) == GetSize(skip_bit_indices))