diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index 256e87ad7..07166fa44 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -1581,6 +1581,10 @@ template void connected_clusters::rename_connection (const ClusterInstance &inst, typename local_cluster::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::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 @@ -1627,7 +1655,7 @@ connected_clusters::join_cluster_with (typename local_cluster::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]; diff --git a/src/db/db/dbLayoutToNetlist.cc b/src/db/db/dbLayoutToNetlist.cc index 9ca1c1f9f..db8e9d146 100644 --- a/src/db/db/dbLayoutToNetlist.cc +++ b/src/db/db/dbLayoutToNetlist.cc @@ -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; } diff --git a/src/tl/tl/tlSList.h b/src/tl/tl/tlSList.h index a5412e40a..b387f9e57 100644 --- a/src/tl/tl/tlSList.h +++ b/src/tl/tl/tlSList.h @@ -46,6 +46,8 @@ namespace tl * - empty */ +template class slist; + template struct slist_node_type { @@ -87,6 +89,7 @@ public: private: friend class slist_const_iterator; + friend class slist; node_type *mp_p; }; @@ -119,6 +122,7 @@ public: bool operator!= (slist_const_iterator other) const { return mp_p != other.mp_p; } private: + friend class slist; 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; diff --git a/src/tl/unit_tests/tlSListTests.cc b/src/tl/unit_tests/tlSListTests.cc index 78b94df80..636f70028 100644 --- a/src/tl/unit_tests/tlSListTests.cc +++ b/src/tl/unit_tests/tlSListTests.cc @@ -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));