From f1adf5b26acd327cfc4b5950036b573ff2efb340 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Tue, 23 Jun 2026 15:09:08 -0700 Subject: [PATCH] Graph::visitFanouts, visitFanins Signed-off-by: James Cherry --- graph/Graph.cc | 85 +++++++++++++++++++++++++++++++++++---- include/sta/Graph.hh | 15 ++++++- include/sta/GraphClass.hh | 2 + search/Genclks.cc | 26 ++++-------- 4 files changed, 101 insertions(+), 27 deletions(-) diff --git a/graph/Graph.cc b/graph/Graph.cc index 6c9d47e8..92775d57 100644 --- a/graph/Graph.cc +++ b/graph/Graph.cc @@ -32,6 +32,7 @@ #include "Mutex.hh" #include "Network.hh" #include "PortDirection.hh" +#include "SearchPred.hh" #include "Stats.hh" #include "TimingArc.hh" #include "TimingRole.hh" @@ -487,7 +488,7 @@ Graph::deleteVertex(Vertex *vertex) EdgeId edge_id, next_id; for (edge_id = vertex->in_edges_; edge_id; edge_id = next_id) { Edge *edge = Graph::edge(edge_id); - next_id = edge->vertex_in_link_; + next_id = edge->vertex_in_next_; deleteOutEdge(edge->from(this), edge); edge->clear(); edges_->destroy(edge); @@ -508,7 +509,7 @@ bool Graph::hasFaninOne(Vertex *vertex) const { return vertex->in_edges_ - && edge(vertex->in_edges_)->vertex_in_link_ == 0; + && edge(vertex->in_edges_)->vertex_in_next_ == 0; } void @@ -519,12 +520,12 @@ Graph::deleteInEdge(Vertex *vertex, EdgeId prev = 0; for (EdgeId i = vertex->in_edges_; i && i != edge_id; - i = Graph::edge(i)->vertex_in_link_) + i = Graph::edge(i)->vertex_in_next_) prev = i; if (prev) - Graph::edge(prev)->vertex_in_link_ = edge->vertex_in_link_; + Graph::edge(prev)->vertex_in_next_ = edge->vertex_in_next_; else - vertex->in_edges_ = edge->vertex_in_link_; + vertex->in_edges_ = edge->vertex_in_next_; } void @@ -574,6 +575,72 @@ Graph::gateEdgeArc(const Pin *in_pin, //////////////////////////////////////////////////////////////// +void +Graph::visitFanouts(Vertex *vertex, + SearchPred *pred, + const VertexFn &fn) +{ + if (pred->searchFrom(vertex)) { + for (Edge *edge = this->edge(vertex->out_edges_); + edge; + edge = this->edge(edge->vertex_out_next_)) { + Vertex *to_vertex = this->vertex(edge->to_); + if (pred->searchThru(edge) && pred->searchTo(to_vertex)) + fn(to_vertex); + } + } +} + +void +Graph::visitFanoutEdges(Vertex *vertex, + SearchPred *pred, + const EdgeFn &fn) +{ + if (pred->searchFrom(vertex)) { + for (Edge *edge = this->edge(vertex->out_edges_); + edge; + edge = this->edge(edge->vertex_out_next_)) { + Vertex *to_vertex = this->vertex(edge->to_); + if (pred->searchThru(edge) && pred->searchTo(to_vertex)) + fn(edge, to_vertex); + } + } +} + +void +Graph::visitFanins(Vertex *vertex, + SearchPred *pred, + const VertexFn &fn) +{ + if (pred->searchFrom(vertex)) { + for (Edge *edge = this->edge(vertex->in_edges_); + edge; + edge = this->edge(edge->vertex_in_next_)) { + Vertex *from_vertex = this->vertex(edge->from_); + if (pred->searchThru(edge) && pred->searchFrom(from_vertex)) + fn(from_vertex); + } + } +} + +void +Graph::visitFaninEdges(Vertex *vertex, + SearchPred *pred, + const EdgeFn &fn) +{ + if (pred->searchFrom(vertex)) { + for (Edge *edge = this->edge(vertex->in_edges_); + edge; + edge = this->edge(edge->vertex_in_next_)) { + Vertex *from_vertex = this->vertex(edge->from_); + if (pred->searchThru(edge) && pred->searchFrom(from_vertex)) + fn(edge, from_vertex); + } + } +} + +//////////////////////////////////////////////////////////////// + Slew Graph::slew(const Vertex *vertex, const RiseFall *rf, @@ -650,7 +717,7 @@ Graph::makeEdge(Vertex *from, from->out_edges_ = edge_id; // Add in edge to to vertex. - edge->vertex_in_link_ = to->in_edges_; + edge->vertex_in_next_ = to->in_edges_; to->in_edges_ = edge_id; initArcDelays(edge); @@ -1213,7 +1280,7 @@ Edge::init(VertexId from, from_ = from; to_ = to; arc_set_ = arc_set; - vertex_in_link_ = edge_id_null; + vertex_in_next_ = edge_id_null; vertex_out_next_ = edge_id_null; vertex_out_prev_ = edge_id_null; is_bidirect_inst_path_ = false; @@ -1464,6 +1531,8 @@ VertexIterator::findNext() findNextPin(); } +//////////////////////////////////////////////////////////////// + VertexInEdgeIterator::VertexInEdgeIterator(Vertex *vertex, const Graph *graph) : next_(graph->edge(vertex->in_edges_)), @@ -1483,7 +1552,7 @@ VertexInEdgeIterator::next() { Edge *next = next_; if (next_) - next_ = graph_->edge(next_->vertex_in_link_); + next_ = graph_->edge(next_->vertex_in_next_); return next; } diff --git a/include/sta/Graph.hh b/include/sta/Graph.hh index 1f6e7ce2..abe38883 100644 --- a/include/sta/Graph.hh +++ b/include/sta/Graph.hh @@ -87,6 +87,19 @@ public: bool hasFaninOne(Vertex *vertex) const; VertexId vertexCount() { return vertices_->size(); } + void visitFanouts(Vertex *vertex, + SearchPred *pred, + const VertexFn &fn); + void visitFanins(Vertex *vertex, + SearchPred *pred, + const VertexFn &fn); + void visitFanoutEdges(Vertex *vertex, + SearchPred *pred, + const EdgeFn &fn); + void visitFaninEdges(Vertex *vertex, + SearchPred *pred, + const EdgeFn &fn); + // Reported slew are the same as those in the liberty tables. // reported_slews = measured_slews / slew_derate_from_library // Measured slews are between slew_lower_threshold and slew_upper_threshold. @@ -394,7 +407,7 @@ protected: TimingArcSet *arc_set_; VertexId from_; VertexId to_; - EdgeId vertex_in_link_; // Vertex in edges list. + EdgeId vertex_in_next_; // Vertex in edges list. EdgeId vertex_out_next_; // Vertex out edges doubly linked list. EdgeId vertex_out_prev_; float *arc_delays_; diff --git a/include/sta/GraphClass.hh b/include/sta/GraphClass.hh index cdf7539b..542f3ac0 100644 --- a/include/sta/GraphClass.hh +++ b/include/sta/GraphClass.hh @@ -65,6 +65,8 @@ using Level = int; using DcalcAPIndex = int; using TagGroupIndex = int; using SlewSeq = std::vector; +using VertexFn = std::function; +using EdgeFn = std::function; static constexpr int level_max = std::numeric_limits::max(); diff --git a/search/Genclks.cc b/search/Genclks.cc index 03d53d74..7b16a51f 100644 --- a/search/Genclks.cc +++ b/search/Genclks.cc @@ -625,16 +625,10 @@ Genclks::enqueueFanin(Vertex *vertex, VertexQueue &insert_queue, SearchPred &srch_pred) { - if (srch_pred.searchTo(vertex, mode_)) { - VertexInEdgeIterator edge_iter(vertex, graph_); - while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - Vertex *from_vertex = edge->from(graph_); - if (srch_pred.searchFrom(from_vertex, mode_) - && srch_pred.searchThru(edge, mode_)) - insert_queue.push(from_vertex); - } - } + graph_->visitFanins(vertex, &srch_pred, + [&insert_queue] (Vertex *fanin) { + insert_queue.push(fanin); + }); } void @@ -642,14 +636,10 @@ Genclks::enqueueFanout(Vertex *vertex, VertexQueue &insert_queue, SearchPred &srch_pred) { - VertexOutEdgeIterator edge_iter(vertex, graph_); - while (edge_iter.hasNext()) { - Edge *edge = edge_iter.next(); - Vertex *to_vertex = edge->to(graph_); - if (srch_pred.searchThru(edge, mode_) - && srch_pred.searchTo(to_vertex, mode_)) - insert_queue.push(to_vertex); - } + graph_->visitFanouts(vertex, &srch_pred, + [&insert_queue] (Vertex *fanout) { + insert_queue.push(fanout); + }); } Tag *