Trying to save some (potentially expensive) layout updates on 'overwrite' cell name conflict resolution.

This commit is contained in:
Matthias Koefferlein 2020-11-13 01:19:18 +01:00
parent 4f0b9118c3
commit 5988c92f05
3 changed files with 32 additions and 10 deletions

View File

@ -506,7 +506,7 @@ Cell::collect_caller_cells (std::set<cell_index_type> &callers, const std::set<c
{
if (levels != 0) {
for (parent_cell_iterator cc = begin_parent_cells (); cc != end_parent_cells (); ++cc) {
if (cone.find (*cc) != cone.end () && callers.find (*cc) == callers.end ()) {
if (cone.find (*cc) != cone.end () && 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);
}
@ -519,7 +519,7 @@ Cell::collect_caller_cells (std::set<cell_index_type> &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<cell_index_type> &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);
}

View File

@ -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 {

View File

@ -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<size_t, std::pair<std::string, db::cell_index_type> > m_id_map;
std::map<std::string, std::pair<size_t, db::cell_index_type> > m_name_map;