VIS
|
00001 00028 #include "resInt.h" 00029 #include "var_set.h" 00030 00031 static char rcsid[] UNUSED = "$Id: resSmartVarUse.c,v 1.15 2002/09/08 23:56:11 fabio Exp $"; 00032 00033 /*---------------------------------------------------------------------------*/ 00034 /* Constant declarations */ 00035 /*---------------------------------------------------------------------------*/ 00036 00037 #define DEFAULT_NUMBER_OF_VARIABLES (sizeof(int)*16) 00038 #define ELEMENTS_PER_WORD (sizeof(int)<<3) 00039 00040 /*---------------------------------------------------------------------------*/ 00041 /* Type declarations */ 00042 /*---------------------------------------------------------------------------*/ 00043 00044 00045 /*---------------------------------------------------------------------------*/ 00046 /* Structure declarations */ 00047 /*---------------------------------------------------------------------------*/ 00048 00049 00050 /*---------------------------------------------------------------------------*/ 00051 /* Variable declarations */ 00052 /*---------------------------------------------------------------------------*/ 00053 00054 static var_set_t *idSet = NIL(var_set_t); 00055 static int numVarsInUse = 0; 00056 00057 /*--------------------------------------------------------------------*/ 00058 /* Macro declarations */ 00059 /*---------------------------------------------------------------------------*/ 00060 /* based on the fact that var set word size = ELEMENTS_PER_WORD */ 00061 #define MaxSizeOfSet(set) ((set)->n_words * ELEMENTS_PER_WORD) 00062 00065 /*---------------------------------------------------------------------------*/ 00066 /* Static function prototypes */ 00067 /*---------------------------------------------------------------------------*/ 00068 00069 static var_set_t * InitializeVariableManager(int numOfVars); 00070 static void ResizeVariableManager(int newSize); 00071 00075 /*---------------------------------------------------------------------------*/ 00076 /* Definition of exported functions */ 00077 /*---------------------------------------------------------------------------*/ 00078 00079 /*---------------------------------------------------------------------------*/ 00080 /* Definition of internal functions */ 00081 /*---------------------------------------------------------------------------*/ 00082 00100 void 00101 MddCreateVariables(mdd_manager *mgr, 00102 int numVarsToBeAdded) 00103 { 00104 array_t *mvar_values; 00105 array_t *mvar_names = NIL(array_t); 00106 array_t *mvar_strides = NIL(array_t); 00107 int i, two_values; 00108 00109 if (numVarsToBeAdded <= 0) return; 00110 00111 /* Create 2 mvar values 0,1 */ 00112 mvar_values = array_alloc(int, numVarsToBeAdded); 00113 00114 /* Assume we create only Bdd variables here */ 00115 two_values = 2; 00116 for(i = 0; i < numVarsToBeAdded; i++) { 00117 array_insert(int, mvar_values, i, two_values); 00118 } 00119 00120 /* creates the mdd variables and updates the mvar_list field */ 00121 mdd_create_variables(mgr, mvar_values, mvar_names, mvar_strides); 00122 00123 array_free(mvar_values); 00124 00125 } /* End of MddCreateVariables */ 00126 00148 int * 00149 ResResidueVarAllocate(bdd_manager *ddManager, 00150 lsList orderList, 00151 array_t *newIdArray) 00152 { 00153 lsGen listGen; /* generator to step through a list of nodes */ 00154 Ntk_Node_t *nodePtr; /* variable to store node pointer */ 00155 int nodeId; /* mdd id of a node */ 00156 char *flagValue; /* string to store flag value */ 00157 int newVarsRequired; /* number of new variables required by layer */ 00158 int verbose; /* verbosity value */ 00159 var_set_t *assignedSet; /* var_set of assigned Ids in this layer */ 00160 var_set_t *idsNotInList; /* set of assigned Ids not in layer or fanin */ 00161 var_set_t *notAssignedSet; /* var_set of Ids not in this layer */ 00162 int *invPermArray; /* inverse permutation array for shuffle */ 00163 int invPermIndex, newIdIndex; /* iterators */ 00164 int i, j, id; /* iterators */ 00165 int holes; /* number of holes filled so far */ 00166 int lastDdId; /* last variable in dd manager before expansion */ 00167 int numberOfFreeVars; /* number of free variables */ 00168 00169 /* read verbosity flag */ 00170 verbose = 0; 00171 flagValue = Cmd_FlagReadByName("residue_verbosity"); 00172 if (flagValue != NIL(char)) { 00173 verbose = atoi(flagValue); 00174 } 00175 /* no work required */ 00176 if (!lsLength(orderList)) { 00177 error_append("Something wrong order list is empty \n"); 00178 return NIL(int); 00179 } 00180 00181 /* if manager not yet initialized, initialize here */ 00182 if (idSet == NIL(var_set_t)) { 00183 ResResidueInitializeVariableManager(lsLength(orderList)); 00184 } 00185 00186 /* number of nodes with unassigned Ids */ 00187 newVarsRequired = 0; 00188 00189 /* for output nodes list, ids are assigned, just set them in the 00190 * var set 00191 */ 00192 if (var_set_is_empty(idSet)) { 00193 invPermArray = ALLOC(int, bdd_num_vars(ddManager)); 00194 for (i = 0; (unsigned) i < bdd_num_vars(ddManager); i++) { 00195 invPermArray[i] = bdd_get_id_from_level(ddManager, i); 00196 } 00197 invPermIndex = 0; 00198 lsForEachItem(orderList, listGen, nodePtr) { 00199 nodeId = Ntk_NodeReadMddId(nodePtr); 00200 assert(nodeId != NTK_UNASSIGNED_MDD_ID); 00201 /* mark output node mdd id as in use */ 00202 var_set_set_elt(idSet, nodeId); 00203 /* increase number of variables in use */ 00204 numVarsInUse++; 00205 invPermArray[invPermIndex] = nodeId; 00206 invPermArray[nodeId] = invPermIndex; 00207 invPermIndex++; 00208 } 00209 return(invPermArray); 00210 } 00211 00212 /* create a set for already assigned Ids */ 00213 assignedSet = var_set_new(MaxSizeOfSet(idSet)); 00214 00215 /* for each item in the list, check against the set if Id 00216 * is assigned. Also create a set to isolate assigned Ids 00217 * that are not in the list. If unassigned Id, increment 00218 * new variables 00219 */ 00220 lsForEachItem(orderList, listGen, nodePtr) { 00221 nodeId = Ntk_NodeReadMddId(nodePtr); 00222 if (nodeId != NTK_UNASSIGNED_MDD_ID) { 00223 assert(var_set_get_elt(idSet, nodeId) == 1); 00224 /* create a var set with assigned ids in list */ 00225 var_set_set_elt(assignedSet, nodeId); 00226 } else { 00227 newVarsRequired++; 00228 } 00229 } 00230 00231 /* find out from the set, the assigned Ids which are not in 00232 * this list 00233 */ 00234 idsNotInList = var_set_new(MaxSizeOfSet(idSet)); 00235 00236 /* do the operation idSet - assignedSet */ 00237 notAssignedSet = var_set_new(MaxSizeOfSet(idSet)); 00238 notAssignedSet = var_set_not(notAssignedSet, assignedSet); 00239 idsNotInList = var_set_and(idsNotInList, notAssignedSet, idSet); 00240 var_set_free(assignedSet); 00241 var_set_free(notAssignedSet); 00242 00243 00244 /* initialize return value */ 00245 if (newVarsRequired) { 00246 00247 if (verbose >= 3) { 00248 fprintf(vis_stdout, "Number of new variables to be assigned = %d\n", 00249 newVarsRequired); 00250 } 00251 /* compute number of free variables available in the manager */ 00252 numberOfFreeVars = MaxSizeOfSet(idSet) - numVarsInUse; 00253 00254 /* if too few free variables available, resize manager */ 00255 if (numberOfFreeVars < newVarsRequired) { 00256 ResizeVariableManager(numVarsInUse + newVarsRequired); 00257 } 00258 00259 invPermArray = ALLOC(int, bdd_num_vars(ddManager)); 00260 /* fill the inverse permutation array */ 00261 for (i = 0; (unsigned) i < bdd_num_vars(ddManager); i++) { 00262 invPermArray[i] = bdd_get_id_from_level(ddManager, i); 00263 } 00264 /* create the array of new ids ; assign them starting from the 00265 * top(in position) available ID 00266 */ 00267 /* number of available ids in the variable manager */ 00268 holes = 0; 00269 /* There could be two cases here: the number of new vars required 00270 * are filled by holes or new variables are required in the DD 00271 * manager to fill the requirement 00272 */ 00273 00274 /* assign as many new Ids as required by the list */ 00275 for (i = 0; ((unsigned) i < bdd_num_vars(ddManager)) && (holes < newVarsRequired); i++) { 00276 /* done when holes fill the new variable requirements or when 00277 * new variables are needed in the ddManager 00278 */ 00279 if (!var_set_get_elt(idSet, invPermArray[i])) { 00280 /* the number of holes filled above are the variables that exist in 00281 * the ddManager and are not in use 00282 */ 00283 array_insert_last(int , newIdArray, invPermArray[i]); 00284 holes++; 00285 } 00286 } 00287 FREE(invPermArray); 00288 if (verbose >= 4) { 00289 if (holes) { 00290 fprintf(vis_stdout, "Holes filled are ids:"); 00291 arrayForEachItem(int, newIdArray, i, nodeId) { 00292 fprintf(vis_stdout, "%d ", nodeId); 00293 } 00294 fprintf(vis_stdout, "\n"); 00295 } 00296 } 00297 00298 00299 /* newVarsRequired-holes is the number of variables to be added to the 00300 * mdd manager 00301 */ 00302 if (holes < newVarsRequired) { 00303 lastDdId = bdd_num_vars(ddManager); 00304 /* create mdd variables, dirty stuff needed to add to the mvar_list */ 00305 MddCreateVariables((mdd_manager *)ddManager, newVarsRequired - holes); 00306 00307 /* since all the variables were created in the end, use the ids 00308 * starting at the size of the manager 00309 */ 00310 for(i = 0; i < (newVarsRequired-holes); i++) { 00311 array_insert_last(int, newIdArray, lastDdId+i); 00312 } 00313 if (verbose >= 4) { 00314 fprintf(vis_stdout, "New dd ids assigned are: "); 00315 for(i = 0; i < (newVarsRequired-holes); i++) { 00316 fprintf(vis_stdout, "%d ", array_fetch(int, newIdArray, holes+i)); 00317 } 00318 fprintf(vis_stdout, "\n"); 00319 } 00320 } /* end of new vars needed to be assigned in the manager */ 00321 } /* end of new vars need to be assigned to nodes */ 00322 00323 /* Create Inverse Permutation Array for the DD Manager */ 00324 00325 /* create inverse permutation array with nodes in list */ 00326 invPermArray = ALLOC(int, bdd_num_vars(ddManager)); 00327 invPermIndex = 0; 00328 newIdIndex = 0; 00329 if (verbose >= 4) { 00330 fprintf(vis_stdout, "Final order to shuffle heap is:\n"); 00331 } 00332 lsForEachItem(orderList, listGen, nodePtr) { 00333 /* for nodes with assigned ids, get id from node */ 00334 nodeId = Ntk_NodeReadMddId(nodePtr); 00335 if (nodeId == NTK_UNASSIGNED_MDD_ID) { 00336 /* for nodes with unassigned ids, get id from array */ 00337 nodeId = array_fetch(int, newIdArray, newIdIndex); 00338 /* update var set with teh new ids added */ 00339 var_set_set_elt(idSet, nodeId); 00340 numVarsInUse++; 00341 newIdIndex++; 00342 } 00343 invPermArray[invPermIndex] = nodeId; 00344 if (verbose >= 4) { 00345 fprintf(vis_stdout, "%d ", nodeId); 00346 } 00347 invPermIndex++; 00348 } 00349 /* all new ids been accounted for */ 00350 assert(newIdIndex == array_n(newIdArray)); 00351 00352 /* push nodes not in list with assigned Ids below those in list */ 00353 /* fill inv Perm array with Ids that are not in the list 00354 * and not in the idsNotInList. These are ids in the 00355 * ddManager that are not in idSet. 00356 */ 00357 /* if the number of ids in use in residue verification is less 00358 * than that in the manager 00359 */ 00360 if (((unsigned) invPermIndex < bdd_num_vars(ddManager)) || 00361 (!var_set_is_empty(idsNotInList))) { 00362 00363 /* collect the ids that are not in use in residue verification */ 00364 for (j = 0; (unsigned) j < bdd_num_vars(ddManager); j++) { 00365 /* if not idSet, it means that it is not in use by 00366 * residue verification, hence add to the end of invpermArray. 00367 * Get id from the invPermArray that was filled in the 00368 * above lines(where invPermArray was copied in the manager). 00369 * Nodes already in the list will not get added since idSet 00370 * was updated as the list was read. The id is read from the 00371 * invPermArray so as to not disturb the relative order of 00372 * the ids not in use and those in the manager. The check 00373 * has the additional clause on the id < 00374 * MaxSizeOfSet(idsNotInList)since idsNotInList was created 00375 * before the additional variables were added to the manager. 00376 */ 00377 id = bdd_get_id_from_level(ddManager, j); 00378 if ((!var_set_get_elt(idSet, id)) || 00379 (((unsigned) id < MaxSizeOfSet(idsNotInList)) && 00380 (var_set_get_elt(idsNotInList, id)))) { 00381 /* add to the inverse permutation array */ 00382 invPermArray[invPermIndex] = id; 00383 if (verbose >= 4) { 00384 fprintf(vis_stdout, "%d ", id); 00385 } 00386 invPermIndex++; 00387 } /* end of if not in idSet */ 00388 } /* end of iterating through the ids in the dd manager */ 00389 } /* end of if */ 00390 if (verbose >= 4) { 00391 fprintf(vis_stdout, "\n"); 00392 } 00393 00394 var_set_free(idsNotInList); 00395 assert(invPermIndex == bdd_num_vars(ddManager)); 00396 00397 return(invPermArray); 00398 }/* End of ResResidueVarAllocate */ 00399 00412 void 00413 ResResidueVarDeallocate(array_t *currentLayer) 00414 { 00415 int i=0; 00416 int nodeId; 00417 Ntk_Node_t *nodePtr; 00418 00419 LayerForEachNode(currentLayer, i, nodePtr) { 00420 nodeId = Ntk_NodeReadMddId(nodePtr); 00421 var_set_clear_elt(idSet, nodeId); 00422 numVarsInUse--; 00423 } 00424 00425 return; 00426 } /* End of Res_ResidueVarUseDeallocate */ 00427 00441 void 00442 ResResidueFreeVariableManager(void) 00443 { 00444 00445 if (idSet == NIL(var_set_t)) { 00446 return; 00447 } /* End of if */ 00448 00449 numVarsInUse = 0; 00450 var_set_free(idSet); 00451 00452 idSet = NIL(var_set_t); 00453 00454 return; 00455 } /* End of ResResidueFreeVariableManager */ 00456 00466 void 00467 ResResidueInitializeVariableManager(int numOfVars) 00468 { 00469 idSet = InitializeVariableManager(numOfVars); 00470 return; 00471 } /* End of ResResidueInitializeVariableManager */ 00472 00473 00474 /*---------------------------------------------------------------------------*/ 00475 /* Definition of static functions */ 00476 /*---------------------------------------------------------------------------*/ 00477 00490 static var_set_t * 00491 InitializeVariableManager(int numOfVars) 00492 { 00493 if (numOfVars != 0) { 00494 if (numOfVars % ELEMENTS_PER_WORD != 0) { 00495 /* round up to the next word length */ 00496 numOfVars = ((numOfVars/ELEMENTS_PER_WORD)+1)*ELEMENTS_PER_WORD; 00497 } 00498 } else { 00499 numOfVars = DEFAULT_NUMBER_OF_VARIABLES; 00500 } 00501 00502 /* default value of number of words = 2 */ 00503 return var_set_new(numOfVars); 00504 00505 } /* End of InitializeVariableManager */ 00506 00520 static void 00521 ResizeVariableManager(int newSize) 00522 { 00523 var_set_t *newSet; 00524 int i; 00525 00526 /* resize only if the new size is larger than the previous size */ 00527 assert(newSize > MaxSizeOfSet(idSet)); 00528 00529 /* create a new set with the new size */ 00530 newSet = InitializeVariableManager(newSize); 00531 00532 for (i=0; i < idSet->n_words; i++) { 00533 newSet->data[i] |= idSet->data[i]; 00534 } 00535 /* free the old id set, not using ResResidueFreeVariableManager() 00536 * because it resets the numVarsInUse 00537 */ 00538 var_set_free(idSet); 00539 00540 idSet = newSet; 00541 return; 00542 } /* End of ResizeVariableManager */ 00543 00544 00545 00546 00547 00548 00549 00550 00551 00552 00553 00554 00555