From 5eb52e8a8fd3b597fd991812c3c90e2698dbe71f Mon Sep 17 00:00:00 2001 From: Peter Gadfort Date: Mon, 23 Sep 2024 16:24:41 -0400 Subject: [PATCH] tap: avoid iterating over insts multiple times when placing tapcells Signed-off-by: Peter Gadfort --- src/tap/include/tap/tapcell.h | 17 ++++++++++++++++- src/tap/src/tapcell.cpp | 32 +++++++++++++++++++------------- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/tap/include/tap/tapcell.h b/src/tap/include/tap/tapcell.h index 05d721675fe..a7ea8adfa7c 100644 --- a/src/tap/include/tap/tapcell.h +++ b/src/tap/include/tap/tapcell.h @@ -36,6 +36,7 @@ #include #include "odb/db.h" +#include "odb/geom_boost.h" namespace ord { class OpenRoad; @@ -163,6 +164,19 @@ class Tapcell using Polygon90 = boost::polygon::polygon_90_with_holes_data; using CornerMap = std::map>; + struct InstIndexableGetter + { + using result_type = odb::Rect; + odb::Rect operator()(odb::dbInst* inst) const + { + return inst->getBBox()->getBox(); + } + }; + using InstTree + = boost::geometry::index::rtree, + InstIndexableGetter>; + std::vector findBlockages(); bool checkSymmetry(odb::dbMaster* master, const odb::dbOrientType& ori); odb::dbInst* makeInstance(odb::dbBlock* block, @@ -190,7 +204,8 @@ class Tapcell int dist, odb::dbRow* row, bool is_edge, - bool disallow_one_site_gaps); + bool disallow_one_site_gaps, + const InstTree& fixed_instances); int defaultDistance() const; diff --git a/src/tap/src/tapcell.cpp b/src/tap/src/tapcell.cpp index 627436e0f2e..3335e286589 100644 --- a/src/tap/src/tapcell.cpp +++ b/src/tap/src/tapcell.cpp @@ -160,11 +160,23 @@ int Tapcell::placeTapcells(odb::dbMaster* tapcell_master, edge_rows.insert(rows.begin(), rows.end()); } + std::vector fixed_insts; + for (auto* inst : db_->getChip()->getBlock()->getInsts()) { + if (inst->isFixed()) { + fixed_insts.push_back(inst); + } + } + InstTree instancetree(fixed_insts.begin(), fixed_insts.end()); + int inst = 0; for (auto* row : db_->getChip()->getBlock()->getRows()) { const bool is_edge = edge_rows.find(row) != edge_rows.end(); - inst += placeTapcells( - tapcell_master, dist, row, is_edge, disallow_one_site_gaps); + inst += placeTapcells(tapcell_master, + dist, + row, + is_edge, + disallow_one_site_gaps, + instancetree); } logger_->info(utl::TAP, 5, "Inserted {} tapcells.", inst); return inst; @@ -174,7 +186,8 @@ int Tapcell::placeTapcells(odb::dbMaster* tapcell_master, const int dist, odb::dbRow* row, const bool is_edge, - const bool disallow_one_site_gaps) + const bool disallow_one_site_gaps, + const InstTree& fixed_instances) { if (row->getSite()->getName() != tapcell_master->getSite()->getName()) { return 0; @@ -202,16 +215,9 @@ int Tapcell::placeTapcells(odb::dbMaster* tapcell_master, const odb::Rect row_bb = row->getBBox(); - std::set row_insts; - for (auto* inst : db_->getChip()->getBlock()->getInsts()) { - if (!inst->isFixed()) { - continue; - } - - if (row_bb.contains(inst->getBBox()->getBox())) { - row_insts.insert(inst); - } - } + std::set row_insts( + fixed_instances.qbegin(boost::geometry::index::covered_by(row_bb)), + fixed_instances.qend()); const int llx = row_bb.xMin(); const int urx = row_bb.xMax();