diff --git a/passes/cmds/autoname.cc b/passes/cmds/autoname.cc index 2a7043a2b..134d36ee6 100644 --- a/passes/cmds/autoname.cc +++ b/passes/cmds/autoname.cc @@ -79,6 +79,7 @@ struct node { unsigned int fanout = 0; bool is_public = false; bool renameable = false; + bool selected = false; size_t name_length = 0; // Node index from which we want to construct the rename @@ -89,6 +90,8 @@ struct node { string suffix; // Is this name final? bool decided = false; + + const IdString& name() const { return cell ? cell->name : wire->name; } }; // Decides the order of exploring neighbors @@ -106,7 +109,7 @@ struct ModuleAutonamer // Cells in module order, then wires in the order that they're seen from cells. // The index doubles as the tie-break between equally good - // proposals for different nodes. + // proposals for different nodes vector nodes; vector decided; std::priority_queue, std::greater<>> queue; @@ -116,9 +119,9 @@ struct ModuleAutonamer void build_adjacency() { - auto selected = module->selected_cells(); - // Arbitrary. Kinda just for passing tests without modifying them. - for (auto cell : selected | std::views::reverse) + vector cells(module->cells().begin(), module->cells().end()); + // Arbitrary. Kinda just for passing tests without modifying them + for (auto cell : cells | std::views::reverse) nodes.emplace_back().cell = cell; int ncells = GetSize(nodes); @@ -153,23 +156,25 @@ struct ModuleAutonamer } } + // Resolve selection before renaming for (auto &nd : nodes) { - IdString name = nd.cell ? nd.cell->name : nd.wire->name; + IdString name = nd.name(); + nd.selected = nd.cell ? module->selected(nd.cell) : module->selected(nd.wire); nd.is_public = (name[0] != '$'); nd.renameable = !nd.is_public && (nd.cell || nd.wire->port_id == 0); if (nd.is_public) nd.name_length = name.str().size(); } - // Only possible once every fanout is known. + // Only possible once every fanout is known for (auto &nd : nodes) for (auto &edge : nd.edges) edge.score = edge.cell_is_output ? 0 : nodes[edge.wire].fanout; } - void offer(int from, int n, const Edge &edge, int edge_pos) + void offer(int from, int to, const Edge &edge, int edge_pos) { - node &nd = nodes[n]; + node &nd = nodes[to]; if (!nd.renameable || nd.decided) return; string suffix = nd.cell @@ -182,7 +187,7 @@ struct ModuleAutonamer nd.from_node = from; nd.name_length = c.length; nd.suffix = std::move(suffix); - queue.push(queue_item{c.score, c.length, n}); + queue.push(queue_item{c.score, c.length, to}); } // Expand a public (or newly decided) node. The name it lends @@ -214,15 +219,23 @@ struct ModuleAutonamer } } - // The source neighbour is decided before this node, so commit() reaches it - // first and its name is already final -- uniquify() suffix and all. + void append_name(int n, string &out) + { + const node &nd = nodes[n]; + if (nd.is_public || nd.selected) + return nd.name().append_to(&out); + append_name(nd.from_node, out); + out += nd.suffix; + } + void commit(int n) { node &nd = nodes[n]; - const node &src = nodes[nd.from_node]; + if (!nd.selected) + return; string full; full.reserve(nd.name_length); - (src.cell ? src.cell->name : src.wire->name).append_to(&full); + append_name(nd.from_node, full); full += nd.suffix; IdString name = module->uniquify(IdString(full)); if (nd.cell) { diff --git a/tests/various/autoname.ys b/tests/various/autoname.ys index c5bd0ba3b..22b532f2c 100644 --- a/tests/various/autoname.ys +++ b/tests/various/autoname.ys @@ -78,12 +78,21 @@ module \top end end EOT +design -save fanout_test logger -expect log "Rename cell .name in top to bcd_.and_B" 1 logger -expect log "Rename cell .name2 in top to c_has_a_long_name_.or_B" 1 logger -expect log "Renamed 2 objects" 1 debug autoname logger -check-expected +# a selection only limits what gets renamed, never the name that gets picked: +# \a's fanout still counts $name2, even though it isn't selected +design -load fanout_test +logger -expect log "Rename cell .name in top to bcd_.and_B" 1 +logger -expect log "Renamed 1 objects" 1 +debug autoname c:$name +logger -check-expected + # names are unique design -reset read_rtlil <