From 11bddc2914f8bfca7913f2b2e1b3a4cdea22ce8f Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Fri, 31 May 2024 14:44:56 +0200 Subject: [PATCH] Refining solution for "blend-mode 0" enhancement --- src/db/db/dbCommonReader.cc | 48 ++++++++++++++++++++++---------- src/db/db/dbCommonReader.h | 2 +- src/db/db/dbInstances.cc | 5 ++++ testdata/gds/collect_add_au.gds | Bin 13292 -> 13266 bytes 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/db/db/dbCommonReader.cc b/src/db/db/dbCommonReader.cc index fb4f5dfe7..108a62851 100644 --- a/src/db/db/dbCommonReader.cc +++ b/src/db/db/dbCommonReader.cc @@ -164,7 +164,7 @@ CommonReaderBase::rename_cell (db::Layout &layout, size_t id, const std::string // Both cells already exist and are not identical: merge ID-declared cell into the name-declared one layout.force_update (); - merge_cell (layout, iname->second.second, iid->second.second, true); + merge_cell (layout, iname->second.second, iid->second.second, true, false); iid->second.second = iname->second.second; } @@ -239,24 +239,44 @@ CommonReaderBase::cell_for_instance (db::Layout &layout, const std::string &cn) } void -CommonReaderBase::merge_cell (db::Layout &layout, db::cell_index_type target_cell_index, db::cell_index_type src_cell_index, bool with_meta) const +CommonReaderBase::merge_cell (db::Layout &layout, db::cell_index_type target_cell_index, db::cell_index_type src_cell_index, bool with_meta, bool no_duplicate_instances) const { const db::Cell &src_cell = layout.cell (src_cell_index); db::Cell &target_cell = layout.cell (target_cell_index); target_cell.set_ghost_cell (src_cell.is_ghost_cell () && target_cell.is_ghost_cell ()); - // avoid generating duplicates - std::set current; - for (db::Cell::const_iterator i = target_cell.begin (); ! i.at_end (); ++i) { - current.insert (*i); - } + if (no_duplicate_instances) { - // copy over the instances - for (db::Cell::const_iterator i = src_cell.begin (); ! i.at_end (); ++i) { - // NOTE: cell indexed may be invalid because we delete subcells without update() - if (layout.is_valid_cell_index (i->cell_index ()) && current.find (*i) == current.end ()) { - target_cell.insert (*i); + // avoid generating duplicates + std::set current; + for (db::Cell::const_iterator i = target_cell.begin (); ! i.at_end (); ++i) { + current.insert (*i); } + + // copy over the instances + // NOTE: need to do that in a two-step fashion as inserting instances may invalidate + // the existing ones. + std::vector selected; + for (db::Cell::const_iterator i = src_cell.begin (); ! i.at_end (); ++i) { + // NOTE: cell indexed may be invalid because we delete subcells without update() + selected.push_back (layout.is_valid_cell_index (i->cell_index ()) && current.find (*i) == current.end ()); + } + auto s = selected.begin (); + for (db::Cell::const_iterator i = src_cell.begin (); ! i.at_end (); ++i, ++s) { + if (*s) { + target_cell.insert (*i); + } + } + + } else { + + for (db::Cell::const_iterator i = src_cell.begin (); ! i.at_end (); ++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, with_meta); @@ -391,7 +411,7 @@ CommonReaderBase::finish (db::Layout &layout) layout.cell (ci_org).clear_shapes (); - merge_cell (layout, ci_org, ci_new, true); + merge_cell (layout, ci_org, ci_new, true, false); } else if (m_cc_resolution == SkipNewCell && ! layout.cell (ci_org).is_ghost_cell ()) { @@ -403,7 +423,7 @@ CommonReaderBase::finish (db::Layout &layout) } else { - merge_cell (layout, ci_org, ci_new, m_cc_resolution != SkipNewCell); + merge_cell (layout, ci_org, ci_new, m_cc_resolution != SkipNewCell, m_cc_resolution == AddToCell); } diff --git a/src/db/db/dbCommonReader.h b/src/db/db/dbCommonReader.h index 90e98d339..d8749c368 100644 --- a/src/db/db/dbCommonReader.h +++ b/src/db/db/dbCommonReader.h @@ -242,7 +242,7 @@ protected: /** * @brief Merge (and delete) the src_cell into target_cell */ - void merge_cell (db::Layout &layout, db::cell_index_type target_cell_index, db::cell_index_type src_cell_index, bool with_meta) const; + void merge_cell (db::Layout &layout, db::cell_index_type target_cell_index, db::cell_index_type src_cell_index, bool with_meta, bool no_duplicate_instances) const; /** * @brief Merge (and delete) the src_cell into target_cell without instances diff --git a/src/db/db/dbInstances.cc b/src/db/db/dbInstances.cc index 4f1a8ca54..3ad24f8c1 100644 --- a/src/db/db/dbInstances.cc +++ b/src/db/db/dbInstances.cc @@ -539,6 +539,11 @@ template class instance_iterator; // ------------------------------------------------------------------------------------- // NormalInstanceIteratorTraits implementation +// TOOD: this class could use standard iterators instead of flat +// box tree ones. This potentially saves a sorting step when +// no box trees are needed and order will remain more stable in +// that case. + NormalInstanceIteratorTraits::NormalInstanceIteratorTraits () : mp_insts (0) { } diff --git a/testdata/gds/collect_add_au.gds b/testdata/gds/collect_add_au.gds index b021521a81c58832235cef4463c2658404635fe8..c18d23dff49bf27781dfd8840a97f179c1821a70 100644 GIT binary patch delta 909 zcmaEpekomvfsKKQDS|*ZfQ4xFn8nbab4&K|mH~KuT#X#Oj=LTJy1rH)ub{Dqf|t z6RWtJ?p>_nW_sAoG0;DWRXvY^F;?*)1MDeln*nxzWf@{m(L6>|v6;Vli;)E*01}Ls A&j0`b delta 902 zcmcbV{w7_CfsKKQDS|uR?P`I zJF$xE=-$ODE~EDxtGJl{Nvz_Z^s)M7vV{TmBsIqXyC(w-u_xtEhEuWGyLpz81tS1W CD2=uN