1 /**CFile****************************************************************
2 
3   FileName    [ifMan.c]
4 
5   SystemName  [ABC: Logic synthesis and verification system.]
6 
7   PackageName [FPGA mapping based on priority cuts.]
8 
9   Synopsis    [Mapping manager.]
10 
11   Author      [Alan Mishchenko]
12 
13   Affiliation [UC Berkeley]
14 
15   Date        [Ver. 1.0. Started - November 21, 2006.]
16 
17   Revision    [$Id: ifMan.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 static If_Obj_t * If_ManSetupObj( If_Man_t * p );
31 
If_ManCutSetRecycle(If_Man_t * p,If_Set_t * pSet)32 static void       If_ManCutSetRecycle( If_Man_t * p, If_Set_t * pSet ) { pSet->pNext = p->pFreeList; p->pFreeList = pSet;                            }
If_ManCutSetFetch(If_Man_t * p)33 static If_Set_t * If_ManCutSetFetch( If_Man_t * p )                    { If_Set_t * pTemp = p->pFreeList; p->pFreeList = p->pFreeList->pNext; return pTemp; }
34 
35 ////////////////////////////////////////////////////////////////////////
36 ///                     FUNCTION DEFINITIONS                         ///
37 ////////////////////////////////////////////////////////////////////////
38 
39 /**Function*************************************************************
40 
41   Synopsis    [Starts the AIG manager.]
42 
43   Description []
44 
45   SideEffects []
46 
47   SeeAlso     []
48 
49 ***********************************************************************/
If_ManStart(If_Par_t * pPars)50 If_Man_t * If_ManStart( If_Par_t * pPars )
51 {
52     If_Man_t * p; int v;
53     assert( !pPars->fUseDsd || !pPars->fUseTtPerm );
54     // start the manager
55     p = ABC_ALLOC( If_Man_t, 1 );
56     memset( p, 0, sizeof(If_Man_t) );
57     p->pPars    = pPars;
58     p->fEpsilon = pPars->Epsilon;
59     // allocate arrays for nodes
60     p->vCis     = Vec_PtrAlloc( 100 );
61     p->vCos     = Vec_PtrAlloc( 100 );
62     p->vObjs    = Vec_PtrAlloc( 100 );
63     p->vTemp    = Vec_PtrAlloc( 100 );
64     p->vVisited = Vec_PtrAlloc( 100 );
65     // prepare the memory manager
66     if ( p->pPars->fTruth )
67     {
68         for ( v = 0; v <= p->pPars->nLutSize; v++ )
69             p->nTruth6Words[v] = Abc_Truth6WordNum( v );
70         for ( v = 6; v <= Abc_MaxInt(6,p->pPars->nLutSize); v++ )
71             p->vTtMem[v] = Vec_MemAllocForTT( v, pPars->fUseTtPerm );
72         for ( v = 0; v < 6; v++ )
73             p->vTtMem[v] = p->vTtMem[6];
74         if ( p->pPars->fDelayOpt || pPars->nGateSize > 0 )
75         {
76             for ( v = 6; v <= Abc_MaxInt(6,p->pPars->nLutSize); v++ )
77                 p->vTtIsops[v] = Vec_WecAlloc( 1000 );
78             for ( v = 6; v <= Abc_MaxInt(6,p->pPars->nLutSize); v++ )
79                 Vec_WecInit( p->vTtIsops[v], 2 );
80             for ( v = 0; v < 6; v++ )
81                 p->vTtIsops[v] = p->vTtIsops[6];
82         }
83         if ( pPars->fDelayOpt || pPars->nGateSize > 0 || pPars->fDsdBalance )
84         {
85             p->vCover = Vec_IntAlloc( 0 );
86             p->vArray = Vec_IntAlloc( 1000 );
87         }
88     }
89     p->nPermWords  = p->pPars->fUsePerm? If_CutPermWords( p->pPars->nLutSize ) : 0;
90     p->nObjBytes   = sizeof(If_Obj_t) + sizeof(int) * (p->pPars->nLutSize + p->nPermWords);
91     p->nCutBytes   = sizeof(If_Cut_t) + sizeof(int) * (p->pPars->nLutSize + p->nPermWords);
92     p->nSetBytes   = sizeof(If_Set_t) + (sizeof(If_Cut_t *) + p->nCutBytes) * (p->pPars->nCutsMax + 1);
93     p->pMemObj     = Mem_FixedStart( p->nObjBytes );
94     // report expected memory usage
95     if ( p->pPars->fVerbose )
96         Abc_Print( 1, "K = %d. Memory (bytes): Truth = %4d. Cut = %4d. Obj = %4d. Set = %4d. CutMin = %s\n",
97             p->pPars->nLutSize, 8 * p->nTruth6Words[p->pPars->nLutSize], p->nCutBytes, p->nObjBytes, p->nSetBytes, p->pPars->fCutMin? "yes":"no" );
98     // room for temporary truth tables
99     p->puTemp[0] = p->pPars->fTruth? ABC_ALLOC( unsigned, 8 * p->nTruth6Words[p->pPars->nLutSize] ) : NULL;
100     p->puTemp[1] = p->puTemp[0] + p->nTruth6Words[p->pPars->nLutSize]*2;
101     p->puTemp[2] = p->puTemp[1] + p->nTruth6Words[p->pPars->nLutSize]*2;
102     p->puTemp[3] = p->puTemp[2] + p->nTruth6Words[p->pPars->nLutSize]*2;
103     p->puTempW   = p->pPars->fTruth? ABC_ALLOC( word, p->nTruth6Words[p->pPars->nLutSize] ) : NULL;
104     if ( pPars->fUseDsd )
105     {
106         for ( v = 6; v <= Abc_MaxInt(6,p->pPars->nLutSize); v++ )
107         {
108             p->vTtDsds[v] = Vec_IntAlloc( 1000 );
109             Vec_IntPush( p->vTtDsds[v], 0 );
110             Vec_IntPush( p->vTtDsds[v], 2 );
111             p->vTtPerms[v] = Vec_StrAlloc( 10000 );
112             Vec_StrFill( p->vTtPerms[v], 2 * v, IF_BIG_CHAR );
113             Vec_StrWriteEntry( p->vTtPerms[v], v, 0 );
114         }
115         for ( v = 0; v < 6; v++ )
116         {
117             p->vTtDsds[v]  = p->vTtDsds[6];
118             p->vTtPerms[v] = p->vTtPerms[6];
119         }
120     }
121     if ( pPars->fUseTtPerm )
122     {
123         p->vPairHash = Hash_IntManStart( 10000 );
124         p->vPairPerms = Vec_StrAlloc( 10000 );
125         Vec_StrFill( p->vPairPerms, p->pPars->nLutSize, 0 );
126         p->vPairRes = Vec_IntAlloc( 1000 );
127         Vec_IntPush( p->vPairRes, -1 );
128         for ( v = 6; v <= Abc_MaxInt(6,p->pPars->nLutSize); v++ )
129             p->vTtOccurs[v] = Vec_IntAlloc( 1000 );
130         for ( v = 0; v < 6; v++ )
131             p->vTtOccurs[v] = p->vTtOccurs[6];
132         for ( v = 6; v <= Abc_MaxInt(6,p->pPars->nLutSize); v++ )
133             Vec_IntPushTwo( p->vTtOccurs[v], 0, 0 );
134     }
135     if ( pPars->fUseCofVars )
136     {
137         for ( v = 6; v <= Abc_MaxInt(6,p->pPars->nLutSize); v++ )
138         {
139             p->vTtVars[v] = Vec_StrAlloc( 1000 );
140             Vec_StrPush( p->vTtVars[v], 0 );
141             Vec_StrPush( p->vTtVars[v], 0 );
142         }
143         for ( v = 0; v < 6; v++ )
144             p->vTtVars[v]  = p->vTtVars[6];
145     }
146     if ( pPars->fUseAndVars )
147     {
148         for ( v = 6; v <= Abc_MaxInt(6,p->pPars->nLutSize); v++ )
149         {
150             p->vTtDecs[v] = Vec_IntAlloc( 1000 );
151             Vec_IntPush( p->vTtDecs[v], 0 );
152             Vec_IntPush( p->vTtDecs[v], 0 );
153         }
154         for ( v = 0; v < 6; v++ )
155             p->vTtDecs[v]  = p->vTtDecs[6];
156     }
157     if ( pPars->fUseBat )
158     {
159 //        abctime clk = Abc_Clock();
160         extern int Bat_ManCellFuncLookup( void * pMan, unsigned * pTruth, int nVars, int nLeaves, char * pStr );
161         extern void Bat_ManFuncSetupTable();
162         pPars->pFuncCell = (int (*)  (If_Man_t *, unsigned *, int, int, char *))Bat_ManCellFuncLookup;
163         Bat_ManFuncSetupTable();
164 //        Abc_PrintTime( 1, "Setup time", Abc_Clock() - clk );
165     }
166     // create the constant node
167     p->pConst1   = If_ManSetupObj( p );
168     p->pConst1->Type   = IF_CONST1;
169     p->pConst1->fPhase = 1;
170     p->nObjs[IF_CONST1]++;
171     return p;
172 }
173 
174 /**Function*************************************************************
175 
176   Synopsis    []
177 
178   Description []
179 
180   SideEffects []
181 
182   SeeAlso     []
183 
184 ***********************************************************************/
If_ManRestart(If_Man_t * p)185 void If_ManRestart( If_Man_t * p )
186 {
187     ABC_FREE( p->pMemCi );
188     Vec_PtrClear( p->vCis );
189     Vec_PtrClear( p->vCos );
190     Vec_PtrClear( p->vObjs );
191     Vec_PtrClear( p->vTemp );
192     Mem_FixedRestart( p->pMemObj );
193     // create the constant node
194     p->pConst1 = If_ManSetupObj( p );
195     p->pConst1->Type = IF_CONST1;
196     p->pConst1->fPhase = 1;
197     // reset the counter of other nodes
198     p->nObjs[IF_CI] = p->nObjs[IF_CO] = p->nObjs[IF_AND] = 0;
199 }
200 
201 /**Function*************************************************************
202 
203   Synopsis    []
204 
205   Description []
206 
207   SideEffects []
208 
209   SeeAlso     []
210 
211 ***********************************************************************/
If_ManStop(If_Man_t * p)212 void If_ManStop( If_Man_t * p )
213 {
214     extern void If_ManCacheAnalize( If_Man_t * p );
215     int i;
216     if ( p->pPars->fVerbose && p->vCutData )
217         If_ManCacheAnalize( p );
218     if ( p->pPars->fVerbose && p->pPars->fTruth )
219     {
220         int nUnique = 0, nMemTotal = 0;
221         for ( i = 6; i <= Abc_MaxInt(6,p->pPars->nLutSize); i++ )
222             nUnique += Vec_MemEntryNum(p->vTtMem[i]);
223         for ( i = 6; i <= Abc_MaxInt(6,p->pPars->nLutSize); i++ )
224             nMemTotal += (int)Vec_MemMemory(p->vTtMem[i]);
225         printf( "Unique truth tables = %d   Memory = %.2f MB   ", nUnique, 1.0 * nMemTotal / (1<<20) );
226         Abc_PrintTime( 1, "Time", p->timeCache[4] );
227         if ( p->nCacheMisses )
228         {
229             printf( "Cache hits = %d. Cache misses = %d  (%.2f %%)\n", p->nCacheHits, p->nCacheMisses, 100.0 * p->nCacheMisses / (p->nCacheHits + p->nCacheMisses) );
230             Abc_PrintTime( 1, "Non-DSD   ", p->timeCache[0] );
231             Abc_PrintTime( 1, "DSD hits  ", p->timeCache[1] );
232             Abc_PrintTime( 1, "DSD misses", p->timeCache[2] );
233             Abc_PrintTime( 1, "TOTAL     ", p->timeCache[0] + p->timeCache[1] + p->timeCache[2] );
234             Abc_PrintTime( 1, "Canon     ", p->timeCache[3] );
235         }
236     }
237     if ( p->pPars->fVerbose && p->nCutsUselessAll )
238     {
239         for ( i = 0; i <= 16; i++ )
240             if ( p->nCutsUseless[i] )
241                 Abc_Print( 1, "Useless cuts %2d  = %9d  (out of %9d)  (%6.2f %%)\n", i, p->nCutsUseless[i], p->nCutsCount[i], 100.0*p->nCutsUseless[i]/Abc_MaxInt(p->nCutsCount[i],1) );
242         Abc_Print( 1, "Useless cuts all = %9d  (out of %9d)  (%6.2f %%)\n", p->nCutsUselessAll, p->nCutsCountAll, 100.0*p->nCutsUselessAll/Abc_MaxInt(p->nCutsCountAll,1) );
243     }
244 //    if ( p->pPars->fVerbose && p->nCuts5 )
245 //        Abc_Print( 1, "Statistics about 5-cuts: Total = %d  Non-decomposable = %d (%.2f %%)\n", p->nCuts5, p->nCuts5-p->nCuts5a, 100.0*(p->nCuts5-p->nCuts5a)/p->nCuts5 );
246     if ( p->pIfDsdMan )
247         p->pIfDsdMan = NULL;
248     if ( p->pPars->fUseDsd && (p->nCountNonDec[0] || p->nCountNonDec[1]) )
249         printf( "NonDec0 = %d.  NonDec1 = %d.\n", p->nCountNonDec[0], p->nCountNonDec[1] );
250     Vec_IntFreeP( &p->vCoAttrs );
251     Vec_PtrFree( p->vCis );
252     Vec_PtrFree( p->vCos );
253     Vec_PtrFree( p->vObjs );
254     Vec_PtrFree( p->vTemp );
255     Vec_IntFreeP( &p->vCover );
256     Vec_IntFreeP( &p->vArray );
257     Vec_WrdFreeP( &p->vAnds );
258     Vec_WrdFreeP( &p->vAndGate );
259     Vec_WrdFreeP( &p->vOrGate );
260     Vec_PtrFreeP( &p->vObjsRev );
261     Vec_PtrFreeP( &p->vLatchOrder );
262     Vec_IntFreeP( &p->vLags );
263     Vec_IntFreeP( &p->vDump );
264     for ( i = 6; i <= Abc_MaxInt(6,p->pPars->nLutSize); i++ )
265         Vec_IntFreeP( &p->vTtDsds[i] );
266     for ( i = 6; i <= Abc_MaxInt(6,p->pPars->nLutSize); i++ )
267         Vec_StrFreeP( &p->vTtPerms[i] );
268     for ( i = 6; i <= Abc_MaxInt(6,p->pPars->nLutSize); i++ )
269         Vec_StrFreeP( &p->vTtVars[i] );
270     for ( i = 6; i <= Abc_MaxInt(6,p->pPars->nLutSize); i++ )
271         Vec_IntFreeP( &p->vTtDecs[i] );
272     Vec_IntFreeP( &p->vCutData );
273     Vec_IntFreeP( &p->vPairRes );
274     Vec_StrFreeP( &p->vPairPerms );
275     Vec_PtrFreeP( &p->vVisited );
276     if ( p->vPairHash )
277         Hash_IntManStop( p->vPairHash );
278     for ( i = 6; i <= Abc_MaxInt(6,p->pPars->nLutSize); i++ )
279         Vec_MemHashFree( p->vTtMem[i] );
280     for ( i = 6; i <= Abc_MaxInt(6,p->pPars->nLutSize); i++ )
281         Vec_MemFreeP( &p->vTtMem[i] );
282     for ( i = 6; i <= Abc_MaxInt(6,p->pPars->nLutSize); i++ )
283         Vec_WecFreeP( &p->vTtIsops[i] );
284     for ( i = 6; i <= Abc_MaxInt(6,p->pPars->nLutSize); i++ )
285         Vec_IntFreeP( &p->vTtOccurs[i] );
286     Mem_FixedStop( p->pMemObj, 0 );
287     if ( p->vTtMem6 )
288     {
289         Vec_MemHashFree( p->vTtMem6 );
290         Vec_MemFreeP( &p->vTtMem6 );
291     }
292     ABC_FREE( p->pMemCi );
293     ABC_FREE( p->pMemAnd );
294     ABC_FREE( p->puTemp[0] );
295     ABC_FREE( p->puTempW );
296     // free pars memory
297     ABC_FREE( p->pPars->pTimesArr );
298     ABC_FREE( p->pPars->pTimesReq );
299     if ( p->pManTim )
300         Tim_ManStop( p->pManTim );
301     if ( p->vSwitching )
302         Vec_IntFree( p->vSwitching );
303     if ( p->pPars->fUseBat )
304     {
305         extern void Bat_ManFuncSetdownTable();
306         Bat_ManFuncSetdownTable();
307     }
308     // hash table
309 //    if ( p->pPars->fVerbose && p->nTableEntries[0] )
310 //        printf( "Hash table 2:  Entries = %7d.  Size = %7d.\n", p->nTableEntries[0], p->nTableSize[0] );
311 //    if ( p->pPars->fVerbose && p->nTableEntries[1] )
312 //        printf( "Hash table 3:  Entries = %7d.  Size = %7d.\n", p->nTableEntries[1], p->nTableSize[1] );
313     ABC_FREE( p->pHashTable[0] );
314     ABC_FREE( p->pHashTable[1] );
315     if ( p->pMemEntries )
316         Mem_FixedStop( p->pMemEntries, 0 );
317     ABC_FREE( p->pName );
318     ABC_FREE( p );
319 }
320 
321 /**Function*************************************************************
322 
323   Synopsis    [Creates primary input.]
324 
325   Description []
326 
327   SideEffects []
328 
329   SeeAlso     []
330 
331 ***********************************************************************/
If_ManCreateCi(If_Man_t * p)332 If_Obj_t * If_ManCreateCi( If_Man_t * p )
333 {
334     If_Obj_t * pObj;
335     pObj = If_ManSetupObj( p );
336     pObj->Type = IF_CI;
337     pObj->IdPio = Vec_PtrSize( p->vCis );
338     Vec_PtrPush( p->vCis, pObj );
339     p->nObjs[IF_CI]++;
340     return pObj;
341 }
342 
343 /**Function*************************************************************
344 
345   Synopsis    [Creates primary output with the given driver.]
346 
347   Description []
348 
349   SideEffects []
350 
351   SeeAlso     []
352 
353 ***********************************************************************/
If_ManCreateCo(If_Man_t * p,If_Obj_t * pDriver)354 If_Obj_t * If_ManCreateCo( If_Man_t * p, If_Obj_t * pDriver )
355 {
356     If_Obj_t * pObj;
357     pObj = If_ManSetupObj( p );
358     pObj->IdPio = Vec_PtrSize( p->vCos );
359     Vec_PtrPush( p->vCos, pObj );
360     pObj->Type = IF_CO;
361     pObj->fCompl0 = If_IsComplement(pDriver); pDriver = If_Regular(pDriver);
362     pObj->pFanin0 = pDriver; pDriver->nRefs++;
363     pObj->fPhase  = (pObj->fCompl0 ^ pDriver->fPhase);
364     pObj->Level   = pDriver->Level;
365     if ( p->nLevelMax < (int)pObj->Level )
366         p->nLevelMax = (int)pObj->Level;
367     p->nObjs[IF_CO]++;
368     return pObj;
369 }
370 
371 /**Function*************************************************************
372 
373   Synopsis    [Create the new node assuming it does not exist.]
374 
375   Description []
376 
377   SideEffects []
378 
379   SeeAlso     []
380 
381 ***********************************************************************/
If_ManCreateAnd(If_Man_t * p,If_Obj_t * pFan0,If_Obj_t * pFan1)382 If_Obj_t * If_ManCreateAnd( If_Man_t * p, If_Obj_t * pFan0, If_Obj_t * pFan1 )
383 {
384     If_Obj_t * pObj;
385     // perform constant propagation
386     if ( pFan0 == pFan1 )
387         return pFan0;
388     if ( pFan0 == If_Not(pFan1) )
389         return If_Not(p->pConst1);
390     if ( If_Regular(pFan0) == p->pConst1 )
391         return pFan0 == p->pConst1 ? pFan1 : If_Not(p->pConst1);
392     if ( If_Regular(pFan1) == p->pConst1 )
393         return pFan1 == p->pConst1 ? pFan0 : If_Not(p->pConst1);
394     // get memory for the new object
395     pObj = If_ManSetupObj( p );
396     pObj->Type    = IF_AND;
397     pObj->fCompl0 = If_IsComplement(pFan0); pFan0 = If_Regular(pFan0);
398     pObj->fCompl1 = If_IsComplement(pFan1); pFan1 = If_Regular(pFan1);
399     pObj->pFanin0 = pFan0; pFan0->nRefs++; pFan0->nVisits++; pFan0->nVisitsCopy++;
400     pObj->pFanin1 = pFan1; pFan1->nRefs++; pFan1->nVisits++; pFan1->nVisitsCopy++;
401     pObj->fPhase  = (pObj->fCompl0 ^ pFan0->fPhase) & (pObj->fCompl1 ^ pFan1->fPhase);
402     pObj->Level   = 1 + IF_MAX( pFan0->Level, pFan1->Level );
403     if ( p->nLevelMax < (int)pObj->Level )
404         p->nLevelMax = (int)pObj->Level;
405     p->nObjs[IF_AND]++;
406     return pObj;
407 }
408 
409 /**Function*************************************************************
410 
411   Synopsis    [Create the new node assuming it does not exist.]
412 
413   Description []
414 
415   SideEffects []
416 
417   SeeAlso     []
418 
419 ***********************************************************************/
If_ManCreateXor(If_Man_t * p,If_Obj_t * pFan0,If_Obj_t * pFan1)420 If_Obj_t * If_ManCreateXor( If_Man_t * p, If_Obj_t * pFan0, If_Obj_t * pFan1 )
421 {
422     If_Obj_t * pRes1, * pRes2;
423     pRes1 = If_ManCreateAnd( p, If_Not(pFan0), pFan1 );
424     pRes2 = If_ManCreateAnd( p, pFan0, If_Not(pFan1) );
425     return If_Not( If_ManCreateAnd( p, If_Not(pRes1), If_Not(pRes2) ) );
426 }
427 
428 /**Function*************************************************************
429 
430   Synopsis    [Create the new node assuming it does not exist.]
431 
432   Description []
433 
434   SideEffects []
435 
436   SeeAlso     []
437 
438 ***********************************************************************/
If_ManCreateMux(If_Man_t * p,If_Obj_t * pFan0,If_Obj_t * pFan1,If_Obj_t * pCtrl)439 If_Obj_t * If_ManCreateMux( If_Man_t * p, If_Obj_t * pFan0, If_Obj_t * pFan1, If_Obj_t * pCtrl )
440 {
441     If_Obj_t * pRes1, * pRes2;
442     pRes1 = If_ManCreateAnd( p, pFan0, If_Not(pCtrl) );
443     pRes2 = If_ManCreateAnd( p, pFan1, pCtrl );
444     return If_Not( If_ManCreateAnd( p, If_Not(pRes1), If_Not(pRes2) ) );
445 }
446 
447 /**Function*************************************************************
448 
449   Synopsis    [Creates the choice node.]
450 
451   Description [Should be called after the equivalence class nodes are linked.]
452 
453   SideEffects []
454 
455   SeeAlso     []
456 
457 ***********************************************************************/
If_ManCreateChoice(If_Man_t * p,If_Obj_t * pObj)458 void If_ManCreateChoice( If_Man_t * p, If_Obj_t * pObj )
459 {
460     If_Obj_t * pTemp;
461     // mark the node as a representative if its class
462     assert( pObj->fRepr == 0 );
463     pObj->fRepr = 1;
464     // update the level of this node (needed for correct required time computation)
465     for ( pTemp = pObj; pTemp; pTemp = pTemp->pEquiv )
466     {
467         pObj->Level = IF_MAX( pObj->Level, pTemp->Level );
468         pTemp->nVisits++; pTemp->nVisitsCopy++;
469     }
470     // mark the largest level
471     if ( p->nLevelMax < (int)pObj->Level )
472         p->nLevelMax = (int)pObj->Level;
473     p->nChoices++;
474 }
475 
476 /**Function*************************************************************
477 
478   Synopsis    [Prepares memory for one cutset.]
479 
480   Description []
481 
482   SideEffects []
483 
484   SeeAlso     []
485 
486 ***********************************************************************/
If_ManSetupSet(If_Man_t * p,If_Set_t * pSet)487 void If_ManSetupSet( If_Man_t * p, If_Set_t * pSet )
488 {
489     char * pArray;
490     int i;
491     pSet->nCuts = 0;
492     pSet->nCutsMax = p->pPars->nCutsMax;
493     pSet->ppCuts = (If_Cut_t **)(pSet + 1);
494     pArray = (char *)pSet->ppCuts + sizeof(If_Cut_t *) * (pSet->nCutsMax+1);
495     for ( i = 0; i <= pSet->nCutsMax; i++ )
496     {
497         pSet->ppCuts[i] = (If_Cut_t *)(pArray + i * p->nCutBytes);
498         If_CutSetup( p, pSet->ppCuts[i] );
499     }
500 //    pArray += (pSet->nCutsMax + 1) * p->nCutBytes;
501 //    assert( ((char *)pArray) - ((char *)pSet) == p->nSetBytes );
502 }
503 
504 /**Function*************************************************************
505 
506   Synopsis    [Prepares memory for one cut.]
507 
508   Description []
509 
510   SideEffects []
511 
512   SeeAlso     []
513 
514 ***********************************************************************/
If_ManSetupCutTriv(If_Man_t * p,If_Cut_t * pCut,int ObjId)515 void If_ManSetupCutTriv( If_Man_t * p, If_Cut_t * pCut, int ObjId )
516 {
517     pCut->fCompl     = 0;
518     pCut->nLimit     = p->pPars->nLutSize;
519     pCut->nLeaves    = 1;
520     pCut->pLeaves[0] = p->pPars->fLiftLeaves? (ObjId << 8) : ObjId;
521     pCut->uSign      = If_ObjCutSign( pCut->pLeaves[0] );
522     pCut->iCutFunc   = p->pPars->fUseTtPerm ? 3 : (p->pPars->fTruth ? 2: -1);
523     pCut->uMaskFunc  = 0;
524     assert( pCut->pLeaves[0] < p->vObjs->nSize );
525 }
526 
527 /**Function*************************************************************
528 
529   Synopsis    [Prepares memory for the node with cuts.]
530 
531   Description []
532 
533   SideEffects []
534 
535   SeeAlso     []
536 
537 ***********************************************************************/
If_ManSetupObj(If_Man_t * p)538 If_Obj_t * If_ManSetupObj( If_Man_t * p )
539 {
540     If_Obj_t * pObj;
541     // get memory for the object
542     pObj = (If_Obj_t *)Mem_FixedEntryFetch( p->pMemObj );
543     memset( pObj, 0, sizeof(If_Obj_t) );
544     If_CutSetup( p, &pObj->CutBest );
545     // assign ID and save
546     pObj->Id = Vec_PtrSize(p->vObjs);
547     Vec_PtrPush( p->vObjs, pObj );
548     // set the required times
549     pObj->Required = IF_FLOAT_LARGE;
550     return pObj;
551 }
552 
553 /**Function*************************************************************
554 
555   Synopsis    [Prepares memory for one cut.]
556 
557   Description []
558 
559   SideEffects []
560 
561   SeeAlso     []
562 
563 ***********************************************************************/
If_ManSetupCiCutSets(If_Man_t * p)564 void If_ManSetupCiCutSets( If_Man_t * p )
565 {
566     If_Obj_t * pObj;
567     int i;
568     assert( p->pMemCi == NULL );
569     // create elementary cuts for the CIs
570     If_ManForEachCi( p, pObj, i )
571         If_ManSetupCutTriv( p, &pObj->CutBest, pObj->Id );
572     // create elementary cutsets for the CIs
573     p->pMemCi = (If_Set_t *)ABC_ALLOC( char, If_ManCiNum(p) * (sizeof(If_Set_t) + sizeof(void *)) );
574     If_ManForEachCi( p, pObj, i )
575     {
576         pObj->pCutSet = (If_Set_t *)((char *)p->pMemCi + i * (sizeof(If_Set_t) + sizeof(void *)));
577         pObj->pCutSet->nCuts = 1;
578         pObj->pCutSet->nCutsMax = p->pPars->nCutsMax;
579         pObj->pCutSet->ppCuts = (If_Cut_t **)(pObj->pCutSet + 1);
580         pObj->pCutSet->ppCuts[0] = &pObj->CutBest;
581     }
582 }
583 
584 /**Function*************************************************************
585 
586   Synopsis    [Prepares cutset of the node.]
587 
588   Description [Elementary cutset will be added last.]
589 
590   SideEffects []
591 
592   SeeAlso     []
593 
594 ***********************************************************************/
If_ManSetupNodeCutSet(If_Man_t * p,If_Obj_t * pObj)595 If_Set_t * If_ManSetupNodeCutSet( If_Man_t * p, If_Obj_t * pObj )
596 {
597     assert( If_ObjIsAnd(pObj) );
598     assert( pObj->pCutSet == NULL );
599 //    pObj->pCutSet = (If_Set_t *)Mem_FixedEntryFetch( p->pMemSet );
600 //    If_ManSetupSet( p, pObj->pCutSet );
601     pObj->pCutSet = If_ManCutSetFetch( p );
602     pObj->pCutSet->nCuts = 0;
603     pObj->pCutSet->nCutsMax = p->pPars->nCutsMax;
604     return pObj->pCutSet;
605 }
606 
607 /**Function*************************************************************
608 
609   Synopsis    [Dereferences cutset of the node.]
610 
611   Description []
612 
613   SideEffects []
614 
615   SeeAlso     []
616 
617 ***********************************************************************/
If_ManDerefNodeCutSet(If_Man_t * p,If_Obj_t * pObj)618 void If_ManDerefNodeCutSet( If_Man_t * p, If_Obj_t * pObj )
619 {
620     If_Obj_t * pFanin;
621     assert( If_ObjIsAnd(pObj) );
622     // consider the node
623     assert( pObj->nVisits >= 0 );
624     if ( pObj->nVisits == 0 )
625     {
626 //        Mem_FixedEntryRecycle( p->pMemSet, (char *)pObj->pCutSet );
627         If_ManCutSetRecycle( p, pObj->pCutSet );
628         pObj->pCutSet = NULL;
629     }
630     // consider the first fanin
631     pFanin = If_ObjFanin0(pObj);
632     assert( pFanin->nVisits > 0 );
633     if ( !If_ObjIsCi(pFanin) && --pFanin->nVisits == 0 )
634     {
635 //        Mem_FixedEntryRecycle( p->pMemSet, (char *)pFanin->pCutSet );
636         If_ManCutSetRecycle( p, pFanin->pCutSet );
637         pFanin->pCutSet = NULL;
638     }
639     // consider the second fanin
640     pFanin = If_ObjFanin1(pObj);
641     assert( pFanin->nVisits > 0 );
642     if ( !If_ObjIsCi(pFanin) && --pFanin->nVisits == 0 )
643     {
644 //        Mem_FixedEntryRecycle( p->pMemSet, (char *)pFanin->pCutSet );
645         If_ManCutSetRecycle( p, pFanin->pCutSet );
646         pFanin->pCutSet = NULL;
647     }
648 }
649 
650 /**Function*************************************************************
651 
652   Synopsis    [Dereferences cutset of the node.]
653 
654   Description []
655 
656   SideEffects []
657 
658   SeeAlso     []
659 
660 ***********************************************************************/
If_ManDerefChoiceCutSet(If_Man_t * p,If_Obj_t * pObj)661 void If_ManDerefChoiceCutSet( If_Man_t * p, If_Obj_t * pObj )
662 {
663     If_Obj_t * pTemp;
664     assert( If_ObjIsAnd(pObj) );
665     assert( pObj->fRepr );
666     assert( pObj->nVisits > 0 );
667     // consider the nodes in the choice class
668     for ( pTemp = pObj; pTemp; pTemp = pTemp->pEquiv )
669     {
670 //        assert( pTemp == pObj || pTemp->nVisits == 1 );
671         if ( --pTemp->nVisits == 0 )
672         {
673 //            Mem_FixedEntryRecycle( p->pMemSet, (char *)pTemp->pCutSet );
674             If_ManCutSetRecycle( p, pTemp->pCutSet );
675             pTemp->pCutSet = NULL;
676         }
677     }
678 }
679 
680 /**Function*************************************************************
681 
682   Synopsis    [Dereferences cutset of the node.]
683 
684   Description []
685 
686   SideEffects []
687 
688   SeeAlso     []
689 
690 ***********************************************************************/
If_ManSetupSetAll(If_Man_t * p,int nCrossCut)691 void If_ManSetupSetAll( If_Man_t * p, int nCrossCut )
692 {
693     If_Set_t * pCutSet;
694     int i, nCutSets;
695     nCutSets = 128 + nCrossCut;
696     p->pFreeList = p->pMemAnd = pCutSet = (If_Set_t *)ABC_ALLOC( char, nCutSets * p->nSetBytes );
697     for ( i = 0; i < nCutSets; i++ )
698     {
699         If_ManSetupSet( p, pCutSet );
700         if ( i == nCutSets - 1 )
701             pCutSet->pNext = NULL;
702         else
703             pCutSet->pNext = (If_Set_t *)( (char *)pCutSet + p->nSetBytes );
704         pCutSet = pCutSet->pNext;
705     }
706     assert( pCutSet == NULL );
707 
708     if ( p->pPars->fVerbose )
709     {
710         Abc_Print( 1, "Node = %7d.  Ch = %5d.  Total mem = %7.2f MB. Peak cut mem = %7.2f MB.\n",
711             If_ManAndNum(p), p->nChoices,
712             1.0 * (p->nObjBytes + 2*sizeof(void *)) * If_ManObjNum(p) / (1<<20),
713             1.0 * p->nSetBytes * nCrossCut / (1<<20) );
714     }
715 //    Abc_Print( 1, "Cross cut = %d.\n", nCrossCut );
716 
717 }
718 
719 ////////////////////////////////////////////////////////////////////////
720 ///                       END OF FILE                                ///
721 ////////////////////////////////////////////////////////////////////////
722 
723 
724 ABC_NAMESPACE_IMPL_END
725 
726