@@ -452,32 +452,26 @@ bool SetupLegacyBase::makePinTargetOnPath(const sta::Pin* pin,
452452 return false ;
453453 }
454454
455+ // Search the main path first, then the latch D fanin path of a
456+ // latch-through path.
455457 sta::PathExpanded expanded (path, sta_);
456- if (makePinTargetInExpandedPath (pin, path, expanded, focus_slack, target)) {
457- return true ;
458- }
459-
460- const sta::Path* d_path = latchDataPath (expanded, sta_);
461- if (d_path == nullptr ) {
462- return false ;
463- }
464-
465- sta::PathExpanded d_expanded (d_path, sta_);
466- return makePinTargetInExpandedPath (
467- pin, d_path, d_expanded, focus_slack, target);
458+ return visitPathSegments (
459+ path,
460+ expanded,
461+ sta_,
462+ [&](const sta::Path* seg_path, sta::PathExpanded& seg_expanded) {
463+ return makePinTargetInExpandedPath (
464+ pin, vertex, seg_path, seg_expanded, focus_slack, target);
465+ });
468466}
469467
470468bool SetupLegacyBase::makePinTargetInExpandedPath (const sta::Pin* pin,
469+ sta::Vertex* vertex,
471470 const sta::Path* path,
472471 sta::PathExpanded& expanded,
473472 const sta::Slack focus_slack,
474473 Target& target) const
475474{
476- sta::Vertex* vertex = graph_->pinDrvrVertex (pin);
477- if (vertex == nullptr ) {
478- return false ;
479- }
480-
481475 const int start_index = static_cast <int >(expanded.startIndex ());
482476 const int path_count = static_cast <int >(expanded.size ());
483477 for (int index = start_index; index < path_count; index++) {
@@ -754,51 +748,46 @@ bool SetupLegacyBase::repairPath(sta::Path* path,
754748 return false ;
755749 }
756750
757- const sta::Scene* corner = path->scene (sta_);
758751 if (path->minMax (sta_) != resizer_.max_ ) {
759752 logger_->error (utl::RSZ ,
760753 kMsgRepairSetupExpectedMaxPath ,
761754 " repairSetup expects max delay path" );
762755 return false ;
763756 }
764757
765- const std::vector<std::pair<int , sta::Delay>> load_delays
766- = rankPathDrivers (expanded, corner, corner->libertyIndex (resizer_.max_ ));
767758 const int repairs_per_pass = repairBudget (path_slack, force_single_repair);
768759
760+ // Rank drivers on the main path and, for latch-through paths, on the latch
761+ // D fanin path, then merge both segments into a single ranking.
762+ std::vector<std::pair<Target, sta::Delay>> ranked_targets;
763+ visitPathSegments (
764+ path,
765+ expanded,
766+ sta_,
767+ [&](const sta::Path* seg_path, sta::PathExpanded& seg_expanded) {
768+ const sta::Scene* seg_corner = seg_path->scene (sta_);
769+ const std::vector<std::pair<int , sta::Delay>> load_delays
770+ = rankPathDrivers (seg_expanded,
771+ seg_corner,
772+ seg_corner->libertyIndex (resizer_.max_ ));
773+ ranked_targets.reserve (ranked_targets.size () + load_delays.size ());
774+ for (const std::pair<int , sta::Delay>& load_delay : load_delays) {
775+ Target target;
776+ makePathDriverTarget (
777+ seg_path, seg_expanded, load_delay.first , path_slack, target);
778+ ranked_targets.emplace_back (std::move (target), load_delay.second );
779+ }
780+ return false ;
781+ });
782+
769783 debugPrint (logger_,
770784 RSZ ,
771785 " repair_setup" ,
772786 3 ,
773- " Path slack: {}, repairs: {}, load_delays : {}" ,
787+ " Path slack: {}, repairs: {}, ranked_targets : {}" ,
774788 delayAsString (path_slack, 3 , sta_),
775789 repairs_per_pass,
776- load_delays.size ());
777-
778- // Construct target vector
779- std::vector<std::pair<Target, sta::Delay>> ranked_targets;
780- ranked_targets.reserve (load_delays.size ());
781- for (const std::pair<int , sta::Delay>& load_delay : load_delays) {
782- Target target;
783- makePathDriverTarget (path, expanded, load_delay.first , path_slack, target);
784- ranked_targets.emplace_back (std::move (target), load_delay.second );
785- }
786-
787- const sta::Path* d_path = latchDataPath (expanded, sta_);
788- if (d_path != nullptr ) {
789- sta::PathExpanded d_expanded (d_path, sta_);
790- const sta::Scene* d_corner = d_path->scene (sta_);
791- const std::vector<std::pair<int , sta::Delay>> d_load_delays
792- = rankPathDrivers (
793- d_expanded, d_corner, d_corner->libertyIndex (resizer_.max_ ));
794- ranked_targets.reserve (ranked_targets.size () + d_load_delays.size ());
795- for (const std::pair<int , sta::Delay>& load_delay : d_load_delays) {
796- Target target;
797- makePathDriverTarget (
798- d_path, d_expanded, load_delay.first , path_slack, target);
799- ranked_targets.emplace_back (std::move (target), load_delay.second );
800- }
801- }
790+ ranked_targets.size ());
802791
803792 std::ranges::stable_sort (ranked_targets,
804793 [](const std::pair<Target, sta::Delay>& lhs,
0 commit comments