diff --git a/src/buddies/src/bd/strmxor.cc b/src/buddies/src/bd/strmxor.cc index ba165cd4b..876373056 100644 --- a/src/buddies/src/bd/strmxor.cc +++ b/src/buddies/src/bd/strmxor.cc @@ -554,6 +554,7 @@ bool run_deep_xor (const XORData &xor_data) { db::DeepShapeStore dss; dss.set_threads (xor_data.threads); + dss.set_keep_layouts (true); // avoids excessive cell mapping double dbu = std::min (xor_data.layout_a->dbu (), xor_data.layout_b->dbu ()); diff --git a/src/db/db/dbDeepShapeStore.cc b/src/db/db/dbDeepShapeStore.cc index 74e8f6e8b..e62c2cfd9 100644 --- a/src/db/db/dbDeepShapeStore.cc +++ b/src/db/db/dbDeepShapeStore.cc @@ -154,17 +154,25 @@ DeepLayer::add_from (const DeepLayer &dl) db::cell_index_type source_cell = dl.initial_cell ().cell_index (); const db::Layout *source_layout = &dl.layout (); - db::CellMapping cm; - cm.create_from_geometry_full (*into_layout, into_cell, *source_layout, source_cell); + // create or reuse a layout mapping - // Actually copy the shapes + const db::CellMapping *cell_mapping = 0; + db::CellMapping cm; + if (store () == dl.store ()) { + cell_mapping = &const_cast (mp_store.get ())->internal_cell_mapping (layout_index (), dl.layout_index ()); + } else { + cm.create_from_geometry_full (*into_layout, into_cell, *source_layout, source_cell); + cell_mapping = &cm; + } + + // actually copy the shapes std::map lm; lm.insert (std::make_pair (dl.layer (), layer ())); std::vector source_cells; source_cells.push_back (source_cell); - db::copy_shapes (*into_layout, *source_layout, db::ICplxTrans (), source_cells, cm.table (), lm); + db::copy_shapes (*into_layout, *source_layout, db::ICplxTrans (), source_cells, cell_mapping->table (), lm); } } @@ -418,11 +426,13 @@ static unsigned int init_layer (db::Layout &layout, const db::RecursiveShapeIter } DeepShapeStore::DeepShapeStore () + : m_keep_layouts (false) { ++s_instance_count; } DeepShapeStore::DeepShapeStore (const std::string &topcell_name, double dbu) + : m_keep_layouts (false) { ++s_instance_count; @@ -711,6 +721,16 @@ db::Layout &DeepShapeStore::layout (unsigned int n) return m_layouts [n]->layout; } +unsigned int DeepShapeStore::layout_index (const db::Layout *layout) const +{ + for (std::vector::const_iterator i = m_layouts.begin (); i != m_layouts.end (); ++i) { + if (&(*i)->layout == layout) { + return (unsigned int) (i - m_layouts.begin ()); + } + } + tl_assert (false); +} + size_t DeepShapeStore::instance_count () { return s_instance_count; @@ -743,7 +763,7 @@ void DeepShapeStore::remove_ref (unsigned int layout, unsigned int layer) } - if ((m_layouts[layout]->refs -= 1) <= 0) { + if ((m_layouts[layout]->refs -= 1) <= 0 && ! m_keep_layouts) { delete m_layouts[layout]; m_layouts[layout] = 0; clear_breakout_cells (layout); @@ -919,6 +939,7 @@ void DeepShapeStore::invalidate_hier () { m_delivery_mapping_cache.clear (); + m_internal_mapping_cache.clear (); } void @@ -934,6 +955,26 @@ DeepShapeStore::issue_variants (unsigned int layout_index, const std::map, db::CellMapping>::iterator cm = m_internal_mapping_cache.find (std::make_pair (from_layout_index, into_layout_index)); + if (cm == m_internal_mapping_cache.end ()) { + + cm = m_internal_mapping_cache.insert (std::make_pair (std::make_pair (from_layout_index, into_layout_index), db::CellMapping ())).first; + + db::Layout &into_layout = layout (into_layout_index); + db::cell_index_type into_cell = initial_cell (into_layout_index).cell_index (); + const db::Layout &source_layout = layout (from_layout_index); + db::cell_index_type source_cell = initial_cell (from_layout_index).cell_index (); + + cm->second.create_from_geometry_full (into_layout, into_cell, source_layout, source_cell); + + } + + return cm->second; +} + const db::CellMapping & DeepShapeStore::cell_mapping_to_original (unsigned int layout_index, db::Layout *into_layout, db::cell_index_type into_cell, const std::set *excluded_cells, const std::set *included_cells) { diff --git a/src/db/db/dbDeepShapeStore.h b/src/db/db/dbDeepShapeStore.h index 9532ffd2b..990ecfb2e 100644 --- a/src/db/db/dbDeepShapeStore.h +++ b/src/db/db/dbDeepShapeStore.h @@ -339,6 +339,25 @@ public: */ bool is_singular () const; + /** + * @brief Sets a value indicating whether to keep layouts + * + * If this value is set to true, layouts are not released when their reference count + * goes down to zero. + */ + void set_keep_layouts (bool f) + { + m_keep_layouts = f; + } + + /** + * @brief Gets a value indicating whether to keep layouts + */ + bool keep_layouts () const + { + return m_keep_layouts; + } + /** * @brief Creates a new layer from a flat region (or the region is made flat) * @@ -479,6 +498,11 @@ public: */ const db::CellMapping &cell_mapping_to_original (unsigned int layout_index, db::Layout *into_layout, db::cell_index_type into_cell, const std::set *excluded_cells = 0, const std::set *included_cells = 0); + /** + * @brief Gets the cell mapping from one internal layout to another + */ + const db::CellMapping &internal_cell_mapping (unsigned int from_layout_index, unsigned int into_layout_index); + /** * @brief Create cell variants from the given variant collector * @@ -544,6 +568,11 @@ public: */ db::Cell &initial_cell (unsigned int n); + /** + * @brief Gets the layout index for a given internal layout + */ + unsigned int layout_index (const db::Layout *layout) const; + /** * @brief Gets the singular layout (const version) * @@ -752,6 +781,7 @@ private: layout_map_type m_layout_map; DeepShapeStoreState m_state; std::list m_state_stack; + bool m_keep_layouts; tl::Mutex m_lock; struct DeliveryMappingCacheKey @@ -781,6 +811,7 @@ private: }; std::map m_delivery_mapping_cache; + std::map, db::CellMapping> m_internal_mapping_cache; }; template