Refactored net_delay and route_tree_timing code
diff --git a/vpr/src/draw/draw.cpp b/vpr/src/draw/draw.cpp
index 4a2afdc..8e108d3 100644
--- a/vpr/src/draw/draw.cpp
+++ b/vpr/src/draw/draw.cpp
@@ -3240,7 +3240,7 @@
     std::reverse(rr_nodes_on_path.begin(), rr_nodes_on_path.end());
 
     if (allocated_route_tree_structs) {
-        free_route_tree_timing_structs(); //Clean-up
+        free_route_tree_timing_structs();
     }
     return rr_nodes_on_path;
 }
diff --git a/vpr/src/route/route_timing.cpp b/vpr/src/route/route_timing.cpp
index 8ec3ea5..80d5962 100644
--- a/vpr/src/route/route_timing.cpp
+++ b/vpr/src/route/route_timing.cpp
@@ -841,6 +841,7 @@
     free(sink_order + 1);
     // coverity[offset_free : Intentional]
     free(rt_node_of_sink + 1);
+
     free_route_tree_timing_structs();
 }
 
diff --git a/vpr/src/route/route_tree_timing.cpp b/vpr/src/route/route_tree_timing.cpp
index 52d1de3..0cb14b9 100644
--- a/vpr/src/route/route_tree_timing.cpp
+++ b/vpr/src/route/route_tree_timing.cpp
@@ -21,11 +21,7 @@
  * about the partial routing during timing-driven routing, so the routines
  * in this module are used to keep a tree representation of the partial
  * routing during timing-driven routing.  This allows rapid incremental
- * timing analysis.  The net_delay module does timing analysis in one step
- * (not incrementally as pieces of the routing are added).  I could probably
- * one day remove a lot of net_delay.c and call the corresponding routines
- * here, but it's useful to have a from-scratch delay calculator to check
- * the results of this one.                                                  */
+ * timing analysis.                                                          */
 
 /********************** Variables local to this module ***********************/
 
@@ -612,6 +608,7 @@
     if (!rr_node_to_rt_node.empty()) {
         rr_node_to_rt_node.at(rt_node->inode) = nullptr;
     }
+
     free_rt_node(rt_node);
 }
 
@@ -690,7 +687,13 @@
     while (trace) { //Each branch
         trace = traceback_to_route_tree_branch(trace, rr_node_to_rt);
     }
+    // Due to the recursive nature of traceback_to_route_tree_branch,
+    // the source node is not properly configured.
+    // Here, for the source we set the parent node and switch to be
+    // nullptr and OPEN respectively.
 
+    rr_node_to_rt[head->index]->parent_node = nullptr;
+    rr_node_to_rt[head->index]->parent_switch = OPEN;
     return rr_node_to_rt[head->index];
 }
 
diff --git a/vpr/src/timing/net_delay.cpp b/vpr/src/timing/net_delay.cpp
index 6045ea7..3fa6fb2 100644
--- a/vpr/src/timing/net_delay.cpp
+++ b/vpr/src/timing/net_delay.cpp
@@ -9,87 +9,37 @@
 
 #include "globals.h"
 #include "net_delay.h"
-/***************** Types and defines local to this module ********************/
-struct t_rc_node;
+#include "route_tree_timing.h"
 
-/* Linked list listing the children of an rc_node.                           *
- * child:  Pointer to an rc_node (child of the current node).                *
- * iswitch:  Index of the switch type used to connect to the child node.     *
- * next:   Pointer to the next linked_rc_edge in the linked list (allows     *
- *         you to get the next child of the current rc_node).                */
-struct t_linked_rc_edge {
-    t_rc_node* child;
-    short iswitch;
-    t_linked_rc_edge* next;
-};
+/* This module keeps track of the time delays for signals to arrive at       *
+ * each pin in every net after timing-driven routing is complete. It         *
+ * achieves this by first constructing the skeleton route tree               * 
+ * from the traceback. Next, to obtain the completed route tree, it          *
+ * calls functions to calculate the resistance, capacitance, and time        *
+ * delays associated with each node. Then, it recursively traverses          *
+ * the tree, copying the time delay from each node into the                  *
+ * net_delay data structure. Essentially, the delays are calculated          *
+ * by building the completed route tree from scratch, and is used            *
+ * to check against the time delays computed incrementally during           * 
+ * timing-driven routing.                                                    */
 
-/* Structure describing one node in an RC tree (used to get net delays).     *
- * u.child_list:  Pointer to a linked list of linked_rc_edge.  Each one of   *
- *                the linked list entries gives a child of this node.        *
- * u.next:  Used only when this node is on the free list.  Gives the next    *
- *          node on the free list.                                           *
- * inode:  index (ID) of the rr_node that corresponds to this rc_node.       *
- * C_downstream:  Total downstream capacitance from this rc_node.  That is,  *
- *                the total C of the subtree rooted at the current node,     *
- *                including the C of the current node.                       *
- * Tdel:  Time delay for the signal to get from the net source to this node. *
- *        Includes the time to go through this node.                         */
-struct t_rc_node {
-    union {
-        t_linked_rc_edge* child_list;
-        t_rc_node* next;
-    } u;
-    int inode;
-    float C_downstream;
-    float Tdel;
-};
+/********************** Variables local to this module ***********************/
 
-/* Linked list of pointers to rc_nodes.                                      *
- * rc_node:  Pointer to an rc_node.                                          *
- * next:  Next list element.                                                 */
-struct t_linked_rc_ptr {
-    t_rc_node* rc_node;
-    t_linked_rc_ptr* next;
-};
+/* Unordered map below stores the pair whose key is the index of the rr_node *
+ * that corresponds to the rt_node, and whose value is the time delay        *
+ * associated with that node. The map will be used to store delays while     *
+ * traversing the nodes of the route tree in load_one_net_delay_recurr.      */
+
+static std::unordered_map<int, float> inode_to_Tdel_map;
 
 /*********************** Subroutines local to this module ********************/
 
-static t_rc_node* alloc_and_load_rc_tree(ClusterNetId net_id,
-                                         t_rc_node** rc_node_free_list_ptr,
-                                         t_linked_rc_edge** rc_edge_free_list_ptr,
-                                         t_linked_rc_ptr* rr_node_to_rc_node);
+static void load_one_net_delay(vtr::vector<ClusterNetId, float*>& net_delay, ClusterNetId net_id);
 
-static void add_to_rc_tree(t_rc_node* parent_rc, t_rc_node* child_rc, short iswitch, int inode, t_linked_rc_edge** rc_edge_free_list_ptr);
-
-static t_rc_node* alloc_rc_node(t_rc_node** rc_node_free_list_ptr);
-
-static void free_rc_node(t_rc_node* rc_node,
-                         t_rc_node** rc_node_free_list_ptr);
-
-static t_linked_rc_edge* alloc_linked_rc_edge(t_linked_rc_edge** rc_edge_free_list_ptr);
-
-static void free_linked_rc_edge(t_linked_rc_edge* rc_edge,
-                                t_linked_rc_edge** rc_edge_free_list_ptr);
-
-static float load_rc_tree_C(t_rc_node* rc_node);
-
-static void load_rc_tree_T(t_rc_node* rc_node, float T_arrival);
-
-static void load_one_net_delay(vtr::vector<ClusterNetId, float*>& net_delay, ClusterNetId net_id, t_linked_rc_ptr* rr_node_to_rc_node);
+static void load_one_net_delay_recurr(t_rt_node* node, ClusterNetId net_id);
 
 static void load_one_constant_net_delay(vtr::vector<ClusterNetId, float*>& net_delay, ClusterNetId net_id, float delay_value);
 
-static void free_rc_tree(t_rc_node* rc_root,
-                         t_rc_node** rc_node_free_list_ptr,
-                         t_linked_rc_edge** rc_edge_free_list_ptr);
-
-static void reset_rr_node_to_rc_node(t_linked_rc_ptr* rr_node_to_rc_node,
-                                     ClusterNetId net_id);
-
-static void free_rc_node_free_list(t_rc_node* rc_node_free_list);
-
-static void free_rc_edge_free_list(t_linked_rc_edge* rc_edge_free_list);
-
 /*************************** Subroutine definitions **************************/
 
 /* Allocates space for the net_delay data structure   *
@@ -118,399 +68,76 @@
 
 void free_net_delay(vtr::vector<ClusterNetId, float*>& net_delay,
                     vtr::t_chunk* chunk_list_ptr) {
-    /* Frees the net_delay structure.  Assumes it was chunk allocated.          */
-
     net_delay.clear();
     vtr::free_chunk_memory(chunk_list_ptr);
 }
 
 void load_net_delay_from_routing(vtr::vector<ClusterNetId, float*>& net_delay) {
     /* This routine loads net_delay[0..nets.size()-1][1..num_pins-1].  Each entry   *
-     * is the Elmore delay from the net source to the appropriate sink.  Both    *
-     * the rr_graph and the routing traceback must be completely constructed     *
-     * before this routine is called, and the net_delay array must have been     *
-     * allocated.                                                                */
-    auto& device_ctx = g_vpr_ctx.device();
+     * is the Elmore delay from the net source to the appropriate sink. Both       *
+     * the rr_graph and the routing traceback must be completely constructed        *
+     * before this routine is called, and the net_delay array must have been        *
+     * allocated.                                                                   */
     auto& cluster_ctx = g_vpr_ctx.clustering();
 
-    t_rc_node *rc_node_free_list, *rc_root;
-    t_linked_rc_edge* rc_edge_free_list;
-    t_linked_rc_ptr* rr_node_to_rc_node; /* [0..device_ctx.rr_nodes.size()-1]  */
-
-    rr_node_to_rc_node = (t_linked_rc_ptr*)vtr::calloc(device_ctx.rr_nodes.size(),
-                                                       sizeof(t_linked_rc_ptr));
-
-    rc_node_free_list = nullptr;
-    rc_edge_free_list = nullptr;
-
     for (auto net_id : cluster_ctx.clb_nlist.nets()) {
         if (cluster_ctx.clb_nlist.net_is_ignored(net_id)) {
             load_one_constant_net_delay(net_delay, net_id, 0.);
         } else {
-            rc_root = alloc_and_load_rc_tree(net_id, &rc_node_free_list,
-                                             &rc_edge_free_list, rr_node_to_rc_node);
-            load_rc_tree_C(rc_root);
-            load_rc_tree_T(rc_root, 0.);
-            load_one_net_delay(net_delay, net_id, rr_node_to_rc_node);
-            free_rc_tree(rc_root, &rc_node_free_list, &rc_edge_free_list);
-            reset_rr_node_to_rc_node(rr_node_to_rc_node, net_id);
+            load_one_net_delay(net_delay, net_id);
         }
     }
-
-    free_rc_node_free_list(rc_node_free_list);
-    free_rc_edge_free_list(rc_edge_free_list);
-    free(rr_node_to_rc_node);
 }
 
-static t_rc_node*
-alloc_and_load_rc_tree(ClusterNetId net_id, t_rc_node** rc_node_free_list_ptr, t_linked_rc_edge** rc_edge_free_list_ptr, t_linked_rc_ptr* rr_node_to_rc_node) {
-    /* Builds a tree describing the routing of net inet.  Allocates all the data *
-     * and inserts all the connections in the tree.                              */
-
-    t_rc_node *curr_rc, *prev_rc, *root_rc;
-    t_trace* tptr;
-    int inode;
-    short iswitch;
-    t_linked_rc_ptr* linked_rc_ptr;
+static void load_one_net_delay(vtr::vector<ClusterNetId, float*>& net_delay, ClusterNetId net_id) {
+    /* This routine loads delay values for one net in                            *
+     * net_delay[net_id][1..num_pins-1]. First, from the traceback, it           *
+     * constructs the route tree and computes its values for R, C, and Tdel.     *
+     * Next, it walks the route tree recursively, storing the time delays for    * 
+     * each node into the map inode_to_Tdel. Then, while looping through the     *
+     * net_delay array we search for the inode corresponding to the pin          * 
+     * identifiers, and correspondingly update the entry in net_delay.           *
+     * Finally, it frees the route tree and clears the inode_to_Tdel_map         *
+     * associated with that net.                                                 */
 
     auto& route_ctx = g_vpr_ctx.routing();
 
-    root_rc = alloc_rc_node(rc_node_free_list_ptr);
-    tptr = route_ctx.trace[net_id].head;
-
-    if (tptr == nullptr) {
+    if (route_ctx.trace[net_id].head == nullptr) {
         VPR_FATAL_ERROR(VPR_ERROR_TIMING,
-                        "in alloc_and_load_rc_tree: Traceback for net %lu does not exist.\n", size_t(net_id));
+                        "in load_one_net_delay: Traceback for net %lu does not exist.\n", size_t(net_id));
     }
 
-    inode = tptr->index;
-    iswitch = tptr->iswitch;
-    root_rc->inode = inode;
-    root_rc->u.child_list = nullptr;
-    rr_node_to_rc_node[inode].rc_node = root_rc;
-
-    prev_rc = root_rc;
-    tptr = tptr->next;
-
-    while (tptr != nullptr) {
-        inode = tptr->index;
-
-        /* Is this node a "stitch-in" point to part of the existing routing or a   *
-         * new piece of routing along the current routing "arm?"                   */
-
-        if (rr_node_to_rc_node[inode].rc_node == nullptr) { /* Part of current "arm" */
-            curr_rc = alloc_rc_node(rc_node_free_list_ptr);
-            add_to_rc_tree(prev_rc, curr_rc, iswitch, inode, rc_edge_free_list_ptr);
-            rr_node_to_rc_node[inode].rc_node = curr_rc;
-            prev_rc = curr_rc;
-
-        } else if (iswitch == OPEN) { /* Connection to old stuff. */
-
-            prev_rc = rr_node_to_rc_node[inode].rc_node;
-
-        } else { /* SINK that this net has connected to more than once. */
-
-            /* I can connect to a SINK node more than once in some weird architectures. *
-             * That means the routing isn't really a tree -- there is reconvergent      *
-             * fanout from two or more IPINs into one SINK.  I convert this structure   *
-             * into a true RC tree on the fly by creating a new rc_node each time I hit *
-             * the same sink.  This means I need to keep a linked list of the rc_nodes  *
-             * associated with the rr_node (inode) associated with that SINK.           */
-
-            curr_rc = alloc_rc_node(rc_node_free_list_ptr);
-            add_to_rc_tree(prev_rc, curr_rc, iswitch, inode, rc_edge_free_list_ptr);
-
-            linked_rc_ptr = (t_linked_rc_ptr*)vtr::malloc(sizeof(t_linked_rc_ptr));
-            linked_rc_ptr->next = rr_node_to_rc_node[inode].next;
-            rr_node_to_rc_node[inode].next = linked_rc_ptr;
-            linked_rc_ptr->rc_node = curr_rc;
-
-            prev_rc = curr_rc;
-        }
-        iswitch = tptr->iswitch;
-        tptr = tptr->next;
-    }
-
-    return (root_rc);
-}
-
-static void add_to_rc_tree(t_rc_node* parent_rc, t_rc_node* child_rc, short iswitch, int inode, t_linked_rc_edge** rc_edge_free_list_ptr) {
-    /* Adds child_rc to the child list of parent_rc, and sets the switch between *
-     * them to iswitch.  This routine also intitializes the child_rc properly    *
-     * and sets its node value to inode.                                         */
-
-    t_linked_rc_edge* linked_rc_edge;
-
-    linked_rc_edge = alloc_linked_rc_edge(rc_edge_free_list_ptr);
-
-    linked_rc_edge->next = parent_rc->u.child_list;
-    parent_rc->u.child_list = linked_rc_edge;
-
-    linked_rc_edge->child = child_rc;
-    linked_rc_edge->iswitch = iswitch;
-
-    child_rc->u.child_list = nullptr;
-    child_rc->inode = inode;
-}
-
-static t_rc_node*
-alloc_rc_node(t_rc_node** rc_node_free_list_ptr) {
-    /* Allocates a new rc_node, from the free list if possible, from the free   *
-     * store otherwise.                                                         */
-
-    t_rc_node* rc_node;
-
-    rc_node = *rc_node_free_list_ptr;
-
-    if (rc_node != nullptr) {
-        *rc_node_free_list_ptr = rc_node->u.next;
-    } else {
-        rc_node = (t_rc_node*)vtr::malloc(sizeof(t_rc_node));
-    }
-
-    return (rc_node);
-}
-
-static void free_rc_node(t_rc_node* rc_node,
-                         t_rc_node** rc_node_free_list_ptr) {
-    /* Adds rc_node to the proper free list.          */
-
-    rc_node->u.next = *rc_node_free_list_ptr;
-    *rc_node_free_list_ptr = rc_node;
-}
-
-static t_linked_rc_edge*
-alloc_linked_rc_edge(t_linked_rc_edge** rc_edge_free_list_ptr) {
-    /* Allocates a new linked_rc_edge, from the free list if possible, from the  *
-     * free store otherwise.                                                     */
-
-    t_linked_rc_edge* linked_rc_edge;
-
-    linked_rc_edge = *rc_edge_free_list_ptr;
-
-    if (linked_rc_edge != nullptr) {
-        *rc_edge_free_list_ptr = linked_rc_edge->next;
-    } else {
-        linked_rc_edge = (t_linked_rc_edge*)vtr::malloc(sizeof(t_linked_rc_edge));
-    }
-
-    return (linked_rc_edge);
-}
-
-static void free_linked_rc_edge(t_linked_rc_edge* rc_edge,
-                                t_linked_rc_edge** rc_edge_free_list_ptr) {
-    /* Adds the rc_edge to the rc_edge free list.                       */
-
-    rc_edge->next = *rc_edge_free_list_ptr;
-    *rc_edge_free_list_ptr = rc_edge;
-}
-
-static float load_rc_tree_C(t_rc_node* rc_node) {
-    /* Does a post-order traversal of the rc tree to load each node's           *
-     * C_downstream with the proper sum of all the downstream capacitances.     *
-     * This routine calls itself recursively to perform the traversal.          */
-
-    t_linked_rc_edge* linked_rc_edge;
-    t_rc_node* child_node;
-    int inode;
-    short iswitch;
-    float C, C_downstream;
-
-    auto& device_ctx = g_vpr_ctx.device();
-
-    linked_rc_edge = rc_node->u.child_list;
-    inode = rc_node->inode;
-    C = device_ctx.rr_nodes[inode].C();
-
-    while (linked_rc_edge != nullptr) { /* For all children */
-        iswitch = linked_rc_edge->iswitch;
-        child_node = linked_rc_edge->child;
-        C_downstream = load_rc_tree_C(child_node);
-
-        if (!device_ctx.rr_switch_inf[iswitch].buffered())
-            C += C_downstream;
-
-        linked_rc_edge = linked_rc_edge->next;
-    }
-
-    rc_node->C_downstream = C;
-    return (C);
-}
-
-static void load_rc_tree_T(t_rc_node* rc_node, float T_arrival) {
-    /* This routine does a pre-order depth-first traversal of the rc tree to    *
-     * compute the Tdel to each node in the rc tree.  The T_arrival is the time *
-     * at which the signal hits the input to this node.  This routine calls     *
-     * itself recursively to perform the traversal.                             */
-
-    float Tdel, Rmetal, Tchild;
-    t_linked_rc_edge* linked_rc_edge;
-    t_rc_node* child_node;
-    short iswitch;
-    int inode;
-
-    auto& device_ctx = g_vpr_ctx.device();
-
-    Tdel = T_arrival;
-    inode = rc_node->inode;
-    Rmetal = device_ctx.rr_nodes[inode].R();
-
-    /* NB:  device_ctx.rr_nodes[inode].C gives the capacitance of this node, while          *
-     * rc_node->C_downstream gives the unbuffered downstream capacitance rooted *
-     * at this node, including the C of the node itself.  I want to multiply    *
-     * the C of this node by 0.5 Rmetal, since it's a distributed RC line.      *
-     * Hence 0.5 Rmetal * Cnode is a pessimistic estimate of delay (i.e. end to *
-     * end).  For the downstream capacitance rooted at this node (not including *
-     * the capacitance of the node itself), I assume it is, on average,         *
-     * connected halfway along the line, so I also multiply by 0.5 Rmetal.  To  *
-     * be totally pessimistic I would multiply the downstream part of the       *
-     * capacitance by Rmetal.  Play with this equation if you like.             */
-
-    /* Rmetal is distributed so x0.5 */
-    Tdel += 0.5 * rc_node->C_downstream * Rmetal;
-    rc_node->Tdel = Tdel;
-
-    /* Now expand the children of this node to load their Tdel values.       */
-
-    linked_rc_edge = rc_node->u.child_list;
-
-    while (linked_rc_edge != nullptr) { /* For all children */
-        iswitch = linked_rc_edge->iswitch;
-        child_node = linked_rc_edge->child;
-
-        Tchild = Tdel + device_ctx.rr_switch_inf[iswitch].R * child_node->C_downstream;
-        Tchild += device_ctx.rr_switch_inf[iswitch].Tdel; /* Intrinsic switch delay. */
-        load_rc_tree_T(child_node, Tchild);
-
-        linked_rc_edge = linked_rc_edge->next;
-    }
-}
-
-/* Loads the net delay array for net inet.  The rc tree for that net must  *
- * have already been completely built and loaded.                           */
-static void load_one_net_delay(vtr::vector<ClusterNetId, float*>& net_delay, ClusterNetId net_id, t_linked_rc_ptr* rr_node_to_rc_node) {
-    unsigned int ipin, inode;
-    float Tmax;
-    t_rc_node* rc_node;
-    t_linked_rc_ptr *linked_rc_ptr, *next_ptr;
-
     auto& cluster_ctx = g_vpr_ctx.clustering();
-    auto& route_ctx = g_vpr_ctx.routing();
+    int inode;
 
-    for (ipin = 1; ipin < cluster_ctx.clb_nlist.net_pins(net_id).size(); ipin++) {
-        inode = route_ctx.net_rr_terminals[net_id][ipin];
-        linked_rc_ptr = rr_node_to_rc_node[inode].next;
-        rc_node = rr_node_to_rc_node[inode].rc_node;
-        Tmax = rc_node->Tdel;
+    t_rt_node* rt_root = traceback_to_route_tree(net_id); // obtain the root of the tree constructed from the traceback
+    load_new_subtree_R_upstream(rt_root);                 // load in the resistance values for the route tree
+    load_new_subtree_C_downstream(rt_root);               // load in the capacitance values for the route tree
+    load_route_tree_Tdel(rt_root, 0.);                    // load the time delay values for the route tree
+    load_one_net_delay_recurr(rt_root, net_id);           // recursively traverse the tree and load entries into the inode_to_Tdel map
 
-        /* If below only executes when one net connects several times to the      *
-         * same SINK.  In this case, I can't tell which net pin each connection   *
-         * to this SINK corresponds to (I can just choose arbitrarily).  To make  *
-         * sure the timing behaviour converges, I pessimistically set the delay   *
-         * for all of the connections to this SINK by this net to be the max. of  *
-         * the delays from this net to this SINK.  NB:  This code only occurs     *
-         * when a net connect more than once to the same pin class on the same    *
-         * logic block.  Only a weird architecture would allow this.              */
+    for (unsigned int ipin = 1; ipin < cluster_ctx.clb_nlist.net_pins(net_id).size(); ipin++) {
+        inode = route_ctx.net_rr_terminals[net_id][ipin];                // look for the index of the rr node that corresponds to the sink that was used to route a certain connection.
+        net_delay[net_id][ipin] = inode_to_Tdel_map.find(inode)->second; // search for the value of Tdel in the inode map and load into net_delay
+    }
+    free_route_tree(rt_root);  // free the route tree
+    inode_to_Tdel_map.clear(); // clear the map
+}
 
-        if (linked_rc_ptr != nullptr) {
-            /* The first time I hit a multiply-used SINK, I choose the largest delay  *
-             * from this net to this SINK and use it for every connection to this     *
-             * SINK by this net.                                                      */
+static void load_one_net_delay_recurr(t_rt_node* node, ClusterNetId net_id) {
+    /* This routine recursively traverses the route tree, and copies the Tdel of the node into the map.  */
 
-            do {
-                rc_node = linked_rc_ptr->rc_node;
-                if (rc_node->Tdel > Tmax) {
-                    Tmax = rc_node->Tdel;
-                    rr_node_to_rc_node[inode].rc_node = rc_node;
-                }
-                next_ptr = linked_rc_ptr->next;
-                free(linked_rc_ptr);
-                linked_rc_ptr = next_ptr;
-            } while (linked_rc_ptr != nullptr); /* End do while */
+    inode_to_Tdel_map[node->inode] = node->Tdel; // add to the map, process current node
 
-            rr_node_to_rc_node[inode].next = nullptr;
-        }
-        /* End of if multiply-used SINK */
-        net_delay[net_id][ipin] = Tmax;
+    for (t_linked_rt_edge* edge = node->u.child_list; edge != nullptr; edge = edge->next) { // process children
+        load_one_net_delay_recurr(edge->child, net_id);
     }
 }
 
 static void load_one_constant_net_delay(vtr::vector<ClusterNetId, float*>& net_delay, ClusterNetId net_id, float delay_value) {
     /* Sets each entry of the net_delay array for net inet to delay_value.     */
-    unsigned int ipin;
     auto& cluster_ctx = g_vpr_ctx.clustering();
 
-    for (ipin = 1; ipin < cluster_ctx.clb_nlist.net_pins(net_id).size(); ipin++)
+    for (unsigned int ipin = 1; ipin < cluster_ctx.clb_nlist.net_pins(net_id).size(); ipin++)
         net_delay[net_id][ipin] = delay_value;
 }
-
-static void free_rc_tree(t_rc_node* rc_root,
-                         t_rc_node** rc_node_free_list_ptr,
-                         t_linked_rc_edge** rc_edge_free_list_ptr) {
-    /* Puts the rc tree pointed to by rc_root back on the free list.  Depth-     *
-     * first post-order traversal via recursion.                                 */
-
-    t_rc_node *rc_node, *child_node;
-    t_linked_rc_edge *rc_edge, *next_edge;
-
-    rc_node = rc_root;
-    rc_edge = rc_node->u.child_list;
-
-    while (rc_edge != nullptr) { /* For all children */
-        child_node = rc_edge->child;
-        free_rc_tree(child_node, rc_node_free_list_ptr, rc_edge_free_list_ptr);
-        next_edge = rc_edge->next;
-        free_linked_rc_edge(rc_edge, rc_edge_free_list_ptr);
-        rc_edge = next_edge;
-    }
-
-    free_rc_node(rc_node, rc_node_free_list_ptr);
-}
-
-static void reset_rr_node_to_rc_node(t_linked_rc_ptr* rr_node_to_rc_node, ClusterNetId net_id) {
-    /* Resets the rr_node_to_rc_node mapping entries that were set during       *
-     * construction of the RC tree for net inet.  Any extra linked list entries *
-     * added to deal with a SINK being connected to multiple times have already *
-     * been freed by load_one_net_delay.                                        */
-
-    t_trace* tptr;
-    int inode;
-
-    auto& route_ctx = g_vpr_ctx.routing();
-
-    tptr = route_ctx.trace[net_id].head;
-
-    while (tptr != nullptr) {
-        inode = tptr->index;
-        rr_node_to_rc_node[inode].rc_node = nullptr;
-        tptr = tptr->next;
-    }
-}
-
-static void free_rc_node_free_list(t_rc_node* rc_node_free_list) {
-    /* Really frees (i.e. calls free()) all the rc_nodes on the free list.   */
-
-    t_rc_node *rc_node, *next_node;
-
-    rc_node = rc_node_free_list;
-
-    while (rc_node != nullptr) {
-        next_node = rc_node->u.next;
-        free(rc_node);
-        rc_node = next_node;
-    }
-}
-
-static void free_rc_edge_free_list(t_linked_rc_edge* rc_edge_free_list) {
-    /* Really frees (i.e. calls free()) all the rc_edges on the free list.   */
-
-    t_linked_rc_edge *rc_edge, *next_edge;
-
-    rc_edge = rc_edge_free_list;
-
-    while (rc_edge != nullptr) {
-        next_edge = rc_edge->next;
-        free(rc_edge);
-        rc_edge = next_edge;
-    }
-}