00001
00021 #include "hop.h"
00022
00026
00027 static Hop_Obj_t * Hop_NodeBalance_rec( Hop_Man_t * pNew, Hop_Obj_t * pObj, Vec_Vec_t * vStore, int Level, int fUpdateLevel );
00028 static Vec_Ptr_t * Hop_NodeBalanceCone( Hop_Obj_t * pObj, Vec_Vec_t * vStore, int Level );
00029 static int Hop_NodeBalanceFindLeft( Vec_Ptr_t * vSuper );
00030 static void Hop_NodeBalancePermute( Hop_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor );
00031 static void Hop_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Hop_Obj_t * pObj );
00032
00036
00048 Hop_Man_t * Hop_ManBalance( Hop_Man_t * p, int fUpdateLevel )
00049 {
00050 Hop_Man_t * pNew;
00051 Hop_Obj_t * pObj, * pObjNew;
00052 Vec_Vec_t * vStore;
00053 int i;
00054
00055 pNew = Hop_ManStart();
00056 pNew->fRefCount = 0;
00057
00058 Hop_ManCleanData( p );
00059 Hop_ManConst1(p)->pData = Hop_ManConst1(pNew);
00060 Hop_ManForEachPi( p, pObj, i )
00061 pObj->pData = Hop_ObjCreatePi(pNew);
00062
00063 vStore = Vec_VecAlloc( 50 );
00064 Hop_ManForEachPo( p, pObj, i )
00065 {
00066 pObjNew = Hop_NodeBalance_rec( pNew, Hop_ObjFanin0(pObj), vStore, 0, fUpdateLevel );
00067 Hop_ObjCreatePo( pNew, Hop_NotCond( pObjNew, Hop_ObjFaninC0(pObj) ) );
00068 }
00069 Vec_VecFree( vStore );
00070
00071
00072
00073
00074
00075 if ( !Hop_ManCheck(pNew) )
00076 printf( "Hop_ManBalance(): The check has failed.\n" );
00077 return pNew;
00078 }
00079
00091 Hop_Obj_t * Hop_NodeBalance_rec( Hop_Man_t * pNew, Hop_Obj_t * pObjOld, Vec_Vec_t * vStore, int Level, int fUpdateLevel )
00092 {
00093 Hop_Obj_t * pObjNew;
00094 Vec_Ptr_t * vSuper;
00095 int i;
00096 assert( !Hop_IsComplement(pObjOld) );
00097
00098 if ( pObjOld->pData )
00099 return pObjOld->pData;
00100 assert( Hop_ObjIsNode(pObjOld) );
00101
00102 vSuper = Hop_NodeBalanceCone( pObjOld, vStore, Level );
00103
00104 if ( vSuper->nSize == 0 )
00105 return pObjOld->pData = Hop_ManConst0(pNew);
00106 if ( Vec_PtrSize(vSuper) < 2 )
00107 printf( "BUG!\n" );
00108
00109 for ( i = 0; i < Vec_PtrSize(vSuper); i++ )
00110 {
00111 pObjNew = Hop_NodeBalance_rec( pNew, Hop_Regular(vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel );
00112 vSuper->pArray[i] = Hop_NotCond( pObjNew, Hop_IsComplement(vSuper->pArray[i]) );
00113 }
00114
00115 pObjNew = Hop_NodeBalanceBuildSuper( pNew, vSuper, Hop_ObjType(pObjOld), fUpdateLevel );
00116
00117
00118 assert( pObjOld->pData == NULL );
00119 return pObjOld->pData = pObjNew;
00120 }
00121
00133 int Hop_NodeBalanceCone_rec( Hop_Obj_t * pRoot, Hop_Obj_t * pObj, Vec_Ptr_t * vSuper )
00134 {
00135 int RetValue1, RetValue2, i;
00136
00137 if ( Hop_Regular(pObj)->fMarkB )
00138 {
00139
00140 for ( i = 0; i < vSuper->nSize; i++ )
00141 if ( vSuper->pArray[i] == pObj )
00142 return 1;
00143
00144 for ( i = 0; i < vSuper->nSize; i++ )
00145 if ( vSuper->pArray[i] == Hop_Not(pObj) )
00146 return -1;
00147 assert( 0 );
00148 return 0;
00149 }
00150
00151 if ( pObj != pRoot && (Hop_IsComplement(pObj) || Hop_ObjType(pObj) != Hop_ObjType(pRoot) || Hop_ObjRefs(pObj) > 1) )
00152 {
00153 Vec_PtrPush( vSuper, pObj );
00154 Hop_Regular(pObj)->fMarkB = 1;
00155 return 0;
00156 }
00157 assert( !Hop_IsComplement(pObj) );
00158 assert( Hop_ObjIsNode(pObj) );
00159
00160 RetValue1 = Hop_NodeBalanceCone_rec( pRoot, Hop_ObjChild0(pObj), vSuper );
00161 RetValue2 = Hop_NodeBalanceCone_rec( pRoot, Hop_ObjChild1(pObj), vSuper );
00162 if ( RetValue1 == -1 || RetValue2 == -1 )
00163 return -1;
00164
00165 return RetValue1 || RetValue2;
00166 }
00167
00179 Vec_Ptr_t * Hop_NodeBalanceCone( Hop_Obj_t * pObj, Vec_Vec_t * vStore, int Level )
00180 {
00181 Vec_Ptr_t * vNodes;
00182 int RetValue, i;
00183 assert( !Hop_IsComplement(pObj) );
00184
00185 if ( Vec_VecSize( vStore ) <= Level )
00186 Vec_VecPush( vStore, Level, 0 );
00187
00188 vNodes = Vec_VecEntry( vStore, Level );
00189 Vec_PtrClear( vNodes );
00190
00191 RetValue = Hop_NodeBalanceCone_rec( pObj, pObj, vNodes );
00192 assert( vNodes->nSize > 1 );
00193
00194 Vec_PtrForEachEntry( vNodes, pObj, i )
00195 Hop_Regular(pObj)->fMarkB = 0;
00196
00197
00198 if ( RetValue == -1 )
00199 vNodes->nSize = 0;
00200 return vNodes;
00201 }
00202
00214 int Hop_NodeCompareLevelsDecrease( Hop_Obj_t ** pp1, Hop_Obj_t ** pp2 )
00215 {
00216 int Diff = Hop_ObjLevel(Hop_Regular(*pp1)) - Hop_ObjLevel(Hop_Regular(*pp2));
00217 if ( Diff > 0 )
00218 return -1;
00219 if ( Diff < 0 )
00220 return 1;
00221 return 0;
00222 }
00223
00235 Hop_Obj_t * Hop_NodeBalanceBuildSuper( Hop_Man_t * p, Vec_Ptr_t * vSuper, Hop_Type_t Type, int fUpdateLevel )
00236 {
00237 Hop_Obj_t * pObj1, * pObj2;
00238 int LeftBound;
00239 assert( vSuper->nSize > 1 );
00240
00241 Vec_PtrSort( vSuper, Hop_NodeCompareLevelsDecrease );
00242
00243 while ( vSuper->nSize > 1 )
00244 {
00245
00246 LeftBound = (!fUpdateLevel)? 0 : Hop_NodeBalanceFindLeft( vSuper );
00247
00248 Hop_NodeBalancePermute( p, vSuper, LeftBound, Type == AIG_EXOR );
00249
00250 pObj1 = Vec_PtrPop(vSuper);
00251 pObj2 = Vec_PtrPop(vSuper);
00252 Hop_NodeBalancePushUniqueOrderByLevel( vSuper, Hop_Oper(p, pObj1, pObj2, Type) );
00253 }
00254 return Vec_PtrEntry(vSuper, 0);
00255 }
00256
00272 int Hop_NodeBalanceFindLeft( Vec_Ptr_t * vSuper )
00273 {
00274 Hop_Obj_t * pObjRight, * pObjLeft;
00275 int Current;
00276
00277 if ( Vec_PtrSize(vSuper) < 3 )
00278 return 0;
00279
00280 Current = Vec_PtrSize(vSuper) - 2;
00281 pObjRight = Vec_PtrEntry( vSuper, Current );
00282
00283 for ( Current--; Current >= 0; Current-- )
00284 {
00285
00286 pObjLeft = Vec_PtrEntry( vSuper, Current );
00287
00288 if ( Hop_ObjLevel(Hop_Regular(pObjLeft)) != Hop_ObjLevel(Hop_Regular(pObjRight)) )
00289 break;
00290 }
00291 Current++;
00292
00293 pObjLeft = Vec_PtrEntry( vSuper, Current );
00294 assert( Hop_ObjLevel(Hop_Regular(pObjLeft)) == Hop_ObjLevel(Hop_Regular(pObjRight)) );
00295 return Current;
00296 }
00297
00310 void Hop_NodeBalancePermute( Hop_Man_t * p, Vec_Ptr_t * vSuper, int LeftBound, int fExor )
00311 {
00312 Hop_Obj_t * pObj1, * pObj2, * pObj3, * pGhost;
00313 int RightBound, i;
00314
00315 RightBound = Vec_PtrSize(vSuper) - 2;
00316 assert( LeftBound <= RightBound );
00317 if ( LeftBound == RightBound )
00318 return;
00319
00320 pObj1 = Vec_PtrEntry( vSuper, RightBound + 1 );
00321 pObj2 = Vec_PtrEntry( vSuper, RightBound );
00322 if ( Hop_Regular(pObj1) == p->pConst1 || Hop_Regular(pObj2) == p->pConst1 )
00323 return;
00324
00325 for ( i = RightBound; i >= LeftBound; i-- )
00326 {
00327 pObj3 = Vec_PtrEntry( vSuper, i );
00328 if ( Hop_Regular(pObj3) == p->pConst1 )
00329 {
00330 Vec_PtrWriteEntry( vSuper, i, pObj2 );
00331 Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
00332 return;
00333 }
00334 pGhost = Hop_ObjCreateGhost( p, pObj1, pObj3, fExor? AIG_EXOR : AIG_AND );
00335 if ( Hop_TableLookup( p, pGhost ) )
00336 {
00337 if ( pObj3 == pObj2 )
00338 return;
00339 Vec_PtrWriteEntry( vSuper, i, pObj2 );
00340 Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );
00341 return;
00342 }
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 }
00356
00368 void Hop_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Hop_Obj_t * pObj )
00369 {
00370 Hop_Obj_t * pObj1, * pObj2;
00371 int i;
00372 if ( Vec_PtrPushUnique(vStore, pObj) )
00373 return;
00374
00375 for ( i = vStore->nSize-1; i > 0; i-- )
00376 {
00377 pObj1 = vStore->pArray[i ];
00378 pObj2 = vStore->pArray[i-1];
00379 if ( Hop_ObjLevel(Hop_Regular(pObj1)) <= Hop_ObjLevel(Hop_Regular(pObj2)) )
00380 break;
00381 vStore->pArray[i ] = pObj2;
00382 vStore->pArray[i-1] = pObj1;
00383 }
00384 }
00385
00386
00390
00391