VIS
|
00001 00023 #include "partInt.h" 00024 00025 static char rcsid[] UNUSED = "$Id: partCollapse.c,v 1.5 2005/04/16 06:14:54 fabio Exp $"; 00026 00027 /*---------------------------------------------------------------------------*/ 00028 /* Constant declarations */ 00029 /*---------------------------------------------------------------------------*/ 00030 00031 00032 /*---------------------------------------------------------------------------*/ 00033 /* Structure declarations */ 00034 /*---------------------------------------------------------------------------*/ 00035 00036 00037 /*---------------------------------------------------------------------------*/ 00038 /* Type declarations */ 00039 /*---------------------------------------------------------------------------*/ 00040 00041 00042 /*---------------------------------------------------------------------------*/ 00043 /* Variable declarations */ 00044 /*---------------------------------------------------------------------------*/ 00045 00046 00047 /*---------------------------------------------------------------------------*/ 00048 /* Macro declarations */ 00049 /*---------------------------------------------------------------------------*/ 00050 00051 00054 /*---------------------------------------------------------------------------*/ 00055 /* Static function prototypes */ 00056 /*---------------------------------------------------------------------------*/ 00057 00058 static Mvf_Function_t * CollapseRecur(graph_t *partition, vertex_t *vertexPtr, st_table *tableOfLeaves, mdd_t *careSet, st_table *alreadyComputed); 00059 00063 /*---------------------------------------------------------------------------*/ 00064 /* Definition of exported functions */ 00065 /*---------------------------------------------------------------------------*/ 00066 00081 array_t * 00082 Part_PartitionBuildFunctions( 00083 graph_t *partition, 00084 array_t *roots, 00085 array_t *leaves, 00086 mdd_t *careSet) 00087 { 00088 st_table *leavesTable; /* To pass to Part_PartitionCollapse */ 00089 array_t *rootVertexArray; /* To pass to Part_PartitionCollapse */ 00090 array_t *result; /* Array of Arrays of mdd_t * */ 00091 int i; 00092 00093 /* Create the table of leaves */ 00094 leavesTable = st_init_table(st_ptrcmp, st_ptrhash); 00095 for(i = 0; i < array_n(leaves); i++) { 00096 int varId = array_fetch(int, leaves, i); 00097 vertex_t *vertexPtr; 00098 00099 /* turned off the check below since it is done later in the */ 00100 /* function SimTestPartInTermsOfCI */ 00101 /* Make sure the leaves have a valid mddId */ 00102 /* assert(varId != NTK_UNASSIGNED_MDD_ID); */ 00103 00104 vertexPtr = Part_PartitionFindVertexByMddId(partition, varId); 00105 if (vertexPtr != NIL(vertex_t)) { 00106 st_insert(leavesTable, (char *)vertexPtr, NIL(char)); 00107 } /* End of if */ 00108 } /* End of for */ 00109 00110 /* Create array of roots */ 00111 rootVertexArray = array_alloc(vertex_t *, array_n(roots)); 00112 for(i = 0; i < array_n(roots); i++) { 00113 char *vertexName = array_fetch(char *, roots, i); 00114 vertex_t *vertexPtr = Part_PartitionFindVertexByName(partition, 00115 vertexName); 00116 00117 /* Make sure the vertex is member of the partition */ 00118 assert(vertexPtr != NIL(vertex_t)); 00119 00120 array_insert(vertex_t *, rootVertexArray, i, vertexPtr); 00121 } /* End of for */ 00122 00123 /* Effectively build the functions */ 00124 result = Part_PartitionCollapse(partition, rootVertexArray, 00125 leavesTable, careSet); 00126 00127 /* Clean up */ 00128 array_free(rootVertexArray); 00129 st_free_table(leavesTable); 00130 00131 return result; 00132 } /* End of Part_PartitionBuildFunctions */ 00133 00147 array_t * 00148 Part_PartitionCollapse( 00149 graph_t *partition, 00150 array_t *roots, 00151 st_table *leaves, 00152 mdd_t *careSet) 00153 { 00154 int i; 00155 st_table *vertexCache; /* Store already processed vertices */ 00156 st_generator *stGen; /* To iterate over st_table */ 00157 vertex_t *vertexPtr; /* Pointer to vertex being processed */ 00158 array_t *result; /* Mvf_Function_ts for the roots */ 00159 Mvf_Function_t *collapsedFunction; 00160 00161 /* Array holding the result */ 00162 result = array_alloc(Mvf_Function_t *, array_n(roots)); 00163 00164 /* Table to store the already computed vertices */ 00165 vertexCache = st_init_table(st_ptrcmp, st_ptrhash); 00166 00167 /* iterate over the given roots */ 00168 arrayForEachItem(vertex_t *, roots, i, vertexPtr) { 00169 /* No cluster vertices are allowed in the roots specification */ 00170 if (PartVertexReadType(vertexPtr) == Part_VertexCluster_c) { 00171 (void) fprintf(vis_stderr, "Warning -- Ignoring cluster vertices in"); 00172 (void) fprintf(vis_stderr, " PartitionCollapse\n"); 00173 } /* End of if */ 00174 else { 00175 Mvf_Function_t *functionLookUp; 00176 00177 if (st_lookup(vertexCache, vertexPtr, &functionLookUp) == 1) { 00178 collapsedFunction = Mvf_FunctionDuplicate(functionLookUp); 00179 } 00180 else { 00181 collapsedFunction = CollapseRecur(partition, vertexPtr, 00182 leaves, careSet, vertexCache); 00183 } 00184 /* Store the function in the result array */ 00185 array_insert(Mvf_Function_t *, result, i, collapsedFunction); 00186 } 00187 } /* End of arrayForEachItem */ 00188 00189 /* 00190 * Save the root nodes from deletion and save their mdds from 00191 * deallocation. 00192 */ 00193 arrayForEachItem(vertex_t *, roots, i, vertexPtr) { 00194 st_delete(vertexCache, &vertexPtr, NULL); 00195 } 00196 00197 /* Delete the intermediate results produced in the computation */ 00198 st_foreach_item(vertexCache, stGen, &vertexPtr, &collapsedFunction) { 00199 Mvf_FunctionFree(collapsedFunction); 00200 } 00201 st_free_table(vertexCache); 00202 00203 return result; 00204 } /* End of Part_PartitionCollapse */ 00205 00206 /*---------------------------------------------------------------------------*/ 00207 /* Definition of internal functions */ 00208 /*---------------------------------------------------------------------------*/ 00209 00210 00211 /*---------------------------------------------------------------------------*/ 00212 /* Definition of static functions */ 00213 /*---------------------------------------------------------------------------*/ 00214 00229 static Mvf_Function_t * 00230 CollapseRecur( 00231 graph_t *partition, 00232 vertex_t *vertexPtr, 00233 st_table *tableOfLeaves, 00234 mdd_t *careSet, 00235 st_table *alreadyComputed) 00236 { 00237 Mvf_Function_t *result; /* Array to return the result */ 00238 Mvf_Function_t *preresult; /* Result before careSet minimization */ 00239 Mvf_Function_t *vertexFn; /* Mvf attached to vertexPtr */ 00240 array_t *faninMddIds; /* Ids of every vertex of the fanin */ 00241 array_t *faninMvfs; /* Array of functions obtained for the fanins */ 00242 Mvf_Function_t *faninResult; /* Function obtained for one fanin */ 00243 edge_t *edgePtr; /* Fanin edge*/ 00244 lsGen gen; /* List generator used for iteration */ 00245 int i; 00246 00247 /* Look up in the alreadyComputedTable */ 00248 if (st_lookup(alreadyComputed, vertexPtr, &result) == 1) { 00249 return result; 00250 } /* End of if */ 00251 00252 /* 00253 * Initialize the arrays needed to call the function 00254 * Mvf_FunctionComposeWithFunctionArray 00255 */ 00256 faninMddIds = array_alloc(int, 0); 00257 faninMvfs = array_alloc(Mvf_Function_t *, 0); 00258 00259 /* Obtain results for each fanin */ 00260 i=0; 00261 foreach_in_edge(vertexPtr, gen, edgePtr) { 00262 vertex_t *fromVertex = g_e_source(edgePtr); 00263 00264 /* Skip the fanins that are leaves */ 00265 if (!st_is_member(tableOfLeaves, (char *)fromVertex) ) { 00266 /* Compute the array recursively */ 00267 faninResult = CollapseRecur(partition, fromVertex, tableOfLeaves, careSet, 00268 alreadyComputed); 00269 array_insert(int, faninMddIds, i, PartVertexReadMddId(fromVertex)); 00270 array_insert(Mvf_Function_t *, faninMvfs, i, faninResult); 00271 i++; 00272 } /* End of if */ 00273 } 00274 00275 /* 00276 * Compose the obtained fanin functions as variables in the 00277 * vertexPtr's function. If all the fanins are leaves, the function 00278 * Mvf_FunctionComposeWithFunctionArray returns a duplicate of the 00279 * array which is needed to be stored in the alreadyComputed table. 00280 */ 00281 vertexFn = PartVertexReadFunction(vertexPtr); 00282 preresult = Mvf_FunctionComposeWithFunctionArray(vertexFn, 00283 faninMddIds, 00284 faninMvfs); 00285 /* Minimize the result with respect to the given care set */ 00286 if (careSet != NIL(mdd_t)) { 00287 result = Mvf_FunctionMinimize(preresult, careSet); 00288 Mvf_FunctionFree(preresult); 00289 } 00290 else { 00291 result = preresult; 00292 } 00293 00294 array_free(faninMddIds); 00295 /* 00296 * There is no need to delete the mdds stored in this array since 00297 * they are stored in the alreadyComputed table. 00298 */ 00299 array_free(faninMvfs); 00300 00301 /* Insert the result in the already-obtained results */ 00302 st_insert(alreadyComputed, (char *)vertexPtr, (char *)result); 00303 00304 return result; 00305 } /* End of CollapseRecur */ 00306 00307 00308 00309 00310 00311 00312