From 1e3190f1fd966f3448a73478b8482a1aa7881483 Mon Sep 17 00:00:00 2001 From: dsengupta0628 Date: Wed, 25 Feb 2026 16:18:15 +0000 Subject: [PATCH] Combined changes to speedup OpenRoad compared to OpenSTA Signed-off-by: dsengupta0628 --- graph/Graph.cc | 13 +++++- include/sta/ExceptionPath.hh | 9 +++++ include/sta/GraphClass.hh | 9 ++++- include/sta/NetworkClass.hh | 24 +++++++++++ network/Network.cc | 78 +++++++++++++++++++++++++++++++++--- sdc/ExceptionPath.cc | 36 +++++++++++++---- search/Levelize.cc | 39 +++++++++++------- 7 files changed, 177 insertions(+), 31 deletions(-) diff --git a/graph/Graph.cc b/graph/Graph.cc index 2fe4d934..438e724c 100644 --- a/graph/Graph.cc +++ b/graph/Graph.cc @@ -1546,7 +1546,18 @@ bool VertexIdLess::operator()(const Vertex *vertex1, const Vertex *vertex2) const { - return graph_->id(vertex1) < graph_->id(vertex2); + return id(vertex1) < id(vertex2); +} + +VertexId +VertexIdLess::id(const Vertex *vertex) const +{ + int index = (reinterpret_cast(vertex) >> 4) & 0xf; + if (vertex == last_vertices_[index]) + return last_ids_[index]; + last_vertices_[index] = vertex; + last_ids_[index] = (graph_) ? graph_->id(vertex) : 0; + return last_ids_[index]; } diff --git a/include/sta/ExceptionPath.hh b/include/sta/ExceptionPath.hh index f5b89f14..bbec5572 100644 --- a/include/sta/ExceptionPath.hh +++ b/include/sta/ExceptionPath.hh @@ -497,8 +497,17 @@ protected: const Network *network) const; virtual const char *cmdKeyword() const; + bool matchesInst(const Pin *pin, + bool inst_matches_reg_clk_pin, + const Network *network) const; + // -rise|-fall endpoint transition. const RiseFallBoth *end_rf_; + + static constexpr int cache_size_ = 16; + mutable const Pin *inst_match_pins_[cache_size_] = {nullptr}; + mutable bool inst_match_results_[cache_size_] = {false}; + mutable bool inst_match_reg_clk_[cache_size_] = {false}; }; class ExceptionThru : public ExceptionPt diff --git a/include/sta/GraphClass.hh b/include/sta/GraphClass.hh index ebe184c8..a625d0d8 100644 --- a/include/sta/GraphClass.hh +++ b/include/sta/GraphClass.hh @@ -43,6 +43,9 @@ class VertexIterator; class VertexInEdgeIterator; class VertexOutEdgeIterator; +using VertexId = ObjectId; +using EdgeId = ObjectId; + class VertexIdLess { public: @@ -52,11 +55,13 @@ public: const Vertex *vertex2) const; private: + VertexId id(const Vertex *vertex) const; Graph *&graph_; + static constexpr int cache_size_ = 16; + mutable const Vertex *last_vertices_[cache_size_] = {nullptr}; + mutable VertexId last_ids_[cache_size_] = {0}; }; -using VertexId = ObjectId; -using EdgeId = ObjectId; using VertexSeq = std::vector; using VertexSet = std::set; using EdgeSeq = std::vector; diff --git a/include/sta/NetworkClass.hh b/include/sta/NetworkClass.hh index 9e72fef6..6cc5b3ea 100644 --- a/include/sta/NetworkClass.hh +++ b/include/sta/NetworkClass.hh @@ -85,7 +85,11 @@ public: bool operator()(const Cell *cell1, const Cell *cell2) const; private: + ObjectId id(const Cell *cell) const; const Network *network_; + static constexpr int cache_size_ = 16; + mutable const Cell *last_cells_[cache_size_] = {nullptr}; + mutable ObjectId last_ids_[cache_size_] = {0}; }; class PortIdLess @@ -95,7 +99,11 @@ public: bool operator()(const Port *port1, const Port *port2) const; private: + ObjectId id(const Port *port) const; const Network *network_; + static constexpr int cache_size_ = 16; + mutable const Port *last_ports_[cache_size_] = {nullptr}; + mutable ObjectId last_ids_[cache_size_] = {0}; }; class InstanceIdLess @@ -105,7 +113,11 @@ public: bool operator()(const Instance *inst1, const Instance *inst2) const; private: + ObjectId id(const Instance *inst) const; const Network *network_; + static constexpr int cache_size_ = 16; + mutable const Instance *last_insts_[cache_size_] = {nullptr}; + mutable ObjectId last_ids_[cache_size_] = {0}; }; class PinIdLess @@ -115,7 +127,11 @@ public: bool operator()(const Pin *pin1, const Pin *pin2) const; private: + ObjectId id(const Pin *pin) const; const Network *network_; + static constexpr int cache_size_ = 16; + mutable const Pin *last_pins_[cache_size_] = {nullptr}; + mutable ObjectId last_ids_[cache_size_] = {0}; }; class PinIdHash @@ -125,7 +141,11 @@ public: size_t operator()(const Pin *pin) const; private: + size_t id(const Pin *pin) const; const Network *network_; + static constexpr int cache_size_ = 16; + mutable const Pin *last_pins_[cache_size_] = {nullptr}; + mutable size_t last_ids_[cache_size_] = {0}; }; class NetIdLess @@ -135,7 +155,11 @@ public: bool operator()(const Net *net1, const Net *net2) const; private: + ObjectId id(const Net *net) const; const Network *network_; + static constexpr int cache_size_ = 16; + mutable const Net *last_nets_[cache_size_] = {nullptr}; + mutable ObjectId last_ids_[cache_size_] = {0}; }; //////////////////////////////////////////////////////////////// diff --git a/network/Network.cc b/network/Network.cc index 8e03a704..d7f21db1 100644 --- a/network/Network.cc +++ b/network/Network.cc @@ -1986,7 +1986,18 @@ bool CellIdLess::operator()(const Cell *cell1, const Cell *cell2) const { - return network_->id(cell1) < network_->id(cell2); + return id(cell1) < id(cell2); +} + +ObjectId +CellIdLess::id(const Cell *cell) const +{ + int index = (reinterpret_cast(cell) >> 4) & 0xf; + if (cell == last_cells_[index]) + return last_ids_[index]; + last_cells_[index] = cell; + last_ids_[index] = (network_) ? network_->id(cell) : 0; + return last_ids_[index]; } PortIdLess::PortIdLess(const Network *network) : @@ -1998,7 +2009,18 @@ bool PortIdLess::operator()(const Port *port1, const Port *port2) const { - return network_->id(port1) < network_->id(port2); + return id(port1) < id(port2); +} + +ObjectId +PortIdLess::id(const Port *port) const +{ + int index = (reinterpret_cast(port) >> 4) & 0xf; + if (port == last_ports_[index]) + return last_ids_[index]; + last_ports_[index] = port; + last_ids_[index] = (network_) ? network_->id(port) : 0; + return last_ids_[index]; } InstanceIdLess::InstanceIdLess(const Network *network) : @@ -2010,7 +2032,18 @@ bool InstanceIdLess::operator()(const Instance *inst1, const Instance *inst2) const { - return network_->id(inst1) < network_->id(inst2); + return id(inst1) < id(inst2); +} + +ObjectId +InstanceIdLess::id(const Instance *inst) const +{ + int index = (reinterpret_cast(inst) >> 4) & 0xf; + if (inst == last_insts_[index]) + return last_ids_[index]; + last_insts_[index] = inst; + last_ids_[index] = (network_) ? network_->id(inst) : 0; + return last_ids_[index]; } PinIdLess::PinIdLess(const Network *network) : @@ -2022,7 +2055,18 @@ bool PinIdLess::operator()(const Pin *pin1, const Pin *pin2) const { - return network_->id(pin1) < network_->id(pin2); + return id(pin1) < id(pin2); +} + +ObjectId +PinIdLess::id(const Pin *pin) const +{ + int index = (reinterpret_cast(pin) >> 4) & 0xf; + if (pin == last_pins_[index]) + return last_ids_[index]; + last_pins_[index] = pin; + last_ids_[index] = (network_) ? network_->id(pin) : 0; + return last_ids_[index]; } PinIdHash::PinIdHash(const Network *network) : @@ -2033,7 +2077,18 @@ PinIdHash::PinIdHash(const Network *network) : size_t PinIdHash::operator()(const Pin *pin) const { - return network_->id(pin); + return id(pin); +} + +size_t +PinIdHash::id(const Pin *pin) const +{ + int index = (reinterpret_cast(pin) >> 4) & 0xf; + if (pin == last_pins_[index]) + return last_ids_[index]; + last_pins_[index] = pin; + last_ids_[index] = (network_) ? network_->id(pin) : 0; + return last_ids_[index]; } NetIdLess::NetIdLess(const Network *network) : @@ -2045,7 +2100,18 @@ bool NetIdLess::operator()(const Net *net1, const Net *net2) const { - return network_->id(net1) < network_->id(net2); + return id(net1) < id(net2); +} + +ObjectId +NetIdLess::id(const Net *net) const +{ + int index = (reinterpret_cast(net) >> 4) & 0xf; + if (net == last_nets_[index]) + return last_ids_[index]; + last_nets_[index] = net; + last_ids_[index] = (network_) ? network_->id(net) : 0; + return last_ids_[index]; } //////////////////////////////////////////////////////////////// diff --git a/sdc/ExceptionPath.cc b/sdc/ExceptionPath.cc index 70d131c9..9a9cfd62 100644 --- a/sdc/ExceptionPath.cc +++ b/sdc/ExceptionPath.cc @@ -1383,6 +1383,32 @@ ExceptionTo::intersectsPts(ExceptionTo *to, || (insts_ && intersects(insts_, to->instances(), network))); } +bool +ExceptionTo::matchesInst(const Pin *pin, + bool inst_matches_reg_clk_pin, + const Network *network) const +{ + size_t hash = reinterpret_cast(pin); + hash ^= (hash >> 4); + int index = hash % cache_size_; + + if (inst_match_pins_[index] == pin + && inst_match_reg_clk_[index] == inst_matches_reg_clk_pin) { + return inst_match_results_[index]; + } + + bool result = (inst_matches_reg_clk_pin || !network->isRegClkPin(pin)) + && insts_->contains(network->instance(pin)) + && (network->direction(pin)->isAnyInput() + || network->direction(pin)->isInternal()); + + inst_match_pins_[index] = pin; + inst_match_reg_clk_[index] = inst_matches_reg_clk_pin; + inst_match_results_[index] = result; + + return result; +} + bool ExceptionTo::matchesFilter(const Pin *pin, const ClockEdge *clk_edge, @@ -1421,11 +1447,7 @@ ExceptionTo::matches(const Pin *pin, && rf_->matches(clk_edge->transition()) && end_rf_->matches(end_rf)) || (insts_ - && (inst_matches_reg_clk_pin - || !network->isRegClkPin(pin)) - && insts_->contains(network->instance(pin)) - && (network->direction(pin)->isAnyInput() - || network->direction(pin)->isInternal()) + && matchesInst(pin, inst_matches_reg_clk_pin, network) && rf_->matches(end_rf) && end_rf_->matches(end_rf)) || (pins_ == nullptr @@ -1444,9 +1466,7 @@ ExceptionTo::matches(const Pin *pin, && rf_->matches(end_rf) && end_rf_->matches(end_rf)) || (insts_ - && insts_->contains(network->instance(pin)) - && (network->direction(pin)->isAnyInput() - || network->direction(pin)->isInternal()) + && matchesInst(pin, true, network) && rf_->matches(end_rf) && end_rf_->matches(end_rf)); } diff --git a/search/Levelize.cc b/search/Levelize.cc index cb64ee77..efdac4f1 100644 --- a/search/Levelize.cc +++ b/search/Levelize.cc @@ -352,7 +352,17 @@ VertexSeq Levelize::findTopologicalOrder() { Stats stats(debug_, report_); - std::map in_degree; + + // Use vector instead of map for O(1) access + VertexId max_id = 0; + VertexIterator vertex_iter_max(graph_); + while (vertex_iter_max.hasNext()) { + Vertex *vertex = vertex_iter_max.next(); + VertexId id = graph_->id(vertex); + if (id > max_id) + max_id = id; + } + std::vector in_degree(max_id + 1, 0); VertexIterator vertex_iter(graph_); while (vertex_iter.hasNext()) { @@ -362,7 +372,7 @@ Levelize::findTopologicalOrder() Edge *edge = edge_iter.next(); Vertex *to_vertex = edge->to(graph_); if (searchThru(edge)) - in_degree[to_vertex] += 1; + in_degree[graph_->id(to_vertex)] += 1; if (edge->role() == TimingRole::latchDtoQ()) latch_d_to_q_edges_.insert(edge); } @@ -370,8 +380,9 @@ Levelize::findTopologicalOrder() const Pin *pin = vertex->pin(); if (graph_delay_calc_->bidirectDrvrSlewFromLoad(pin) && !vertex->isBidirectDriver()) { - Vertex *to_vertex = graph_->pinDrvrVertex(pin);; - in_degree[to_vertex] += 1; + Vertex *to_vertex = graph_->pinDrvrVertex(pin); + if (to_vertex) + in_degree[graph_->id(to_vertex)] += 1; } } @@ -389,10 +400,9 @@ Levelize::findTopologicalOrder() Edge *edge = edge_iter.next(); Vertex *to_vertex = edge->to(graph_); if (searchThru(edge)) { - const auto &to_degree_itr = in_degree.find(to_vertex); - int &to_in_degree = to_degree_itr->second; - to_in_degree -= 1; - if (to_in_degree == 0) + int °ree = in_degree[graph_->id(to_vertex)]; + degree -= 1; + if (degree == 0) queue.push_back(to_vertex); } } @@ -401,11 +411,12 @@ Levelize::findTopologicalOrder() if (graph_delay_calc_->bidirectDrvrSlewFromLoad(pin) && !vertex->isBidirectDriver()) { Vertex *to_vertex = graph_->pinDrvrVertex(pin); - const auto °ree_itr = in_degree.find(to_vertex); - int &in_degree = degree_itr->second; - in_degree -= 1; - if (in_degree == 0) - queue.push_back(to_vertex); + if (to_vertex) { + int °ree = in_degree[graph_->id(to_vertex)]; + degree -= 1; + if (degree == 0) + queue.push_back(to_vertex); + } } } @@ -413,7 +424,7 @@ Levelize::findTopologicalOrder() VertexIterator vertex_iter(graph_); while (vertex_iter.hasNext()) { Vertex *vertex = vertex_iter.next(); - if (in_degree[vertex] != 0) + if (in_degree[graph_->id(vertex)] != 0) debugPrint(debug_, "levelize", 2, "topological sort missing %s", vertex->to_string(this).c_str()); }