Improving solution for net cluster renaming for join_nets

This commit is contained in:
Matthias Koefferlein 2026-01-11 20:53:18 +01:00
parent b324f3f5cc
commit 80f78bffc9
4 changed files with 69 additions and 18 deletions

View File

@ -1581,6 +1581,10 @@ template <class T>
void
connected_clusters<T>::rename_connection (const ClusterInstance &inst, typename local_cluster<T>::id_type to_id)
{
if (inst.id () == to_id) {
return; // nothing to do
}
ClusterInstance new_inst (to_id, inst);
auto rc = m_rev_connections.find (inst);
@ -1589,24 +1593,48 @@ connected_clusters<T>::rename_connection (const ClusterInstance &inst, typename
}
auto id = rc->second;
// TODO: this linear search may be slow
auto &connections = m_connections [id];
for (auto i = connections.begin (); i != connections.end (); ++i) {
if (*i == inst) {
*i = new_inst;
break;
}
}
m_rev_connections.erase (rc);
// NOTE: if a connection to the new cluster already exists, we will not insert here.
// This may mean we are connecting two clusters here on parent level. In the netlist, this
// is reflected by having multiple upward pins. Right now, we cannot reflect this case
// in the reverse connection structures and keep the first one only in the reverse
// lookup.
m_rev_connections.insert (std::make_pair (new_inst, id));
auto &connections = m_connections [id];
auto rc_exists = m_rev_connections.find (new_inst);
if (rc_exists != m_rev_connections.end ()) {
// NOTE: possibly a different connection to the new cluster already exists (i.e.
// rc_exists->second != id).
// This may mean we are connecting two clusters here on parent level. In the netlist, this
// is reflected by having multiple upward pins. Right now, we cannot reflect this case
// in the reverse connection structures and keep the existing one only in the reverse
// lookup.
// Remove to original connections downwards
// TODO: this linear search may be slow
for (auto i = connections.begin (), ii = connections.begin (); i != connections.end (); ii = i, ++i) {
if (*i == inst) {
if (ii == i) {
connections.pop_front ();
} else {
connections.erase_after (ii);
}
break;
}
}
} else {
m_rev_connections.insert (std::make_pair (new_inst, id));
// Replace connections downwards
// TODO: this linear search may be slow
for (auto i = connections.begin (); i != connections.end (); ++i) {
if (*i == inst) {
*i = new_inst;
break;
}
}
}
}
template <class T>
@ -1627,7 +1655,7 @@ connected_clusters<T>::join_cluster_with (typename local_cluster<T>::id_type id,
connections_type &to_join = tc->second;
for (connections_type::const_iterator c = to_join.begin (); c != to_join.end (); ++c) {
m_rev_connections.insert (std::make_pair (*c, id));
m_rev_connections [*c] = id;
}
connections_type &target = m_connections [id];

View File

@ -212,7 +212,7 @@ void LayoutToNetlist::link_nets (const db::Net *net, const db::Net *with)
{
if (! net->circuit () || net->circuit () != with->circuit () || ! internal_layout ()
|| ! internal_layout ()->is_valid_cell_index (net->circuit ()->cell_index ())
|| net->cluster_id () == 0 || with->cluster_id () == 0) {
|| net->cluster_id () == 0 || with->cluster_id () == 0 || net == with) {
return;
}

View File

@ -46,6 +46,8 @@ namespace tl
* - empty
*/
template <class T> class slist;
template <class T>
struct slist_node_type
{
@ -87,6 +89,7 @@ public:
private:
friend class slist_const_iterator<T>;
friend class slist<T>;
node_type *mp_p;
};
@ -119,6 +122,7 @@ public:
bool operator!= (slist_const_iterator<T> other) const { return mp_p != other.mp_p; }
private:
friend class slist<T>;
const node_type *mp_p;
};
@ -304,6 +308,15 @@ public:
other.m_size = 0;
}
void erase_after (iterator at)
{
node_type *n = at.mp_p->next;
if (n) {
at.mp_p->next = n->next;
delete n;
}
}
private:
node_type *mp_first, *mp_last;
size_t m_size;

View File

@ -105,6 +105,16 @@ TEST(1_Basic)
EXPECT_EQ (l2s (l2), "17,42");
l2.pop_front ();
EXPECT_EQ (l2s (l2), "42");
l2.push_front (MyClass1 (11));
EXPECT_EQ (l2s (l2), "11,42");
l2.erase_after (l2.begin ());
EXPECT_EQ (l2s (l2), "11");
l2.erase_after (l2.begin ()); // ignored
EXPECT_EQ (l2s (l2), "11");
l2.pop_front ();
EXPECT_EQ (l2s (l2), "");
EXPECT_EQ (l2.empty (), true);
l2.push_front (MyClass1 (42));
l3.push_back (MyClass1 (2));
l3.push_front (MyClass1 (1));