00001
00021 #include "ivy.h"
00022
00026
00027 static int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone );
00028 static Ivy_Obj_t * Ivy_NodeRewriteAlg( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Vec_Ptr_t * vSols, int LevelR, int fUseZeroCost );
00029 static int Ivy_NodeCountMffc( Ivy_Obj_t * pNode );
00030
00034
00046 int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost )
00047 {
00048 Vec_Int_t * vRequired;
00049 Vec_Ptr_t * vFront, * vLeaves, * vCone, * vSol;
00050 Ivy_Obj_t * pObj, * pResult;
00051 int i, RetValue, LevelR, nNodesOld;
00052 int CountUsed, CountUndo;
00053 vRequired = fUpdateLevel? Ivy_ManRequiredLevels( p ) : NULL;
00054 vFront = Vec_PtrAlloc( 100 );
00055 vLeaves = Vec_PtrAlloc( 100 );
00056 vCone = Vec_PtrAlloc( 100 );
00057 vSol = Vec_PtrAlloc( 100 );
00058
00059 CountUsed = CountUndo = 0;
00060 nNodesOld = Ivy_ManObjIdNext(p);
00061 Ivy_ManForEachObj( p, pObj, i )
00062 {
00063 assert( !Ivy_ObjIsBuf(pObj) );
00064 if ( i >= nNodesOld )
00065 break;
00066
00067 if ( !Ivy_ObjIsNode(pObj) || Ivy_ObjIsExor(pObj) || Ivy_ObjIsMuxType(pObj) )
00068 continue;
00069
00070
00071 if ( pObj->Id == 297 )
00072 {
00073 int x = 0;
00074 }
00075
00076 RetValue = Ivy_ManFindAlgCut( pObj, vFront, vLeaves, vCone );
00077
00078 if ( RetValue == 1 )
00079 continue;
00080
00081 if ( RetValue == -1 )
00082 {
00083 Ivy_ObjReplace( pObj, Ivy_ManConst0(p), 1, 0, 1 );
00084 continue;
00085 }
00086 assert( Vec_PtrSize(vLeaves) > 2 );
00087
00088 LevelR = vRequired? Vec_IntEntry(vRequired, pObj->Id) : 1000000;
00089
00090 pResult = Ivy_NodeRewriteAlg( pObj, vFront, vLeaves, vCone, vSol, LevelR, fUseZeroCost );
00091 if ( pResult == NULL || pResult == pObj )
00092 continue;
00093 assert( Vec_PtrSize(vSol) == 1 || !Ivy_IsComplement(pResult) );
00094 if ( Ivy_ObjLevel(Ivy_Regular(pResult)) > LevelR && Ivy_ObjRefs(Ivy_Regular(pResult)) == 0 )
00095 Ivy_ObjDelete_rec(Ivy_Regular(pResult), 1), CountUndo++;
00096 else
00097 Ivy_ObjReplace( pObj, pResult, 1, 0, 1 ), CountUsed++;
00098 }
00099 printf( "Used = %d. Undo = %d.\n", CountUsed, CountUndo );
00100 Vec_PtrFree( vFront );
00101 Vec_PtrFree( vCone );
00102 Vec_PtrFree( vSol );
00103 if ( vRequired ) Vec_IntFree( vRequired );
00104 if ( i = Ivy_ManCleanup(p) )
00105 printf( "Cleanup after rewriting removed %d dangling nodes.\n", i );
00106 if ( !Ivy_ManCheck(p) )
00107 printf( "Ivy_ManRewriteAlg(): The check has failed.\n" );
00108 return 1;
00109 }
00110
00122 Ivy_Obj_t * Ivy_NodeRewriteAlg( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Vec_Ptr_t * vSols, int LevelR, int fUseZeroCost )
00123 {
00124 int fVerbose = 0;
00125 Ivy_Obj_t * pTemp;
00126 int k, Counter, nMffc, RetValue;
00127
00128 if ( fVerbose )
00129 {
00130 if ( Ivy_ObjIsExor(pObj) )
00131 printf( "x " );
00132 else
00133 printf( " " );
00134 }
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 if ( Ivy_ObjIsExor(pObj) )
00145 Ivy_ManCollectCone( pObj, vFront, vCone );
00146 else
00147 Ivy_ManCollectCone( pObj, vLeaves, vCone );
00148
00149
00150 Vec_PtrForEachEntry( vCone, pTemp, k )
00151 {
00152 Ivy_ObjRefsDec( Ivy_ObjFanin0(pTemp) );
00153 Ivy_ObjRefsDec( Ivy_ObjFanin1(pTemp) );
00154 pTemp->fMarkB = 1;
00155 }
00156
00157
00158 Vec_PtrForEachEntry( vFront, pTemp, k )
00159 Ivy_Regular(pTemp)->fMarkA = 1;
00160 nMffc = Ivy_NodeCountMffc( pObj );
00161 Vec_PtrForEachEntry( vFront, pTemp, k )
00162 Ivy_Regular(pTemp)->fMarkA = 0;
00163
00164 if ( fVerbose )
00165 {
00166 Counter = 0;
00167 Vec_PtrForEachEntry( vCone, pTemp, k )
00168 Counter += (Ivy_ObjRefs(pTemp) > 0);
00169 printf( "%5d : Leaves = %2d. Cone = %2d. ConeRef = %2d. Mffc = %d. Lev = %d. LevR = %d.\n",
00170 pObj->Id, Vec_PtrSize(vFront), Vec_PtrSize(vCone), Counter-1, nMffc, Ivy_ObjLevel(pObj), LevelR );
00171 }
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 RetValue = Ivy_MultiPlus( vLeaves, vCone, Ivy_ObjType(pObj), nMffc + fUseZeroCost, vSols );
00185
00186
00187 Vec_PtrForEachEntry( vCone, pTemp, k )
00188 {
00189 Ivy_ObjRefsInc( Ivy_ObjFanin0(pTemp) );
00190 Ivy_ObjRefsInc( Ivy_ObjFanin1(pTemp) );
00191 pTemp->fMarkA = 0;
00192 pTemp->fMarkB = 0;
00193 }
00194
00195 if ( !RetValue )
00196 return NULL;
00197
00198 if ( Vec_PtrSize( vSols ) == 1 )
00199 return Vec_PtrEntry( vSols, 0 );
00200 return Ivy_NodeBalanceBuildSuper( vSols, Ivy_ObjType(pObj), 1 );
00201 }
00202
00214 int Ivy_NodeCountMffc_rec( Ivy_Obj_t * pNode )
00215 {
00216 if ( Ivy_ObjRefs(pNode) > 0 || Ivy_ObjIsCi(pNode) || pNode->fMarkA )
00217 return 0;
00218 assert( pNode->fMarkB );
00219 pNode->fMarkA = 1;
00220
00221 if ( Ivy_ObjIsBuf(pNode) )
00222 return Ivy_NodeCountMffc_rec( Ivy_ObjFanin0(pNode) );
00223 return 1 + Ivy_NodeCountMffc_rec( Ivy_ObjFanin0(pNode) ) + Ivy_NodeCountMffc_rec( Ivy_ObjFanin1(pNode) );
00224 }
00225
00237 int Ivy_NodeCountMffc( Ivy_Obj_t * pNode )
00238 {
00239 assert( pNode->fMarkB );
00240 return 1 + Ivy_NodeCountMffc_rec( Ivy_ObjFanin0(pNode) ) + Ivy_NodeCountMffc_rec( Ivy_ObjFanin1(pNode) );
00241 }
00242
00254 int Ivy_ManFindAlgCutCompare( Ivy_Obj_t ** pp1, Ivy_Obj_t ** pp2 )
00255 {
00256 if ( *pp1 < *pp2 )
00257 return -1;
00258 if ( *pp1 > *pp2 )
00259 return 1;
00260 return 0;
00261 }
00262
00276 int Ivy_ManFindAlgCut_rec( Ivy_Obj_t * pObj, Ivy_Type_t Type, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone )
00277 {
00278 int RetValue0, RetValue1;
00279 Ivy_Obj_t * pObjR = Ivy_Regular(pObj);
00280 assert( !Ivy_ObjIsBuf(pObjR) );
00281 assert( Type != IVY_EXOR || !Ivy_IsComplement(pObj) );
00282
00283
00284 if ( Ivy_IsComplement(pObj) )
00285 {
00286 if ( pObjR->fMarkA )
00287 return -1;
00288 pObjR->fMarkB = 1;
00289 }
00290 else
00291 {
00292 if ( pObjR->fMarkB )
00293 return -1;
00294 pObjR->fMarkA = 1;
00295 }
00296 Vec_PtrPush( vCone, pObjR );
00297
00298
00299 if ( Ivy_IsComplement(pObj) || Ivy_ObjType(pObj) != Type )
00300 {
00301 if ( Ivy_ObjRefs(pObjR) == 1 )
00302 return 1;
00303 assert( Ivy_ObjRefs(pObjR) > 1 );
00304 Vec_PtrPush( vFront, pObj );
00305 return 0;
00306 }
00307
00308
00309 assert( !Ivy_IsComplement(pObj) );
00310 assert( Ivy_ObjIsNode(pObj) );
00311
00312 RetValue0 = Ivy_ManFindAlgCut_rec( Ivy_ObjReal( Ivy_ObjChild0(pObj) ), Type, vFront, vCone );
00313 RetValue1 = Ivy_ManFindAlgCut_rec( Ivy_ObjReal( Ivy_ObjChild1(pObj) ), Type, vFront, vCone );
00314 if ( RetValue0 == -1 || RetValue1 == -1 )
00315 return -1;
00316
00317
00318 if ( RetValue0 && RetValue1 )
00319 {
00320 if ( Ivy_ObjRefs(pObj) == 1 )
00321 return 1;
00322 assert( Ivy_ObjRefs(pObj) > 1 );
00323 Vec_PtrPush( vFront, pObj );
00324 return 0;
00325 }
00326
00327 if ( RetValue0 )
00328 Vec_PtrPush( vFront, Ivy_ObjReal( Ivy_ObjChild0(pObj) ) );
00329 if ( RetValue1 )
00330 Vec_PtrPush( vFront, Ivy_ObjReal( Ivy_ObjChild1(pObj) ) );
00331 return 0;
00332 }
00333
00347 int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone )
00348 {
00349 Ivy_Obj_t * pObj, * pPrev;
00350 int RetValue, i;
00351 assert( !Ivy_IsComplement(pRoot) );
00352 assert( Ivy_ObjIsNode(pRoot) );
00353
00354 Vec_PtrClear( vCone );
00355 Vec_PtrClear( vFront );
00356 Vec_PtrClear( vLeaves );
00357 RetValue = Ivy_ManFindAlgCut_rec( pRoot, Ivy_ObjType(pRoot), vFront, vCone );
00358
00359 Vec_PtrForEachEntry( vCone, pObj, i )
00360 pObj->fMarkA = pObj->fMarkB = 0;
00361
00362 if ( RetValue == -1 )
00363 return -1;
00364
00365 if ( RetValue == 1 )
00366 return 1;
00367
00368 if ( Vec_PtrSize(vFront) <= 2 )
00369 return 1;
00370
00371 Vec_PtrSort( vFront, Ivy_ManFindAlgCutCompare );
00372
00373 pPrev = Vec_PtrEntry(vFront, 0);
00374 Vec_PtrPush( vLeaves, pPrev );
00375 Vec_PtrForEachEntryStart( vFront, pObj, i, 1 )
00376 {
00377
00378 if ( pObj == pPrev )
00379 {
00380 if ( Ivy_ObjIsExor(pRoot) )
00381 {
00382
00383 Vec_PtrPop(vLeaves);
00384 pPrev = Vec_PtrSize(vLeaves) == 0 ? NULL : Vec_PtrEntryLast(vLeaves);
00385 }
00386 continue;
00387 }
00388 if ( pObj == Ivy_Not(pPrev) )
00389 {
00390 assert( Ivy_ObjIsAnd(pRoot) );
00391 return -1;
00392 }
00393 pPrev = pObj;
00394 Vec_PtrPush( vLeaves, pObj );
00395 }
00396 if ( Vec_PtrSize(vLeaves) == 0 )
00397 return -1;
00398 if ( Vec_PtrSize(vLeaves) <= 2 )
00399 return 1;
00400 return 0;
00401 }
00402
00403
00407
00408