From 5988c92f052a9aee6dac958f8e5c914f5ecb1ca4 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Fri, 13 Nov 2020 01:19:18 +0100 Subject: [PATCH] Trying to save some (potentially expensive) layout updates on 'overwrite' cell name conflict resolution. --- src/db/db/dbCell.cc | 6 +++--- src/db/db/dbCommonReader.cc | 31 ++++++++++++++++++++++++------- src/db/db/dbCommonReader.h | 5 +++++ 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/db/db/dbCell.cc b/src/db/db/dbCell.cc index 0b1522e82..4a1adf813 100644 --- a/src/db/db/dbCell.cc +++ b/src/db/db/dbCell.cc @@ -506,7 +506,7 @@ Cell::collect_caller_cells (std::set &callers, const std::setis_valid_cell_index (*cc)) { callers.insert (*cc); mp_layout->cell (*cc).collect_caller_cells (callers, levels < 0 ? levels : levels - 1); } @@ -519,7 +519,7 @@ Cell::collect_caller_cells (std::set &callers, int levels) cons { if (levels != 0) { for (parent_cell_iterator cc = begin_parent_cells (); cc != end_parent_cells (); ++cc) { - if (callers.find (*cc) == callers.end ()) { + if (callers.find (*cc) == callers.end () && mp_layout->is_valid_cell_index (*cc)) { callers.insert (*cc); mp_layout->cell (*cc).collect_caller_cells (callers, levels < 0 ? levels : levels - 1); } @@ -538,7 +538,7 @@ Cell::collect_called_cells (std::set &called, int levels) const { if (levels != 0) { for (child_cell_iterator cc = begin_child_cells (); ! cc.at_end (); ++cc) { - if (called.find (*cc) == called.end ()) { + if (called.find (*cc) == called.end () && mp_layout->is_valid_cell_index (*cc)) { called.insert (*cc); mp_layout->cell (*cc).collect_called_cells (called, levels < 0 ? levels : levels - 1); } diff --git a/src/db/db/dbCommonReader.cc b/src/db/db/dbCommonReader.cc index 741cf1f0d..2d4afc86d 100644 --- a/src/db/db/dbCommonReader.cc +++ b/src/db/db/dbCommonReader.cc @@ -237,9 +237,21 @@ CommonReader::merge_cell (db::Layout &layout, db::cell_index_type target_cell_in // copy over the instances for (db::Cell::const_iterator i = src_cell.begin (); ! i.at_end (); ++i) { - target_cell.insert (*i); + // NOTE: cell indexed may be invalid because we delete subcells without update() + if (layout.is_valid_cell_index (i->cell_index ())) { + target_cell.insert (*i); + } } + merge_cell_without_instances (layout, target_cell_index, src_cell_index); +} + +void +CommonReader::merge_cell_without_instances (db::Layout &layout, db::cell_index_type target_cell_index, db::cell_index_type src_cell_index) const +{ + const db::Cell &src_cell = layout.cell (src_cell_index); + db::Cell &target_cell = layout.cell (target_cell_index); + // copy over the shapes for (unsigned int l = 0; l < layout.layers (); ++l) { if (layout.is_valid_layer (l) && ! src_cell.shapes (l).empty ()) { @@ -338,11 +350,17 @@ CommonReader::finish (db::Layout &layout) // we have a cell conflict - layout.force_update (); - if (m_cc_resolution == OverwriteCell && ! layout.cell (ci_new).is_ghost_cell ()) { - layout.prune_subcells (ci_org); + if (! layout.cell (ci_org).begin ().at_end ()) { + + // NOTE: because prune_subcells needs the parents for sub cells and we are going do delete + // the current cell, we cannot save the "update()" just by traversing bottom-up. + layout.force_update (); + layout.prune_subcells (ci_org); + + } + layout.cell (ci_org).clear_shapes (); merge_cell (layout, ci_org, ci_new); @@ -352,9 +370,8 @@ CommonReader::finish (db::Layout &layout) layout.prune_subcells (ci_new); layout.cell (ci_new).clear_shapes (); - // we need the instances of the cell we just cleaned - layout.force_update (); - merge_cell (layout, ci_org, ci_new); + // NOTE: ignore instances -> this saves us a layout update + merge_cell_without_instances (layout, ci_org, ci_new); } else { diff --git a/src/db/db/dbCommonReader.h b/src/db/db/dbCommonReader.h index 2bcecfaa7..f0ed56bcf 100644 --- a/src/db/db/dbCommonReader.h +++ b/src/db/db/dbCommonReader.h @@ -141,6 +141,11 @@ protected: */ void merge_cell (db::Layout &layout, db::cell_index_type target_cell_index, db::cell_index_type src_cell_index) const; + /** + * @brief Merge (and delete) the src_cell into target_cell without instances + */ + void merge_cell_without_instances (db::Layout &layout, db::cell_index_type target_cell_index, db::cell_index_type src_cell_index) const; + private: std::map > m_id_map; std::map > m_name_map;