|
19 | 19 | #include "atom_netlist.h"
|
20 | 20 | #include "cluster_placement.h"
|
21 | 21 | #include "cluster_router.h"
|
| 22 | +#include "cluster_util.h" |
22 | 23 | #include "globals.h"
|
23 | 24 | #include "logic_types.h"
|
24 | 25 | #include "netlist_utils.h"
|
@@ -139,6 +140,26 @@ static void check_cluster_atom_blocks(t_pb* pb, std::unordered_set<AtomBlockId>&
|
139 | 140 | }
|
140 | 141 | }
|
141 | 142 |
|
| 143 | +/// @brief Recursively frees the pb stats of the given pb, without freeing the |
| 144 | +/// pb itself. |
| 145 | +static void free_pb_stats_recursive(t_pb* pb) { |
| 146 | + /* Releases all the memory used by clustering data structures. */ |
| 147 | + if (pb) { |
| 148 | + if (pb->pb_graph_node != nullptr) { |
| 149 | + if (!pb->pb_graph_node->is_primitive()) { |
| 150 | + for (int i = 0; i < pb->pb_graph_node->pb_type->modes[pb->mode].num_pb_type_children; i++) { |
| 151 | + for (int j = 0; j < pb->pb_graph_node->pb_type->modes[pb->mode].pb_type_children[i].num_pb; j++) { |
| 152 | + if (pb->child_pbs && pb->child_pbs[i]) { |
| 153 | + free_pb_stats_recursive(&pb->child_pbs[i][j]); |
| 154 | + } |
| 155 | + } |
| 156 | + } |
| 157 | + } |
| 158 | + } |
| 159 | + free_pb_stats(pb); |
| 160 | + } |
| 161 | +} |
| 162 | + |
142 | 163 | /* Record the failure of the molecule in this cluster in the current pb stats.
|
143 | 164 | * If a molecule fails repeatedly, it's gain will be penalized if packing with
|
144 | 165 | * attraction groups on. */
|
@@ -1468,6 +1489,7 @@ e_block_pack_status ClusterLegalizer::add_mol_to_cluster(t_pack_molecule* molecu
|
1468 | 1489 |
|
1469 | 1490 | // Get the cluster.
|
1470 | 1491 | LegalizationCluster& cluster = legalization_clusters[cluster_id];
|
| 1492 | + VTR_ASSERT(cluster.router_data != nullptr && "Cannot add molecule to cleaned cluster!"); |
1471 | 1493 | // Set the target_external_pin_util.
|
1472 | 1494 | t_ext_pin_util target_ext_pin_util = target_external_pin_util.get_pin_util(cluster.type->name);
|
1473 | 1495 | // Try to pack the molecule into the cluster.
|
@@ -1548,9 +1570,26 @@ void ClusterLegalizer::compress() {
|
1548 | 1570 | atom_cluster.shrink_to_fit();
|
1549 | 1571 | }
|
1550 | 1572 |
|
| 1573 | +void ClusterLegalizer::clean_cluster(LegalizationClusterId cluster_id) { |
| 1574 | + // Safety asserts to make sure the inputs are valid. |
| 1575 | + VTR_ASSERT_SAFE(cluster_id.is_valid() && (size_t)cluster_id < legalization_clusters.size()); |
| 1576 | + // Get the cluster. |
| 1577 | + LegalizationCluster& cluster = legalization_clusters[cluster_id]; |
| 1578 | + // Free the pb stats. |
| 1579 | + free_pb_stats_recursive(cluster.pb); |
| 1580 | + // Load the pb_route so we can free the cluster router data. |
| 1581 | + // The pb_route is used when creating a netlist from the legalized clusters. |
| 1582 | + std::vector<t_intra_lb_net>* saved_lb_nets = cluster.router_data->saved_lb_nets; |
| 1583 | + t_pb_graph_node* pb_graph_node = cluster.pb->pb_graph_node; |
| 1584 | + cluster.pb->pb_route = alloc_and_load_pb_route(saved_lb_nets, pb_graph_node); |
| 1585 | + // Free the router data. |
| 1586 | + free_router_data(cluster.router_data); |
| 1587 | + cluster.router_data = nullptr; |
| 1588 | +} |
| 1589 | + |
1551 | 1590 | bool ClusterLegalizer::check_cluster_legality(LegalizationClusterId cluster_id) {
|
1552 | 1591 | // Safety asserts to make sure the inputs are valid.
|
1553 |
| - VTR_ASSERT_DEBUG(cluster_id.is_valid() && (size_t)cluster_id < legalization_clusters.size()); |
| 1592 | + VTR_ASSERT_SAFE(cluster_id.is_valid() && (size_t)cluster_id < legalization_clusters.size()); |
1554 | 1593 | // To check if a cluster is fully legal, try to perform an intra logic block
|
1555 | 1594 | // route on the cluster. If it succeeds, the cluster is fully legal.
|
1556 | 1595 | t_mode_selection_status mode_status;
|
@@ -1616,8 +1655,6 @@ void ClusterLegalizer::reset() {
|
1616 | 1655 | // Reset the molecule_cluster map
|
1617 | 1656 | molecule_cluster.clear();
|
1618 | 1657 | // Reset the cluster placement stats.
|
1619 |
| - // FIXME: Is this necessary? Or is there a way to clear the cluster placement |
1620 |
| - // stats? |
1621 | 1658 | free_cluster_placement_stats(cluster_placement_stats);
|
1622 | 1659 | cluster_placement_stats = alloc_and_load_cluster_placement_stats();
|
1623 | 1660 | }
|
@@ -1692,12 +1729,11 @@ void ClusterLegalizer::finalize() {
|
1692 | 1729 | for (LegalizationClusterId cluster_id : legalization_cluster_ids) {
|
1693 | 1730 | if (!cluster_id.is_valid())
|
1694 | 1731 | continue;
|
1695 |
| - LegalizationCluster& cluster = legalization_clusters[cluster_id]; |
1696 |
| - t_pb* cluster_pb = cluster.pb; |
1697 |
| - t_lb_router_data* cluster_router_data = cluster.router_data; |
1698 |
| - std::vector<t_intra_lb_net>* saved_lb_nets = cluster_router_data->saved_lb_nets; |
1699 |
| - t_pb_graph_node* pb_graph_node = cluster_pb->pb_graph_node; |
1700 |
| - cluster_pb->pb_route = alloc_and_load_pb_route(saved_lb_nets, pb_graph_node); |
| 1732 | + // If the cluster has not already been cleaned, clean it. This will |
| 1733 | + // generate the pb_route necessary for generating a clustered netlist. |
| 1734 | + const LegalizationCluster& cluster = legalization_clusters[cluster_id]; |
| 1735 | + if (cluster.router_data != nullptr) |
| 1736 | + clean_cluster(cluster_id); |
1701 | 1737 | }
|
1702 | 1738 | }
|
1703 | 1739 |
|
|
0 commit comments