00001
00021 #include "cswInt.h"
00022
00026
00030
00042 static inline int Csw_CutFindCost( Csw_Man_t * p, Csw_Cut_t * pCut )
00043 {
00044 Aig_Obj_t * pLeaf;
00045 int i, Cost = 0;
00046 assert( pCut->nFanins > 0 );
00047 Csw_CutForEachLeaf( p->pManRes, pCut, pLeaf, i )
00048 {
00049
00050 Cost += Csw_ObjRefs( p, pLeaf );
00051
00052 }
00053
00054 return Cost * 100 / pCut->nFanins;
00055 }
00056
00068 static inline float Csw_CutFindCost2( Csw_Man_t * p, Csw_Cut_t * pCut )
00069 {
00070 Aig_Obj_t * pLeaf;
00071 float Cost = 0.0;
00072 int i;
00073 assert( pCut->nFanins > 0 );
00074 Csw_CutForEachLeaf( p->pManRes, pCut, pLeaf, i )
00075 Cost += (float)1.0/pLeaf->nRefs;
00076 return 1/Cost;
00077 }
00078
00090 static inline Csw_Cut_t * Csw_CutFindFree( Csw_Man_t * p, Aig_Obj_t * pObj )
00091 {
00092 Csw_Cut_t * pCut, * pCutMax;
00093 int i;
00094 pCutMax = NULL;
00095 Csw_ObjForEachCut( p, pObj, pCut, i )
00096 {
00097 if ( pCut->nFanins == 0 )
00098 return pCut;
00099 if ( pCutMax == NULL || pCutMax->Cost < pCut->Cost )
00100 pCutMax = pCut;
00101 }
00102 assert( pCutMax != NULL );
00103 pCutMax->nFanins = 0;
00104 return pCutMax;
00105 }
00106
00118 static inline unsigned Cut_TruthPhase( Csw_Cut_t * pCut, Csw_Cut_t * pCut1 )
00119 {
00120 unsigned uPhase = 0;
00121 int i, k;
00122 for ( i = k = 0; i < pCut->nFanins; i++ )
00123 {
00124 if ( k == pCut1->nFanins )
00125 break;
00126 if ( pCut->pFanins[i] < pCut1->pFanins[k] )
00127 continue;
00128 assert( pCut->pFanins[i] == pCut1->pFanins[k] );
00129 uPhase |= (1 << i);
00130 k++;
00131 }
00132 return uPhase;
00133 }
00134
00146 unsigned * Csw_CutComputeTruth( Csw_Man_t * p, Csw_Cut_t * pCut, Csw_Cut_t * pCut0, Csw_Cut_t * pCut1, int fCompl0, int fCompl1 )
00147 {
00148
00149 if ( fCompl0 )
00150 Kit_TruthNot( p->puTemp[0], Csw_CutTruth(pCut0), p->nLeafMax );
00151 else
00152 Kit_TruthCopy( p->puTemp[0], Csw_CutTruth(pCut0), p->nLeafMax );
00153 Kit_TruthStretch( p->puTemp[2], p->puTemp[0], pCut0->nFanins, p->nLeafMax, Cut_TruthPhase(pCut, pCut0), 0 );
00154
00155 if ( fCompl1 )
00156 Kit_TruthNot( p->puTemp[1], Csw_CutTruth(pCut1), p->nLeafMax );
00157 else
00158 Kit_TruthCopy( p->puTemp[1], Csw_CutTruth(pCut1), p->nLeafMax );
00159 Kit_TruthStretch( p->puTemp[3], p->puTemp[1], pCut1->nFanins, p->nLeafMax, Cut_TruthPhase(pCut, pCut1), 0 );
00160
00161 Kit_TruthAnd( Csw_CutTruth(pCut), p->puTemp[2], p->puTemp[3], p->nLeafMax );
00162
00163 return Csw_CutTruth(pCut);
00164 }
00165
00177 int Csw_CutSupportMinimize( Csw_Man_t * p, Csw_Cut_t * pCut )
00178 {
00179 unsigned * pTruth;
00180 int uSupp, nFansNew, i, k;
00181
00182 pTruth = Csw_CutTruth( pCut );
00183
00184 uSupp = Kit_TruthSupport( pTruth, p->nLeafMax );
00185
00186 nFansNew = Kit_WordCountOnes( uSupp );
00187
00188 if ( nFansNew == pCut->nFanins )
00189 return nFansNew;
00190 assert( nFansNew < pCut->nFanins );
00191
00192 Kit_TruthShrink( p->puTemp[0], pTruth, nFansNew, p->nLeafMax, uSupp, 1 );
00193 for ( i = k = 0; i < pCut->nFanins; i++ )
00194 if ( uSupp & (1 << i) )
00195 pCut->pFanins[k++] = pCut->pFanins[i];
00196 assert( k == nFansNew );
00197 pCut->nFanins = nFansNew;
00198
00199
00200 return nFansNew;
00201 }
00202
00214 static inline int Csw_CutCheckDominance( Csw_Cut_t * pDom, Csw_Cut_t * pCut )
00215 {
00216 int i, k;
00217 for ( i = 0; i < (int)pDom->nFanins; i++ )
00218 {
00219 for ( k = 0; k < (int)pCut->nFanins; k++ )
00220 if ( pDom->pFanins[i] == pCut->pFanins[k] )
00221 break;
00222 if ( k == (int)pCut->nFanins )
00223 return 0;
00224 }
00225
00226 return 1;
00227 }
00228
00240 int Csw_CutFilter( Csw_Man_t * p, Aig_Obj_t * pObj, Csw_Cut_t * pCut )
00241 {
00242 Csw_Cut_t * pTemp;
00243 int i;
00244
00245 Csw_ObjForEachCut( p, pObj, pTemp, i )
00246 {
00247 if ( pTemp->nFanins < 2 )
00248 continue;
00249 if ( pTemp == pCut )
00250 continue;
00251 if ( pTemp->nFanins > pCut->nFanins )
00252 {
00253
00254 if ( (pTemp->uSign & pCut->uSign) != pCut->uSign )
00255 continue;
00256
00257 if ( Csw_CutCheckDominance( pCut, pTemp ) )
00258 {
00259
00260 pTemp->nFanins = 0;
00261 }
00262 }
00263 else
00264 {
00265
00266 if ( (pTemp->uSign & pCut->uSign) != pTemp->uSign )
00267 continue;
00268
00269 if ( Csw_CutCheckDominance( pTemp, pCut ) )
00270 {
00271
00272 pCut->nFanins = 0;
00273 return 1;
00274 }
00275 }
00276 }
00277 return 0;
00278 }
00279
00291 static inline int Csw_CutMergeOrdered( Csw_Man_t * p, Csw_Cut_t * pC0, Csw_Cut_t * pC1, Csw_Cut_t * pC )
00292 {
00293 int i, k, c;
00294 assert( pC0->nFanins >= pC1->nFanins );
00295
00296 if ( pC0->nFanins == p->nLeafMax && pC1->nFanins == p->nLeafMax )
00297 {
00298 for ( i = 0; i < pC0->nFanins; i++ )
00299 if ( pC0->pFanins[i] != pC1->pFanins[i] )
00300 return 0;
00301 for ( i = 0; i < pC0->nFanins; i++ )
00302 pC->pFanins[i] = pC0->pFanins[i];
00303 pC->nFanins = pC0->nFanins;
00304 return 1;
00305 }
00306
00307 if ( pC0->nFanins == p->nLeafMax )
00308 {
00309 for ( i = 0; i < pC1->nFanins; i++ )
00310 {
00311 for ( k = pC0->nFanins - 1; k >= 0; k-- )
00312 if ( pC0->pFanins[k] == pC1->pFanins[i] )
00313 break;
00314 if ( k == -1 )
00315 return 0;
00316 }
00317 for ( i = 0; i < pC0->nFanins; i++ )
00318 pC->pFanins[i] = pC0->pFanins[i];
00319 pC->nFanins = pC0->nFanins;
00320 return 1;
00321 }
00322
00323
00324 i = k = 0;
00325 for ( c = 0; c < p->nLeafMax; c++ )
00326 {
00327 if ( k == pC1->nFanins )
00328 {
00329 if ( i == pC0->nFanins )
00330 {
00331 pC->nFanins = c;
00332 return 1;
00333 }
00334 pC->pFanins[c] = pC0->pFanins[i++];
00335 continue;
00336 }
00337 if ( i == pC0->nFanins )
00338 {
00339 if ( k == pC1->nFanins )
00340 {
00341 pC->nFanins = c;
00342 return 1;
00343 }
00344 pC->pFanins[c] = pC1->pFanins[k++];
00345 continue;
00346 }
00347 if ( pC0->pFanins[i] < pC1->pFanins[k] )
00348 {
00349 pC->pFanins[c] = pC0->pFanins[i++];
00350 continue;
00351 }
00352 if ( pC0->pFanins[i] > pC1->pFanins[k] )
00353 {
00354 pC->pFanins[c] = pC1->pFanins[k++];
00355 continue;
00356 }
00357 pC->pFanins[c] = pC0->pFanins[i++];
00358 k++;
00359 }
00360 if ( i < pC0->nFanins || k < pC1->nFanins )
00361 return 0;
00362 pC->nFanins = c;
00363 return 1;
00364 }
00365
00377 int Csw_CutMerge( Csw_Man_t * p, Csw_Cut_t * pCut0, Csw_Cut_t * pCut1, Csw_Cut_t * pCut )
00378 {
00379 assert( p->nLeafMax > 0 );
00380
00381 if ( pCut0->nFanins < pCut1->nFanins )
00382 {
00383 if ( !Csw_CutMergeOrdered( p, pCut1, pCut0, pCut ) )
00384 return 0;
00385 }
00386 else
00387 {
00388 if ( !Csw_CutMergeOrdered( p, pCut0, pCut1, pCut ) )
00389 return 0;
00390 }
00391 pCut->uSign = pCut0->uSign | pCut1->uSign;
00392 return 1;
00393 }
00394
00406 Aig_Obj_t * Csw_ObjTwoVarCut( Csw_Man_t * p, Csw_Cut_t * pCut )
00407 {
00408 Aig_Obj_t * pRes, * pIn0, * pIn1;
00409 int nVars, uTruth, fCompl = 0;
00410 assert( pCut->nFanins > 2 );
00411
00412 nVars = Csw_CutSupportMinimize( p, pCut );
00413 assert( nVars == 2 );
00414
00415 pIn0 = Aig_ManObj( p->pManRes, pCut->pFanins[0] );
00416 pIn1 = Aig_ManObj( p->pManRes, pCut->pFanins[1] );
00417
00418 uTruth = 0xF & *Csw_CutTruth(pCut);
00419 if ( uTruth == 14 || uTruth == 13 || uTruth == 11 || uTruth == 7 )
00420 {
00421 uTruth = 0xF & ~uTruth;
00422 fCompl = 1;
00423 }
00424
00425 pRes = NULL;
00426 if ( uTruth == 1 )
00427 pRes = Aig_And( p->pManRes, Aig_Not(pIn0), Aig_Not(pIn1) );
00428 if ( uTruth == 2 )
00429 pRes = Aig_And( p->pManRes, pIn0 , Aig_Not(pIn1) );
00430 if ( uTruth == 4 )
00431 pRes = Aig_And( p->pManRes, Aig_Not(pIn0), pIn1 );
00432 if ( uTruth == 8 )
00433 pRes = Aig_And( p->pManRes, pIn0 , pIn1 );
00434 if ( pRes )
00435 pRes = Aig_NotCond( pRes, fCompl );
00436 return pRes;
00437 }
00438
00450 Csw_Cut_t * Csw_ObjPrepareCuts( Csw_Man_t * p, Aig_Obj_t * pObj, int fTriv )
00451 {
00452 Csw_Cut_t * pCutSet, * pCut;
00453 int i;
00454
00455 pCutSet = (Csw_Cut_t *)Aig_MmFixedEntryFetch( p->pMemCuts );
00456 Csw_ObjSetCuts( p, pObj, pCutSet );
00457 Csw_ObjForEachCut( p, pObj, pCut, i )
00458 {
00459 pCut->nFanins = 0;
00460 pCut->iNode = pObj->Id;
00461 pCut->nCutSize = p->nCutSize;
00462 pCut->nLeafMax = p->nLeafMax;
00463 }
00464
00465 if ( fTriv )
00466 {
00467 pCut = pCutSet;
00468 pCut->Cost = 0;
00469 pCut->iNode = pObj->Id;
00470 pCut->nFanins = 1;
00471 pCut->pFanins[0] = pObj->Id;
00472 pCut->uSign = Aig_ObjCutSign( pObj->Id );
00473 memset( Csw_CutTruth(pCut), 0xAA, sizeof(unsigned) * p->nTruthWords );
00474 }
00475 return pCutSet;
00476 }
00477
00489 Aig_Obj_t * Csw_ObjSweep( Csw_Man_t * p, Aig_Obj_t * pObj, int fTriv )
00490 {
00491 int fUseResub = 1;
00492 Csw_Cut_t * pCut0, * pCut1, * pCut, * pCutSet;
00493 Aig_Obj_t * pFanin0 = Aig_ObjFanin0(pObj);
00494 Aig_Obj_t * pFanin1 = Aig_ObjFanin1(pObj);
00495 Aig_Obj_t * pObjNew;
00496 unsigned * pTruth;
00497 int i, k, nVars, nFanins, iVar, clk;
00498
00499 assert( !Aig_IsComplement(pObj) );
00500 if ( !Aig_ObjIsNode(pObj) )
00501 return pObj;
00502 if ( Csw_ObjCuts(p, pObj) )
00503 return pObj;
00504
00505 assert( Csw_ObjCuts(p, pObj) == NULL );
00506 assert( Aig_ObjIsNode(pObj) );
00507
00508
00509 pCutSet = Csw_ObjPrepareCuts( p, pObj, fTriv );
00510
00511
00512 Csw_ObjForEachCut( p, pFanin0, pCut0, i )
00513 if ( pCut0->nFanins > 0 )
00514 Csw_ObjForEachCut( p, pFanin1, pCut1, k )
00515 if ( pCut1->nFanins > 0 )
00516 {
00517
00518 if ( Kit_WordCountOnes(pCut0->uSign | pCut1->uSign) > p->nLeafMax )
00519 continue;
00520
00521 pCut = Csw_CutFindFree( p, pObj );
00522 clk = clock();
00523
00524 if ( !Csw_CutMerge( p, pCut0, pCut1, pCut ) )
00525 {
00526 assert( pCut->nFanins == 0 );
00527 continue;
00528 }
00529
00530 if ( Csw_CutFilter( p, pObj, pCut ) )
00531 {
00532 assert( pCut->nFanins == 0 );
00533 continue;
00534 }
00535
00536 pTruth = Csw_CutComputeTruth( p, pCut, pCut0, pCut1, Aig_ObjFaninC0(pObj), Aig_ObjFaninC1(pObj) );
00537
00538 nFanins = pCut->nFanins;
00539
00540 nVars = Kit_TruthSupportSize( pTruth, p->nLeafMax );
00541 p->timeCuts += clock() - clk;
00542
00543
00544 if ( nVars == 0 )
00545 {
00546 p->nNodesTriv0++;
00547 return Aig_NotCond( Aig_ManConst1(p->pManRes), !(pTruth[0] & 1) );
00548 }
00549 if ( nVars == 1 )
00550 {
00551 p->nNodesTriv1++;
00552 iVar = Kit_WordFindFirstBit( Kit_TruthSupport(pTruth, p->nLeafMax) );
00553 assert( iVar < pCut->nFanins );
00554 return Aig_NotCond( Aig_ManObj(p->pManRes, pCut->pFanins[iVar]), (pTruth[0] & 1) );
00555 }
00556 if ( nVars == 2 && nFanins > 2 && fUseResub )
00557 {
00558 if ( pObjNew = Csw_ObjTwoVarCut( p, pCut ) )
00559 {
00560 p->nNodesTriv2++;
00561 return pObjNew;
00562 }
00563 }
00564
00565
00566 clk = clock();
00567 pObjNew = pCut->nFanins > 2 ? Csw_TableCutLookup( p, pCut ) : NULL;
00568 p->timeHash += clock() - clk;
00569 if ( pObjNew )
00570 {
00571 p->nNodesCuts++;
00572 return pObjNew;
00573 }
00574
00575
00576 pCut->Cost = Csw_CutFindCost( p, pCut );
00577 assert( pCut->nFanins > 0 );
00578 assert( pCut->Cost > 0 );
00579 }
00580 p->nNodesTried++;
00581
00582
00583 clk = clock();
00584 Csw_ObjForEachCut( p, pObj, pCut, i )
00585 {
00586 if ( pCut->nFanins > 2 )
00587 {
00588 assert( pCut->Cost > 0 );
00589 Csw_TableCutInsert( p, pCut );
00590 }
00591 }
00592 p->timeHash += clock() - clk;
00593
00594
00595 return pObj;
00596 }
00597
00601
00602