From 3ed4e73e548c3db029482a94d42c0df47c2e3b28 Mon Sep 17 00:00:00 2001 From: Krzysztof Bieganski Date: Thu, 14 Dec 2023 14:11:36 +0100 Subject: [PATCH] Fewer pin loc lookups in Steiner tree construction Signed-off-by: Krzysztof Bieganski --- src/rsz/src/SteinerTree.cc | 50 +++++++++++++++++++------------------- src/rsz/src/SteinerTree.hh | 15 +++++++++--- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/src/rsz/src/SteinerTree.cc b/src/rsz/src/SteinerTree.cc index 62fb69f2eeb..0900ce316ff 100644 --- a/src/rsz/src/SteinerTree.cc +++ b/src/rsz/src/SteinerTree.cc @@ -58,8 +58,9 @@ using sta::NetConnectedPinIterator; static void connectedPins(const Net *net, Network *network, + dbNetwork* db_network, // Return value. - PinSeq &pins); + Vector &pins); SteinerPt SteinerTree::null_pt = -1; @@ -74,18 +75,16 @@ Resizer::makeSteinerTree(const Pin *drvr_pin) debugPrint(logger_, RSZ, "steiner", 1, "Net {}", sdc_network->pathName(net)); SteinerTree *tree = new SteinerTree(drvr_pin, this); - PinSeq &pins = tree->pins(); + Vector &pinlocs = tree->pinlocs(); // Find all the connected pins - connectedPins(net, network_, pins); + connectedPins(net, network_, db_network_, pinlocs); // Sort pins by location because connectedPins order is not deterministic. - sort(pins, [=](const Pin *pin1, const Pin *pin2) { - Point loc1 = db_network_->location(pin1); - Point loc2 = db_network_->location(pin2); - return loc1.getX() < loc2.getX() - || (loc1.getX() == loc2.getX() - && loc1.getY() < loc2.getY()); + sort(pinlocs, [=](const PinLoc& pin1, const PinLoc& pin2) { + return pin1.loc.getX() < pin2.loc.getX() + || (pin1.loc.getX() == pin2.loc.getX() + && pin1.loc.getY() < pin2.loc.getY()); }); - int pin_count = pins.size(); + int pin_count = pinlocs.size(); bool is_placed = true; // Warn if there are too many pins (>10000) if (pin_count > max_steiner_pin_count_) { @@ -96,23 +95,22 @@ Resizer::makeSteinerTree(const Pin *drvr_pin) vector x, y; // Two separate vectors of coordinates needed by flute. int drvr_idx = 0; // The "driver_pin" or the root of the Steiner tree. for (int i = 0; i < pin_count; i++) { - const Pin *pin = pins[i]; - if (pin == drvr_pin) { + const PinLoc& pinloc = pinlocs[i]; + if (pinloc.pin == drvr_pin) { drvr_idx = i; // drvr_index is needed by flute. } - Point loc = db_network_->location(pin); - x.push_back(loc.x()); - y.push_back(loc.y()); + x.push_back(pinloc.loc.x()); + y.push_back(pinloc.loc.y()); debugPrint(logger_, RSZ, "steiner", 3, " {} ({} {})", - sdc_network->pathName(pin), - loc.x(), loc.y()); + sdc_network->pathName(pinloc.pin), + pinloc.loc.x(), pinloc.loc.y()); // Track that all our pins are placed. - is_placed &= db_network_->isPlaced(pin); + is_placed &= db_network_->isPlaced(pinloc.pin); // Flute may reorder the input points, so it takes some unravelling // to find the mapping back to the original pins. The complication is // that multiple pins can occupy the same location. - tree->locAddPin(loc, pin); + tree->locAddPin(pinloc.loc, pinloc.pin); } if (is_placed) { stt::Tree ftree = stt_builder_->makeSteinerTree(db_network_->staToDb(net), @@ -130,13 +128,15 @@ Resizer::makeSteinerTree(const Pin *drvr_pin) static void connectedPins(const Net *net, Network *network, + dbNetwork* db_network, // Return value. - PinSeq &pins) + Vector &pins) { NetConnectedPinIterator *pin_iter = network->connectedPinIterator(net); while (pin_iter->hasNext()) { const Pin *pin = pin_iter->next(); - pins.push_back(pin); + Point loc = db_network->location(pin); + pins.push_back({pin, loc}); } delete pin_iter; } @@ -174,7 +174,7 @@ SteinerTree::SteinerTree(const Pin *drvr_pin, Resizer *resizer) : void SteinerTree::createSteinerPtToPinMap() { - unsigned int pin_count = pins_.size(); + unsigned int pin_count = pinlocs_.size(); point_pin_array_.resize(pin_count); for (unsigned int i = 0; i < pin_count; i++) { @@ -193,7 +193,7 @@ SteinerTree::branchCount() const } void -SteinerTree::locAddPin(Point &loc, +SteinerTree::locAddPin(const Point& loc, const Pin *pin) { PinSeq &pins = loc_pin_map_[loc]; @@ -372,7 +372,7 @@ SteinerTree::populateSides(const SteinerPt from, const SteinerPt to, const std::vector& adj2, const std::vector& adj3) { - if (to >= (int) pins_.size()) { + if (to >= (int) pinlocs_.size()) { SteinerPt adj; adj = adj1[to]; populateSides(from, to, adj, adj1, adj2, adj3); @@ -440,7 +440,7 @@ int SteinerTree::distance(SteinerPt& from, SteinerPt& to) const const Pin *SteinerTree::pin(SteinerPt pt) const { validatePoint(pt); - if (pt < (int)pins_.size()) { + if (pt < (int)pinlocs_.size()) { return point_pin_array_[pt]; } return nullptr; diff --git a/src/rsz/src/SteinerTree.hh b/src/rsz/src/SteinerTree.hh index cfea130acad..2c131faa3f8 100644 --- a/src/rsz/src/SteinerTree.hh +++ b/src/rsz/src/SteinerTree.hh @@ -80,6 +80,13 @@ public: const Point &pt2) const; }; +class PinLoc +{ +public: + const Pin* pin; + Point loc; +}; + using LocPinMap = std::unordered_map; class SteinerTree; @@ -97,8 +104,8 @@ class SteinerTree { public: SteinerTree(const Pin *drvr_pin, Resizer *resizer); - PinSeq &pins() { return pins_; } - int pinCount() const { return pins_.size(); } + Vector &pinlocs() { return pinlocs_; } + int pinCount() const { return pinlocs_.size(); } int branchCount() const; void branch(int index, // Return values. @@ -147,13 +154,13 @@ public: static SteinerPt null_pt; protected: - void locAddPin(Point &loc, + void locAddPin(const Point &loc, const Pin *pin); stt::Tree tree_; const Pin *drvr_pin_; int drvr_steiner_pt_; // index into tree_.branch - PinSeq pins_; // Initial input + Vector pinlocs_; // Initial input LocPinMap loc_pin_map_; // location -> pins map std::vector left_; std::vector right_;