From a14e2c921fea9a603c4ea7e718958cca7d9b3e94 Mon Sep 17 00:00:00 2001 From: Alan Mishchenko Date: Sun, 9 Aug 2015 22:46:40 -0700 Subject: Improvements to Cba data-structure. --- src/base/cba/cba.h | 26 +++---- src/base/cba/cbaReadVer.c | 179 ++++++++++++++++++++++++++++++++++++++------- src/base/cba/cbaWriteVer.c | 41 ++++++----- src/misc/vec/vecInt.h | 23 ++++-- 4 files changed, 205 insertions(+), 64 deletions(-) diff --git a/src/base/cba/cba.h b/src/base/cba/cba.h index 6e52daea..7dd1b8ac 100644 --- a/src/base/cba/cba.h +++ b/src/base/cba/cba.h @@ -562,6 +562,18 @@ static inline int Cba_NtkNewStrId( Cba_Ntk_t * pNtk, const char * format, ... ) va_end( args ); return Abc_NamStrFindOrAddLim( p, Vec_StrLimit(vBuf), Vec_StrLimit(vBuf) + nAdded, NULL ); } +static inline int Cba_ManNewConstId( Cba_Ntk_t * p, Vec_Str_t * vBits ) +{ + Vec_Str_t * vOut = Abc_NamBuffer(Cba_NtkNam(p)); + Vec_StrPrintF( vOut, "%d\'b%s", Vec_StrSize(vBits)-1, Vec_StrArray(vBits) ); + return Abc_NamStrFindOrAdd(p->pDesign->pFuns, Vec_StrArray(vOut), NULL); +} +static inline int Cba_ManNewConstZero( Cba_Ntk_t * p, int nBits ) +{ + Vec_Str_t * vOut = Abc_NamBuffer(Cba_NtkNam(p)); + Vec_StrPrintF( vOut, "%d\'b%0s", nBits, "" ); + return Abc_NamStrFindOrAdd(p->pDesign->pFuns, Vec_StrArray(vOut), NULL); +} static inline void Cba_NtkAdd( Cba_Man_t * p, Cba_Ntk_t * pNtk ) { int fFound, NtkId = Abc_NamStrFindOrAdd( p->pMods, Cba_NtkName(pNtk), &fFound ); @@ -919,20 +931,6 @@ static inline void Cba_NtkSetMap2( Cba_Ntk_t * p, int i, int x ) { Cba_ManSetM static inline void Cba_NtkUnsetMap2( Cba_Ntk_t * p, int i ) { Cba_ManUnsetMap2(p->pDesign, i); } static inline void Cba_NtkCleanMap2( Cba_Ntk_t * p ) { Cba_ManCleanMap2(p->pDesign); } -static inline int Cba_ManNewConstId( Cba_Man_t * p, Vec_Str_t * vBits ) -{ - Vec_Str_t * vOut = &p->vOut; - char Symb; int i; - assert( Vec_StrSize(vBits) > 0 ); - Vec_StrClear( vOut ); - Vec_StrPrintNum( vOut, Vec_StrSize(vBits) ); - Vec_StrPush( vOut, '\'' ); - Vec_StrPush( vOut, 'b' ); - Vec_StrForEachEntry( vBits, Symb, i ) - Vec_StrPush( vOut, Symb ); - Vec_StrPush( vOut, '\0' ); - return Abc_NamStrFindOrAdd(p->pFuns, Vec_StrArray(vOut), NULL); -} static inline int Cba_ManMemory( Cba_Man_t * p ) { Cba_Ntk_t * pNtk; int i; diff --git a/src/base/cba/cbaReadVer.c b/src/base/cba/cbaReadVer.c index 268742d4..032d75cc 100644 --- a/src/base/cba/cbaReadVer.c +++ b/src/base/cba/cbaReadVer.c @@ -668,8 +668,6 @@ static inline int Prs_ManReadAssign( Prs_Man_t * p ) // check unary operator if ( Prs_ManIsChar(p, ';') ) { - Vec_IntPush( &p->vTemp, 0 ); - Vec_IntPush( &p->vTemp, OutItem ); Oper = fCompl ? CBA_BOX_INV : CBA_BOX_BUF; Prs_NtkAddBox( p->pNtk, Oper, 0, &p->vTemp ); return 1; @@ -1072,7 +1070,7 @@ int Prs_CreateSignalIn( Cba_Ntk_t * p, Prs_Ntk_t * pNtk, int Sig ) assert( Type == CBA_PRS_CONCAT ); return Prs_CreateCatIn( p, pNtk, Value ); } -int Prs_CreateRange( Cba_Ntk_t * p, int iFon, Prs_Ntk_t * pNtk, int NameId ) +int Prs_CreateRange( Cba_Ntk_t * p, int iFon, int NameId ) { int RangeId = -Cba_NtkGetMap(p, NameId); if ( RangeId < 0 ) // this variable is already created @@ -1085,6 +1083,7 @@ int Prs_CreateRange( Cba_Ntk_t * p, int iFon, Prs_Ntk_t * pNtk, int NameId ) Cba_FonSetRange( p, iFon, RangeId ); return Cba_FonRangeSize( p, iFon ); } +/* int Prs_CreateCatOut( Cba_Ntk_t * p, int iFon, Prs_Ntk_t * pNtk, int Con ) { int i, Sig, iObj, iFonNew, NameId, nBits = 0; @@ -1106,14 +1105,14 @@ int Prs_CreateCatOut( Cba_Ntk_t * p, int iFon, Prs_Ntk_t * pNtk, int Con ) pSigName = Prs_NtkStr(pNtk, Value); NameId = Cba_NtkNewStrId( p, pSigName ); Cba_FonSetName( p, iFonNew, NameId ); - nBits += Prs_CreateRange( p, iFonNew, pNtk, NameId ); + nBits += Prs_CreateRange( p, iFonNew, NameId ); } else if ( Type == CBA_PRS_SLICE ) { pSigName = Prs_NtkStr(pNtk, Prs_SliceName(pNtk, Value)); NameId = Cba_NtkNewStrId( p, pSigName ); Cba_FonSetName( p, iFonNew, NameId ); - Prs_CreateRange( p, iFonNew, pNtk, NameId ); + Prs_CreateRange( p, iFonNew, NameId ); // create slice of this concat Prs_CreateSlice( p, iFonNew, pNtk, Prs_SliceRange(pNtk, Value) ); nBits += Cba_NtkRangeSize( p, Prs_SliceRange(pNtk, Value) ); @@ -1123,35 +1122,149 @@ int Prs_CreateCatOut( Cba_Ntk_t * p, int iFon, Prs_Ntk_t * pNtk, int Con ) Cba_FonSetRange( p, iFon, Cba_NtkHashRange(p, nBits-1, 0) ); return iObj; } +*/ void Prs_CreateSignalOut( Cba_Ntk_t * p, int iFon, Prs_Ntk_t * pNtk, int Sig ) { - int iObj, NameId, Value = Abc_Lit2Var2( Sig ); - Prs_ManType_t Type = (Prs_ManType_t)Abc_Lit2Att2( Sig ); + int i, iFonNew, NameOut, RangeOut, NameId, RangeId, RangeSize, nBits = 0; + Prs_ManType_t SigType = (Prs_ManType_t)Abc_Lit2Att2( Sig ); + int SigValue = Abc_Lit2Var2( Sig ); if ( !Sig ) return; - if ( Type == CBA_PRS_NAME ) + if ( SigType == CBA_PRS_NAME ) { - int NameId = Cba_NtkNewStrId(p, Prs_NtkStr(pNtk, Value)); + NameId = SigValue; + if ( !strncmp(Cba_NtkStr(p, NameId), "Open_", 5) ) + return; Cba_FonSetName( p, iFon, NameId ); - Prs_CreateRange( p, iFon, pNtk, NameId ); + Prs_CreateRange( p, iFon, NameId ); return; } - if ( Type == CBA_PRS_SLICE ) + // create name for this fan + NameOut = Cba_NtkNewStrId( p, "_occ%d_", iFon ); + Cba_FonSetName( p, iFon, NameOut ); + Cba_NtkSetMap( p, NameOut, iFon ); + // consider special cases + if ( SigType == CBA_PRS_SLICE ) { - char * pSigName = Prs_NtkStr(pNtk, Prs_SliceName(pNtk, Value)); - // create buffer - iObj = Cba_ObjAlloc( p, CBA_BOX_BUF, 1, 1 ); - Cba_ObjSetFinFon( p, iObj, 0, iFon ); - iFon = Cba_ObjFon0( p, iObj ); - NameId = Cba_NtkNewStrId( p, pSigName ); - Cba_FonSetName( p, iFon, NameId ); - Prs_CreateRange( p, iFon, pNtk, NameId ); - // create slice of this concat - Prs_CreateSlice( p, iFon, pNtk, Prs_SliceRange(pNtk, Value) ); - return; + NameId = Prs_SliceName(pNtk, SigValue); + RangeId = Prs_SliceRange(pNtk, SigValue); + nBits = Cba_NtkRangeSize(p, RangeId); + // save this slice + Vec_IntPushThree( &p->vArray0, NameId, RangeId, iFon ); } - assert( Type == CBA_PRS_CONCAT ); - Prs_CreateCatOut( p, iFon, pNtk, Value ); + else if ( SigType == CBA_PRS_CONCAT ) + { + Vec_Int_t * vSigs = Prs_CatSignals(pNtk, SigValue); + Vec_IntReverseOrder( vSigs ); + Vec_IntForEachEntry( vSigs, Sig, i ) + { + SigType = (Prs_ManType_t)Abc_Lit2Att2( Sig ); + SigValue = Abc_Lit2Var2( Sig ); + if ( SigType == CBA_PRS_NAME ) + { + int iObjBuf, iFonBuf; + // create buffer + NameId = SigValue; + if ( !strncmp(Cba_NtkStr(p, NameId), "Open_", 5) ) + { + nBits++; + continue; + } + iObjBuf = Cba_ObjAlloc( p, CBA_BOX_BUF, 1, 1 ); + iFonBuf = Cba_ObjFon0(p, iObjBuf); + Cba_FonSetName( p, iFonBuf, NameId ); + RangeSize = Prs_CreateRange( p, iFonBuf, NameId ); + RangeOut = Cba_NtkHashRange(p, nBits+RangeSize-1, nBits); + // create slice + iFonNew = Prs_CreateSlice( p, iFon, pNtk, RangeOut ); + Cba_ObjSetFinFon( p, iObjBuf, 0, iFonNew ); + } + else if ( SigType == CBA_PRS_SLICE ) + { + NameId = Prs_SliceName(pNtk, SigValue); + RangeId = Prs_SliceRange(pNtk, SigValue); + RangeSize = Cba_NtkRangeSize(p, RangeId); + RangeOut = Cba_NtkHashRange(p, nBits+RangeSize-1, nBits); + // create slice + iFonNew = Prs_CreateSlice( p, iFon, pNtk, RangeOut ); + // save this slice + Vec_IntPushThree( &p->vArray0, NameId, RangeId, iFonNew ); + } + else assert( 0 ); + // increment complete range + nBits += RangeSize; + } + Vec_IntReverseOrder( vSigs ); + } + else assert( 0 ); + // set the range for the output + Cba_FonHashRange( p, iFon, nBits-1, 0 ); } + +void Prs_CreateOutConcat( Cba_Ntk_t * p, int * pSlices, int nSlices ) +{ + Vec_Int_t * vBits = &p->vArray1; + int NameId = pSlices[0]; + int RangeId = -Cba_NtkGetMap(p, NameId); + int LeftId = Cba_NtkRangeLeft( p, RangeId ); + int RightId = Cba_NtkRangeRight( p, RangeId ); + int BotId = Abc_MinInt( LeftId, RightId ); + int TopId = Abc_MaxInt( LeftId, RightId ); + int RangeSize = Cba_NtkRangeSize( p, RangeId ); + int i, k, iObj, iFon, nParts = 0, Prev = -1, nBits; + assert( RangeId > 0 ); + Vec_IntFill( vBits, Abc_MaxInt(LeftId, RightId) + 1, 0 ); + // fill up with slices + for ( i = 0; i < nSlices; i++ ) + { + int Name = pSlices[3*i+0]; + int Range = pSlices[3*i+1]; + int iFon = pSlices[3*i+2]; + int Size = Cba_NtkRangeSize( p, Range ); + int Left = Cba_NtkRangeLeft( p, Range ); + int Right = Cba_NtkRangeRight( p, Range ); + int Bot = Abc_MinInt( Left, Right ); + int Top = Abc_MaxInt( Left, Right ); + assert( Name == NameId && iFon > 0 ); + assert( TopId >= Top && Bot >= BotId ); + for ( k = Bot; k <= Top; k++ ) + { + assert( Vec_IntEntry(vBits, k) == 0 ); + Vec_IntWriteEntry( vBits, k, iFon ); + } + } + // check how many parts we have + Vec_IntForEachEntryStartStop( vBits, iFon, i, BotId, TopId+1 ) + { + if ( Prev != iFon ) + nParts++; + Prev = iFon; + } + // create new concatenation + iObj = Cba_ObjAlloc( p, CBA_BOX_CATIN, nParts, 1 ); + iFon = Cba_ObjFon0(p, iObj); + Cba_FonSetName( p, iFon, NameId ); + Prs_CreateRange( p, iFon, NameId ); + // set inputs + k = 0; Prev = -1; nBits = 0; + Vec_IntForEachEntryStartStop( vBits, iFon, i, BotId, TopId+1 ) + { + if ( Prev == -1 || Prev == iFon ) + nBits++; + else + { + if ( Prev == 0 ) // create constant + Prev = Cba_ManNewConstZero( p, nBits ); + assert( nBits == Cba_FonRangeSize(p, Prev) ); + Cba_ObjSetFinFon( p, iObj, nParts-1-k++, Prev ); + nBits = 1; + } + Prev = iFon; + } + assert( nBits == Cba_FonRangeSize(p, Prev) ); + Cba_ObjSetFinFon( p, iObj, nParts-1-k++, Prev ); + assert( k == nParts ); +} + // looks at multi-bit signal; if one bit is repeated, returns this bit; otherwise, returns -1 int Prs_CreateBitSignal( Prs_Ntk_t * pNtk, int Sig ) { @@ -1354,7 +1467,7 @@ int Prs_CreateVerilogNtk( Cba_Ntk_t * p, Prs_Ntk_t * pNtk ) iFon = Cba_ObjFon0(p, iObj); NameId = Cba_NtkNewStrId( p, pRamName ); Cba_FonSetName( p, iFon, NameId ); - Prs_CreateRange( p, iFon, pNtk, NameId ); + Prs_CreateRange( p, iFon, NameId ); assert( Cba_FonLeft(p, iFon) <= MemSize-1 ); assert( Cba_FonRight(p, iFon) == 0 ); //Cba_VerificSaveLineFile( p, iObj, pNet->Linefile() ); @@ -1384,6 +1497,7 @@ int Prs_CreateVerilogNtk( Cba_Ntk_t * p, Prs_Ntk_t * pNtk ) Vec_PtrFreeP( &vAllRams ); // create objects + Vec_IntClear( &p->vArray0 ); Prs_NtkForEachBox( pNtk, vBox, i ) { if ( Prs_BoxIsNode(pNtk, i) ) // node @@ -1456,6 +1570,21 @@ int Prs_CreateVerilogNtk( Cba_Ntk_t * p, Prs_Ntk_t * pNtk ) //Cba_VerificSaveLineFile( p, iObj, pInst->Linefile() ); } + // create concatenations for split signals + if ( Vec_IntSize(&p->vArray0) ) + { + int Prev = -1, Index = 0; + Vec_IntSortMulti( &p->vArray0, 3, 0 ); + Vec_IntForEachEntryTriple( &p->vArray0, NameId, RangeId, iFon, i ) + { + if ( Prev != -1 && Prev != NameId ) + Prs_CreateOutConcat( p, Vec_IntArray(&p->vArray0) + Index, (i - Index)/3 ), Index = i; + Prev = NameId; + } + Prs_CreateOutConcat( p, Vec_IntArray(&p->vArray0) + Index, (i - Index)/3 ), Index = i; + //Cba_VerificSaveLineFile( p, iObj, pInst->Linefile() ); + } + // connect objects Prs_NtkForEachBox( pNtk, vBox, i ) { diff --git a/src/base/cba/cbaWriteVer.c b/src/base/cba/cbaWriteVer.c index bf54e2a1..b47ee460 100644 --- a/src/base/cba/cbaWriteVer.c +++ b/src/base/cba/cbaWriteVer.c @@ -44,6 +44,15 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ +static inline char * Prs_ManWriteRange( Prs_Ntk_t * p, int RangeId, int fSlice ) +{ + int Left = RangeId ? Hash_IntObjData0( p->vHash, RangeId ) : 0; + int Right = RangeId ? Hash_IntObjData1( p->vHash, RangeId ) : 0; + if ( Left == Right && fSlice ) + return Vec_StrPrintF( Abc_NamBuffer(p->pStrs), "[%d]", Right ); + else + return Vec_StrPrintF( Abc_NamBuffer(p->pStrs), "[%d:%d]", Left, Right ); +} static void Prs_ManWriteVerilogConcat( FILE * pFile, Prs_Ntk_t * p, int Con ) { extern void Prs_ManWriteVerilogArray( FILE * pFile, Prs_Ntk_t * p, Vec_Int_t * vSigs, int fOdd ); @@ -61,7 +70,7 @@ static void Prs_ManWriteVerilogSignal( FILE * pFile, Prs_Ntk_t * p, int Sig ) else if ( Type == CBA_PRS_CONST ) fprintf( pFile, "%s", Prs_NtkConst(p, Value) ); else if ( Type == CBA_PRS_SLICE ) - fprintf( pFile, "%s%s", Prs_NtkStr(p, Prs_SliceName(p, Value)), Prs_NtkStr(p, Prs_SliceRange(p, Value)) ); + fprintf( pFile, "%s%s", Prs_NtkStr(p, Prs_SliceName(p, Value)), Prs_ManWriteRange(p, Prs_SliceRange(p, Value), 1) ); else if ( Type == CBA_PRS_CONCAT ) Prs_ManWriteVerilogConcat( pFile, p, Value ); else assert( 0 ); @@ -138,7 +147,7 @@ static void Prs_ManWriteVerilogIos( FILE * pFile, Prs_Ntk_t * p, int SigType ) if ( SigType == 3 ) fprintf( pFile, "\n" ); Vec_IntForEachEntryTwo( vSigs[SigType], vSigsR[SigType], NameId, RangeId, i ) - fprintf( pFile, " %s %s%s;\n", pSigNames[SigType], RangeId ? Prs_NtkStr(p, RangeId) : "", Prs_NtkStr(p, NameId) ); + fprintf( pFile, " %s %s%s;\n", pSigNames[SigType], RangeId ? Prs_ManWriteRange(p, RangeId, 0) : "", Prs_NtkStr(p, NameId) ); } static void Prs_ManWriteVerilogIoOrder( FILE * pFile, Prs_Ntk_t * p, Vec_Int_t * vOrder ) { @@ -264,8 +273,7 @@ void Cba_ManCreatePrimMap( char ** pMap ) } - -static inline int Cba_NameIsLegalInVerilog( char * pName ) +static inline int Cba_NameIsLegalInVerilog( char * pName, int NameId ) { // identifier ::= simple_identifier | escaped_identifier // simple_identifier ::= [a-zA-Z_][a-zA-Z0-9_$] @@ -274,6 +282,8 @@ static inline int Cba_NameIsLegalInVerilog( char * pName ) assert( pName != NULL && *pName != '\0' ); if ( *pName == '\\' ) return 1; + if ( NameId < 13 ) // see PRS_VER_UNKNOWN in cbaReadVer.c + return 0; if ( (*pName < 'a' || *pName > 'z') && (*pName < 'A' || *pName > 'Z') && *pName != '_' ) return 0; while ( *(++pName) ) @@ -281,21 +291,12 @@ static inline int Cba_NameIsLegalInVerilog( char * pName ) return 0; return 1; } -static inline char * Cba_NameLegal( char * pName ) -{ - static char pNewName[1000]; - if ( Cba_NameIsLegalInVerilog(pName) ) - return pName; - assert( strlen(pName) < 1000 ); - sprintf( pNewName, "\\%s ", pName ); - return pNewName; -} char * Cba_ObjGetName( Cba_Ntk_t * p, int i ) { char * pName = Cba_ObjNameStr(p, i); if ( pName == NULL ) return pName; - if ( Cba_NameIsLegalInVerilog(pName) ) + if ( Cba_NameIsLegalInVerilog(pName, Cba_ObjName(p, i)) ) return pName; return Vec_StrPrintF( Abc_NamBuffer(Cba_NtkNam(p)), "\\%s ", pName ); } @@ -306,7 +307,7 @@ char * Cba_FonGetName( Cba_Ntk_t * p, int i ) return pName; if ( Cba_ObjType(p, Cba_FonObj(p, i)) == CBA_BOX_SLICE ) return pName; - if ( Cba_NameIsLegalInVerilog(pName) ) + if ( Cba_NameIsLegalInVerilog(pName, Cba_FonName(p, i)) ) return pName; return Vec_StrPrintF( Abc_NamBuffer(Cba_NtkNam(p)), "\\%s ", pName ); } @@ -315,7 +316,7 @@ char * Cba_ManGetSliceName( Cba_Ntk_t * p, int iFon, int RangeId ) int Left = Cba_NtkRangeLeft(p, RangeId); int Right = Cba_NtkRangeRight(p, RangeId); char * pName = Cba_FonNameStr(p, iFon); - if ( Cba_NameIsLegalInVerilog(pName) ) + if ( Cba_NameIsLegalInVerilog(pName, Cba_FonName(p, iFon)) ) if ( Left == Right ) return Vec_StrPrintF( Abc_NamBuffer(Cba_NtkNam(p)), "%s[%d]", pName, Right ); else @@ -330,7 +331,7 @@ char * Cba_ManGetSliceName( Cba_Ntk_t * p, int iFon, int RangeId ) void Cba_ManWriteFonRange( Cba_Ntk_t * p, int iFon ) { Vec_Str_t * vStr = &p->pDesign->vOut; - if ( Cba_FonIsConst(iFon) || (Cba_FonRangeSize(p, iFon) == 1 && Cba_FonRight(p, iFon) == 0) ) + if ( !iFon || Cba_FonIsConst(iFon) || (Cba_FonRangeSize(p, iFon) == 1 && Cba_FonRight(p, iFon) == 0) ) return; Vec_StrPrintF( vStr, "[%d:%d] ", Cba_FonLeft(p, iFon), Cba_FonRight(p, iFon) ); @@ -340,8 +341,8 @@ void Cba_ManWriteFonName( Cba_Ntk_t * p, int iFon, int fInlineConcat, int fInput extern void Cba_ManWriteCatIn( Cba_Ntk_t * p, int iObj ); Vec_Str_t * vStr = &p->pDesign->vOut; if ( !iFon || (!Cba_FonIsConst(iFon) && !Cba_FonName(p, iFon)) ) -// Vec_StrPrintF( vStr, "Open_%d", Cba_NtkMan(p)->nOpens++ ); - Vec_StrPrintF( vStr, "1\'b0" ); + Vec_StrPrintF( vStr, "Open_%d", Cba_NtkMan(p)->nOpens++ ); +// Vec_StrPrintF( vStr, "1\'b0" ); else if ( fInlineConcat && !Cba_FonIsConst(iFon) && Cba_ObjIsCatIn(p, Cba_FonObj(p, iFon)) ) Cba_ManWriteCatIn( p, Cba_FonObj(p, iFon) ); else @@ -858,7 +859,7 @@ void Cba_ManWriteVerilogNtk( Cba_Ntk_t * p, int fInlineConcat ) Cba_NtkForEachPo( p, iObj, i ) { iFon = Cba_ObjFinFon(p, iObj, 0); - if ( !Cba_FonIsConst(iFon) && Cba_FonName(p, iFon) == Cba_ObjName(p, iObj) ) // already written + if ( !iFon || !Cba_FonIsConst(iFon) && Cba_FonName(p, iFon) == Cba_ObjName(p, iObj) ) // already written continue; Vec_StrPrintStr( vStr, " assign " ); Vec_StrPrintStr( vStr, Cba_ObjGetName(p, iObj) ); diff --git a/src/misc/vec/vecInt.h b/src/misc/vec/vecInt.h index 2487911a..785b0aef 100644 --- a/src/misc/vec/vecInt.h +++ b/src/misc/vec/vecInt.h @@ -728,6 +728,19 @@ static inline void Vec_IntPushTwo( Vec_Int_t * p, int Entry1, int Entry2 ) Vec_IntPush( p, Entry1 ); Vec_IntPush( p, Entry2 ); } +static inline void Vec_IntPushThree( Vec_Int_t * p, int Entry1, int Entry2, int Entry3 ) +{ + Vec_IntPush( p, Entry1 ); + Vec_IntPush( p, Entry2 ); + Vec_IntPush( p, Entry3 ); +} +static inline void Vec_IntPushFour( Vec_Int_t * p, int Entry1, int Entry2, int Entry3, int Entry4 ) +{ + Vec_IntPush( p, Entry1 ); + Vec_IntPush( p, Entry2 ); + Vec_IntPush( p, Entry3 ); + Vec_IntPush( p, Entry4 ); +} static inline void Vec_IntPushArray( Vec_Int_t * p, int * pEntries, int nEntries ) { int i; @@ -1338,14 +1351,14 @@ static inline void Vec_IntSort( Vec_Int_t * p, int fReverse ) qsort( (void *)p->pArray, p->nSize, sizeof(int), (int (*)(const void *, const void *)) Vec_IntSortCompare1 ); } -static inline void Vec_IntSortPairs( Vec_Int_t * p, int fReverse ) +static inline void Vec_IntSortMulti( Vec_Int_t * p, int nMulti, int fReverse ) { - assert( Vec_IntSize(p) % 2 == 0 ); + assert( Vec_IntSize(p) % nMulti == 0 ); if ( fReverse ) - qsort( (void *)p->pArray, p->nSize/2, 2*sizeof(int), + qsort( (void *)p->pArray, p->nSize/nMulti, nMulti*sizeof(int), (int (*)(const void *, const void *)) Vec_IntSortCompare2 ); else - qsort( (void *)p->pArray, p->nSize/2, 2*sizeof(int), + qsort( (void *)p->pArray, p->nSize/nMulti, nMulti*sizeof(int), (int (*)(const void *, const void *)) Vec_IntSortCompare1 ); } @@ -1419,7 +1432,7 @@ static inline int Vec_IntUniqifyPairs( Vec_Int_t * p ) assert( p->nSize % 2 == 0 ); if ( p->nSize < 4 ) return 0; - Vec_IntSortPairs( p, 0 ); + Vec_IntSortMulti( p, 2, 0 ); for ( i = k = 1; i < p->nSize/2; i++ ) if ( p->pArray[2*i] != p->pArray[2*(i-1)] || p->pArray[2*i+1] != p->pArray[2*(i-1)+1] ) { -- cgit v1.2.3