diff --git a/dcalc/GraphDelayCalc1.cc b/dcalc/GraphDelayCalc1.cc index 297bdf54..2567cf1f 100644 --- a/dcalc/GraphDelayCalc1.cc +++ b/dcalc/GraphDelayCalc1.cc @@ -710,9 +710,7 @@ GraphDelayCalc1::driveCellDefaultFromPort(LibertyCell *cell, { LibertyPort *from_port = 0; int from_port_index = 0; - LibertyCellTimingArcSetIterator set_iter(cell, nullptr, to_port); - while (set_iter.hasNext()) { - TimingArcSet *arc_set = set_iter.next(); + for (TimingArcSet *arc_set : cell->timingArcSets(nullptr, to_port)) { LibertyPort *set_from_port = arc_set->from(); int set_from_port_index = findPortIndex(cell, set_from_port); if (from_port == nullptr @@ -754,9 +752,7 @@ GraphDelayCalc1::findInputDriverDelay(LibertyCell *drvr_cell, debugPrint(debug_, "delay_calc", 2, " driver cell %s %s", drvr_cell->name(), rf->asString()); - LibertyCellTimingArcSetIterator set_iter(drvr_cell, from_port, to_port); - while (set_iter.hasNext()) { - TimingArcSet *arc_set = set_iter.next(); + 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(); diff --git a/graph/Graph.cc b/graph/Graph.cc index 3181cd9d..ce71f569 100644 --- a/graph/Graph.cc +++ b/graph/Graph.cc @@ -185,9 +185,7 @@ Graph::makePortInstanceEdges(const Instance *inst, LibertyCell *cell, LibertyPort *from_to_port) { - LibertyCellTimingArcSetIterator timing_iter(cell); - while (timing_iter.hasNext()) { - TimingArcSet *arc_set = timing_iter.next(); + for (TimingArcSet *arc_set : cell->timingArcSets()) { LibertyPort *from_port = arc_set->from(); LibertyPort *to_port = arc_set->to(); if ((from_to_port == nullptr diff --git a/include/sta/Liberty.hh b/include/sta/Liberty.hh index 9e829504..f35ad33d 100644 --- a/include/sta/Liberty.hh +++ b/include/sta/Liberty.hh @@ -424,9 +424,10 @@ public: bool isClockGateOther() const; bool isClockGate() const; void setClockGateType(ClockGateType type); + const TimingArcSetSeq &timingArcSets() const { return timing_arc_sets_; } // from or to may be nullptr to wildcard. - TimingArcSetSeq *timingArcSets(const LibertyPort *from, - const LibertyPort *to) const; + const TimingArcSetSeq &timingArcSets(const LibertyPort *from, + const LibertyPort *to) const; size_t timingArcSetCount() const; // Find a timing arc set equivalent to key. TimingArcSet *findTimingArcSet(TimingArcSet *key) const; @@ -583,7 +584,6 @@ private: friend class LibertyCellPgPortIterator; friend class LibertyPort; friend class LibertyBuilder; - friend class LibertyCellTimingArcSetIterator; friend class LibertyCellSequentialIterator; }; @@ -621,16 +621,6 @@ private: LibertyPgPortMap::Iterator iter_; }; -class LibertyCellTimingArcSetIterator : public TimingArcSetSeq::ConstIterator -{ -public: - LibertyCellTimingArcSetIterator(const LibertyCell *cell); - // from or to may be nullptr to wildcard. - LibertyCellTimingArcSetIterator(const LibertyCell *cell, - const LibertyPort *from, - const LibertyPort *to); -}; - class LibertyCellSequentialIterator : public SequentialSeq::ConstIterator { public: diff --git a/liberty/EquivCells.cc b/liberty/EquivCells.cc index 6373ef41..dcde932a 100644 --- a/liberty/EquivCells.cc +++ b/liberty/EquivCells.cc @@ -355,11 +355,9 @@ equivCellTimingArcSets(const LibertyCell *cell1, if (cell1->timingArcSetCount() != cell2->timingArcSetCount()) return false; else { - LibertyCellTimingArcSetIterator set_iter1(cell1); - while (set_iter1.hasNext()) { - TimingArcSet *set1 = set_iter1.next(); - TimingArcSet *set2 = cell2->findTimingArcSet(set1); - if (!(set2 && TimingArcSet::equiv(set1, set2))) + for (TimingArcSet *arc_set1 : cell1->timingArcSets()) { + TimingArcSet *arc_set2 = cell2->findTimingArcSet(arc_set1); + if (!(arc_set2 && TimingArcSet::equiv(arc_set1, arc_set2))) return false; } return true; diff --git a/liberty/Liberty.cc b/liberty/Liberty.cc index d05a7647..8f97cad5 100644 --- a/liberty/Liberty.cc +++ b/liberty/Liberty.cc @@ -1353,20 +1353,26 @@ LibertyCell::makeTimingArcPortMaps() } } -TimingArcSetSeq * +const TimingArcSetSeq & LibertyCell::timingArcSets(const LibertyPort *from, const LibertyPort *to) const { + TimingArcSetSeq *arc_sets = nullptr; if (from && to) { LibertyPortPair port_pair(from, to); - return port_timing_arc_set_map_.findKey(port_pair); + arc_sets = port_timing_arc_set_map_.findKey(port_pair); } else if (from) - return timing_arc_set_from_map_.findKey(from); + arc_sets = timing_arc_set_from_map_.findKey(from); else if (to) - return timing_arc_set_to_map_.findKey(to); - else - return nullptr; + arc_sets = timing_arc_set_to_map_.findKey(to); + + if (arc_sets) + return *arc_sets; + else { + static TimingArcSetSeq null_set; + return null_set; + } } TimingArcSet * @@ -1461,11 +1467,13 @@ LibertyCell::addScaledCell(OperatingConditions *op_cond, port->addScaledPort(op_cond, scaled_port); } - LibertyCellTimingArcSetIterator set_iter1(this); - LibertyCellTimingArcSetIterator set_iter2(scaled_cell); - while (set_iter1.hasNext() && set_iter2.hasNext()) { - TimingArcSet *arc_set1 = set_iter1.next(); - TimingArcSet *arc_set2 = set_iter2.next(); + const TimingArcSetSeq &arc_sets1 = this->timingArcSets(); + const TimingArcSetSeq &arc_sets2 = scaled_cell->timingArcSets(); + for (auto set_itr1 = arc_sets1.begin(), set_itr2 = arc_sets2.begin(); + set_itr1 != arc_sets1.end() && set_itr2 != arc_sets2.end(); + 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()) { @@ -1566,20 +1574,6 @@ LibertyCell::addOcvDerate(OcvDerate *derate) //////////////////////////////////////////////////////////////// -LibertyCellTimingArcSetIterator::LibertyCellTimingArcSetIterator(const LibertyCell *cell) : - TimingArcSetSeq::ConstIterator(&cell->timing_arc_sets_) -{ -} - -LibertyCellTimingArcSetIterator::LibertyCellTimingArcSetIterator(const LibertyCell *cell, - const LibertyPort *from, - const LibertyPort *to): - TimingArcSetSeq::ConstIterator(cell->timingArcSets(from, to)) -{ -} - -//////////////////////////////////////////////////////////////// - // Latch enable port/function for a latch D->Q timing arc set. class LatchEnable { @@ -1644,14 +1638,11 @@ LibertyCell::makeLatchEnables(Report *report, if (en_to_q->role() == TimingRole::latchEnToQ()) { LibertyPort *en = en_to_q->from(); LibertyPort *q = en_to_q->to(); - LibertyCellTimingArcSetIterator to_iter(this, nullptr, q); - while (to_iter.hasNext()) { - TimingArcSet *d_to_q = to_iter.next(); + + for (TimingArcSet *d_to_q : timingArcSets(nullptr, q)) { if (d_to_q->role() == TimingRole::latchDtoQ()) { LibertyPort *d = d_to_q->from(); - LibertyCellTimingArcSetIterator check_iter(this, en, d); - while (check_iter.hasNext()) { - TimingArcSet *setup_check = check_iter.next(); + for (TimingArcSet *setup_check : timingArcSets(en, d)) { if (setup_check->role() == TimingRole::setup()) { LatchEnable *latch_enable = makeLatchEnable(d, en, q, d_to_q, en_to_q, @@ -1749,16 +1740,12 @@ LibertyCell::inferLatchRoles(Debug *debug) if (hasInferedRegTimingArcs()) { // Hunt down potential latch D/EN/Q triples. LatchEnableSet latch_enables; - LibertyCellTimingArcSetIterator set_iter(this); - while (set_iter.hasNext()) { - TimingArcSet *en_to_q = set_iter.next(); + for (TimingArcSet *en_to_q : timingArcSets()) { // Locate potential d->q arcs from reg clk->q arcs. if (en_to_q->role() == TimingRole::regClkToQ()) { LibertyPort *en = en_to_q->from(); LibertyPort *q = en_to_q->to(); - LibertyCellTimingArcSetIterator to_iter(this, nullptr, q); - while (to_iter.hasNext()) { - TimingArcSet *d_to_q = to_iter.next(); + for (TimingArcSet *d_to_q : timingArcSets(nullptr, q)) { // Look for combinational d->q arcs. TimingRole *d_to_q_role = d_to_q->role(); if ((d_to_q_role == TimingRole::combinational() @@ -1770,9 +1757,7 @@ LibertyCell::inferLatchRoles(Debug *debug) || d_to_q_role == TimingRole::latchDtoQ()) { LibertyPort *d = d_to_q->from(); // Check for setup check from en -> d. - LibertyCellTimingArcSetIterator check_iter(this, en, d); - while (check_iter.hasNext()) { - TimingArcSet *setup_check = check_iter.next(); + for (TimingArcSet *setup_check : timingArcSets(en, d)) { if (setup_check->role() == TimingRole::setup()) { makeLatchEnable(d, en, q, d_to_q, en_to_q, setup_check, debug); d_to_q->setRole(TimingRole::latchDtoQ()); @@ -2035,11 +2020,9 @@ LibertyPort::driveResistance(const RiseFall *rf, { float max_drive = min_max->initValue(); bool found_drive = false; - LibertyCellTimingArcSetIterator set_iter(liberty_cell_, nullptr, this); - while (set_iter.hasNext()) { - TimingArcSet *set = set_iter.next(); - if (!set->role()->isTimingCheck()) { - TimingArcSetArcIterator arc_iter(set); + 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(); if (rf == nullptr @@ -2073,11 +2056,9 @@ LibertyPort::intrinsicDelay(const RiseFall *rf, { ArcDelay max_delay = min_max->initValue(); bool found_delay = false; - LibertyCellTimingArcSetIterator set_iter(liberty_cell_, nullptr, this); - while (set_iter.hasNext()) { - TimingArcSet *set = set_iter.next(); - if (!set->role()->isTimingCheck()) { - TimingArcSetArcIterator arc_iter(set); + 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(); if (rf == nullptr diff --git a/liberty/LibertyWriter.cc b/liberty/LibertyWriter.cc index 87833b1a..1643b554 100644 --- a/liberty/LibertyWriter.cc +++ b/liberty/LibertyWriter.cc @@ -354,12 +354,8 @@ LibertyWriter::writePortAttrs(const LibertyPort *port) fprintf(stream_, " max_capacitance : %s;\n", cap_unit_->asString(limit, 3)); - LibertyCellTimingArcSetIterator set_iter(port->libertyCell(), - nullptr, port); - while (set_iter.hasNext()) { - const TimingArcSet *arc_set = set_iter.next(); + for (TimingArcSet *arc_set : port->libertyCell()->timingArcSets(nullptr,port)) writeTimingArcSet(arc_set); - } } void diff --git a/sdc/Sdc.cc b/sdc/Sdc.cc index a74f0599..96c9d90f 100644 --- a/sdc/Sdc.cc +++ b/sdc/Sdc.cc @@ -382,11 +382,8 @@ Sdc::removeLibertyAnnotations() LibertyPortPair *pair = from_to_iter.next(); const LibertyPort *from = pair->first; const LibertyPort *to = pair->second; - LibertyCellTimingArcSetIterator arc_iter(cell, from, to); - while (arc_iter.hasNext()) { - TimingArcSet *arc_set = arc_iter.next(); + for (TimingArcSet *arc_set : cell->timingArcSets(from, to)) arc_set->setIsDisabledConstraint(false); - } } } @@ -3408,11 +3405,8 @@ Sdc::disable(LibertyCell *cell, } if (from && to) { disabled_cell->setDisabledFromTo(from, to); - LibertyCellTimingArcSetIterator arc_iter(cell, from, to); - while (arc_iter.hasNext()) { - TimingArcSet *arc_set = arc_iter.next(); + for (TimingArcSet *arc_set : cell->timingArcSets(from, to)) arc_set->setIsDisabledConstraint(true); - } } else if (from) { disabled_cell->setDisabledFrom(from); @@ -3437,11 +3431,8 @@ Sdc::removeDisable(LibertyCell *cell, if (disabled_cell) { if (from && to) { disabled_cell->removeDisabledFromTo(from, to); - LibertyCellTimingArcSetIterator arc_iter(cell, from, to); - while (arc_iter.hasNext()) { - TimingArcSet *arc_set = arc_iter.next(); - arc_set->setIsDisabledConstraint(false); - } + for (TimingArcSet *arc_set : cell->timingArcSets(from, to)) + arc_set->setIsDisabledConstraint(false); } else if (from) { disabled_cell->removeDisabledFrom(from); @@ -3884,10 +3875,8 @@ Sdc::exceptionToInvalid(const Pin *pin) LibertyPort *port = network_->libertyPort(pin); if (port) { LibertyCell *cell = port->libertyCell(); - LibertyCellTimingArcSetIterator set_iter(cell, nullptr, port); - while (set_iter.hasNext()) { - TimingArcSet *set = set_iter.next(); - TimingRole *role = set->role(); + for (TimingArcSet *arc_set : cell->timingArcSets(nullptr, port)) { + TimingRole *role = arc_set->role(); if (role->genericRole() == TimingRole::regClkToQ()) return true; } @@ -4050,9 +4039,7 @@ Sdc::hasLibertyChecks(const Pin *pin) if (cell) { LibertyPort *port = network_->libertyPort(pin); if (port) { - LibertyCellTimingArcSetIterator timing_iter(cell, nullptr, port); - while (timing_iter.hasNext()) { - TimingArcSet *arc_set = timing_iter.next(); + for (TimingArcSet *arc_set : cell->timingArcSets(nullptr, port)) { if (arc_set->role()->isTimingCheck()) return true; } diff --git a/search/FindRegister.cc b/search/FindRegister.cc index 30208a30..983d4703 100644 --- a/search/FindRegister.cc +++ b/search/FindRegister.cc @@ -273,10 +273,8 @@ FindRegVisitor::findInferedSequential(LibertyCell *cell, { bool matches = false; const RiseFall *clk_rf1 = clk_rf->asRiseFall(); - LibertyCellTimingArcSetIterator set_iter(cell); - while (set_iter.hasNext()) { - TimingArcSet *set = set_iter.next(); - TimingArcSetArcIterator arc_iter(set); + for (TimingArcSet *arc_set : cell->timingArcSets()) { + TimingArcSetArcIterator arc_iter(arc_set); TimingArc *arc = arc_iter.next(); RiseFall *arc_clk_rf = arc->fromEdge()->asRiseFall(); bool tr_matches = (clk_rf == RiseFallBoth::riseFall() @@ -284,7 +282,7 @@ FindRegVisitor::findInferedSequential(LibertyCell *cell, && clk_sense == TimingSense::positive_unate) || (arc_clk_rf == clk_rf1->opposite() && clk_sense == TimingSense::negative_unate)); - TimingRole *role = set->role(); + TimingRole *role = arc_set->role(); if (tr_matches && ((role == TimingRole::regClkToQ() && edge_triggered) @@ -302,10 +300,8 @@ FindRegVisitor::hasTimingCheck(LibertyCell *cell, LibertyPort *clk, LibertyPort *d) { - LibertyCellTimingArcSetIterator set_iter(cell, clk, d); - while (set_iter.hasNext()) { - TimingArcSet *set = set_iter.next(); - TimingRole *role = set->role(); + for (TimingArcSet *arc_set : cell->timingArcSets(clk, d)) { + TimingRole *role = arc_set->role(); if (role->isTimingCheck()) return true; } @@ -541,10 +537,8 @@ FindRegClkPins::matchPin(Pin *pin) { LibertyPort *port = network_->libertyPort(pin); LibertyCell *cell = port->libertyCell(); - LibertyCellTimingArcSetIterator set_iter(cell, port, nullptr); - while (set_iter.hasNext()) { - TimingArcSet *set = set_iter.next(); - TimingRole *role = set->role(); + for (TimingArcSet *arc_set : cell->timingArcSets(port, nullptr)) { + TimingRole *role = arc_set->role(); if (role->isTimingCheck()) return true; } @@ -598,10 +592,8 @@ FindRegAsyncPins::matchPin(Pin *pin) { LibertyPort *port = network_->libertyPort(pin); LibertyCell *cell = port->libertyCell(); - LibertyCellTimingArcSetIterator set_iter(cell, port, nullptr); - while (set_iter.hasNext()) { - TimingArcSet *set = set_iter.next(); - TimingRole *role = set->role(); + for (TimingArcSet *arc_set : cell->timingArcSets(port, nullptr)) { + TimingRole *role = arc_set->role(); if (role == TimingRole::regSetClr()) return true; } @@ -647,10 +639,8 @@ FindRegOutputPins::matchPin(Pin *pin) { LibertyPort *port = network_->libertyPort(pin); LibertyCell *cell = port->libertyCell(); - LibertyCellTimingArcSetIterator set_iter(cell, nullptr, port); - while (set_iter.hasNext()) { - TimingArcSet *set = set_iter.next(); - TimingRole *role = set->role(); + for (TimingArcSet *arc_set : cell->timingArcSets(nullptr, port)) { + TimingRole *role = arc_set->role(); if (role == TimingRole::regClkToQ() || role == TimingRole::latchEnToQ() || role == TimingRole::latchDtoQ()) diff --git a/search/MakeTimingModel.cc b/search/MakeTimingModel.cc index 5c053da6..78193037 100644 --- a/search/MakeTimingModel.cc +++ b/search/MakeTimingModel.cc @@ -489,9 +489,7 @@ MakeTimingModel::makeGateModelTable(const Pin *output_pin, const LibertyPort *drvr_port = network_->libertyPort(drvr_pin); if (drvr_port) { const LibertyCell *drvr_cell = drvr_port->libertyCell(); - LibertyCellTimingArcSetIterator set_iter(drvr_cell, nullptr, drvr_port); - while (set_iter.hasNext()) { - TimingArcSet *arc_set = set_iter.next(); + 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(); diff --git a/search/Power.cc b/search/Power.cc index 845b6e36..f4b82a95 100644 --- a/search/Power.cc +++ b/search/Power.cc @@ -911,9 +911,9 @@ isPositiveUnate(const LibertyCell *cell, const LibertyPort *from, const LibertyPort *to) { - TimingArcSetSeq *arc_sets = cell->timingArcSets(from, to); - if (arc_sets && !arc_sets->empty()) { - TimingSense sense = (*arc_sets)[0]->sense(); + const TimingArcSetSeq &arc_sets = cell->timingArcSets(from, to); + if (!arc_sets.empty()) { + TimingSense sense = arc_sets[0]->sense(); return sense == TimingSense::positive_unate || sense == TimingSense::non_unate; } diff --git a/search/Sim.cc b/search/Sim.cc index b49400e0..493eecc2 100644 --- a/search/Sim.cc +++ b/search/Sim.cc @@ -1244,10 +1244,8 @@ isCondDisabled(Edge *edge, LibertyCell *cell = network->libertyCell(inst); LibertyPort *from_port = network->libertyPort(from_pin); LibertyPort *to_port = network->libertyPort(to_pin); - LibertyCellTimingArcSetIterator cond_iter(cell, from_port, to_port); is_disabled = false; - while (cond_iter.hasNext()) { - TimingArcSet *cond_set = cond_iter.next(); + for (TimingArcSet *cond_set : cell->timingArcSets(from_port, to_port)) { FuncExpr *cond = cond_set->cond(); if (cond && sim->evalExpr(cond, inst) == LogicValue::one) { disable_cond = cond; diff --git a/tcl/Sta.tcl b/tcl/Sta.tcl index 6b702e90..abbe87f7 100644 --- a/tcl/Sta.tcl +++ b/tcl/Sta.tcl @@ -1268,7 +1268,7 @@ proc get_timing_arcs_objects { object_arg } { } elseif { $libcells != {} } { set arc_sets {} foreach libcell $libcells { - lappend arc_sets [libcell_timing_arc_sets $libcell] + lappend arc_sets [$libcell timing_arc_sets] } return $arc_sets } diff --git a/tcl/StaTcl.i b/tcl/StaTcl.i index 550216ef..c5d97b45 100644 --- a/tcl/StaTcl.i +++ b/tcl/StaTcl.i @@ -576,6 +576,16 @@ using namespace sta; Tcl_SetObjResult(interp, obj); } +%typemap(out) const TimingArcSetSeq& { + Tcl_Obj *list = Tcl_NewListObj(0, nullptr); + const TimingArcSetSeq *arc_sets = $1; + for (TimingArcSet *arc_set : *arc_sets) { + Tcl_Obj *obj = SWIG_NewInstanceObj(arc_set, SWIGTYPE_p_TimingArcSet, 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); @@ -1238,16 +1248,6 @@ using namespace sta; Tcl_SetObjResult(interp, obj); } -%typemap(out) TimingArcSetArcIterator* { - Tcl_Obj *obj=SWIG_NewInstanceObj($1, $1_descriptor, false); - Tcl_SetObjResult(interp, obj); -} - -%typemap(out) LibertyCellTimingArcSetIterator* { - Tcl_Obj *obj=SWIG_NewInstanceObj($1, $1_descriptor, false); - Tcl_SetObjResult(interp, obj); -} - %typemap(out) CheckErrorSeq & { Tcl_Obj *error_list = Tcl_NewListObj(0, nullptr); CheckErrorSeq *check_errors = $1; @@ -1649,13 +1649,6 @@ private: ~TimingArcSet(); }; -class LibertyCellTimingArcSetIterator -{ -private: - LibertyCellTimingArcSetIterator(); - ~LibertyCellTimingArcSetIterator(); -}; - class TimingArcSetArcIterator { private: @@ -5714,8 +5707,11 @@ find_liberty_ports_matching(const char *pattern, LibertyCellPortIterator * liberty_port_iterator() { return new LibertyCellPortIterator(self); } -LibertyCellTimingArcSetIterator * -timing_arc_set_iterator() { return new LibertyCellTimingArcSetIterator(self); } +const TimingArcSetSeq & +timing_arc_sets() +{ + return self->timingArcSets(); +} } // LibertyCell methods @@ -5816,12 +5812,6 @@ full_name() } // TimingArcSet methods -%extend LibertyCellTimingArcSetIterator { -bool has_next() { return self->hasNext(); } -TimingArcSet *next() { return self->next(); } -void finish() { delete self; } -} - %extend TimingArc { LibertyPort *from() { return self->from(); } LibertyPort *to() { return self->to(); }