WIP: hier netlist processort: performance improvement in instance-to-instance checking, leaner output of net shapes.

This commit is contained in:
Matthias Koefferlein 2019-01-04 08:03:31 +01:00
parent 72f838f8ee
commit e439d50111
2 changed files with 58 additions and 15 deletions

View File

@ -330,6 +330,8 @@ template <class T>
bool
local_cluster<T>::interacts (const local_cluster<T> &other, const db::ICplxTrans &trans, const Connectivity &conn) const
{
db::box_convert<T> bc;
const_cast<local_cluster<T> *> (this)->ensure_sorted ();
box_type common = other.bbox ().transformed (trans) & bbox ();
@ -339,35 +341,59 @@ local_cluster<T>::interacts (const local_cluster<T> &other, const db::ICplxTrans
box_type common_for_other = common.transformed (trans.inverted ());
db::box_scanner2<T, unsigned int, T, unsigned int> scanner;
transformed_box <T, db::ICplxTrans> bc_t (trans);
db::box_convert<T> bc;
// shortcut evaluation for disjunct layers
bool any = false;
std::set<unsigned int> ll1;
for (typename std::map<unsigned int, tree_type>::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<unsigned int> ll2;
for (typename std::map<unsigned int, tree_type>::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<unsigned int>::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<T, unsigned int, T, unsigned int> scanner;
transformed_box <T, db::ICplxTrans> bc_t (trans);
for (typename std::map<unsigned int, tree_type>::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<unsigned int, tree_type>::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<T> 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<db::InstElement> &p1, const db::ICplxTrans &t1,
db::cell_index_type ci2, const std::vector<db::InstElement> &p2, const db::ICplxTrans &t2)
{
const db::Cell &cell2 = mp_layout->cell (ci2);
const db::local_clusters<T> &cl1 = mp_tree->clusters_per_cell (ci1);
const db::local_clusters<T> &cl2 = mp_tree->clusters_per_cell (ci2);
@ -1046,6 +1074,11 @@ private:
for (typename db::local_clusters<T>::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<T>::touching_iterator j = cl2.begin_touching (bc1.transformed (t2i)); ! j.at_end (); ++j) {

View File

@ -209,6 +209,16 @@ const db::hier_clusters<db::PolygonRef> &LayoutToNetlist::net_clusters () const
return m_netex.clusters ();
}
template <class Tr>
static void deliver_shape (const db::PolygonRef &pr, db::Region &region, 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<db::PolygonRef> &lc = m_netex.clusters ().clusters_per_cell (ci).cluster_by_id (net.cluster_id ());
for (db::local_cluster<db::PolygonRef>::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<db::PolygonRef> 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 ());
}
}