VIS

src/part/partCollapse.c

Go to the documentation of this file.
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