From eab1f1cc019b354398b3ade59402b63f9e1c762f Mon Sep 17 00:00:00 2001 From: James Cherry Date: Sun, 12 Jun 2022 11:47:26 -0700 Subject: [PATCH] TimingArcSet::arcs() range iteration Signed-off-by: James Cherry --- dcalc/DelayCalc.tcl | 5 +--- dcalc/GraphDelayCalc1.cc | 16 +++-------- doc/ApiChanges.txt | 14 ++++++++++ graph/Graph.cc | 8 ++---- include/sta/Liberty.hh | 17 ------------ include/sta/TimingArc.hh | 9 ------- liberty/Liberty.cc | 49 ++++++++++++++++----------------- liberty/TimingArc.cc | 57 +++++++++++++++++++-------------------- sdf/SdfReader.cc | 12 +++------ sdf/SdfWriter.cc | 13 +++------ search/CheckMaxSkews.cc | 4 +-- search/FindRegister.cc | 3 +-- search/Latches.cc | 4 +-- search/MakeTimingModel.cc | 4 +-- search/Property.cc | 4 +-- search/Sta.cc | 4 +-- search/VisitPathEnds.cc | 8 ++---- tcl/Graph.tcl | 5 +--- tcl/Sta.tcl | 20 ++------------ tcl/StaTcl.i | 27 +++++++++---------- 20 files changed, 101 insertions(+), 182 deletions(-) diff --git a/dcalc/DelayCalc.tcl b/dcalc/DelayCalc.tcl index 5dbb9b98..33846ee9 100644 --- a/dcalc/DelayCalc.tcl +++ b/dcalc/DelayCalc.tcl @@ -87,9 +87,7 @@ proc report_edge_dcalc { edge corner min_max digits } { report_line "Arc sense: [$edge sense]" report_line "Arc type: $role" - set arc_iter [$edge timing_arc_iterator] - while {[$arc_iter has_next]} { - set arc [$arc_iter next] + foreach arc [$edge timing_arcs] { set from [get_name [$from_pin port]] set from_rf [$arc from_edge] set to [get_name [$to_pin port]] @@ -103,7 +101,6 @@ proc report_edge_dcalc { edge corner min_max digits } { report_line "............................................." report_line "" } - $arc_iter finish } } } diff --git a/dcalc/GraphDelayCalc1.cc b/dcalc/GraphDelayCalc1.cc index 2567cf1f..d9b5b5d0 100644 --- a/dcalc/GraphDelayCalc1.cc +++ b/dcalc/GraphDelayCalc1.cc @@ -753,9 +753,7 @@ GraphDelayCalc1::findInputDriverDelay(LibertyCell *drvr_cell, drvr_cell->name(), rf->asString()); for (TimingArcSet *arc_set : drvr_cell->timingArcSets(from_port, to_port)) { - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) { if (arc->toEdge()->asRiseFall() == rf) { float from_slew = from_slews[arc->fromEdge()->index()]; findInputArcDelay(drvr_cell, drvr_pin, drvr_vertex, @@ -1007,9 +1005,7 @@ GraphDelayCalc1::findDriverEdgeDelays(LibertyCell *drvr_cell, const Pvt *pvt = sdc_->pvt(drvr_inst, dcalc_ap->constraintMinMax()); if (pvt == nullptr) pvt = dcalc_ap->operatingConditions(); - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) { const RiseFall *rf = arc->toEdge()->asRiseFall(); Parasitic *parasitic = arc_delay_calc->findParasitic(drvr_pin, rf, dcalc_ap); @@ -1378,9 +1374,7 @@ GraphDelayCalc1::findMultiDrvrGateDelay(MultiDrvrNet *multi_drvr, Edge *edge1 = edge_iter.next(); TimingArcSet *arc_set1 = edge1->timingArcSet(); const LibertyPort *related_out_port = arc_set1->relatedOut(); - TimingArcSetArcIterator arc_iter(arc_set1); - while (arc_iter.hasNext()) { - TimingArc *arc1 = arc_iter.next(); + for (TimingArc *arc1 : arc_set1->arcs()) { RiseFall *drvr_rf1 = arc1->toEdge()->asRiseFall(); if (drvr_rf1 == drvr_rf) { Vertex *from_vertex1 = edge1->from(graph_); @@ -1520,9 +1514,7 @@ GraphDelayCalc1::findCheckEdgeDelays(Edge *edge, network_->portName(from_vertex->pin()), network_->portName(to_pin)); bool delay_changed = false; - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) { RiseFall *from_rf = arc->fromEdge()->asRiseFall(); RiseFall *to_rf = arc->toEdge()->asRiseFall(); if (from_rf && to_rf) { diff --git a/doc/ApiChanges.txt b/doc/ApiChanges.txt index b472de7e..681f6b8d 100644 --- a/doc/ApiChanges.txt +++ b/doc/ApiChanges.txt @@ -16,6 +16,20 @@ This file summarizes STA API changes for each release. +Release 2.3.1 2022/06/12 + +LibertyCellTimingArcSetIterator has been removed. +Use range iteration as shown below: + for (TimingArcSet *arc_set : cell->timingArcSets()) + for (TimingArcSet *arc_set : cell->timingArcSets(from, to)) + +TimingArcSetArcIterator has been removed. +Use range iteration as shown below: + for (TimingArc *arc : arc_set->arcs()) + +LibertyCellSequentialIterator has been removed. + for (Sequential *seq : cell->sequentials()) + Release 2.1.1 2020/12/13 Report::error, Report::warn functions now take a unique message ID as a first argument. InternalError has been renamed Report::cricical. diff --git a/graph/Graph.cc b/graph/Graph.cc index ce71f569..9257ba0c 100644 --- a/graph/Graph.cc +++ b/graph/Graph.cc @@ -873,9 +873,7 @@ Graph::removeDelayAnnotated(Edge *edge) { edge->setDelayAnnotationIsIncremental(false); TimingArcSet *arc_set = edge->timingArcSet(); - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) { for (DcalcAPIndex ap_index = 0; ap_index < ap_count_; ap_index++) { setArcDelayAnnotated(edge, arc, ap_index, false); } @@ -886,9 +884,7 @@ bool Graph::delayAnnotated(Edge *edge) { TimingArcSet *arc_set = edge->timingArcSet(); - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) { for (DcalcAPIndex ap_index = 0; ap_index < ap_count_; ap_index++) { if (arcDelayAnnotated(edge, arc, ap_index)) return true; diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index b8572693..3e4e6812 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -353,8 +353,6 @@ protected: private: friend class LibertyCell; friend class LibertyCellIterator; - friend class TableTemplateIterator; - friend class OperatingConditionsIterator; }; class LibertyCellIterator : public Iterator @@ -368,21 +366,6 @@ private: ConcreteCellMap::ConstIterator iter_; }; -class TableTemplateIterator : public TableTemplateMap::ConstIterator -{ -public: - TableTemplateIterator(const LibertyLibrary *library, - TableTemplateType type) : - TableTemplateMap::ConstIterator(library->template_maps_[int(type)]) {} -}; - -class OperatingConditionsIterator : public OperatingConditionsMap::ConstIterator -{ -public: - OperatingConditionsIterator(const LibertyLibrary *library) : - OperatingConditionsMap::ConstIterator(library->operating_conditions_) {} -}; - //////////////////////////////////////////////////////////////// class LibertyCell : public ConcreteCell diff --git a/include/sta/TimingArc.hh b/include/sta/TimingArc.hh index 8489c6f5..17073bc7 100644 --- a/include/sta/TimingArc.hh +++ b/include/sta/TimingArc.hh @@ -26,7 +26,6 @@ namespace sta { class TimingArcAttrs; class WireTimingArc; class WireTimingArcSetArcIterator; -class TimingArcSetArcIterator; typedef int TimingArcIndex; typedef Vector TimingArcSeq; @@ -157,8 +156,6 @@ public: TimingArc *&arc2) const; TimingArc *arcTo(const RiseFall *to_rf) const; const TimingArcSeq &arcs() const { return arcs_; } - // Use the TimingArcSetArcIterator(arc_set) constructor instead. - TimingArcSetArcIterator *timingArcIterator() __attribute__ ((deprecated)); TimingArcIndex addTimingArc(TimingArc *arc); void deleteTimingArc(TimingArc *arc); TimingArc *findTimingArc(unsigned arc_index); @@ -221,12 +218,6 @@ protected: static TimingArcSet *wire_timing_arc_set_; }; -class TimingArcSetArcIterator : public TimingArcSeq::ConstIterator -{ -public: - TimingArcSetArcIterator(const TimingArcSet *set); -}; - // A timing arc is a single from/to transition between two ports. // The timing model parameters used for delay calculation are also found here. class TimingArc diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index 8f97cad5..24985051 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -757,11 +757,14 @@ LibertyLibrary::makeCornerMap(LibertyCell *cell1, auto arc_set2 = cell2->findTimingArcSet(arc_set1); if (arc_set2) { if (link) { - TimingArcSetArcIterator arc_iter1(arc_set1); - TimingArcSetArcIterator arc_iter2(arc_set2); - while (arc_iter1.hasNext() && arc_iter2.hasNext()) { - TimingArc *arc1 = arc_iter1.next(); - TimingArc *arc2 = arc_iter2.next(); + const TimingArcSeq &arcs1 = arc_set1->arcs(); + const TimingArcSeq &arcs2 = arc_set2->arcs(); + auto arc_itr1 = arcs1.begin(), arc_itr2 = arcs2.begin(); + for (; + arc_itr1 != arcs1.end() && arc_itr2 != arcs2.end(); + arc_itr1++, arc_itr2++) { + TimingArc *arc1 = *arc_itr1; + TimingArc *arc2 = *arc_itr2; if (TimingArc::equiv(arc1, arc2)) arc1->setCornerArc(arc2, ap_index); } @@ -841,8 +844,7 @@ LibertyLibrary::supplyExists(const char *supply_name) const //////////////////////////////////////////////////////////////// -LibertyCellIterator::LibertyCellIterator(const LibertyLibrary * - library): +LibertyCellIterator::LibertyCellIterator(const LibertyLibrary *library) : iter_(library->cell_map_) { } @@ -1474,11 +1476,15 @@ LibertyCell::addScaledCell(OperatingConditions *op_cond, set_itr1++, set_itr2++) { TimingArcSet *arc_set1 = *set_itr1; TimingArcSet *arc_set2 = *set_itr2; - TimingArcSetArcIterator arc_iter1(arc_set1); - TimingArcSetArcIterator arc_iter2(arc_set2); - while (arc_iter1.hasNext() && arc_iter2.hasNext()) { - TimingArc *arc = arc_iter1.next(); - TimingArc *scaled_arc = arc_iter2.next(); + const TimingArcSeq &arcs1 = arc_set1->arcs(); + const TimingArcSeq &arcs2 = arc_set2->arcs(); + auto arc_itr1 = arcs1.begin(), arc_itr2 = arcs2.begin(); + for (; + arc_itr1 != arcs1.end() && arc_itr2 != arcs2.end(); + arc_itr1++, arc_itr2++) { + TimingArc *arc = *arc_itr1; + const TimingArc *scaled_arc = *arc_itr2; + if (TimingArc::equiv(arc, scaled_arc)) { TimingModel *model = scaled_arc->model(); model->setIsScaled(true); @@ -1638,7 +1644,6 @@ LibertyCell::makeLatchEnables(Report *report, if (en_to_q->role() == TimingRole::latchEnToQ()) { LibertyPort *en = en_to_q->from(); LibertyPort *q = en_to_q->to(); - for (TimingArcSet *d_to_q : timingArcSets(nullptr, q)) { if (d_to_q->role() == TimingRole::latchDtoQ()) { LibertyPort *d = d_to_q->from(); @@ -1648,13 +1653,11 @@ LibertyCell::makeLatchEnables(Report *report, en_to_q, setup_check, debug); - TimingArcSetArcIterator check_arc_iter(setup_check); - if (check_arc_iter.hasNext()) { - TimingArc *check_arc = check_arc_iter.next(); + for (TimingArc *check_arc : setup_check->arcs()) { RiseFall *en_rf = latch_enable->enableEdge(); RiseFall *check_rf = check_arc->fromEdge()->asRiseFall(); - if (check_rf == en_rf) { - report->warn(4, "cell %s/%s %s -> %s latch enable %s_edge timing arc is inconsistent with %s -> %s setup_%s check.", + if (check_rf == en_rf) + report->warn(4, "cell %s/%s %s -> %s latch enable %s_edge is inconsistent with %s -> %s setup_%s check.", library_->name(), name_, en->name(), @@ -1663,7 +1666,6 @@ LibertyCell::makeLatchEnables(Report *report, en->name(), d->name(), check_rf==RiseFall::rise()?"rising":"falling"); - } FuncExpr *en_func = latch_enable->enableFunc(); if (en_func) { TimingSense en_sense = en_func->portTimingSense(en); @@ -1684,7 +1686,6 @@ LibertyCell::makeLatchEnables(Report *report, q->name(), en_rf == RiseFall::rise()?"rising":"falling"); } - break; } } } @@ -2022,9 +2023,7 @@ LibertyPort::driveResistance(const RiseFall *rf, bool found_drive = false; for (TimingArcSet *arc_set : liberty_cell_->timingArcSets(nullptr, this)) { if (!arc_set->role()->isTimingCheck()) { - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) { if (rf == nullptr || arc->toEdge()->asRiseFall() == rf) { float drive = arc->driveResistance(); @@ -2058,9 +2057,7 @@ LibertyPort::intrinsicDelay(const RiseFall *rf, bool found_delay = false; for (TimingArcSet *arc_set : liberty_cell_->timingArcSets(nullptr, this)) { if (!arc_set->role()->isTimingCheck()) { - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) { if (rf == nullptr || arc->toEdge()->asRiseFall() == rf) { ArcDelay delay = arc->intrinsicDelay(); diff --git a/liberty/TimingArc.cc b/liberty/TimingArc.cc index 39d35fdf..bd502330 100644 --- a/liberty/TimingArc.cc +++ b/liberty/TimingArc.cc @@ -244,12 +244,6 @@ TimingArcSet::libertyCell() const return nullptr; } -TimingArcSetArcIterator * -TimingArcSet::timingArcIterator() -{ - return new TimingArcSetArcIterator(this); -} - TimingArcIndex TimingArcSet::addTimingArc(TimingArc *arc) { @@ -396,18 +390,23 @@ TimingArcSet::equiv(const TimingArcSet *set1, } static bool -timingArcsEquiv(const TimingArcSet *set1, - const TimingArcSet *set2) +timingArcsEquiv(const TimingArcSet *arc_set1, + const TimingArcSet *arc_set2) { - TimingArcSetArcIterator arc_iter1(set1); - TimingArcSetArcIterator arc_iter2(set2); - while (arc_iter1.hasNext() && arc_iter2.hasNext()) { - TimingArc *arc1 = arc_iter1.next(); - TimingArc *arc2 = arc_iter2.next(); + const TimingArcSeq &arcs1 = arc_set1->arcs(); + const TimingArcSeq &arcs2 = arc_set2->arcs(); + if (arcs1.size() != arcs2.size()) + return false; + auto arc_itr1 = arcs1.begin(), arc_itr2 = arcs2.begin(); + for (; + arc_itr1 != arcs1.end() && arc_itr2 != arcs2.end(); + arc_itr1++, arc_itr2++) { + const TimingArc *arc1 = *arc_itr1; + const TimingArc *arc2 = *arc_itr2; if (!TimingArc::equiv(arc1, arc2)) return false; } - return !arc_iter1.hasNext() && !arc_iter2.hasNext(); + return true; } bool @@ -478,14 +477,21 @@ timingArcSetLess(const TimingArcSet *set1, } static bool -timingArcsLess(const TimingArcSet *set1, - const TimingArcSet *set2) +timingArcsLess(const TimingArcSet *arc_set1, + const TimingArcSet *arc_set2) { - TimingArcSetArcIterator arc_iter1(set1); - TimingArcSetArcIterator arc_iter2(set2); - while (arc_iter1.hasNext() && arc_iter2.hasNext()) { - TimingArc *arc1 = arc_iter1.next(); - TimingArc *arc2 = arc_iter2.next(); + const TimingArcSeq &arcs1 = arc_set1->arcs(); + const TimingArcSeq &arcs2 = arc_set2->arcs(); + if (arcs1.size() < arcs2.size()) + return true; + if (arcs1.size() > arcs2.size()) + return false; + auto arc_itr1 = arcs1.begin(), arc_itr2 = arcs2.begin(); + for (; + arc_itr1 != arcs1.end() && arc_itr2 != arcs2.end(); + arc_itr1++, arc_itr2++) { + const TimingArc *arc1 = *arc_itr1; + const TimingArc *arc2 = *arc_itr2; int from_index1 = arc1->fromEdge()->index(); int from_index2 = arc2->fromEdge()->index(); if (from_index1 < from_index2) @@ -501,7 +507,7 @@ timingArcsLess(const TimingArcSet *set1, return false; // Continue if arc transitions are equal. } - return !arc_iter1.hasNext() && arc_iter2.hasNext(); + return false; } //////////////////////////////////////////////////////////////// @@ -531,13 +537,6 @@ TimingArcSet::destroy() //////////////////////////////////////////////////////////////// -TimingArcSetArcIterator::TimingArcSetArcIterator(const TimingArcSet *set) : - TimingArcSeq::ConstIterator(set->arcs()) -{ -} - -//////////////////////////////////////////////////////////////// - TimingArc::TimingArc(TimingArcSet *set, Transition *from_rf, Transition *to_rf, diff --git a/sdf/SdfReader.cc b/sdf/SdfReader.cc index fc880473..0815744e 100644 --- a/sdf/SdfReader.cc +++ b/sdf/SdfReader.cc @@ -270,9 +270,7 @@ SdfReader::setEdgeDelays(Edge *edge, if (triple_count == 1 || triple_count == 2) { TimingArcSet *arc_set = edge->timingArcSet(); - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) { size_t triple_index; if (triple_count == 1) triple_index = 0; @@ -379,9 +377,7 @@ SdfReader::iopath(SdfPortSpec *from_edge, // condelse matches the default (unconditional) arc. || (condelse && lib_cond == nullptr))) { matched = true; - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) { if ((from_edge->transition() == Transition::riseFall()) || (arc->fromEdge() == from_edge->transition())) { size_t triple_index = arc->toEdge()->sdfTripleIndex(); @@ -523,9 +519,7 @@ SdfReader::annotateCheckEdges(Pin *data_pin, && edge_role->genericRole() == sdf_role->genericRole())) && cond_matches) { TimingArcSet *arc_set = edge->timingArcSet(); - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) { if (((data_edge->transition() == Transition::riseFall()) || (arc->toEdge() == data_edge->transition())) && ((clk_edge->transition() == Transition::riseFall()) diff --git a/sdf/SdfWriter.cc b/sdf/SdfWriter.cc index 4159e260..e5055278 100644 --- a/sdf/SdfWriter.cc +++ b/sdf/SdfWriter.cc @@ -420,9 +420,7 @@ SdfWriter::writeArcDelays(Edge *edge) { RiseFallMinMax delays; TimingArcSet *arc_set = edge->timingArcSet(); - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) { RiseFall *rf = arc->toEdge()->asRiseFall(); ArcDelay min_delay = graph_->arcDelay(edge, arc, arc_delay_min_index_); delays.setValue(rf, MinMax::min(), delayAsFloat(min_delay)); @@ -577,9 +575,7 @@ SdfWriter::writeCheck(Edge *edge, // Examine the arcs to see if the check requires clk or data edge specifiers. TimingArc *arcs[RiseFall::index_count][RiseFall::index_count] = {{nullptr, nullptr}, {nullptr, nullptr}}; - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) { RiseFall *clk_rf = arc->fromEdge()->asRiseFall(); RiseFall *data_rf = arc->toEdge()->asRiseFall();; arcs[clk_rf->index()][data_rf->index()] = arc; @@ -593,11 +589,8 @@ SdfWriter::writeCheck(Edge *edge, writeEdgeCheck(edge, sdf_check, RiseFall::fallIndex(), arcs); else { // No special case; write all the checks with data and clock edge specifiers. - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) writeCheck(edge, arc, sdf_check, true, true); - } } } diff --git a/search/CheckMaxSkews.cc b/search/CheckMaxSkews.cc index b2e62d3c..e60ea1a6 100644 --- a/search/CheckMaxSkews.cc +++ b/search/CheckMaxSkews.cc @@ -186,9 +186,7 @@ CheckMaxSkews:: visitMaxSkewChecks(Vertex *vertex, if (edge->role() == TimingRole::skew()) { Vertex *ref_vertex = edge->from(graph); TimingArcSet *arc_set = edge->timingArcSet(); - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) { RiseFall *clk_rf = arc->fromEdge()->asRiseFall(); RiseFall *ref_rf = arc->toEdge()->asRiseFall(); VertexPathIterator clk_path_iter(vertex, clk_rf, clk_min_max, search); diff --git a/search/FindRegister.cc b/search/FindRegister.cc index 63e30b32..c58bc2d3 100644 --- a/search/FindRegister.cc +++ b/search/FindRegister.cc @@ -272,8 +272,7 @@ FindRegVisitor::findInferedSequential(LibertyCell *cell, bool matches = false; const RiseFall *clk_rf1 = clk_rf->asRiseFall(); for (TimingArcSet *arc_set : cell->timingArcSets()) { - TimingArcSetArcIterator arc_iter(arc_set); - TimingArc *arc = arc_iter.next(); + TimingArc *arc = *arc_set->arcs().begin(); RiseFall *arc_clk_rf = arc->fromEdge()->asRiseFall(); bool tr_matches = (clk_rf == RiseFallBoth::riseFall() || (arc_clk_rf == clk_rf1 diff --git a/search/Latches.cc b/search/Latches.cc index febeeb48..1e4d0ea8 100644 --- a/search/Latches.cc +++ b/search/Latches.cc @@ -422,9 +422,7 @@ Latches::latchSetupMargin(Vertex *data_vertex, && !edge->isDisabledCond() && !sdc_->isDisabledCondDefault(edge)) { TimingArcSet *arc_set = edge->timingArcSet(); - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *check_arc = arc_iter.next(); + for (TimingArc *check_arc : arc_set->arcs()) { if (check_arc->toEdge()->asRiseFall() == data_rf && check_arc->fromEdge()->asRiseFall() == disable_rf) return search_->deratedDelay(from_vertex, check_arc, edge, diff --git a/search/MakeTimingModel.cc b/search/MakeTimingModel.cc index 78193037..07e7ef24 100644 --- a/search/MakeTimingModel.cc +++ b/search/MakeTimingModel.cc @@ -490,9 +490,7 @@ MakeTimingModel::makeGateModelTable(const Pin *output_pin, if (drvr_port) { const LibertyCell *drvr_cell = drvr_port->libertyCell(); for (TimingArcSet *arc_set : drvr_cell->timingArcSets(nullptr, drvr_port)) { - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *drvr_arc = arc_iter.next(); + for (TimingArc *drvr_arc : arc_set->arcs()) { // Use the first timing arc to simplify life. if (drvr_arc->toEdge()->asRiseFall() == rf) { const LibertyPort *gate_in_port = drvr_arc->from(); diff --git a/search/Property.cc b/search/Property.cc index 14cf7dc5..6f32f1a5 100644 --- a/search/Property.cc +++ b/search/Property.cc @@ -937,9 +937,7 @@ edgeDelayProperty(Edge *edge, ArcDelay delay = 0.0; bool delay_exists = false; TimingArcSet *arc_set = edge->timingArcSet(); - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) { RiseFall *to_rf = arc->toEdge()->asRiseFall(); if (to_rf == rf) { for (auto corner : *sta->corners()) { diff --git a/search/Sta.cc b/search/Sta.cc index 0d3d0217..82a4e905 100644 --- a/search/Sta.cc +++ b/search/Sta.cc @@ -1659,9 +1659,7 @@ hasDisabledArcs(Edge *edge, Graph *graph) { TimingArcSet *arc_set = edge->timingArcSet(); - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *arc = arc_iter.next(); + for (TimingArc *arc : arc_set->arcs()) { if (!searchThru(edge, arc, graph)) return true; } diff --git a/search/VisitPathEnds.cc b/search/VisitPathEnds.cc index b6ae62f0..e636e1b2 100644 --- a/search/VisitPathEnds.cc +++ b/search/VisitPathEnds.cc @@ -146,9 +146,7 @@ VisitPathEnds::visitCheckEnd(const Pin *pin, if (checkEdgeEnabled(edge) && check_role->pathMinMax() == min_max) { TimingArcSet *arc_set = edge->timingArcSet(); - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *check_arc = arc_iter.next(); + for (TimingArc *check_arc : arc_set->arcs()) { RiseFall *clk_rf = check_arc->fromEdge()->asRiseFall(); if (check_arc->toEdge()->asRiseFall() == end_rf && clk_rf) { @@ -250,9 +248,7 @@ VisitPathEnds::visitCheckEndUnclked(const Pin *pin, if (checkEdgeEnabled(edge) && check_role->pathMinMax() == min_max) { TimingArcSet *arc_set = edge->timingArcSet(); - TimingArcSetArcIterator arc_iter(arc_set); - while (arc_iter.hasNext()) { - TimingArc *check_arc = arc_iter.next(); + for (TimingArc *check_arc : arc_set->arcs()) { RiseFall *clk_rf = check_arc->fromEdge()->asRiseFall(); if (check_arc->toEdge()->asRiseFall() == end_rf && clk_rf diff --git a/tcl/Graph.tcl b/tcl/Graph.tcl index bc727847..d38c96af 100644 --- a/tcl/Graph.tcl +++ b/tcl/Graph.tcl @@ -116,9 +116,7 @@ proc report_edge_ { edge vertex_from_name_proc vertex_to_name_proc } { report_line " Mode: $mode_name [$edge mode_value]" } - set iter [$edge timing_arc_iterator] - while {[$iter has_next]} { - set arc [$iter next] + foreach arc [$edge timing_arcs] { set delays [$edge arc_delay_strings $arc $sta_report_default_digits] set delays_fmt [format_delays $delays] set disable_reason "" @@ -127,7 +125,6 @@ proc report_edge_ { edge vertex_from_name_proc vertex_to_name_proc } { } report_line " [$arc from_edge] -> [$arc to_edge] $delays_fmt$disable_reason" } - $iter finish } # Separate list elements with colons. diff --git a/tcl/Sta.tcl b/tcl/Sta.tcl index abbe87f7..f40ab78f 100644 --- a/tcl/Sta.tcl +++ b/tcl/Sta.tcl @@ -717,15 +717,12 @@ proc set_assigned_delay2 {from_vertex to_vertex to_rf corner min_max delay} { set edge [$edge_iter next] if { [$edge to] == $to_vertex \ && ![timing_role_is_check [$edge role]] } { - set arc_iter [$edge timing_arc_iterator] - while {[$arc_iter has_next]} { - set arc [$arc_iter next] + foreach arc [$edge timing_arcs] { if { $to_rf == "rise_fall" \ || $to_rf eq [$arc to_edge_name] } { set_arc_delay $edge $arc $corner $min_max $delay } } - $arc_iter finish } } $edge_iter finish @@ -829,9 +826,7 @@ proc set_assigned_check2 { from_vertex from_rf to_vertex to_rf \ while {[$edge_iter has_next]} { set edge [$edge_iter next] if { [$edge to] == $to_vertex } { - set arc_iter [$edge timing_arc_iterator] - while {[$arc_iter has_next]} { - set arc [$arc_iter next] + foreach arc [$edge timing_arcs] { if { ($from_rf eq "rise_fall" \ || $from_rf eq [$arc from_edge_name]) \ && ($to_rf eq "rise_fall" \ @@ -841,7 +836,6 @@ proc set_assigned_check2 { from_vertex from_rf to_vertex to_rf \ set_arc_delay $edge $arc $corner $min_max $check_value } } - $arc_iter finish } } $edge_iter finish @@ -1294,16 +1288,6 @@ proc instance_edges { inst } { return $edges } -proc libcell_timing_arc_sets { libcell } { - set arc_sets {} - set arc_iter [$libcell timing_arc_set_iterator] - while { [$arc_iter has_next] } { - lappend arc_sets [$arc_iter next] - } - $arc_iter finish - return $arc_sets -} - proc get_timing_arcs_from_to { from_pin_arg to_pin_arg } { set edges {} set from_pin [get_port_pin_error "from" $from_pin_arg] diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index c5d97b45..6addfdb0 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -586,6 +586,16 @@ using namespace sta; Tcl_SetObjResult(interp, list); } +%typemap(out) const TimingArcSeq& { + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); + const TimingArcSeq *arcs = $1; + for (TimingArc *arc : *arcs) { + Tcl_Obj *obj = SWIG_NewInstanceObj(arc, SWIGTYPE_p_TimingArc, false); + Tcl_ListObjAppendElement(interp, list, obj); + } + Tcl_SetObjResult(interp, list); +} + %typemap(out) Wireload* { Tcl_Obj *obj = SWIG_NewInstanceObj($1, $1_descriptor, false); Tcl_SetObjResult(interp, obj); @@ -1649,13 +1659,6 @@ private: ~TimingArcSet(); }; -class TimingArcSetArcIterator -{ -private: - TimingArcSetArcIterator(); - ~TimingArcSetArcIterator(); -}; - class TimingArc { private: @@ -5822,12 +5825,6 @@ const char *to_edge_name() { return self->toEdge()->asRiseFall()->name(); } TimingRole *role() { return self->role(); } } // TimingArc methods -%extend TimingArcSetArcIterator { -bool has_next() { return self->hasNext(); } -TimingArc *next() { return self->next(); } -void finish() { delete self; } -} - %extend Instance { Instance *parent() { return cmdLinkedNetwork()->parent(self); } Cell *cell() { return cmdLinkedNetwork()->cell(self); } @@ -6215,8 +6212,8 @@ Pin *from_pin() { return self->from(Sta::sta()->graph())->pin(); } Pin *to_pin() { return self->to(Sta::sta()->graph())->pin(); } TimingRole *role() { return self->role(); } const char *sense() { return timingSenseString(self->sense()); } -TimingArcSetArcIterator * -timing_arc_iterator() { return new TimingArcSetArcIterator(self->timingArcSet()); } +const TimingArcSeq & +timing_arcs() { return self->timingArcSet()->arcs(); } bool is_disabled_loop() { return Sta::sta()->isDisabledLoop(self); } bool is_disabled_constraint() { return Sta::sta()->isDisabledConstraint(self);} bool is_disabled_constant() { return Sta::sta()->isDisabledConstant(self); }