00001
00021 #include "ivy.h"
00022
00026
00027 static inline int Ivy_NodeCutHashValue( int NodeId ) { return 1 << (NodeId % 31); }
00028
00032
00045 static inline int Ivy_NodeGetLeafCostOne( Ivy_Man_t * p, int Leaf, Vec_Int_t * vInside )
00046 {
00047 Ivy_Obj_t * pNode;
00048 int nLatches, FaninLeaf, Cost;
00049
00050 assert( Leaf > 0 );
00051
00052 pNode = Ivy_ManObj( p, Ivy_LeafId(Leaf) );
00053
00054 if ( Ivy_ObjIsPi(pNode) || Ivy_ObjIsConst1(pNode) )
00055 return 999;
00056
00057 nLatches = Ivy_LeafLat(Leaf) + Ivy_ObjIsLatch(pNode);
00058 if ( nLatches > 15 )
00059 return 999;
00060
00061 FaninLeaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pNode), nLatches );
00062 Cost = FaninLeaf && (Vec_IntFind(vInside, FaninLeaf) == -1);
00063
00064 if ( Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) )
00065 return Cost;
00066 assert( Ivy_ObjIsNode(pNode) );
00067
00068 FaninLeaf = Ivy_LeafCreate( Ivy_ObjFaninId1(pNode), nLatches );
00069 Cost += FaninLeaf && (Vec_IntFind(vInside, FaninLeaf) == -1);
00070 return Cost;
00071 }
00072
00087 int Ivy_ManSeqFindCut_int( Ivy_Man_t * p, Vec_Int_t * vFront, Vec_Int_t * vInside, int nSizeLimit )
00088 {
00089 Ivy_Obj_t * pNode;
00090 int CostBest, CostCur, Leaf, LeafBest, Next, nLatches, i;
00091 int LeavesBest[10];
00092 int Counter;
00093
00094
00095
00096
00097 CostBest = 99;
00098 LeafBest = -1;
00099 Counter = -1;
00100
00101 Vec_IntForEachEntry( vFront, Leaf, i )
00102 {
00103 CostCur = Ivy_NodeGetLeafCostOne( p, Leaf, vInside );
00104
00105 if ( CostBest > CostCur )
00106 {
00107 CostBest = CostCur;
00108 LeafBest = Leaf;
00109 LeavesBest[0] = Leaf;
00110 Counter = 1;
00111 }
00112 else if ( CostBest == CostCur )
00113 LeavesBest[Counter++] = Leaf;
00114
00115 if ( CostBest <= 1 )
00116 break;
00117 }
00118 if ( CostBest == 99 )
00119 return 0;
00120
00121
00122 assert( CostBest < 3 );
00123 if ( Vec_IntSize(vFront) - 1 + CostBest > nSizeLimit )
00124 return 0;
00125
00126
00127 assert( Counter > 0 );
00128 printf( "%d", Counter );
00129
00130 LeafBest = LeavesBest[rand() % Counter];
00131
00132
00133 assert( LeafBest >= 0 );
00134 Vec_IntRemove( vFront, LeafBest );
00135
00136
00137
00138 pNode = Ivy_ManObj( p, Ivy_LeafId(LeafBest) );
00139 nLatches = Ivy_LeafLat(LeafBest) + Ivy_ObjIsLatch(pNode);
00140 assert( Ivy_ObjIsNode(pNode) || Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) );
00141
00142
00143 Next = Ivy_LeafCreate( Ivy_ObjFaninId0(pNode), nLatches );
00144 if ( Next && Vec_IntFind(vInside, Next) == -1 )
00145 {
00146
00147 Vec_IntPush( vFront, Next );
00148 Vec_IntPush( vInside, Next );
00149 }
00150
00151
00152 if ( Ivy_ObjIsLatch(pNode) || Ivy_ObjIsBuf(pNode) )
00153 return 1;
00154 assert( Ivy_ObjIsNode(pNode) );
00155
00156
00157 Next = Ivy_LeafCreate( Ivy_ObjFaninId1(pNode), nLatches );
00158 if ( Next && Vec_IntFind(vInside, Next) == -1 )
00159 {
00160
00161 Vec_IntPush( vFront, Next );
00162 Vec_IntPush( vInside, Next );
00163 }
00164 assert( Vec_IntSize(vFront) <= nSizeLimit );
00165
00166 return 1;
00167 }
00168
00180 void Ivy_ManSeqFindCut( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Int_t * vFront, Vec_Int_t * vInside, int nSize )
00181 {
00182 assert( !Ivy_IsComplement(pRoot) );
00183 assert( Ivy_ObjIsNode(pRoot) );
00184 assert( Ivy_ObjFaninId0(pRoot) );
00185 assert( Ivy_ObjFaninId1(pRoot) );
00186
00187
00188 Vec_IntClear( vFront );
00189 Vec_IntPush( vFront, Ivy_LeafCreate(Ivy_ObjFaninId0(pRoot), 0) );
00190 Vec_IntPush( vFront, Ivy_LeafCreate(Ivy_ObjFaninId1(pRoot), 0) );
00191
00192
00193 Vec_IntClear( vInside );
00194 Vec_IntPush( vInside, Ivy_LeafCreate(pRoot->Id, 0) );
00195 Vec_IntPush( vInside, Ivy_LeafCreate(Ivy_ObjFaninId0(pRoot), 0) );
00196 Vec_IntPush( vInside, Ivy_LeafCreate(Ivy_ObjFaninId1(pRoot), 0) );
00197
00198
00199 while ( Ivy_ManSeqFindCut_int( p, vFront, vInside, nSize ) );
00200 assert( Vec_IntSize(vFront) <= nSize );
00201 }
00202
00203
00204
00205
00206
00218 int Ivy_ManFindBoolCut_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vVolume, Ivy_Obj_t * pPivot )
00219 {
00220 int RetValue0, RetValue1;
00221 if ( pObj == pPivot )
00222 {
00223 Vec_PtrPushUnique( vLeaves, pObj );
00224 Vec_PtrPushUnique( vVolume, pObj );
00225 return 1;
00226 }
00227 if ( pObj->fMarkA )
00228 return 0;
00229
00230
00231 if ( Ivy_ObjIsCi(pObj) )
00232 return 0;
00233
00234 if ( Ivy_ObjIsBuf(pObj) )
00235 {
00236 RetValue0 = Ivy_ManFindBoolCut_rec( p, Ivy_ObjFanin0(pObj), vLeaves, vVolume, pPivot );
00237 if ( !RetValue0 )
00238 return 0;
00239 Vec_PtrPushUnique( vVolume, pObj );
00240 return 1;
00241 }
00242 assert( Ivy_ObjIsNode(pObj) );
00243 RetValue0 = Ivy_ManFindBoolCut_rec( p, Ivy_ObjFanin0(pObj), vLeaves, vVolume, pPivot );
00244 RetValue1 = Ivy_ManFindBoolCut_rec( p, Ivy_ObjFanin1(pObj), vLeaves, vVolume, pPivot );
00245 if ( !RetValue0 && !RetValue1 )
00246 return 0;
00247
00248 if ( !RetValue0 )
00249 {
00250 Vec_PtrPushUnique( vLeaves, Ivy_ObjFanin0(pObj) );
00251 Vec_PtrPushUnique( vVolume, Ivy_ObjFanin0(pObj) );
00252 }
00253 if ( !RetValue1 )
00254 {
00255 Vec_PtrPushUnique( vLeaves, Ivy_ObjFanin1(pObj) );
00256 Vec_PtrPushUnique( vVolume, Ivy_ObjFanin1(pObj) );
00257 }
00258 Vec_PtrPushUnique( vVolume, pObj );
00259 return 1;
00260 }
00261
00273 int Ivy_ManFindBoolCutCost( Ivy_Obj_t * pObj )
00274 {
00275 int Cost;
00276
00277 assert( pObj->fMarkA == 1 );
00278
00279 if ( Ivy_ObjIsCi(pObj) )
00280 return 999;
00281
00282 if ( Ivy_ObjIsBuf(pObj) )
00283 return !Ivy_ObjFanin0(pObj)->fMarkA;
00284
00285 Cost = (!Ivy_ObjFanin0(pObj)->fMarkA) + (!Ivy_ObjFanin1(pObj)->fMarkA);
00286
00287 return Cost;
00288 }
00289
00301 int Ivy_ManFindBoolCut( Ivy_Man_t * p, Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vVolume, Vec_Ptr_t * vLeaves )
00302 {
00303 Ivy_Obj_t * pObj, * pFaninC, * pFanin0, * pFanin1, * pPivot;
00304 int RetValue, LevelLimit, Lev, k;
00305 assert( !Ivy_IsComplement(pRoot) );
00306
00307 Vec_PtrClear( vFront );
00308 Vec_PtrClear( vVolume );
00309 if ( Ivy_ObjIsMuxType(pRoot) )
00310 pFaninC = Ivy_ObjRecognizeMux( pRoot, &pFanin0, &pFanin1 );
00311 else
00312 {
00313 pFaninC = NULL;
00314 pFanin0 = Ivy_ObjFanin0(pRoot);
00315 pFanin1 = Ivy_ObjFanin1(pRoot);
00316 }
00317
00318 pFanin0->fMarkA = 1;
00319 Vec_PtrPush( vFront, pFanin0 );
00320 Vec_PtrPush( vVolume, pFanin0 );
00321
00322 pFanin1->fMarkB = 1;
00323 Vec_PtrPush( vFront, pFanin1 );
00324 Vec_PtrPush( vVolume, pFanin1 );
00325
00326 assert( Ivy_ObjLevel(pRoot) == Ivy_ObjLevelNew(pRoot) );
00327 pPivot = NULL;
00328 LevelLimit = IVY_MAX( Ivy_ObjLevel(pRoot) - 10, 1 );
00329 for ( Lev = Ivy_ObjLevel(pRoot) - 1; Lev >= LevelLimit; Lev-- )
00330 {
00331 while ( 1 )
00332 {
00333
00334 Vec_PtrForEachEntry( vFront, pObj, k )
00335 if ( (int)pObj->Level == Lev )
00336 break;
00337 if ( k == Vec_PtrSize(vFront) )
00338 break;
00339 assert( (int)pObj->Level <= Lev );
00340 assert( pObj->fMarkA ^ pObj->fMarkB );
00341
00342 Vec_PtrRemove( vFront, pObj );
00343
00344
00345 pFanin0 = Ivy_ObjFanin0(pObj);
00346 if ( !pFanin0->fMarkA && !pFanin0->fMarkB )
00347 {
00348 Vec_PtrPush( vFront, pFanin0 );
00349 Vec_PtrPush( vVolume, pFanin0 );
00350 }
00351
00352 if ( pObj->fMarkA )
00353 pFanin0->fMarkA = 1;
00354 if ( pObj->fMarkB )
00355 pFanin0->fMarkB = 1;
00356
00357 if ( Ivy_ObjIsBuf(pObj) )
00358 {
00359 if ( pFanin0->fMarkA && pFanin0->fMarkB )
00360 {
00361 pPivot = pFanin0;
00362 break;
00363 }
00364 continue;
00365 }
00366
00367
00368 pFanin1 = Ivy_ObjFanin1(pObj);
00369 if ( !pFanin1->fMarkA && !pFanin1->fMarkB )
00370 {
00371 Vec_PtrPush( vFront, pFanin1 );
00372 Vec_PtrPush( vVolume, pFanin1 );
00373 }
00374
00375 if ( pObj->fMarkA )
00376 pFanin1->fMarkA = 1;
00377 if ( pObj->fMarkB )
00378 pFanin1->fMarkB = 1;
00379
00380
00381 if ( pFanin0->fMarkA && pFanin0->fMarkB )
00382 {
00383 pPivot = pFanin0;
00384 break;
00385 }
00386 if ( pFanin1->fMarkA && pFanin1->fMarkB )
00387 {
00388 pPivot = pFanin1;
00389 break;
00390 }
00391 }
00392 if ( pPivot != NULL )
00393 break;
00394 }
00395 if ( pPivot == NULL )
00396 return 0;
00397
00398 if ( pFaninC && !pFaninC->fMarkA && !pFaninC->fMarkB )
00399 Vec_PtrPush( vFront, pFaninC );
00400
00401 Vec_PtrForEachEntry( vVolume, pObj, k )
00402 pObj->fMarkA = pObj->fMarkB = 0;
00403
00404
00405 Vec_PtrForEachEntry( vFront, pObj, k )
00406 pObj->fMarkA = 1;
00407
00408 Vec_PtrClear( vLeaves );
00409 Vec_PtrClear( vVolume );
00410 RetValue = Ivy_ManFindBoolCut_rec( p, pRoot, vLeaves, vVolume, pPivot );
00411 assert( RetValue == 1 );
00412
00413 Vec_PtrForEachEntry( vFront, pObj, k )
00414 pObj->fMarkA = 0;
00415
00416
00417 Vec_PtrForEachEntry( vVolume, pObj, k )
00418 pObj->fMarkA = 1;
00419
00420 while ( 1 )
00421 {
00422 Vec_PtrForEachEntry( vLeaves, pObj, k )
00423 if ( Ivy_ManFindBoolCutCost(pObj) < 2 )
00424 break;
00425 if ( k == Vec_PtrSize(vLeaves) )
00426 break;
00427
00428
00429 Vec_PtrRemove( vLeaves, pObj );
00430
00431 pFanin0 = Ivy_ObjFanin0(pObj);
00432 if ( !pFanin0->fMarkA )
00433 {
00434 pFanin0->fMarkA = 1;
00435 Vec_PtrPush( vVolume, pFanin0 );
00436 Vec_PtrPush( vLeaves, pFanin0 );
00437 }
00438 if ( Ivy_ObjIsBuf(pObj) )
00439 continue;
00440
00441 pFanin1 = Ivy_ObjFanin1(pObj);
00442 if ( !pFanin1->fMarkA )
00443 {
00444 pFanin1->fMarkA = 1;
00445 Vec_PtrPush( vVolume, pFanin1 );
00446 Vec_PtrPush( vLeaves, pFanin1 );
00447 }
00448 }
00449
00450 Vec_PtrForEachEntry( vVolume, pObj, k )
00451 pObj->fMarkA = 0;
00452 return 1;
00453 }
00454
00455
00467 void Ivy_ManTestCutsBool( Ivy_Man_t * p )
00468 {
00469 Vec_Ptr_t * vFront, * vVolume, * vLeaves;
00470 Ivy_Obj_t * pObj;
00471 int i, RetValue;
00472 vFront = Vec_PtrAlloc( 100 );
00473 vVolume = Vec_PtrAlloc( 100 );
00474 vLeaves = Vec_PtrAlloc( 100 );
00475 Ivy_ManForEachObj( p, pObj, i )
00476 {
00477 if ( !Ivy_ObjIsNode(pObj) )
00478 continue;
00479 if ( Ivy_ObjIsMuxType(pObj) )
00480 {
00481 printf( "m" );
00482 continue;
00483 }
00484 if ( Ivy_ObjIsExor(pObj) )
00485 printf( "x" );
00486 RetValue = Ivy_ManFindBoolCut( p, pObj, vFront, vVolume, vLeaves );
00487 if ( RetValue == 0 )
00488 printf( "- " );
00489 else
00490 printf( "%d ", Vec_PtrSize(vLeaves) );
00491
00492
00493
00494
00495
00496
00497 }
00498 printf( "\n" );
00499 Vec_PtrFree( vFront );
00500 Vec_PtrFree( vVolume );
00501 Vec_PtrFree( vLeaves );
00502 }
00503
00504
00505
00517 static inline unsigned Ivy_NodeCutHash( Ivy_Cut_t * pCut )
00518 {
00519 int i;
00520
00521
00522 pCut->uHash = 0;
00523 for ( i = 0; i < pCut->nSize; i++ )
00524 pCut->uHash |= (1 << (pCut->pArray[i] % 31));
00525 return pCut->uHash;
00526 }
00527
00539 static inline void Ivy_NodeCutShrink( Ivy_Cut_t * pCut, int iOld )
00540 {
00541 int i, k;
00542 for ( i = k = 0; i < pCut->nSize; i++ )
00543 if ( pCut->pArray[i] != iOld )
00544 pCut->pArray[k++] = pCut->pArray[i];
00545 assert( k == pCut->nSize - 1 );
00546 pCut->nSize--;
00547 }
00548
00560 static inline int Ivy_NodeCutExtend( Ivy_Cut_t * pCut, int iNew )
00561 {
00562 int i;
00563 for ( i = 0; i < pCut->nSize; i++ )
00564 if ( pCut->pArray[i] == iNew )
00565 return 1;
00566
00567 if ( pCut->nSize == pCut->nSizeMax )
00568 return 0;
00569
00570 for ( i = pCut->nSize - 1; i >= 0; i-- )
00571 if ( pCut->pArray[i] > iNew )
00572 pCut->pArray[i+1] = pCut->pArray[i];
00573 else
00574 {
00575 assert( pCut->pArray[i] < iNew );
00576 break;
00577 }
00578 pCut->pArray[i+1] = iNew;
00579 pCut->nSize++;
00580 return 1;
00581 }
00582
00594 static inline int Ivy_NodeCutPrescreen( Ivy_Cut_t * pCut, int Id0, int Id1 )
00595 {
00596 int i;
00597 if ( pCut->nSize < pCut->nSizeMax )
00598 return 1;
00599 for ( i = 0; i < pCut->nSize; i++ )
00600 if ( pCut->pArray[i] == Id0 || pCut->pArray[i] == Id1 )
00601 return 1;
00602 return 0;
00603 }
00604
00616 static inline int Ivy_NodeCutDeriveNew( Ivy_Cut_t * pCut, Ivy_Cut_t * pCutNew, int IdOld, int IdNew0, int IdNew1 )
00617 {
00618 unsigned uHash = 0;
00619 int i, k;
00620 assert( pCut->nSize > 0 );
00621 assert( IdNew0 < IdNew1 );
00622 for ( i = k = 0; i < pCut->nSize; i++ )
00623 {
00624 if ( pCut->pArray[i] == IdOld )
00625 continue;
00626 if ( IdNew0 <= pCut->pArray[i] )
00627 {
00628 if ( IdNew0 < pCut->pArray[i] )
00629 {
00630 pCutNew->pArray[ k++ ] = IdNew0;
00631 uHash |= Ivy_NodeCutHashValue( IdNew0 );
00632 }
00633 IdNew0 = 0x7FFFFFFF;
00634 }
00635 if ( IdNew1 <= pCut->pArray[i] )
00636 {
00637 if ( IdNew1 < pCut->pArray[i] )
00638 {
00639 pCutNew->pArray[ k++ ] = IdNew1;
00640 uHash |= Ivy_NodeCutHashValue( IdNew1 );
00641 }
00642 IdNew1 = 0x7FFFFFFF;
00643 }
00644 pCutNew->pArray[ k++ ] = pCut->pArray[i];
00645 uHash |= Ivy_NodeCutHashValue( pCut->pArray[i] );
00646 }
00647 if ( IdNew0 < 0x7FFFFFFF )
00648 {
00649 pCutNew->pArray[ k++ ] = IdNew0;
00650 uHash |= Ivy_NodeCutHashValue( IdNew0 );
00651 }
00652 if ( IdNew1 < 0x7FFFFFFF )
00653 {
00654 pCutNew->pArray[ k++ ] = IdNew1;
00655 uHash |= Ivy_NodeCutHashValue( IdNew1 );
00656 }
00657 pCutNew->nSize = k;
00658 pCutNew->uHash = uHash;
00659 assert( pCutNew->nSize <= pCut->nSizeMax );
00660
00661
00662 return 1;
00663 }
00664
00676 int Ivy_NodeCutFindOrAdd( Ivy_Store_t * pCutStore, Ivy_Cut_t * pCutNew )
00677 {
00678 Ivy_Cut_t * pCut;
00679 int i, k;
00680 assert( pCutNew->uHash );
00681
00682 for ( i = 0; i < pCutStore->nCuts; i++ )
00683 {
00684 pCut = pCutStore->pCuts + i;
00685 if ( pCut->uHash == pCutNew->uHash && pCut->nSize == pCutNew->nSize )
00686 {
00687 for ( k = 0; k < pCutNew->nSize; k++ )
00688 if ( pCut->pArray[k] != pCutNew->pArray[k] )
00689 break;
00690 if ( k == pCutNew->nSize )
00691 return 1;
00692 }
00693 }
00694 assert( pCutStore->nCuts < pCutStore->nCutsMax );
00695
00696 pCut = pCutStore->pCuts + pCutStore->nCuts++;
00697 *pCut = *pCutNew;
00698 return 0;
00699 }
00700
00712 static inline int Ivy_CutCheckDominance( Ivy_Cut_t * pDom, Ivy_Cut_t * pCut )
00713 {
00714 int i, k;
00715 for ( i = 0; i < pDom->nSize; i++ )
00716 {
00717 for ( k = 0; k < pCut->nSize; k++ )
00718 if ( pDom->pArray[i] == pCut->pArray[k] )
00719 break;
00720 if ( k == pCut->nSize )
00721 return 0;
00722 }
00723
00724 return 1;
00725 }
00726
00738 int Ivy_NodeCutFindOrAddFilter( Ivy_Store_t * pCutStore, Ivy_Cut_t * pCutNew )
00739 {
00740 Ivy_Cut_t * pCut;
00741 int i, k;
00742 assert( pCutNew->uHash );
00743
00744 for ( i = 0; i < pCutStore->nCuts; i++ )
00745 {
00746 pCut = pCutStore->pCuts + i;
00747 if ( pCut->nSize == 0 )
00748 continue;
00749 if ( pCut->nSize == pCutNew->nSize )
00750 {
00751 if ( pCut->uHash == pCutNew->uHash )
00752 {
00753 for ( k = 0; k < pCutNew->nSize; k++ )
00754 if ( pCut->pArray[k] != pCutNew->pArray[k] )
00755 break;
00756 if ( k == pCutNew->nSize )
00757 return 1;
00758 }
00759 continue;
00760 }
00761 if ( pCut->nSize < pCutNew->nSize )
00762 {
00763
00764 if ( (pCut->uHash & pCutNew->uHash) != pCut->uHash )
00765 continue;
00766
00767 if ( Ivy_CutCheckDominance( pCut, pCutNew ) )
00768 return 1;
00769 continue;
00770 }
00771
00772
00773
00774 if ( (pCut->uHash & pCutNew->uHash) != pCutNew->uHash )
00775 continue;
00776
00777 if ( Ivy_CutCheckDominance( pCutNew, pCut ) )
00778 {
00779
00780
00781
00782
00783
00784 pCut->nSize = 0;
00785 }
00786 }
00787 assert( pCutStore->nCuts < pCutStore->nCutsMax );
00788
00789 pCut = pCutStore->pCuts + pCutStore->nCuts++;
00790 *pCut = *pCutNew;
00791 return 0;
00792 }
00793
00805 void Ivy_NodeCompactCuts( Ivy_Store_t * pCutStore )
00806 {
00807 Ivy_Cut_t * pCut;
00808 int i, k;
00809 for ( i = k = 0; i < pCutStore->nCuts; i++ )
00810 {
00811 pCut = pCutStore->pCuts + i;
00812 if ( pCut->nSize == 0 )
00813 continue;
00814 pCutStore->pCuts[k++] = *pCut;
00815 }
00816 pCutStore->nCuts = k;
00817 }
00818
00830 void Ivy_NodePrintCut( Ivy_Cut_t * pCut )
00831 {
00832 int i;
00833 assert( pCut->nSize > 0 );
00834 printf( "%d : {", pCut->nSize );
00835 for ( i = 0; i < pCut->nSize; i++ )
00836 printf( " %d", pCut->pArray[i] );
00837 printf( " }\n" );
00838 }
00839
00851 void Ivy_NodePrintCuts( Ivy_Store_t * pCutStore )
00852 {
00853 int i;
00854 printf( "Node %d\n", pCutStore->pCuts[0].pArray[0] );
00855 for ( i = 0; i < pCutStore->nCuts; i++ )
00856 Ivy_NodePrintCut( pCutStore->pCuts + i );
00857 }
00858
00870 static inline Ivy_Obj_t * Ivy_ObjRealFanin( Ivy_Obj_t * pObj )
00871 {
00872 if ( !Ivy_ObjIsBuf(pObj) )
00873 return pObj;
00874 return Ivy_ObjRealFanin( Ivy_ObjFanin0(pObj) );
00875 }
00876
00888 Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Man_t * p, Ivy_Obj_t * pObj, int nLeaves )
00889 {
00890 static Ivy_Store_t CutStore, * pCutStore = &CutStore;
00891 Ivy_Cut_t CutNew, * pCutNew = &CutNew, * pCut;
00892 Ivy_Obj_t * pLeaf;
00893 int i, k, iLeaf0, iLeaf1;
00894
00895 assert( nLeaves <= IVY_CUT_INPUT );
00896
00897
00898 pCutStore->nCuts = 0;
00899 pCutStore->nCutsMax = IVY_CUT_LIMIT;
00900
00901 pCutNew->uHash = 0;
00902 pCutNew->nSize = 1;
00903 pCutNew->nSizeMax = nLeaves;
00904 pCutNew->pArray[0] = pObj->Id;
00905 Ivy_NodeCutHash( pCutNew );
00906
00907 Ivy_NodeCutFindOrAdd( pCutStore, pCutNew );
00908 assert( pCutStore->nCuts == 1 );
00909
00910
00911 for ( i = 0; i < pCutStore->nCuts; i++ )
00912 {
00913
00914 pCut = pCutStore->pCuts + i;
00915 if ( pCut->nSize == 0 )
00916 continue;
00917 for ( k = 0; k < pCut->nSize; k++ )
00918 {
00919 pLeaf = Ivy_ManObj( p, pCut->pArray[k] );
00920 if ( Ivy_ObjIsCi(pLeaf) )
00921 continue;
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931 iLeaf0 = Ivy_ObjId( Ivy_ObjRealFanin(Ivy_ObjFanin0(pLeaf)) );
00932 iLeaf1 = Ivy_ObjId( Ivy_ObjRealFanin(Ivy_ObjFanin1(pLeaf)) );
00933
00934
00935 if ( !Ivy_NodeCutPrescreen( pCut, iLeaf0, iLeaf1 ) )
00936 continue;
00937 if ( iLeaf0 > iLeaf1 )
00938 Ivy_NodeCutDeriveNew( pCut, pCutNew, pCut->pArray[k], iLeaf1, iLeaf0 );
00939 else
00940 Ivy_NodeCutDeriveNew( pCut, pCutNew, pCut->pArray[k], iLeaf0, iLeaf1 );
00941 Ivy_NodeCutFindOrAddFilter( pCutStore, pCutNew );
00942 if ( pCutStore->nCuts == IVY_CUT_LIMIT )
00943 break;
00944 }
00945 if ( pCutStore->nCuts == IVY_CUT_LIMIT )
00946 break;
00947 }
00948 Ivy_NodeCompactCuts( pCutStore );
00949
00950 return pCutStore;
00951 }
00952
00964 void Ivy_ManTestCutsAll( Ivy_Man_t * p )
00965 {
00966 Ivy_Obj_t * pObj;
00967 int i, nCutsCut, nCutsTotal, nNodeTotal, nNodeOver;
00968 int clk = clock();
00969 nNodeTotal = nNodeOver = 0;
00970 nCutsTotal = -Ivy_ManNodeNum(p);
00971 Ivy_ManForEachObj( p, pObj, i )
00972 {
00973 if ( !Ivy_ObjIsNode(pObj) )
00974 continue;
00975 nCutsCut = Ivy_NodeFindCutsAll( p, pObj, 5 )->nCuts;
00976 nCutsTotal += nCutsCut;
00977 nNodeOver += (nCutsCut == IVY_CUT_LIMIT);
00978 nNodeTotal++;
00979 }
00980 printf( "Total cuts = %6d. Trivial = %6d. Nodes = %6d. Satur = %6d. ",
00981 nCutsTotal, Ivy_ManPiNum(p) + Ivy_ManNodeNum(p), nNodeTotal, nNodeOver );
00982 PRT( "Time", clock() - clk );
00983 }
00984
00988
00989