@@ -559,6 +559,14 @@ bool NegotiationLegalizer::initFromDb()
559559 cells_.clear ();
560560 cells_.reserve (block->getInsts ().size ());
561561
562+ // Cache region boundaries converted to grid coordinates, keyed by dbRegion*.
563+ struct RegionRectInline
564+ {
565+ int xlo, ylo, xhi, yhi;
566+ };
567+ std::unordered_map<odb::dbRegion*, std::vector<RegionRectInline>>
568+ region_rect_cache;
569+
562570 for (auto * db_inst : block->getInsts ()) {
563571 const auto status = db_inst->getPlacementStatus ();
564572 if (status == odb::dbPlacementStatus::NONE ) {
@@ -650,29 +658,32 @@ bool NegotiationLegalizer::initFromDb()
650658 odb_region = grp->getRegion ();
651659 }
652660 }
653- struct RegionRectInline
654- {
655- int xlo, ylo, xhi, yhi;
656- };
657- std::vector<RegionRectInline> region_rects_inline;
661+ // Look up (or populate) the cache for this region.
662+ const std::vector<RegionRectInline>* region_rects_ptr = nullptr ;
658663 if (odb_region != nullptr ) {
659- for (auto * box : odb_region->getBoundaries ()) {
660- RegionRectInline r;
661- r.xlo = (box->xMin () - die_xlo_) / site_width_;
662- r.ylo = (box->yMin () - die_ylo_) / row_height_;
663- r.xhi = (box->xMax () - die_xlo_) / site_width_;
664- r.yhi = (box->yMax () - die_ylo_) / row_height_;
665- region_rects_inline.push_back (r);
664+ auto it = region_rect_cache.find (odb_region);
665+ if (it == region_rect_cache.end ()) {
666+ std::vector<RegionRectInline> rects;
667+ for (auto * box : odb_region->getBoundaries ()) {
668+ RegionRectInline r;
669+ r.xlo = (box->xMin () - die_xlo_) / site_width_;
670+ r.ylo = (box->yMin () - die_ylo_) / row_height_;
671+ r.xhi = (box->xMax () - die_xlo_) / site_width_;
672+ r.yhi = (box->yMax () - die_ylo_) / row_height_;
673+ rects.push_back (r);
674+ }
675+ it = region_rect_cache.emplace (odb_region, std::move (rects)).first ;
666676 }
677+ region_rects_ptr = &it->second ;
667678 }
668679 // Returns true when (gx,gy) satisfies the region constraint:
669680 // region-constrained cells must land inside their region;
670681 // unconstrained cells have no restriction here (negotiation handles it).
671682 auto isInRegionOk = [&](int gx, int gy) -> bool {
672- if (region_rects_inline. empty () ) {
683+ if (region_rects_ptr == nullptr ) {
673684 return true ;
674685 }
675- for (const auto & r : region_rects_inline ) {
686+ for (const auto & r : *region_rects_ptr ) {
676687 if (gx >= r.xlo && gy >= r.ylo && gx + cell.width <= r.xhi
677688 && gy + cell.height <= r.yhi ) {
678689 return true ;
0 commit comments