From e439d50111f48a02d2f58fd51aa0713aa32d649d Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Fri, 4 Jan 2019 08:03:31 +0100 Subject: [PATCH] WIP: hier netlist processort: performance improvement in instance-to-instance checking, leaner output of net shapes. --- src/db/db/dbHierNetworkProcessor.cc | 59 ++++++++++++++++++++++------- src/db/db/dbLayoutToNetlist.cc | 14 ++++++- 2 files changed, 58 insertions(+), 15 deletions(-) diff --git a/src/db/db/dbHierNetworkProcessor.cc b/src/db/db/dbHierNetworkProcessor.cc index 2c08701e1..d80880951 100644 --- a/src/db/db/dbHierNetworkProcessor.cc +++ b/src/db/db/dbHierNetworkProcessor.cc @@ -330,6 +330,8 @@ template bool local_cluster::interacts (const local_cluster &other, const db::ICplxTrans &trans, const Connectivity &conn) const { + db::box_convert bc; + const_cast *> (this)->ensure_sorted (); box_type common = other.bbox ().transformed (trans) & bbox (); @@ -339,35 +341,59 @@ local_cluster::interacts (const local_cluster &other, const db::ICplxTrans box_type common_for_other = common.transformed (trans.inverted ()); - db::box_scanner2 scanner; - transformed_box bc_t (trans); - db::box_convert bc; + // shortcut evaluation for disjunct layers - bool any = false; + std::set ll1; for (typename std::map::const_iterator s = m_shapes.begin (); s != m_shapes.end (); ++s) { - for (typename tree_type::touching_iterator i = s->second.begin_touching (common, bc); ! i.at_end (); ++i) { - scanner.insert1 (i.operator-> (), s->first); - any = true; + if (! s->second.begin_touching (common, bc).at_end ()) { + ll1.insert (s->first); } } + if (ll1.empty ()) { + return false; + } + + std::set ll2; + for (typename std::map::const_iterator s = other.m_shapes.begin (); s != other.m_shapes.end (); ++s) { + if (! s->second.begin_touching (common_for_other, bc).at_end ()) { + ll2.insert (s->first); + } + } + + if (ll2.empty ()) { + return false; + } + + bool any = false; + + for (std::set::const_iterator i = ll1.begin (); i != ll1.end () && !any; ++i) { + db::Connectivity::layer_iterator je = conn.end_connected (*i); + for (db::Connectivity::layer_iterator j = conn.begin_connected (*i); j != je && !any; ++j) { + any = (ll2.find (*j) != ll2.end ()); + } + } if (! any) { return false; } - any = false; + // detailed analysis + + db::box_scanner2 scanner; + transformed_box bc_t (trans); + + for (typename std::map::const_iterator s = m_shapes.begin (); s != m_shapes.end (); ++s) { + for (typename tree_type::touching_iterator i = s->second.begin_touching (common, bc); ! i.at_end (); ++i) { + scanner.insert1 (i.operator-> (), s->first); + } + } for (typename std::map::const_iterator s = other.m_shapes.begin (); s != other.m_shapes.end (); ++s) { for (typename tree_type::touching_iterator i = s->second.begin_touching (common_for_other, bc); ! i.at_end (); ++i) { scanner.insert2 (i.operator-> (), s->first); - any = true; } } - if (! any) { - return false; - } - interaction_receiver rec (conn, trans); return ! scanner.process (rec, 1 /*==touching*/, bc, bc_t); } @@ -1037,6 +1063,8 @@ private: db::cell_index_type ci1, const std::vector &p1, const db::ICplxTrans &t1, db::cell_index_type ci2, const std::vector &p2, const db::ICplxTrans &t2) { + const db::Cell &cell2 = mp_layout->cell (ci2); + const db::local_clusters &cl1 = mp_tree->clusters_per_cell (ci1); const db::local_clusters &cl2 = mp_tree->clusters_per_cell (ci2); @@ -1046,6 +1074,11 @@ private: for (typename db::local_clusters::touching_iterator i = cl1.begin_touching (common.transformed (t1i)); ! i.at_end (); ++i) { + // skip the test, if this cluster doesn't interact with the whole cell2 + if (! i->interacts (cell2, t21, *mp_conn)) { + continue; + } + box_type bc1 = common & i->bbox ().transformed (t1); for (typename db::local_clusters::touching_iterator j = cl2.begin_touching (bc1.transformed (t2i)); ! j.at_end (); ++j) { diff --git a/src/db/db/dbLayoutToNetlist.cc b/src/db/db/dbLayoutToNetlist.cc index b8491b9ac..ab6895ef2 100644 --- a/src/db/db/dbLayoutToNetlist.cc +++ b/src/db/db/dbLayoutToNetlist.cc @@ -209,6 +209,16 @@ const db::hier_clusters &LayoutToNetlist::net_clusters () const return m_netex.clusters (); } +template +static void deliver_shape (const db::PolygonRef &pr, db::Region ®ion, const Tr &tr) +{ + if (pr.obj ().is_box ()) { + region.insert (pr.obj ().box ().transformed (pr.trans ()).transformed (tr)); + } else { + region.insert (pr.obj ().transformed (pr.trans ()).transformed (tr)); + } +} + db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region &of_layer, bool recursive) const { unsigned int lid = layer_of (of_layer); @@ -224,7 +234,7 @@ db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region const db::local_cluster &lc = m_netex.clusters ().clusters_per_cell (ci).cluster_by_id (net.cluster_id ()); for (db::local_cluster::shape_iterator s = lc.begin (lid); !s.at_end (); ++s) { - res->insert (s->obj ().transformed (s->trans ())); + deliver_shape (*s, *res, db::UnitTrans ()); } } else { @@ -235,7 +245,7 @@ db::Region *LayoutToNetlist::shapes_of_net (const db::Net &net, const db::Region db::cell_index_type ci = circuit->cell_index (); for (db::recursive_cluster_shape_iterator rci (m_netex.clusters (), lid, ci, net.cluster_id ()); !rci.at_end (); ++rci) { - res->insert (rci->obj ().transformed (rci.trans () * db::ICplxTrans (rci->trans ()))); + deliver_shape (*rci, *res, rci.trans ()); } }