1 /**CFile****************************************************************
2 
3   FileName    [ifCut.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [FPGA mapping based on priority cuts.]
8 
9   Synopsis    [Cut computation.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - November 21, 2006.]
16 
17   Revision    [$Id: ifCut.c,v 1.00 2006/11/21 00:00:00 alanmi Exp $]
18 
19 ***********************************************************************/
20 
21 #include "if.h"
22 
23 ABC_NAMESPACE_IMPL_START
24 
25 
26 ////////////////////////////////////////////////////////////////////////
27 ///                        DECLARATIONS                              ///
28 ////////////////////////////////////////////////////////////////////////
29 
30 ////////////////////////////////////////////////////////////////////////
31 ///                     FUNCTION DEFINITIONS                         ///
32 ////////////////////////////////////////////////////////////////////////
33 
34 /**Function*************************************************************
35 
36   Synopsis    [Check correctness of cuts.]
37 
38   Description []
39 
40   SideEffects []
41 
42   SeeAlso     []
43 
44 ***********************************************************************/
If_CutVerifyCut(If_Cut_t * pBase,If_Cut_t * pCut)45 static inline int If_CutVerifyCut( If_Cut_t * pBase, If_Cut_t * pCut ) // check if pCut is contained in pBase
46 {
47     int nSizeB = pBase->nLeaves;
48     int nSizeC = pCut->nLeaves;
49     int * pB = pBase->pLeaves;
50     int * pC = pCut->pLeaves;
51     int i, k;
52     for ( i = 0; i < nSizeC; i++ )
53     {
54         for ( k = 0; k < nSizeB; k++ )
55             if ( pC[i] == pB[k] )
56                 break;
57         if ( k == nSizeB )
58             return 0;
59     }
60     return 1;
61 }
If_CutVerifyCuts(If_Set_t * pCutSet,int fOrdered)62 int If_CutVerifyCuts( If_Set_t * pCutSet, int fOrdered )
63 {
64     static int Count = 0;
65     If_Cut_t * pCut0, * pCut1;
66     int i, k, m, n, Value;
67     assert( pCutSet->nCuts > 0 );
68     for ( i = 0; i < pCutSet->nCuts; i++ )
69     {
70         pCut0 = pCutSet->ppCuts[i];
71         assert( pCut0->uSign == If_ObjCutSignCompute(pCut0) );
72         if ( fOrdered )
73         {
74             // check duplicates
75             for ( m = 1; m < (int)pCut0->nLeaves; m++ )
76                 assert( pCut0->pLeaves[m-1] < pCut0->pLeaves[m] );
77         }
78         else
79         {
80             // check duplicates
81             for ( m = 0; m < (int)pCut0->nLeaves; m++ )
82             for ( n = m+1; n < (int)pCut0->nLeaves; n++ )
83             assert( pCut0->pLeaves[m] != pCut0->pLeaves[n] );
84         }
85         // check pairs
86         for ( k = 0; k < pCutSet->nCuts; k++ )
87         {
88             pCut1 = pCutSet->ppCuts[k];
89             if ( pCut0 == pCut1 )
90                 continue;
91             Count++;
92             // check containments
93             Value = If_CutVerifyCut( pCut0, pCut1 );
94 //            assert( Value == 0 );
95             if ( Value )
96             {
97                 assert( pCut0->uSign == If_ObjCutSignCompute(pCut0) );
98                 assert( pCut1->uSign == If_ObjCutSignCompute(pCut1) );
99                 If_CutPrint( pCut0 );
100                 If_CutPrint( pCut1 );
101                 assert( 0 );
102             }
103         }
104     }
105     return 1;
106 }
107 
108 /**Function*************************************************************
109 
110   Synopsis    [Returns 1 if pDom is contained in pCut.]
111 
112   Description []
113 
114   SideEffects []
115 
116   SeeAlso     []
117 
118 ***********************************************************************/
If_CutCheckDominance(If_Cut_t * pDom,If_Cut_t * pCut)119 static inline int If_CutCheckDominance( If_Cut_t * pDom, If_Cut_t * pCut )
120 {
121     int i, k;
122     assert( pDom->nLeaves <= pCut->nLeaves );
123     for ( i = 0; i < (int)pDom->nLeaves; i++ )
124     {
125         for ( k = 0; k < (int)pCut->nLeaves; k++ )
126             if ( pDom->pLeaves[i] == pCut->pLeaves[k] )
127                 break;
128         if ( k == (int)pCut->nLeaves ) // node i in pDom is not contained in pCut
129             return 0;
130     }
131     // every node in pDom is contained in pCut
132     return 1;
133 }
134 
135 /**Function*************************************************************
136 
137   Synopsis    [Returns 1 if the cut is contained.]
138 
139   Description []
140 
141   SideEffects []
142 
143   SeeAlso     []
144 
145 ***********************************************************************/
If_CutFilter(If_Set_t * pCutSet,If_Cut_t * pCut,int fSaveCut0)146 int If_CutFilter( If_Set_t * pCutSet, If_Cut_t * pCut, int fSaveCut0 )
147 {
148     If_Cut_t * pTemp;
149     int i, k;
150     assert( pCutSet->ppCuts[pCutSet->nCuts] == pCut );
151     for ( i = 0; i < pCutSet->nCuts; i++ )
152     {
153         pTemp = pCutSet->ppCuts[i];
154         if ( pTemp->nLeaves > pCut->nLeaves )
155         {
156             // do not fiter the first cut
157             if ( i == 0 && ((pCutSet->nCuts > 1 && pCutSet->ppCuts[1]->fUseless) || (fSaveCut0 && pCutSet->nCuts == 1)) )
158                 continue;
159             // skip the non-contained cuts
160             if ( (pTemp->uSign & pCut->uSign) != pCut->uSign )
161                 continue;
162             // check containment seriously
163             if ( If_CutCheckDominance( pCut, pTemp ) )
164             {
165 //                p->ppCuts[i] = p->ppCuts[p->nCuts-1];
166 //                p->ppCuts[p->nCuts-1] = pTemp;
167 //                p->nCuts--;
168 //                i--;
169                 // remove contained cut
170                 for ( k = i; k < pCutSet->nCuts; k++ )
171                     pCutSet->ppCuts[k] = pCutSet->ppCuts[k+1];
172                 pCutSet->ppCuts[pCutSet->nCuts] = pTemp;
173                 pCutSet->nCuts--;
174                 i--;
175             }
176          }
177         else
178         {
179             // skip the non-contained cuts
180             if ( (pTemp->uSign & pCut->uSign) != pTemp->uSign )
181                 continue;
182             // check containment seriously
183             if ( If_CutCheckDominance( pTemp, pCut ) )
184                 return 1;
185         }
186     }
187     return 0;
188 }
189 
190 /**Function*************************************************************
191 
192   Synopsis    [Prepares the object for FPGA mapping.]
193 
194   Description []
195 
196   SideEffects []
197 
198   SeeAlso     []
199 
200 ***********************************************************************/
If_CutMergeOrdered_(If_Man_t * p,If_Cut_t * pC0,If_Cut_t * pC1,If_Cut_t * pC)201 int If_CutMergeOrdered_( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC )
202 {
203     int nSizeC0 = pC0->nLeaves;
204     int nSizeC1 = pC1->nLeaves;
205     int nLimit  = pC0->nLimit;
206     int i, k, c, s;
207 
208     // both cuts are the largest
209     if ( nSizeC0 == nLimit && nSizeC1 == nLimit )
210     {
211         for ( i = 0; i < nSizeC0; i++ )
212         {
213             if ( pC0->pLeaves[i] != pC1->pLeaves[i] )
214                 return 0;
215             p->pPerm[0][i] = p->pPerm[1][i] = p->pPerm[2][i] = i;
216             pC->pLeaves[i] = pC0->pLeaves[i];
217         }
218         pC->nLeaves = nLimit;
219         pC->uSign = pC0->uSign | pC1->uSign;
220         p->uSharedMask = Abc_InfoMask( nLimit );
221         return 1;
222     }
223 
224     // compare two cuts with different numbers
225     i = k = c = s = 0;
226     p->uSharedMask = 0;
227     if ( nSizeC0 == 0 ) goto FlushCut1;
228     if ( nSizeC1 == 0 ) goto FlushCut0;
229     while ( 1 )
230     {
231         if ( c == nLimit ) return 0;
232         if ( pC0->pLeaves[i] < pC1->pLeaves[k] )
233         {
234             p->pPerm[0][i] = c;
235             pC->pLeaves[c++] = pC0->pLeaves[i++];
236             if ( i == nSizeC0 ) goto FlushCut1;
237         }
238         else if ( pC0->pLeaves[i] > pC1->pLeaves[k] )
239         {
240             p->pPerm[1][k] = c;
241             pC->pLeaves[c++] = pC1->pLeaves[k++];
242             if ( k == nSizeC1 ) goto FlushCut0;
243         }
244         else
245         {
246             p->uSharedMask |= (1 << c);
247             p->pPerm[0][i] = p->pPerm[1][k] = p->pPerm[2][s++] = c;
248             pC->pLeaves[c++] = pC0->pLeaves[i++]; k++;
249             if ( i == nSizeC0 ) goto FlushCut1;
250             if ( k == nSizeC1 ) goto FlushCut0;
251         }
252     }
253 
254 FlushCut0:
255     if ( c + nSizeC0 > nLimit + i ) return 0;
256     while ( i < nSizeC0 )
257     {
258         p->pPerm[0][i] = c;
259         pC->pLeaves[c++] = pC0->pLeaves[i++];
260     }
261     pC->nLeaves = c;
262     pC->uSign = pC0->uSign | pC1->uSign;
263     assert( c > 0 );
264     return 1;
265 
266 FlushCut1:
267     if ( c + nSizeC1 > nLimit + k ) return 0;
268     while ( k < nSizeC1 )
269     {
270         p->pPerm[1][k] = c;
271         pC->pLeaves[c++] = pC1->pLeaves[k++];
272     }
273     pC->nLeaves = c;
274     pC->uSign = pC0->uSign | pC1->uSign;
275     assert( c > 0 );
276     return 1;
277 }
278 
279 /**Function*************************************************************
280 
281   Synopsis    [Prepares the object for FPGA mapping.]
282 
283   Description []
284 
285   SideEffects []
286 
287   SeeAlso     []
288 
289 ***********************************************************************/
If_CutMergeOrdered(If_Man_t * p,If_Cut_t * pC0,If_Cut_t * pC1,If_Cut_t * pC)290 int If_CutMergeOrdered( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC )
291 {
292     int nSizeC0 = pC0->nLeaves;
293     int nSizeC1 = pC1->nLeaves;
294     int nLimit  = pC0->nLimit;
295     int i, k, c, s;
296 
297     // both cuts are the largest
298     if ( nSizeC0 == nLimit && nSizeC1 == nLimit )
299     {
300         for ( i = 0; i < nSizeC0; i++ )
301         {
302             if ( pC0->pLeaves[i] != pC1->pLeaves[i] )
303                 return 0;
304             pC->pLeaves[i] = pC0->pLeaves[i];
305         }
306         pC->nLeaves = nLimit;
307         pC->uSign = pC0->uSign | pC1->uSign;
308         return 1;
309     }
310 
311     // compare two cuts with different numbers
312     i = k = c = s = 0;
313     if ( nSizeC0 == 0 ) goto FlushCut1;
314     if ( nSizeC1 == 0 ) goto FlushCut0;
315     while ( 1 )
316     {
317         if ( c == nLimit ) return 0;
318         if ( pC0->pLeaves[i] < pC1->pLeaves[k] )
319         {
320             pC->pLeaves[c++] = pC0->pLeaves[i++];
321             if ( i == nSizeC0 ) goto FlushCut1;
322         }
323         else if ( pC0->pLeaves[i] > pC1->pLeaves[k] )
324         {
325             pC->pLeaves[c++] = pC1->pLeaves[k++];
326             if ( k == nSizeC1 ) goto FlushCut0;
327         }
328         else
329         {
330             pC->pLeaves[c++] = pC0->pLeaves[i++]; k++;
331             if ( i == nSizeC0 ) goto FlushCut1;
332             if ( k == nSizeC1 ) goto FlushCut0;
333         }
334     }
335 
336 FlushCut0:
337     if ( c + nSizeC0 > nLimit + i ) return 0;
338     while ( i < nSizeC0 )
339         pC->pLeaves[c++] = pC0->pLeaves[i++];
340     pC->nLeaves = c;
341     pC->uSign = pC0->uSign | pC1->uSign;
342     return 1;
343 
344 FlushCut1:
345     if ( c + nSizeC1 > nLimit + k ) return 0;
346     while ( k < nSizeC1 )
347         pC->pLeaves[c++] = pC1->pLeaves[k++];
348     pC->nLeaves = c;
349     pC->uSign = pC0->uSign | pC1->uSign;
350     return 1;
351 }
352 
353 /**Function*************************************************************
354 
355   Synopsis    [Prepares the object for FPGA mapping.]
356 
357   Description []
358 
359   SideEffects []
360 
361   SeeAlso     []
362 
363 ***********************************************************************/
If_CutMerge(If_Man_t * p,If_Cut_t * pCut0,If_Cut_t * pCut1,If_Cut_t * pCut)364 int If_CutMerge( If_Man_t * p, If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * pCut )
365 {
366     int nLutSize = pCut0->nLimit;
367     int nSize0 = pCut0->nLeaves;
368     int nSize1 = pCut1->nLeaves;
369     int * pC0 = pCut0->pLeaves;
370     int * pC1 = pCut1->pLeaves;
371     int * pC = pCut->pLeaves;
372     int i, k, c;
373     // compare two cuts with different numbers
374     c = nSize0;
375     for ( i = 0; i < nSize1; i++ )
376     {
377         for ( k = 0; k < nSize0; k++ )
378             if ( pC1[i] == pC0[k] )
379                 break;
380         if ( k < nSize0 )
381         {
382             p->pPerm[1][i] = k;
383             continue;
384         }
385         if ( c == nLutSize )
386             return 0;
387         p->pPerm[1][i] = c;
388         pC[c++] = pC1[i];
389     }
390     for ( i = 0; i < nSize0; i++ )
391         pC[i] = pC0[i];
392     pCut->nLeaves = c;
393     pCut->uSign = pCut0->uSign | pCut1->uSign;
394     return 1;
395 }
396 
397 /**Function*************************************************************
398 
399   Synopsis    [Prepares the object for FPGA mapping.]
400 
401   Description []
402 
403   SideEffects []
404 
405   SeeAlso     []
406 
407 ***********************************************************************/
If_CutCompareDelay(If_Man_t * p,If_Cut_t ** ppC0,If_Cut_t ** ppC1)408 int If_CutCompareDelay( If_Man_t * p, If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
409 {
410     If_Cut_t * pC0 = *ppC0;
411     If_Cut_t * pC1 = *ppC1;
412     if ( pC0->Delay < pC1->Delay - p->fEpsilon )
413         return -1;
414     if ( pC0->Delay > pC1->Delay + p->fEpsilon )
415         return 1;
416     if ( pC0->nLeaves < pC1->nLeaves )
417         return -1;
418     if ( pC0->nLeaves > pC1->nLeaves )
419         return 1;
420     if ( pC0->Area < pC1->Area - p->fEpsilon )
421         return -1;
422     if ( pC0->Area > pC1->Area + p->fEpsilon )
423         return 1;
424     return 0;
425 }
426 
427 /**Function*************************************************************
428 
429   Synopsis    [Prepares the object for FPGA mapping.]
430 
431   Description []
432 
433   SideEffects []
434 
435   SeeAlso     []
436 
437 ***********************************************************************/
If_CutCompareDelayOld(If_Man_t * p,If_Cut_t ** ppC0,If_Cut_t ** ppC1)438 int If_CutCompareDelayOld( If_Man_t * p, If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
439 {
440     If_Cut_t * pC0 = *ppC0;
441     If_Cut_t * pC1 = *ppC1;
442     if ( pC0->Delay < pC1->Delay - p->fEpsilon )
443         return -1;
444     if ( pC0->Delay > pC1->Delay + p->fEpsilon )
445         return 1;
446     if ( pC0->Area < pC1->Area - p->fEpsilon )
447         return -1;
448     if ( pC0->Area > pC1->Area + p->fEpsilon )
449         return 1;
450     if ( pC0->nLeaves < pC1->nLeaves )
451         return -1;
452     if ( pC0->nLeaves > pC1->nLeaves )
453         return 1;
454     return 0;
455 }
456 
457 /**Function*************************************************************
458 
459   Synopsis    [Prepares the object for FPGA mapping.]
460 
461   Description []
462 
463   SideEffects []
464 
465   SeeAlso     []
466 
467 ***********************************************************************/
If_CutCompareArea(If_Man_t * p,If_Cut_t ** ppC0,If_Cut_t ** ppC1)468 int If_CutCompareArea( If_Man_t * p, If_Cut_t ** ppC0, If_Cut_t ** ppC1 )
469 {
470     If_Cut_t * pC0 = *ppC0;
471     If_Cut_t * pC1 = *ppC1;
472     if ( pC0->Area < pC1->Area - p->fEpsilon )
473         return -1;
474     if ( pC0->Area > pC1->Area + p->fEpsilon )
475         return 1;
476 //    if ( pC0->AveRefs > pC1->AveRefs )
477 //        return -1;
478 //    if ( pC0->AveRefs < pC1->AveRefs )
479 //        return 1;
480     if ( pC0->nLeaves < pC1->nLeaves )
481         return -1;
482     if ( pC0->nLeaves > pC1->nLeaves )
483         return 1;
484     if ( pC0->Delay < pC1->Delay - p->fEpsilon )
485         return -1;
486     if ( pC0->Delay > pC1->Delay + p->fEpsilon )
487         return 1;
488     return 0;
489 }
490 
491 /**Function*************************************************************
492 
493   Synopsis    [Comparison function for two cuts.]
494 
495   Description []
496 
497   SideEffects []
498 
499   SeeAlso     []
500 
501 ***********************************************************************/
If_ManSortCompare(If_Man_t * p,If_Cut_t * pC0,If_Cut_t * pC1)502 static inline int If_ManSortCompare( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1 )
503 {
504     if ( p->pPars->fPower )
505     {
506         if ( p->SortMode == 1 ) // area flow
507         {
508             if ( pC0->Area < pC1->Area - p->fEpsilon )
509                 return -1;
510             if ( pC0->Area > pC1->Area + p->fEpsilon )
511                 return 1;
512             //Abc_Print( 1,"area(%.2f, %.2f), power(%.2f, %.2f), edge(%.2f, %.2f)\n",
513             //         pC0->Area, pC1->Area, pC0->Power, pC1->Power, pC0->Edge, pC1->Edge);
514             if ( pC0->Power < pC1->Power - p->fEpsilon )
515                 return -1;
516             if ( pC0->Power > pC1->Power + p->fEpsilon )
517                 return 1;
518             if ( pC0->Edge < pC1->Edge - p->fEpsilon )
519                 return -1;
520             if ( pC0->Edge > pC1->Edge + p->fEpsilon )
521                 return 1;
522 //            if ( pC0->AveRefs > pC1->AveRefs )
523 //                return -1;
524 //            if ( pC0->AveRefs < pC1->AveRefs )
525 //                return 1;
526             if ( pC0->nLeaves < pC1->nLeaves )
527                 return -1;
528             if ( pC0->nLeaves > pC1->nLeaves )
529                 return 1;
530             if ( pC0->Delay < pC1->Delay - p->fEpsilon )
531                 return -1;
532             if ( pC0->Delay > pC1->Delay + p->fEpsilon )
533                 return 1;
534             return 0;
535         }
536         if ( p->SortMode == 0 ) // delay
537         {
538             if ( pC0->Delay < pC1->Delay - p->fEpsilon )
539                 return -1;
540             if ( pC0->Delay > pC1->Delay + p->fEpsilon )
541                 return 1;
542             if ( pC0->nLeaves < pC1->nLeaves )
543                 return -1;
544             if ( pC0->nLeaves > pC1->nLeaves )
545                 return 1;
546             if ( pC0->Area < pC1->Area - p->fEpsilon )
547                 return -1;
548             if ( pC0->Area > pC1->Area + p->fEpsilon )
549                 return 1;
550             if ( pC0->Power < pC1->Power - p->fEpsilon  )
551                 return -1;
552             if ( pC0->Power > pC1->Power + p->fEpsilon  )
553                 return 1;
554             if ( pC0->Edge < pC1->Edge - p->fEpsilon )
555                 return -1;
556             if ( pC0->Edge > pC1->Edge + p->fEpsilon )
557                 return 1;
558             return 0;
559         }
560         assert( p->SortMode == 2 ); // delay old, exact area
561         if ( pC0->Delay < pC1->Delay - p->fEpsilon )
562             return -1;
563         if ( pC0->Delay > pC1->Delay + p->fEpsilon )
564             return 1;
565         if ( pC0->Power < pC1->Power - p->fEpsilon  )
566             return -1;
567         if ( pC0->Power > pC1->Power + p->fEpsilon  )
568             return 1;
569         if ( pC0->Edge < pC1->Edge - p->fEpsilon )
570             return -1;
571         if ( pC0->Edge > pC1->Edge + p->fEpsilon )
572             return 1;
573         if ( pC0->Area < pC1->Area - p->fEpsilon )
574             return -1;
575         if ( pC0->Area > pC1->Area + p->fEpsilon )
576             return 1;
577         if ( pC0->nLeaves < pC1->nLeaves )
578             return -1;
579         if ( pC0->nLeaves > pC1->nLeaves )
580             return 1;
581         return 0;
582     }
583     else  // regular
584     {
585         if ( p->SortMode == 1 ) // area
586         {
587             if ( pC0->Area < pC1->Area - p->fEpsilon )
588                 return -1;
589             if ( pC0->Area > pC1->Area + p->fEpsilon )
590                 return 1;
591             if ( pC0->Edge < pC1->Edge - p->fEpsilon )
592                 return -1;
593             if ( pC0->Edge > pC1->Edge + p->fEpsilon )
594                 return 1;
595             if ( pC0->Power < pC1->Power - p->fEpsilon )
596                 return -1;
597             if ( pC0->Power > pC1->Power + p->fEpsilon )
598                 return 1;
599 //            if ( pC0->AveRefs > pC1->AveRefs )
600 //                return -1;
601 //            if ( pC0->AveRefs < pC1->AveRefs )
602 //                return 1;
603             if ( pC0->nLeaves < pC1->nLeaves )
604                 return -1;
605             if ( pC0->nLeaves > pC1->nLeaves )
606                 return 1;
607             if ( pC0->Delay < pC1->Delay - p->fEpsilon )
608                 return -1;
609             if ( pC0->Delay > pC1->Delay + p->fEpsilon )
610                 return 1;
611             return 0;
612         }
613         if ( p->SortMode == 0 ) // delay
614         {
615             if ( pC0->Delay < pC1->Delay - p->fEpsilon )
616                 return -1;
617             if ( pC0->Delay > pC1->Delay + p->fEpsilon )
618                 return 1;
619             if ( pC0->nLeaves < pC1->nLeaves )
620                 return -1;
621             if ( pC0->nLeaves > pC1->nLeaves )
622                 return 1;
623             if ( pC0->Area < pC1->Area - p->fEpsilon )
624                 return -1;
625             if ( pC0->Area > pC1->Area + p->fEpsilon )
626                 return 1;
627             if ( pC0->Edge < pC1->Edge - p->fEpsilon )
628                 return -1;
629             if ( pC0->Edge > pC1->Edge + p->fEpsilon )
630                 return 1;
631             if ( pC0->Power < pC1->Power - p->fEpsilon )
632                 return -1;
633             if ( pC0->Power > pC1->Power + p->fEpsilon )
634                 return 1;
635             return 0;
636         }
637         assert( p->SortMode == 2 ); // delay old
638         if ( pC0->Delay < pC1->Delay - p->fEpsilon )
639             return -1;
640         if ( pC0->Delay > pC1->Delay + p->fEpsilon )
641             return 1;
642         if ( pC0->Area < pC1->Area - p->fEpsilon )
643             return -1;
644         if ( pC0->Area > pC1->Area + p->fEpsilon )
645             return 1;
646         if ( pC0->Edge < pC1->Edge - p->fEpsilon )
647             return -1;
648         if ( pC0->Edge > pC1->Edge + p->fEpsilon )
649             return 1;
650         if ( pC0->Power < pC1->Power - p->fEpsilon )
651             return -1;
652         if ( pC0->Power > pC1->Power + p->fEpsilon )
653             return 1;
654         if ( pC0->nLeaves < pC1->nLeaves )
655             return -1;
656         if ( pC0->nLeaves > pC1->nLeaves )
657             return 1;
658         return 0;
659     }
660 }
661 
662 /**Function*************************************************************
663 
664   Synopsis    [Comparison function for two cuts.]
665 
666   Description []
667 
668   SideEffects []
669 
670   SeeAlso     []
671 
672 ***********************************************************************/
If_ManSortCompare_old(If_Man_t * p,If_Cut_t * pC0,If_Cut_t * pC1)673 static inline int If_ManSortCompare_old( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1 )
674 {
675     if ( p->SortMode == 1 ) // area
676     {
677         if ( pC0->Area < pC1->Area - p->fEpsilon )
678             return -1;
679         if ( pC0->Area > pC1->Area + p->fEpsilon )
680             return 1;
681 //        if ( pC0->AveRefs > pC1->AveRefs )
682 //            return -1;
683 //        if ( pC0->AveRefs < pC1->AveRefs )
684 //            return 1;
685         if ( pC0->nLeaves < pC1->nLeaves )
686             return -1;
687         if ( pC0->nLeaves > pC1->nLeaves )
688             return 1;
689         if ( pC0->Delay < pC1->Delay - p->fEpsilon )
690             return -1;
691         if ( pC0->Delay > pC1->Delay + p->fEpsilon )
692             return 1;
693         return 0;
694     }
695     if ( p->SortMode == 0 ) // delay
696     {
697         if ( pC0->Delay < pC1->Delay - p->fEpsilon )
698             return -1;
699         if ( pC0->Delay > pC1->Delay + p->fEpsilon )
700             return 1;
701         if ( pC0->nLeaves < pC1->nLeaves )
702             return -1;
703         if ( pC0->nLeaves > pC1->nLeaves )
704             return 1;
705         if ( pC0->Area < pC1->Area - p->fEpsilon )
706             return -1;
707         if ( pC0->Area > pC1->Area + p->fEpsilon )
708             return 1;
709         return 0;
710     }
711     assert( p->SortMode == 2 ); // delay old
712     if ( pC0->Delay < pC1->Delay - p->fEpsilon )
713         return -1;
714     if ( pC0->Delay > pC1->Delay + p->fEpsilon )
715         return 1;
716     if ( pC0->Area < pC1->Area - p->fEpsilon )
717         return -1;
718     if ( pC0->Area > pC1->Area + p->fEpsilon )
719         return 1;
720     if ( pC0->nLeaves < pC1->nLeaves )
721         return -1;
722     if ( pC0->nLeaves > pC1->nLeaves )
723         return 1;
724     return 0;
725 }
726 
727 /**Function*************************************************************
728 
729   Synopsis    [Performs incremental sorting of cuts.]
730 
731   Description [Currently only the trivial sorting is implemented.]
732 
733   SideEffects []
734 
735   SeeAlso     []
736 
737 ***********************************************************************/
If_CutSort(If_Man_t * p,If_Set_t * pCutSet,If_Cut_t * pCut)738 void If_CutSort( If_Man_t * p, If_Set_t * pCutSet, If_Cut_t * pCut )
739 {
740 //    int Counter = 0;
741     int i;
742 
743     // the new cut is the last one
744     assert( pCutSet->ppCuts[pCutSet->nCuts] == pCut );
745     assert( pCutSet->nCuts <= pCutSet->nCutsMax );
746 
747     // cut structure is empty
748     if ( pCutSet->nCuts == 0 )
749     {
750         pCutSet->nCuts++;
751         return;
752     }
753 
754     if ( !pCut->fUseless &&
755          (p->pPars->fUseDsd || p->pPars->pFuncCell2 || p->pPars->fUseBat ||
756           p->pPars->pLutStruct || p->pPars->fUserRecLib || p->pPars->fUserSesLib ||
757           p->pPars->fEnableCheck07 || p->pPars->fUseCofVars || p->pPars->fUseAndVars || p->pPars->fUse34Spec ||
758           p->pPars->fUseDsdTune || p->pPars->fEnableCheck75 || p->pPars->fEnableCheck75u) )
759     {
760         If_Cut_t * pFirst = pCutSet->ppCuts[0];
761         if ( pFirst->fUseless || If_ManSortCompare(p, pFirst, pCut) == 1 )
762         {
763             pCutSet->ppCuts[0] = pCut;
764             pCutSet->ppCuts[pCutSet->nCuts] = pFirst;
765             If_CutSort( p, pCutSet, pFirst );
766             return;
767         }
768     }
769 
770     // the cut will be added - find its place
771     for ( i = pCutSet->nCuts-1; i >= 0; i-- )
772     {
773 //        Counter++;
774         if ( If_ManSortCompare( p, pCutSet->ppCuts[i], pCut ) <= 0 || (i == 0 && !pCutSet->ppCuts[0]->fUseless && pCut->fUseless) )
775             break;
776         pCutSet->ppCuts[i+1] = pCutSet->ppCuts[i];
777         pCutSet->ppCuts[i] = pCut;
778     }
779 //    Abc_Print( 1, "%d ", Counter );
780 
781     // update the number of cuts
782     if ( pCutSet->nCuts < pCutSet->nCutsMax )
783         pCutSet->nCuts++;
784 }
785 
786 /**Function*************************************************************
787 
788   Synopsis    [Orders the leaves of the cut.]
789 
790   Description []
791 
792   SideEffects []
793 
794   SeeAlso     []
795 
796 ***********************************************************************/
If_CutOrder(If_Cut_t * pCut)797 void If_CutOrder( If_Cut_t * pCut )
798 {
799     int i, Temp, fChanges;
800     do {
801         fChanges = 0;
802         for ( i = 0; i < (int)pCut->nLeaves - 1; i++ )
803         {
804             assert( pCut->pLeaves[i] != pCut->pLeaves[i+1] );
805             if ( pCut->pLeaves[i] <= pCut->pLeaves[i+1] )
806                 continue;
807             Temp = pCut->pLeaves[i];
808             pCut->pLeaves[i] = pCut->pLeaves[i+1];
809             pCut->pLeaves[i+1] = Temp;
810             fChanges = 1;
811         }
812     } while ( fChanges );
813 }
814 
815 /**Function*************************************************************
816 
817   Synopsis    [Checks correctness of the cut.]
818 
819   Description []
820 
821   SideEffects []
822 
823   SeeAlso     []
824 
825 ***********************************************************************/
If_CutCheck(If_Cut_t * pCut)826 int If_CutCheck( If_Cut_t * pCut )
827 {
828     int i;
829     assert( pCut->nLeaves <= pCut->nLimit );
830     if ( pCut->nLeaves < 2 )
831         return 1;
832     for ( i = 1; i < (int)pCut->nLeaves; i++ )
833     {
834         if ( pCut->pLeaves[i-1] >= pCut->pLeaves[i] )
835         {
836             Abc_Print( -1, "If_CutCheck(): Cut has wrong ordering of inputs.\n" );
837             return 0;
838         }
839         assert( pCut->pLeaves[i-1] < pCut->pLeaves[i] );
840     }
841     return 1;
842 }
843 
844 
845 /**Function*************************************************************
846 
847   Synopsis    [Prints one cut.]
848 
849   Description []
850 
851   SideEffects []
852 
853   SeeAlso     []
854 
855 ***********************************************************************/
If_CutPrint(If_Cut_t * pCut)856 void If_CutPrint( If_Cut_t * pCut )
857 {
858     unsigned i;
859     Abc_Print( 1, "{" );
860     for ( i = 0; i < pCut->nLeaves; i++ )
861         Abc_Print( 1, " %s%d", If_CutLeafBit(pCut, i) ? "!":"", pCut->pLeaves[i] );
862     Abc_Print( 1, " }\n" );
863 }
864 
865 /**Function*************************************************************
866 
867   Synopsis    [Prints one cut.]
868 
869   Description []
870 
871   SideEffects []
872 
873   SeeAlso     []
874 
875 ***********************************************************************/
If_CutPrintTiming(If_Man_t * p,If_Cut_t * pCut)876 void If_CutPrintTiming( If_Man_t * p, If_Cut_t * pCut )
877 {
878     If_Obj_t * pLeaf;
879     unsigned i;
880     Abc_Print( 1, "{" );
881     If_CutForEachLeaf( p, pCut, pLeaf, i )
882         Abc_Print( 1, " %d(%.2f/%.2f)", pLeaf->Id, If_ObjCutBest(pLeaf)->Delay, pLeaf->Required );
883     Abc_Print( 1, " }\n" );
884 }
885 
886 /**Function*************************************************************
887 
888   Synopsis    [Moves the cut over the latch.]
889 
890   Description []
891 
892   SideEffects []
893 
894   SeeAlso     []
895 
896 ***********************************************************************/
If_CutLift(If_Cut_t * pCut)897 void If_CutLift( If_Cut_t * pCut )
898 {
899     unsigned i;
900     for ( i = 0; i < pCut->nLeaves; i++ )
901     {
902         assert( (pCut->pLeaves[i] & 255) < 255 );
903         pCut->pLeaves[i]++;
904     }
905 }
906 
907 
908 /**Function*************************************************************
909 
910   Synopsis    [Computes area flow.]
911 
912   Description []
913 
914   SideEffects []
915 
916   SeeAlso     []
917 
918 ***********************************************************************/
If_CutAreaFlow(If_Man_t * p,If_Cut_t * pCut)919 float If_CutAreaFlow( If_Man_t * p, If_Cut_t * pCut )
920 {
921     If_Obj_t * pLeaf;
922     float Flow, AddOn;
923     int i;
924     Flow = If_CutLutArea(p, pCut);
925     If_CutForEachLeaf( p, pCut, pLeaf, i )
926     {
927         if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) )
928             AddOn = If_ObjCutBest(pLeaf)->Area;
929         else
930         {
931             assert( pLeaf->EstRefs > p->fEpsilon );
932             AddOn = If_ObjCutBest(pLeaf)->Area / pLeaf->EstRefs;
933         }
934         if ( Flow >= (float)1e32 || AddOn >= (float)1e32 )
935             Flow = (float)1e32;
936         else
937         {
938             Flow += AddOn;
939             if ( Flow > (float)1e32 )
940                  Flow = (float)1e32;
941         }
942     }
943     return Flow;
944 }
945 
946 /**Function*************************************************************
947 
948   Synopsis    [Computes area flow.]
949 
950   Description []
951 
952   SideEffects []
953 
954   SeeAlso     []
955 
956 ***********************************************************************/
If_CutEdgeFlow(If_Man_t * p,If_Cut_t * pCut)957 float If_CutEdgeFlow( If_Man_t * p, If_Cut_t * pCut )
958 {
959     If_Obj_t * pLeaf;
960     float Flow, AddOn;
961     int i;
962     Flow = pCut->nLeaves;
963     If_CutForEachLeaf( p, pCut, pLeaf, i )
964     {
965         if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) )
966             AddOn = If_ObjCutBest(pLeaf)->Edge;
967         else
968         {
969             assert( pLeaf->EstRefs > p->fEpsilon );
970             AddOn = If_ObjCutBest(pLeaf)->Edge / pLeaf->EstRefs;
971         }
972         if ( Flow >= (float)1e32 || AddOn >= (float)1e32 )
973             Flow = (float)1e32;
974         else
975         {
976             Flow += AddOn;
977             if ( Flow > (float)1e32 )
978                  Flow = (float)1e32;
979         }
980     }
981     return Flow;
982 }
983 
984 /**Function*************************************************************
985 
986   Synopsis    [Computes area flow.]
987 
988   Description []
989 
990   SideEffects []
991 
992   SeeAlso     []
993 
994 ***********************************************************************/
If_CutPowerFlow(If_Man_t * p,If_Cut_t * pCut,If_Obj_t * pRoot)995 float If_CutPowerFlow( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot )
996 {
997     If_Obj_t * pLeaf;
998     float * pSwitching = (float *)p->vSwitching->pArray;
999     float Power = 0;
1000     int i;
1001     If_CutForEachLeaf( p, pCut, pLeaf, i )
1002     {
1003         Power += pSwitching[pLeaf->Id];
1004         if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) )
1005             Power += If_ObjCutBest(pLeaf)->Power;
1006         else
1007         {
1008             assert( pLeaf->EstRefs > p->fEpsilon );
1009             Power += If_ObjCutBest(pLeaf)->Power / pLeaf->EstRefs;
1010         }
1011     }
1012     return Power;
1013 }
1014 
1015 /**Function*************************************************************
1016 
1017   Synopsis    [Average number of references of the leaves.]
1018 
1019   Description []
1020 
1021   SideEffects []
1022 
1023   SeeAlso     []
1024 
1025 ***********************************************************************/
If_CutAverageRefs(If_Man_t * p,If_Cut_t * pCut)1026 float If_CutAverageRefs( If_Man_t * p, If_Cut_t * pCut )
1027 {
1028     If_Obj_t * pLeaf;
1029     int nRefsTotal, i;
1030     nRefsTotal = 0;
1031     If_CutForEachLeaf( p, pCut, pLeaf, i )
1032         nRefsTotal += pLeaf->nRefs;
1033     return ((float)nRefsTotal)/pCut->nLeaves;
1034 }
1035 
1036 
1037 /**Function*************************************************************
1038 
1039   Synopsis    [Computes area of the first level.]
1040 
1041   Description [The cut need to be derefed.]
1042 
1043   SideEffects []
1044 
1045   SeeAlso     []
1046 
1047 ***********************************************************************/
If_CutAreaDeref(If_Man_t * p,If_Cut_t * pCut)1048 float If_CutAreaDeref( If_Man_t * p, If_Cut_t * pCut )
1049 {
1050     If_Obj_t * pLeaf;
1051     float Area;
1052     int i;
1053     Area = If_CutLutArea(p, pCut);
1054     If_CutForEachLeaf( p, pCut, pLeaf, i )
1055     {
1056         assert( pLeaf->nRefs > 0 );
1057         if ( --pLeaf->nRefs > 0 || !If_ObjIsAnd(pLeaf) )
1058             continue;
1059         Area += If_CutAreaDeref( p, If_ObjCutBest(pLeaf) );
1060     }
1061     return Area;
1062 }
1063 
1064 /**Function*************************************************************
1065 
1066   Synopsis    [Computes area of the first level.]
1067 
1068   Description [The cut need to be derefed.]
1069 
1070   SideEffects []
1071 
1072   SeeAlso     []
1073 
1074 ***********************************************************************/
If_CutAreaRef(If_Man_t * p,If_Cut_t * pCut)1075 float If_CutAreaRef( If_Man_t * p, If_Cut_t * pCut )
1076 {
1077     If_Obj_t * pLeaf;
1078     float Area;
1079     int i;
1080     Area = If_CutLutArea(p, pCut);
1081     If_CutForEachLeaf( p, pCut, pLeaf, i )
1082     {
1083         assert( pLeaf->nRefs >= 0 );
1084         if ( pLeaf->nRefs++ > 0 || !If_ObjIsAnd(pLeaf) )
1085             continue;
1086         Area += If_CutAreaRef( p, If_ObjCutBest(pLeaf) );
1087     }
1088     return Area;
1089 }
1090 
1091 /**Function*************************************************************
1092 
1093   Synopsis    [Computes area of the first level.]
1094 
1095   Description [The cut need to be derefed.]
1096 
1097   SideEffects []
1098 
1099   SeeAlso     []
1100 
1101 ***********************************************************************/
If_CutAreaDerefed(If_Man_t * p,If_Cut_t * pCut)1102 float If_CutAreaDerefed( If_Man_t * p, If_Cut_t * pCut )
1103 {
1104     float aResult, aResult2;
1105     if ( pCut->nLeaves < 2 )
1106         return 0;
1107     aResult2 = If_CutAreaRef( p, pCut );
1108     aResult  = If_CutAreaDeref( p, pCut );
1109     assert( aResult > aResult2 - 3*p->fEpsilon );
1110     assert( aResult < aResult2 + 3*p->fEpsilon );
1111     return aResult;
1112 }
1113 
1114 /**Function*************************************************************
1115 
1116   Synopsis    [Computes area of the first level.]
1117 
1118   Description [The cut need to be derefed.]
1119 
1120   SideEffects []
1121 
1122   SeeAlso     []
1123 
1124 ***********************************************************************/
If_CutAreaRefed(If_Man_t * p,If_Cut_t * pCut)1125 float If_CutAreaRefed( If_Man_t * p, If_Cut_t * pCut )
1126 {
1127     float aResult, aResult2;
1128     if ( pCut->nLeaves < 2 )
1129         return 0;
1130     aResult2 = If_CutAreaDeref( p, pCut );
1131     aResult  = If_CutAreaRef( p, pCut );
1132     assert( aResult > aResult2 - p->fEpsilon );
1133     assert( aResult < aResult2 + p->fEpsilon );
1134     return aResult;
1135 }
1136 
1137 
1138 /**Function*************************************************************
1139 
1140   Synopsis    [Computes area of the first level.]
1141 
1142   Description [The cut need to be derefed.]
1143 
1144   SideEffects []
1145 
1146   SeeAlso     []
1147 
1148 ***********************************************************************/
If_CutEdgeDeref(If_Man_t * p,If_Cut_t * pCut)1149 float If_CutEdgeDeref( If_Man_t * p, If_Cut_t * pCut )
1150 {
1151     If_Obj_t * pLeaf;
1152     float Edge;
1153     int i;
1154     Edge = pCut->nLeaves;
1155     If_CutForEachLeaf( p, pCut, pLeaf, i )
1156     {
1157         assert( pLeaf->nRefs > 0 );
1158         if ( --pLeaf->nRefs > 0 || !If_ObjIsAnd(pLeaf) )
1159             continue;
1160         Edge += If_CutEdgeDeref( p, If_ObjCutBest(pLeaf) );
1161     }
1162     return Edge;
1163 }
1164 
1165 /**Function*************************************************************
1166 
1167   Synopsis    [Computes area of the first level.]
1168 
1169   Description [The cut need to be derefed.]
1170 
1171   SideEffects []
1172 
1173   SeeAlso     []
1174 
1175 ***********************************************************************/
If_CutEdgeRef(If_Man_t * p,If_Cut_t * pCut)1176 float If_CutEdgeRef( If_Man_t * p, If_Cut_t * pCut )
1177 {
1178     If_Obj_t * pLeaf;
1179     float Edge;
1180     int i;
1181     Edge = pCut->nLeaves;
1182     If_CutForEachLeaf( p, pCut, pLeaf, i )
1183     {
1184         assert( pLeaf->nRefs >= 0 );
1185         if ( pLeaf->nRefs++ > 0 || !If_ObjIsAnd(pLeaf) )
1186             continue;
1187         Edge += If_CutEdgeRef( p, If_ObjCutBest(pLeaf) );
1188     }
1189     return Edge;
1190 }
1191 
1192 /**Function*************************************************************
1193 
1194   Synopsis    [Computes edge of the first level.]
1195 
1196   Description [The cut need to be derefed.]
1197 
1198   SideEffects []
1199 
1200   SeeAlso     []
1201 
1202 ***********************************************************************/
If_CutEdgeDerefed(If_Man_t * p,If_Cut_t * pCut)1203 float If_CutEdgeDerefed( If_Man_t * p, If_Cut_t * pCut )
1204 {
1205     float aResult, aResult2;
1206     if ( pCut->nLeaves < 2 )
1207         return pCut->nLeaves;
1208     aResult2 = If_CutEdgeRef( p, pCut );
1209     aResult  = If_CutEdgeDeref( p, pCut );
1210     assert( aResult > aResult2 - 3*p->fEpsilon );
1211     assert( aResult < aResult2 + 3*p->fEpsilon );
1212     return aResult;
1213 }
1214 
1215 /**Function*************************************************************
1216 
1217   Synopsis    [Computes area of the first level.]
1218 
1219   Description [The cut need to be derefed.]
1220 
1221   SideEffects []
1222 
1223   SeeAlso     []
1224 
1225 ***********************************************************************/
If_CutEdgeRefed(If_Man_t * p,If_Cut_t * pCut)1226 float If_CutEdgeRefed( If_Man_t * p, If_Cut_t * pCut )
1227 {
1228     float aResult, aResult2;
1229     if ( pCut->nLeaves < 2 )
1230         return pCut->nLeaves;
1231     aResult2 = If_CutEdgeDeref( p, pCut );
1232     aResult  = If_CutEdgeRef( p, pCut );
1233     assert( aResult > aResult2 - p->fEpsilon );
1234     assert( aResult < aResult2 + p->fEpsilon );
1235     return aResult;
1236 }
1237 
1238 
1239 /**Function*************************************************************
1240 
1241   Synopsis    [Computes area of the first level.]
1242 
1243   Description [The cut need to be derefed.]
1244 
1245   SideEffects []
1246 
1247   SeeAlso     []
1248 
1249 ***********************************************************************/
If_CutPowerDeref(If_Man_t * p,If_Cut_t * pCut,If_Obj_t * pRoot)1250 float If_CutPowerDeref( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot )
1251 {
1252     If_Obj_t * pLeaf;
1253     float * pSwitching = (float *)p->vSwitching->pArray;
1254     float Power = 0;
1255     int i;
1256     If_CutForEachLeaf( p, pCut, pLeaf, i )
1257     {
1258         Power += pSwitching[pLeaf->Id];
1259         assert( pLeaf->nRefs > 0 );
1260         if ( --pLeaf->nRefs > 0 || !If_ObjIsAnd(pLeaf) )
1261             continue;
1262         Power += If_CutPowerDeref( p, If_ObjCutBest(pLeaf), pRoot );
1263     }
1264     return Power;
1265 }
1266 
1267 /**Function*************************************************************
1268 
1269   Synopsis    [Computes area of the first level.]
1270 
1271   Description [The cut need to be derefed.]
1272 
1273   SideEffects []
1274 
1275   SeeAlso     []
1276 
1277 ***********************************************************************/
If_CutPowerRef(If_Man_t * p,If_Cut_t * pCut,If_Obj_t * pRoot)1278 float If_CutPowerRef( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot )
1279 {
1280     If_Obj_t * pLeaf;
1281     float * pSwitching = (float *)p->vSwitching->pArray;
1282     float Power = 0;
1283     int i;
1284     If_CutForEachLeaf( p, pCut, pLeaf, i )
1285     {
1286         Power += pSwitching[pLeaf->Id];
1287         assert( pLeaf->nRefs >= 0 );
1288         if ( pLeaf->nRefs++ > 0 || !If_ObjIsAnd(pLeaf) )
1289             continue;
1290         Power += If_CutPowerRef( p, If_ObjCutBest(pLeaf), pRoot );
1291     }
1292     return Power;
1293 }
1294 
1295 /**Function*************************************************************
1296 
1297   Synopsis    [Computes Power of the first level.]
1298 
1299   Description [The cut need to be derefed.]
1300 
1301   SideEffects []
1302 
1303   SeeAlso     []
1304 
1305 ***********************************************************************/
If_CutPowerDerefed(If_Man_t * p,If_Cut_t * pCut,If_Obj_t * pRoot)1306 float If_CutPowerDerefed( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot )
1307 {
1308     float aResult, aResult2;
1309     if ( pCut->nLeaves < 2 )
1310         return 0;
1311     aResult2 = If_CutPowerRef( p, pCut, pRoot );
1312     aResult  = If_CutPowerDeref( p, pCut, pRoot );
1313     assert( aResult > aResult2 - p->fEpsilon );
1314     assert( aResult < aResult2 + p->fEpsilon );
1315     return aResult;
1316 }
1317 
1318 /**Function*************************************************************
1319 
1320   Synopsis    [Computes area of the first level.]
1321 
1322   Description [The cut need to be derefed.]
1323 
1324   SideEffects []
1325 
1326   SeeAlso     []
1327 
1328 ***********************************************************************/
If_CutPowerRefed(If_Man_t * p,If_Cut_t * pCut,If_Obj_t * pRoot)1329 float If_CutPowerRefed( If_Man_t * p, If_Cut_t * pCut, If_Obj_t * pRoot )
1330 {
1331     float aResult, aResult2;
1332     if ( pCut->nLeaves < 2 )
1333         return 0;
1334     aResult2 = If_CutPowerDeref( p, pCut, pRoot );
1335     aResult  = If_CutPowerRef( p, pCut, pRoot );
1336     assert( aResult > aResult2 - p->fEpsilon );
1337     assert( aResult < aResult2 + p->fEpsilon );
1338     return aResult;
1339 }
1340 
1341 /**Function*************************************************************
1342 
1343   Synopsis    [Computes the cone of the cut in AIG with choices.]
1344 
1345   Description []
1346 
1347   SideEffects []
1348 
1349   SeeAlso     []
1350 
1351 ***********************************************************************/
If_CutGetCutMinLevel(If_Man_t * p,If_Cut_t * pCut)1352 int If_CutGetCutMinLevel( If_Man_t * p, If_Cut_t * pCut )
1353 {
1354     If_Obj_t * pLeaf;
1355     int i, nMinLevel = IF_INFINITY;
1356     If_CutForEachLeaf( p, pCut, pLeaf, i )
1357         nMinLevel = IF_MIN( nMinLevel, (int)pLeaf->Level );
1358     return nMinLevel;
1359 }
1360 
1361 /**Function*************************************************************
1362 
1363   Synopsis    [Computes the cone of the cut in AIG with choices.]
1364 
1365   Description []
1366 
1367   SideEffects []
1368 
1369   SeeAlso     []
1370 
1371 ***********************************************************************/
If_CutGetCone_rec(If_Man_t * p,If_Obj_t * pObj,If_Cut_t * pCut)1372 int If_CutGetCone_rec( If_Man_t * p, If_Obj_t * pObj, If_Cut_t * pCut )
1373 {
1374     If_Obj_t * pTemp;
1375     int i, RetValue;
1376     // check if the node is in the cut
1377     for ( i = 0; i < (int)pCut->nLeaves; i++ )
1378         if ( pCut->pLeaves[i] == pObj->Id )
1379             return 1;
1380         else if ( pCut->pLeaves[i] > pObj->Id )
1381             break;
1382     // return if we reached the boundary
1383     if ( If_ObjIsCi(pObj) )
1384         return 0;
1385     // check the choice node
1386     for ( pTemp = pObj; pTemp; pTemp = pTemp->pEquiv )
1387     {
1388         // check if the node itself is bound
1389         RetValue = If_CutGetCone_rec( p, If_ObjFanin0(pTemp), pCut );
1390         if ( RetValue )
1391             RetValue &= If_CutGetCone_rec( p, If_ObjFanin1(pTemp), pCut );
1392         if ( RetValue )
1393             return 1;
1394     }
1395     return 0;
1396 }
1397 
1398 /**Function*************************************************************
1399 
1400   Synopsis    [Computes the cone of the cut in AIG with choices.]
1401 
1402   Description []
1403 
1404   SideEffects []
1405 
1406   SeeAlso     []
1407 
1408 ***********************************************************************/
If_CutGetCones(If_Man_t * p)1409 int If_CutGetCones( If_Man_t * p )
1410 {
1411     If_Obj_t * pObj;
1412     int i, Counter = 0;
1413     abctime clk = Abc_Clock();
1414     If_ManForEachObj( p, pObj, i )
1415     {
1416         if ( If_ObjIsAnd(pObj) && pObj->nRefs )
1417         {
1418             Counter += !If_CutGetCone_rec( p, pObj, If_ObjCutBest(pObj) );
1419 //            Abc_Print( 1, "%d ", If_CutGetCutMinLevel( p, If_ObjCutBest(pObj) ) );
1420         }
1421     }
1422     Abc_Print( 1, "Cound not find boundary for %d nodes.\n", Counter );
1423     Abc_PrintTime( 1, "Cones", Abc_Clock() - clk );
1424     return 1;
1425 }
1426 
1427 
1428 /**Function*************************************************************
1429 
1430   Synopsis    [Computes the cone of the cut in AIG with choices.]
1431 
1432   Description []
1433 
1434   SideEffects []
1435 
1436   SeeAlso     []
1437 
1438 ***********************************************************************/
If_CutFoundFanins_rec(If_Obj_t * pObj,Vec_Int_t * vLeaves)1439 void If_CutFoundFanins_rec( If_Obj_t * pObj, Vec_Int_t * vLeaves )
1440 {
1441     if ( pObj->nRefs || If_ObjIsCi(pObj) )
1442     {
1443         Vec_IntPushUnique( vLeaves, pObj->Id );
1444         return;
1445     }
1446     If_CutFoundFanins_rec( If_ObjFanin0(pObj), vLeaves );
1447     If_CutFoundFanins_rec( If_ObjFanin1(pObj), vLeaves );
1448 }
1449 
1450 /**Function*************************************************************
1451 
1452   Synopsis    [Computes the cone of the cut in AIG with choices.]
1453 
1454   Description []
1455 
1456   SideEffects []
1457 
1458   SeeAlso     []
1459 
1460 ***********************************************************************/
If_CutCountTotalFanins(If_Man_t * p)1461 int If_CutCountTotalFanins( If_Man_t * p )
1462 {
1463     If_Obj_t * pObj;
1464     Vec_Int_t * vLeaves;
1465     int i, nFaninsTotal = 0, Counter = 0;
1466     abctime clk = Abc_Clock();
1467     vLeaves = Vec_IntAlloc( 100 );
1468     If_ManForEachObj( p, pObj, i )
1469     {
1470         if ( If_ObjIsAnd(pObj) && pObj->nRefs )
1471         {
1472             nFaninsTotal += If_ObjCutBest(pObj)->nLeaves;
1473             Vec_IntClear( vLeaves );
1474             If_CutFoundFanins_rec( If_ObjFanin0(pObj), vLeaves );
1475             If_CutFoundFanins_rec( If_ObjFanin1(pObj), vLeaves );
1476             Counter += Vec_IntSize(vLeaves);
1477         }
1478     }
1479     Abc_Print( 1, "Total cut inputs = %d. Total fanins incremental = %d.\n", nFaninsTotal, Counter );
1480     Abc_PrintTime( 1, "Fanins", Abc_Clock() - clk );
1481     Vec_IntFree( vLeaves );
1482     return 1;
1483 }
1484 
1485 ////////////////////////////////////////////////////////////////////////
1486 ///                       END OF FILE                                ///
1487 ////////////////////////////////////////////////////////////////////////
1488 
1489 
1490 ABC_NAMESPACE_IMPL_END
1491 
1492