00001
00021 #include "abc.h"
00022 #include "dec.h"
00023 #include "dsd.h"
00024 #include "cut.h"
00025
00029
00030 #define RST_RANDOM_UNSIGNED ((((unsigned)rand()) << 24) ^ (((unsigned)rand()) << 12) ^ ((unsigned)rand()))
00031
00032 typedef struct Abc_ManRst_t_ Abc_ManRst_t;
00033 struct Abc_ManRst_t_
00034 {
00035
00036 Abc_Ntk_t * pNtk;
00037
00038 int nCutMax;
00039 int fUpdateLevel;
00040 int fUseZeros;
00041 int fVerbose;
00042
00043 DdManager * dd;
00044 Dsd_Manager_t * pManDsd;
00045 Vec_Ptr_t * vVisited;
00046 Vec_Ptr_t * vLeaves;
00047 Vec_Ptr_t * vDecs;
00048 Vec_Ptr_t * vTemp;
00049 Vec_Int_t * vSims;
00050 Vec_Int_t * vRands;
00051 Vec_Int_t * vOnes;
00052 Vec_Int_t * vBinate;
00053 Vec_Int_t * vTwos;
00054
00055 int nLastGain;
00056 int nCutsConsidered;
00057 int nCutsExplored;
00058 int nNodesConsidered;
00059 int nNodesRestructured;
00060 int nNodesGained;
00061
00062 int timeCut;
00063 int timeBdd;
00064 int timeDsd;
00065 int timeEval;
00066 int timeRes;
00067 int timeNtk;
00068 int timeTotal;
00069 };
00070
00071 static Dec_Graph_t * Abc_NodeResubstitute( Abc_ManRst_t * p, Abc_Obj_t * pNode, Cut_Cut_t * pCutList );
00072
00073 static Dec_Graph_t * Abc_NodeRestructure( Abc_ManRst_t * p, Abc_Obj_t * pNode, Cut_Cut_t * pCutList );
00074 static Dec_Graph_t * Abc_NodeRestructureCut( Abc_ManRst_t * p, Abc_Obj_t * pNode, Cut_Cut_t * pCut );
00075 static Dec_Graph_t * Abc_NodeEvaluateDsd( Abc_ManRst_t * pManRst, Dsd_Node_t * pNodeDsd, Abc_Obj_t * pRoot, int Required, int nNodesSaved, int * pnNodesAdded );
00076
00077 static Cut_Man_t * Abc_NtkStartCutManForRestruct( Abc_Ntk_t * pNtk, int nCutMax, int fDag );
00078 static Abc_ManRst_t * Abc_NtkManRstStart( int nCutMax, bool fUpdateLevel, bool fUseZeros, bool fVerbose );
00079 static void Abc_NtkManRstStop( Abc_ManRst_t * p );
00080 static void Abc_NtkManRstPrintStats( Abc_ManRst_t * p );
00081
00085
00097 int Abc_NtkRestructure( Abc_Ntk_t * pNtk, int nCutMax, bool fUpdateLevel, bool fUseZeros, bool fVerbose )
00098 {
00099 ProgressBar * pProgress;
00100 Abc_ManRst_t * pManRst;
00101 Cut_Man_t * pManCut;
00102 Cut_Cut_t * pCutList;
00103 Dec_Graph_t * pGraph;
00104 Abc_Obj_t * pNode;
00105 int clk, clkStart = clock();
00106 int fMulti = 1;
00107 int fResub = 0;
00108 int i, nNodes;
00109
00110 assert( Abc_NtkIsStrash(pNtk) );
00111
00112 Abc_AigCleanup(pNtk->pManFunc);
00113 Abc_NtkCleanCopy(pNtk);
00114
00115
00116 if ( fUpdateLevel )
00117 Abc_NtkStartReverseLevels( pNtk, 0 );
00118
00119
00120 pManRst = Abc_NtkManRstStart( nCutMax, fUpdateLevel, fUseZeros, fVerbose );
00121 pManRst->pNtk = pNtk;
00122
00123 clk = clock();
00124 pManCut = Abc_NtkStartCutManForRestruct( pNtk, nCutMax, fMulti );
00125 pManRst->timeCut += clock() - clk;
00126
00127
00128
00129 nNodes = Abc_NtkObjNumMax(pNtk);
00130 pProgress = Extra_ProgressBarStart( stdout, nNodes );
00131 Abc_NtkForEachNode( pNtk, pNode, i )
00132 {
00133 Extra_ProgressBarUpdate( pProgress, i, NULL );
00134
00135
00136
00137
00138 if ( Abc_NodeIsPersistant(pNode) )
00139 continue;
00140
00141
00142
00143
00144 if ( Abc_ObjFanoutNum(pNode) > 1000 )
00145 continue;
00146
00147 if ( i >= nNodes )
00148 break;
00149
00150 clk = clock();
00151 pCutList = Abc_NodeGetCutsRecursive( pManCut, pNode, fMulti, 0 );
00152 pManRst->timeCut += clock() - clk;
00153
00154
00155 clk = clock();
00156 if ( fResub )
00157 pGraph = Abc_NodeResubstitute( pManRst, pNode, pCutList );
00158 else
00159 pGraph = Abc_NodeRestructure( pManRst, pNode, pCutList );
00160 pManRst->timeRes += clock() - clk;
00161 if ( pGraph == NULL )
00162 continue;
00163
00164
00165 clk = clock();
00166 Dec_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, pManRst->nLastGain );
00167 pManRst->timeNtk += clock() - clk;
00168 Dec_GraphFree( pGraph );
00169 }
00170 Extra_ProgressBarStop( pProgress );
00171 pManRst->timeTotal = clock() - clkStart;
00172
00173
00174
00175 Abc_NtkManRstPrintStats( pManRst );
00176
00177 Cut_ManStop( pManCut );
00178 Abc_NtkManRstStop( pManRst );
00179
00180 Abc_NtkReassignIds( pNtk );
00181
00182
00183 if ( fUpdateLevel )
00184 Abc_NtkStopReverseLevels( pNtk );
00185 else
00186 Abc_NtkLevel( pNtk );
00187
00188 if ( !Abc_NtkCheck( pNtk ) )
00189 {
00190 printf( "Abc_NtkRefactor: The network check has failed.\n" );
00191 return 0;
00192 }
00193 return 1;
00194 }
00195
00207 void Abc_RestructNodeDivisors( Abc_ManRst_t * p, Abc_Obj_t * pRoot, int nNodesSaved )
00208 {
00209 Abc_Obj_t * pNode, * pFanout;
00210 int i, k;
00211
00212 Vec_PtrClear( p->vDecs );
00213 Vec_PtrForEachEntry( p->vLeaves, pNode, i )
00214 {
00215 Vec_PtrPush( p->vDecs, pNode );
00216 assert( pNode->fMarkC == 0 );
00217 pNode->fMarkC = 1;
00218 }
00219
00220 Vec_PtrForEachEntry( p->vDecs, pNode, i )
00221 {
00222
00223 Abc_ObjForEachFanout( pNode, pFanout, k )
00224 {
00225 if ( pFanout->fMarkC || Abc_ObjIsPo(pFanout) )
00226 continue;
00227 if ( Abc_ObjFanin0(pFanout)->fMarkC && Abc_ObjFanin1(pFanout)->fMarkC )
00228 {
00229 Vec_PtrPush( p->vDecs, pFanout );
00230 pFanout->fMarkC = 1;
00231 }
00232 }
00233 }
00234
00235 Vec_PtrForEachEntry( p->vDecs, pNode, i )
00236 pNode->fMarkC = 0;
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 printf( "%d\n", Vec_PtrSize(p->vDecs)-nNodesSaved-Vec_PtrSize(p->vLeaves) );
00264 }
00265
00266
00278 Dec_Graph_t * Abc_NodeRestructure( Abc_ManRst_t * p, Abc_Obj_t * pNode, Cut_Cut_t * pCutList )
00279 {
00280 Dec_Graph_t * pGraph;
00281 Cut_Cut_t * pCut;
00282
00283 p->nNodesConsidered++;
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 for ( pCut = pCutList; pCut; pCut = pCut->pNext )
00294 {
00295 if ( pCut->nLeaves < 4 )
00296 continue;
00297 if ( pGraph = Abc_NodeRestructureCut( p, pNode, pCut ) )
00298 return pGraph;
00299 }
00300 return NULL;
00301 }
00302
00314 Dec_Graph_t * Abc_NodeRestructureCut( Abc_ManRst_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut )
00315 {
00316 Dec_Graph_t * pGraph;
00317 Dsd_Node_t * pNodeDsd;
00318 Abc_Obj_t * pLeaf;
00319 DdNode * bFunc;
00320 int nNodesSaved, nNodesAdded;
00321 int Required, nMaxSize, clk, i;
00322 int fVeryVerbose = 0;
00323
00324 p->nCutsConsidered++;
00325
00326
00327 Required = p->fUpdateLevel? Abc_ObjRequiredLevel(pRoot) : ABC_INFINITY;
00328
00329
00330 Vec_PtrClear( p->vLeaves );
00331 for ( i = 0; i < (int)pCut->nLeaves; i++ )
00332 {
00333 pLeaf = Abc_NtkObj(pRoot->pNtk, pCut->pLeaves[i]);
00334 if ( pLeaf == NULL )
00335 return NULL;
00336 Vec_PtrPush( p->vLeaves, pLeaf );
00337 }
00338
00339 if ( pRoot->Id == 29 )
00340 {
00341 int x = 0;
00342 }
00343
00344 clk = clock();
00345
00346
00347
00348 bFunc = Abc_NodeConeBdd( p->dd, p->dd->vars, pRoot, p->vLeaves, p->vVisited ); Cudd_Ref( bFunc );
00349 p->timeBdd += clock() - clk;
00350
00351
00352 if ( Cudd_IsConstant(bFunc) )
00353 {
00354 p->nLastGain = Abc_NodeMffcSize( pRoot );
00355 p->nNodesGained += p->nLastGain;
00356 p->nNodesRestructured++;
00357 Cudd_RecursiveDeref( p->dd, bFunc );
00358 if ( Cudd_IsComplement(bFunc) )
00359 return Dec_GraphCreateConst0();
00360 return Dec_GraphCreateConst1();
00361 }
00362
00363 clk = clock();
00364
00365 pNodeDsd = Dsd_DecomposeOne( p->pManDsd, bFunc );
00366 p->timeDsd += clock() - clk;
00367
00368
00369 Dsd_TreeNodeGetInfoOne( pNodeDsd, NULL, &nMaxSize );
00370 if ( nMaxSize > 3 )
00371 {
00372 Cudd_RecursiveDeref( p->dd, bFunc );
00373 return NULL;
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386 p->nCutsExplored++;
00387
00388
00389
00390 Vec_PtrForEachEntry( p->vLeaves, pLeaf, i )
00391 pLeaf->vFanouts.nSize++;
00392
00393 Abc_NtkIncrementTravId( pRoot->pNtk );
00394 nNodesSaved = Abc_NodeMffcLabelAig( pRoot );
00395
00396 Vec_PtrForEachEntry( p->vLeaves, pLeaf, i )
00397 pLeaf->vFanouts.nSize--;
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 clk = clock();
00424 if ( nMaxSize > 3 )
00425 pGraph = NULL;
00426 else
00427 pGraph = Abc_NodeEvaluateDsd( p, pNodeDsd, pRoot, Required, nNodesSaved, &nNodesAdded );
00428
00429 p->timeEval += clock() - clk;
00430
00431
00432 if ( pGraph == NULL || nNodesAdded == -1 || nNodesAdded == nNodesSaved && !p->fUseZeros )
00433 {
00434 Cudd_RecursiveDeref( p->dd, bFunc );
00435 if ( pGraph ) Dec_GraphFree( pGraph );
00436 return NULL;
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 p->nLastGain = nNodesSaved - nNodesAdded;
00450 p->nNodesGained += p->nLastGain;
00451 p->nNodesRestructured++;
00452
00453
00454 if ( fVeryVerbose )
00455 {
00456 printf( "Node %6s : ", Abc_ObjName(pRoot) );
00457 printf( "Cone = %2d. ", p->vLeaves->nSize );
00458 printf( "BDD = %2d. ", Cudd_DagSize(bFunc) );
00459 printf( "FF = %2d. ", 1 + Dec_GraphNodeNum(pGraph) );
00460 printf( "MFFC = %2d. ", nNodesSaved );
00461 printf( "Add = %2d. ", nNodesAdded );
00462 printf( "GAIN = %2d. ", p->nLastGain );
00463 printf( "\n" );
00464 }
00465 Cudd_RecursiveDeref( p->dd, bFunc );
00466 return pGraph;
00467 }
00468
00469
00482 void Abc_NodeEdgeDsdPermute( Dec_Graph_t * pGraph, Abc_ManRst_t * pManRst, Vec_Int_t * vEdges, int fExor )
00483 {
00484 Dec_Edge_t eNode1, eNode2, eNode3;
00485 Abc_Obj_t * pNode1, * pNode2, * pNode3, * pTemp;
00486 int LeftBound = 0, RightBound, i;
00487
00488 RightBound = Vec_IntSize(vEdges) - 2;
00489 assert( LeftBound <= RightBound );
00490 if ( LeftBound == RightBound )
00491 return;
00492
00493 eNode1 = Dec_IntToEdge( Vec_IntEntry(vEdges, RightBound + 1) );
00494 eNode2 = Dec_IntToEdge( Vec_IntEntry(vEdges, RightBound ) );
00495 pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc;
00496 pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc;
00497 pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl );
00498 pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl );
00499
00500 if ( pNode1 == NULL )
00501 return;
00502
00503 for ( i = RightBound; i >= LeftBound; i-- )
00504 {
00505
00506 eNode3 = Dec_IntToEdge( Vec_IntEntry(vEdges, i) );
00507 pNode3 = Dec_GraphNode( pGraph, eNode3.Node )->pFunc;
00508 pNode3 = !pNode3? NULL : Abc_ObjNotCond( pNode3, eNode3.fCompl );
00509 if ( pNode3 == NULL )
00510 continue;
00511
00512 if ( fExor )
00513 {
00514 if ( pNode1 && pNode3 )
00515 {
00516 pTemp = Abc_AigXorLookup( pManRst->pNtk->pManFunc, pNode1, pNode3, NULL );
00517 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00518 continue;
00519
00520 if ( pNode3 == pNode2 )
00521 return;
00522 Vec_IntWriteEntry( vEdges, i, Dec_EdgeToInt(eNode2) );
00523 Vec_IntWriteEntry( vEdges, RightBound, Dec_EdgeToInt(eNode3) );
00524 return;
00525 }
00526 }
00527 else
00528 {
00529 if ( pNode1 && pNode3 )
00530 {
00531 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode3) );
00532 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00533 continue;
00534
00535 if ( eNode3.Node == eNode2.Node )
00536 return;
00537 Vec_IntWriteEntry( vEdges, i, Dec_EdgeToInt(eNode2) );
00538 Vec_IntWriteEntry( vEdges, RightBound, Dec_EdgeToInt(eNode3) );
00539 return;
00540 }
00541 }
00542 }
00543 }
00544
00556 void Abc_NodeEdgeDsdPushOrdered( Dec_Graph_t * pGraph, Vec_Int_t * vEdges, int Edge )
00557 {
00558 int i, NodeOld, NodeNew;
00559 vEdges->nSize++;
00560 for ( i = vEdges->nSize-2; i >= 0; i-- )
00561 {
00562 NodeOld = Dec_IntToEdge(vEdges->pArray[i]).Node;
00563 NodeNew = Dec_IntToEdge(Edge).Node;
00564
00565 if ( Dec_GraphNode(pGraph, NodeOld)->Level <= Dec_GraphNode(pGraph, NodeNew)->Level )
00566 vEdges->pArray[i+1] = vEdges->pArray[i];
00567 else
00568 break;
00569 }
00570 vEdges->pArray[i+1] = Edge;
00571 }
00572
00584 Dec_Edge_t Abc_NodeEvaluateDsd_rec( Dec_Graph_t * pGraph, Abc_ManRst_t * pManRst, Dsd_Node_t * pNodeDsd, int Required, int nNodesSaved, int * pnNodesAdded )
00585 {
00586 Dec_Edge_t eNode1, eNode2, eNode3, eResult, eQuit = { 0, 2006 };
00587 Abc_Obj_t * pNode1, * pNode2, * pNode3, * pNode4, * pTemp;
00588 Dsd_Node_t * pChildDsd;
00589 Dsd_Type_t DecType;
00590 Vec_Int_t * vEdges;
00591 int Level1, Level2, Level3, Level4;
00592 int i, Index, fCompl, Type;
00593
00594
00595 fCompl = Dsd_IsComplement( pNodeDsd );
00596 pNodeDsd = Dsd_Regular( pNodeDsd );
00597
00598
00599 DecType = Dsd_NodeReadType( pNodeDsd );
00600 if ( DecType == DSD_NODE_BUF )
00601 {
00602 Index = Dsd_NodeReadFunc(pNodeDsd)->index;
00603 assert( Index < Dec_GraphLeaveNum(pGraph) );
00604 eResult = Dec_EdgeCreate( Index, fCompl );
00605 return eResult;
00606 }
00607 assert( DecType == DSD_NODE_OR || DecType == DSD_NODE_EXOR || DecType == DSD_NODE_PRIME );
00608
00609
00610 vEdges = Vec_IntAlloc( Dsd_NodeReadDecsNum(pNodeDsd) );
00611 Dsd_NodeForEachChild( pNodeDsd, i, pChildDsd )
00612 {
00613 eResult = Abc_NodeEvaluateDsd_rec( pGraph, pManRst, pChildDsd, Required, nNodesSaved, pnNodesAdded );
00614 if ( eResult.Node == eQuit.Node )
00615 {
00616 Vec_IntFree( vEdges );
00617 return eQuit;
00618 }
00619
00620 if ( DecType == DSD_NODE_PRIME )
00621 Vec_IntPush( vEdges, Dec_EdgeToInt(eResult) );
00622 else
00623 Abc_NodeEdgeDsdPushOrdered( pGraph, vEdges, Dec_EdgeToInt(eResult) );
00624 }
00625
00626
00627
00628
00629 if ( DecType == DSD_NODE_OR )
00630 {
00631
00632 assert( Vec_IntSize(vEdges) > 1 );
00633 while ( Vec_IntSize(vEdges) > 1 )
00634 {
00635
00636 if ( Vec_IntSize(vEdges) > 2 )
00637 Abc_NodeEdgeDsdPermute( pGraph, pManRst, vEdges, 0 );
00638
00639 eNode1 = Dec_IntToEdge( Vec_IntPop(vEdges) );
00640 eNode2 = Dec_IntToEdge( Vec_IntPop(vEdges) );
00641 pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc;
00642 pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc;
00643 pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl );
00644 pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl );
00645
00646 pNode3 = NULL;
00647 if ( pNode1 && pNode2 )
00648 {
00649 pNode3 = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) );
00650 pNode3 = !pNode3? NULL : Abc_ObjNot(pNode3);
00651 }
00652
00653 eNode3 = Dec_GraphAddNodeOr( pGraph, eNode1, eNode2 );
00654
00655 Level1 = Dec_GraphNode( pGraph, eNode1.Node )->Level;
00656 Level2 = Dec_GraphNode( pGraph, eNode2.Node )->Level;
00657 Dec_GraphNode( pGraph, eNode3.Node )->Level = 1 + ABC_MAX(Level1, Level2);
00658
00659 if ( pNode3 )
00660 {
00661 Dec_GraphNode( pGraph, eNode3.Node )->pFunc = Abc_ObjNotCond(pNode3, eNode3.fCompl);
00662 Level3 = Dec_GraphNode( pGraph, eNode3.Node )->Level;
00663 assert( Required == ABC_INFINITY || Level3 == (int)Abc_ObjRegular(pNode3)->Level );
00664 }
00665 if ( !pNode3 || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pNode3)) )
00666 {
00667 (*pnNodesAdded)++;
00668 if ( *pnNodesAdded > nNodesSaved )
00669 {
00670 Vec_IntFree( vEdges );
00671 return eQuit;
00672 }
00673 }
00674
00675 Abc_NodeEdgeDsdPushOrdered( pGraph, vEdges, Dec_EdgeToInt(eNode3) );
00676 }
00677
00678 eResult = Dec_IntToEdge( Vec_IntPop(vEdges) );
00679 Vec_IntFree( vEdges );
00680
00681 eResult.fCompl ^= fCompl;
00682 return eResult;
00683 }
00684 if ( DecType == DSD_NODE_EXOR )
00685 {
00686
00687 assert( Vec_IntSize(vEdges) > 1 );
00688 while ( Vec_IntSize(vEdges) > 1 )
00689 {
00690
00691 if ( Vec_IntSize(vEdges) > 2 )
00692 Abc_NodeEdgeDsdPermute( pGraph, pManRst, vEdges, 1 );
00693
00694 eNode1 = Dec_IntToEdge( Vec_IntPop(vEdges) );
00695 eNode2 = Dec_IntToEdge( Vec_IntPop(vEdges) );
00696 pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc;
00697 pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc;
00698 pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl );
00699 pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl );
00700
00701 Type = 0;
00702 pNode3 = NULL;
00703 if ( pNode1 && pNode2 )
00704 pNode3 = Abc_AigXorLookup( pManRst->pNtk->pManFunc, pNode1, pNode2, &Type );
00705
00706 eNode3 = Dec_GraphAddNodeXor( pGraph, eNode1, eNode2, Type );
00707
00708 Level1 = Dec_GraphNode( pGraph, eNode1.Node )->Level;
00709 Level2 = Dec_GraphNode( pGraph, eNode2.Node )->Level;
00710 Dec_GraphNode( pGraph, eNode3.Node )->Level = 2 + ABC_MAX(Level1, Level2);
00711
00712 if ( pNode3 )
00713 {
00714 Dec_GraphNode( pGraph, eNode3.Node )->pFunc = Abc_ObjNotCond(pNode3, eNode3.fCompl);
00715 Level3 = Dec_GraphNode( pGraph, eNode3.Node )->Level;
00716 assert( Required == ABC_INFINITY || Level3 == (int)Abc_ObjRegular(pNode3)->Level );
00717 }
00718 if ( !pNode3 || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pNode3)) )
00719 {
00720 (*pnNodesAdded)++;
00721 if ( !pNode1 || !pNode2 )
00722 (*pnNodesAdded) += 2;
00723 else if ( Type == 0 )
00724 {
00725 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, Abc_ObjNot(pNode2) );
00726 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00727 (*pnNodesAdded)++;
00728 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), pNode2 );
00729 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00730 (*pnNodesAdded)++;
00731 }
00732 else
00733 {
00734 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode2) );
00735 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00736 (*pnNodesAdded)++;
00737 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, pNode2 );
00738 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00739 (*pnNodesAdded)++;
00740 }
00741 if ( *pnNodesAdded > nNodesSaved )
00742 {
00743 Vec_IntFree( vEdges );
00744 return eQuit;
00745 }
00746 }
00747
00748 Abc_NodeEdgeDsdPushOrdered( pGraph, vEdges, Dec_EdgeToInt(eNode3) );
00749 }
00750
00751 eResult = Dec_IntToEdge( Vec_IntPop(vEdges) );
00752 Vec_IntFree( vEdges );
00753
00754 eResult.fCompl ^= fCompl;
00755 return eResult;
00756 }
00757 if ( DecType == DSD_NODE_PRIME )
00758 {
00759 DdNode * bLocal, * bVar, * bCofT, * bCofE;
00760 bLocal = Dsd_TreeGetPrimeFunction( pManRst->dd, pNodeDsd ); Cudd_Ref( bLocal );
00761
00762
00763 bVar = pManRst->dd->vars[0];
00764 bCofE = Cudd_Cofactor( pManRst->dd, bLocal, Cudd_Not(bVar) ); Cudd_Ref( bCofE );
00765 bCofT = Cudd_Cofactor( pManRst->dd, bLocal, bVar ); Cudd_Ref( bCofT );
00766 if ( !Extra_bddIsVar(bCofE) || !Extra_bddIsVar(bCofT) )
00767 {
00768 Cudd_RecursiveDeref( pManRst->dd, bCofE );
00769 Cudd_RecursiveDeref( pManRst->dd, bCofT );
00770 bVar = pManRst->dd->vars[1];
00771 bCofE = Cudd_Cofactor( pManRst->dd, bLocal, Cudd_Not(bVar) ); Cudd_Ref( bCofE );
00772 bCofT = Cudd_Cofactor( pManRst->dd, bLocal, bVar ); Cudd_Ref( bCofT );
00773 if ( !Extra_bddIsVar(bCofE) || !Extra_bddIsVar(bCofT) )
00774 {
00775 Cudd_RecursiveDeref( pManRst->dd, bCofE );
00776 Cudd_RecursiveDeref( pManRst->dd, bCofT );
00777 bVar = pManRst->dd->vars[2];
00778 bCofE = Cudd_Cofactor( pManRst->dd, bLocal, Cudd_Not(bVar) ); Cudd_Ref( bCofE );
00779 bCofT = Cudd_Cofactor( pManRst->dd, bLocal, bVar ); Cudd_Ref( bCofT );
00780 if ( !Extra_bddIsVar(bCofE) || !Extra_bddIsVar(bCofT) )
00781 {
00782 Cudd_RecursiveDeref( pManRst->dd, bCofE );
00783 Cudd_RecursiveDeref( pManRst->dd, bCofT );
00784 Cudd_RecursiveDeref( pManRst->dd, bLocal );
00785 Vec_IntFree( vEdges );
00786 return eQuit;
00787 }
00788 }
00789 }
00790 Cudd_RecursiveDeref( pManRst->dd, bLocal );
00791
00792
00793
00794 eNode1 = Dec_IntToEdge( Vec_IntEntry(vEdges, bVar->index) );
00795 eNode2 = Dec_IntToEdge( Vec_IntEntry(vEdges, Cudd_Regular(bCofT)->index) );
00796 eNode3 = Dec_IntToEdge( Vec_IntEntry(vEdges, Cudd_Regular(bCofE)->index) );
00797
00798 eNode2.fCompl ^= Cudd_IsComplement(bCofT);
00799 eNode3.fCompl ^= Cudd_IsComplement(bCofE);
00800
00801
00802 Cudd_RecursiveDeref( pManRst->dd, bCofE );
00803 Cudd_RecursiveDeref( pManRst->dd, bCofT );
00804
00805
00806 pNode1 = Dec_GraphNode( pGraph, eNode1.Node )->pFunc;
00807 pNode2 = Dec_GraphNode( pGraph, eNode2.Node )->pFunc;
00808 pNode3 = Dec_GraphNode( pGraph, eNode3.Node )->pFunc;
00809 pNode1 = !pNode1? NULL : Abc_ObjNotCond( pNode1, eNode1.fCompl );
00810 pNode2 = !pNode2? NULL : Abc_ObjNotCond( pNode2, eNode2.fCompl );
00811 pNode3 = !pNode3? NULL : Abc_ObjNotCond( pNode3, eNode3.fCompl );
00812
00813
00814 Type = 0;
00815 pNode4 = NULL;
00816 if ( pNode1 && pNode2 && pNode3 )
00817 pNode4 = Abc_AigMuxLookup( pManRst->pNtk->pManFunc, pNode1, pNode2, pNode3, &Type );
00818
00819
00820 eResult = Dec_GraphAddNodeMux( pGraph, eNode1, eNode2, eNode3, Type );
00821
00822
00823 Level1 = Dec_GraphNode( pGraph, eNode1.Node )->Level;
00824 Level2 = Dec_GraphNode( pGraph, eNode2.Node )->Level;
00825 Level3 = Dec_GraphNode( pGraph, eNode3.Node )->Level;
00826 Dec_GraphNode( pGraph, eResult.Node )->Level = 2 + ABC_MAX( ABC_MAX(Level1, Level2), Level3 );
00827
00828 if ( pNode4 )
00829 {
00830 Dec_GraphNode( pGraph, eResult.Node )->pFunc = Abc_ObjNotCond(pNode4, eResult.fCompl);
00831 Level4 = Dec_GraphNode( pGraph, eResult.Node )->Level;
00832 assert( Required == ABC_INFINITY || Level4 == (int)Abc_ObjRegular(pNode4)->Level );
00833 }
00834 if ( !pNode4 || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pNode4)) )
00835 {
00836 (*pnNodesAdded)++;
00837 if ( Type == 0 )
00838 {
00839 if ( !pNode1 || !pNode2 )
00840 (*pnNodesAdded)++;
00841 else
00842 {
00843 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, pNode2 );
00844 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00845 (*pnNodesAdded)++;
00846 }
00847 if ( !pNode1 || !pNode3 )
00848 (*pnNodesAdded)++;
00849 else
00850 {
00851 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), pNode3 );
00852 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00853 (*pnNodesAdded)++;
00854 }
00855 }
00856 else
00857 {
00858 if ( !pNode1 || !pNode2 )
00859 (*pnNodesAdded)++;
00860 else
00861 {
00862 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, pNode1, Abc_ObjNot(pNode2) );
00863 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00864 (*pnNodesAdded)++;
00865 }
00866 if ( !pNode1 || !pNode3 )
00867 (*pnNodesAdded)++;
00868 else
00869 {
00870 pTemp = Abc_AigAndLookup( pManRst->pNtk->pManFunc, Abc_ObjNot(pNode1), Abc_ObjNot(pNode3) );
00871 if ( !pTemp || Abc_NodeIsTravIdCurrent(Abc_ObjRegular(pTemp)) )
00872 (*pnNodesAdded)++;
00873 }
00874 }
00875 if ( *pnNodesAdded > nNodesSaved )
00876 {
00877 Vec_IntFree( vEdges );
00878 return eQuit;
00879 }
00880 }
00881
00882 Vec_IntFree( vEdges );
00883
00884 eResult.fCompl ^= fCompl;
00885 return eResult;
00886 }
00887 Vec_IntFree( vEdges );
00888 return eQuit;
00889 }
00890
00902 Dec_Graph_t * Abc_NodeEvaluateDsd( Abc_ManRst_t * pManRst, Dsd_Node_t * pNodeDsd, Abc_Obj_t * pRoot, int Required, int nNodesSaved, int * pnNodesAdded )
00903 {
00904 Dec_Graph_t * pGraph;
00905 Dec_Edge_t gEdge;
00906 Abc_Obj_t * pLeaf;
00907 Dec_Node_t * pNode;
00908 int i;
00909
00910
00911 pGraph = Dec_GraphCreate( Vec_PtrSize(pManRst->vLeaves) );
00912 Dec_GraphForEachLeaf( pGraph, pNode, i )
00913 {
00914 pLeaf = Vec_PtrEntry( pManRst->vLeaves, i );
00915 pNode->pFunc = pLeaf;
00916 pNode->Level = pLeaf->Level;
00917 }
00918
00919
00920 *pnNodesAdded = 0;
00921 gEdge = Abc_NodeEvaluateDsd_rec( pGraph, pManRst, pNodeDsd, Required, nNodesSaved, pnNodesAdded );
00922 if ( gEdge.Node > 1000 )
00923 {
00924 *pnNodesAdded = -1;
00925 Dec_GraphFree( pGraph );
00926 return NULL;
00927 }
00928
00929
00930 pLeaf = Dec_GraphNode( pGraph, gEdge.Node )->pFunc;
00931 if ( Abc_ObjRegular(pLeaf) == pRoot )
00932 {
00933 *pnNodesAdded = -1;
00934 Dec_GraphFree( pGraph );
00935 return NULL;
00936 }
00937
00938 Dec_GraphSetRoot( pGraph, gEdge );
00939 return pGraph;
00940 }
00941
00942
00943
00955 Cut_Man_t * Abc_NtkStartCutManForRestruct( Abc_Ntk_t * pNtk, int nCutMax, int fDag )
00956 {
00957 static Cut_Params_t Params, * pParams = &Params;
00958 Cut_Man_t * pManCut;
00959 Abc_Obj_t * pObj;
00960 int i;
00961
00962 memset( pParams, 0, sizeof(Cut_Params_t) );
00963 pParams->nVarsMax = nCutMax;
00964 pParams->nKeepMax = 250;
00965 pParams->fTruth = 0;
00966 pParams->fFilter = 1;
00967 pParams->fSeq = 0;
00968 pParams->fDrop = 0;
00969 pParams->fDag = fDag;
00970 pParams->fTree = 0;
00971 pParams->fVerbose = 0;
00972 pParams->nIdsMax = Abc_NtkObjNumMax( pNtk );
00973 pManCut = Cut_ManStart( pParams );
00974 if ( pParams->fDrop )
00975 Cut_ManSetFanoutCounts( pManCut, Abc_NtkFanoutCounts(pNtk) );
00976
00977 Abc_NtkForEachCi( pNtk, pObj, i )
00978 if ( Abc_ObjFanoutNum(pObj) > 0 )
00979 Cut_NodeSetTriv( pManCut, pObj->Id );
00980 return pManCut;
00981 }
00982
00994 Abc_ManRst_t * Abc_NtkManRstStart( int nCutMax, bool fUpdateLevel, bool fUseZeros, bool fVerbose )
00995 {
00996 Abc_ManRst_t * p;
00997 p = ALLOC( Abc_ManRst_t, 1 );
00998 memset( p, 0, sizeof(Abc_ManRst_t) );
00999
01000 p->nCutMax = nCutMax;
01001 p->fUpdateLevel = fUpdateLevel;
01002 p->fUseZeros = fUseZeros;
01003 p->fVerbose = fVerbose;
01004
01005 p->dd = Cudd_Init( p->nCutMax, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
01006 Cudd_zddVarsFromBddVars( p->dd, 2 );
01007
01008 p->pManDsd = Dsd_ManagerStart( p->dd, p->dd->size, 0 );
01009
01010 p->vVisited = Vec_PtrAlloc( 100 );
01011 p->vLeaves = Vec_PtrAlloc( 100 );
01012 p->vDecs = Vec_PtrAlloc( 100 );
01013 p->vTemp = Vec_PtrAlloc( 100 );
01014 p->vSims = Vec_IntAlloc( 100 );
01015 p->vOnes = Vec_IntAlloc( 100 );
01016 p->vBinate = Vec_IntAlloc( 100 );
01017 p->vTwos = Vec_IntAlloc( 100 );
01018 p->vRands = Vec_IntAlloc( 20 );
01019
01020 {
01021 int i;
01022 for ( i = 0; i < 20; i++ )
01023 Vec_IntPush( p->vRands, (int)RST_RANDOM_UNSIGNED );
01024 }
01025 return p;
01026 }
01027
01039 void Abc_NtkManRstStop( Abc_ManRst_t * p )
01040 {
01041 Dsd_ManagerStop( p->pManDsd );
01042 Extra_StopManager( p->dd );
01043 Vec_PtrFree( p->vDecs );
01044 Vec_PtrFree( p->vLeaves );
01045 Vec_PtrFree( p->vVisited );
01046 Vec_PtrFree( p->vTemp );
01047 Vec_IntFree( p->vSims );
01048 Vec_IntFree( p->vOnes );
01049 Vec_IntFree( p->vBinate );
01050 Vec_IntFree( p->vTwos );
01051 Vec_IntFree( p->vRands );
01052 free( p );
01053 }
01054
01066 void Abc_NtkManRstPrintStats( Abc_ManRst_t * p )
01067 {
01068 printf( "Refactoring statistics:\n" );
01069 printf( "Nodes considered = %8d.\n", p->nNodesConsidered );
01070 printf( "Cuts considered = %8d.\n", p->nCutsConsidered );
01071 printf( "Cuts explored = %8d.\n", p->nCutsExplored );
01072 printf( "Nodes restructured = %8d.\n", p->nNodesRestructured );
01073 printf( "Calculated gain = %8d.\n", p->nNodesGained );
01074 PRT( "Cuts ", p->timeCut );
01075 PRT( "Resynthesis", p->timeRes );
01076 PRT( " BDD ", p->timeBdd );
01077 PRT( " DSD ", p->timeDsd );
01078 PRT( " Eval ", p->timeEval );
01079 PRT( "AIG update ", p->timeNtk );
01080 PRT( "TOTAL ", p->timeTotal );
01081 }
01082
01083
01095 int Abc_Abc_NodeResubCollectDivs( Abc_ManRst_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut )
01096 {
01097 Abc_Obj_t * pNode, * pFanout;
01098 int i, k;
01099
01100 Vec_PtrClear( p->vDecs );
01101 Abc_NtkIncrementTravId( pRoot->pNtk );
01102 for ( i = 0; i < (int)pCut->nLeaves; i++ )
01103 {
01104 pNode = Abc_NtkObj(pRoot->pNtk, pCut->pLeaves[i]);
01105 if ( pNode == NULL )
01106 return 0;
01107 Vec_PtrPush( p->vDecs, pNode );
01108 Abc_NodeSetTravIdCurrent( pNode );
01109 }
01110
01111 Vec_PtrForEachEntry( p->vDecs, pNode, i )
01112 {
01113
01114 Abc_ObjForEachFanout( pNode, pFanout, k )
01115 {
01116 if ( Abc_NodeIsTravIdCurrent(pFanout) || Abc_ObjIsPo(pFanout) )
01117 continue;
01118 if ( Abc_NodeIsTravIdCurrent(Abc_ObjFanin0(pFanout)) && Abc_NodeIsTravIdCurrent(Abc_ObjFanin1(pFanout)) )
01119 {
01120 Vec_PtrPush( p->vDecs, pFanout );
01121 Abc_NodeSetTravIdCurrent( pFanout );
01122 }
01123 }
01124 }
01125 return 1;
01126 }
01127
01139 int Abc_NodeResubMffc_rec( Abc_Obj_t * pNode )
01140 {
01141 if ( Abc_NodeIsTravIdCurrent(pNode) )
01142 return 0;
01143 Abc_NodeSetTravIdCurrent( pNode );
01144 return 1 + Abc_NodeResubMffc_rec( Abc_ObjFanin0(pNode) ) +
01145 Abc_NodeResubMffc_rec( Abc_ObjFanin1(pNode) );
01146 }
01147
01159 int Abc_NodeResubMffc( Abc_ManRst_t * p, Vec_Ptr_t * vDecs, int nLeaves, Abc_Obj_t * pRoot )
01160 {
01161 Abc_Obj_t * pObj;
01162 int Counter, i, k;
01163
01164 Abc_NtkIncrementTravId( pRoot->pNtk );
01165
01166 Vec_PtrForEachEntryStop( vDecs, pObj, i, nLeaves )
01167 Abc_NodeSetTravIdCurrent( pObj );
01168
01169 assert( Abc_NodeIsTravIdPrevious(pRoot) );
01170 Counter = Abc_NodeResubMffc_rec( pRoot );
01171
01172 Vec_PtrClear( p->vTemp );
01173 k = 0;
01174 Vec_PtrForEachEntryStart( vDecs, pObj, i, nLeaves )
01175 if ( Abc_NodeIsTravIdCurrent(pObj) )
01176 Vec_PtrPush( p->vTemp, pObj );
01177 else
01178 Vec_PtrWriteEntry( vDecs, k++, pObj );
01179
01180 Vec_PtrForEachEntry( p->vTemp, pObj, i )
01181 Vec_PtrWriteEntry( vDecs, k++, pObj );
01182 assert( k == Vec_PtrSize(p->vDecs) );
01183 assert( pRoot == Vec_PtrEntryLast(p->vDecs) );
01184 return Counter;
01185 }
01186
01198 void Abc_NodeMffcSimulate( Vec_Ptr_t * vDecs, int nLeaves, Vec_Int_t * vRands, Vec_Int_t * vSims )
01199 {
01200 Abc_Obj_t * pObj;
01201 unsigned uData0, uData1, uData;
01202 int i;
01203
01204 Vec_IntClear( vSims );
01205 Vec_PtrForEachEntryStop( vDecs, pObj, i, nLeaves )
01206 {
01207 uData = (unsigned)Vec_IntEntry( vRands, i );
01208 pObj->pData = (void *)uData;
01209 Vec_IntPush( vSims, uData );
01210 }
01211
01212 Vec_PtrForEachEntryStart( vDecs, pObj, i, nLeaves )
01213 {
01214 uData0 = (unsigned)Abc_ObjFanin0(pObj)->pData;
01215 uData1 = (unsigned)Abc_ObjFanin1(pObj)->pData;
01216 uData = (Abc_ObjFaninC0(pObj)? ~uData0 : uData0) & (Abc_ObjFaninC1(pObj)? ~uData1 : uData1);
01217 pObj->pData = (void *)uData;
01218 Vec_IntPush( vSims, uData );
01219 }
01220 }
01221
01233 int Abc_NodeCheckFull( Abc_ManRst_t * p, Dec_Graph_t * pGraph )
01234 {
01235 return 1;
01236 }
01248 Dec_Graph_t * Abc_NodeMffcConstants( Abc_ManRst_t * p, Vec_Int_t * vSims )
01249 {
01250 Dec_Graph_t * pGraph;
01251 unsigned uRoot;
01252
01253 uRoot = (unsigned)Vec_IntEntryLast( vSims );
01254
01255 if ( uRoot == 0 )
01256 pGraph = Dec_GraphCreateConst0();
01257 else if ( uRoot == ~(unsigned)0 )
01258 pGraph = Dec_GraphCreateConst1();
01259
01260 if ( Abc_NodeCheckFull( p, pGraph ) )
01261 return pGraph;
01262 Dec_GraphFree( pGraph );
01263 return NULL;
01264 }
01265
01277 Dec_Graph_t * Abc_NodeMffcSingleVar( Abc_ManRst_t * p, Vec_Int_t * vSims, int nNodes, Vec_Int_t * vOnes )
01278 {
01279 Dec_Graph_t * pGraph;
01280 unsigned uRoot, uNode;
01281 int i;
01282
01283 Vec_IntClear( vOnes );
01284 Vec_IntClear( p->vBinate );
01285 uRoot = (unsigned)Vec_IntEntryLast( vSims );
01286 for ( i = 0; i < nNodes; i++ )
01287 {
01288 uNode = (unsigned)Vec_IntEntry( vSims, i );
01289 if ( uRoot == uNode || uRoot == ~uNode )
01290 {
01291 pGraph = Dec_GraphCreate( 1 );
01292 Dec_GraphNode( pGraph, 0 )->pFunc = Vec_PtrEntry( p->vDecs, i );
01293 Dec_GraphSetRoot( pGraph, Dec_IntToEdge( (int)(uRoot == ~uNode) ) );
01294
01295 if ( Abc_NodeCheckFull( p, pGraph ) )
01296 return pGraph;
01297 Dec_GraphFree( pGraph );
01298 }
01299 if ( (uRoot & uNode) == 0 )
01300 Vec_IntPush( vOnes, i << 1 );
01301 else if ( (uRoot & ~uNode) == 0 )
01302 Vec_IntPush( vOnes, (i << 1) + 1 );
01303 else
01304 Vec_IntPush( p->vBinate, i );
01305 }
01306 return NULL;
01307 }
01308
01320 Dec_Graph_t * Abc_NodeMffcSingleNode( Abc_ManRst_t * p, Vec_Int_t * vSims, int nNodes, Vec_Int_t * vOnes )
01321 {
01322 Dec_Graph_t * pGraph;
01323 Dec_Edge_t eNode0, eNode1, eRoot;
01324 unsigned uRoot;
01325 int i, k;
01326 uRoot = (unsigned)Vec_IntEntryLast( vSims );
01327 for ( i = 0; i < vOnes->nSize; i++ )
01328 for ( k = i+1; k < vOnes->nSize; k++ )
01329 if ( ~uRoot == ((unsigned)vOnes->pArray[i] | (unsigned)vOnes->pArray[k]) )
01330 {
01331 eNode0 = Dec_IntToEdge( vOnes->pArray[i] ^ 1 );
01332 eNode1 = Dec_IntToEdge( vOnes->pArray[k] ^ 1 );
01333 pGraph = Dec_GraphCreate( 2 );
01334 Dec_GraphNode( pGraph, 0 )->pFunc = Vec_PtrEntry( p->vDecs, eNode0.Node );
01335 Dec_GraphNode( pGraph, 1 )->pFunc = Vec_PtrEntry( p->vDecs, eNode1.Node );
01336 eRoot = Dec_GraphAddNodeAnd( pGraph, eNode0, eNode1 );
01337 Dec_GraphSetRoot( pGraph, eRoot );
01338 if ( Abc_NodeCheckFull( p, pGraph ) )
01339 return pGraph;
01340 Dec_GraphFree( pGraph );
01341 }
01342 return NULL;
01343 }
01344
01356 Dec_Graph_t * Abc_NodeMffcDoubleNode( Abc_ManRst_t * p, Vec_Int_t * vSims, int nNodes, Vec_Int_t * vOnes )
01357 {
01358
01359
01360
01361
01362
01363 return NULL;
01364 }
01365
01377 Dec_Graph_t * Abc_NodeResubEval( Abc_ManRst_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut )
01378 {
01379 Dec_Graph_t * pGraph;
01380 int nNodesSaved;
01381
01382
01383 if ( !Abc_Abc_NodeResubCollectDivs( p, pRoot, pCut ) )
01384 return NULL;
01385
01386
01387 nNodesSaved = Abc_NodeResubMffc( p, p->vDecs, pCut->nLeaves, pRoot );
01388 assert( nNodesSaved > 0 );
01389
01390
01391 Abc_NodeMffcSimulate( p->vDecs, pCut->nLeaves, p->vRands, p->vSims );
01392
01393
01394 pGraph = Abc_NodeMffcConstants( p, p->vSims );
01395 if ( pGraph )
01396 {
01397 p->nNodesGained += nNodesSaved;
01398 p->nNodesRestructured++;
01399 return pGraph;
01400 }
01401
01402
01403 pGraph = Abc_NodeMffcSingleVar( p, p->vSims, Vec_IntSize(p->vSims) - nNodesSaved, p->vOnes );
01404 if ( pGraph )
01405 {
01406 p->nNodesGained += nNodesSaved;
01407 p->nNodesRestructured++;
01408 return pGraph;
01409 }
01410 if ( nNodesSaved == 1 )
01411 return NULL;
01412
01413
01414 pGraph = Abc_NodeMffcSingleNode( p, p->vSims, Vec_IntSize(p->vSims) - nNodesSaved, p->vOnes );
01415 if ( pGraph )
01416 {
01417 p->nNodesGained += nNodesSaved - 1;
01418 p->nNodesRestructured++;
01419 return pGraph;
01420 }
01421 if ( nNodesSaved == 2 )
01422 return NULL;
01423
01424
01425 pGraph = Abc_NodeMffcDoubleNode( p, p->vSims, Vec_IntSize(p->vSims) - nNodesSaved, p->vOnes );
01426 if ( pGraph )
01427 {
01428 p->nNodesGained += nNodesSaved - 2;
01429 p->nNodesRestructured++;
01430 return pGraph;
01431 }
01432 if ( nNodesSaved == 3 )
01433 return NULL;
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444 return NULL;
01445 }
01446
01458 Dec_Graph_t * Abc_NodeResubstitute( Abc_ManRst_t * p, Abc_Obj_t * pNode, Cut_Cut_t * pCutList )
01459 {
01460 Dec_Graph_t * pGraph, * pGraphBest = NULL;
01461 Cut_Cut_t * pCut;
01462 int nCuts;
01463 p->nNodesConsidered++;
01464
01465
01466 nCuts = 0;
01467 for ( pCut = pCutList; pCut; pCut = pCut->pNext )
01468 nCuts += (int)(pCut->nLeaves > 3);
01469 printf( "-----------------------------------\n" );
01470 printf( "Node %6d : Factor-cuts = %5d.\n", pNode->Id, nCuts );
01471
01472
01473 for ( pCut = pCutList; pCut; pCut = pCut->pNext )
01474 {
01475 if ( pCut->nLeaves < 4 )
01476 continue;
01477 pGraph = Abc_NodeResubEval( p, pNode, pCut );
01478 if ( pGraph == NULL )
01479 continue;
01480 if ( !pGraphBest || Dec_GraphNodeNum(pGraph) < Dec_GraphNodeNum(pGraphBest) )
01481 {
01482 if ( pGraphBest )
01483 Dec_GraphFree(pGraphBest);
01484 pGraphBest = pGraph;
01485 }
01486 else
01487 Dec_GraphFree(pGraph);
01488 }
01489 return pGraphBest;
01490 }
01491
01495
01496