Graph::visitFanouts, visitFanins

Signed-off-by: James Cherry <cherry@CerezoBook.local>
This commit is contained in:
James Cherry 2026-06-23 15:09:08 -07:00
parent a456c352cf
commit f1adf5b26a
4 changed files with 101 additions and 27 deletions

View File

@ -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;
}

View File

@ -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_;

View File

@ -65,6 +65,8 @@ using Level = int;
using DcalcAPIndex = int;
using TagGroupIndex = int;
using SlewSeq = std::vector<Slew>;
using VertexFn = std::function<void(Vertex*)>;
using EdgeFn = std::function<void(Edge *, Vertex*)>;
static constexpr int level_max = std::numeric_limits<Level>::max();

View File

@ -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 *