From 61c0f9d73c33d1a6bc204c9c52d450232ad061d6 Mon Sep 17 00:00:00 2001 From: James Cherry Date: Tue, 1 Mar 2022 06:55:25 -0700 Subject: [PATCH] VertexSet use vertex id for comparison Signed-off-by: James Cherry --- dcalc/GraphDelayCalc1.cc | 32 ++--- dcalc/GraphDelayCalc1.hh | 2 +- graph/Graph.cc | 29 ++++- include/sta/Graph.hh | 22 +++- include/sta/GraphClass.hh | 2 +- include/sta/Search.hh | 8 +- include/sta/Sta.hh | 2 + search/CheckTiming.cc | 6 +- search/ClkSkew.cc | 6 +- search/FindRegister.cc | 6 +- search/Genclks.cc | 8 +- search/Levelize.cc | 35 +++--- search/Levelize.hh | 6 +- search/PathGroup.cc | 2 +- search/Power.cc | 2 +- search/Search.cc | 72 ++++++----- search/Sta.cc | 24 +++- search/VisitPathGroupVertices.cc | 5 +- search/WorstSlack.cc | 206 ++++++++++++++----------------- search/WorstSlack.hh | 30 ++--- 20 files changed, 265 insertions(+), 240 deletions(-) diff --git a/dcalc/GraphDelayCalc1.cc b/dcalc/GraphDelayCalc1.cc index c3dd9d0b..d6f911c5 100644 --- a/dcalc/GraphDelayCalc1.cc +++ b/dcalc/GraphDelayCalc1.cc @@ -214,6 +214,8 @@ GraphDelayCalc1::GraphDelayCalc1(StaState *sta) : observer_(nullptr), delays_seeded_(false), incremental_(false), + delays_exist_(false), + invalid_delays_(new VertexSet(graph_)), search_pred_(new SearchPred1(sta)), search_non_latch_pred_(new SearchPredNonLatch2(sta)), clk_pred_(new ClkTreeSearchPred(sta)), @@ -226,6 +228,7 @@ GraphDelayCalc1::GraphDelayCalc1(StaState *sta) : GraphDelayCalc1::~GraphDelayCalc1() { delete search_pred_; + delete invalid_delays_; delete search_non_latch_pred_; delete clk_pred_; delete iter_; @@ -293,7 +296,7 @@ GraphDelayCalc1::delaysInvalid() incremental_ = false; iter_->clear(); // No need to keep track of incremental updates any more. - invalid_delays_.clear(); + invalid_delays_->clear(); invalid_check_edges_.clear(); invalid_latch_edges_.clear(); } @@ -326,11 +329,11 @@ GraphDelayCalc1::delayInvalid(Vertex *vertex) debugPrint(debug_, "delay_calc", 2, "delay invalid %s", vertex->name(sdc_network_)); if (graph_ && incremental_) { - invalid_delays_.insert(vertex); + invalid_delays_->insert(vertex); // Invalidate driver that triggers dcalc for multi-driver nets. MultiDrvrNet *multi_drvr = multiDrvrNet(vertex); if (multi_drvr) - invalid_delays_.insert(multi_drvr->dcalcDrvr()); + invalid_delays_->insert(multi_drvr->dcalcDrvr()); } } @@ -339,7 +342,7 @@ GraphDelayCalc1::deleteVertexBefore(Vertex *vertex) { iter_->deleteVertexBefore(vertex); if (incremental_) - invalid_delays_.erase(vertex); + invalid_delays_->erase(vertex); MultiDrvrNet *multi_drvr = multiDrvrNet(vertex); if (multi_drvr) { multi_drvr->drvrs()->erase(vertex); @@ -432,9 +435,7 @@ GraphDelayCalc1::findDelays(Level level) void GraphDelayCalc1::seedInvalidDelays() { - VertexSet::Iterator vertex_iter(invalid_delays_); - while (vertex_iter.hasNext()) { - Vertex *vertex = vertex_iter.next(); + for (Vertex *vertex : *invalid_delays_) { if (vertex->isRoot()) seedRootSlew(vertex, arc_delay_calc_); else { @@ -442,7 +443,7 @@ GraphDelayCalc1::seedInvalidDelays() iter_->enqueue(vertex); } } - invalid_delays_.clear(); + invalid_delays_->clear(); } class FindNetDrvrs : public PinVisitor @@ -508,7 +509,7 @@ void GraphDelayCalc1::makeMultiDrvrNet(PinSet &drvr_pins) { debugPrint(debug_, "delay_calc", 3, "multi-driver net"); - VertexSet *drvr_vertices = new VertexSet; + VertexSet *drvr_vertices = new VertexSet(graph_); MultiDrvrNet *multi_drvr = new MultiDrvrNet(drvr_vertices); Level max_drvr_level = 0; Vertex *max_drvr = nullptr; @@ -549,11 +550,8 @@ GraphDelayCalc1::multiDrvrNet(const Vertex *drvr_vertex) const void GraphDelayCalc1::seedRootSlews() { - VertexSet::Iterator root_iter(levelize_->roots()); - while (root_iter.hasNext()) { - Vertex *vertex = root_iter.next(); + for (Vertex *vertex : *levelize_->roots()) seedRootSlew(vertex, arc_delay_calc_); - } } void @@ -919,9 +917,7 @@ GraphDelayCalc1::findDriverDelays(Vertex *drvr_vertex, Vertex *dcalc_drvr = multi_drvr->dcalcDrvr(); if (drvr_vertex == dcalc_drvr) { bool init_load_slews = true; - VertexSet::Iterator drvr_iter(multi_drvr->drvrs()); - while (drvr_iter.hasNext()) { - Vertex *drvr_vertex = drvr_iter.next(); + for (Vertex *drvr_vertex : *multi_drvr->drvrs()) { // Only init load slews once so previous driver dcalc results // aren't clobbered. delay_changed |= findDriverDelays1(drvr_vertex, init_load_slews, @@ -1381,9 +1377,7 @@ GraphDelayCalc1::findMultiDrvrGateDelay(MultiDrvrNet *multi_drvr, { ArcDelay delay_sum = 1.0; Slew slew_sum = 1.0; - VertexSet::Iterator drvr_iter(multi_drvr->drvrs()); - while (drvr_iter.hasNext()) { - Vertex *drvr_vertex1 = drvr_iter.next(); + for (Vertex *drvr_vertex1 : *multi_drvr->drvrs()) { Pin *drvr_pin1 = drvr_vertex1->pin(); Instance *drvr_inst1 = network_->instance(drvr_pin1); LibertyCell *drvr_cell1 = network_->libertyCell(drvr_inst1); diff --git a/dcalc/GraphDelayCalc1.hh b/dcalc/GraphDelayCalc1.hh index 39bcb3cb..adedec8a 100644 --- a/dcalc/GraphDelayCalc1.hh +++ b/dcalc/GraphDelayCalc1.hh @@ -212,7 +212,7 @@ protected: bool incremental_; bool delays_exist_; // Vertices with invalid -to delays. - VertexSet invalid_delays_; + VertexSet *invalid_delays_; // Timing check edges with invalid delays. EdgeSet invalid_check_edges_; // Latch D->Q edges with invalid delays. diff --git a/graph/Graph.cc b/graph/Graph.cc index 16ef0f29..3181cd9d 100644 --- a/graph/Graph.cc +++ b/graph/Graph.cc @@ -48,14 +48,18 @@ Graph::Graph(StaState *sta, have_arc_delays_(have_arc_delays), ap_count_(ap_count), width_check_annotations_(nullptr), - period_check_annotations_(nullptr) + period_check_annotations_(nullptr), + reg_clk_vertices_(new VertexSet(graph_)) { + // For the benifit of reg_clk_vertices_ that references graph_. + graph_ = this; } Graph::~Graph() { delete vertices_; delete edges_; + delete reg_clk_vertices_; deleteSlewTables(); deleteArcDelayTables(); removeWidthCheckAnnotations(); @@ -396,7 +400,7 @@ Graph::makeVertex(Pin *pin, vertex->init(pin, is_bidirect_drvr, is_reg_clk); makeVertexSlews(vertex); if (is_reg_clk) - reg_clk_vertices_.insert(vertex); + reg_clk_vertices_->insert(vertex); return vertex; } @@ -432,7 +436,7 @@ void Graph::deleteVertex(Vertex *vertex) { if (vertex->isRegClk()) - reg_clk_vertices_.erase(vertex); + reg_clk_vertices_->erase(vertex); Pin *pin = vertex->pin_; if (vertex->isBidirectDriver()) pin_bidirect_drvr_vertex_map_.erase(pin_bidirect_drvr_vertex_map_ @@ -1599,4 +1603,23 @@ EdgesThruHierPinIterator::EdgesThruHierPinIterator(const Pin *hpin, edge_iter_.init(edges_); } +//////////////////////////////////////////////////////////////// + +VertexIdLess::VertexIdLess(Graph *&graph) : + graph_(graph) +{ +} + +bool +VertexIdLess::operator()(const Vertex *vertex1, + const Vertex *vertex2) const +{ + return graph_->id(vertex1) < graph_->id(vertex2); +} + +VertexSet::VertexSet(Graph *&graph) : + Set(VertexIdLess(graph)) +{ +} + } // namespace diff --git a/include/sta/Graph.hh b/include/sta/Graph.hh index 2bfea752..96db47f3 100644 --- a/include/sta/Graph.hh +++ b/include/sta/Graph.hh @@ -199,7 +199,7 @@ public: float period); // Remove all delay and slew annotations. void removeDelaySlewAnnotations(); - VertexSet *regClkVertices() { return ®_clk_vertices_; } + VertexSet *regClkVertices() { return reg_clk_vertices_; } static const int vertex_level_bits = 24; static const int vertex_level_max = (1< +{ +public: + VertexSet(Graph *&graph); + VertexSet(const VertexSet &set); +}; + } // namespace diff --git a/include/sta/GraphClass.hh b/include/sta/GraphClass.hh index 5c2c1527..f59d1d12 100644 --- a/include/sta/GraphClass.hh +++ b/include/sta/GraphClass.hh @@ -32,11 +32,11 @@ class VertexIterator; class VertexInEdgeIterator; class VertexOutEdgeIterator; class GraphLoop; +class VertexSet; typedef ObjectId VertexId; typedef ObjectId EdgeId; typedef ObjectId ArcId; -typedef Set VertexSet; typedef Vector VertexSeq; typedef Vector EdgeSeq; typedef Set EdgeSet; diff --git a/include/sta/Search.hh b/include/sta/Search.hh index 8ab75568..510f418d 100644 --- a/include/sta/Search.hh +++ b/include/sta/Search.hh @@ -548,15 +548,15 @@ protected: // Requireds have been seeded by searching arrivals to all endpoints. bool requireds_seeded_; // Vertices with invalid arrival times to update and search from. - VertexSet invalid_arrivals_; + VertexSet *invalid_arrivals_; std::mutex invalid_arrivals_lock_; BfsFwdIterator *arrival_iter_; // Vertices with invalid required times to update and search from. - VertexSet invalid_requireds_; + VertexSet *invalid_requireds_; BfsBkwdIterator *required_iter_; bool tns_exists_; // Endpoint vertices with slacks that have changed since tns was found. - VertexSet invalid_tns_; + VertexSet *invalid_tns_; // Indexed by path_ap->index(). SlackSeq tns_; // Indexed by path_ap->index(). @@ -585,7 +585,7 @@ protected: TagGroupIndex tag_group_capacity_; std::mutex tag_group_lock_; // Latches data outputs to queue on the next search pass. - VertexSet pending_latch_outputs_; + VertexSet *pending_latch_outputs_; std::mutex pending_latch_outputs_lock_; VertexSet *endpoints_; VertexSet *invalid_endpoints_; diff --git a/include/sta/Sta.hh b/include/sta/Sta.hh index 5edb0b8b..67e17f09 100644 --- a/include/sta/Sta.hh +++ b/include/sta/Sta.hh @@ -984,6 +984,8 @@ public: Arrival vertexArrival(Vertex *vertex, const RiseFall *rf, const PathAnalysisPt *path_ap); + Arrival vertexArrival(Vertex *vertex, + const MinMax *min_max); Required vertexRequired(Vertex *vertex, const MinMax *min_max); Required vertexRequired(Vertex *vertex, diff --git a/search/CheckTiming.cc b/search/CheckTiming.cc index 615c4429..343d9be1 100644 --- a/search/CheckTiming.cc +++ b/search/CheckTiming.cc @@ -153,9 +153,7 @@ CheckTiming::checkRegClks(bool reg_multiple_clks, bool reg_no_clks) { PinSet no_clk_pins, multiple_clk_pins; - VertexSet::ConstIterator reg_clk_iter(graph_->regClkVertices()); - while (reg_clk_iter.hasNext()) { - Vertex *vertex = reg_clk_iter.next(); + for (Vertex *vertex : *graph_->regClkVertices()) { Pin *pin = vertex->pin(); ClockSet clks; search_->clocks(vertex, clks); @@ -318,7 +316,7 @@ CheckTiming::checkGeneratedClocks() if (clk->isGenerated()) { search_->genclks()->checkMaster(clk); bool found_clk = false; - VertexSet src_vertices; + VertexSet src_vertices(graph_); clk->srcPinVertices(src_vertices, network_, graph_); VertexSet::Iterator vertex_iter(src_vertices); while (vertex_iter.hasNext()) { diff --git a/search/ClkSkew.cc b/search/ClkSkew.cc index fc0e89bd..77816dab 100644 --- a/search/ClkSkew.cc +++ b/search/ClkSkew.cc @@ -190,9 +190,7 @@ ClkSkews::findClkSkew(ClockSet *clks, const SetupHold *setup_hold, ClkSkewMap &skews) { - VertexSet::ConstIterator reg_clk_iter(graph_->regClkVertices()); - while (reg_clk_iter.hasNext()) { - Vertex *src_vertex = reg_clk_iter.next(); + for (Vertex *src_vertex : *graph_->regClkVertices()) { if (hasClkPaths(src_vertex, clks)) { VertexOutEdgeIterator edge_iter(src_vertex, graph_); while (edge_iter.hasNext()) { @@ -343,7 +341,7 @@ ClkSkews::findFanout(Vertex *from) { debugPrint(debug_, "fanout", 1, "%s", from->name(sdc_network_)); - VertexSet endpoints; + VertexSet endpoints(graph_); FanOutSrchPred pred(this); BfsFwdIterator fanout_iter(BfsIndex::other, &pred, this); fanout_iter.enqueue(from); diff --git a/search/FindRegister.cc b/search/FindRegister.cc index 28b5198f..30208a30 100644 --- a/search/FindRegister.cc +++ b/search/FindRegister.cc @@ -139,7 +139,7 @@ FindRegVisitor::visitRegs(ClockSet *clks, while (clk_iter.hasNext()) { Clock *clk = clk_iter.next(); FindRegClkPred clk_pred(clk, this); - VertexSet visited_vertices; + VertexSet visited_vertices(graph_); for (Pin *pin : clk->leafPins()) { Vertex *vertex, *bidirect_drvr_vertex; graph_->pinVertices(pin, vertex, bidirect_drvr_vertex); @@ -158,9 +158,7 @@ FindRegVisitor::visitRegs(ClockSet *clks, } } else { - VertexSet::ConstIterator reg_clk_iter(graph_->regClkVertices()); - while (reg_clk_iter.hasNext()) { - Vertex *vertex = reg_clk_iter.next(); + for (Vertex *vertex : *graph_->regClkVertices()) { visitRegs(vertex->pin(), TimingSense::positive_unate, RiseFallBoth::riseFall(), edge_triggered, latches); diff --git a/search/Genclks.cc b/search/Genclks.cc index a63f8f05..303292da 100644 --- a/search/Genclks.cc +++ b/search/Genclks.cc @@ -389,7 +389,7 @@ void Genclks::seedSrcPins(Clock *clk, BfsBkwdIterator &iter) { - VertexSet src_vertices; + VertexSet src_vertices(graph_); clk->srcPinVertices(src_vertices, network_, graph_); VertexSet::Iterator vertex_iter(src_vertices); while (vertex_iter.hasNext()) { @@ -583,7 +583,7 @@ Genclks::makeGenclkInfo(Clock *gclk) { FilterPath *src_filter = makeSrcFilter(gclk); Level gclk_level = clkPinMaxLevel(gclk); - VertexSet *fanins = new VertexSet; + VertexSet *fanins = new VertexSet(graph_); findFanin(gclk, fanins); GenclkInfo *genclk_info = new GenclkInfo(gclk, gclk_level, fanins, src_filter); @@ -643,8 +643,8 @@ Genclks::findLatchFdbkEdges(const Clock *gclk, EdgeSet *fdbk_edges = nullptr; for (Pin *pin : gclk->masterClk()->leafPins()) { Vertex *vertex = graph_->pinDrvrVertex(pin); - VertexSet path_vertices; - VertexSet visited_vertices; + VertexSet path_vertices(graph_); + VertexSet visited_vertices(graph_); SearchPred1 srch_pred(this); findLatchFdbkEdges(vertex, gclk_level, srch_pred, path_vertices, visited_vertices, fdbk_edges); diff --git a/search/Levelize.cc b/search/Levelize.cc index 350672e8..6982fc52 100644 --- a/search/Levelize.cc +++ b/search/Levelize.cc @@ -40,6 +40,8 @@ Levelize::Levelize(StaState *sta) : levels_valid_(false), max_level_(0), level_space_(10), + roots_(new VertexSet(graph_)), + relevelize_from_(new VertexSet(graph_)), loops_(nullptr), observer_(nullptr) { @@ -47,6 +49,8 @@ Levelize::Levelize(StaState *sta) : Levelize::~Levelize() { + delete roots_; + delete relevelize_from_; delete search_pred_; delete observer_; deleteLoops(); @@ -70,8 +74,8 @@ Levelize::clear() { levelized_ = false; levels_valid_ = false; - roots_.clear(); - relevelize_from_.clear(); + roots_->clear(); + relevelize_from_->clear(); clearLoopEdges(); deleteLoops(); } @@ -146,7 +150,7 @@ Levelize::findRoots() setLevel(vertex, 0); if (isRoot(vertex)) { debugPrint(debug_, "levelize", 2, "root %s", vertex->name(sdc_network_)); - roots_.insert(vertex); + roots_->insert(vertex); if (hasFanout(vertex, search_pred_, graph_)) // Color roots with no fanout black so that they are // not treated as degenerate loops by levelizeCycles(). @@ -183,11 +187,8 @@ Levelize::sortRoots(VertexSeq &roots) { // roots_ is a set so insert/delete are fast for incremental changes. // Copy the set into a vector for sorting. - VertexSet::Iterator root_iter(roots_); - while (root_iter.hasNext()) { - Vertex *root = root_iter.next(); + for (Vertex *root : *roots_) roots.push_back(root); - } sort(roots, VertexNameLess(network_)); } @@ -362,7 +363,7 @@ Levelize::levelizeCycles() // root". if (vertex->color() == LevelColor::white) { EdgeSeq path; - roots_.insert(vertex); + roots_->insert(vertex); visit(vertex, 0, level_space_, path); } } @@ -384,17 +385,17 @@ Levelize::invalidFrom(Vertex *vertex) while (edge_iter.hasNext()) { Edge *edge = edge_iter.next(); Vertex *from_vertex = edge->from(graph_); - relevelize_from_.insert(from_vertex); + relevelize_from_->insert(from_vertex); } - relevelize_from_.insert(vertex); + relevelize_from_->insert(vertex); levels_valid_ = false; } void Levelize::deleteVertexBefore(Vertex *vertex) { - roots_.erase(vertex); - relevelize_from_.erase(vertex); + roots_->erase(vertex); + relevelize_from_->erase(vertex); } void @@ -402,7 +403,7 @@ Levelize::relevelizeFrom(Vertex *vertex) { debugPrint(debug_, "levelize", 1, "invalid relevelize from %s", vertex->name(sdc_network_)); - relevelize_from_.insert(vertex); + relevelize_from_->insert(vertex); levels_valid_ = false; } @@ -429,15 +430,13 @@ Levelize::deleteEdgeBefore(Edge *edge) void Levelize::relevelize() { - VertexSet::Iterator vertex_iter(relevelize_from_); - while (vertex_iter.hasNext()) { - Vertex *vertex = vertex_iter.next(); + for (Vertex *vertex : *relevelize_from_) { debugPrint(debug_, "levelize", 1, "relevelize from %s", vertex->name(sdc_network_)); if (search_pred_->searchFrom(vertex)) { if (isRoot(vertex)) { setLevel(vertex, 0); - roots_.insert(vertex); + roots_->insert(vertex); } EdgeSeq path; visit(vertex, vertex->level(), 1, path); @@ -445,7 +444,7 @@ Levelize::relevelize() } ensureLatchLevels(); levels_valid_ = true; - relevelize_from_.clear(); + relevelize_from_->clear(); } bool diff --git a/search/Levelize.hh b/search/Levelize.hh index c11a7f9a..03f8db29 100644 --- a/search/Levelize.hh +++ b/search/Levelize.hh @@ -44,7 +44,7 @@ public: void deleteEdgeBefore(Edge *edge); int maxLevel() const { return max_level_; } // Vertices with no fanin edges. - VertexSet &roots() { return roots_; } + VertexSet *roots() { return roots_; } bool isRoot(Vertex *vertex); // Reset to virgin state. void clear(); @@ -77,8 +77,8 @@ protected: bool levels_valid_; Level max_level_; Level level_space_; - VertexSet roots_; - VertexSet relevelize_from_; + VertexSet *roots_; + VertexSet *relevelize_from_; GraphLoopSeq *loops_; EdgeSet loop_edges_; EdgeSet disabled_loop_edges_; diff --git a/search/PathGroup.cc b/search/PathGroup.cc index d55411e2..3a29e67c 100644 --- a/search/PathGroup.cc +++ b/search/PathGroup.cc @@ -808,7 +808,7 @@ PathGroups::makeGroupPathEnds(ExceptionTo *to, makeGroupPathEnds(search->endpoints(), corner, min_max, visitor); else { // Only visit -to filter pins. - VertexSet endpoints; + VertexSet endpoints(graph_); PinSet pins; to->allPins(network, &pins); PinSet::Iterator pin_iter(pins); diff --git a/search/Power.cc b/search/Power.cc index fa4ceb3a..e598b5cc 100644 --- a/search/Power.cc +++ b/search/Power.cc @@ -509,7 +509,7 @@ Power::ensureActivities() void Power::seedActivities(BfsFwdIterator &bfs) { - for (Vertex *vertex : levelize_->roots()) { + for (Vertex *vertex : *levelize_->roots()) { const Pin *pin = vertex->pin(); // Clock activities are baked in. if (!sdc_->isLeafPinClock(pin) diff --git a/search/Search.cc b/search/Search.cc index c329bbf7..4c83a8d1 100644 --- a/search/Search.cc +++ b/search/Search.cc @@ -225,6 +225,9 @@ Search::init(StaState *sta) arrivals_seeded_ = false; requireds_exist_ = false; requireds_seeded_ = false; + invalid_arrivals_ = new VertexSet(graph_); + invalid_requireds_ = new VertexSet(graph_); + invalid_tns_ = new VertexSet(graph_); tns_exists_ = false; worst_slacks_ = nullptr; arrival_iter_ = new BfsFwdIterator(BfsIndex::arrival, nullptr, sta); @@ -238,6 +241,7 @@ Search::init(StaState *sta) tag_groups_ = new TagGroup*[tag_group_capacity_]; tag_group_next_ = 0; tag_group_set_ = new TagGroupSet(tag_group_capacity_); + pending_latch_outputs_ = new VertexSet(graph_); visit_path_ends_ = new VisitPathEnds(this); gated_clk_ = new GatedClk(this); path_groups_ = nullptr; @@ -273,7 +277,11 @@ Search::~Search() delete arrival_iter_; delete required_iter_; delete endpoints_; + delete invalid_arrivals_; + delete invalid_requireds_; + delete invalid_tns_; delete invalid_endpoints_; + delete pending_latch_outputs_; delete visit_path_ends_; delete gated_clk_; delete worst_slacks_; @@ -295,10 +303,10 @@ Search::clear() requireds_seeded_ = false; tns_exists_ = false; clearWorstSlack(); - invalid_arrivals_.clear(); + invalid_arrivals_->clear(); arrival_iter_->clear(); - invalid_requireds_.clear(); - invalid_tns_.clear(); + invalid_requireds_->clear(); + invalid_tns_->clear(); required_iter_->clear(); endpointsInvalid(); deletePathGroups(); @@ -633,12 +641,12 @@ Search::deleteVertexBefore(Vertex *vertex) if (arrivals_exist_) { deletePaths(vertex); arrival_iter_->deleteVertexBefore(vertex); - invalid_arrivals_.erase(vertex); + invalid_arrivals_->erase(vertex); } if (requireds_exist_) { required_iter_->deleteVertexBefore(vertex); - invalid_requireds_.erase(vertex); - invalid_tns_.erase(vertex); + invalid_requireds_->erase(vertex); + invalid_tns_->erase(vertex); } if (endpoints_) endpoints_->erase(vertex); @@ -650,7 +658,7 @@ bool Search::arrivalsValid() { return arrivals_exist_ - && invalid_requireds_.empty(); + && invalid_requireds_->empty(); } void @@ -673,11 +681,11 @@ Search::arrivalsInvalid() arrival_iter_->clear(); required_iter_->clear(); // No need to keep track of incremental updates any more. - invalid_arrivals_.clear(); - invalid_requireds_.clear(); + invalid_arrivals_->clear(); + invalid_requireds_->clear(); tns_exists_ = false; clearWorstSlack(); - invalid_tns_.clear(); + invalid_tns_->clear(); } } @@ -687,10 +695,10 @@ Search::requiredsInvalid() debugPrint(debug_, "search", 1, "requireds invalid"); requireds_exist_ = false; requireds_seeded_ = false; - invalid_requireds_.clear(); + invalid_requireds_->clear(); tns_exists_ = false; clearWorstSlack(); - invalid_tns_.clear(); + invalid_tns_->clear(); } void @@ -702,7 +710,7 @@ Search::arrivalInvalid(Vertex *vertex) if (!arrival_iter_->inQueue(vertex)) { // Lock for StaDelayCalcObserver called by delay calc threads. UniqueLock lock(invalid_arrivals_lock_); - invalid_arrivals_.insert(vertex); + invalid_arrivals_->insert(vertex); } tnsInvalid(vertex); } @@ -772,7 +780,7 @@ Search::requiredInvalid(Vertex *vertex) if (!required_iter_->inQueue(vertex)) { // Lock for StaDelayCalcObserver called by delay calc threads. UniqueLock lock(invalid_arrivals_lock_); - invalid_requireds_.insert(vertex); + invalid_requireds_->insert(vertex); } tnsInvalid(vertex); } @@ -926,19 +934,19 @@ Search::findAllArrivals(VertexVisitor *arrival_visitor) bool Search::havePendingLatchOutputs() { - return pending_latch_outputs_.size() > 0; + return !pending_latch_outputs_->empty(); } void Search::clearPendingLatchOutputs() { - pending_latch_outputs_.clear(); + pending_latch_outputs_->clear(); } void Search::enqueuePendingLatchOutputs() { - for (Vertex *latch_vertex : pending_latch_outputs_) + for (Vertex *latch_vertex : *pending_latch_outputs_) arrival_iter_->enqueue(latch_vertex); clearPendingLatchOutputs(); } @@ -966,7 +974,7 @@ Search::findArrivals(Level level, int arrival_count = arrival_iter_->visitParallel(level, arrival_visitor); stats.report("Find arrivals"); if (arrival_iter_->empty() - && invalid_arrivals_.empty()) { + && invalid_arrivals_->empty()) { clk_arrivals_valid_ = true; arrivals_at_endpoints_exist_ = true; } @@ -1360,7 +1368,7 @@ Search::enqueueLatchDataOutputs(Vertex *vertex) if (latches_->isLatchDtoQ(out_edge)) { Vertex *out_vertex = out_edge->to(graph_); UniqueLock lock(pending_latch_outputs_lock_); - pending_latch_outputs_.insert(out_vertex); + pending_latch_outputs_->insert(out_vertex); } } } @@ -1368,7 +1376,7 @@ Search::enqueueLatchDataOutputs(Vertex *vertex) void Search::seedArrivals() { - VertexSet vertices; + VertexSet vertices(graph_); findClockVertices(vertices); findRootVertices(vertices); findInputDrvrVertices(vertices); @@ -1394,9 +1402,9 @@ Search::findClockVertices(VertexSet &vertices) void Search::seedInvalidArrivals() { - for (Vertex *vertex : invalid_arrivals_) + for (Vertex *vertex : *invalid_arrivals_) seedArrival(vertex); - invalid_arrivals_.clear(); + invalid_arrivals_->clear(); } void @@ -1605,7 +1613,7 @@ Search::makeUnclkedPaths(Vertex *vertex, void Search::findRootVertices(VertexSet &vertices) { - for (Vertex *vertex : levelize_->roots()) { + for (Vertex *vertex : *levelize_->roots()) { const Pin *pin = vertex->pin(); if (!sdc_->isLeafPinClock(pin) && !sdc_->hasInputDelay(pin) @@ -3103,8 +3111,8 @@ VertexSet * Search::endpoints() { if (endpoints_ == nullptr) { - endpoints_ = new VertexSet; - invalid_endpoints_ = new VertexSet; + endpoints_ = new VertexSet(graph_); + invalid_endpoints_ = new VertexSet(graph_); VertexIterator vertex_iter(graph_); while (vertex_iter.hasNext()) { Vertex *vertex = vertex_iter.next(); @@ -3193,9 +3201,9 @@ Search::endpointsInvalid() void Search::seedInvalidRequireds() { - for (Vertex *vertex : invalid_requireds_) + for (Vertex *vertex : *invalid_requireds_) required_iter_->enqueue(vertex); - invalid_requireds_.clear(); + invalid_requireds_->clear(); } //////////////////////////////////////////////////////////////// @@ -3687,7 +3695,7 @@ Search::tnsInvalid(Vertex *vertex) debugPrint(debug_, "tns", 2, "tns invalid %s", vertex->name(sdc_network_)); UniqueLock lock(tns_lock_); - invalid_tns_.insert(vertex); + invalid_tns_->insert(vertex); } } @@ -3695,7 +3703,7 @@ void Search::updateInvalidTns() { PathAPIndex path_ap_count = corners_->pathAnalysisPtCount(); - for (Vertex *vertex : invalid_tns_) { + for (Vertex *vertex : *invalid_tns_) { // Network edits can change endpointedness since tnsInvalid was called. if (isEndpoint(vertex)) { debugPrint(debug_, "tns", 2, "update tns %s", @@ -3709,7 +3717,7 @@ Search::updateInvalidTns() worst_slacks_->updateWorstSlacks(vertex, slacks); } } - invalid_tns_.clear(); + invalid_tns_->clear(); } void @@ -3826,7 +3834,7 @@ Search::wnsTnsPreamble() findAllArrivals(); // Required times are only needed at endpoints. if (requireds_seeded_) { - for (Vertex *vertex : invalid_requireds_) { + for (Vertex *vertex : *invalid_requireds_) { debugPrint(debug_, "search", 2, "tns update required %s", vertex->name(sdc_network_)); if (isEndpoint(vertex)) { @@ -3839,7 +3847,7 @@ Search::wnsTnsPreamble() required_iter_->enqueue(vertex); } } - invalid_requireds_.clear(); + invalid_requireds_->clear(); } else seedRequireds(); diff --git a/search/Sta.cc b/search/Sta.cc index 539e3a9d..d82d651d 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -2792,6 +2792,26 @@ Sta::vertexWorstSlackPath(Vertex *vertex, return vertexWorstSlackPath(vertex, nullptr, min_max); } +Arrival +Sta::vertexArrival(Vertex *vertex, + const MinMax *min_max) +{ + searchPreamble(); + search_->findArrivals(vertex->level()); + Arrival arrival = min_max->initValue(); + VertexPathIterator path_iter(vertex, this); + while (path_iter.hasNext()) { + Path *path = path_iter.next(); + const Arrival &path_arrival = path->arrival(this); + ClkInfo *clk_info = path->clkInfo(search_); + if (path->minMax(this) == min_max + && !clk_info->isGenClkSrcPath() + && delayGreater(path->arrival(this), arrival, min_max, this)) + arrival = path_arrival; + } + return arrival; +} + Arrival Sta::vertexArrival(Vertex *vertex, const RiseFall *rf, @@ -4813,7 +4833,7 @@ Sta::findFaninPins(Vertex *vertex, PinSet *fanin, SearchPred &pred) { - VertexSet visited; + VertexSet visited(graph_); findFaninPins(vertex, flat, inst_levels, pin_levels, visited, &pred, 0, 0); VertexSet::Iterator visited_iter(visited); @@ -4923,7 +4943,7 @@ Sta::findFanoutPins(Vertex *vertex, PinSet *fanout, SearchPred &pred) { - VertexSet visited; + VertexSet visited(graph_); findFanoutPins(vertex, flat, inst_levels, pin_levels, visited, &pred, 0, 0); VertexSet::Iterator visited_iter(visited); diff --git a/search/VisitPathGroupVertices.cc b/search/VisitPathGroupVertices.cc index 636419bd..082b4d9e 100644 --- a/search/VisitPathGroupVertices.cc +++ b/search/VisitPathGroupVertices.cc @@ -118,11 +118,8 @@ visitPathGroupVertices(PathGroup *path_group, VisitPathGroupEnds end_visitor(path_group, visitor, &matching_path_map, &bkwd_iter, sta); VisitPathEnds visit_path_ends(sta); - VertexSet::Iterator end_iter(search->endpoints()); - while (end_iter.hasNext()) { - Vertex *vertex = end_iter.next(); + for(Vertex *vertex : *search->endpoints()) visit_path_ends.visitPathEnds(vertex, &end_visitor); - } // Search backward from the path ends thru vertices that have arrival tags // that match path_group end paths. diff --git a/search/WorstSlack.cc b/search/WorstSlack.cc index a73e49b3..9fad2fbf 100644 --- a/search/WorstSlack.cc +++ b/search/WorstSlack.cc @@ -29,9 +29,9 @@ namespace sta { using std::min; WorstSlacks::WorstSlacks(StaState *sta) : + worst_slacks_(sta->corners()->pathAnalysisPtCount(), sta), sta_(sta) { - worst_slacks_.resize(sta->corners()->pathAnalysisPtCount()); } void @@ -46,7 +46,7 @@ WorstSlacks::worstSlack(const MinMax *min_max, PathAPIndex path_ap_index = corner->findPathAnalysisPt(min_max)->index(); Slack worst_slack1; Vertex *worst_vertex1; - worst_slacks_[path_ap_index].worstSlack(path_ap_index, sta_, + worst_slacks_[path_ap_index].worstSlack(path_ap_index, worst_slack1, worst_vertex1); if (delayLess(worst_slack1, worst_slack, sta_)) { worst_slack = worst_slack1; @@ -63,7 +63,7 @@ WorstSlacks::worstSlack(const Corner *corner, Vertex *&worst_vertex) { PathAPIndex path_ap_index = corner->findPathAnalysisPt(min_max)->index(); - worst_slacks_[path_ap_index].worstSlack(path_ap_index, sta_, + worst_slacks_[path_ap_index].worstSlack(path_ap_index, worst_slack, worst_vertex); } @@ -73,7 +73,7 @@ WorstSlacks::updateWorstSlacks(Vertex *vertex, { PathAPIndex path_ap_count = sta_->corners()->pathAnalysisPtCount(); for (PathAPIndex i = 0; i < path_ap_count; i++) - worst_slacks_[i].updateWorstSlack(vertex, slacks, i, sta_); + worst_slacks_[i].updateWorstSlack(vertex, slacks, i); } void @@ -88,21 +88,30 @@ WorstSlacks::worstSlackNotifyBefore(Vertex *vertex) //////////////////////////////////////////////////////////////// -WorstSlack::WorstSlack() : +WorstSlack::WorstSlack(StaState *sta) : + StaState(sta), slack_init_(MinMax::min()->initValue()), worst_vertex_(nullptr), worst_slack_(slack_init_), slack_threshold_(slack_init_), + queue_(new VertexSet(graph_)), min_queue_size_(10), max_queue_size_(20) { } -WorstSlack::WorstSlack(const WorstSlack &) : +WorstSlack::~WorstSlack() +{ + delete queue_; +} + +WorstSlack::WorstSlack(const WorstSlack &worst_slack) : + StaState(worst_slack), slack_init_(MinMax::min()->initValue()), worst_vertex_(nullptr), worst_slack_(slack_init_), slack_threshold_(slack_init_), + queue_(new VertexSet(graph_)), min_queue_size_(10), max_queue_size_(20) { @@ -116,214 +125,181 @@ WorstSlack::deleteVertexBefore(Vertex *vertex) worst_vertex_ = nullptr; worst_slack_ = slack_init_; } - queue_.erase(vertex); + queue_->erase(vertex); } void WorstSlack::worstSlack(PathAPIndex path_ap_index, - const StaState *sta, // Return values. Slack &worst_slack, Vertex *&worst_vertex) { - findWorstSlack(path_ap_index, sta); + findWorstSlack(path_ap_index); worst_slack = worst_slack_; worst_vertex = worst_vertex_; } void -WorstSlack::findWorstSlack(PathAPIndex path_ap_index, - const StaState *sta) +WorstSlack::findWorstSlack(PathAPIndex path_ap_index) { if (worst_vertex_ == nullptr) { - if (queue_.empty()) - initQueue(path_ap_index, sta); + if (queue_->empty()) + initQueue(path_ap_index); else - findWorstInQueue(path_ap_index, sta); + findWorstInQueue(path_ap_index); } } void -WorstSlack::initQueue(PathAPIndex path_ap_index, - const StaState *sta) +WorstSlack::initQueue(PathAPIndex path_ap_index) { - Search *search = sta->search(); - const Debug *debug = sta->debug(); - debugPrint(debug, "wns", 3, "init queue"); + debugPrint(debug_, "wns", 3, "init queue"); - queue_.clear(); + queue_->clear(); worst_vertex_ = nullptr; worst_slack_ = slack_init_; slack_threshold_ = slack_init_; - VertexSet::Iterator end_iter(search->endpoints()); - while (end_iter.hasNext()) { - Vertex *vertex = end_iter.next(); - Slack slack = search->wnsSlack(vertex, path_ap_index); + for(Vertex *vertex : *search_->endpoints()) { + Slack slack = search_->wnsSlack(vertex, path_ap_index); if (!delayEqual(slack, slack_init_)) { - if (delayLess(slack, worst_slack_, sta)) - setWorstSlack(vertex, slack, sta); - if (delayLessEqual(slack, slack_threshold_, sta)) - queue_.insert(vertex); - int queue_size = queue_.size(); + if (delayLess(slack, worst_slack_, this)) + setWorstSlack(vertex, slack); + if (delayLessEqual(slack, slack_threshold_, this)) + queue_->insert(vertex); + int queue_size = queue_->size(); if (queue_size >= max_queue_size_) - sortQueue(path_ap_index, sta); + sortQueue(path_ap_index); } } - debugPrint(debug, "wns", 3, "threshold %s", - delayAsString(slack_threshold_, sta)); + debugPrint(debug_, "wns", 3, "threshold %s", + delayAsString(slack_threshold_, this)); // checkQueue(); } void -WorstSlack::sortQueue(PathAPIndex path_ap_index, - const StaState *sta) +WorstSlack::sortQueue(PathAPIndex path_ap_index) { - if (queue_.size() > 0) { - Search *search = sta->search(); - const Debug *debug = sta->debug(); - debugPrint(debug, "wns", 3, "sort queue"); + if (queue_->size() > 0) { + debugPrint(debug_, "wns", 3, "sort queue"); VertexSeq vertices; - vertices.reserve(queue_.size()); - VertexSet::Iterator queue_iter(queue_); - while (queue_iter.hasNext()) { - Vertex *vertex = queue_iter.next(); + vertices.reserve(queue_->size()); + for (Vertex *vertex : *queue_) vertices.push_back(vertex); - } - WnsSlackLess slack_less(path_ap_index, sta); + WnsSlackLess slack_less(path_ap_index, this); sort(vertices, slack_less); int vertex_count = vertices.size(); int threshold_index = min(min_queue_size_, vertex_count - 1); Vertex *threshold_vertex = vertices[threshold_index]; - slack_threshold_ = search->wnsSlack(threshold_vertex, path_ap_index); - debugPrint(debug, "wns", 3, "threshold %s", - delayAsString(slack_threshold_, sta)); + slack_threshold_ = search_->wnsSlack(threshold_vertex, path_ap_index); + debugPrint(debug_, "wns", 3, "threshold %s", + delayAsString(slack_threshold_, this)); // Reinsert vertices with slack < threshold. - queue_.clear(); + queue_->clear(); VertexSeq::Iterator queue_iter2(vertices); while (queue_iter2.hasNext()) { Vertex *vertex = queue_iter2.next(); - Slack slack = search->wnsSlack(vertex, path_ap_index); - if (delayGreater(slack, slack_threshold_, sta)) + Slack slack = search_->wnsSlack(vertex, path_ap_index); + if (delayGreater(slack, slack_threshold_, this)) break; - queue_.insert(vertex); + queue_->insert(vertex); } - max_queue_size_ = queue_.size() * 2; + max_queue_size_ = queue_->size() * 2; Vertex *worst_slack_vertex = vertices[0]; - Slack worst_slack_slack = search->wnsSlack(worst_slack_vertex, path_ap_index); - setWorstSlack(worst_slack_vertex, worst_slack_slack, sta); + Slack worst_slack_slack = search_->wnsSlack(worst_slack_vertex, path_ap_index); + setWorstSlack(worst_slack_vertex, worst_slack_slack); } } void -WorstSlack::findWorstInQueue(PathAPIndex path_ap_index, - const StaState *sta) +WorstSlack::findWorstInQueue(PathAPIndex path_ap_index) { - Search *search = sta->search(); - const Debug *debug = sta->debug(); - debugPrint(debug, "wns", 3, "find worst in queue"); + debugPrint(debug_, "wns", 3, "find worst in queue"); worst_vertex_ = nullptr; worst_slack_ = slack_init_; - VertexSet::Iterator queue_iter(queue_); - while (queue_iter.hasNext()) { - Vertex *vertex = queue_iter.next(); - Slack slack = search->wnsSlack(vertex, path_ap_index); - if (delayLess(slack, worst_slack_, sta)) - setWorstSlack(vertex, slack, sta); + for (Vertex *vertex : *queue_) { + Slack slack = search_->wnsSlack(vertex, path_ap_index); + if (delayLess(slack, worst_slack_, this)) + setWorstSlack(vertex, slack); } } void -WorstSlack::checkQueue(PathAPIndex path_ap_index, - const StaState *sta) +WorstSlack::checkQueue(PathAPIndex path_ap_index) { - Search *search = sta->search(); - Report *report = sta->report(); - const Network *network = sta->network(); - VertexSeq ends; - VertexSet::Iterator end_iter(search->endpoints()); - while (end_iter.hasNext()) { - Vertex *end = end_iter.next(); - if (delayLessEqual(search->wnsSlack(end, path_ap_index), - slack_threshold_, sta)) + for(Vertex *end : *search_->endpoints()) { + if (delayLessEqual(search_->wnsSlack(end, path_ap_index), + slack_threshold_, this)) ends.push_back(end); } - WnsSlackLess slack_less(path_ap_index, sta); + WnsSlackLess slack_less(path_ap_index, this); sort(ends, slack_less); - VertexSet end_set; - VertexSeq::Iterator end_iter2(ends); - while (end_iter2.hasNext()) { - Vertex *end = end_iter2.next(); + VertexSet end_set(graph_); + for (Vertex *end : ends) { end_set.insert(end); - if (!queue_.hasKey(end) - && delayLessEqual(search->wnsSlack(end, path_ap_index), - slack_threshold_, sta)) - report->reportLine("WorstSlack queue missing %s %s < %s", - end->name(network), - delayAsString(search->wnsSlack(end, path_ap_index), sta), - delayAsString(slack_threshold_, sta)); + if (!queue_->hasKey(end) + && delayLessEqual(search_->wnsSlack(end, path_ap_index), + slack_threshold_, this)) + report_->reportLine("WorstSlack queue missing %s %s < %s", + end->name(network_), + delayAsString(search_->wnsSlack(end, path_ap_index), this), + delayAsString(slack_threshold_, this)); } - VertexSet::Iterator queue_iter(queue_); - while (queue_iter.hasNext()) { - Vertex *end = queue_iter.next(); + for (Vertex *end : *queue_) { if (!end_set.hasKey(end)) - report->reportLine("WorstSlack queue extra %s %s > %s", - end->name(network), - delayAsString(search->wnsSlack(end, path_ap_index), sta), - delayAsString(slack_threshold_, sta)); + report_->reportLine("WorstSlack queue extra %s %s > %s", + end->name(network_), + delayAsString(search_->wnsSlack(end, path_ap_index), this), + delayAsString(slack_threshold_, this)); } } void WorstSlack::updateWorstSlack(Vertex *vertex, SlackSeq &slacks, - PathAPIndex path_ap_index, - const StaState *sta) + PathAPIndex path_ap_index) { - const Debug *debug = sta->debug(); - const Network *network = sta->network(); Slack slack = slacks[path_ap_index]; // Locking is required because ArrivalVisitor is called by multiple // threads. UniqueLock lock(lock_); if (worst_vertex_ - && delayLess(slack, worst_slack_, sta)) - setWorstSlack(vertex, slack, sta); + && delayLess(slack, worst_slack_, this)) + setWorstSlack(vertex, slack); else if (vertex == worst_vertex_) // Mark worst slack as unknown (updated by findWorstSlack(). worst_vertex_ = nullptr; if (!delayEqual(slack, slack_init_) - && delayLessEqual(slack, slack_threshold_, sta)) { - debugPrint(debug, "wns", 3, "insert %s %s", - vertex->name(network), - delayAsString(slack, sta)); - queue_.insert(vertex); + && delayLessEqual(slack, slack_threshold_, this)) { + debugPrint(debug_, "wns", 3, "insert %s %s", + vertex->name(network_), + delayAsString(slack, this)); + queue_->insert(vertex); } else { - debugPrint(debug, "wns", 3, "delete %s %s", - vertex->name(network), - delayAsString(slack, sta)); - queue_.erase(vertex); + debugPrint(debug_, "wns", 3, "delete %s %s", + vertex->name(network_), + delayAsString(slack, this)); + queue_->erase(vertex); } // checkQueue(); } void WorstSlack::setWorstSlack(Vertex *vertex, - Slack slack, - const StaState *sta) + Slack slack) { - debugPrint(sta->debug(), "wns", 3, "%s %s", - vertex->name(sta->network()), - delayAsString(slack, sta)); + debugPrint(debug_, "wns", 3, "%s %s", + vertex->name(network_), + delayAsString(slack, this)); worst_vertex_ = vertex; worst_slack_ = slack; } diff --git a/search/WorstSlack.hh b/search/WorstSlack.hh index 57387bb4..bb6d52b5 100644 --- a/search/WorstSlack.hh +++ b/search/WorstSlack.hh @@ -22,6 +22,7 @@ #include "Vector.hh" #include "GraphClass.hh" #include "SearchClass.hh" +#include "StaState.hh" namespace sta { @@ -66,36 +67,29 @@ private: Search *search_; }; -class WorstSlack +class WorstSlack : public StaState { public: - WorstSlack(); + WorstSlack(StaState *sta); + ~WorstSlack(); WorstSlack(const WorstSlack &); void worstSlack(PathAPIndex path_ap_index, - const StaState *sta, // Return values. Slack &worst_slack, Vertex *&worst_vertex); void updateWorstSlack(Vertex *vertex, SlackSeq &slacks, - PathAPIndex path_ap_index, - const StaState *sta); + PathAPIndex path_ap_index); void deleteVertexBefore(Vertex *vertex); protected: - void findWorstSlack(PathAPIndex path_ap_index, - const StaState *sta); - void initQueue(PathAPIndex path_ap_index, - const StaState *sta); - void findWorstInQueue(PathAPIndex path_ap_index, - const StaState *sta); + void findWorstSlack(PathAPIndex path_ap_index); + void initQueue(PathAPIndex path_ap_index); + void findWorstInQueue(PathAPIndex path_ap_index); void setWorstSlack(Vertex *vertex, - Slack slack, - const StaState *sta); - void sortQueue(PathAPIndex path_ap_index, - const StaState *sta); - void checkQueue(PathAPIndex path_ap_index, - const StaState *sta); + Slack slack); + void sortQueue(PathAPIndex path_ap_index); + void checkQueue(PathAPIndex path_ap_index); Slack slack_init_; // Vertex with the worst slack. @@ -104,7 +98,7 @@ protected: Slack worst_slack_; Slack slack_threshold_; // Vertices with slack < threshold_ - VertexSet queue_; + VertexSet *queue_; // Queue is sorted and pruned to min_queue_size_ vertices when it // reaches max_queue_size_. int min_queue_size_;