VIS
|
00001 00017 #include "synthInt.h" 00018 00019 static char rcsid[] UNUSED = "$Id: synthFactor.c,v 1.49 2005/04/23 14:37:51 jinh Exp $"; 00020 00021 /*---------------------------------------------------------------------------*/ 00022 /* Constant declarations */ 00023 /*---------------------------------------------------------------------------*/ 00024 00025 00026 /*---------------------------------------------------------------------------*/ 00027 /* Type declarations */ 00028 /*---------------------------------------------------------------------------*/ 00029 00030 00031 /*---------------------------------------------------------------------------*/ 00032 /* Structure declarations */ 00033 /*---------------------------------------------------------------------------*/ 00034 00046 typedef struct ml_size_list { 00047 int size; /* the number of literals */ 00048 char *string; /* string of the size to put into st_table */ 00049 struct ml_size_list *next; 00050 } MlSizeList; 00051 00052 /*---------------------------------------------------------------------------*/ 00053 /* Variable declarations */ 00054 /*---------------------------------------------------------------------------*/ 00055 00056 static bdd_node *(* ZddProductFunc)(bdd_manager *, bdd_node *, bdd_node *) = bdd_zdd_product; 00057 static bdd_node *(* ZddProductRecurFunc)(bdd_manager *, bdd_node *, bdd_node *) = bdd_zdd_product_recur; 00058 static bdd_node *(* ZddDivideFunc)(bdd_manager *, bdd_node *, bdd_node *) = bdd_zdd_weak_div; 00059 static bdd_node *(* ZddDivideRecurFunc)(bdd_manager *, bdd_node *, bdd_node *) = bdd_zdd_weak_div_recur; 00060 static bdd_node *(* ZddDivisorFunc)(bdd_manager *, bdd_node *) = Synth_ZddQuickDivisor; 00061 static int NumTree; 00062 static int ResolveConflictMode = 0; 00063 static st_table *HeadListTable, *TailListTable; 00064 static MlTree *MlTreeHead; 00065 static MlSizeList *MlSizeHead; 00066 00067 int UseMtree = 1; 00068 int UseCommonDivisor = 1; 00069 int TryNodeSharing = 0; 00070 int Resubstitution = 1; 00071 int RemainderComplement = 0; 00072 int noMemoryFlag = 0; 00073 int VerifyTreeMode = 0; 00074 /* 00075 ** 0 : nothing 00076 ** 1 : incrementally 00077 ** 2 : recursively after each factorization 00078 ** 3 : 2 & dump blif file with bdds 00079 */ 00080 00083 /*---------------------------------------------------------------------------*/ 00084 /* Static function prototypes */ 00085 /*---------------------------------------------------------------------------*/ 00086 00087 static MlTree * ResolveConflictNode(bdd_manager *dd, st_table *table, MlTree *tree1, MlTree *tree2, int comp_flag, int verbosity); 00088 static void DeleteMlTree(bdd_manager *dd, st_table *table, MlTree *kill_tree, MlTree *live_tree, int deref, int comp_flag); 00089 static void UnlinkMlTree(MlTree *kill_tree); 00090 static void DeleteMlSizeList(MlTree *tree); 00091 static int InsertMlTable(st_table *table, bdd_node *node, MlTree *tree); 00092 static bdd_node * MakeComplementOfZddCover(bdd_manager *dd, bdd_node *node, int verbosity); 00093 static char * GetIntString(int v); 00094 static void VerifyTreeList(void); 00095 00099 /*---------------------------------------------------------------------------*/ 00100 /* Definition of exported functions */ 00101 /*---------------------------------------------------------------------------*/ 00102 00103 00104 00105 /*---------------------------------------------------------------------------*/ 00106 /* Definition of internal functions */ 00107 /*---------------------------------------------------------------------------*/ 00108 00109 00121 bdd_node * 00122 (* SynthGetZddProductFunc(void))(bdd_manager *, bdd_node *, bdd_node *) 00123 { 00124 return(ZddProductFunc); 00125 } 00126 00127 00139 bdd_node * 00140 (* SynthGetZddProductRecurFunc(void))(bdd_manager *, bdd_node *, bdd_node *) 00141 { 00142 return(ZddProductRecurFunc); 00143 } 00144 00145 00157 bdd_node * 00158 (* SynthGetZddDivideFunc(void))(bdd_manager *, bdd_node *, bdd_node *) 00159 { 00160 return(ZddDivideFunc); 00161 } 00162 00163 00175 bdd_node * 00176 (* SynthGetZddDivideRecurFunc(void))(bdd_manager *, bdd_node *, bdd_node *) 00177 { 00178 return(ZddDivideRecurFunc); 00179 } 00180 00181 00193 bdd_node * 00194 (* SynthGetZddDivisorFunc(void))(bdd_manager *, bdd_node *) 00195 { 00196 return(ZddDivisorFunc); 00197 } 00198 00199 00211 void 00212 SynthSetZddDivisorFunc(int mode) 00213 { 00214 if (mode == 0) 00215 ZddDivisorFunc = Synth_ZddQuickDivisor; 00216 else if (mode == 1) 00217 ZddDivisorFunc = Synth_ZddLeastDivisor; 00218 else if (mode == 2) 00219 ZddDivisorFunc = Synth_ZddMostDivisor; 00220 else 00221 ZddDivisorFunc = Synth_ZddLevelZeroDivisor; 00222 } 00223 00224 00237 void 00238 SynthGetSpaceString(char *string, 00239 int n, 00240 int max) 00241 { 00242 int i; 00243 00244 if (n >= max - 1) 00245 n = max - 2; 00246 00247 for (i = 0; i < n; i++) 00248 string[i] = ' '; 00249 string[n] = '\0'; 00250 } 00251 00252 00267 MlTree * 00268 SynthLookupMlTable(st_table *table, 00269 bdd_manager *dd, 00270 bdd_node *node, 00271 int candidate, 00272 int verbosity) 00273 { 00274 MlTree *tree, *m_tree; 00275 int flag; 00276 00277 flag = st_lookup(table, (char *)node, &tree); 00278 if (flag) { 00279 if (MlTree_Regular(tree)->candidate) { 00280 m_tree = MlTree_Regular(tree); 00281 if (candidate) { 00282 if (!SynthUseCandidate(table, dd, m_tree, verbosity)) { 00283 return(NULL); 00284 } 00285 } 00286 } 00287 if (candidate) 00288 SynthSetSharedFlag(dd, tree); 00289 return(tree); 00290 } 00291 00292 return((MlTree *)NULL); 00293 } 00294 00295 00310 int 00311 SynthUseCandidate(st_table *table, 00312 bdd_manager *dd, 00313 MlTree *m_tree, 00314 int verbosity) 00315 { 00316 MlTree *parent, *c_tree, *tmp_tree; 00317 bdd_node *one = bdd_read_one(dd); 00318 bdd_node *zero = bdd_read_zero(dd); 00319 int ref; 00320 int comp_flag; 00321 00322 m_tree = MlTree_Regular(m_tree); 00323 if (!m_tree->r) { 00324 (void) fprintf(vis_stdout, 00325 "** synth fatal: Internal error in synthesize_network.\n"); 00326 (void) fprintf(vis_stdout, 00327 "** synth fatal: Please report this bug to VIS developers.\n"); 00328 return (0); 00329 } 00330 parent = m_tree->r; 00331 m_tree->r = (MlTree *)NULL; 00332 m_tree->candidate = 0; 00333 c_tree = SynthFindOrCreateMlTree(table, dd, zero, 1, 0, &ref, verbosity); 00334 if (!c_tree) 00335 return (0); 00336 if (MlTree_IsComplement(c_tree)) { 00337 c_tree = MlTree_Regular(c_tree); 00338 m_tree->r_comp = 1; 00339 } 00340 tmp_tree = c_tree; 00341 c_tree = SynthCheckAndMakeComplement(dd, table, c_tree, 00342 &comp_flag, verbosity); 00343 if (!c_tree) 00344 return (0); 00345 else if (c_tree != tmp_tree) { 00346 if (comp_flag) 00347 m_tree->r_comp = 1; 00348 ref = 1; 00349 } 00350 m_tree->r = c_tree; 00351 m_tree->r_ref = ref; 00352 parent->q = m_tree; 00353 parent->q_ref = 0; 00354 parent->q_comp = 0; 00355 c_tree = SynthFindOrCreateMlTree(table, dd, one, 1, 0, &ref, verbosity); 00356 if (!c_tree) 00357 return (0); 00358 if (MlTree_IsComplement(c_tree)) { 00359 c_tree = MlTree_Regular(c_tree); 00360 parent->d_comp = 1; 00361 } else 00362 parent->d_comp = 0; 00363 parent->d = c_tree; 00364 parent->d_ref = ref; 00365 m_tree->id = NumTree; 00366 NumTree++; 00367 if (verbosity > 1) 00368 (void)fprintf(vis_stdout, "** synth info: Used candidate %d.\n", 00369 m_tree->id); 00370 if (VerifyTreeMode) { 00371 SynthVerifyTree(dd, parent, 0); 00372 SynthVerifyTree(dd, m_tree, 0); 00373 SynthVerifyMlTable(dd, table); 00374 } 00375 return(1); 00376 } 00377 00378 00394 MlTree * 00395 SynthFindOrCreateMlTree(st_table *table, 00396 bdd_manager *dd, 00397 bdd_node *f, 00398 int leaf, 00399 int candidate, 00400 int *ref, 00401 int verbosity) 00402 { 00403 MlTree *tree; 00404 bdd_node *one = bdd_read_one(dd); 00405 bdd_node *zero = bdd_read_zero(dd); 00406 00407 tree = SynthLookupMlTable(table, dd, f, 1, verbosity); 00408 if (tree) { 00409 if (MlTree_Regular(tree)->candidate) { 00410 if (!SynthUseCandidate(table, dd, tree, verbosity)) { 00411 return(NULL); 00412 } 00413 SynthSetSharedFlag(dd, tree); 00414 } 00415 *ref = 1; 00416 return(tree); 00417 } else if (bdd_read_reordered_field(dd) || noMemoryFlag == 1) 00418 return(NULL); 00419 00420 tree = ALLOC(MlTree, 1); 00421 if (!tree) { 00422 noMemoryFlag = 1; 00423 return(NULL); 00424 } 00425 (void)memset((void *)tree, 0, sizeof(MlTree)); 00426 tree->node = f; 00427 bdd_ref(f); 00428 tree->leaf = leaf; 00429 if (bdd_bdd_T(f) == one && bdd_bdd_E(f) == zero) 00430 tree->pi = 1; 00431 if (candidate) 00432 tree->candidate = 1; 00433 if (!tree->candidate) { 00434 tree->id = NumTree; 00435 NumTree++; 00436 } 00437 if (!InsertMlTable(table, f, tree)) { 00438 bdd_recursive_deref_zdd(dd, f); 00439 FREE(tree); 00440 return NULL; 00441 } 00442 *ref = 0; 00443 00444 return(tree); 00445 } 00446 00447 00459 void 00460 SynthInitMlTable(void) 00461 { 00462 NumTree = 1; 00463 MlTreeHead = NIL(MlTree); 00464 MlSizeHead = NIL(MlSizeList); 00465 HeadListTable = st_init_table(strcmp, st_strhash); 00466 TailListTable = st_init_table(strcmp, st_strhash); 00467 } 00468 00469 00481 void 00482 SynthClearMlTable(bdd_manager *dd, 00483 st_table *table) 00484 { 00485 st_generator *gen; 00486 bdd_node *k; 00487 MlTree *r; 00488 MlSizeList *l, *next; 00489 00490 st_foreach_item(table, gen, (&k), (&r)) { 00491 bdd_recursive_deref_zdd(dd, k); 00492 if (!MlTree_IsComplement(r)) 00493 SynthFreeMlTree(r, 0); 00494 } 00495 00496 NumTree = 1; 00497 MlTreeHead = NIL(MlTree); 00498 00499 st_free_table(HeadListTable); 00500 st_free_table(TailListTable); 00501 HeadListTable = TailListTable = NIL(st_table); 00502 00503 l = MlSizeHead; 00504 while (l) { 00505 next = l->next; 00506 FREE(l->string); 00507 FREE(l); 00508 l = next; 00509 } 00510 MlSizeHead = NIL(MlSizeList); 00511 } 00512 00513 00532 void 00533 SynthPutMlTreeInList(bdd_manager *dd, 00534 MlTree *tree, 00535 int candidate) 00536 { 00537 int i; 00538 int word, size; 00539 unsigned int *mask; 00540 int top; 00541 MlTree *last; 00542 MlSizeList *list, *pre_list, *new_list; 00543 00544 word = sizeof(int) * 8; 00545 size = bdd_num_zdd_vars(dd) / word + 1; 00546 00547 if (candidate) { 00548 tree->nLiterals = tree->q->nLiterals + tree->d->nLiterals; 00549 00550 mask = ALLOC(unsigned int, size); 00551 for (i = 0; i < size; i++) 00552 mask[i] = tree->q->support[i] | tree->d->support[i]; 00553 tree->support = mask; 00554 } else { 00555 if (tree->nLiterals == 0) { 00556 top = tree->top; 00557 tree->top = 1; 00558 tree->nLiterals = SynthCountMlLiteral(dd, tree, 0); 00559 tree->top = top; 00560 } 00561 00562 if (!tree->support) { 00563 mask = ALLOC(unsigned int, size); 00564 (void)memset((void *)mask, 0, size * sizeof(int)); 00565 SynthGetSupportMask(dd, tree->node, mask); 00566 tree->support = mask; 00567 } 00568 } 00569 00570 if ((!MlTreeHead) || (tree->nLiterals > MlTreeHead->nLiterals)) { 00571 tree->next = MlTreeHead; 00572 MlTreeHead = tree; 00573 00574 list = ALLOC(MlSizeList, 1); 00575 list->size = tree->nLiterals; 00576 list->string = GetIntString(list->size); 00577 list->next = MlSizeHead; 00578 MlSizeHead = list; 00579 00580 st_insert(HeadListTable, list->string, (char *)tree); 00581 st_insert(TailListTable, list->string, (char *)tree); 00582 } else { 00583 pre_list = NIL(MlSizeList); 00584 list = MlSizeHead; 00585 while (list) { 00586 if (tree->nLiterals == list->size) { 00587 if (list == MlSizeHead) { 00588 tree->next = MlTreeHead; 00589 MlTreeHead = tree; 00590 st_insert(HeadListTable, list->string, (char *)tree); 00591 } else { 00592 st_lookup(TailListTable, list->string, (&last)); 00593 tree->next = last->next; 00594 last->next = tree; 00595 st_insert(TailListTable, list->string, (char *)tree); 00596 } 00597 break; 00598 } else if (tree->nLiterals > list->size) { 00599 st_lookup(TailListTable, pre_list->string, (&last)); 00600 tree->next = last->next; 00601 last->next = tree; 00602 00603 new_list = ALLOC(MlSizeList, 1); 00604 new_list->size = tree->nLiterals; 00605 new_list->string = GetIntString(new_list->size); 00606 new_list->next = list; 00607 pre_list->next = new_list; 00608 00609 st_insert(HeadListTable, new_list->string, (char *)tree); 00610 st_insert(TailListTable, new_list->string, (char *)tree); 00611 break; 00612 } else if (!list->next) { 00613 st_lookup(TailListTable, list->string, (&last)); 00614 tree->next = NIL(MlTree); 00615 last->next = tree; 00616 00617 new_list = ALLOC(MlSizeList, 1); 00618 new_list->size = tree->nLiterals; 00619 new_list->string = GetIntString(new_list->size); 00620 new_list->next = NIL(MlSizeList); 00621 list->next = new_list; 00622 00623 st_insert(HeadListTable, new_list->string, (char *)tree); 00624 st_insert(TailListTable, new_list->string, (char *)tree); 00625 break; 00626 } 00627 pre_list = list; 00628 list = list->next; 00629 } 00630 } 00631 00632 if (VerifyTreeMode) 00633 VerifyTreeList(); 00634 } 00635 00636 00649 MlTree * 00650 SynthGetHeadTreeOfSize(int size) 00651 { 00652 MlTree *head; 00653 MlSizeList *list; 00654 00655 list = MlSizeHead; 00656 while (list) { 00657 if (size == list->size) { 00658 st_lookup(HeadListTable, list->string, (&head)); 00659 return(head); 00660 } else if (size > list->size) 00661 return(NULL); 00662 list = list->next; 00663 } 00664 return(NULL); 00665 } 00666 00667 00684 MlTree * 00685 SynthCheckAndMakeComplement(bdd_manager *dd, 00686 st_table *table, 00687 MlTree *tree, 00688 int *comp_flag, 00689 int verbosity) 00690 { 00691 bdd_node *c; 00692 MlTree *c_tree, *new_; 00693 00694 if (MlTree_IsComplement(tree)) 00695 return(tree); 00696 00697 *comp_flag = 0; 00698 if (!tree->complement) { 00699 c = MakeComplementOfZddCover(dd, tree->node, verbosity); 00700 if (!c) 00701 return(NULL); 00702 bdd_ref(c); 00703 c_tree = SynthLookupMlTable(table, dd, (char *)c, 0, verbosity); 00704 if (c_tree) { 00705 MlTree *m_tree = MlTree_Regular(c_tree); 00706 if (MlTree_Regular(tree)->candidate && 00707 MlTree_Regular(c_tree)->candidate) { 00708 /* 00709 ** tree m_tree 00710 ** |\ /| 00711 ** | \/ | 00712 ** | / \ | 00713 ** q d 00714 **/ 00715 00716 if (ResolveConflictMode == 0 || c_tree == m_tree || 00717 tree->nLiterals <= m_tree->nLiterals) { 00718 /* throw away m_tree and assign c to tree->complement */ 00719 UnlinkMlTree(m_tree); 00720 bdd_recursive_deref_zdd(dd, m_tree->node); 00721 bdd_recursive_deref_zdd(dd, m_tree->complement); 00722 st_delete(table, (char **)(&m_tree->node), NIL(char *)); 00723 st_delete(table, (char **)(&m_tree->complement), NIL(char *)); 00724 if (m_tree->support) 00725 FREE(m_tree->support); 00726 FREE(m_tree); 00727 tree->complement = c; 00728 if (!InsertMlTable(table, c, MlTree_Not(tree))) { 00729 tree->complement = NIL(bdd_node); 00730 bdd_recursive_deref_zdd(dd, c); 00731 return(NULL); 00732 } 00733 } else if (c_tree != m_tree) { 00734 /* takes m_tree's contents and throws away m_tree */ 00735 UnlinkMlTree(tree); 00736 UnlinkMlTree(m_tree); 00737 bdd_recursive_deref_zdd(dd, tree->node); 00738 st_delete(table, (char **)(&tree->node), NIL(char *)); 00739 if (tree->support) 00740 FREE(tree->support); 00741 memcpy(tree, m_tree, sizeof(MlTree)); 00742 FREE(m_tree); 00743 tree->complement = c; 00744 if (!InsertMlTable(table, tree->node, tree)) 00745 return(NULL); 00746 if (!InsertMlTable(table, tree->complement, MlTree_Not(tree))) 00747 return(NULL); 00748 } else { /* It never happens at this time, 00749 * the case(c_tree == m_tree) is already taken care of. 00750 * But, it should be implemented to improve 00751 * in the future. 00752 */ 00753 } 00754 if (VerifyTreeMode) { 00755 SynthVerifyTree(dd, tree, 0); 00756 SynthVerifyMlTable(dd, table); 00757 } 00758 return(tree); 00759 } else if (MlTree_Regular(tree)->candidate) { 00760 /* 00761 ** tree m_tree 00762 ** |\ /|\ 00763 ** | \/ | \ 00764 ** | / \ | \ 00765 ** q d r 00766 **/ 00767 00768 if (tree->r == m_tree) { 00769 if (c_tree == m_tree) 00770 *comp_flag = 1; 00771 else 00772 *comp_flag = 0; 00773 00774 if (ResolveConflictMode == 0 || c_tree == m_tree || 00775 m_tree->nLiterals <= tree->nLiterals) { 00776 /* throw away tree and returns m_tree */ 00777 bdd_recursive_deref_zdd(dd, c); 00778 UnlinkMlTree(tree); 00779 bdd_recursive_deref_zdd(dd, tree->node); 00780 st_delete(table, (char **)(&m_tree->node), NIL(char *)); 00781 if (tree->support) 00782 FREE(tree->support); 00783 FREE(tree); 00784 } else if (c_tree != m_tree) { 00785 /* 00786 ** tree->complement = m_tree->complement 00787 ** 00788 ** tree m_tree 00789 ** |\ /|\ 00790 ** | \/ | \ 00791 ** | / \ | \ 00792 ** q d r 00793 **/ 00794 00795 MlTree *r_tree, *tmp_tree; 00796 int r_comp; 00797 int ref; 00798 bdd_node *zero = bdd_read_zero(dd); 00799 00800 /* takes tree's contents and throw away tree and m_tree->r */ 00801 00802 bdd_recursive_deref_zdd(dd, c); 00803 r_tree = SynthFindOrCreateMlTree(table, dd, zero, 1, 0, &ref, 00804 verbosity); 00805 if (!r_tree) 00806 return(NULL); 00807 if (MlTree_IsComplement(r_tree)) { 00808 r_tree = MlTree_Regular(r_tree); 00809 m_tree->r_comp = 1; 00810 } 00811 tmp_tree = r_tree; 00812 r_tree = SynthCheckAndMakeComplement(dd, table, r_tree, 00813 &r_comp, verbosity); 00814 if (!r_tree) 00815 return(NULL); 00816 else if (r_tree != tmp_tree) { 00817 if (r_comp) 00818 m_tree->r_comp = 1; 00819 ref = 1; 00820 } 00821 tree->r = r_tree; 00822 tree->r_ref = ref; 00823 tree->id = m_tree->id; 00824 tree->candidate = 0; 00825 00826 bdd_recursive_deref_zdd(dd, m_tree->node); 00827 bdd_recursive_deref_zdd(dd, m_tree->complement); 00828 st_delete(table, (char **)(&m_tree->node), NIL(char *)); 00829 st_delete(table, (char **)(&m_tree->complement), NIL(char *)); 00830 UnlinkMlTree(m_tree); 00831 if (m_tree->support) 00832 FREE(m_tree->support); 00833 ref = m_tree->r_ref; 00834 r_tree = m_tree->r; 00835 memcpy(m_tree, tree, sizeof(MlTree)); 00836 FREE(tree); 00837 SynthPutMlTreeInList(dd, m_tree, 0); 00838 00839 if (ref) { 00840 if (r_tree->shared) 00841 DeleteMlTree(dd, table, r_tree, NULL, 1, 0); 00842 } else 00843 DeleteMlTree(dd, table, r_tree, NULL, 1, 0); 00844 } else { /* It never happens at this time, 00845 * the case(c_tree == m_tree) is already taken care of. 00846 * But, it should be implemented to improve 00847 * in the future. 00848 */ 00849 } 00850 if (VerifyTreeMode) { 00851 SynthVerifyTree(dd, m_tree, 0); 00852 SynthVerifyMlTable(dd, table); 00853 } 00854 return(m_tree); 00855 } 00856 if (!SynthUseCandidate(table, dd, tree, verbosity)) { 00857 bdd_recursive_deref_zdd(dd, c); 00858 return(NULL); 00859 } 00860 SynthSetSharedFlag(dd, tree); 00861 } else if (MlTree_Regular(c_tree)->candidate) { 00862 if (m_tree->r == tree) { 00863 /* 00864 ** m_tree tree 00865 ** |\ /|\ 00866 ** | \/ | \ 00867 ** | / \ | \ 00868 ** q d r 00869 **/ 00870 00871 if (ResolveConflictMode == 0 || c_tree == m_tree || 00872 tree->nLiterals <= m_tree->nLiterals) { 00873 /* throw away m_tree and assign c to tree->complement */ 00874 UnlinkMlTree(m_tree); 00875 bdd_recursive_deref_zdd(dd, m_tree->node); 00876 bdd_recursive_deref_zdd(dd, m_tree->complement); 00877 st_delete(table, (char **)(&m_tree->node), NIL(char *)); 00878 st_delete(table, (char **)(&m_tree->complement), NIL(char *)); 00879 if (m_tree->support) 00880 FREE(m_tree->support); 00881 FREE(m_tree); 00882 tree->complement = c; 00883 if (!InsertMlTable(table, c, MlTree_Not(tree))) { 00884 tree->complement = NIL(bdd_node); 00885 bdd_recursive_deref_zdd(dd, c); 00886 return(NULL); 00887 } 00888 } else if (c_tree != m_tree) { 00889 /* 00890 ** tree->complement = m_tree->complement 00891 ** 00892 ** m_tree tree 00893 ** |\ /|\ 00894 ** | \/ | \ 00895 ** | / \ | \ 00896 ** q d r 00897 **/ 00898 00899 MlTree *r_tree, *tmp_tree; 00900 int r_comp; 00901 int ref; 00902 bdd_node *zero = bdd_read_zero(dd); 00903 00904 /* takes m_tree's contents and throw away m_tree and tree->r */ 00905 00906 bdd_recursive_deref_zdd(dd, c); 00907 r_tree = SynthFindOrCreateMlTree(table, dd, zero, 1, 0, &ref, 00908 verbosity); 00909 if (!r_tree) 00910 return(NULL); 00911 if (MlTree_IsComplement(r_tree)) { 00912 r_tree = MlTree_Regular(r_tree); 00913 m_tree->r_comp = 1; 00914 } 00915 tmp_tree = r_tree; 00916 r_tree = SynthCheckAndMakeComplement(dd, table, r_tree, 00917 &r_comp, verbosity); 00918 if (!r_tree) 00919 return(NULL); 00920 else if (r_tree != tmp_tree) { 00921 if (r_comp) 00922 m_tree->r_comp = 1; 00923 ref = 1; 00924 } 00925 m_tree->r = r_tree; 00926 m_tree->r_ref = ref; 00927 m_tree->id = tree->id; 00928 m_tree->candidate = 0; 00929 00930 bdd_recursive_deref_zdd(dd, tree->node); 00931 st_delete(table, (char **)(&tree->node), NIL(char *)); 00932 UnlinkMlTree(tree); 00933 if (tree->support) 00934 FREE(tree->support); 00935 ref = tree->r_ref; 00936 r_tree = tree->r; 00937 memcpy(tree, m_tree, sizeof(MlTree)); 00938 FREE(m_tree); 00939 SynthPutMlTreeInList(dd, tree, 0); 00940 00941 if (ref) { 00942 if (r_tree->shared) 00943 DeleteMlTree(dd, table, r_tree, NULL, 1, 0); 00944 } else 00945 DeleteMlTree(dd, table, r_tree, NULL, 1, 0); 00946 } else { /* It never happens at this time, 00947 * the case(c_tree == m_tree) is already taken care of. 00948 * But, it should be implemented to improve 00949 * in the future. 00950 */ 00951 /* 00952 ** tree->complement = m_tree->node 00953 ** 00954 ** m_tree tree 00955 ** |\ /|\ 00956 ** | \/ | \ 00957 ** | / \ | \ 00958 ** q d r 00959 **/ 00960 } 00961 return(tree); 00962 } 00963 if (!SynthUseCandidate(table, dd, m_tree, verbosity)) { 00964 bdd_recursive_deref_zdd(dd, c); 00965 return(NULL); 00966 } 00967 SynthSetSharedFlag(dd, m_tree); 00968 } 00969 00970 bdd_recursive_deref_zdd(dd, c); 00971 if (c_tree == m_tree) 00972 *comp_flag = 1; 00973 else 00974 *comp_flag = 0; 00975 00976 if (verbosity) 00977 (void) fprintf(vis_stdout, "** synth warning: Duplicate entry ...\n"); 00978 new_ = ResolveConflictNode(dd, table, c_tree, tree, *comp_flag, verbosity); 00979 if (verbosity) 00980 (void) fprintf(vis_stdout, "** synth info: Conflict was resolved.\n"); 00981 if (VerifyTreeMode) { 00982 SynthVerifyTree(dd, new_, 0); 00983 SynthVerifyMlTable(dd, table); 00984 } 00985 return(new_); 00986 } else if (bdd_read_reordered_field(dd) || noMemoryFlag == 1) { 00987 bdd_recursive_deref_zdd(dd, c); 00988 return(NULL); 00989 } 00990 tree->complement = c; 00991 if (!InsertMlTable(table, c, MlTree_Not(tree))) { 00992 tree->complement = NIL(bdd_node); 00993 bdd_recursive_deref_zdd(dd, c); 00994 return NULL; 00995 } 00996 } 00997 return(tree); 00998 } 00999 01000 01012 void 01013 SynthSetSharedFlag(bdd_manager *dd, 01014 MlTree *tree) 01015 { 01016 MlTree *t; 01017 bdd_node *one = bdd_read_one(dd); 01018 bdd_node *zero = bdd_read_zero(dd); 01019 01020 t = MlTree_Regular(tree); 01021 if (t->node == zero || t->node == one) 01022 return; 01023 if (t->pi == 0) 01024 t->shared = 1; 01025 } 01026 01027 01043 int 01044 SynthPostFactoring(bdd_manager *dd, 01045 st_table *table, 01046 MlTree *(* factoring_func)(bdd_manager *, st_table *, 01047 bdd_node *, int, int *, MlTree *, 01048 int, MlTree *, int), 01049 int verbosity) 01050 { 01051 MlTree *cur, *candy; 01052 int ref; 01053 bdd_node *q; 01054 bdd_node *zero = bdd_read_zero(dd); 01055 01056 if (VerifyTreeMode) { 01057 SynthVerifyMlTable(dd, table); 01058 VerifyTreeList(); 01059 } 01060 01061 cur = MlTreeHead; 01062 while (cur) { 01063 if (cur->leaf) { 01064 if (cur->nLiterals < 2) 01065 break; 01066 candy = cur->next; 01067 while (candy) { 01068 if (candy->nLiterals == 1) 01069 break; 01070 else if (candy->leaf == 0 || 01071 candy->nLiterals == cur->nLiterals) { 01072 candy = candy->next; 01073 continue; 01074 } 01075 01076 q = (* ZddDivideFunc)(dd, cur->node, candy->node); 01077 if (!q) 01078 return(1); 01079 bdd_ref(q); 01080 /* Even though we deref q, it still exists as a 01081 * pointer and beyond this point, we use it only to 01082 * check if it is zero or not. 01083 */ 01084 bdd_recursive_deref_zdd(dd,q); 01085 if (q != zero) { 01086 (void) (* factoring_func)(dd, table, cur->node, 01087 0, &ref, candy, 0, cur, verbosity); 01088 if (VerifyTreeMode) { 01089 SynthVerifyTree(dd, cur, 0); 01090 SynthVerifyMlTable(dd, table); 01091 VerifyTreeList(); 01092 } 01093 if (bdd_read_reordered_field(dd) || noMemoryFlag == 1) 01094 return(1); 01095 01096 SynthSetSharedFlag(dd, candy); 01097 break; 01098 } else { 01099 q = (* ZddDivideFunc)(dd, cur->node, 01100 candy->complement); 01101 if (!q) 01102 return(1); 01103 bdd_ref(q); 01104 /* Even though we deref q, it still exists as a 01105 * pointer and beyond this point, we use it only 01106 * to check if it is zero or not. 01107 */ 01108 bdd_recursive_deref_zdd(dd,q); 01109 if (q != zero) { 01110 (void) (* factoring_func)(dd, table, cur->node, 0, 01111 &ref, candy, 1, cur, verbosity); 01112 if (VerifyTreeMode) { 01113 SynthVerifyTree(dd, cur, 0); 01114 SynthVerifyMlTable(dd, table); 01115 VerifyTreeList(); 01116 } 01117 if (bdd_read_reordered_field(dd) || noMemoryFlag == 1 ) 01118 return(1); 01119 SynthSetSharedFlag(dd, candy); 01120 break; 01121 } 01122 } 01123 candy = candy->next; 01124 } 01125 } 01126 cur = cur->next; 01127 } 01128 return(0); 01129 } 01130 01131 01145 void 01146 SynthUpdateRefOfParent(MlTree *top) 01147 { 01148 MlTree *cur; 01149 01150 cur = MlTreeHead; 01151 while (cur) { 01152 if (cur->q == top) 01153 cur->q_ref = 1; 01154 else if (cur->d == top) 01155 cur->d_ref = 1; 01156 else if (cur->r == top) 01157 cur->r_ref = 1; 01158 cur = cur->next; 01159 } 01160 } 01161 01162 01176 void 01177 SynthVerifyTree(bdd_manager *dd, 01178 MlTree *tree, 01179 int flag) 01180 { 01181 bdd_node *node, *comp; 01182 bdd_node *q, *d, *r, *f, *m; 01183 int bdd_diff; 01184 01185 if (flag && !tree->leaf) { 01186 if (!tree->q_ref) 01187 SynthVerifyTree(dd, tree->q, flag); 01188 if (!tree->d_ref) 01189 SynthVerifyTree(dd, tree->d, flag); 01190 if (!tree->r_ref) 01191 SynthVerifyTree(dd, tree->r, flag); 01192 } 01193 01194 node = bdd_make_bdd_from_zdd_cover(dd, tree->node); 01195 if (!node) 01196 return; 01197 bdd_ref(node); 01198 if (tree->complement) { 01199 comp = bdd_make_bdd_from_zdd_cover(dd, tree->complement); 01200 if (!comp) { 01201 bdd_recursive_deref(dd, node); 01202 return; 01203 } 01204 bdd_ref(comp); 01205 01206 if (node != bdd_not_bdd_node(comp)) { 01207 (void) fprintf(vis_stdout, 01208 "** synth error: Invalid complement node in tree [%d].\n", tree->id); 01209 } 01210 01211 bdd_recursive_deref(dd, comp); 01212 } 01213 01214 if (tree->leaf) { 01215 if (tree->q) { 01216 (void) fprintf(vis_stdout, 01217 "** synth error: q exists in leaf tree [%d].\n", tree->id); 01218 } 01219 if (tree->d) { 01220 (void) fprintf(vis_stdout, 01221 "** synth error: d exists in leaf tree [%d].\n", tree->id); 01222 } 01223 if (tree->r) { 01224 (void) fprintf(vis_stdout, 01225 "** synth error: r exists in leaf tree [%d].\n", tree->id); 01226 } 01227 if (tree->q_ref) { 01228 (void) fprintf(vis_stdout, 01229 "** synth error: q_ref = 1 in leaf tree [%d].\n", tree->id); 01230 } 01231 if (tree->d_ref) { 01232 (void) fprintf(vis_stdout, 01233 "** synth error: d_ref = 1 in leaf tree [%d].\n", tree->id); 01234 } 01235 if (tree->r_ref) { 01236 (void) fprintf(vis_stdout, 01237 "** synth error: r_ref = 1 in leaf tree [%d].\n", tree->id); 01238 } 01239 if (tree->q_comp) { 01240 (void) fprintf(vis_stdout, 01241 "** synth error: q_comp = 1 in leaf tree [%d].\n", tree->id); 01242 } 01243 if (tree->d_comp) { 01244 (void) fprintf(vis_stdout, 01245 "** synth error: d_comp = 1 in leaf tree [%d].\n", tree->id); 01246 } 01247 if (tree->r_comp) { 01248 (void) fprintf(vis_stdout, 01249 "** synth error: r_comp = 1 in leaf tree [%d].\n", tree->id); 01250 } 01251 bdd_recursive_deref(dd, node); 01252 return; 01253 } 01254 else { 01255 if (tree->pi) { 01256 (void) fprintf(vis_stdout, 01257 "** synth error: pi = 1 in non-leaf tree [%d].\n", tree->id); 01258 } 01259 } 01260 01261 if (!tree->q) { 01262 (void) fprintf(vis_stdout, 01263 "** synth error: no q in tree [%d].\n", tree->id); 01264 bdd_recursive_deref(dd, node); 01265 return; 01266 } 01267 if (tree->q_comp) 01268 q = bdd_make_bdd_from_zdd_cover(dd, tree->q->complement); 01269 else 01270 q = bdd_make_bdd_from_zdd_cover(dd, tree->q->node); 01271 if (!q) { 01272 (void) fprintf(vis_stdout, 01273 "** synth error: no q node in tree [%d].\n", tree->id); 01274 bdd_recursive_deref(dd, node); 01275 return; 01276 } 01277 bdd_ref(q); 01278 if (!tree->d) { 01279 (void) fprintf(vis_stdout, 01280 "** synth error: no d in tree [%d].\n", tree->id); 01281 bdd_recursive_deref(dd, node); 01282 bdd_recursive_deref(dd, q); 01283 return; 01284 } 01285 if (tree->d_comp) 01286 d = bdd_make_bdd_from_zdd_cover(dd, tree->d->complement); 01287 else 01288 d = bdd_make_bdd_from_zdd_cover(dd, tree->d->node); 01289 if (!d) { 01290 (void) fprintf(vis_stdout, 01291 "** synth error: no d node in tree [%d].\n", tree->id); 01292 bdd_recursive_deref(dd, node); 01293 bdd_recursive_deref(dd, q); 01294 return; 01295 } 01296 bdd_ref(d); 01297 if (!tree->candidate) { 01298 if (!tree->r) { 01299 (void) fprintf(vis_stdout, 01300 "** synth error: no r in tree [%d].\n", tree->id); 01301 bdd_recursive_deref(dd, node); 01302 bdd_recursive_deref(dd, q); 01303 bdd_recursive_deref(dd, d); 01304 return; 01305 } 01306 if (tree->r_comp) 01307 r = bdd_make_bdd_from_zdd_cover(dd, tree->r->complement); 01308 else 01309 r = bdd_make_bdd_from_zdd_cover(dd, tree->r->node); 01310 if (!r) { 01311 (void) fprintf(vis_stdout, 01312 "** synth error: no r node in tree [%d].\n", tree->id); 01313 bdd_recursive_deref(dd, node); 01314 bdd_recursive_deref(dd, q); 01315 bdd_recursive_deref(dd, d); 01316 return; 01317 } 01318 bdd_ref(r); 01319 01320 m = bdd_bdd_and(dd, q, d); 01321 if (!m) { 01322 bdd_recursive_deref(dd, node); 01323 bdd_recursive_deref(dd, q); 01324 bdd_recursive_deref(dd, d); 01325 bdd_recursive_deref(dd, r); 01326 return; 01327 } 01328 bdd_ref(m); 01329 bdd_recursive_deref(dd, q); 01330 bdd_recursive_deref(dd, d); 01331 f = bdd_bdd_or(dd, m, r); 01332 if (!f) { 01333 bdd_recursive_deref(dd, node); 01334 bdd_recursive_deref(dd, r); 01335 bdd_recursive_deref(dd, m); 01336 return; 01337 } 01338 bdd_ref(f); 01339 bdd_recursive_deref(dd, r); 01340 bdd_recursive_deref(dd, m); 01341 } else { 01342 f = bdd_bdd_and(dd, q, d); 01343 if (!f) { 01344 bdd_recursive_deref(dd, node); 01345 bdd_recursive_deref(dd, q); 01346 bdd_recursive_deref(dd, d); 01347 return; 01348 } 01349 bdd_ref(f); 01350 bdd_recursive_deref(dd, q); 01351 bdd_recursive_deref(dd, d); 01352 } 01353 if (!f) { 01354 bdd_recursive_deref(dd, node); 01355 return; 01356 } 01357 01358 if (f == node) 01359 bdd_diff = 0; 01360 else 01361 bdd_diff = 1; 01362 01363 bdd_recursive_deref(dd, f); 01364 bdd_recursive_deref(dd, node); 01365 01366 if (tree->comp) 01367 node = tree->complement; 01368 else 01369 node = tree->node; 01370 if (tree->q_comp) 01371 q = tree->q->complement; 01372 else 01373 q = tree->q->node; 01374 if (tree->d_comp) 01375 d = tree->d->complement; 01376 else 01377 d = tree->d->node; 01378 if (!tree->candidate) { 01379 if (tree->r_comp) 01380 r = tree->r->complement; 01381 else 01382 r = tree->r->node; 01383 m = (* SynthGetZddProductFunc())(dd, d, q); 01384 if (!m) 01385 return; 01386 bdd_ref(m); 01387 f = bdd_zdd_union(dd, m, r); 01388 if (!f) { 01389 bdd_recursive_deref_zdd(dd, m); 01390 return; 01391 } 01392 bdd_ref(f); 01393 bdd_recursive_deref_zdd(dd, m); 01394 } else { 01395 f = (* SynthGetZddProductFunc())(dd, d, q); 01396 if (!f) 01397 return; 01398 bdd_ref(f); 01399 } 01400 if (f != node) { 01401 if (bdd_diff) { 01402 (void) fprintf(vis_stdout, 01403 "** synth error: BDD & ZDD f != qd+r in tree [%d - 0x%lx].\n", 01404 tree->id, (unsigned long)tree); 01405 } 01406 else { 01407 (void) fprintf(vis_stdout, 01408 "Warning : ZDD f != qd+r in tree [%d - 0x%lx].\n", 01409 tree->id, (unsigned long)tree); 01410 } 01411 } 01412 else if (bdd_diff) { 01413 (void) fprintf(vis_stdout, 01414 "** synth error: BDD f != qd+r in tree [%d - 0x%lx].\n", 01415 tree->id, (unsigned long)tree); 01416 } 01417 bdd_recursive_deref_zdd(dd, f); 01418 } 01419 01420 01434 void 01435 SynthVerifyMlTable(bdd_manager *dd, 01436 st_table *table) 01437 { 01438 st_generator *gen; 01439 bdd_node *node; 01440 MlTree *tree, *reg; 01441 01442 st_foreach_item(table, gen, (&node), (&tree)) { 01443 reg = MlTree_Regular(tree); 01444 if ((reg == tree && node != reg->node) || 01445 (reg != tree && node != reg->complement)) { 01446 (void) fprintf(vis_stdout, 01447 "** synth error: wrong node in tree [%d].\n", reg->id); 01448 } 01449 tree = reg; 01450 if (tree->id >= NumTree) { 01451 (void) fprintf(vis_stdout, 01452 "** synth error: wrong id in tree [%d].\n", tree->id); 01453 } 01454 if (!tree->leaf) { 01455 if (!tree->d) { 01456 (void) fprintf(vis_stdout, 01457 "** synth error: d doesn't exist in tree [%d].\n", tree->id); 01458 } 01459 if (!tree->q) { 01460 (void) fprintf(vis_stdout, 01461 "** synth error: q doesn't exist in tree [%d].\n", tree->id); 01462 } 01463 if (!tree->r && !tree->candidate) { 01464 (void) fprintf(vis_stdout, 01465 "** synth error: r doesn't exist in tree [%d].\n", tree->id); 01466 } 01467 } 01468 } 01469 } 01470 01471 01483 void 01484 SynthPrintTreeList(MlTree *list) 01485 { 01486 MlTree *cur = list; 01487 if (!cur) 01488 cur = MlTreeHead; 01489 while (cur) { 01490 printf("%d (%d) - %d [0x%lx]\n", cur->id, cur->nLiterals, 01491 cur->leaf, (unsigned long)cur); 01492 cur = cur->next; 01493 } 01494 } 01495 01496 01508 void 01509 SynthPrintLeafList(MlTree *list) 01510 { 01511 MlTree *cur = list; 01512 if (!cur) 01513 cur = MlTreeHead; 01514 while (cur) { 01515 if (cur->leaf) 01516 printf("%d (%d) [0x%lx]\n", cur->id, cur->nLiterals, (unsigned long)cur); 01517 cur = cur->next; 01518 } 01519 } 01520 01521 01522 /*---------------------------------------------------------------------------*/ 01523 /* Definition of static functions */ 01524 /*---------------------------------------------------------------------------*/ 01525 01526 01542 static MlTree * 01543 ResolveConflictNode(bdd_manager *dd, 01544 st_table *table, 01545 MlTree *tree1, 01546 MlTree *tree2, 01547 int comp_flag, 01548 int verbosity) 01549 { 01550 MlTree *live_tree, *kill_tree; 01551 01552 if (MlTree_IsComplement(tree1)) 01553 tree1 = MlTree_Regular(tree1); 01554 if (MlTree_IsComplement(tree2)) 01555 tree2 = MlTree_Regular(tree2); 01556 01557 if (verbosity) { 01558 if (tree1->complement || tree2->complement) 01559 (void) fprintf(vis_stdout, "** synth warning: real conflict.\n"); 01560 } 01561 01562 if (ResolveConflictMode == 0) { 01563 live_tree = tree1; 01564 kill_tree = tree2; 01565 } else { 01566 if (tree1->nLiterals > tree2->nLiterals) { 01567 live_tree = tree2; 01568 kill_tree = tree1; 01569 } else { 01570 live_tree = tree1; 01571 kill_tree = tree2; 01572 } 01573 } 01574 01575 if (!live_tree->complement) { 01576 if (comp_flag) 01577 live_tree->complement = kill_tree->node; 01578 else 01579 live_tree->complement = kill_tree->complement; 01580 bdd_ref(live_tree->complement); 01581 bdd_recursive_deref_zdd(dd, kill_tree->node); 01582 st_delete(table, (char **)(&kill_tree->node), NIL(char *)); 01583 if (kill_tree->complement) { 01584 bdd_recursive_deref_zdd(dd, kill_tree->complement); 01585 st_delete(table, (char **)(&kill_tree->complement), NIL(char *)); 01586 } 01587 st_insert(table, (char *)live_tree->complement, 01588 (char *)MlTree_Not(live_tree)); 01589 } else { 01590 bdd_recursive_deref_zdd(dd, kill_tree->node); 01591 st_delete(table, (char **)(&kill_tree->node), NIL(char *)); 01592 if (kill_tree->complement) { 01593 bdd_recursive_deref_zdd(dd, kill_tree->complement); 01594 st_delete(table, (char **)(&kill_tree->complement), NIL(char *)); 01595 } 01596 } 01597 01598 DeleteMlTree(dd, table, kill_tree, live_tree, 0, comp_flag); 01599 SynthSetSharedFlag(dd, live_tree); 01600 01601 if (VerifyTreeMode) { 01602 SynthVerifyTree(dd, live_tree, 0); 01603 SynthVerifyMlTable(dd, table); 01604 VerifyTreeList(); 01605 } 01606 01607 return(live_tree); 01608 } 01609 01610 01622 static void 01623 DeleteMlTree(bdd_manager *dd, 01624 st_table *table, 01625 MlTree *kill_tree, 01626 MlTree *live_tree, 01627 int deref, 01628 int comp_flag) 01629 { 01630 MlTree *cur, *pre, *next; 01631 int ref; 01632 01633 if (kill_tree->shared && deref) { 01634 ref = 0; 01635 cur = MlTreeHead; 01636 while (cur) { 01637 if (cur == kill_tree) { 01638 cur = cur->next; 01639 continue; 01640 } 01641 if (cur->q == kill_tree) 01642 ref++; 01643 else if (cur->d == kill_tree) 01644 ref++; 01645 else if (cur->r == kill_tree) 01646 ref++; 01647 cur = cur->next; 01648 } 01649 01650 if (ref == 1) 01651 kill_tree->shared = 0; 01652 return; 01653 } 01654 01655 DeleteMlSizeList(kill_tree); 01656 01657 if (kill_tree->id == NumTree - 1) 01658 NumTree--; 01659 if (deref) { 01660 bdd_recursive_deref_zdd(dd, kill_tree->node); 01661 st_delete(table, (char **)(&kill_tree->node), NIL(char *)); 01662 if (kill_tree->complement) { 01663 bdd_recursive_deref_zdd(dd, kill_tree->complement); 01664 st_delete(table, (char **)(&kill_tree->complement), NIL(char *)); 01665 } 01666 } 01667 pre = NIL(MlTree); 01668 cur = MlTreeHead; 01669 while (cur) { 01670 if (cur == kill_tree) { 01671 next = cur->next; 01672 if (pre) 01673 pre->next = next; 01674 else 01675 MlTreeHead = next; 01676 cur = next; 01677 if (!live_tree) 01678 break; 01679 } else { 01680 if (live_tree) { 01681 if (cur->q == kill_tree) { 01682 if (comp_flag) 01683 cur->q_comp ^= 01; 01684 cur->q = live_tree; 01685 cur->q_ref = 1; 01686 if (VerifyTreeMode) 01687 SynthVerifyTree(dd, cur, 0); 01688 } else if (cur->d == kill_tree) { 01689 if (comp_flag) 01690 cur->d_comp ^= 01; 01691 cur->d = live_tree; 01692 cur->d_ref = 1; 01693 if (VerifyTreeMode) 01694 SynthVerifyTree(dd, cur, 0); 01695 } else if (cur->r == kill_tree) { 01696 if (comp_flag) 01697 cur->r_comp ^= 01; 01698 cur->r = live_tree; 01699 cur->r_ref = 1; 01700 if (VerifyTreeMode) 01701 SynthVerifyTree(dd, cur, 0); 01702 } 01703 } 01704 pre = cur; 01705 cur = cur->next; 01706 } 01707 } 01708 01709 if (kill_tree->leaf == 0) { 01710 if (kill_tree->q_ref) { 01711 if (kill_tree->q->shared) 01712 DeleteMlTree(dd, table, kill_tree->q, NULL, 1, 0); 01713 } else 01714 DeleteMlTree(dd, table, kill_tree->q, NULL, 1, 0); 01715 if (kill_tree->d_ref) { 01716 if (kill_tree->d->shared) 01717 DeleteMlTree(dd, table, kill_tree->d, NULL, 1, 0); 01718 } else 01719 DeleteMlTree(dd, table, kill_tree->d, NULL, 1, 0); 01720 if (kill_tree->r_ref) { 01721 if (kill_tree->r->shared) 01722 DeleteMlTree(dd, table, kill_tree->r, NULL, 1, 0); 01723 } else 01724 DeleteMlTree(dd, table, kill_tree->r, NULL, 1, 0); 01725 } 01726 01727 if (kill_tree->support) 01728 FREE(kill_tree->support); 01729 FREE(kill_tree); 01730 } 01731 01732 01744 static void 01745 UnlinkMlTree(MlTree *kill_tree) 01746 { 01747 MlTree *cur, *pre; 01748 01749 DeleteMlSizeList(kill_tree); 01750 01751 pre = (MlTree *)NULL; 01752 cur = MlTreeHead; 01753 while (cur) { 01754 if (cur == kill_tree) { 01755 if (pre) 01756 pre->next = cur->next; 01757 else 01758 MlTreeHead = cur->next; 01759 break; 01760 } 01761 pre = cur; 01762 cur = cur->next; 01763 } 01764 } 01765 01766 01778 static void 01779 DeleteMlSizeList(MlTree *tree) 01780 { 01781 MlTree *head, *tail, *cur, *pre; 01782 MlSizeList *list, *pre_list; 01783 int size; 01784 01785 size = tree->nLiterals; 01786 pre_list = NIL(MlSizeList); 01787 list = MlSizeHead; 01788 while (list) { 01789 if (size == list->size) { 01790 st_lookup(HeadListTable, list->string, (&head)); 01791 st_lookup(TailListTable, list->string, (&tail)); 01792 if (head == tail) { 01793 assert(tree == head); 01794 if (pre_list) 01795 pre_list->next = list->next; 01796 else 01797 MlSizeHead = list->next; 01798 st_delete(HeadListTable, (char **)&list->string, NIL(char *)); 01799 st_delete(TailListTable, (char **)&list->string, NIL(char *)); 01800 FREE(list->string); 01801 FREE(list); 01802 } else { 01803 pre = NIL(MlTree); 01804 cur = head; 01805 while (cur) { 01806 if (cur == tree) { 01807 if (cur == head) { 01808 st_delete(HeadListTable, (char **)&list->string, NIL(char *)); 01809 st_insert(HeadListTable, list->string, (char *)cur->next); 01810 } else if (cur == tail) { 01811 st_delete(TailListTable, (char **)&list->string, NIL(char *)); 01812 st_insert(TailListTable, list->string, (char *)pre); 01813 } 01814 break; 01815 } 01816 pre = cur; 01817 cur = cur->next; 01818 } 01819 } 01820 break; 01821 } else if (size > list->size) 01822 break; 01823 pre_list = list; 01824 list = list->next; 01825 } 01826 } 01827 01828 01840 static int 01841 InsertMlTable(st_table *table, 01842 bdd_node *node, 01843 MlTree *tree) 01844 { 01845 int flag; 01846 01847 flag = st_insert(table, (char *)node, (char *)tree); 01848 if (flag == ST_OUT_OF_MEM) { 01849 (void) fprintf(vis_stdout,"** synth error: Out of Memory.\n"); 01850 noMemoryFlag = 1; 01851 return (0); 01852 } else if (flag == 1) 01853 (void) fprintf(vis_stdout, "** synth warning: Duplicate entry.\n"); 01854 return(1); 01855 } 01856 01857 01869 static bdd_node * 01870 MakeComplementOfZddCover(bdd_manager *dd, 01871 bdd_node *node, 01872 int verbosity) 01873 { 01874 bdd_node *comp; 01875 01876 if (verbosity > 1) { 01877 (void) fprintf(vis_stdout,"*****\n"); 01878 SynthPrintZddTreeMessage(dd, node, "R : "); 01879 } 01880 01881 comp = bdd_zdd_complement(dd, node); 01882 if (!comp) 01883 return(NULL); 01884 01885 if (verbosity > 1) { 01886 SynthPrintZddTreeMessage(dd, comp, "C : "); 01887 (void) fprintf(vis_stdout,"*****\n"); 01888 } 01889 01890 return(comp); 01891 } 01892 01893 01905 static char * 01906 GetIntString(int v) 01907 { 01908 char string[12]; 01909 char *ret; 01910 01911 sprintf(string, "%d", v); 01912 ret = (char *)ALLOC(char, strlen(string) + 1); 01913 strcpy(ret, string); 01914 return(ret); 01915 } 01916 01917 01930 static void 01931 VerifyTreeList(void) 01932 { 01933 int count; 01934 MlTree *cur, *candy; 01935 01936 cur = MlTreeHead; 01937 while (cur) { 01938 count = 0; 01939 candy = cur->next; 01940 if (candy && candy->nLiterals > cur->nLiterals) { 01941 (void) fprintf(vis_stdout, 01942 "** synth error: predecessor[%d]'s size < successor[%d]'s size.\n", 01943 cur->id, candy->id); 01944 } 01945 while (candy) { 01946 if (cur->id != 0) { 01947 if (candy->id == cur->id && candy != cur) { 01948 (void) fprintf(vis_stdout, 01949 "** synth error: same id already exists [%d].\n", cur->id); 01950 break; 01951 } 01952 } 01953 if (candy == cur) { 01954 if (count > 0) { 01955 (void) fprintf(vis_stdout, 01956 "** synth error: same address already exists [%d - 0x%lx].\n", 01957 cur->id, (unsigned long)cur); 01958 break; 01959 } 01960 count++; 01961 } 01962 candy = candy->next; 01963 } 01964 cur = cur->next; 01965 } 01966 }