diff --git a/src/buddies/src/bd/strmxor.cc b/src/buddies/src/bd/strmxor.cc index ccac991fd..a6d8487e6 100644 --- a/src/buddies/src/bd/strmxor.cc +++ b/src/buddies/src/bd/strmxor.cc @@ -754,6 +754,7 @@ bool run_deep_xor (const XORData &xor_data) { db::DeepShapeStore dss; dss.set_threads (xor_data.threads); + dss.set_wants_all_cells (true); // saves time for less cell mapping operations double dbu = std::min (xor_data.layout_a->dbu (), xor_data.layout_b->dbu ()); diff --git a/src/db/db/dbCellMapping.cc b/src/db/db/dbCellMapping.cc index 1cb4d698d..de115e629 100644 --- a/src/db/db/dbCellMapping.cc +++ b/src/db/db/dbCellMapping.cc @@ -151,10 +151,6 @@ public: } - std::set callers_b; - m_layout_b.cell (cell_b).collect_caller_cells (callers_b, selection_cone_b, -1); - callers_b.insert (cell_b); - m_repr_set = false; std::map::const_iterator r = m_repr.find (cell_b); @@ -164,7 +160,11 @@ public: return false; } } - + + std::set callers_b; + m_layout_b.cell (cell_b).collect_caller_cells (callers_b, selection_cone_b, -1); + callers_b.insert (cell_b); + trans_set_t trans (m_trans); double mag = m_layout_b.dbu () / m_layout_a.dbu (); diff --git a/src/db/db/dbDeepRegion.cc b/src/db/db/dbDeepRegion.cc index bed425c3d..1ab9d322e 100644 --- a/src/db/db/dbDeepRegion.cc +++ b/src/db/db/dbDeepRegion.cc @@ -1916,6 +1916,7 @@ DeepRegion::run_check (db::edge_relation_type rel, bool different_polygons, cons // force different polygons in the different properties case to skip intra-polygon checks if (pc_always_different (options.prop_constraint)) { + // TODO: this forces merged primaries, so maybe that is not a good optimization? different_polygons = true; } diff --git a/src/db/db/dbDeepShapeStore.cc b/src/db/db/dbDeepShapeStore.cc index bc9dc11d2..7fb293523 100644 --- a/src/db/db/dbDeepShapeStore.cc +++ b/src/db/db/dbDeepShapeStore.cc @@ -487,13 +487,13 @@ static unsigned int init_layer (db::Layout &layout, const db::RecursiveShapeIter } DeepShapeStore::DeepShapeStore () - : m_keep_layouts (true) + : m_keep_layouts (true), m_wants_all_cells (false) { ++s_instance_count; } DeepShapeStore::DeepShapeStore (const std::string &topcell_name, double dbu) - : m_keep_layouts (true) + : m_keep_layouts (true), m_wants_all_cells (false) { ++s_instance_count; @@ -765,6 +765,16 @@ double DeepShapeStore::max_area_ratio () const return m_state.max_area_ratio (); } +void DeepShapeStore::set_wants_all_cells (bool f) +{ + m_wants_all_cells = f; +} + +bool DeepShapeStore::wants_all_cells () const +{ + return m_wants_all_cells; +} + void DeepShapeStore::set_reject_odd_polygons (bool f) { m_state.set_reject_odd_polygons (f); @@ -929,6 +939,8 @@ DeepLayer DeepShapeStore::create_polygon_layer (const db::RecursiveShapeIterator db::Layout &layout = m_layouts[layout_index]->layout; db::HierarchyBuilder &builder = m_layouts[layout_index]->builder; + builder.set_wants_all_cells (m_wants_all_cells); + unsigned int layer_index = init_layer (layout, si); builder.set_target_layer (layer_index); diff --git a/src/db/db/dbDeepShapeStore.h b/src/db/db/dbDeepShapeStore.h index 1f12063b5..98c53c8fa 100644 --- a/src/db/db/dbDeepShapeStore.h +++ b/src/db/db/dbDeepShapeStore.h @@ -727,6 +727,23 @@ public: */ int threads () const; + /** + * @brief Sets a flag indicating whether the working layouts will store the whole original hierarchy + * + * Setting this flag to true will make the deep shape store copy the + * hierarchy exactly from the origin layouts. This will take somewhat + * more memory but avoid future cell hierarchy mapping operations. + * + * If set to false, only the needed parts of the hierarchy are copied. + * This part may need to grow when further operations are triggered. + */ + void set_wants_all_cells (bool f); + + /** + * @brief Gets a flag indicating whether the working layouts will store the whole original hierarchy + */ + bool wants_all_cells () const; + /** * @brief Sets a flag indicating whether to reject odd polygons * @@ -878,6 +895,7 @@ private: DeepShapeStoreState m_state; std::list m_state_stack; bool m_keep_layouts; + bool m_wants_all_cells; tl::Mutex m_lock; struct DeliveryMappingCacheKey diff --git a/src/db/db/dbHierarchyBuilder.cc b/src/db/db/dbHierarchyBuilder.cc index c8a77cbb6..d8698a83e 100644 --- a/src/db/db/dbHierarchyBuilder.cc +++ b/src/db/db/dbHierarchyBuilder.cc @@ -152,13 +152,13 @@ static std::pair > compute_clip_variant (const db::Box & } HierarchyBuilder::HierarchyBuilder (db::Layout *target, unsigned int target_layer, const db::ICplxTrans &trans, HierarchyBuilderShapeReceiver *pipe) - : mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (target_layer), m_trans (trans) + : mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (target_layer), m_wants_all_cells (false), m_trans (trans) { set_shape_receiver (pipe); } HierarchyBuilder::HierarchyBuilder (db::Layout *target, const db::ICplxTrans &trans, HierarchyBuilderShapeReceiver *pipe) - : mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (0), m_trans (trans) + : mp_target (target), m_initial_pass (true), m_cm_new_entry (false), m_target_layer (0), m_wants_all_cells (false), m_trans (trans) { set_shape_receiver (pipe); } diff --git a/src/db/db/dbHierarchyBuilder.h b/src/db/db/dbHierarchyBuilder.h index 4cd47efce..b3f2104ef 100644 --- a/src/db/db/dbHierarchyBuilder.h +++ b/src/db/db/dbHierarchyBuilder.h @@ -295,6 +295,7 @@ public: */ void set_shape_receiver (HierarchyBuilderShapeReceiver *pipe); + virtual bool wants_all_cells () const { return m_wants_all_cells; } virtual void begin (const RecursiveShapeIterator *iter); virtual void end (const RecursiveShapeIterator *iter); virtual void enter_cell (const RecursiveShapeIterator *iter, const db::Cell *cell, const db::Box ®ion, const box_tree_type *complex_region); @@ -311,6 +312,14 @@ public: m_target_layer = target_layer; } + /** + * @brief Sets the target layer - shapes will be put there + */ + void set_wants_all_cells (bool f) + { + m_wants_all_cells = f; + } + /** * @brief Reset the builder - performs a new initial pass */ @@ -416,6 +425,7 @@ private: cell_map_type::const_iterator m_cm_entry; bool m_cm_new_entry; unsigned int m_target_layer; + bool m_wants_all_cells; std::vector > > m_cell_stack; db::Cell *mp_initial_cell; diff --git a/src/db/db/dbRecursiveShapeIterator.cc b/src/db/db/dbRecursiveShapeIterator.cc index af551b6e2..979ab6d78 100644 --- a/src/db/db/dbRecursiveShapeIterator.cc +++ b/src/db/db/dbRecursiveShapeIterator.cc @@ -693,7 +693,11 @@ RecursiveShapeIterator::next_shape (RecursiveShapeReceiver *receiver) const // determine whether the cell is empty with respect to the layers specified bool is_empty = false; - if (! m_has_layers) { + if (receiver && receiver->wants_all_cells ()) { + + // don't skip empty cells in that case + + } else if (! m_has_layers) { is_empty = mp_layout->cell (m_inst->cell_index ()).bbox (m_layer).empty (); diff --git a/src/db/db/dbRecursiveShapeIterator.h b/src/db/db/dbRecursiveShapeIterator.h index 99ffeb1fc..281a7ce82 100644 --- a/src/db/db/dbRecursiveShapeIterator.h +++ b/src/db/db/dbRecursiveShapeIterator.h @@ -913,6 +913,11 @@ public: */ virtual ~RecursiveShapeReceiver () { } + /** + * @brief Returns true, if the receivers wants the full hierarchy and not just non-empty cells + */ + virtual bool wants_all_cells () const { return false; } + /** * @brief Called once when the iterator begins pushing */ diff --git a/src/db/db/gsiDeclDbDeepShapeStore.cc b/src/db/db/gsiDeclDbDeepShapeStore.cc index ad395cda3..ca4197def 100644 --- a/src/db/db/gsiDeclDbDeepShapeStore.cc +++ b/src/db/db/gsiDeclDbDeepShapeStore.cc @@ -111,6 +111,21 @@ Class decl_dbDeepShapeStore ("db", "DeepShapeStore", gsi::method ("threads", &db::DeepShapeStore::threads, "@brief Gets the number of threads.\n" ) + + gsi::method ("wants_all_cells=", &db::DeepShapeStore::set_wants_all_cells, gsi::arg ("flag"), + "@brief Sets a flag wether to copy the full hierarchy for the working layouts\n" + "\n" + "The DeepShapeStore object keeps a copy of the original hierarchy internally for the working layouts.\n" + "By default, this hierarchy is mapping only non-empty cells. While the operations proceed, more cells " + "may need to be added. This conservative approach saves some memory, but the update operations may " + "reduce overall performance. Setting this flag to 'true' switches to a mode where the full " + "hierarchy is copied always. This will take more memory but may save CPU time.\n" + "\n" + "This attribute has been introduced in version 0.28.10." + ) + + gsi::method ("wants_all_cells", &db::DeepShapeStore::wants_all_cells, + "@brief Gets a flag wether to copy the full hierarchy for the working layouts\n" + "This attribute has been introduced in version 0.28.10." + ) + gsi::method ("reject_odd_polygons=", &db::DeepShapeStore::set_reject_odd_polygons, gsi::arg ("count"), "@brief Sets a flag indicating whether to reject odd polygons\n" "\n" diff --git a/src/drc/drc/built-in-macros/_drc_layer.rb b/src/drc/drc/built-in-macros/_drc_layer.rb index 30ea3a692..75bb29735 100644 --- a/src/drc/drc/built-in-macros/_drc_layer.rb +++ b/src/drc/drc/built-in-macros/_drc_layer.rb @@ -2630,7 +2630,7 @@ CODE # @brief Returns the intersection points of intersecting edge segments for two edge collections # @synopsis layer.intersections(edges) # This operation is similar to the "&" operator, but it does also report intersection points - # between non-colinear, but intersection edges. Such points are reported as point-like, + # between non-colinear, but intersecting edges. Such points are reported as point-like, # degenerated edge objects. # # This method is available for edge layers. The argument must be an edge layer. diff --git a/src/lay/lay/gsiDeclLayMainWindow.cc b/src/lay/lay/gsiDeclLayMainWindow.cc index cbe106285..e6faed12b 100644 --- a/src/lay/lay/gsiDeclLayMainWindow.cc +++ b/src/lay/lay/gsiDeclLayMainWindow.cc @@ -472,15 +472,15 @@ Class decl_MainWindow (QT_EXTERNAL_BASE (QMainWindow) "lay", "M "\n" "This method has been added in version 0.24." ) + - gsi::method ("message", &lay::MainWindow::message, gsi::arg ("message"), gsi::arg ("time"), + gsi::method ("message", &lay::MainWindow::message, gsi::arg ("message"), gsi::arg ("time", -1, "infinite"), "@brief Displays a message in the status bar\n" "\n" "@param message The message to display\n" - "@param time The time how long to display the message in ms\n" + "@param time The time how long to display the message in ms. A negative value means 'infinitely'.\n" "\n" "This given message is shown in the status bar for the given time.\n" "\n" - "This method has been added in version 0.18." + "This method has been added in version 0.18. The 'time' parameter was made optional in version 0.28.10." ) + gsi::method ("resize", (void (lay::MainWindow::*)(int, int)) &lay::MainWindow::resize, gsi::arg ("width"), gsi::arg ("height"), "@brief Resizes the window\n"