00001
00021 #include "if.h"
00022
00026
00030
00031
00043 static inline int If_CutCheckDominance( If_Cut_t * pDom, If_Cut_t * pCut )
00044 {
00045 int i, k;
00046 for ( i = 0; i < (int)pDom->nLeaves; i++ )
00047 {
00048 for ( k = 0; k < (int)pCut->nLeaves; k++ )
00049 if ( pDom->pLeaves[i] == pCut->pLeaves[k] )
00050 break;
00051 if ( k == (int)pCut->nLeaves )
00052 return 0;
00053 }
00054
00055 return 1;
00056 }
00057
00069 static inline int If_CutCheckEquality( If_Cut_t * pDom, If_Cut_t * pCut )
00070 {
00071 int i;
00072 if ( (int)pDom->nLeaves != (int)pCut->nLeaves )
00073 return 0;
00074 for ( i = 0; i < (int)pDom->nLeaves; i++ )
00075 if ( pDom->pLeaves[i] != pCut->pLeaves[i] )
00076 return 0;
00077 return 1;
00078 }
00079
00091 int If_CutFilter( If_Set_t * pCutSet, If_Cut_t * pCut )
00092 {
00093 If_Cut_t * pTemp;
00094 int i, k;
00095 assert( pCutSet->ppCuts[pCutSet->nCuts] == pCut );
00096 for ( i = 0; i < pCutSet->nCuts; i++ )
00097 {
00098 pTemp = pCutSet->ppCuts[i];
00099 if ( pTemp->nLeaves > pCut->nLeaves )
00100 {
00101
00102 if ( i == 0 )
00103 continue;
00104
00105 if ( (pTemp->uSign & pCut->uSign) != pCut->uSign )
00106 continue;
00107
00108 if ( If_CutCheckDominance( pCut, pTemp ) )
00109 {
00110
00111
00112
00113
00114
00115 for ( k = i; k < pCutSet->nCuts; k++ )
00116 pCutSet->ppCuts[k] = pCutSet->ppCuts[k+1];
00117 pCutSet->ppCuts[pCutSet->nCuts] = pTemp;
00118 pCutSet->nCuts--;
00119 i--;
00120 }
00121 }
00122 else
00123 {
00124
00125 if ( (pTemp->uSign & pCut->uSign) != pTemp->uSign )
00126 continue;
00127
00128 if ( If_CutCheckDominance( pTemp, pCut ) )
00129 return 1;
00130 }
00131 }
00132 return 0;
00133 }
00134
00146 static inline int If_CutMergeOrdered( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC )
00147 {
00148 int i, k, c;
00149 assert( pC0->nLeaves >= pC1->nLeaves );
00150
00151 if ( pC0->nLeaves == pC->nLimit && pC1->nLeaves == pC->nLimit )
00152 {
00153 for ( i = 0; i < (int)pC0->nLeaves; i++ )
00154 if ( pC0->pLeaves[i] != pC1->pLeaves[i] )
00155 return 0;
00156 for ( i = 0; i < (int)pC0->nLeaves; i++ )
00157 pC->pLeaves[i] = pC0->pLeaves[i];
00158 pC->nLeaves = pC0->nLeaves;
00159 return 1;
00160 }
00161
00162 if ( pC0->nLeaves == pC->nLimit )
00163 {
00164 for ( i = 0; i < (int)pC1->nLeaves; i++ )
00165 {
00166 for ( k = (int)pC0->nLeaves - 1; k >= 0; k-- )
00167 if ( pC0->pLeaves[k] == pC1->pLeaves[i] )
00168 break;
00169 if ( k == -1 )
00170 return 0;
00171 }
00172 for ( i = 0; i < (int)pC0->nLeaves; i++ )
00173 pC->pLeaves[i] = pC0->pLeaves[i];
00174 pC->nLeaves = pC0->nLeaves;
00175 return 1;
00176 }
00177
00178
00179 i = k = 0;
00180 for ( c = 0; c < (int)pC->nLimit; c++ )
00181 {
00182 if ( k == (int)pC1->nLeaves )
00183 {
00184 if ( i == (int)pC0->nLeaves )
00185 {
00186 pC->nLeaves = c;
00187 return 1;
00188 }
00189 pC->pLeaves[c] = pC0->pLeaves[i++];
00190 continue;
00191 }
00192 if ( i == (int)pC0->nLeaves )
00193 {
00194 if ( k == (int)pC1->nLeaves )
00195 {
00196 pC->nLeaves = c;
00197 return 1;
00198 }
00199 pC->pLeaves[c] = pC1->pLeaves[k++];
00200 continue;
00201 }
00202 if ( pC0->pLeaves[i] < pC1->pLeaves[k] )
00203 {
00204 pC->pLeaves[c] = pC0->pLeaves[i++];
00205 continue;
00206 }
00207 if ( pC0->pLeaves[i] > pC1->pLeaves[k] )
00208 {
00209 pC->pLeaves[c] = pC1->pLeaves[k++];
00210 continue;
00211 }
00212 pC->pLeaves[c] = pC0->pLeaves[i++];
00213 k++;
00214 }
00215 if ( i < (int)pC0->nLeaves || k < (int)pC1->nLeaves )
00216 return 0;
00217 pC->nLeaves = c;
00218 return 1;
00219 }
00220
00232 static inline int If_CutMergeOrdered2( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC )
00233 {
00234 int i, k, c;
00235 assert( pC0->nLeaves >= pC1->nLeaves );
00236
00237 for ( i = 0; i < (int)pC0->nLeaves; i++ )
00238 pC->pLeaves[i] = pC0->pLeaves[i];
00239 pC->nLeaves = pC0->nLeaves;
00240
00241 if ( pC0->nLeaves == pC->nLimit )
00242 return 1;
00243
00244 k = 0;
00245 for ( i = 0; i < (int)pC1->nLeaves; i++ )
00246 {
00247
00248 for ( ; k < (int)pC->nLeaves; k++ )
00249 if ( pC->pLeaves[k] >= pC1->pLeaves[i] )
00250 break;
00251
00252 if ( k == (int)pC->nLeaves )
00253 {
00254 pC->pLeaves[k++] = pC1->pLeaves[i];
00255 pC->nLeaves++;
00256 continue;
00257 }
00258
00259 if ( pC1->pLeaves[i] == pC->pLeaves[k] )
00260 continue;
00261
00262 for ( c = (int)pC->nLeaves; c > k; c-- )
00263 pC->pLeaves[c] = pC->pLeaves[c-1];
00264 pC->pLeaves[k++] = pC1->pLeaves[i];
00265 pC->nLeaves++;
00266 }
00267
00268
00269
00270
00271
00272 return 1;
00273 }
00274
00286 int If_CutMerge( If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * pCut )
00287 {
00288 assert( pCut->nLimit > 0 );
00289
00290 if ( pCut0->nLeaves < pCut1->nLeaves )
00291 {
00292 if ( !If_CutMergeOrdered( pCut1, pCut0, pCut ) )
00293 return 0;
00294 }
00295 else
00296 {
00297 if ( !If_CutMergeOrdered( pCut0, pCut1, pCut ) )
00298 return 0;
00299 }
00300 pCut->uSign = pCut0->uSign | pCut1->uSign;
00301 return 1;
00302 }
00303
00315 int If_CutCompareDelay( If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
00316 {
00317 If_Cut_t * pC0 = *ppC0;
00318 If_Cut_t * pC1 = *ppC1;
00319 if ( pC0->Delay < pC1->Delay - 0.0001 )
00320 return -1;
00321 if ( pC0->Delay > pC1->Delay + 0.0001 )
00322 return 1;
00323 if ( pC0->nLeaves < pC1->nLeaves )
00324 return -1;
00325 if ( pC0->nLeaves > pC1->nLeaves )
00326 return 1;
00327 if ( pC0->Area < pC1->Area - 0.0001 )
00328 return -1;
00329 if ( pC0->Area > pC1->Area + 0.0001 )
00330 return 1;
00331 return 0;
00332 }
00333
00345 int If_CutCompareDelayOld( If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
00346 {
00347 If_Cut_t * pC0 = *ppC0;
00348 If_Cut_t * pC1 = *ppC1;
00349 if ( pC0->Delay < pC1->Delay - 0.0001 )
00350 return -1;
00351 if ( pC0->Delay > pC1->Delay + 0.0001 )
00352 return 1;
00353 if ( pC0->Area < pC1->Area - 0.0001 )
00354 return -1;
00355 if ( pC0->Area > pC1->Area + 0.0001 )
00356 return 1;
00357 if ( pC0->nLeaves < pC1->nLeaves )
00358 return -1;
00359 if ( pC0->nLeaves > pC1->nLeaves )
00360 return 1;
00361 return 0;
00362 }
00363
00375 int If_CutCompareArea( If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
00376 {
00377 If_Cut_t * pC0 = *ppC0;
00378 If_Cut_t * pC1 = *ppC1;
00379 if ( pC0->Area < pC1->Area - 0.0001 )
00380 return -1;
00381 if ( pC0->Area > pC1->Area + 0.0001 )
00382 return 1;
00383 if ( pC0->AveRefs > pC1->AveRefs )
00384 return -1;
00385 if ( pC0->AveRefs < pC1->AveRefs )
00386 return 1;
00387 if ( pC0->nLeaves < pC1->nLeaves )
00388 return -1;
00389 if ( pC0->nLeaves > pC1->nLeaves )
00390 return 1;
00391 if ( pC0->Delay < pC1->Delay - 0.0001 )
00392 return -1;
00393 if ( pC0->Delay > pC1->Delay + 0.0001 )
00394 return 1;
00395 return 0;
00396 }
00397
00409 void If_ManSortCuts( If_Man_t * p, int Mode )
00410 {
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 }
00421
00433 static inline int If_ManSortCompare( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1 )
00434 {
00435 if ( p->SortMode == 1 )
00436 {
00437 if ( pC0->Area < pC1->Area - 0.0001 )
00438 return -1;
00439 if ( pC0->Area > pC1->Area + 0.0001 )
00440 return 1;
00441 if ( pC0->AveRefs > pC1->AveRefs )
00442 return -1;
00443 if ( pC0->AveRefs < pC1->AveRefs )
00444 return 1;
00445 if ( pC0->nLeaves < pC1->nLeaves )
00446 return -1;
00447 if ( pC0->nLeaves > pC1->nLeaves )
00448 return 1;
00449 if ( pC0->Delay < pC1->Delay - 0.0001 )
00450 return -1;
00451 if ( pC0->Delay > pC1->Delay + 0.0001 )
00452 return 1;
00453 return 0;
00454 }
00455 if ( p->SortMode == 0 )
00456 {
00457 if ( pC0->Delay < pC1->Delay - 0.0001 )
00458 return -1;
00459 if ( pC0->Delay > pC1->Delay + 0.0001 )
00460 return 1;
00461 if ( pC0->nLeaves < pC1->nLeaves )
00462 return -1;
00463 if ( pC0->nLeaves > pC1->nLeaves )
00464 return 1;
00465 if ( pC0->Area < pC1->Area - 0.0001 )
00466 return -1;
00467 if ( pC0->Area > pC1->Area + 0.0001 )
00468 return 1;
00469 return 0;
00470 }
00471 assert( p->SortMode == 2 );
00472 if ( pC0->Delay < pC1->Delay - 0.0001 )
00473 return -1;
00474 if ( pC0->Delay > pC1->Delay + 0.0001 )
00475 return 1;
00476 if ( pC0->Area < pC1->Area - 0.0001 )
00477 return -1;
00478 if ( pC0->Area > pC1->Area + 0.0001 )
00479 return 1;
00480 if ( pC0->nLeaves < pC1->nLeaves )
00481 return -1;
00482 if ( pC0->nLeaves > pC1->nLeaves )
00483 return 1;
00484 return 0;
00485 }
00486
00498 void If_CutSort( If_Man_t * p, If_Set_t * pCutSet, If_Cut_t * pCut )
00499 {
00500
00501 int i;
00502
00503
00504 assert( pCutSet->ppCuts[pCutSet->nCuts] == pCut );
00505 assert( pCutSet->nCuts <= pCutSet->nCutsMax );
00506
00507
00508 if ( pCutSet->nCuts == 0 )
00509 {
00510 pCutSet->nCuts++;
00511 return;
00512 }
00513
00514
00515 for ( i = pCutSet->nCuts-1; i >= 0; i-- )
00516 {
00517
00518 if ( If_ManSortCompare( p, pCutSet->ppCuts[i], pCut ) <= 0 )
00519 break;
00520 pCutSet->ppCuts[i+1] = pCutSet->ppCuts[i];
00521 pCutSet->ppCuts[i] = pCut;
00522 }
00523
00524
00525
00526 if ( pCutSet->nCuts < pCutSet->nCutsMax )
00527 pCutSet->nCuts++;
00528 }
00529
00541 float If_CutFlow( If_Man_t * p, If_Cut_t * pCut )
00542 {
00543 If_Obj_t * pLeaf;
00544 float Flow;
00545 int i;
00546 assert( p->pPars->fSeqMap || pCut->nLeaves > 1 );
00547 Flow = If_CutLutArea(p, pCut);
00548 If_CutForEachLeaf( p, pCut, pLeaf, i )
00549 {
00550 if ( pLeaf->nRefs == 0 )
00551 Flow += If_ObjCutBest(pLeaf)->Area;
00552 else if ( p->pPars->fSeqMap )
00553 Flow += If_ObjCutBest(pLeaf)->Area / pLeaf->nRefs;
00554 else
00555 {
00556 assert( pLeaf->EstRefs > p->fEpsilon );
00557 Flow += If_ObjCutBest(pLeaf)->Area / pLeaf->EstRefs;
00558 }
00559 }
00560 return Flow;
00561 }
00562
00574 float If_CutAverageRefs( If_Man_t * p, If_Cut_t * pCut )
00575 {
00576 If_Obj_t * pLeaf;
00577 int nRefsTotal, i;
00578 assert( p->pPars->fSeqMap || pCut->nLeaves > 1 );
00579 nRefsTotal = 0;
00580 If_CutForEachLeaf( p, pCut, pLeaf, i )
00581 nRefsTotal += pLeaf->nRefs;
00582 return ((float)nRefsTotal)/pCut->nLeaves;
00583 }
00584
00596 float If_CutDeref( If_Man_t * p, If_Cut_t * pCut, int nLevels )
00597 {
00598 If_Obj_t * pLeaf;
00599 float Area;
00600 int i;
00601 Area = If_CutLutArea(p, pCut);
00602 If_CutForEachLeaf( p, pCut, pLeaf, i )
00603 {
00604 assert( pLeaf->nRefs > 0 );
00605 if ( --pLeaf->nRefs > 0 || !If_ObjIsAnd(pLeaf) || nLevels == 1 )
00606 continue;
00607 Area += If_CutDeref( p, If_ObjCutBest(pLeaf), nLevels - 1 );
00608 }
00609 return Area;
00610 }
00611
00623 float If_CutRef( If_Man_t * p, If_Cut_t * pCut, int nLevels )
00624 {
00625 If_Obj_t * pLeaf;
00626 float Area;
00627 int i;
00628 Area = If_CutLutArea(p, pCut);
00629 If_CutForEachLeaf( p, pCut, pLeaf, i )
00630 {
00631 assert( pLeaf->nRefs >= 0 );
00632 if ( pLeaf->nRefs++ > 0 || !If_ObjIsAnd(pLeaf) || nLevels == 1 )
00633 continue;
00634 Area += If_CutRef( p, If_ObjCutBest(pLeaf), nLevels - 1 );
00635 }
00636 return Area;
00637 }
00638
00650 void If_CutPrint( If_Man_t * p, If_Cut_t * pCut )
00651 {
00652 unsigned i;
00653 printf( "{" );
00654 for ( i = 0; i < pCut->nLeaves; i++ )
00655 printf( " %d", pCut->pLeaves[i] );
00656 printf( " }\n" );
00657 }
00658
00670 void If_CutPrintTiming( If_Man_t * p, If_Cut_t * pCut )
00671 {
00672 If_Obj_t * pLeaf;
00673 unsigned i;
00674 printf( "{" );
00675 If_CutForEachLeaf( p, pCut, pLeaf, i )
00676 printf( " %d(%.2f/%.2f)", pLeaf->Id, If_ObjCutBest(pLeaf)->Delay, pLeaf->Required );
00677 printf( " }\n" );
00678 }
00679
00691 float If_CutAreaDerefed( If_Man_t * p, If_Cut_t * pCut, int nLevels )
00692 {
00693 float aResult, aResult2;
00694 assert( p->pPars->fSeqMap || pCut->nLeaves > 1 );
00695 aResult2 = If_CutRef( p, pCut, nLevels );
00696 aResult = If_CutDeref( p, pCut, nLevels );
00697 assert( aResult > aResult2 - p->fEpsilon );
00698 assert( aResult < aResult2 + p->fEpsilon );
00699 return aResult;
00700 }
00701
00713 float If_CutAreaRefed( If_Man_t * p, If_Cut_t * pCut, int nLevels )
00714 {
00715 float aResult, aResult2;
00716 assert( p->pPars->fSeqMap || pCut->nLeaves > 1 );
00717 aResult2 = If_CutDeref( p, pCut, nLevels );
00718 aResult = If_CutRef( p, pCut, nLevels );
00719 assert( aResult > aResult2 - p->fEpsilon );
00720 assert( aResult < aResult2 + p->fEpsilon );
00721 return aResult;
00722 }
00723
00735 void If_CutLift( If_Cut_t * pCut )
00736 {
00737 unsigned i;
00738 for ( i = 0; i < pCut->nLeaves; i++ )
00739 {
00740 assert( (pCut->pLeaves[i] & 255) < 255 );
00741 pCut->pLeaves[i]++;
00742 }
00743 }
00744
00756 void If_CutCopy( If_Man_t * p, If_Cut_t * pCutDest, If_Cut_t * pCutSrc )
00757 {
00758 int * pLeaves;
00759 char * pPerm;
00760 unsigned * pTruth;
00761
00762 pLeaves = pCutDest->pLeaves;
00763 pPerm = pCutDest->pPerm;
00764 pTruth = pCutDest->pTruth;
00765
00766 memcpy( pCutDest, pCutSrc, p->nCutBytes );
00767
00768 pCutDest->pLeaves = pLeaves;
00769 pCutDest->pPerm = pPerm;
00770 pCutDest->pTruth = pTruth;
00771 }
00772
00776
00777