00001
00021 #include "rwr.h"
00022 #include "dec.h"
00023
00027
00028 static Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, int fPlaceEnable );
00029 static int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves );
00030 static int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut );
00031 static int Rwr_NodeGetDepth_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves );
00032
00036
00055 int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int fUpdateLevel, int fUseZeros, int fPlaceEnable )
00056 {
00057 int fVeryVerbose = 0;
00058 Dec_Graph_t * pGraph;
00059 Cut_Cut_t * pCut;
00060 Abc_Obj_t * pFanin;
00061 unsigned uPhase, uTruthBest, uTruth;
00062 char * pPerm;
00063 int Required, nNodesSaved, nNodesSaveCur;
00064 int i, GainCur, GainBest = -1;
00065 int clk, clk2;
00066
00067 p->nNodesConsidered++;
00068
00069 Required = fUpdateLevel? Abc_ObjRequiredLevel(pNode) : ABC_INFINITY;
00070
00071
00072 clk = clock();
00073 pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCut, pNode, 0, 0 );
00074 assert( pCut != NULL );
00075 p->timeCut += clock() - clk;
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 clk = clock();
00086 for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
00087 {
00088
00089 if ( pCut->nLeaves < 4 )
00090 continue;
00091
00092
00093
00094 uTruth = 0xFFFF & *Cut_CutReadTruth(pCut);
00095 pPerm = p->pPerms4[ p->pPerms[uTruth] ];
00096 uPhase = p->pPhases[uTruth];
00097
00098 Vec_PtrClear( p->vFaninsCur );
00099 Vec_PtrFill( p->vFaninsCur, (int)pCut->nLeaves, 0 );
00100 for ( i = 0; i < (int)pCut->nLeaves; i++ )
00101 {
00102 pFanin = Abc_NtkObj( pNode->pNtk, pCut->pLeaves[pPerm[i]] );
00103 if ( pFanin == NULL )
00104 break;
00105 pFanin = Abc_ObjNotCond(pFanin, ((uPhase & (1<<i)) > 0) );
00106 Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin );
00107 }
00108 if ( i != (int)pCut->nLeaves )
00109 {
00110 p->nCutsBad++;
00111 continue;
00112 }
00113 p->nCutsGood++;
00114
00115 {
00116 int Counter = 0;
00117 Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
00118 if ( Abc_ObjFanoutNum(Abc_ObjRegular(pFanin)) == 1 )
00119 Counter++;
00120 if ( Counter > 2 )
00121 continue;
00122 }
00123
00124 clk2 = clock();
00125
00126
00127
00128
00129
00130
00131
00132 Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
00133 Abc_ObjRegular(pFanin)->vFanouts.nSize++;
00134
00135
00136 Abc_NtkIncrementTravId( pNode->pNtk );
00137 nNodesSaved = Abc_NodeMffcLabelAig( pNode );
00138
00139 Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
00140 Abc_ObjRegular(pFanin)->vFanouts.nSize--;
00141 p->timeMffc += clock() - clk2;
00142
00143
00144 clk2 = clock();
00145 pGraph = Rwr_CutEvaluate( p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur, fPlaceEnable );
00146 p->timeEval += clock() - clk2;
00147
00148
00149 if ( pGraph != NULL && GainBest < GainCur )
00150 {
00151
00152 nNodesSaveCur = nNodesSaved;
00153 GainBest = GainCur;
00154 p->pGraph = pGraph;
00155 p->fCompl = ((uPhase & (1<<4)) > 0);
00156 uTruthBest = 0xFFFF & *Cut_CutReadTruth(pCut);
00157
00158 Vec_PtrClear( p->vFanins );
00159 Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
00160 Vec_PtrPush( p->vFanins, pFanin );
00161 }
00162 }
00163 p->timeRes += clock() - clk;
00164
00165 if ( GainBest == -1 )
00166 return -1;
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 Vec_PtrForEachEntry( p->vFanins, pFanin, i )
00204 Dec_GraphNode(p->pGraph, i)->pFunc = pFanin;
00205
00206
00207
00208
00209
00210
00211
00212
00213 p->nScores[p->pMap[uTruthBest]]++;
00214 p->nNodesGained += GainBest;
00215 if ( fUseZeros || GainBest > 0 )
00216 {
00217 p->nNodesRewritten++;
00218 }
00219
00220
00221 if ( fVeryVerbose && GainBest > 0 )
00222 {
00223 printf( "Node %6s : ", Abc_ObjName(pNode) );
00224 printf( "Fanins = %d. ", p->vFanins->nSize );
00225 printf( "Save = %d. ", nNodesSaveCur );
00226 printf( "Add = %d. ", nNodesSaveCur-GainBest );
00227 printf( "GAIN = %d. ", GainBest );
00228 printf( "Cone = %d. ", p->pGraph? Dec_GraphNodeNum(p->pGraph) : 0 );
00229 printf( "Class = %d. ", p->pMap[uTruthBest] );
00230 printf( "\n" );
00231 }
00232 return GainBest;
00233 }
00234
00246 Dec_Graph_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, int fPlaceEnable )
00247 {
00248 Vec_Ptr_t * vSubgraphs;
00249 Dec_Graph_t * pGraphBest, * pGraphCur;
00250 Rwr_Node_t * pNode, * pFanin;
00251 int nNodesAdded, GainBest, i, k;
00252 unsigned uTruth;
00253 float CostBest;
00254
00255 uTruth = 0xFFFF & *Cut_CutReadTruth(pCut);
00256 vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] );
00257 p->nSubgraphs += vSubgraphs->nSize;
00258
00259 GainBest = -1;
00260 CostBest = ABC_INFINITY;
00261 Vec_PtrForEachEntry( vSubgraphs, pNode, i )
00262 {
00263
00264 pGraphCur = (Dec_Graph_t *)pNode->pNext;
00265
00266 Vec_PtrForEachEntry( vFaninsCur, pFanin, k )
00267 Dec_GraphNode(pGraphCur, k)->pFunc = pFanin;
00268
00269 nNodesAdded = Dec_GraphToNetworkCount( pRoot, pGraphCur, nNodesSaved, LevelMax );
00270 if ( nNodesAdded == -1 )
00271 continue;
00272 assert( nNodesSaved >= nNodesAdded );
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 {
00311
00312 if ( GainBest < nNodesSaved - nNodesAdded )
00313 {
00314 GainBest = nNodesSaved - nNodesAdded;
00315 pGraphBest = pGraphCur;
00316
00317
00318 if ( nNodesSaved - nNodesAdded > 0 )
00319 {
00320 pNode->nScore++;
00321 pNode->nGain += GainBest;
00322 pNode->nAdded += nNodesAdded;
00323 }
00324 }
00325 }
00326 }
00327 if ( GainBest == -1 )
00328 return NULL;
00329 *pGainBest = GainBest;
00330 return pGraphBest;
00331 }
00332
00344 void Rwr_CutIsBoolean_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves, int fMarkA )
00345 {
00346 if ( Vec_PtrFind(vLeaves, pObj) >= 0 || Vec_PtrFind(vLeaves, Abc_ObjNot(pObj)) >= 0 )
00347 {
00348 if ( fMarkA )
00349 pObj->fMarkA = 1;
00350 else
00351 pObj->fMarkB = 1;
00352 return;
00353 }
00354 assert( !Abc_ObjIsCi(pObj) );
00355 Rwr_CutIsBoolean_rec( Abc_ObjFanin0(pObj), vLeaves, fMarkA );
00356 Rwr_CutIsBoolean_rec( Abc_ObjFanin1(pObj), vLeaves, fMarkA );
00357 }
00358
00370 int Rwr_CutIsBoolean( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves )
00371 {
00372 Abc_Obj_t * pTemp;
00373 int i, RetValue;
00374 Vec_PtrForEachEntry( vLeaves, pTemp, i )
00375 {
00376 pTemp = Abc_ObjRegular(pTemp);
00377 assert( !pTemp->fMarkA && !pTemp->fMarkB );
00378 }
00379 Rwr_CutIsBoolean_rec( Abc_ObjFanin0(pObj), vLeaves, 1 );
00380 Rwr_CutIsBoolean_rec( Abc_ObjFanin1(pObj), vLeaves, 0 );
00381 RetValue = 0;
00382 Vec_PtrForEachEntry( vLeaves, pTemp, i )
00383 {
00384 pTemp = Abc_ObjRegular(pTemp);
00385 RetValue |= pTemp->fMarkA && pTemp->fMarkB;
00386 pTemp->fMarkA = pTemp->fMarkB = 0;
00387 }
00388 return RetValue;
00389 }
00390
00391
00403 void Rwr_CutCountNumNodes_rec( Abc_Obj_t * pObj, Cut_Cut_t * pCut, Vec_Ptr_t * vNodes )
00404 {
00405 int i;
00406 for ( i = 0; i < (int)pCut->nLeaves; i++ )
00407 if ( pCut->pLeaves[i] == pObj->Id )
00408 {
00409
00410 if ( pObj->fMarkC == 0 )
00411 {
00412 pObj->fMarkC = 1;
00413 Vec_PtrPush( vNodes, pObj );
00414 }
00415 return;
00416 }
00417 assert( Abc_ObjIsNode(pObj) );
00418
00419 if ( pObj->fMarkC == 0 )
00420 {
00421 pObj->fMarkC = 1;
00422 Vec_PtrPush( vNodes, pObj );
00423 }
00424
00425 Rwr_CutCountNumNodes_rec( Abc_ObjFanin0(pObj), pCut, vNodes );
00426 Rwr_CutCountNumNodes_rec( Abc_ObjFanin1(pObj), pCut, vNodes );
00427 }
00428
00440 int Rwr_CutCountNumNodes( Abc_Obj_t * pObj, Cut_Cut_t * pCut )
00441 {
00442 Vec_Ptr_t * vNodes;
00443 int i, Counter;
00444
00445 vNodes = Vec_PtrAlloc( 100 );
00446 for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
00447 Rwr_CutCountNumNodes_rec( pObj, pCut, vNodes );
00448
00449 Vec_PtrForEachEntry( vNodes, pObj, i )
00450 pObj->fMarkC = 0;
00451
00452 Counter = Vec_PtrSize(vNodes);
00453 Vec_PtrFree( vNodes );
00454 return Counter;
00455 }
00456
00457
00469 int Rwr_NodeGetDepth_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vLeaves )
00470 {
00471 Abc_Obj_t * pLeaf;
00472 int i, Depth0, Depth1;
00473 if ( Abc_ObjIsCi(pObj) )
00474 return 0;
00475 Vec_PtrForEachEntry( vLeaves, pLeaf, i )
00476 if ( pObj == Abc_ObjRegular(pLeaf) )
00477 return 0;
00478 Depth0 = Rwr_NodeGetDepth_rec( Abc_ObjFanin0(pObj), vLeaves );
00479 Depth1 = Rwr_NodeGetDepth_rec( Abc_ObjFanin1(pObj), vLeaves );
00480 return 1 + ABC_MAX( Depth0, Depth1 );
00481 }
00482
00483
00495 void Rwr_ScoresClean( Rwr_Man_t * p )
00496 {
00497 Vec_Ptr_t * vSubgraphs;
00498 Rwr_Node_t * pNode;
00499 int i, k;
00500 for ( i = 0; i < p->vClasses->nSize; i++ )
00501 {
00502 vSubgraphs = Vec_VecEntry( p->vClasses, i );
00503 Vec_PtrForEachEntry( vSubgraphs, pNode, k )
00504 pNode->nScore = pNode->nGain = pNode->nAdded = 0;
00505 }
00506 }
00507
00508 static int Gains[222];
00509
00521 int Rwr_ScoresCompare( int * pNum1, int * pNum2 )
00522 {
00523 if ( Gains[*pNum1] > Gains[*pNum2] )
00524 return -1;
00525 if ( Gains[*pNum1] < Gains[*pNum2] )
00526 return 1;
00527 return 0;
00528 }
00529
00541 void Rwr_ScoresReport( Rwr_Man_t * p )
00542 {
00543 extern void Ivy_TruthDsdComputePrint( unsigned uTruth );
00544 int Perm[222];
00545 Vec_Ptr_t * vSubgraphs;
00546 Rwr_Node_t * pNode;
00547 int i, iNew, k;
00548 unsigned uTruth;
00549
00550 assert( p->vClasses->nSize == 222 );
00551 for ( i = 0; i < p->vClasses->nSize; i++ )
00552 {
00553 Perm[i] = i;
00554 Gains[i] = 0;
00555 vSubgraphs = Vec_VecEntry( p->vClasses, i );
00556 Vec_PtrForEachEntry( vSubgraphs, pNode, k )
00557 Gains[i] += pNode->nGain;
00558 }
00559
00560 qsort( Perm, 222, sizeof(int), (int (*)(const void *, const void *))Rwr_ScoresCompare );
00561
00562
00563 for ( i = 0; i < p->vClasses->nSize; i++ )
00564 {
00565 iNew = Perm[i];
00566 if ( Gains[iNew] == 0 )
00567 break;
00568 vSubgraphs = Vec_VecEntry( p->vClasses, iNew );
00569 printf( "CLASS %3d: Subgr = %3d. Total gain = %6d. ", iNew, Vec_PtrSize(vSubgraphs), Gains[iNew] );
00570 uTruth = (unsigned)p->pMapInv[iNew];
00571 Extra_PrintBinary( stdout, &uTruth, 16 );
00572 printf( " " );
00573 Ivy_TruthDsdComputePrint( (unsigned)p->pMapInv[iNew] | ((unsigned)p->pMapInv[iNew] << 16) );
00574 Vec_PtrForEachEntry( vSubgraphs, pNode, k )
00575 {
00576 if ( pNode->nScore == 0 )
00577 continue;
00578 printf( " %2d: S=%5d. A=%5d. G=%6d. ", k, pNode->nScore, pNode->nAdded, pNode->nGain );
00579 Dec_GraphPrint( stdout, (Dec_Graph_t *)pNode->pNext, NULL, NULL );
00580 }
00581 }
00582 }
00583
00587
00588