mirror of https://github.com/YosysHQ/abc.git
568 lines
15 KiB
C
568 lines
15 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [vecWec.h]
|
|
|
|
SystemName [ABC: Logic synthesis and verification system.]
|
|
|
|
PackageName [Resizable arrays.]
|
|
|
|
Synopsis [Resizable vector of resizable vectors.]
|
|
|
|
Author [Alan Mishchenko]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - June 20, 2005.]
|
|
|
|
Revision [$Id: vecWec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#ifndef ABC__misc__vec__vecWec_h
|
|
#define ABC__misc__vec__vecWec_h
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// INCLUDES ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
#include <stdio.h>
|
|
|
|
ABC_NAMESPACE_HEADER_START
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// PARAMETERS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// BASIC TYPES ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
typedef struct Vec_Wec_t_ Vec_Wec_t;
|
|
struct Vec_Wec_t_
|
|
{
|
|
int nCap;
|
|
int nSize;
|
|
Vec_Int_t * pArray;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// MACRO DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
// iterators through levels
|
|
#define Vec_WecForEachLevel( vGlob, vVec, i ) \
|
|
for ( i = 0; (i < Vec_WecSize(vGlob)) && (((vVec) = Vec_WecEntry(vGlob, i)), 1); i++ )
|
|
#define Vec_WecForEachLevelStart( vGlob, vVec, i, LevelStart ) \
|
|
for ( i = LevelStart; (i < Vec_WecSize(vGlob)) && (((vVec) = Vec_WecEntry(vGlob, i)), 1); i++ )
|
|
#define Vec_WecForEachLevelStop( vGlob, vVec, i, LevelStop ) \
|
|
for ( i = 0; (i < LevelStop) && (((vVec) = Vec_WecEntry(vGlob, i)), 1); i++ )
|
|
#define Vec_WecForEachLevelStartStop( vGlob, vVec, i, LevelStart, LevelStop ) \
|
|
for ( i = LevelStart; (i < LevelStop) && (((vVec) = Vec_WecEntry(vGlob, i)), 1); i++ )
|
|
#define Vec_WecForEachLevelReverse( vGlob, vVec, i ) \
|
|
for ( i = Vec_WecSize(vGlob)-1; (i >= 0) && (((vVec) = Vec_WecEntry(vGlob, i)), 1); i-- )
|
|
#define Vec_WecForEachLevelReverseStartStop( vGlob, vVec, i, LevelStart, LevelStop ) \
|
|
for ( i = LevelStart-1; (i >= LevelStop) && (((vVec) = Vec_WecEntry(vGlob, i)), 1); i-- )
|
|
#define Vec_WecForEachLevelTwo( vGlob1, vGlob2, vVec1, vVec2, i ) \
|
|
for ( i = 0; (i < Vec_WecSize(vGlob1)) && (((vVec1) = Vec_WecEntry(vGlob1, i)), 1) && (((vVec2) = Vec_WecEntry(vGlob2, i)), 1); i++ )
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Allocates a vector with the given capacity.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline Vec_Wec_t * Vec_WecAlloc( int nCap )
|
|
{
|
|
Vec_Wec_t * p;
|
|
p = ABC_ALLOC( Vec_Wec_t, 1 );
|
|
if ( nCap > 0 && nCap < 8 )
|
|
nCap = 8;
|
|
p->nSize = 0;
|
|
p->nCap = nCap;
|
|
p->pArray = p->nCap? ABC_CALLOC( Vec_Int_t, p->nCap ) : NULL;
|
|
return p;
|
|
}
|
|
static inline Vec_Wec_t * Vec_WecStart( int nSize )
|
|
{
|
|
Vec_Wec_t * p;
|
|
p = Vec_WecAlloc( nSize );
|
|
p->nSize = nSize;
|
|
return p;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Resizes the vector to the given capacity.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline void Vec_WecGrow( Vec_Wec_t * p, int nCapMin )
|
|
{
|
|
if ( p->nCap >= nCapMin )
|
|
return;
|
|
p->pArray = ABC_REALLOC( Vec_Int_t, p->pArray, nCapMin );
|
|
memset( p->pArray + p->nCap, 0, sizeof(Vec_Int_t) * (nCapMin - p->nCap) );
|
|
p->nCap = nCapMin;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline Vec_Int_t * Vec_WecEntry( Vec_Wec_t * p, int i )
|
|
{
|
|
assert( i >= 0 && i < p->nSize );
|
|
return p->pArray + i;
|
|
}
|
|
static inline Vec_Int_t * Vec_WecEntryLast( Vec_Wec_t * p )
|
|
{
|
|
assert( p->nSize > 0 );
|
|
return p->pArray + p->nSize - 1;
|
|
}
|
|
static inline int Vec_WecEntryEntry( Vec_Wec_t * p, int i, int k )
|
|
{
|
|
return Vec_IntEntry( Vec_WecEntry(p, i), k );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline int Vec_WecCap( Vec_Wec_t * p )
|
|
{
|
|
return p->nCap;
|
|
}
|
|
static inline int Vec_WecSize( Vec_Wec_t * p )
|
|
{
|
|
return p->nSize;
|
|
}
|
|
static inline int Vec_WecLevelSize( Vec_Wec_t * p, int i )
|
|
{
|
|
assert( i >= 0 && i < p->nSize );
|
|
return Vec_IntSize( p->pArray + i );
|
|
}
|
|
static inline int Vec_WecSizeSize( Vec_Wec_t * p )
|
|
{
|
|
Vec_Int_t * vVec;
|
|
int i, Counter = 0;
|
|
Vec_WecForEachLevel( p, vVec, i )
|
|
Counter += Vec_IntSize(vVec);
|
|
return Counter;
|
|
}
|
|
static inline int Vec_WecSizeUsed( Vec_Wec_t * p )
|
|
{
|
|
Vec_Int_t * vVec;
|
|
int i, Counter = 0;
|
|
Vec_WecForEachLevel( p, vVec, i )
|
|
Counter += (int)(Vec_IntSize(vVec) > 0);
|
|
return Counter;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline void Vec_WecShrink( Vec_Wec_t * p, int nSizeNew )
|
|
{
|
|
assert( p->nSize >= nSizeNew );
|
|
p->nSize = nSizeNew;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline void Vec_WecClear( Vec_Wec_t * p )
|
|
{
|
|
Vec_Int_t * vVec;
|
|
int i;
|
|
Vec_WecForEachLevel( p, vVec, i )
|
|
Vec_IntClear( vVec );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline void Vec_WecPush( Vec_Wec_t * p, int Level, int Entry )
|
|
{
|
|
if ( p->nSize < Level + 1 )
|
|
{
|
|
Vec_WecGrow( p, Level + 1 );
|
|
p->nSize = Level + 1;
|
|
}
|
|
Vec_IntPush( Vec_WecEntry(p, Level), Entry );
|
|
}
|
|
static inline Vec_Int_t * Vec_WecPushLevel( Vec_Wec_t * p )
|
|
{
|
|
Vec_WecGrow( p, ++p->nSize );
|
|
return Vec_WecEntryLast( p );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline double Vec_WecMemory( Vec_Wec_t * p )
|
|
{
|
|
int i;
|
|
double Mem;
|
|
if ( p == NULL ) return 0.0;
|
|
Mem = sizeof(Vec_Int_t) * Vec_WecCap(p);
|
|
for ( i = 0; i < p->nSize; i++ )
|
|
Mem += sizeof(int) * Vec_IntCap( Vec_WecEntry(p, i) );
|
|
return Mem;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Frees the vector.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline void Vec_WecFree( Vec_Wec_t * p )
|
|
{
|
|
Vec_Int_t * vVec;
|
|
int i;
|
|
Vec_WecForEachLevel( p, vVec, i )
|
|
ABC_FREE( vVec->pArray );
|
|
ABC_FREE( p->pArray );
|
|
ABC_FREE( p );
|
|
}
|
|
static inline void Vec_WecFreeP( Vec_Wec_t ** p )
|
|
{
|
|
if ( *p == NULL )
|
|
return;
|
|
Vec_WecFree( *p );
|
|
*p = NULL;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline void Vec_WecPushUnique( Vec_Wec_t * p, int Level, int Entry )
|
|
{
|
|
if ( p->nSize < Level + 1 )
|
|
Vec_WecPush( p, Level, Entry );
|
|
else
|
|
Vec_IntPushUnique( Vec_WecEntry(p, Level), Entry );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Frees the vector.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline Vec_Wec_t * Vec_WecDup( Vec_Wec_t * p )
|
|
{
|
|
Vec_Wec_t * vNew;
|
|
Vec_Int_t * vVec;
|
|
int i, k, Entry;
|
|
vNew = Vec_WecAlloc( Vec_WecSize(p) );
|
|
Vec_WecForEachLevel( p, vVec, i )
|
|
Vec_IntForEachEntry( vVec, Entry, k )
|
|
Vec_WecPush( vNew, i, Entry );
|
|
return vNew;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Comparison procedure for two arrays.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static int Vec_WecSortCompare1( Vec_Int_t * p1, Vec_Int_t * p2 )
|
|
{
|
|
if ( Vec_IntSize(p1) < Vec_IntSize(p2) )
|
|
return -1;
|
|
if ( Vec_IntSize(p1) > Vec_IntSize(p2) )
|
|
return 1;
|
|
return 0;
|
|
}
|
|
static int Vec_WecSortCompare2( Vec_Int_t * p1, Vec_Int_t * p2 )
|
|
{
|
|
if ( Vec_IntSize(p1) > Vec_IntSize(p2) )
|
|
return -1;
|
|
if ( Vec_IntSize(p1) < Vec_IntSize(p2) )
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Sorting the entries by their integer value.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline void Vec_WecSort( Vec_Wec_t * p, int fReverse )
|
|
{
|
|
if ( fReverse )
|
|
qsort( (void *)p->pArray, p->nSize, sizeof(Vec_Int_t),
|
|
(int (*)(const void *, const void *)) Vec_WecSortCompare2 );
|
|
else
|
|
qsort( (void *)p->pArray, p->nSize, sizeof(Vec_Int_t),
|
|
(int (*)(const void *, const void *)) Vec_WecSortCompare1 );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Comparison procedure for two integers.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static int Vec_WecSortCompare3( Vec_Int_t * p1, Vec_Int_t * p2 )
|
|
{
|
|
if ( Vec_IntEntry(p1,0) < Vec_IntEntry(p2,0) )
|
|
return -1;
|
|
if ( Vec_IntEntry(p1,0) > Vec_IntEntry(p2,0) )
|
|
return 1;
|
|
return 0;
|
|
}
|
|
static int Vec_WecSortCompare4( Vec_Int_t * p1, Vec_Int_t * p2 )
|
|
{
|
|
if ( Vec_IntEntry(p1,0) > Vec_IntEntry(p2,0) )
|
|
return -1;
|
|
if ( Vec_IntEntry(p1,0) < Vec_IntEntry(p2,0) )
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Sorting the entries by their integer value.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline void Vec_WecSortByFirstInt( Vec_Wec_t * p, int fReverse )
|
|
{
|
|
if ( fReverse )
|
|
qsort( (void *)p->pArray, p->nSize, sizeof(Vec_Int_t),
|
|
(int (*)(const void *, const void *)) Vec_WecSortCompare4 );
|
|
else
|
|
qsort( (void *)p->pArray, p->nSize, sizeof(Vec_Int_t),
|
|
(int (*)(const void *, const void *)) Vec_WecSortCompare3 );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline void Vec_WecPrint( Vec_Wec_t * p, int fSkipSingles )
|
|
{
|
|
Vec_Int_t * vVec;
|
|
int i, k, Entry;
|
|
Vec_WecForEachLevel( p, vVec, i )
|
|
{
|
|
if ( fSkipSingles && Vec_IntSize(vVec) == 1 )
|
|
continue;
|
|
printf( " %4d : {", i );
|
|
Vec_IntForEachEntry( vVec, Entry, k )
|
|
printf( " %d", Entry );
|
|
printf( " }\n" );
|
|
}
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis [Derives the set of equivalence classes.]
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline Vec_Wec_t * Vec_WecCreateClasses( Vec_Int_t * vMap )
|
|
{
|
|
Vec_Wec_t * vClasses;
|
|
int i, Entry;
|
|
vClasses = Vec_WecStart( Vec_IntFindMax(vMap) + 1 );
|
|
Vec_IntForEachEntry( vMap, Entry, i )
|
|
Vec_WecPush( vClasses, Entry, i );
|
|
return vClasses;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline int Vec_WecCountNonTrivial( Vec_Wec_t * p, int * pnUsed )
|
|
{
|
|
Vec_Int_t * vClass;
|
|
int i, nClasses = 0;
|
|
*pnUsed = 0;
|
|
Vec_WecForEachLevel( p, vClass, i )
|
|
{
|
|
if ( Vec_IntSize(vClass) < 2 )
|
|
continue;
|
|
nClasses++;
|
|
(*pnUsed) += Vec_IntSize(vClass);
|
|
}
|
|
return nClasses;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline Vec_Int_t * Vec_WecCollectFirsts( Vec_Wec_t * p )
|
|
{
|
|
Vec_Int_t * vFirsts, * vLevel;
|
|
int i;
|
|
vFirsts = Vec_IntAlloc( Vec_WecSize(p) );
|
|
Vec_WecForEachLevel( p, vLevel, i )
|
|
if ( Vec_IntSize(vLevel) > 0 )
|
|
Vec_IntPush( vFirsts, Vec_IntEntry(vLevel, 0) );
|
|
return vFirsts;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
static inline Vec_Ptr_t * Vec_WecConvertToVecPtr( Vec_Wec_t * p )
|
|
{
|
|
Vec_Ptr_t * vCopy;
|
|
Vec_Int_t * vLevel;
|
|
int i;
|
|
vCopy = Vec_PtrAlloc( Vec_WecSize(p) );
|
|
Vec_WecForEachLevel( p, vLevel, i )
|
|
Vec_PtrPush( vCopy, Vec_IntDup(vLevel) );
|
|
return vCopy;
|
|
}
|
|
|
|
ABC_NAMESPACE_HEADER_END
|
|
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|