36static void dsdKernelComputeSumOfComponents(
Dsd_Manager_t * pDsdMan,
Dsd_Node_t ** pCommon,
int nCommon, DdNode ** pCompF, DdNode ** pCompS,
int fExor );
64static int s_Case4Calls;
65static int s_Case4CallsSpecial;
71static int s_nDecBlocks;
72static int s_nLiterals;
73static int s_nExorGates;
74static int s_nReusedBlocks;
75static int s_nCascades;
76static int s_nPrimeBlocks;
78static int HashSuccess = 0;
79static int HashFailure = 0;
81static int s_CacheEntries;
115 DdManager * dd = pDsdMan->
dd;
119 int SumMaxGateSize = 0;
141 printf(
"\nDecomposability statistics for individual outputs:\n" );
150 for ( i = 0; i < nFuncs; i++ )
155 int nReusedBlocksPres;
162 nLiteralsPrev = s_nLiterals;
163 nDecBlocksPrev = s_nDecBlocks;
164 nExorGatesPrev = s_nExorGates;
165 nReusedBlocksPres = s_nReusedBlocks;
166 nPrimeBlocks = s_nPrimeBlocks;
168 pDsdMan->
pRoots[ pDsdMan->
nRoots++ ] = dsdKernelDecompose_rec( pDsdMan, pbFuncs[i] );
171 s_nCascades = ddMax( s_nCascades, nCascades );
177 SumMaxGateSize += MaxBlock;
181 printf(
"#%02d: ", i );
182 printf(
"Ins=%2d. ", Cudd_SupportSize(dd,pbFuncs[i]) );
185 printf(
"Max=%3d. ", MaxBlock );
186 printf(
"Reuse=%2d. ", s_nReusedBlocks-nReusedBlocksPres );
187 printf(
"Csc=%2d. ", nCascades );
188 printf(
"T= %.2f s. ", (
float)(Abc_Clock()-clk)/(
float)(CLOCKS_PER_SEC) ) ;
189 printf(
"Bdd=%2d. ", Cudd_DagSize(pbFuncs[i]) );
199 printf(
"The cumulative decomposability statistics:\n" );
200 printf(
" Total outputs = %5d\n", nFuncs );
201 printf(
" Decomposable outputs = %5d\n", nDecOutputs );
202 printf(
" Completely decomposable outputs = %5d\n", nCBFOutputs );
203 printf(
" The sum of max gate sizes = %5d\n", SumMaxGateSize );
204 printf(
" Shared BDD size = %5d\n", Cudd_SharingSize( pbFuncs, nFuncs ) );
205 printf(
" Decomposition entries = %5d\n",
st__count( pDsdMan->
Table ) );
206 printf(
" Pure decomposition time = %.2f sec\n", (
float)(Abc_Clock() - clk)/(
float)(CLOCKS_PER_SEC) );
232 return dsdKernelDecompose_rec( pDsdMan, bFunc );
248 DdManager * dd = pDsdMan->
dd;
257 DdNode * bSuppNew = NULL, * bTemp;
274 DdNode * bF = Cudd_Regular(bFunc0);
275 int fCompF = (int)(bF != bFunc0);
291 bLowR = Cudd_Regular(bLow);
294 bVarCur = dd->vars[VarInt];
295 pVarCurDE = pDsdMan->
pInputs[VarInt];
299 if ( bLowR->index == CUDD_CONST_INDEX || bHigh->index == CUDD_CONST_INDEX )
309 pThis->
pDecs[0] = NULL;
316 pL = dsdKernelDecompose_rec( pDsdMan, bLow );
318 bSuppNew = Cudd_bddAnd( dd, bVarCur, pLR->
S ); Cudd_Ref(bSuppNew);
322 dsdKernelCopyListPlusOne( pThis, pVarCurDE, pL->
pDecs, pL->
nDecs );
327 dsdKernelCopyListPlusOne( pThis, pVarCurDE, &pL, 1 );
332 pH = dsdKernelDecompose_rec( pDsdMan, bHigh );
334 bSuppNew = Cudd_bddAnd( dd, bVarCur, pHR->
S ); Cudd_Ref(bSuppNew);
349 dsdKernelCopyListPlusOne( pThis,
Dsd_Not(pVarCurDE), &pH, 1 );
364 dsdKernelCopyListPlusOne( pThis,
Dsd_Not(pVarCurDE), &pH, 1 );
372 if ( bLowR == bHigh )
377 pL = dsdKernelDecompose_rec( pDsdMan, bLow );
379 bSuppNew = Cudd_bddAnd( dd, bVarCur, pLR->
S ); Cudd_Ref(bSuppNew);
383 dsdKernelCopyListPlusOne( pThis, pVarCurDE, pLR->
pDecs, pLR->
nDecs );
392 dsdKernelCopyListPlusOne( pThis, pVarCurDE, &pLR, 1 );
396 dsdKernelCopyListPlusOne( pThis, pVarCurDE, &pL, 1 );
404 pL = dsdKernelDecompose_rec( pDsdMan, bLow );
405 pH = dsdKernelDecompose_rec( pDsdMan, bHigh );
425 bTemp = Cudd_bddAnd( dd, pLR->
S, pHR->
S ); Cudd_Ref( bTemp );
429 bSuppNew = Cudd_bddAnd( dd, bTemp, bVarCur ); Cudd_Ref( bSuppNew );
430 Cudd_RecursiveDeref( dd, bTemp );
436 fContained = dsdKernelCheckContainment( pDsdMan, pLR, pHR, &pLargeR, &pSmallR );
447 int c, iCompLarge = -1;
456 if ( pSmallR == pLR )
491 int g, fFoundComp = -1;
493 DdNode * bLarge, * bSmall;
505 for ( g = 0; g < pLargeR->
nDecs; g++ )
508 pDETemp = pLargeR->
pDecs[g];
526 if ( g != pLargeR->
nDecs )
530 bFTemp = Cudd_bddOr( dd, bVarCur, pLargeR->
pDecs[g]->
G );
532 bFTemp = Cudd_bddOr( dd, Cudd_Not(bVarCur), pLargeR->
pDecs[g]->
G );
535 bFTemp = Cudd_bddAnd( dd, Cudd_Not(bVarCur), pLargeR->
pDecs[g]->
G );
537 bFTemp = Cudd_bddAnd( dd, bVarCur, pLargeR->
pDecs[g]->
G );
540 pDENew = dsdKernelDecompose_rec( pDsdMan, bFTemp );
542 Cudd_RecursiveDeref( dd, bFTemp );
546 dsdKernelCopyListPlusOneMinusOne( pThis, pDENew, pLargeR->
pDecs, pLargeR->
nDecs, g );
552 for ( c = 0; c < pLargeR->
nDecs; c++ )
560 if ( c != pLargeR->
nDecs )
562 pComp = pLargeR->
pDecs[iCompLarge];
570 if ( pLargeR->
Type == pSmallR->
Type &&
573 Dsd_Node_t ** pCommon, * pLastDiffL = NULL, * pLastDiffH = NULL;
574 int nCommon = dsdKernelFindCommonComponents( pDsdMan, pLargeR, pSmallR, &pCommon, &pLastDiffL, &pLastDiffH );
577 if ( nCommon == pSmallR->
nDecs )
580 nComp = pSmallR->
nDecs;
589 int fComp1 = (int)( pLarge != pLargeR );
590 int fComp2 = (int)( pComp != pCompR );
591 int fComp3 = (int)( pSmall != pSmallR );
600 if ( (fComp1 ^ fComp2) == fComp3 )
626 bFTemp = (fComp1)? Cudd_Not( bF ): bF;
627 bFuncComp = (fComp2)? Cudd_Not( pCompR->
G ): pCompR->
G;
628 bFuncNew = Cudd_bddAndAbstract( dd, bFTemp, Cudd_Not(bFuncComp), pCompR->
S ); Cudd_Ref( bFuncNew );
632 pDENew = dsdKernelDecompose_rec( pDsdMan, bFuncNew );
634 Cudd_RecursiveDeref( dd, bFuncNew );
640 pThis->
pDecs[0] = pDENew;
641 pThis->
pDecs[1] = pComp;
646 dsdKernelCopyListPlusOne( pThis, pDENew, pComp->
pDecs, nComp );
679 bFTemp = (fComp3)? bF: Cudd_Not( bF );
680 bFuncNew = Cudd_bddXor( dd, bFTemp, pComp->
G ); Cudd_Ref( bFuncNew );
682 pDENew = dsdKernelDecompose_rec( pDsdMan, bFuncNew );
684 Cudd_RecursiveDeref( dd, bFuncNew );
690 pThis->
pDecs[0] = pDENew;
691 pThis->
pDecs[1] = pComp;
696 dsdKernelCopyListPlusOne( pThis, pDENew, pComp->
pDecs, nComp );
708 if ( nSuppLH == nSuppL + nSuppH )
712 if ( dd->perm[pLR->
S->index] < dd->perm[pHR->
S->index] )
714 pThis->
pDecs[1] = pLR;
715 pThis->
pDecs[2] = pHR;
719 pThis->
pDecs[1] = pHR;
720 pThis->
pDecs[2] = pLR;
723 pThis->
pDecs[0] = pVarCurDE;
736 (pLR->
Type !=
DSD_NODE_OR || ( (pL == pLR && pH == pHR) || (pL != pLR && pH != pHR) ) ) &&
740 Dsd_Node_t ** pCommon, * pLastDiffL = NULL, * pLastDiffH = NULL;
741 int nCommon = dsdKernelFindCommonComponents( pDsdMan, pLR, pHR, &pCommon, &pLastDiffL, &pLastDiffH );
750 DdNode * bCommF, * bCommS, * bFTemp, * bFuncNew;
753 dsdKernelComputeSumOfComponents( pDsdMan, pCommon, nCommon, &bCommF, &bCommS, 0 );
756 bFTemp = ( pL != pLR )? Cudd_Not(bF): bF;
758 bFuncNew = Cudd_bddAndAbstract( dd, bFTemp, Cudd_Not(bCommF), bCommS ); Cudd_Ref( bFuncNew );
759 Cudd_RecursiveDeref( dd, bCommF );
760 Cudd_RecursiveDeref( dd, bCommS );
767 dsdKernelCopyListPlusOne( pThis, NULL, pCommon, nCommon );
770 pDENew = dsdKernelDecompose_rec( pDsdMan, bFuncNew );
772 Cudd_RecursiveDeref( dd, bFuncNew );
775 pThis->
pDecs[0] = pDENew;
785 DdNode * bCommF, * bFuncNew;
789 dsdKernelComputeSumOfComponents( pDsdMan, pCommon, nCommon, &bCommF, NULL, 1 );
792 bFuncNew = Cudd_bddXor( dd, bF, bCommF ); Cudd_Ref( bFuncNew );
793 Cudd_RecursiveDeref( dd, bCommF );
800 dsdKernelCopyListPlusOne( pThis, NULL, pCommon, nCommon );
803 pDENew = dsdKernelDecompose_rec( pDsdMan, bFuncNew );
804 Cudd_RecursiveDeref( dd, bFuncNew );
811 pThis->
pDecs[0] = pDENew;
831 if ( nCommon == pLR->
nDecs )
838 for ( m = 0; m < pLR->
nDecs; m++ )
840 pTempL = pLR->
pDecs[m];
841 pTempH = pHR->
pDecs[m];
848 assert( pLastDiffL == pLastDiffH );
873 for ( m = 0; m < pLR->
nDecs; m++ )
874 if ( pLR->
pDecs[m] != pLastDiffL )
875 pCommon[nCommon++] = pLR->
pDecs[m];
901 if ( fCompComp == 1 )
902 bFuncNew = Cudd_bddIte( dd, bVarCur, pLastDiffH->G, pLastDiffL->
G );
904 bFuncNew = Cudd_bddIte( dd, bVarCur, Cudd_Not(pLastDiffH->G), pLastDiffL->
G );
905 Cudd_Ref( bFuncNew );
912 dsdKernelCopyListPlusOne( pThis, NULL, pCommon, nCommon );
915 pDENew = dsdKernelDecompose_rec( pDsdMan, bFuncNew );
916 Cudd_RecursiveDeref( dd, bFuncNew );
921 pThis->
pDecs[0] = pDENew;
937 int nEntriesMax = pDsdMan->
nInputs - dd->perm[VarInt];
942 DdNode * SuppL, * SuppH, * SuppL_init, * SuppH_init;
952 pThis->
pDecs[ nEntries++ ] = pVarCurDE;
966 s_Case4CallsSpecial++;
973 levTopSuppL = cuddI(dd,SuppL->index);
974 levTopSuppH = cuddI(dd,SuppH->index);
977 if ( levTopSuppL <= levTopSuppH )
979 levTop = levTopSuppL;
980 SuppL = cuddT(SuppL);
983 levTop = levTopSuppH;
985 if ( levTopSuppH <= levTopSuppL )
986 SuppH = cuddT(SuppH);
989 pThis->
pDecs[ nEntries++ ] = pDsdMan->
pInputs[ dd->invperm[levTop] ];
991 while ( SuppL !=
b1 || SuppH !=
b1 );
1000 SuppL = pLR->
S; Cudd_Ref( SuppL );
1001 SuppH = pHR->
S; Cudd_Ref( SuppH );
1002 while ( SuppL !=
b1 || SuppH !=
b1 )
1006 int TopLevL = cuddI(dd,SuppL->index);
1007 int TopLevH = cuddI(dd,SuppH->index);
1008 int TopLevel = TopLevH;
1009 int fEqualLevel = 0;
1012 DdNode * bSuppSubract;
1015 if ( TopLevL < TopLevH )
1021 else if ( TopLevL > TopLevH )
1028 assert( TopLevel != CUDD_CONST_INDEX );
1032 bVarTop = dd->vars[dd->invperm[TopLevel]];
1037 DdNode * bSuppLower = (TopLevL < TopLevH)? SuppH_init: SuppL_init;
1048 pCur = dsdKernelFindContainingComponent( pDsdMan, pCur, bVarTop, &fPolarity );
1057 pThis->
pDecs[ nEntries++ ] = pCur;
1059 bSuppSubract = pCur->
S;
1067 int i, nNonOverlap = 0;
1068 for ( i = 0; i < pPrev->
nDecs; i++ )
1072 pNonOverlap[ nNonOverlap++ ] = pPrev->
pDecs[i];
1074 assert( nNonOverlap > 0 );
1076 if ( nNonOverlap == 1 )
1080 pThis->
pDecs[ nEntries++ ] = pCur;
1082 bSuppSubract = pCur->
S;
1088 dsdKernelComputeSumOfComponents( pDsdMan, pNonOverlap, nNonOverlap, &bCommF, NULL, (
int)(pPrev->
Type==
DSD_NODE_EXOR) );
1092 pDENew = dsdKernelDecompose_rec( pDsdMan, bCommF );
1093 Cudd_RecursiveDeref(dd, bCommF);
1098 pThis->
pDecs[ nEntries++ ] = pDENew;
1100 bSuppSubract = pDENew->
S;
1105 if ( TopLevL < TopLevH )
1107 SuppL = Cudd_bddExistAbstract( dd, bTemp = SuppL, bSuppSubract ); Cudd_Ref( SuppL );
1108 Cudd_RecursiveDeref(dd, bTemp);
1112 SuppH = Cudd_bddExistAbstract( dd, bTemp = SuppH, bSuppSubract ); Cudd_Ref( SuppH );
1113 Cudd_RecursiveDeref(dd, bTemp);
1120 int nMarkedLeft = 0;
1125 int fPolarityCurH = 0;
1128 int fPolarityCurL = 0;
1139 pTempL->
Mark = s_Mark;
1140 pMarkedLeft[ nMarkedLeft ] = pTempL;
1141 pMarkedPols[ nMarkedLeft ] = fPolarity;
1143 }
while ( (pTempL = dsdKernelFindContainingComponent( pDsdMan, pTempL, bVarTop, &fPolarity )) );
1147 while ( pCurH->Mark != s_Mark )
1150 pCurH = dsdKernelFindContainingComponent( pDsdMan, pCurH, bVarTop, &fPolarityCurH );
1156 while ( pCurL != pCurH )
1159 pCurL = pMarkedLeft[index];
1160 fPolarityCurL = pMarkedPols[index];
1165 if ( !pPrevL || !pPrevH || pPrevL->
Type != pPrevH->
Type || pPrevL->
Type ==
DSD_NODE_PRIME || fPolarityCurL != fPolarityCurH )
1167 pThis->
pDecs[ nEntries++ ] = pCurH;
1169 bSuppSubract = pCurH->
S;
1174 Dsd_Node_t ** pCommon, * pLastDiffL = NULL, * pLastDiffH = NULL;
1175 int nCommon = dsdKernelFindCommonComponents( pDsdMan, pPrevL, pPrevH, &pCommon, &pLastDiffL, &pLastDiffH );
1177 if ( nCommon == 0 || nCommon == 1 )
1181 pThis->
pDecs[ nEntries++ ] = pCurL;
1183 bSuppSubract = pCurL->
S;
1189 dsdKernelComputeSumOfComponents( pDsdMan, pCommon, nCommon, &bCommF, NULL, (
int)(pPrevL->
Type==
DSD_NODE_EXOR) );
1192 pDENew = dsdKernelDecompose_rec( pDsdMan, bCommF );
1194 Cudd_RecursiveDeref( dd, bCommF );
1197 pThis->
pDecs[ nEntries++ ] = pDENew;
1200 bSuppSubract = pDENew->
S;
1204 SuppL = Cudd_bddExistAbstract( dd, bTemp = SuppL, bSuppSubract ), Cudd_Ref( SuppL );
1205 Cudd_RecursiveDeref(dd, bTemp);
1207 SuppH = Cudd_bddExistAbstract( dd, bTemp = SuppH, bSuppSubract ), Cudd_Ref( SuppH );
1208 Cudd_RecursiveDeref(dd, bTemp);
1213 Cudd_RecursiveDeref( dd, SuppL );
1214 Cudd_RecursiveDeref( dd, SuppH );
1219 assert( nEntries <= nEntriesMax );
1225 pThis->
nDecs = nEntries;
1237 if ( pThisR == pThis )
1240 pThisR->
G = Cudd_Not(bF);
1244 pThisR->
S = bSuppNew;
1309 if ( pWhere->
nDecs == 1 )
1312 for( i = 0; i < pWhere->
nDecs; i++ )
1317 *fPolarity = (int)( pTemp != pWhere->
pDecs[i] );
1359 while ( iCurL < pL->nDecs && iCurH < pH->nDecs )
1369 if ( pDsdMan->
dd->perm[bSLcur->index] < pDsdMan->
dd->perm[bSHcur->index] )
1370 TopVar = bSLcur->index;
1372 TopVar = bSHcur->index;
1374 if ( TopVar == bSLcur->index && TopVar == bSHcur->index )
1378 Common[nCommon++] = pL->
pDecs[iCurL];
1381 *pLastDiffL = pL->
pDecs[iCurL];
1382 *pLastDiffH = pH->
pDecs[iCurH];
1389 else if ( TopVar == bSLcur->index )
1392 *pLastDiffL = pL->
pDecs[iCurL++];
1397 *pLastDiffH = pH->
pDecs[iCurH++];
1402 if ( iCurL < pL->nDecs )
1403 *pLastDiffL = pL->
pDecs[iCurL];
1405 if ( iCurH < pH->nDecs )
1406 *pLastDiffH = pH->
pDecs[iCurH];
1425void dsdKernelComputeSumOfComponents(
Dsd_Manager_t * pDsdMan,
Dsd_Node_t ** pCommon,
int nCommon, DdNode ** pCompF, DdNode ** pCompS,
int fExor )
1427 DdManager * dd = pDsdMan->
dd;
1428 DdNode * bF, * bFadd, * bTemp;
1434 bF =
b0; Cudd_Ref( bF );
1437 bS =
b1, Cudd_Ref( bS );
1440 for ( i = 0; i < nCommon; i++ )
1444 bFadd = (pDE != pDER)? Cudd_Not(pDER->
G): pDER->
G;
1447 bF = Cudd_bddXor( dd, bTemp = bF, bFadd );
1449 bF = Cudd_bddOr( dd, bTemp = bF, bFadd );
1451 Cudd_RecursiveDeref( dd, bTemp );
1455 bS = Cudd_bddAnd( dd, bTemp = bS, pDER->
S ); Cudd_Ref( bS );
1456 Cudd_RecursiveDeref( dd, bTemp );
1465 Cudd_Deref( bS ), *pCompS = bS;
1485 DdManager * dd = pDsdMan->
dd;
1486 DdNode * bSuppLarge, * bSuppSmall;
1491 if ( RetValue == 0 )
1494 if ( pH->
S == bSuppLarge )
1521 assert( nListSize+1 ==
p->nDecs );
1522 p->pDecs[0] = First;
1523 for( i = 0; i < nListSize; i++ )
1524 p->pDecs[i+1] = ppList[i];
1541 assert( nListSize ==
p->nDecs );
1542 p->pDecs[0] = First;
1543 for( i = 0, Counter = 1; i < nListSize; i++ )
1544 if ( i != iSkipped )
1545 p->pDecs[Counter++] = ppList[i];
1561 DdManager * dd = pDsdMan->
dd;
1582 for ( i = 0; i < dd->size; i++ )
1583 bGVars[i] = dd->vars[i];
1586 for ( i = 0; i < pR->
nDecs; i++ )
1587 bGVars[dd->invperm[i]] = pR->
pDecs[i]->
G;
1590 bRes = Cudd_bddVectorCompose( dd, bNewFunc, bGVars ); Cudd_Ref( bRes );
1591 Cudd_RecursiveDeref( dd, bNewFunc );
1594 RetValue = (int)( bRes == pR->
G );
1604 RetValue = (int)( bRes == pR->
G );
1605 Cudd_RecursiveDeref( dd, bRes );
#define ABC_ALLOC(type, num)
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define MAXINPUTS
INCLUDES ///.
int Dsd_CheckRootFunctionIdentity(DdManager *dd, DdNode *bF1, DdNode *bF2, DdNode *bC1, DdNode *bC2)
Dsd_Node_t * Dsd_TreeNodeCreate(int Type, int nDecs, int BlockNum)
FUNCTION DEFINITIONS ///.
DdNode * Dsd_TreeGetPrimeFunctionOld(DdManager *dd, Dsd_Node_t *pNode, int fRemap)
void Dsd_Decompose(Dsd_Manager_t *pDsdMan, DdNode **pbFuncs, int nFuncs)
DECOMPOSITION FUNCTIONS ///.
Dsd_Node_t * Dsd_DecomposeOne(Dsd_Manager_t *pDsdMan, DdNode *bFunc)
ABC_NAMESPACE_IMPL_START void dsdKernelDecompose(Dsd_Manager_t *pDsdMan, DdNode **pbFuncs, int nFuncs)
FUNCTION DECLARATIONS ///.
int Dsd_TreeCountPrimeNodesOne(Dsd_Node_t *pRoot)
void Dsd_TreeNodeGetInfoOne(Dsd_Node_t *pNode, int *DepthMax, int *GateSizeMax)
struct Dsd_Manager_t_ Dsd_Manager_t
TYPEDEF DEFINITIONS ///.
#define Dsd_NotCond(p, c)
int Dsd_TreeCountNonTerminalNodesOne(Dsd_Node_t *pRoot)
struct Dsd_Node_t_ Dsd_Node_t
#define Dsd_IsComplement(p)
MACRO DEFINITIONS ///.
int st__lookup(st__table *table, const char *key, char **value)
int st__insert(st__table *table, const char *key, char *value)