diff --git a/src/db/db/dbRecursiveInstanceIterator.cc b/src/db/db/dbRecursiveInstanceIterator.cc index bb15bf9f4..a52274c5c 100644 --- a/src/db/db/dbRecursiveInstanceIterator.cc +++ b/src/db/db/dbRecursiveInstanceIterator.cc @@ -40,6 +40,9 @@ RecursiveInstanceIterator &RecursiveInstanceIterator::operator= (const Recursive { if (&d != this) { + m_all_targets = d.m_all_targets; + m_targets = d.m_targets; + m_max_depth = d.m_max_depth; m_min_depth = d.m_min_depth; m_shape_flags = d.m_shape_flags; @@ -91,6 +94,7 @@ RecursiveInstanceIterator::RecursiveInstanceIterator () m_shape_inv_prop_sel = false; m_needs_reinit = false; m_inst_quad_id = 0; + m_all_targets = true; } RecursiveInstanceIterator::RecursiveInstanceIterator (const layout_type &layout, const cell_type &cell, const box_type ®ion, bool overlapping) @@ -138,6 +142,7 @@ RecursiveInstanceIterator::init () m_shape_inv_prop_sel = false; m_inst_quad_id = 0; mp_cell = 0; + m_all_targets = true; } void @@ -212,6 +217,26 @@ RecursiveInstanceIterator::confine_region (const region_type ®ion) m_needs_reinit = true; } +void +RecursiveInstanceIterator::all_targets () +{ + if (! m_all_targets) { + m_all_targets = true; + m_targets.clear (); + m_needs_reinit = true; + } +} + +void +RecursiveInstanceIterator::targets (const std::set &tgt) +{ + if (m_all_targets || m_targets != tgt) { + m_targets = tgt; + m_all_targets = false; + m_needs_reinit = true; + } +} + namespace { struct BoxTreePusher @@ -280,8 +305,15 @@ RecursiveInstanceIterator::validate (RecursiveInstanceReceiver *receiver) const } if (mp_top_cell) { + + if (! m_all_targets) { + m_target_tree.clear (); + mp_top_cell->collect_called_cells (m_target_tree); + } + new_cell (receiver); next_instance (receiver); + } } @@ -412,6 +444,12 @@ RecursiveInstanceIterator::next (RecursiveInstanceReceiver *receiver) } } +bool +RecursiveInstanceIterator::needs_visit () const +{ + return int (m_inst_iterators.size ()) >= m_min_depth && ! is_inactive () && (m_all_targets || m_targets.find (m_inst->cell_index ()) != m_targets.end ()); +} + void RecursiveInstanceIterator::next_instance (RecursiveInstanceReceiver *receiver) const { @@ -419,7 +457,7 @@ RecursiveInstanceIterator::next_instance (RecursiveInstanceReceiver *receiver) c if (! m_inst.at_end ()) { - if (int (m_inst_iterators.size ()) < m_max_depth) { + if (int (m_inst_iterators.size ()) < m_max_depth && (m_all_targets || m_target_tree.find (m_inst->cell_index ()) != m_target_tree.end ())) { down (receiver); } @@ -432,14 +470,10 @@ RecursiveInstanceIterator::next_instance (RecursiveInstanceReceiver *receiver) c break; } - if (! m_inst.at_end () && int (m_inst_iterators.size ()) >= m_min_depth && ! is_inactive ()) { - break; - } - } if (! m_inst.at_end ()) { - if (int (m_inst_iterators.size ()) < m_min_depth || is_inactive ()) { + if (! needs_visit ()) { ++m_inst; new_inst (receiver); } else { @@ -549,13 +583,6 @@ RecursiveInstanceIterator::new_cell (RecursiveInstanceReceiver *receiver) const set_inactive (new_cell_inactive); } -// @@@ drop? - // skip instance quad if possible - if (! m_local_complex_region_stack.empty ()) { - skip_inst_iter_for_complex_region (); - } -// @@@ - m_inst = cell ()->begin_touching (correct_box_overlapping (m_local_region_stack.back ())); m_inst_quad_id = 0; diff --git a/src/db/db/dbRecursiveInstanceIterator.h b/src/db/db/dbRecursiveInstanceIterator.h index 9d94d84d1..1a018e3c0 100644 --- a/src/db/db/dbRecursiveInstanceIterator.h +++ b/src/db/db/dbRecursiveInstanceIterator.h @@ -274,6 +274,36 @@ public: m_needs_reinit = true; } + /** + * @brief Gets the selected target cells + * + * Only cells from the targets section are reported if "select_all_targets" is false. + */ + const std::set &targets () const + { + return m_targets; + } + + /** + * @brief Gets a flags indicating whether all targets are selected + */ + bool all_targets () const + { + return m_all_targets; + } + + /** + * @brief Selects all target cells + */ + void all_targets (); + + /** + * @brief Selects the given targets + * + * This will reset the "all_targets" flag to false. + */ + void targets (const std::set &targets); + /** * @brief Select cells * @@ -493,6 +523,8 @@ private: bool m_shape_inv_prop_sel; bool m_overlapping; std::set m_start, m_stop; + std::set m_targets; + bool m_all_targets; const layout_type *mp_layout; const cell_type *mp_top_cell; @@ -515,6 +547,7 @@ private: mutable bool m_needs_reinit; mutable size_t m_inst_quad_id; mutable std::vector m_inst_quad_id_stack; + mutable std::set m_target_tree; void init (); void init_region (const region_type ®ion); @@ -522,6 +555,7 @@ private: void skip_inst_iter_for_complex_region () const; void validate (RecursiveInstanceReceiver *receiver) const; void next (RecursiveInstanceReceiver *receiver); + bool needs_visit () const; void next_instance (RecursiveInstanceReceiver *receiver) const; void new_inst (RecursiveInstanceReceiver *receiver) const; void new_inst_member (RecursiveInstanceReceiver *receiver) const;