From fd4569081e6ce85b841768c44757c94c15a74075 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 17 Mar 2021 14:54:36 -0400 Subject: [PATCH] Added a reference count to the node structure in extflat to account for the "equiv" statement---equivalent nodes names have to be registered in the def->def_nodes hash table, and if they point to the same node, then that node can't be free'd until the last referenced node is seen when iterating through the hash table to free the node records during EFDone(). This is handled by the reference count. --- extflat/EFbuild.c | 18 +++++++++++++++++- extflat/EFflat.c | 1 + extflat/extflat.h | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/extflat/EFbuild.c b/extflat/EFbuild.c index a804a9de..97c71124 100644 --- a/extflat/EFbuild.c +++ b/extflat/EFbuild.c @@ -183,6 +183,7 @@ efBuildNode(def, isSubsnode, nodeName, nodeCap, x, y, layerName, av, ac) newname = (EFNodeName *) mallocMagic((unsigned)(sizeof (EFNodeName))); newname->efnn_hier = EFStrToHN((HierName *) NULL, nodeName); newname->efnn_port = -1; /* No port assignment */ + newname->efnn_refc = 0; /* Only reference is self */ newname->efnn_next = NULL; HashSetValue(he, (char *) newname); } @@ -491,9 +492,15 @@ efBuildEquiv(def, nodeName1, nodeName2) /* points to the merged name's hash. */ if (nn1->efnn_node == NULL) + { HashSetValue(he1, (char *)nn2); + nn2->efnn_refc += nn1->efnn_refc + 1; + } else if (nn2->efnn_node == NULL) + { HashSetValue(he2, (char *)nn1); + nn1->efnn_refc += nn2->efnn_refc + 1; + } } return; } @@ -1561,6 +1568,7 @@ efNodeAddName(node, he, hn) newnn->efnn_node = node; newnn->efnn_hier = hn; newnn->efnn_port = -1; + newnn->efnn_refc = 0; HashSetValue(he, (char *) newnn); /* If the node is a port of the top level cell, denoted by flag */ @@ -1869,7 +1877,15 @@ efFreeNodeTable(table) { for (hn = nn->efnn_hier; hn; hn = hn->hn_parent) (void) HashFind(&efFreeHashTable, (char *) hn); - freeMagic((char *) nn); + + /* Node equivalences made by "equiv" statements are handled */ + /* by reference count. Don't free the node structure until */ + /* all references have been seen. */ + + if (nn->efnn_refc > 0) + nn->efnn_refc--; + else + freeMagic((char *) nn); } } diff --git a/extflat/EFflat.c b/extflat/EFflat.c index 516c1f50..463b196e 100644 --- a/extflat/EFflat.c +++ b/extflat/EFflat.c @@ -545,6 +545,7 @@ efAddNodes(hc, stdcell) newname->efnn_node = newnode; newname->efnn_hier = hierName; newname->efnn_port = -1; + newname->efnn_refc = 0; if (newnode->efnode_name) { newname->efnn_next = newnode->efnode_name->efnn_next; diff --git a/extflat/extflat.h b/extflat/extflat.h index 0e2b361a..a512e7d8 100644 --- a/extflat/extflat.h +++ b/extflat/extflat.h @@ -119,6 +119,7 @@ typedef struct efnn struct efnn *efnn_next; /* Next name for this node */ HierName *efnn_hier; /* HierName for this node */ int efnn_port; /* Port number for this node */ + unsigned char efnn_refc; /* #times referenced in hash */ } EFNodeName; /*