Only prune non-configurable nodes at end of routing.

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
diff --git a/vpr/src/route/route_common.cpp b/vpr/src/route/route_common.cpp
index 778330c..6eb4fd0 100644
--- a/vpr/src/route/route_common.cpp
+++ b/vpr/src/route/route_common.cpp
@@ -162,10 +162,12 @@
 
     for (auto net_id : cluster_ctx.clb_nlist.nets()) {
         /* Free any current routing. */
+        pathfinder_update_path_cost(route_ctx.trace[net_id].head, -1, 0.f);
         free_traceback(net_id);
 
         /* Set the current routing to the saved one. */
         route_ctx.trace[net_id].head = best_routing[net_id];
+        pathfinder_update_path_cost(route_ctx.trace[net_id].head, 1, 0.f);
         best_routing[net_id] = nullptr; /* No stored routing. */
     }
 
diff --git a/vpr/src/route/route_timing.cpp b/vpr/src/route/route_timing.cpp
index 42aa2a9..8a199f9 100644
--- a/vpr/src/route/route_timing.cpp
+++ b/vpr/src/route/route_timing.cpp
@@ -297,6 +297,8 @@
                                           const SetupTimingInfo& timing_info,
                                           const RoutingDelayCalculator& delay_calc);
 
+static void prune_unused_non_configurable_nets(CBRR& connections_inf);
+
 /************************ Subroutine definitions *****************************/
 bool try_timing_driven_route(const t_router_opts& router_opts,
                              const t_analysis_opts& analysis_opts,
@@ -727,9 +729,17 @@
         VTR_LOG("Restoring best routing\n");
 
         auto& router_ctx = g_vpr_ctx.mutable_routing();
+
+        /* Restore congestion from best route */
+        for (auto net_id : cluster_ctx.clb_nlist.nets()) {
+            pathfinder_update_path_cost(route_ctx.trace[net_id].head, -1, pres_fac);
+            pathfinder_update_path_cost(best_routing[net_id].head, 1, pres_fac);
+        }
         router_ctx.trace = best_routing;
         router_ctx.clb_opins_used_locally = best_clb_opins_used_locally;
 
+        prune_unused_non_configurable_nets(connections_inf);
+
         if (timing_info) {
             VTR_LOG("Critical path: %g ns\n", 1e9 * best_routing_metrics.critical_path.delay());
         }
@@ -1539,9 +1549,7 @@
         profiling::net_rebuild_start();
 
         // convert the previous iteration's traceback into a route tree
-        auto& device_ctx = g_vpr_ctx.device();
-        std::vector<int> non_config_node_set_usage(device_ctx.rr_non_config_node_sets.size(), 0);
-        rt_root = traceback_to_route_tree(net_id, &non_config_node_set_usage);
+        rt_root = traceback_to_route_tree(net_id);
 
         //Santiy check that route tree and traceback are equivalent before pruning
         VTR_ASSERT_DEBUG(verify_traceback_route_tree_equivalent(route_ctx.trace[net_id].head, rt_root));
@@ -1551,7 +1559,7 @@
         VTR_ASSERT_SAFE(should_route_net(net_id, connections_inf, true));
 
         //Prune the branches of the tree that don't legally lead to sinks
-        rt_root = prune_route_tree(rt_root, connections_inf, &non_config_node_set_usage);
+        rt_root = prune_route_tree(rt_root, connections_inf);
 
         //Now that the tree has been pruned, we can free the old traceback
         // NOTE: this must happen *after* pruning since it changes the
@@ -2807,3 +2815,46 @@
 
     timing_reporter.report_timing_setup(router_opts.first_iteration_timing_report_file, *timing_info.setup_analyzer(), analysis_opts.timing_report_npaths);
 }
+
+// If a route is ripped up during routing, non-configurable sets are left
+// behind.  As a result, the final routing may have stubs at
+// non-configurable sets.  This function tracks non-configurable set usage,
+// and if the sets are unused, prunes them.
+static void prune_unused_non_configurable_nets(CBRR& connections_inf) {
+    auto& device_ctx = g_vpr_ctx.device();
+    auto& cluster_ctx = g_vpr_ctx.clustering();
+    auto& route_ctx = g_vpr_ctx.routing();
+
+    std::vector<int> non_config_node_set_usage(device_ctx.rr_non_config_node_sets.size(), 0);
+    for (auto net_id : cluster_ctx.clb_nlist.nets()) {
+        connections_inf.prepare_routing_for_net(net_id);
+        connections_inf.clear_force_reroute_for_net();
+
+        std::fill(non_config_node_set_usage.begin(), non_config_node_set_usage.end(), 0);
+        t_rt_node* rt_root = traceback_to_route_tree(net_id, &non_config_node_set_usage);
+        if (rt_root == nullptr) {
+            continue;
+        }
+
+        //Santiy check that route tree and traceback are equivalent before pruning
+        VTR_ASSERT(verify_traceback_route_tree_equivalent(
+            route_ctx.trace[net_id].head, rt_root));
+
+        // check for edge correctness
+        VTR_ASSERT_SAFE(is_valid_skeleton_tree(rt_root));
+
+        //Prune the branches of the tree that don't legally lead to sinks
+        rt_root = prune_route_tree(rt_root, connections_inf,
+                                   &non_config_node_set_usage);
+
+        // Free old traceback.
+        free_traceback(net_id);
+
+        // Update traceback with pruned tree.
+        auto& reached_rt_sinks = connections_inf.get_reached_rt_sinks();
+        traceback_from_route_tree(net_id, rt_root, reached_rt_sinks.size());
+        VTR_ASSERT(verify_traceback_route_tree_equivalent(route_ctx.trace[net_id].head, rt_root));
+
+        free_route_tree(rt_root);
+    }
+}
diff --git a/vpr/src/route/route_tree_timing.cpp b/vpr/src/route/route_tree_timing.cpp
index 0b9bc78..d51aa5d 100644
--- a/vpr/src/route/route_tree_timing.cpp
+++ b/vpr/src/route/route_tree_timing.cpp
@@ -977,7 +977,7 @@
 
             // After removing an edge, check if non_config_node_set_usage
             // needs an update.
-            if (node_set != -1 && device_ctx.rr_switch_inf[old_edge->iswitch].configurable()) {
+            if (non_config_node_set_usage != nullptr && node_set != -1 && device_ctx.rr_switch_inf[old_edge->iswitch].configurable()) {
                 (*non_config_node_set_usage)[node_set] -= 1;
                 VTR_ASSERT((*non_config_node_set_usage)[node_set] >= 0);
             }
@@ -1046,7 +1046,9 @@
             if (reached_non_configurably) {
                 // Check if this non-configurable node set is in use.
                 VTR_ASSERT(node_set != -1);
-                force_prune = force_prune || (*non_config_node_set_usage)[node_set] == 0;
+                if (non_config_node_set_usage != nullptr && (*non_config_node_set_usage)[node_set] == 0) {
+                    force_prune = true;
+                }
             }
         }
 
@@ -1068,7 +1070,7 @@
         //   3. The node set is not active
         //
         //  Then prune this node.
-        if (node_set != -1 && device_ctx.rr_switch_inf[node->parent_switch].configurable() && (*non_config_node_set_usage)[node_set] == 0) {
+        if (non_config_node_set_usage != nullptr && node_set != -1 && device_ctx.rr_switch_inf[node->parent_switch].configurable() && (*non_config_node_set_usage)[node_set] == 0) {
             // This node should be pruned, re-prune edges once more.
             return prune_route_tree_recurr(node, connections_inf, /*force_prune=*/false, non_config_node_set_usage);
         }
@@ -1080,6 +1082,10 @@
     }
 }
 
+t_rt_node* prune_route_tree(t_rt_node* rt_root, CBRR& connections_inf) {
+    return prune_route_tree(rt_root, connections_inf, nullptr);
+}
+
 t_rt_node* prune_route_tree(t_rt_node* rt_root, CBRR& connections_inf, std::vector<int>* non_config_node_set_usage) {
     /* Prune a skeleton route tree of illegal branches - when there is at least 1 congested node on the path to a sink
      * This is the top level function to be called with the SOURCE node as root.
diff --git a/vpr/src/route/route_tree_timing.h b/vpr/src/route/route_tree_timing.h
index e998efa..ae67a15 100644
--- a/vpr/src/route/route_tree_timing.h
+++ b/vpr/src/route/route_tree_timing.h
@@ -55,6 +55,7 @@
 t_rt_node* traceback_to_route_tree(t_trace* head, std::vector<int>* non_config_node_set_usage);
 t_trace* traceback_from_route_tree(ClusterNetId inet, const t_rt_node* root, int num_remaining_sinks);
 
+t_rt_node* prune_route_tree(t_rt_node* rt_root, CBRR& connections_inf);
 t_rt_node* prune_route_tree(t_rt_node* rt_root, CBRR& connections_inf, std::vector<int>* non_config_node_set_usage);
 
 void pathfinder_update_cost_from_route_tree(const t_rt_node* rt_root, int add_or_sub, float pres_fac);