00001
00021 #include "abc.h"
00022 #include "resInt.h"
00023
00027
00031
00043 Res_Win_t * Res_WinAlloc()
00044 {
00045 Res_Win_t * p;
00046
00047 p = ALLOC( Res_Win_t, 1 );
00048 memset( p, 0, sizeof(Res_Win_t) );
00049
00050 p->nFanoutLimit = 10;
00051 p->nLevTfiMinus = 3;
00052
00053 p->vRoots = Vec_PtrAlloc( 256 );
00054 p->vLeaves = Vec_PtrAlloc( 256 );
00055 p->vBranches = Vec_PtrAlloc( 256 );
00056 p->vNodes = Vec_PtrAlloc( 256 );
00057 p->vDivs = Vec_PtrAlloc( 256 );
00058 p->vMatrix = Vec_VecStart( 128 );
00059 return p;
00060 }
00061
00073 void Res_WinFree( Res_Win_t * p )
00074 {
00075 Vec_PtrFree( p->vRoots );
00076 Vec_PtrFree( p->vLeaves );
00077 Vec_PtrFree( p->vBranches );
00078 Vec_PtrFree( p->vNodes );
00079 Vec_PtrFree( p->vDivs );
00080 Vec_VecFree( p->vMatrix );
00081 free( p );
00082 }
00083
00084
00085
00097 int Res_WinCollectLeavesAndNodes( Res_Win_t * p )
00098 {
00099 Vec_Ptr_t * vFront;
00100 Abc_Obj_t * pObj, * pTemp;
00101 int i, k, m;
00102
00103 assert( p->nWinTfiMax > 0 );
00104 assert( Vec_VecSize(p->vMatrix) > p->nWinTfiMax );
00105
00106
00107 Vec_VecClear( p->vMatrix );
00108 Vec_VecPush( p->vMatrix, 0, p->pNode );
00109 Abc_NtkIncrementTravId( p->pNode->pNtk );
00110 Abc_NodeSetTravIdCurrent( p->pNode );
00111
00112
00113 Vec_PtrClear( p->vLeaves );
00114 Vec_VecForEachLevelStartStop( p->vMatrix, vFront, i, 0, p->nWinTfiMax )
00115 {
00116 Vec_PtrForEachEntry( vFront, pObj, k )
00117 {
00118 Abc_ObjForEachFanin( pObj, pTemp, m )
00119 {
00120 if ( Abc_NodeIsTravIdCurrent( pTemp ) )
00121 continue;
00122 Abc_NodeSetTravIdCurrent( pTemp );
00123 if ( Abc_ObjIsCi(pTemp) || (int)(p->pNode->Level - pTemp->Level) > p->nWinTfiMax )
00124 Vec_PtrPush( p->vLeaves, pTemp );
00125 else
00126 Vec_VecPush( p->vMatrix, p->pNode->Level - pTemp->Level, pTemp );
00127 }
00128 }
00129 }
00130 if ( Vec_PtrSize(p->vLeaves) == 0 )
00131 return 0;
00132
00133
00134 Vec_PtrClear( p->vNodes );
00135 Vec_VecForEachLevelReverseStartStop( p->vMatrix, vFront, i, p->nWinTfiMax, 0 )
00136 {
00137 Vec_PtrForEachEntry( vFront, pObj, k )
00138 Vec_PtrPush( p->vNodes, pObj );
00139 Vec_PtrClear( vFront );
00140 }
00141
00142
00143 p->nLevLeafMin = ABC_INFINITY;
00144 Vec_PtrForEachEntry( p->vLeaves, pObj, k )
00145 p->nLevLeafMin = ABC_MIN( p->nLevLeafMin, (int)pObj->Level );
00146
00147
00148 p->nLevTravMin = ABC_MAX( ((int)p->pNode->Level) - p->nWinTfiMax - p->nLevTfiMinus, p->nLevLeafMin );
00149 assert( p->nLevTravMin >= 0 );
00150 return 1;
00151 }
00152
00153
00154
00166 static inline int Res_WinComputeRootsCheck( Abc_Obj_t * pNode, int nLevelMax, int nFanoutLimit )
00167 {
00168 Abc_Obj_t * pFanout;
00169 int i;
00170
00171
00172 if ( Abc_ObjFanoutNum(pNode) > nFanoutLimit )
00173 return 1;
00174
00175
00176 Abc_ObjForEachFanout( pNode, pFanout, i )
00177 if ( Abc_ObjIsCo(pFanout) || (int)pFanout->Level > nLevelMax )
00178 return 1;
00179 return 0;
00180 }
00181
00193 void Res_WinComputeRoots_rec( Abc_Obj_t * pNode, int nLevelMax, int nFanoutLimit, Vec_Ptr_t * vRoots )
00194 {
00195 Abc_Obj_t * pFanout;
00196 int i;
00197 assert( Abc_ObjIsNode(pNode) );
00198 if ( Abc_NodeIsTravIdCurrent(pNode) )
00199 return;
00200 Abc_NodeSetTravIdCurrent( pNode );
00201
00202 if ( Res_WinComputeRootsCheck( pNode, nLevelMax, nFanoutLimit ) )
00203 Vec_PtrPush( vRoots, pNode );
00204 else
00205 Abc_ObjForEachFanout( pNode, pFanout, i )
00206 Res_WinComputeRoots_rec( pFanout, nLevelMax, nFanoutLimit, vRoots );
00207 }
00208
00220 int Res_WinComputeRoots( Res_Win_t * p )
00221 {
00222 Vec_PtrClear( p->vRoots );
00223 Abc_NtkIncrementTravId( p->pNode->pNtk );
00224 Res_WinComputeRoots_rec( p->pNode, p->pNode->Level + p->nWinTfoMax, p->nFanoutLimit, p->vRoots );
00225 assert( Vec_PtrSize(p->vRoots) > 0 );
00226 if ( Vec_PtrSize(p->vRoots) == 1 && Vec_PtrEntry(p->vRoots, 0) == p->pNode )
00227 return 0;
00228 return 1;
00229 }
00230
00231
00232
00244 int Res_WinMarkPaths_rec( Abc_Obj_t * pNode, Abc_Obj_t * pPivot, int nLevelMin )
00245 {
00246 Abc_Obj_t * pFanin;
00247 int i, RetValue;
00248
00249 if ( Abc_NodeIsTravIdCurrent(pNode) )
00250 return 1;
00251 if ( Abc_NodeIsTravIdPrevious(pNode) )
00252 return 0;
00253
00254 Abc_NodeSetTravIdPrevious( pNode );
00255
00256 if ( pNode == pPivot || (int)pNode->Level <= nLevelMin )
00257 return 0;
00258 assert( Abc_ObjIsNode(pNode) );
00259
00260 RetValue = 0;
00261 Abc_ObjForEachFanin( pNode, pFanin, i )
00262 RetValue |= Res_WinMarkPaths_rec( pFanin, pPivot, nLevelMin );
00263
00264 if ( RetValue )
00265 Abc_NodeSetTravIdCurrent( pNode );
00266 return RetValue;
00267 }
00268
00280 void Res_WinMarkPaths( Res_Win_t * p )
00281 {
00282 Abc_Obj_t * pObj;
00283 int i;
00284
00285 Abc_NtkIncrementTravId( p->pNode->pNtk );
00286 Abc_NtkIncrementTravId( p->pNode->pNtk );
00287 Vec_PtrForEachEntry( p->vLeaves, pObj, i )
00288 Abc_NodeSetTravIdCurrent( pObj );
00289
00290
00291
00292 Vec_PtrForEachEntry( p->vRoots, pObj, i )
00293 Res_WinMarkPaths_rec( pObj, p->pNode, p->nLevTravMin );
00294 }
00295
00296
00297
00298
00310 void Res_WinFinalizeRoots_rec( Abc_Obj_t * pObj, Vec_Ptr_t * vRoots )
00311 {
00312 Abc_Obj_t * pFanout;
00313 int i;
00314 assert( Abc_ObjIsNode(pObj) );
00315 assert( Abc_NodeIsTravIdCurrent(pObj) );
00316
00317 Abc_ObjForEachFanout( pObj, pFanout, i )
00318 if ( !Abc_NodeIsTravIdCurrent(pFanout) )
00319 break;
00320
00321 if ( i < Abc_ObjFanoutNum(pObj) )
00322 Vec_PtrPushUnique( vRoots, pObj );
00323 else
00324 Abc_ObjForEachFanout( pObj, pFanout, i )
00325 Res_WinFinalizeRoots_rec( pFanout, vRoots );
00326 }
00327
00340 int Res_WinFinalizeRoots( Res_Win_t * p )
00341 {
00342 assert( !Abc_NodeIsTravIdCurrent(p->pNode) );
00343
00344 Abc_NodeSetTravIdCurrent( p->pNode );
00345
00346 Vec_PtrClear( p->vRoots );
00347 Res_WinFinalizeRoots_rec( p->pNode, p->vRoots );
00348 assert( Vec_PtrSize(p->vRoots) > 0 );
00349 if ( Vec_PtrSize(p->vRoots) == 1 && Vec_PtrEntry(p->vRoots, 0) == p->pNode )
00350 return 0;
00351 return 1;
00352 }
00353
00354
00366 void Res_WinAddMissing_rec( Res_Win_t * p, Abc_Obj_t * pObj, int nLevTravMin )
00367 {
00368 Abc_Obj_t * pFanin;
00369 int i;
00370
00371 if ( Abc_NodeIsTravIdCurrent(pObj) )
00372 return;
00373
00374 if ( !Abc_NodeIsTravIdPrevious(pObj) )
00375 {
00376 assert( Vec_PtrFind(p->vLeaves, pObj) == -1 );
00377 Abc_NodeSetTravIdCurrent( pObj );
00378 Vec_PtrPush( p->vBranches, pObj );
00379 return;
00380 }
00381 assert( Abc_ObjIsNode(pObj) );
00382 Abc_NodeSetTravIdCurrent( pObj );
00383
00384 Abc_ObjForEachFanin( pObj, pFanin, i )
00385 Res_WinAddMissing_rec( p, pFanin, nLevTravMin );
00386
00387 Vec_PtrPush( p->vNodes, pObj );
00388 }
00389
00401 void Res_WinAddMissing( Res_Win_t * p )
00402 {
00403 Abc_Obj_t * pObj;
00404 int i;
00405
00406 Abc_NtkIncrementTravId( p->pNode->pNtk );
00407 Vec_PtrForEachEntry( p->vLeaves, pObj, i )
00408 Abc_NodeSetTravIdCurrent( pObj );
00409
00410 Vec_PtrForEachEntry( p->vNodes, pObj, i )
00411 Abc_NodeSetTravIdCurrent( pObj );
00412
00413 Vec_PtrClear( p->vBranches );
00414 Vec_PtrForEachEntry( p->vRoots, pObj, i )
00415 Res_WinAddMissing_rec( p, pObj, p->nLevTravMin );
00416 }
00417
00418
00419
00420
00432 int Res_WinIsTrivial( Res_Win_t * p )
00433 {
00434 return Vec_PtrSize(p->vRoots) == 1 && Vec_PtrEntry(p->vRoots, 0) == p->pNode;
00435 }
00436
00448 int Res_WinCompute( Abc_Obj_t * pNode, int nWinTfiMax, int nWinTfoMax, Res_Win_t * p )
00449 {
00450 assert( Abc_ObjIsNode(pNode) );
00451 assert( nWinTfiMax > 0 && nWinTfiMax < 10 );
00452 assert( nWinTfoMax >= 0 && nWinTfoMax < 10 );
00453
00454
00455 p->pNode = pNode;
00456 p->nWinTfiMax = nWinTfiMax;
00457 p->nWinTfoMax = nWinTfoMax;
00458
00459 Vec_PtrClear( p->vBranches );
00460 Vec_PtrClear( p->vDivs );
00461 Vec_PtrClear( p->vRoots );
00462 Vec_PtrPush( p->vRoots, pNode );
00463
00464
00465 if ( !Res_WinCollectLeavesAndNodes( p ) )
00466 return 0;
00467
00468
00469 if ( p->nWinTfoMax > 0 && Res_WinComputeRoots(p) )
00470 {
00471
00472 Res_WinMarkPaths( p );
00473
00474 if ( Res_WinFinalizeRoots( p ) )
00475 Res_WinAddMissing( p );
00476 }
00477
00478 return 1;
00479 }
00480
00484
00485