25static inline int Fxch_ManSCAddRemove(
Fxch_Man_t* pFxchMan,
26 unsigned int SubCubeID,
39 iCube, iLit0, iLit1, fUpdate );
45 iCube, iLit0, iLit1, fUpdate );
52static inline int Fxch_ManDivSingleCube(
Fxch_Man_t* pFxchMan,
64 if ( Vec_IntSize( vCube ) < 2 )
70 int * pOutputID, nOnes, j, z;
74 Vec_IntPush( pFxchMan->
vCubeFree, Abc_Var2Lit( Abc_LitNot( Lit0 ), 0 ) );
75 Vec_IntPush( pFxchMan->
vCubeFree, Abc_Var2Lit( Abc_LitNot( Lit1 ), 1 ) );
81 nOnes += Fxch_CountOnes( pOutputID[j] );
88 for ( z = 0; z < nOnes; z++ )
89 Fxch_DivAdd( pFxchMan, fUpdate, fSingleCube, fBase );
94 for ( z = 0; z < nOnes; z++ )
100 return Vec_IntSize( vCube ) * ( Vec_IntSize( vCube ) - 1 ) / 2;
103static inline void Fxch_ManDivDoubleCube(
Fxch_Man_t* pFxchMan,
109 * vCube = Vec_WecEntry( pFxchMan->
vCubes, iCube );
115 SubCubeID += Vec_IntEntry( vLitHashKeys, Lit0 );
117 Fxch_ManSCAddRemove( pFxchMan, SubCubeID,
119 (
char)fAdd, (
char)fUpdate );
124 SubCubeID -= Vec_IntEntry( vLitHashKeys, Lit0 );
126 pFxchMan->nPairsD += Fxch_ManSCAddRemove( pFxchMan, SubCubeID,
128 (
char)fAdd, (
char)fUpdate );
130 if ( Vec_IntSize( vCube ) >= 3 )
138 SubCubeID -= Vec_IntEntry( vLitHashKeys, Lit1 );
140 pFxchMan->nPairsD += Fxch_ManSCAddRemove( pFxchMan, SubCubeID,
142 (
char)fAdd, (
char)fUpdate );
144 SubCubeID += Vec_IntEntry( vLitHashKeys, Lit1 );
148 SubCubeID += Vec_IntEntry( vLitHashKeys, Lit0 );
152static inline void Fxch_ManCompressCubes(
Vec_Wec_t* vCubes,
160 if ( Vec_IntSize(Vec_WecEntry(vCubes, CubeId)) > 0 )
161 Vec_IntWriteEntry( vLit2Cube, k++, CubeId );
163 Vec_IntShrink( vLit2Cube, k );
173 pFxchMan->
vCubes = vCubes;
176 pFxchMan->
pDivHash = Hsh_VecManStart( 1024 );
181 pFxchMan->
vDiv = Vec_IntAlloc( 4 );
183 pFxchMan->
vCubesS = Vec_IntAlloc( 128 );
184 pFxchMan->
vPairs = Vec_IntAlloc( 128 );
187 pFxchMan->
vSCC = Vec_IntAlloc( 64 );
194 Vec_WecFree( pFxchMan->
vLits );
197 Hsh_VecManStop( pFxchMan->
pDivHash );
201 Vec_IntFree( pFxchMan->
vLevels );
204 Vec_IntFree( pFxchMan->
vDiv );
206 Vec_IntFree( pFxchMan->
vCubesS );
207 Vec_IntFree( pFxchMan->
vPairs );
210 Vec_IntFree( pFxchMan->
vSCC );
228 assert( Vec_IntSize(vCube) > 0 );
229 pFxchMan->
nVars = Abc_MaxInt( pFxchMan->
nVars, Vec_IntEntry( vCube, 0 ) );
230 pFxchMan->
nLits += Vec_IntSize(vCube) - 1;
232 pFxchMan->
nVars = Abc_MaxInt( pFxchMan->
nVars, Abc_Lit2Var( Lit ) );
236 pFxchMan->
nVars = nVars;
242 Vec_IntAddToEntry( pFxchMan->
vLitCount, Lit, 1 );
245 pFxchMan->
vLits = Vec_WecStart( 2 * pFxchMan->
nVars );
247 Vec_IntGrow( Vec_WecEntry( pFxchMan->
vLits, Lit ), Count );
252 Vec_WecPush( pFxchMan->
vLits, Lit, i );
261 for ( i = 0; i < (2 * pFxchMan->
nVars); i++ )
274 int nLits = Vec_IntSize( vCube ) - 1,
275 nSubCubes = nLits <= 2? nLits + 1: ( nLits * nLits + nLits ) / 2;
277 nTotalHashed += nSubCubes + 1;
298 Fxch_ManDivSingleCube( pFxchMan, iCube, fAdd, fUpdate );
299 Fxch_ManDivDoubleCube( pFxchMan, iCube, fAdd, fUpdate );
307 Vec_QuePush( pFxchMan->
vDivPrio, iCube );
320 Level = Abc_MaxInt( Level, Vec_IntEntry( pFxchMan->
vLevels, Abc_Lit2Var( Abc_Lit2Var( Lit ) ) ) );
322 return Abc_MinInt( Level, 800 );
333 Level = Abc_MaxInt( Level, Vec_IntEntry( pFxchMan->
vLevels, Abc_Lit2Var( Lit ) ) );
345 iVar = Vec_IntEntry( Vec_WecEntry( pFxchMan->
vCubes, 0 ), 0 );
350 if ( iVar != Vec_IntEntry( vCube, 0 ) )
352 Vec_IntAddToEntry( pFxchMan->
vLevels, iVar, i - iFirst );
353 iVar = Vec_IntEntry( vCube, 0 );
361static inline void Fxch_ManExtractDivFromCube(
Fxch_Man_t* pFxchMan,
374 vCube0 = Fxch_ManGetCube( pFxchMan, iCube0 );
375 RetValue = Vec_IntRemove1( vCube0, Abc_LitNot( Lit0 ) );
376 RetValue += Vec_IntRemove1( vCube0, Abc_LitNot( Lit1 ) );
379 Vec_IntPush( vCube0, Abc_Var2Lit( iVarNew, 0 ) );
380 Vec_IntPush( vLitP, Vec_WecLevelId( pFxchMan->
vCubes, vCube0 ) );
388static inline void Fxch_ManExtractDivFromCubePairs(
Fxch_Man_t* pFxchMan,
392 int iCube0, iCube1, i;
400 int * pOutputID0, * pOutputID1;
403 * vCube0 = Fxch_ManGetCube( pFxchMan, iCube0 ),
404 * vCube1 = Fxch_ManGetCube( pFxchMan, iCube1 ),
405 * vCube0Copy = Vec_IntDup( vCube0 ),
406 * vCube1Copy = Vec_IntDup( vCube1 );
410 assert( RetValue == Vec_IntSize( pFxchMan->
vDiv ) );
412 pFxchMan->
nLits -= Vec_IntSize( pFxchMan->
vDiv ) + Vec_IntSize( vCube1 ) - 2;
419 RetValue = ( pOutputID0[j] == pOutputID1[j] );
424 Vec_IntClear( vCube0 );
425 Vec_IntAppend( vCube0, vCube0Copy );
429 Vec_IntClear( vCube1 );
434 Vec_IntRemove( Vec_WecEntry( pFxchMan->
vLits, Abc_Lit2Var( Lit ) ),
435 Vec_WecLevelId( pFxchMan->
vCubes, vCube0 ) );
436 Vec_IntRemove( Vec_WecEntry( pFxchMan->
vLits, Abc_LitNot( Abc_Lit2Var( Lit ) ) ),
437 Vec_WecLevelId( pFxchMan->
vCubes, vCube0 ) );
445 pFxchMan->
pTempOutputID[j] = ( pOutputID0[j] & pOutputID1[j] );
448 vCube = Vec_WecPushLevel( pFxchMan->
vCubes );
449 Vec_IntAppend( vCube, vCube0Copy );
455 Vec_WecPush( pFxchMan->vLits, Lit, Vec_WecLevelId( pFxchMan->vCubes, vCube ) );
459 for ( j = 0; j < pFxchMan->nSizeOutputID; j++ )
462 RetValue |= ( pOutputID0[j] & ~( pOutputID1[j] ) );
463 pOutputID0[j] &= ~( pOutputID1[j] );
469 Vec_IntClear( vCube0 );
475 RetValue |= ( pOutputID1[j] & ~( pFxchMan->
pTempOutputID[j] ) );
482 Vec_IntClear( vCube1 );
485 Vec_IntFree( vCube0Copy );
486 Vec_IntFree( vCube1Copy );
491 * vLitN = Vec_WecEntry( pFxchMan->
vLits, Vec_WecSize( pFxchMan->
vLits ) - 1 );
494 if ( Vec_IntSize( pFxchMan->
vDiv ) == 2 || fCompl )
496 Vec_IntPush( vCube, Abc_Var2Lit( iVarNew, 1 ) );
497 Vec_IntPush( vLitN, Vec_WecLevelId( pFxchMan->
vCubes, vCube ) );
498 Vec_IntSort( vLitN, 0 );
502 Vec_IntPush( vCube, Abc_Var2Lit( iVarNew, 0 ) );
503 Vec_IntPush( vLitP, Vec_WecLevelId( pFxchMan->
vCubes, vCube ) );
504 Vec_IntSort( vLitP, 0 );
512static inline int Fxch_ManCreateCube(
Fxch_Man_t* pFxchMan,
523 iVarNew = pFxchMan->
nVars;
535 vCube0 = Vec_WecPushLevel( pFxchMan->
vCubes );
536 Vec_IntPush( vCube0, iVarNew );
539 if ( Vec_IntSize( pFxchMan->
vDiv ) == 2 )
544 Vec_IntPush( vCube0, Abc_LitNot( Lit0 ) );
545 Vec_IntPush( vCube0, Abc_LitNot( Lit1 ) );
553 vCube1 = Vec_WecPushLevel( pFxchMan->
vCubes );
554 Vec_IntPush( vCube1, iVarNew );
557 vCube0 = Fxch_ManGetCube( pFxchMan, Vec_WecSize( pFxchMan->
vCubes ) - 2 );
567 Vec_WecPush( pFxchMan->vLits, Lit, Vec_WecLevelId( pFxchMan->vCubes, vCube0 ) );
570 Vec_WecPush( pFxchMan->vLits, Lit, Vec_WecLevelId( pFxchMan->vCubes, vCube1 ) );
572 assert( Vec_IntSize( pFxchMan->vLevels ) == iVarNew );
573 Vec_IntPush( pFxchMan->vLevels, Level );
575 pFxchMan->nLits += Vec_IntSize( pFxchMan->vDiv );
578 Vec_WecPushLevel( pFxchMan->vLits );
579 Vec_WecPushLevel( pFxchMan->vLits );
587 int i, iCube0, iCube1,
597 Vec_IntClear( pFxchMan->vDiv );
598 Vec_IntAppend( pFxchMan->vDiv, Hsh_VecReadEntry( pFxchMan->pDivHash, iDiv ) );
601 Vec_IntClear( pFxchMan->vCubesS );
602 if ( Vec_IntSize( pFxchMan->vDiv ) == 2 )
604 Lit0 = Abc_Lit2Var( Vec_IntEntry( pFxchMan->vDiv, 0 ) );
605 Lit1 = Abc_Lit2Var( Vec_IntEntry( pFxchMan->vDiv, 1 ) );
606 assert( Lit0 >= 0 && Lit1 >= 0 );
608 Fxch_ManCompressCubes( pFxchMan->vCubes, Vec_WecEntry( pFxchMan->vLits, Abc_LitNot( Lit0 ) ) );
609 Fxch_ManCompressCubes( pFxchMan->vCubes, Vec_WecEntry( pFxchMan->vLits, Abc_LitNot( Lit1 ) ) );
610 Vec_IntTwoRemoveCommon( Vec_WecEntry( pFxchMan->vLits, Abc_LitNot( Lit0 ) ),
611 Vec_WecEntry( pFxchMan->vLits, Abc_LitNot( Lit1 ) ),
616 Vec_IntClear( pFxchMan->vPairs );
617 vDivCubePairs = Vec_WecEntry( pFxchMan->vDivCubePairs, iDiv );
618 Vec_IntAppend( pFxchMan->vPairs, vDivCubePairs );
619 Vec_IntErase( vDivCubePairs );
623 assert( Fxch_ManGetLit( pFxchMan, iCube0, 0) == Fxch_ManGetLit( pFxchMan, iCube1, 0) );
626 Vec_IntSetEntry( pFxchMan->vPairs, i, iCube1);
627 Vec_IntSetEntry( pFxchMan->vPairs, i+1, iCube0);
631 Vec_IntUniqifyPairs( pFxchMan->vPairs );
632 assert( Vec_IntSize( pFxchMan->vPairs ) % 2 == 0 );
637 Fxch_ManDivSingleCube( pFxchMan, iCube0, 0, 1);
639 if ( Vec_WecEntryEntry( pFxchMan->vCubes, iCube0, 0 ) == 0 )
640 Fxch_ManDivDoubleCube( pFxchMan, iCube0, 0, 1 );
645 Fxch_ManDivSingleCube( pFxchMan, iCube0, 0, 1);
647 if ( Vec_WecEntryEntry( pFxchMan->vCubes, iCube0, 0 ) == 0 )
648 Fxch_ManDivDoubleCube( pFxchMan, iCube0, 0, 1 );
651 Vec_IntClear( pFxchMan->vCubesToUpdate );
654 iVarNew = Fxch_ManCreateCube( pFxchMan, Lit0, Lit1 );
655 Fxch_ManExtractDivFromCube( pFxchMan, Lit0, Lit1, iVarNew );
656 Fxch_ManExtractDivFromCubePairs( pFxchMan, iVarNew );
659 Fxch_ManExtractDivFromCubePairs( pFxchMan, 0 );
661 assert( Vec_IntSize( pFxchMan->vCubesToUpdate ) );
666 Fxch_ManDivSingleCube( pFxchMan, iCube0, 1, 1 );
668 if ( Vec_WecEntryEntry( pFxchMan->vCubes, iCube0, 0 ) == 0 )
669 Fxch_ManDivDoubleCube( pFxchMan, iCube0, 1, 1 );
673 if ( Vec_IntSize( pFxchMan->vSCC ) )
675 Vec_IntUniqifyPairs( pFxchMan->vSCC );
676 assert( Vec_IntSize( pFxchMan->vSCC ) % 2 == 0 );
681 int* pOutputID0 = Vec_IntEntryP( pFxchMan->vOutputID, iCube0 * pFxchMan->nSizeOutputID );
682 int* pOutputID1 = Vec_IntEntryP( pFxchMan->vOutputID, iCube1 * pFxchMan->nSizeOutputID );
683 vCube0 = Vec_WecEntry( pFxchMan->vCubes, iCube0 );
684 vCube1 = Vec_WecEntry( pFxchMan->vCubes, iCube1 );
686 if ( !Vec_WecIntHasMark( vCube0 ) )
688 Fxch_ManDivSingleCube( pFxchMan, iCube0, 0, 1 );
689 Fxch_ManDivDoubleCube( pFxchMan, iCube0, 0, 1 );
690 Vec_WecIntSetMark( vCube0 );
693 if ( !Vec_WecIntHasMark( vCube1 ) )
695 Fxch_ManDivSingleCube( pFxchMan, iCube1, 0, 1 );
696 Fxch_ManDivDoubleCube( pFxchMan, iCube1, 0, 1 );
697 Vec_WecIntSetMark( vCube1 );
700 if ( Vec_IntSize( vCube0 ) == Vec_IntSize( vCube1 ) )
702 for ( j = 0; j < pFxchMan->nSizeOutputID; j++ )
704 pOutputID1[j] |= pOutputID0[j];
707 Vec_IntClear( Vec_WecEntry( pFxchMan->vCubes, iCube0 ) );
708 Vec_WecIntXorMark( vCube0 );
712 for ( j = 0; j < pFxchMan->nSizeOutputID && RetValue; j++ )
713 RetValue = ( pOutputID0[j] == pOutputID1[j] );
717 Vec_IntClear( Vec_WecEntry( pFxchMan->vCubes, iCube0 ) );
718 Vec_WecIntXorMark( vCube0 );
723 for ( j = 0; j < pFxchMan->nSizeOutputID; j++ )
725 RetValue |= ( pOutputID0[j] & ~( pOutputID1[j] ) );
726 pOutputID0[j] &= ~( pOutputID1[j] );
731 Vec_IntClear( Vec_WecEntry( pFxchMan->vCubes, iCube0 ) );
732 Vec_WecIntXorMark( vCube0 );
739 vCube0 = Vec_WecEntry( pFxchMan->vCubes, iCube0 );
740 vCube1 = Vec_WecEntry( pFxchMan->vCubes, iCube1 );
742 if ( Vec_WecIntHasMark( vCube0 ) )
744 Fxch_ManDivSingleCube( pFxchMan, iCube0, 1, 1 );
745 Fxch_ManDivDoubleCube( pFxchMan, iCube0, 1, 1 );
746 Vec_WecIntXorMark( vCube0 );
749 if ( Vec_WecIntHasMark( vCube1 ) )
751 Fxch_ManDivSingleCube( pFxchMan, iCube1, 1, 1 );
752 Fxch_ManDivDoubleCube( pFxchMan, iCube1, 1, 1 );
753 Vec_WecIntXorMark( vCube1 );
757 Vec_IntClear( pFxchMan->vSCC );
760 pFxchMan->nExtDivs++;
768 for ( iDiv = 0; iDiv < Vec_FltSize( pFxchMan->
vDivWeights ); iDiv++ )
774 printf(
"Cubes =%8d ", Vec_WecSizeUsed( pFxchMan->
vCubes ) );
775 printf(
"Lits =%8d ", Vec_WecSizeUsed( pFxchMan->
vLits ) );
776 printf(
"Divs =%8d ", Hsh_VecSize( pFxchMan->
pDivHash ) );
777 printf(
"Divs+ =%8d ", Vec_QueSize( pFxchMan->
vDivPrio ) );
778 printf(
"Extr =%7d \n", pFxchMan->
nExtDivs );
void Fxch_ManSCHashTablesFree(Fxch_Man_t *pFxchMan)
void Fxch_ManMapLiteralsIntoCubes(Fxch_Man_t *pFxchMan, int nVars)
int Fxch_ManComputeLevelDiv(Fxch_Man_t *pFxchMan, Vec_Int_t *vCubeFree)
int Fxch_ManComputeLevelCube(Fxch_Man_t *pFxchMan, Vec_Int_t *vCube)
void Fxch_ManDivCreate(Fxch_Man_t *pFxchMan)
Fxch_Man_t * Fxch_ManAlloc(Vec_Wec_t *vCubes)
PUBLIC INTERFACE ///.
void Fxch_ManPrintStats(Fxch_Man_t *pFxchMan)
void Fxch_ManFree(Fxch_Man_t *pFxchMan)
void Fxch_ManComputeLevel(Fxch_Man_t *pFxchMan)
void Fxch_ManPrintDivs(Fxch_Man_t *pFxchMan)
void Fxch_ManSCHashTablesInit(Fxch_Man_t *pFxchMan)
void Fxch_ManGenerateLitHashKeys(Fxch_Man_t *pFxchMan)
int Fxch_DivAdd(Fxch_Man_t *pFxchMan, int fUpdate, int fSingleCube, int fBase)
Fxch_SCHashTable_t * Fxch_SCHashTableCreate(Fxch_Man_t *pFxchMan, int nEntries)
int Fxch_DivRemoveLits(Vec_Int_t *vCube0, Vec_Int_t *vCube1, Vec_Int_t *vDiv, int *fCompl)
int Fxch_ManComputeLevelCube(Fxch_Man_t *pFxchMan, Vec_Int_t *vCube)
int Fxch_DivIsNotConstant1(Vec_Int_t *vDiv)
int Fxch_SCHashTableRemove(Fxch_SCHashTable_t *pSCHashTable, Vec_Wec_t *vCubes, uint32_t SubCubeID, uint32_t iCube, uint32_t iLit0, uint32_t iLit1, char fUpdate)
void Fxch_DivSepareteCubes(Vec_Int_t *vDiv, Vec_Int_t *vCube0, Vec_Int_t *vCube1)
void Fxch_DivPrint(Fxch_Man_t *pFxchMan, int iDiv)
int Fxch_DivRemove(Fxch_Man_t *pFxchMan, int fUpdate, int fSingleCube, int fBase)
void Fxch_SCHashTableDelete(Fxch_SCHashTable_t *)
int Fxch_SCHashTableInsert(Fxch_SCHashTable_t *pSCHashTable, Vec_Wec_t *vCubes, uint32_t SubCubeID, uint32_t iCube, uint32_t iLit0, uint32_t iLit1, char fUpdate)
#define ABC_SWAP(Type, a, b)
#define ABC_CALLOC(type, num)
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
unsigned Gia_ManRandom(int fReset)
FUNCTION DEFINITIONS ///.
struct Fxch_Man_t_ Fxch_Man_t
TYPEDEF DECLARATIONS ///.
void Fxch_ManUpdate(Fxch_Man_t *p, int iDiv)
for(p=first;p->value< newval;p=p->next)
Vec_Int_t * vCubesToUpdate
Vec_Int_t * vCubesToRemove
Fxch_SCHashTable_t * pSCHashTable
Vec_Wec_t * vDivCubePairs
#define Vec_FltForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
#define Vec_IntForEachEntryDouble(vVec, Entry1, Entry2, i)
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
#define Vec_IntForEachEntryStart(vVec, Entry, i, Start)
#define Vec_WecForEachLevel(vGlob, vVec, i)
MACRO DEFINITIONS ///.
typedefABC_NAMESPACE_HEADER_START struct Vec_Wec_t_ Vec_Wec_t
INCLUDES ///.