24 #ifdef ABC_USE_PTHREADS
27 #include "../lib/pthread.h"
41 #ifndef ABC_USE_PTHREADS
46 #else // pthreads are used
48 #define KF_LEAF_MAX 16
50 #define KF_PROC_MAX 32
51 #define KF_WORD_MAX ((KF_LEAF_MAX > 6) ? 1 << (KF_LEAF_MAX-6) : 1)
52 #define KF_LOG_TABLE 8
54 #define KF_ADD_ON1 2 // offset in cut storage for each node (cut count; best cut)
55 #define KF_ADD_ON2 4 // offset in cut storage for each cut (leaf count; function, cut delay; cut area)
57 typedef struct Kf_Cut_t_ Kf_Cut_t;
58 typedef struct Kf_Set_t_ Kf_Set_t;
59 typedef struct Kf_Man_t_ Kf_Man_t;
70 int pLeaves[KF_LEAF_MAX];
75 unsigned short nLutSize;
76 unsigned short nCutNum;
82 int pTable[1 << KF_LOG_TABLE];
83 int pValue[1 << KF_LOG_TABLE];
84 int pPlace[KF_LEAF_MAX];
85 int pList [KF_LEAF_MAX+1];
86 Kf_Cut_t pCuts0[KF_CUT_MAX];
87 Kf_Cut_t pCuts1[KF_CUT_MAX];
88 Kf_Cut_t pCutsR[KF_CUT_MAX*KF_CUT_MAX];
89 Kf_Cut_t * ppCuts[KF_CUT_MAX];
104 Kf_Set_t pSett[KF_PROC_MAX];
107 static inline int Kf_SetCutId( Kf_Set_t *
p, Kf_Cut_t * pCut ) {
return pCut - p->pCutsR; }
108 static inline Kf_Cut_t * Kf_SetCut( Kf_Set_t *
p,
int i ) {
return i >= 0 ? p->pCutsR + i : NULL; }
110 static inline int Kf_ObjTime( Kf_Man_t *
p,
int i ) {
return Vec_IntEntry(&p->vTime, i); }
111 static inline float Kf_ObjArea( Kf_Man_t *
p,
int i ) {
return Vec_FltEntry(&p->vArea, i); }
112 static inline float Kf_ObjRefs( Kf_Man_t *
p,
int i ) {
return Vec_FltEntry(&p->vRefs, i); }
115 static inline int * Kf_ObjCuts( Kf_Man_t * p,
int i ) {
return (
int *)
Vec_SetEntry(&p->pMem,
Vec_IntEntry(&p->vCuts, i)); }
116 static inline int * Kf_ObjCuts0( Kf_Man_t * p,
int i ) {
return Kf_ObjCuts(p,
Gia_ObjFaninId0(
Gia_ManObj(p->pGia, i), i)); }
117 static inline int * Kf_ObjCuts1( Kf_Man_t * p,
int i ) {
return Kf_ObjCuts(p,
Gia_ObjFaninId1(
Gia_ManObj(p->pGia, i), i)); }
118 static inline int * Kf_ObjCutBest( Kf_Man_t * p,
int i ) {
int * pCuts = Kf_ObjCuts(p, i);
return pCuts + pCuts[1]; }
120 #define Kf_ObjForEachCutInt( pList, pCut, i ) for ( i = 0, pCut = pList + KF_ADD_ON1; i < pList[0]; i++, pCut += pCut[0] + KF_ADD_ON2 )
121 #define Kf_ListForEachCut( p, iList, pCut ) for ( pCut = Kf_SetCut(p, p->pList[iList]); pCut; pCut = Kf_SetCut(p, pCut->iNext) )
122 #define Kf_ListForEachCutP( p, iList, pCut, pPlace ) for ( pPlace = p->pList+iList, pCut = Kf_SetCut(p, *pPlace); pCut; pCut = Kf_SetCut(p, *pPlace) )
139 static inline int Kf_SetLoadCuts( Kf_Cut_t * pCuts,
int * pIntCuts )
142 int k, * pIntCut, nCuts = 0;
143 Kf_ObjForEachCutInt( pIntCuts, pIntCut, nCuts )
145 pCut = pCuts + nCuts;
148 pCut->iFunc = pIntCut[pIntCut[0] + 1];
149 pCut->Delay = pIntCut[pIntCut[0] + 2];
151 pCut->nLeaves = pIntCut[0];
152 for ( k = 0; k < pIntCut[0]; k++ )
155 pCut->Sign |= ((
word)1) << (pCut->pLeaves[k] & 0x3F);
157 pCut->Polar |= (1 << k);
162 static inline void Kf_SetPrepare( Kf_Set_t * p,
int * pCuts0,
int * pCuts1 )
169 for ( i = 0; i <= p->nLutSize; i++ )
172 p->nCuts0 = Kf_SetLoadCuts( p->pCuts0, pCuts0 );
173 p->nCuts1 = Kf_SetLoadCuts( p->pCuts1, pCuts1 );
188 static inline void Kf_ManStoreStart(
Vec_Int_t * vTemp,
int nCuts )
194 static inline void Kf_ManStoreAddUnit(
Vec_Int_t * vTemp,
int iObj,
int Time,
float Area )
203 static inline void Kf_ManSaveResults( Kf_Cut_t ** ppCuts,
int nCuts, Kf_Cut_t * pCutBest,
Vec_Int_t * vTemp )
206 assert( nCuts > 0 && nCuts < KF_CUT_MAX );
207 Kf_ManStoreStart( vTemp, nCuts );
208 for ( i = 0; i < nCuts; i++ )
210 if ( ppCuts[i] == pCutBest )
214 for ( k = 0; k < ppCuts[i]->nLeaves; k++ )
222 static inline int Kf_SetCompareCuts( Kf_Cut_t * p1, Kf_Cut_t * p2 )
224 if ( p1 == NULL || p2 == NULL )
225 return (p1 != NULL) - (p2 != NULL);
226 if ( p1->nLeaves != p2->nLeaves )
227 return p1->nLeaves - p2->nLeaves;
228 return memcmp( p1->pLeaves, p2->pLeaves,
sizeof(
int)*p1->nLeaves );
230 static inline void Kf_SetAddToList( Kf_Set_t * p, Kf_Cut_t * pCut,
int fSort )
233 pCut->iNext = p->pList[pCut->nLeaves], p->pList[pCut->nLeaves] = Kf_SetCutId(p, pCut);
239 Kf_ListForEachCutP( p, pCut->nLeaves, pTemp, pPlace )
241 if ( (Value = Kf_SetCompareCuts(pTemp, pCut)) > 0 )
244 pPlace = &pTemp->iNext;
246 pCut->iNext = *pPlace, *pPlace = Kf_SetCutId(p, pCut);
249 static inline int Kf_CutCompare( Kf_Cut_t * pCut0, Kf_Cut_t * pCut1,
int fArea )
253 if ( pCut0->Area < pCut1->Area )
return -1;
254 if ( pCut0->Area > pCut1->Area )
return 1;
255 if ( pCut0->Delay < pCut1->Delay )
return -1;
256 if ( pCut0->Delay > pCut1->Delay )
return 1;
257 if ( pCut0->nLeaves < pCut1->nLeaves )
return -1;
258 if ( pCut0->nLeaves > pCut1->nLeaves )
return 1;
262 if ( pCut0->Delay < pCut1->Delay )
return -1;
263 if ( pCut0->Delay > pCut1->Delay )
return 1;
264 if ( pCut0->nLeaves < pCut1->nLeaves )
return -1;
265 if ( pCut0->nLeaves > pCut1->nLeaves )
return 1;
266 if ( pCut0->Area < pCut1->Area )
return -1;
267 if ( pCut0->Area > pCut1->Area )
return 1;
271 static inline int Kf_SetStoreAddOne( Kf_Set_t * p,
int nCuts,
int nCutNum, Kf_Cut_t * pCut,
int fArea )
274 p->ppCuts[nCuts] = pCut;
277 for ( i = nCuts; i > 0; i-- )
278 if ( Kf_CutCompare(p->ppCuts[i-1], p->ppCuts[i], fArea) > 0 )
279 ABC_SWAP( Kf_Cut_t *, p->ppCuts[i-1], p->ppCuts[i] )
284 static
inline void Kf_SetSelectBest( Kf_Set_t * p,
int fArea,
int fSort )
289 for ( i = 0; i <= p->nLutSize; i++ )
290 Kf_ListForEachCut( p, i, pCut )
291 nCuts = Kf_SetStoreAddOne( p, nCuts, p->nCutNum-1, pCut, fArea );
292 assert( nCuts > 0 && nCuts < p->nCutNum );
294 p->pCutBest = p->ppCuts[0];
298 for ( i = 0; i <= p->nLutSize; i++ )
300 for ( i = 0; i < nCuts; i++ )
301 Kf_SetAddToList( p, p->ppCuts[i], 0 );
303 for ( i = p->nLutSize; i >= 0; i-- )
304 Kf_ListForEachCut( p, i, pCut )
305 p->ppCuts[p->nCuts++] = pCut;
306 assert( p->nCuts == nCuts );
320 static
inline int Kf_CheckCut( Kf_Cut_t * pBase, Kf_Cut_t * pCut )
322 int nSizeB = pBase->nLeaves;
323 int nSizeC = pCut->nLeaves;
324 int * pB = pBase->pLeaves;
325 int * pC = pCut->pLeaves;
327 for ( i = 0; i < nSizeC; i++ )
329 for ( k = 0; k < nSizeB; k++ )
330 if ( pC[i] == pB[k] )
337 static inline int Kf_CheckCuts( Kf_Set_t * p )
339 Kf_Cut_t * pCut0, * pCut1;
340 int i, k, m, n, Value;
342 for ( i = 0; i <= p->nLutSize; i++ )
343 Kf_ListForEachCut( p, i, pCut0 )
346 for ( m = 0; m < pCut0->nLeaves; m++ )
347 for ( n = m+1; n < pCut0->nLeaves; n++ )
348 assert( pCut0->pLeaves[m] != pCut0->pLeaves[n] );
350 for ( k = 0; k <= p->nLutSize; k++ )
351 Kf_ListForEachCut( p, k, pCut1 )
353 if ( pCut0 == pCut1 )
356 Value = Kf_CheckCut( pCut0, pCut1 );
374 static inline int Kf_HashLookup( Kf_Set_t * p,
int i )
378 for ( k = i & p->TableMask; p->pTable[k]; k = (k + 1) & p->TableMask )
379 if ( p->pTable[k] == i )
383 static inline int Kf_HashFindOrAdd( Kf_Set_t * p,
int i )
385 int k = Kf_HashLookup( p, i );
388 if ( p->nTEntries == p->nLutSize )
390 assert( p->pTable[k] == 0 );
392 p->pPlace[p->nTEntries] = k;
393 p->pValue[k] = p->nTEntries++;
396 static inline void Kf_HashPopulate( Kf_Set_t * p, Kf_Cut_t * pCut )
399 assert( p->nTEntries == 0 );
400 for ( i = 0; i < pCut->nLeaves; i++ )
401 Kf_HashFindOrAdd( p, pCut->pLeaves[i] );
402 assert( p->nTEntries == pCut->nLeaves );
404 static inline void Kf_HashCleanup( Kf_Set_t * p,
int iStart )
407 for ( i = iStart; i < p->nTEntries; i++ )
408 p->pTable[p->pPlace[i]] = 0;
409 p->nTEntries = iStart;
423 static inline int Kf_SetCountBits(
word i )
425 i = i - ((i >> 1) & 0x5555555555555555);
426 i = (i & 0x3333333333333333) + ((i >> 2) & 0x3333333333333333);
427 i = ((i + (i >> 4)) & 0x0F0F0F0F0F0F0F0F);
428 return (i*(0x0101010101010101))>>56;
430 static inline word Kf_SetCutGetSign( Kf_Cut_t * p )
432 word Sign = 0;
int i;
433 for ( i = 0; i < p->nLeaves; i++ )
434 Sign |= ((
word)1) << (p->pLeaves[i] & 0x3F);
438 static inline int Kf_SetCutDominatedByThis( Kf_Set_t * p, Kf_Cut_t * pCut )
441 for ( i = 0; i < pCut->nLeaves; i++ )
442 if ( Kf_HashLookup(p, pCut->pLeaves[i]) >= 0 )
446 static inline int Kf_SetRemoveDuplicates( Kf_Set_t * p,
int nLeaves,
word Sign )
449 Kf_ListForEachCut( p, nLeaves, pCut )
450 if ( pCut->Sign == Sign && Kf_SetCutDominatedByThis(p, pCut) )
454 static
inline void Kf_SetFilter( Kf_Set_t * p )
456 Kf_Cut_t * pCut0, * pCut1;
459 for ( i = 0; i <= p->nLutSize; i++ )
460 Kf_ListForEachCutP( p, i, pCut0, pPlace )
462 Kf_HashPopulate( p, pCut0 );
463 for ( k = 0; k < pCut0->nLeaves; k++ )
464 Kf_ListForEachCut( p, k, pCut1 )
465 if ( (pCut0->Sign & pCut1->Sign) == pCut1->Sign && Kf_SetCutDominatedByThis(p, pCut1) )
466 { k = pCut0->nLeaves; p->nCuts--;
break; }
467 if ( k == pCut0->nLeaves + 1 )
468 *pPlace = pCut0->iNext;
470 pPlace = &pCut0->iNext;
471 Kf_HashCleanup( p, 0 );
475 static inline void Kf_SetMergePairs( Kf_Set_t * p, Kf_Cut_t * pCut0, Kf_Cut_t * pCuts,
int nCuts,
int fArea )
477 Kf_Cut_t * pCut1, * pCutR;
int i;
478 Kf_HashPopulate( p, pCut0 );
479 for ( pCut1 = pCuts; pCut1 < pCuts + nCuts; pCut1++ )
481 if ( pCut0->nLeaves + pCut1->nLeaves > p->nLutSize && Kf_SetCountBits(pCut0->Sign | pCut1->Sign) > p->nLutSize )
483 Kf_HashCleanup( p, pCut0->nLeaves );
484 for ( i = 0; i < pCut1->nLeaves; i++ )
485 if ( Kf_HashFindOrAdd(p, pCut1->pLeaves[i]) )
487 if ( i < pCut1->nLeaves )
490 if ( Kf_SetRemoveDuplicates(p, p->nTEntries, pCut0->Sign | pCut1->Sign) )
493 pCutR = p->pCutsR + p->nCuts++;
494 pCutR->nLeaves = p->nTEntries;
495 for ( i = 0; i < p->nTEntries; i++ )
496 pCutR->pLeaves[i] = p->pTable[p->pPlace[i]];
497 pCutR->Sign = pCut0->Sign | pCut1->Sign;
498 pCutR->Delay =
Abc_MaxInt(pCut0->Delay, pCut1->Delay);
499 pCutR->Area = pCut0->Area + pCut1->Area;
501 Kf_SetAddToList( p, pCutR, 0 );
503 Kf_HashCleanup( p, 0 );
505 static inline void Kf_SetMerge( Kf_Set_t * p,
int * pCuts0,
int * pCuts1,
int fArea,
int fCutMin )
508 Kf_SetPrepare( p, pCuts0, pCuts1 );
509 p->CutCount[0] += p->nCuts0 * p->nCuts1;
512 for ( c0 = c1 = 0; c0 < p->nCuts0 && c1 < p->nCuts1; )
514 if ( p->pCuts0[c0].nLeaves >= p->pCuts1[c1].nLeaves )
515 Kf_SetMergePairs( p, p->pCuts0 + c0++, p->pCuts1 + c1, p->nCuts1 - c1, fArea );
517 Kf_SetMergePairs( p, p->pCuts1 + c1++, p->pCuts0 + c0, p->nCuts0 - c0, fArea );
519 p->CutCount[2] += p->nCuts;
522 p->CutCount[3] +=
Abc_MinInt( p->nCuts, p->nCutNum-1 );
523 Kf_SetSelectBest( p, fArea, 1 );
537 static inline int Kf_SetCutIsContainedSimple( Kf_Cut_t * pBase, Kf_Cut_t * pCut )
539 int nSizeB = pBase->nLeaves;
540 int nSizeC = pCut->nLeaves;
541 int * pB = pBase->pLeaves;
542 int * pC = pCut->pLeaves;
544 assert( nSizeB >= nSizeC );
545 for ( i = 0; i < nSizeC; i++ )
547 for ( k = 0; k < nSizeB; k++ )
548 if ( pC[i] == pB[k] )
555 static inline int Kf_SetMergeSimpleOne( Kf_Cut_t * pCut0, Kf_Cut_t * pCut1, Kf_Cut_t * pCut,
int nLutSize )
557 int nSize0 = pCut0->nLeaves;
558 int nSize1 = pCut1->nLeaves;
559 int * pC0 = pCut0->pLeaves;
560 int * pC1 = pCut1->pLeaves;
561 int * pC = pCut->pLeaves;
565 for ( i = 0; i < nSize1; i++ )
567 for ( k = 0; k < nSize0; k++ )
568 if ( pC1[i] == pC0[k] )
576 for ( i = 0; i < nSize0; i++ )
581 static inline int Kf_SetRemoveDuplicatesSimple( Kf_Set_t * p, Kf_Cut_t * pCutNew )
584 Kf_ListForEachCut( p, pCutNew->nLeaves, pCut )
585 if ( pCut->Sign == pCutNew->Sign && Kf_SetCutIsContainedSimple(pCut, pCutNew) )
589 static
inline void Kf_SetFilterSimple( Kf_Set_t * p )
591 Kf_Cut_t * pCut0, * pCut1;
594 for ( i = 0; i <= p->nLutSize; i++ )
595 Kf_ListForEachCutP( p, i, pCut0, pPlace )
597 for ( k = 0; k < pCut0->nLeaves; k++ )
598 Kf_ListForEachCut( p, k, pCut1 )
599 if ( (pCut0->Sign & pCut1->Sign) == pCut1->Sign && Kf_SetCutIsContainedSimple(pCut0, pCut1) )
600 { k = pCut0->nLeaves; p->nCuts--;
break; }
601 if ( k == pCut0->nLeaves + 1 )
602 *pPlace = pCut0->iNext;
604 pPlace = &pCut0->iNext;
608 static inline void Kf_SetMergeSimple( Kf_Set_t * p,
int * pCuts0,
int * pCuts1,
int fArea,
int fCutMin )
610 Kf_Cut_t * pCut0, * pCut1, * pCutR;
611 Kf_SetPrepare( p, pCuts0, pCuts1 );
612 p->CutCount[0] += p->nCuts0 * p->nCuts1;
613 for ( pCut0 = p->pCuts0; pCut0 < p->pCuts0 + p->nCuts0; pCut0++ )
614 for ( pCut1 = p->pCuts1; pCut1 < p->pCuts1 + p->nCuts1; pCut1++ )
616 if ( pCut0->nLeaves + pCut1->nLeaves > p->nLutSize && Kf_SetCountBits(pCut0->Sign | pCut1->Sign) > p->nLutSize )
619 pCutR = p->pCutsR + p->nCuts;
620 if ( !Kf_SetMergeSimpleOne(pCut0, pCut1, pCutR, p->nLutSize) )
623 pCutR->Sign = pCut0->Sign | pCut1->Sign;
624 if ( Kf_SetRemoveDuplicatesSimple(p, pCutR) )
629 int nOldSupp = pCutR->nLeaves;
631 assert( pCutR->nLeaves <= nOldSupp );
632 if ( pCutR->nLeaves < nOldSupp )
633 pCutR->Sign = Kf_SetCutGetSign( pCutR );
636 assert( pCutR->nLeaves > 1 );
637 pCutR->Delay =
Abc_MaxInt(pCut0->Delay, pCut1->Delay);
638 pCutR->Area = pCut0->Area + pCut1->Area;
640 Kf_SetAddToList( p, pCutR, 0 );
642 Kf_SetFilterSimple( p );
644 p->CutCount[3] +=
Abc_MinInt( p->nCuts, p->nCutNum-1 );
645 Kf_SetSelectBest( p, fArea, 1 );
659 static inline int Kf_SetCutIsContainedOrder( Kf_Cut_t * pBase, Kf_Cut_t * pCut )
661 int nSizeB = pBase->nLeaves;
662 int nSizeC = pCut->nLeaves;
664 if ( nSizeB == nSizeC )
666 for ( i = 0; i < nSizeB; i++ )
667 if ( pBase->pLeaves[i] != pCut->pLeaves[i] )
671 assert( nSizeB > nSizeC );
672 for ( i = k = 0; i < nSizeB; i++ )
674 if ( pBase->pLeaves[i] > pCut->pLeaves[k] )
676 if ( pBase->pLeaves[i] == pCut->pLeaves[k] )
684 static inline int Kf_SetMergeOrderOne( Kf_Cut_t * pCut0, Kf_Cut_t * pCut1, Kf_Cut_t * pCut,
int nLutSize )
686 int nSize0 = pCut0->nLeaves;
687 int nSize1 = pCut1->nLeaves;
688 int * pC0 = pCut0->pLeaves;
689 int * pC1 = pCut1->pLeaves;
690 int * pC = pCut->pLeaves;
693 if ( nSize0 == nLutSize && nSize1 == nLutSize )
695 for ( i = 0; i < nSize0; i++ )
697 if ( pC0[i] != pC1[i] )
return 0;
700 pCut->nLeaves = nLutSize;
707 if ( c == nLutSize )
return 0;
708 if ( pC0[i] < pC1[k] )
711 if ( i >= nSize0 )
goto FlushCut1;
713 else if ( pC0[i] > pC1[k] )
716 if ( k >= nSize1 )
goto FlushCut0;
720 pC[c++] = pC0[i++]; k++;
721 if ( i >= nSize0 )
goto FlushCut1;
722 if ( k >= nSize1 )
goto FlushCut0;
727 if ( c + nSize0 > nLutSize + i )
return 0;
734 if ( c + nSize1 > nLutSize + k )
return 0;
740 static inline int Kf_SetRemoveDuplicatesOrder( Kf_Set_t * p, Kf_Cut_t * pCutNew )
743 Kf_ListForEachCut( p, pCutNew->nLeaves, pCut )
744 if ( pCut->Sign == pCutNew->Sign && Kf_SetCutIsContainedOrder(pCut, pCutNew) )
748 static
inline void Kf_SetFilterOrder( Kf_Set_t * p )
750 Kf_Cut_t * pCut0, * pCut1;
753 for ( i = 0; i <= p->nLutSize; i++ )
754 Kf_ListForEachCutP( p, i, pCut0, pPlace )
756 for ( k = 0; k < pCut0->nLeaves; k++ )
757 Kf_ListForEachCut( p, k, pCut1 )
758 if ( (pCut0->Sign & pCut1->Sign) == pCut1->Sign && Kf_SetCutIsContainedOrder(pCut0, pCut1) )
759 { k = pCut0->nLeaves; p->nCuts--;
break; }
760 if ( k == pCut0->nLeaves + 1 )
761 *pPlace = pCut0->iNext;
763 pPlace = &pCut0->iNext;
788 static inline void Kf_SetMergeOrder( Kf_Set_t * p,
int * pCuts0,
int * pCuts1,
int fArea,
int fCutMin )
790 Kf_Cut_t * pCut0, * pCut1, * pCutR;
791 Kf_SetPrepare( p, pCuts0, pCuts1 );
792 p->CutCount[0] += p->nCuts0 * p->nCuts1;
793 for ( pCut0 = p->pCuts0; pCut0 < p->pCuts0 + p->nCuts0; pCut0++ )
794 for ( pCut1 = p->pCuts1; pCut1 < p->pCuts1 + p->nCuts1; pCut1++ )
796 if ( pCut0->nLeaves + pCut1->nLeaves > p->nLutSize && Kf_SetCountBits(pCut0->Sign | pCut1->Sign) > p->nLutSize )
799 pCutR = p->pCutsR + p->nCuts;
800 if ( !Kf_SetMergeOrderOne(pCut0, pCut1, pCutR, p->nLutSize) )
803 pCutR->Sign = pCut0->Sign | pCut1->Sign;
804 if ( Kf_SetRemoveDuplicatesOrder(p, pCutR) )
809 int nOldSupp = pCutR->nLeaves;
811 assert( pCutR->nLeaves <= nOldSupp );
812 if ( pCutR->nLeaves < nOldSupp )
813 pCutR->Sign = Kf_SetCutGetSign( pCutR );
816 assert( pCutR->nLeaves > 1 );
817 pCutR->Delay =
Abc_MaxInt(pCut0->Delay, pCut1->Delay);
818 pCutR->Area = pCut0->Area + pCut1->Area;
820 Kf_SetAddToList( p, pCutR, 0 );
822 Kf_SetFilterOrder( p );
824 p->CutCount[3] +=
Abc_MinInt( p->nCuts, p->nCutNum-1 );
825 Kf_SetSelectBest( p, fArea, 1 );
840 static inline int Kf_CutSize(
int * pCut ) {
return pCut[0]; }
841 static inline int Kf_CutFunc(
int * pCut ) {
return pCut[pCut[0] + 1]; }
842 static inline int Kf_CutLeaf(
int * pCut,
int i ) {
assert(i);
return Abc_Lit2Var(pCut[i]); }
843 static inline int Kf_CutTime( Kf_Man_t * p,
int * pCut )
846 for ( i = 1; i <= Kf_CutSize(pCut); i++ )
847 Time =
Abc_MaxInt( Time, Kf_ObjTime(p, Kf_CutLeaf(pCut, i)) );
850 static inline void Kf_CutRef( Kf_Man_t * p,
int * pCut )
853 for ( i = 1; i <= Kf_CutSize(pCut); i++ )
856 static inline void Kf_CutDeref( Kf_Man_t * p,
int * pCut )
859 for ( i = 1; i <= Kf_CutSize(pCut); i++ )
862 static inline void Kf_CutPrint(
int * pCut )
865 printf(
"%d {", Kf_CutSize(pCut) );
866 for ( i = 1; i <= Kf_CutSize(pCut); i++ )
867 printf(
" %d", Kf_CutLeaf(pCut, i) );
868 printf(
" } Func = %d\n", Kf_CutFunc(pCut) );
870 static inline void Gia_CutSetPrint(
int * pCuts )
873 Kf_ObjForEachCutInt( pCuts, pCut, i )
889 int Kf_ManComputeDelay( Kf_Man_t * p,
int fEval )
906 int Kf_ManComputeRefs( Kf_Man_t * p )
909 float nRefsNew;
int i, * pCut;
912 assert( p->pGia->pRefs != NULL );
914 p->pPars->Area = p->pPars->Edge = 0;
921 pCut = Kf_ObjCutBest(p, i);
922 Kf_CutRef( p, pCut );
923 p->pPars->Edge += Kf_CutSize(pCut);
930 if ( p->pPars->fOptEdge )
931 nRefsNew =
Abc_MaxFloat( 1, 0.8 * pRefs[i] + 0.2 * p->pGia->pRefs[i] );
933 nRefsNew =
Abc_MaxFloat( 1, 0.2 * pRefs[i] + 0.8 * p->pGia->pRefs[i] );
934 pFlow[i] = pFlow[i] * pRefs[i] / nRefsNew;
939 p->pPars->Delay = Kf_ManComputeDelay( p, 1 );
940 return p->pPars->Area;
954 #define PAR_THR_MAX 100
955 typedef struct Kf_ThData_t_
962 void * Kf_WorkerThread(
void * pArg )
964 Kf_ThData_t * pThData = (Kf_ThData_t *)pArg;
965 Kf_Man_t * pMan = pThData->pSett->pMan;
966 int fAreaOnly = pThData->pSett->pMan->pPars->fAreaOnly;
967 int fCutMin = pThData->pSett->pMan->pPars->fCutMin;
968 volatile int * pPlace = &pThData->Status;
972 while ( *pPlace == 0 );
973 assert( pThData->Status == 1 );
974 if ( pThData->Id == -1 )
976 pthread_exit( NULL );
980 assert( pThData->Id >= 0 );
982 Kf_SetMergeOrder( pThData->pSett, Kf_ObjCuts0(pMan, pThData->Id), Kf_ObjCuts1(pMan, pThData->Id), fAreaOnly, fCutMin );
1005 void Kf_ManComputeCuts( Kf_Man_t * p )
1007 pthread_t WorkerThread[PAR_THR_MAX];
1008 Kf_ThData_t ThData[PAR_THR_MAX];
1011 int nProcs = p->pPars->nProcNum;
1012 int i, k, iFan, status, nCountFanins, fRunning;
1014 assert( nProcs <= PAR_THR_MAX );
1016 vFanins = Kf_ManCreateFaninCounts( p->pGia );
1024 for ( i = 0; i < nProcs; i++ )
1026 ThData[i].pSett = p->pSett + i;
1028 ThData[i].Status = 0;
1029 ThData[i].clkUsed = 0;
1030 status = pthread_create( WorkerThread + i, NULL, Kf_WorkerThread, (
void *)(ThData + i) );
assert( status == 0 );
1034 while ( nCountFanins > 0 ||
Vec_IntSize(vStack) > 0 || fRunning )
1036 for ( i = 0; i < nProcs; i++ )
1038 if ( ThData[i].Status )
1040 assert( ThData[i].Status == 0 );
1041 if ( ThData[i].Id >= 0 )
1043 int iObj = ThData[i].Id;
1044 Kf_Set_t * pSett = p->pSett + i;
1048 Kf_ManSaveResults( pSett->ppCuts, pSett->nCuts, pSett->pCutBest, p->vTemp );
1050 Vec_FltWriteEntry( &p->vArea, iObj, (pSett->pCutBest->Area + 1)/Kf_ObjRefs(p, iObj) );
1051 if ( pSett->pCutBest->nLeaves > 1 )
1052 Kf_ManStoreAddUnit( p->vTemp, iObj, Kf_ObjTime(p, iObj), Kf_ObjArea(p, iObj) );
1053 Kf_ObjSetCuts( p, iObj, p->vTemp );
1064 assert( nCountFanins > 0 );
1072 ThData[i].Status = 1;
1077 for ( i = 0; i < nProcs; i++ )
1078 if ( ThData[i].Status == 1 || (ThData[i].Status == 0 && ThData[i].Id >= 0) )
1085 printf(
"%d -> %d ", k, iFan );
1090 for ( i = 0; i < nProcs; i++ )
1092 assert( ThData[i].Status == 0 );
1094 ThData[i].Status = 1;
1099 if ( !p->pPars->fVerbose )
1102 printf(
"Main : " );
1104 for ( i = 0; i < nProcs; i++ )
1106 printf(
"Thread %d : ", i );
1123 void Kf_ManPrintStats( Kf_Man_t * p,
char * pTitle )
1125 if ( !p->pPars->fVerbose )
1127 printf(
"%s : ", pTitle );
1128 printf(
"Level =%6lu ", p->pPars->Delay );
1129 printf(
"Area =%9lu ", p->pPars->Area );
1130 printf(
"Edge =%9lu ", p->pPars->Edge );
1134 void Kf_ManComputeMapping( Kf_Man_t * p )
1137 if ( p->pPars->fVerbose )
1140 printf(
"LutSize = %d CutMax = %d Threads = %d\n", p->pPars->nLutSize, p->pPars->nCutNum, p->pPars->nProcNum );
1141 printf(
"Computing cuts...\r" );
1147 Kf_ManStoreStart( p->vTemp, 0 );
1148 Kf_ManStoreAddUnit( p->vTemp, i, 0, 0 );
1150 Kf_ObjSetCuts( p, i, p->vTemp );
1152 if ( p->pPars->nProcNum > 0 )
1153 Kf_ManComputeCuts( p );
1158 if ( p->pPars->fCutHashing )
1159 Kf_SetMerge( p->pSett, Kf_ObjCuts0(p, i), Kf_ObjCuts1(p, i), p->pPars->fAreaOnly, p->pPars->fCutMin );
1160 else if ( p->pPars->fCutSimple )
1161 Kf_SetMergeSimple( p->pSett, Kf_ObjCuts0(p, i), Kf_ObjCuts1(p, i), p->pPars->fAreaOnly, p->pPars->fCutMin );
1163 Kf_SetMergeOrder( p->pSett, Kf_ObjCuts0(p, i), Kf_ObjCuts1(p, i), p->pPars->fAreaOnly, p->pPars->fCutMin );
1164 Kf_ManSaveResults( p->pSett->ppCuts, p->pSett->nCuts, p->pSett->pCutBest, p->vTemp );
1166 Vec_FltWriteEntry( &p->vArea, i, (p->pSett->pCutBest->Area + 1)/Kf_ObjRefs(p, i) );
1167 if ( p->pSett->pCutBest->nLeaves > 1 )
1168 Kf_ManStoreAddUnit( p->vTemp, i, Kf_ObjTime(p, i), Kf_ObjArea(p, i) );
1169 Kf_ObjSetCuts( p, i, p->vTemp );
1173 Kf_ManComputeRefs( p );
1174 if ( p->pPars->fVerbose )
1176 printf(
"CutPair = %lu ", p->pSett->CutCount[0] );
1177 printf(
"Merge = %lu ", p->pSett->CutCount[1] );
1178 printf(
"Eval = %lu ", p->pSett->CutCount[2] );
1179 printf(
"Cut = %lu ", p->pSett->CutCount[3] );
1181 printf(
"Memory: " );
1182 printf(
"Gia = %.2f MB ",
Gia_ManMemory(p->pGia) / (1<<20) );
1183 printf(
"Man = %.2f MB ", 4.0 *
sizeof(
int) *
Gia_ManObjNum(p->pGia) / (1<<20) );
1185 printf(
"Set = %.2f KB ", 1.0 *
sizeof(Kf_Set_t) / (1<<10) );
1188 Kf_ManPrintStats( p,
"Start" );
1205 Gia_Obj_t * pObj, * pCtrl, * pData0, * pData1;
int i;
1226 Kf_Man_t *
p;
int i;
1227 assert( pPars->nLutSize <= KF_LEAF_MAX );
1228 assert( pPars->nCutNum <= KF_CUT_MAX );
1229 assert( pPars->nProcNum <= KF_PROC_MAX );
1239 Kf_ManSetInitRefs( pGia, &p->vRefs );
1243 for ( i = 0; i <
Abc_MaxInt(1, pPars->nProcNum); i++ )
1245 (p->pSett + i)->pMan = p;
1246 (p->pSett + i)->nLutSize = (
unsigned short)pPars->nLutSize;
1247 (p->pSett + i)->nCutNum = (
unsigned short)pPars->nCutNum;
1248 (p->pSett + i)->TableMask = (1 << KF_LOG_TABLE) - 1;
1252 void Kf_ManFree( Kf_Man_t * p )
1263 Gia_Man_t * Kf_ManDerive( Kf_Man_t * p )
1268 assert( !p->pPars->fCutMin );
1275 pCut = Kf_ObjCutBest( p, i );
1278 for ( k = 1; k <= Kf_CutSize(pCut); k++ )
1283 p->pGia->vMapping = vMapping;
1327 p = Kf_ManAlloc( pGia, pPars );
1328 Kf_ManComputeMapping( p );
1329 pNew = Kf_ManDerive( p );
1338 #endif // pthreads are used
static int * Vec_IntArray(Vec_Int_t *p)
static void Vec_FltWriteEntry(Vec_Flt_t *p, int i, float Entry)
#define Gia_ManForEachCo(p, pObj, i)
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
static Gia_Obj_t * Gia_Regular(Gia_Obj_t *p)
static void Vec_SetAlloc_(Vec_Set_t *p, int nPageSize)
FUNCTION DEFINITIONS ///.
static int Abc_Var2Lit(int Var, int fCompl)
static int Gia_ObjRefDecId(Gia_Man_t *p, int Id)
static int Gia_ObjRefNum(Gia_Man_t *p, Gia_Obj_t *pObj)
static int Gia_ObjIsBuf(Gia_Obj_t *pObj)
static float * Vec_FltArray(Vec_Flt_t *p)
#define Gia_ManForEachObjReverse(p, pObj, i)
static abctime Abc_Clock()
static word * Vec_SetEntry(Vec_Set_t *p, int h)
static int Abc_MaxInt(int a, int b)
#define Gia_ManForEachCoDriver(p, pObj, i)
static int Vec_SetAppend(Vec_Set_t *p, int *pArray, int nSize)
static void Vec_FltFill(Vec_Flt_t *p, int nSize, float Entry)
static Gia_Obj_t * Gia_ManObj(Gia_Man_t *p, int v)
static float Abc_MaxFloat(float a, float b)
for(p=first;p->value< newval;p=p->next)
#define ABC_SWAP(Type, a, b)
#define Gia_ManForEachCi(p, pObj, i)
static void Abc_PrintTime(int level, const char *pStr, abctime time)
static void Vec_IntWriteEntry(Vec_Int_t *p, int i, int Entry)
static int Gia_ManAndNum(Gia_Man_t *p)
static void Vec_IntSelectSort(int *pArray, int nSize)
static int Abc_MinInt(int a, int b)
ABC_NAMESPACE_IMPL_START void Kf_ManSetDefaultPars(Jf_Par_t *pPars)
DECLARATIONS ///.
static int Abc_LitIsCompl(int Lit)
static int Abc_Float2Int(float Val)
static Gia_Obj_t * Gia_ObjFanin0(Gia_Obj_t *pObj)
static Vec_Int_t * Vec_IntAlloc(int nCap)
FUNCTION DEFINITIONS ///.
static void Vec_FltUpdateEntry(Vec_Flt_t *p, int i, float Value)
static void Vec_IntAddToEntry(Vec_Int_t *p, int i, int Addition)
Gia_Man_t * Kf_ManPerformMapping(Gia_Man_t *pGia, Jf_Par_t *pPars)
void Gia_ManStaticFanoutStop(Gia_Man_t *p)
static int Vec_IntEntry(Vec_Int_t *p, int i)
unsigned __int64 word
DECLARATIONS ///.
static int Gia_ObjRefInc(Gia_Man_t *p, Gia_Obj_t *pObj)
#define ABC_NAMESPACE_IMPL_END
static void Vec_IntFill(Vec_Int_t *p, int nSize, int Fill)
static void Vec_SetFree_(Vec_Set_t *p)
void Gia_ManStaticFanoutStart(Gia_Man_t *p)
#define Gia_ManForEachAnd(p, pObj, i)
static void Vec_IntPush(Vec_Int_t *p, int Entry)
static int Gia_ObjId(Gia_Man_t *p, Gia_Obj_t *pObj)
#define Gia_ObjForEachFanoutStaticId(p, Id, FanId, i)
void Gia_ObjPrint(Gia_Man_t *p, Gia_Obj_t *pObj)
static void Vec_IntFreeP(Vec_Int_t **p)
static int Vec_IntCap(Vec_Int_t *p)
static int Gia_ObjIsCo(Gia_Obj_t *pObj)
#define ABC_NAMESPACE_IMPL_START
int Gia_ObjIsMuxType(Gia_Obj_t *pNode)
static int Gia_ManCiNum(Gia_Man_t *p)
static void Vec_FltAddToEntry(Vec_Flt_t *p, int i, float Addition)
static int Vec_IntSize(Vec_Int_t *p)
static int Vec_IntSum(Vec_Int_t *p)
typedefABC_NAMESPACE_HEADER_START struct Vec_Set_t_ Vec_Set_t
INCLUDES ///.
Gia_Obj_t * Gia_ObjRecognizeMux(Gia_Obj_t *pNode, Gia_Obj_t **ppNodeT, Gia_Obj_t **ppNodeE)
static int Gia_ObjIsAnd(Gia_Obj_t *pObj)
#define Gia_ManForEachObj(p, pObj, i)
MACRO DEFINITIONS ///.
#define ABC_CALLOC(type, num)
static int Abc_Lit2Var(int Lit)
typedefABC_NAMESPACE_HEADER_START struct Vec_Flt_t_ Vec_Flt_t
INCLUDES ///.
static float Abc_Int2Float(int Num)
static Gia_Obj_t * Gia_ObjFanin1(Gia_Obj_t *pObj)
double Gia_ManMemory(Gia_Man_t *p)
static float Vec_FltEntry(Vec_Flt_t *p, int i)
static void Vec_IntFree(Vec_Int_t *p)
static void Vec_IntClear(Vec_Int_t *p)
static int Gia_ObjIsCi(Gia_Obj_t *pObj)
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
static int Gia_ObjFaninId1(Gia_Obj_t *pObj, int ObjId)
static double Vec_ReportMemory(Vec_Set_t *p)
static int Gia_ManObjNum(Gia_Man_t *p)
static int Gia_ObjRefIncId(Gia_Man_t *p, int Id)
static int Gia_ObjFaninId0(Gia_Obj_t *pObj, int ObjId)
static int Gia_ManCoNum(Gia_Man_t *p)