1 /**CFile****************************************************************
2
3 FileName [aigPartReg.c]
4
5 SystemName [ABC: Logic synthesis and verification system.]
6
7 PackageName [AIG package.]
8
9 Synopsis [Register partitioning algorithm.]
10
11 Author [Alan Mishchenko]
12
13 Affiliation [UC Berkeley]
14
15 Date [Ver. 1.0. Started - April 28, 2007.]
16
17 Revision [$Id: aigPartReg.c,v 1.00 2007/04/28 00:00:00 alanmi Exp $]
18
19 ***********************************************************************/
20
21 #include "aig.h"
22 //#include "fra.h"
23
24 ABC_NAMESPACE_IMPL_START
25
26
27 ////////////////////////////////////////////////////////////////////////
28 /// DECLARATIONS ///
29 ////////////////////////////////////////////////////////////////////////
30
31 typedef struct Aig_ManPre_t_ Aig_ManPre_t;
32
33 struct Aig_ManPre_t_
34 {
35 // input data
36 Aig_Man_t * pAig; // seq AIG manager
37 Vec_Ptr_t * vMatrix; // register dependency
38 int nRegsMax; // the max number of registers in the cluster
39 // information about partitions
40 Vec_Ptr_t * vParts; // the partitions
41 char * pfUsedRegs; // the registers already included in the partitions
42 // info about the current partition
43 Vec_Int_t * vRegs; // registers of this partition
44 Vec_Int_t * vUniques; // unique registers of this partition
45 Vec_Int_t * vFreeVars; // free variables of this partition
46 Vec_Flt_t * vPartCost; // costs of adding each variable
47 char * pfPartVars; // input/output registers of the partition
48 };
49
50
51 ////////////////////////////////////////////////////////////////////////
52 /// FUNCTION DEFINITIONS ///
53 ////////////////////////////////////////////////////////////////////////
54
55 /**Function*************************************************************
56
57 Synopsis [Computes partitioning of registers.]
58
59 Description []
60
61 SideEffects []
62
63 SeeAlso []
64
65 ***********************************************************************/
Aig_ManRegManStart(Aig_Man_t * pAig,int nPartSize)66 Aig_ManPre_t * Aig_ManRegManStart( Aig_Man_t * pAig, int nPartSize )
67 {
68 Aig_ManPre_t * p;
69 p = ABC_ALLOC( Aig_ManPre_t, 1 );
70 memset( p, 0, sizeof(Aig_ManPre_t) );
71 p->pAig = pAig;
72 p->vMatrix = Aig_ManSupportsRegisters( pAig );
73 p->nRegsMax = nPartSize;
74 p->vParts = Vec_PtrAlloc(256);
75 p->vRegs = Vec_IntAlloc(256);
76 p->vUniques = Vec_IntAlloc(256);
77 p->vFreeVars = Vec_IntAlloc(256);
78 p->vPartCost = Vec_FltAlloc(256);
79 p->pfUsedRegs = ABC_ALLOC( char, Aig_ManRegNum(p->pAig) );
80 memset( p->pfUsedRegs, 0, sizeof(char) * Aig_ManRegNum(p->pAig) );
81 p->pfPartVars = ABC_ALLOC( char, Aig_ManRegNum(p->pAig) );
82 return p;
83 }
84
85 /**Function*************************************************************
86
87 Synopsis [Computes partitioning of registers.]
88
89 Description []
90
91 SideEffects []
92
93 SeeAlso []
94
95 ***********************************************************************/
Aig_ManRegManStop(Aig_ManPre_t * p)96 void Aig_ManRegManStop( Aig_ManPre_t * p )
97 {
98 Vec_VecFree( (Vec_Vec_t *)p->vMatrix );
99 if ( p->vParts )
100 Vec_VecFree( (Vec_Vec_t *)p->vParts );
101 Vec_IntFree( p->vRegs );
102 Vec_IntFree( p->vUniques );
103 Vec_IntFree( p->vFreeVars );
104 Vec_FltFree( p->vPartCost );
105 ABC_FREE( p->pfUsedRegs );
106 ABC_FREE( p->pfPartVars );
107 ABC_FREE( p );
108 }
109
110 /**Function*************************************************************
111
112 Synopsis [Determines what register to use as the seed.]
113
114 Description [The register is selected as the one having the largest
115 number of non-taken registers in its support.]
116
117 SideEffects []
118
119 SeeAlso []
120
121 ***********************************************************************/
Aig_ManRegFindSeed(Aig_ManPre_t * p)122 int Aig_ManRegFindSeed( Aig_ManPre_t * p )
123 {
124 Vec_Int_t * vRegs;
125 int i, k, iReg;
126 int iMax = -1; // Suppress "might be used uninitialized"
127 int nRegsCur, nRegsMax = -1;
128 for ( i = 0; i < Aig_ManRegNum(p->pAig); i++ )
129 {
130 if ( p->pfUsedRegs[i] )
131 continue;
132 nRegsCur = 0;
133 vRegs = (Vec_Int_t *)Vec_PtrEntry( p->vMatrix, i );
134 Vec_IntForEachEntry( vRegs, iReg, k )
135 nRegsCur += !p->pfUsedRegs[iReg];
136 if ( nRegsMax < nRegsCur )
137 {
138 nRegsMax = nRegsCur;
139 iMax = i;
140 }
141 }
142 return iMax;
143 }
144
145 /**Function*************************************************************
146
147 Synopsis [Computes the next register to be added to the set.]
148
149 Description []
150
151 SideEffects []
152
153 SeeAlso []
154
155 ***********************************************************************/
Aig_ManRegFindBestVar(Aig_ManPre_t * p)156 int Aig_ManRegFindBestVar( Aig_ManPre_t * p )
157 {
158 Vec_Int_t * vSupp;
159 int nNewVars, nNewVarsBest = ABC_INFINITY;
160 int iVarFree, iVarSupp, iVarBest = -1, i, k;
161 // go through the free variables
162 Vec_IntForEachEntry( p->vFreeVars, iVarFree, i )
163 {
164 // if ( p->pfUsedRegs[iVarFree] )
165 // continue;
166 // get support of this variable
167 vSupp = (Vec_Int_t *)Vec_PtrEntry( p->vMatrix, iVarFree );
168 // count the number of new vars
169 nNewVars = 0;
170 Vec_IntForEachEntry( vSupp, iVarSupp, k )
171 {
172 if ( p->pfPartVars[iVarSupp] )
173 continue;
174 nNewVars += 1 + 3 * p->pfUsedRegs[iVarSupp];
175 }
176 // quit if there is no new variables
177 if ( nNewVars == 0 )
178 return iVarFree;
179 // compare the cost of this
180 if ( nNewVarsBest > nNewVars )
181 {
182 nNewVarsBest = nNewVars;
183 iVarBest = iVarFree;
184 }
185 }
186 return iVarBest;
187 }
188
189 /**Function*************************************************************
190
191 Synopsis [Computes partitioning of registers.]
192
193 Description []
194
195 SideEffects []
196
197 SeeAlso []
198
199 ***********************************************************************/
Aig_ManRegPartitionAdd(Aig_ManPre_t * p,int iReg)200 void Aig_ManRegPartitionAdd( Aig_ManPre_t * p, int iReg )
201 {
202 Vec_Int_t * vSupp;
203 int RetValue, iVar, i;
204 // make sure this is a new variable
205 // assert( !p->pfUsedRegs[iReg] );
206 if ( !p->pfUsedRegs[iReg] )
207 {
208 p->pfUsedRegs[iReg] = 1;
209 Vec_IntPush( p->vUniques, iReg );
210 }
211 // remove it from the free variables
212 if ( Vec_IntSize(p->vFreeVars) > 0 )
213 {
214 assert( p->pfPartVars[iReg] );
215 RetValue = Vec_IntRemove( p->vFreeVars, iReg );
216 assert( RetValue );
217 }
218 else
219 assert( !p->pfPartVars[iReg] );
220 // add it to the partition
221 p->pfPartVars[iReg] = 1;
222 Vec_IntPush( p->vRegs, iReg );
223 // add new variables
224 vSupp = (Vec_Int_t *)Vec_PtrEntry( p->vMatrix, iReg );
225 Vec_IntForEachEntry( vSupp, iVar, i )
226 {
227 if ( p->pfPartVars[iVar] )
228 continue;
229 p->pfPartVars[iVar] = 1;
230 Vec_IntPush( p->vFreeVars, iVar );
231 }
232 // add it to the cost
233 Vec_FltPush( p->vPartCost, 1.0*Vec_IntSize(p->vFreeVars)/Vec_IntSize(p->vRegs) );
234 }
235
236 /**Function*************************************************************
237
238 Synopsis [Creates projection of 1-hot registers onto the given partition.]
239
240 Description [Assumes that the relevant register outputs are labeled with
241 the current traversal ID.]
242
243 SideEffects []
244
245 SeeAlso []
246
247 ***********************************************************************/
Aig_ManRegProjectOnehots(Aig_Man_t * pAig,Aig_Man_t * pPart,Vec_Ptr_t * vOnehots,int fVerbose)248 Vec_Ptr_t * Aig_ManRegProjectOnehots( Aig_Man_t * pAig, Aig_Man_t * pPart, Vec_Ptr_t * vOnehots, int fVerbose )
249 {
250 Vec_Ptr_t * vOnehotsPart = NULL;
251 Vec_Int_t * vGroup, * vGroupNew;
252 Aig_Obj_t * pObj, * pObjNew;
253 int nOffset, iReg, i, k;
254 // set the PI numbers
255 Aig_ManForEachCi( pPart, pObj, i )
256 pObj->iData = i;
257 // go through each group and check if registers are involved in this one
258 nOffset = Aig_ManCiNum(pAig)-Aig_ManRegNum(pAig);
259 Vec_PtrForEachEntry( Vec_Int_t *, vOnehots, vGroup, i )
260 {
261 vGroupNew = NULL;
262 Vec_IntForEachEntry( vGroup, iReg, k )
263 {
264 pObj = Aig_ManCi( pAig, nOffset+iReg );
265 if ( !Aig_ObjIsTravIdCurrent(pAig, pObj) )
266 continue;
267 if ( vGroupNew == NULL )
268 vGroupNew = Vec_IntAlloc( Vec_IntSize(vGroup) );
269 pObjNew = (Aig_Obj_t *)pObj->pData;
270 Vec_IntPush( vGroupNew, pObjNew->iData );
271 }
272 if ( vGroupNew == NULL )
273 continue;
274 if ( Vec_IntSize(vGroupNew) > 1 )
275 {
276 if ( vOnehotsPart == NULL )
277 vOnehotsPart = Vec_PtrAlloc( 100 );
278 Vec_PtrPush( vOnehotsPart, vGroupNew );
279 }
280 else
281 Vec_IntFree( vGroupNew );
282 }
283 // clear the PI numbers
284 Aig_ManForEachCi( pPart, pObj, i )
285 pObj->iData = 0;
286 // print out
287 if ( vOnehotsPart && fVerbose )
288 {
289 printf( "Partition contains %d groups of 1-hot registers: { ", Vec_PtrSize(vOnehotsPart) );
290 Vec_PtrForEachEntry( Vec_Int_t *, vOnehotsPart, vGroup, k )
291 printf( "%d ", Vec_IntSize(vGroup) );
292 printf( "}\n" );
293 }
294 return vOnehotsPart;
295 }
296
297 /**Function*************************************************************
298
299 Synopsis [Computes partitioning of registers.]
300
301 Description []
302
303 SideEffects []
304
305 SeeAlso []
306
307 ***********************************************************************/
Aig_ManRegCreatePart(Aig_Man_t * pAig,Vec_Int_t * vPart,int * pnCountPis,int * pnCountRegs,int ** ppMapBack)308 Aig_Man_t * Aig_ManRegCreatePart( Aig_Man_t * pAig, Vec_Int_t * vPart, int * pnCountPis, int * pnCountRegs, int ** ppMapBack )
309 {
310 Aig_Man_t * pNew;
311 Aig_Obj_t * pObj, * pObjNew;
312 Vec_Ptr_t * vNodes;
313 Vec_Ptr_t * vRoots;
314 int nOffset, iOut, i;
315 int nCountPis, nCountRegs;
316 int * pMapBack;
317 // collect roots
318 vRoots = Vec_PtrAlloc( Vec_IntSize(vPart) );
319 nOffset = Aig_ManCoNum(pAig)-Aig_ManRegNum(pAig);
320 Vec_IntForEachEntry( vPart, iOut, i )
321 {
322 pObj = Aig_ManCo(pAig, nOffset+iOut);
323 Vec_PtrPush( vRoots, Aig_ObjFanin0(pObj) );
324 }
325 // collect/mark nodes/PIs in the DFS order
326 vNodes = Aig_ManDfsNodes( pAig, (Aig_Obj_t **)Vec_PtrArray(vRoots), Vec_PtrSize(vRoots) );
327 Vec_PtrFree( vRoots );
328 // unmark register outputs
329 nOffset = Aig_ManCiNum(pAig)-Aig_ManRegNum(pAig);
330 Vec_IntForEachEntry( vPart, iOut, i )
331 {
332 pObj = Aig_ManCi(pAig, nOffset+iOut);
333 Aig_ObjSetTravIdPrevious( pAig, pObj );
334 }
335 // count pure PIs
336 nCountPis = nCountRegs = 0;
337 Aig_ManForEachPiSeq( pAig, pObj, i )
338 nCountPis += Aig_ObjIsTravIdCurrent(pAig, pObj);
339 // count outputs of other registers
340 Aig_ManForEachLoSeq( pAig, pObj, i )
341 nCountRegs += Aig_ObjIsTravIdCurrent(pAig, pObj);
342 if ( pnCountPis )
343 *pnCountPis = nCountPis;
344 if ( pnCountRegs )
345 *pnCountRegs = nCountRegs;
346 // create the new manager
347 pNew = Aig_ManStart( Vec_PtrSize(vNodes) );
348 Aig_ManConst1(pAig)->pData = Aig_ManConst1(pNew);
349 // create the PIs
350 Aig_ManForEachCi( pAig, pObj, i )
351 if ( Aig_ObjIsTravIdCurrent(pAig, pObj) )
352 pObj->pData = Aig_ObjCreateCi(pNew);
353 // add variables for the register outputs
354 // create fake POs to hold the register outputs
355 nOffset = Aig_ManCiNum(pAig)-Aig_ManRegNum(pAig);
356 Vec_IntForEachEntry( vPart, iOut, i )
357 {
358 pObj = Aig_ManCi(pAig, nOffset+iOut);
359 pObj->pData = Aig_ObjCreateCi(pNew);
360 Aig_ObjCreateCo( pNew, (Aig_Obj_t *)pObj->pData );
361 Aig_ObjSetTravIdCurrent( pAig, pObj ); // added
362 }
363 // create the nodes
364 Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
365 if ( Aig_ObjIsNode(pObj) )
366 pObj->pData = Aig_And(pNew, Aig_ObjChild0Copy(pObj), Aig_ObjChild1Copy(pObj) );
367 // add real POs for the registers
368 nOffset = Aig_ManCoNum(pAig)-Aig_ManRegNum(pAig);
369 Vec_IntForEachEntry( vPart, iOut, i )
370 {
371 pObj = Aig_ManCo( pAig, nOffset+iOut );
372 Aig_ObjCreateCo( pNew, Aig_ObjChild0Copy(pObj) );
373 }
374 pNew->nRegs = Vec_IntSize(vPart);
375 // create map
376 if ( ppMapBack )
377 {
378 pMapBack = ABC_ALLOC( int, Aig_ManObjNumMax(pNew) );
379 memset( pMapBack, 0xff, sizeof(int) * Aig_ManObjNumMax(pNew) );
380 // map constant nodes
381 pMapBack[0] = 0;
382 // logic cones of register outputs
383 Vec_PtrForEachEntry( Aig_Obj_t *, vNodes, pObj, i )
384 {
385 pObjNew = Aig_Regular((Aig_Obj_t *)pObj->pData);
386 pMapBack[pObjNew->Id] = pObj->Id;
387 }
388 // map register outputs
389 nOffset = Aig_ManCiNum(pAig)-Aig_ManRegNum(pAig);
390 Vec_IntForEachEntry( vPart, iOut, i )
391 {
392 pObj = Aig_ManCi(pAig, nOffset+iOut);
393 pObjNew = (Aig_Obj_t *)pObj->pData;
394 pMapBack[pObjNew->Id] = pObj->Id;
395 }
396 *ppMapBack = pMapBack;
397 }
398 Vec_PtrFree( vNodes );
399 return pNew;
400 }
401
402 /**Function*************************************************************
403
404 Synopsis [Computes partitioning of registers.]
405
406 Description []
407
408 SideEffects []
409
410 SeeAlso []
411
412 ***********************************************************************/
Aig_ManRegPartitionSmart(Aig_Man_t * pAig,int nPartSize)413 Vec_Ptr_t * Aig_ManRegPartitionSmart( Aig_Man_t * pAig, int nPartSize )
414 {
415 extern void Ioa_WriteAiger( Aig_Man_t * pMan, char * pFileName, int fWriteSymbols, int fCompact );
416
417 Aig_ManPre_t * p;
418 Vec_Ptr_t * vResult;
419 int iSeed, iNext, i, k;
420 // create the manager
421 p = Aig_ManRegManStart( pAig, nPartSize );
422 // add partitions as long as registers remain
423 for ( i = 0; (iSeed = Aig_ManRegFindSeed(p)) >= 0; i++ )
424 {
425 //printf( "Seed variable = %d.\n", iSeed );
426 // clean the current partition information
427 Vec_IntClear( p->vRegs );
428 Vec_IntClear( p->vUniques );
429 Vec_IntClear( p->vFreeVars );
430 Vec_FltClear( p->vPartCost );
431 memset( p->pfPartVars, 0, sizeof(char) * Aig_ManRegNum(p->pAig) );
432 // add the register and its partition support
433 Aig_ManRegPartitionAdd( p, iSeed );
434 // select the best var to add
435 for ( k = 0; Vec_IntSize(p->vRegs) < p->nRegsMax; k++ )
436 {
437 // get the next best variable
438 iNext = Aig_ManRegFindBestVar( p );
439 if ( iNext == -1 )
440 break;
441 // add the register to the support of the partition
442 Aig_ManRegPartitionAdd( p, iNext );
443 // report the result
444 //printf( "Part %3d Reg %3d : Free = %4d. Total = %4d. Ratio = %6.2f. Unique = %4d.\n", i, k,
445 // Vec_IntSize(p->vFreeVars), Vec_IntSize(p->vRegs),
446 // 1.0*Vec_IntSize(p->vFreeVars)/Vec_IntSize(p->vRegs), Vec_IntSize(p->vUniques) );
447 // quit if there are not free variables
448 if ( Vec_IntSize(p->vFreeVars) == 0 )
449 break;
450 }
451 // add this partition to the set
452 Vec_PtrPush( p->vParts, Vec_IntDup(p->vRegs) );
453 printf( "Part %3d SUMMARY: Free = %4d. Total = %4d. Ratio = %6.2f. Unique = %4d.\n", i,
454 Vec_IntSize(p->vFreeVars), Vec_IntSize(p->vRegs),
455 1.0*Vec_IntSize(p->vFreeVars)/Vec_IntSize(p->vRegs), Vec_IntSize(p->vUniques) );
456 //printf( "\n" );
457 }
458 vResult = p->vParts; p->vParts = NULL;
459 Aig_ManRegManStop( p );
460 return vResult;
461 }
462
463 /**Function*************************************************************
464
465 Synopsis [Computes partitioning of registers.]
466
467 Description []
468
469 SideEffects []
470
471 SeeAlso []
472
473 ***********************************************************************/
Aig_ManRegPartitionSimple(Aig_Man_t * pAig,int nPartSize,int nOverSize)474 Vec_Ptr_t * Aig_ManRegPartitionSimple( Aig_Man_t * pAig, int nPartSize, int nOverSize )
475 {
476 Vec_Ptr_t * vResult;
477 Vec_Int_t * vPart;
478 int i, Counter;
479 if ( nOverSize >= nPartSize )
480 {
481 printf( "Overlap size (%d) is more or equal than the partition size (%d).\n", nOverSize, nPartSize );
482 printf( "Adjusting it to be equal to half of the partition size.\n" );
483 nOverSize = nPartSize/2;
484 }
485 assert( nOverSize < nPartSize );
486 vResult = Vec_PtrAlloc( 100 );
487 for ( Counter = 0; Counter < Aig_ManRegNum(pAig); Counter -= nOverSize )
488 {
489 vPart = Vec_IntAlloc( nPartSize );
490 for ( i = 0; i < nPartSize; i++, Counter++ )
491 if ( Counter < Aig_ManRegNum(pAig) )
492 Vec_IntPush( vPart, Counter );
493 if ( Vec_IntSize(vPart) <= nOverSize )
494 Vec_IntFree(vPart);
495 else
496 Vec_PtrPush( vResult, vPart );
497 }
498 return vResult;
499 }
500
501
502 /**Function*************************************************************
503
504 Synopsis [Divides a large partition into several ones.]
505
506 Description []
507
508 SideEffects []
509
510 SeeAlso []
511
512 ***********************************************************************/
Aig_ManPartDivide(Vec_Ptr_t * vResult,Vec_Int_t * vDomain,int nPartSize,int nOverSize)513 void Aig_ManPartDivide( Vec_Ptr_t * vResult, Vec_Int_t * vDomain, int nPartSize, int nOverSize )
514 {
515 Vec_Int_t * vPart;
516 int i, Counter;
517 assert( nPartSize && Vec_IntSize(vDomain) > nPartSize );
518 if ( nOverSize >= nPartSize )
519 {
520 printf( "Overlap size (%d) is more or equal than the partition size (%d).\n", nOverSize, nPartSize );
521 printf( "Adjusting it to be equal to half of the partition size.\n" );
522 nOverSize = nPartSize/2;
523 }
524 assert( nOverSize < nPartSize );
525 for ( Counter = 0; Counter < Vec_IntSize(vDomain); Counter -= nOverSize )
526 {
527 vPart = Vec_IntAlloc( nPartSize );
528 for ( i = 0; i < nPartSize; i++, Counter++ )
529 if ( Counter < Vec_IntSize(vDomain) )
530 Vec_IntPush( vPart, Vec_IntEntry(vDomain, Counter) );
531 if ( Vec_IntSize(vPart) <= nOverSize )
532 Vec_IntFree(vPart);
533 else
534 Vec_PtrPush( vResult, vPart );
535 }
536 }
537
538 /**Function*************************************************************
539
540 Synopsis [Computes partitioning of registers.]
541
542 Description []
543
544 SideEffects []
545
546 SeeAlso []
547
548 ***********************************************************************/
Aig_ManRegPartitionTraverse_rec(Aig_Man_t * p,Aig_Obj_t * pObj,Vec_Ptr_t * vLos)549 void Aig_ManRegPartitionTraverse_rec( Aig_Man_t * p, Aig_Obj_t * pObj, Vec_Ptr_t * vLos )
550 {
551 if ( Aig_ObjIsTravIdCurrent(p, pObj) )
552 return;
553 Aig_ObjSetTravIdCurrent( p, pObj );
554 if ( Aig_ObjIsCi(pObj) )
555 {
556 if ( pObj->iData >= Aig_ManCiNum(p) - Aig_ManRegNum(p) )
557 {
558 Vec_PtrPush( vLos, pObj );
559 printf( "%d ", pObj->iData - (Aig_ManCiNum(p) - Aig_ManRegNum(p)) );
560 }
561 return;
562 }
563 Aig_ManRegPartitionTraverse_rec( p, Aig_ObjFanin0(pObj), vLos );
564 Aig_ManRegPartitionTraverse_rec( p, Aig_ObjFanin1(pObj), vLos );
565 }
566
567 /**Function*************************************************************
568
569 Synopsis [Computes partitioning of registers.]
570
571 Description []
572
573 SideEffects []
574
575 SeeAlso []
576
577 ***********************************************************************/
Aig_ManRegPartitionTraverse(Aig_Man_t * p)578 Vec_Ptr_t * Aig_ManRegPartitionTraverse( Aig_Man_t * p )
579 {
580 Vec_Ptr_t * vLos;
581 Aig_Obj_t * pObj;
582 int i, nPrev, Counter;
583 // mark the registers
584 Aig_ManForEachCi( p, pObj, i )
585 pObj->iData = i;
586 // collect registers
587 vLos = Vec_PtrAlloc( Aig_ManRegNum(p) );
588 nPrev = 0;
589 Counter = 0;
590 Aig_ManIncrementTravId( p );
591 Aig_ManForEachLiSeq( p, pObj, i )
592 {
593 ++Counter;
594 printf( "Latch %d: ", Counter );
595 Aig_ManRegPartitionTraverse_rec( p, Aig_ObjFanin0(pObj), vLos );
596 printf( "%d=%d \n", Counter, Vec_PtrSize(vLos)-nPrev );
597 nPrev = Vec_PtrSize(vLos);
598 }
599 printf( "Total collected = %d. Total regs = %d.\n", Vec_PtrSize(vLos), Aig_ManRegNum(p) );
600 return vLos;
601 }
602
603 /**Function*************************************************************
604
605 Synopsis [Computes partitioning of registers.]
606
607 Description []
608
609 SideEffects []
610
611 SeeAlso []
612
613 ***********************************************************************/
Aig_ManRegPartitionLinear(Aig_Man_t * pAig,int nPartSize)614 Vec_Ptr_t * Aig_ManRegPartitionLinear( Aig_Man_t * pAig, int nPartSize )
615 {
616 Vec_Ptr_t * vLos;
617 vLos = Aig_ManRegPartitionTraverse( pAig );
618 Vec_PtrFree( vLos );
619 return NULL;
620 }
621
622
623 ////////////////////////////////////////////////////////////////////////
624 /// END OF FILE ///
625 ////////////////////////////////////////////////////////////////////////
626
627
628 ABC_NAMESPACE_IMPL_END
629
630