Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 30 additions & 23 deletions src/aig/aig/aigTable.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,25 @@ ABC_NAMESPACE_IMPL_START
// terms multiply a 0/1 flag by a small constant. Doing those two in unsigned
// arithmetic is defined for every Id and keeps the result a function of the
// operands alone.
static unsigned long Aig_Hash( Aig_Obj_t * pObj, int TableSize )
//
// The mixed key is reduced to a bucket with two multiplies rather than with a
// remainder, which is a hardware divide by a runtime value on the hottest path
// this package has. The key is multiplied by an odd 64-bit constant and the
// high half of the product taken, which every input bit has had an effect on;
// that is then mapped onto the table by multiplying it by the table size and
// taking the high half again. Neither step needs the size to be a power of
// two: nTableSize is a public field and a client may size the table itself.
#define AIG_HASH_MULT ABC_CONST(0x9E3779B97F4A7C15)

static unsigned Aig_Hash( Aig_Obj_t * pObj, int TableSize )
{
unsigned long Key = Aig_ObjIsExor(pObj) * 1699;
unsigned Key = Aig_ObjIsExor(pObj) * 1699, Hash;
Key ^= (unsigned)Aig_ObjFanin0(pObj)->Id * 7937u;
Key ^= (unsigned)Aig_ObjFanin1(pObj)->Id * 2971u;
Key ^= Aig_ObjFaninC0(pObj) * 911;
Key ^= Aig_ObjFaninC1(pObj) * 353;
return Key % TableSize;
Hash = (unsigned)(((word)Key * AIG_HASH_MULT) >> 32);
return (unsigned)(((word)Hash * (word)(unsigned)TableSize) >> 32);
}

// returns the place where this node is stored (or should be stored)
Expand Down Expand Up @@ -76,38 +87,34 @@ static Aig_Obj_t ** Aig_TableFind( Aig_Man_t * p, Aig_Obj_t * pObj )
***********************************************************************/
void Aig_TableResize( Aig_Man_t * p )
{
Aig_Obj_t * pEntry, * pNext;
Aig_Obj_t ** pTableOld, ** ppPlace;
int nTableSizeOld, Counter, i;
abctime clk;
Aig_Obj_t * pEntry;
Aig_Obj_t ** ppPlace;
int Counter, i;
assert( p->pTable != NULL );
clk = Abc_Clock();
// save the old table
pTableOld = p->pTable;
nTableSizeOld = p->nTableSize;
// get the new table
p->nTableSize = Abc_PrimeCudd( 2 * Aig_ManNodeNum(p) );
// The table is rebuilt from vObjs rather than from the old buckets, so
// the old array can be freed before the new one is allocated: the
// resize transient is max(old, new) instead of their sum, and the
// sweep reads the nodes sequentially where chain-chasing did not.
// Membership is unchanged -- the table holds exactly the AND and EXOR
// nodes, which is the invariant the Counter assert below has always
// stated, and the hash is recomputed from each node's fanins either
// way. Stale pNext values from the freed chains are never read: a
// node's pNext is only walked once it is in the new table, and it is
// nulled at insertion.
ABC_FREE( p->pTable );
p->nTableSize = Abc_PrimeCudd( 2 * Aig_ManNodeNum(p) );
p->pTable = ABC_ALLOC( Aig_Obj_t *, p->nTableSize );
memset( p->pTable, 0, sizeof(Aig_Obj_t *) * p->nTableSize );
// rehash the entries from the old table
Counter = 0;
for ( i = 0; i < nTableSizeOld; i++ )
for ( pEntry = pTableOld[i], pNext = pEntry? pEntry->pNext : NULL;
pEntry; pEntry = pNext, pNext = pEntry? pEntry->pNext : NULL )
Aig_ManForEachNode( p, pEntry, i )
{
// get the place where this entry goes in the table
ppPlace = Aig_TableFind( p, pEntry );
assert( *ppPlace == NULL ); // should not be there
// add the entry to the list
*ppPlace = pEntry;
pEntry->pNext = NULL;
Counter++;
}
assert( Counter == Aig_ManNodeNum(p) );
// printf( "Increasing the structural table size from %6d to %6d. ", nTableSizeOld, p->nTableSize );
// ABC_PRT( "Time", Abc_Clock() - clk );
// replace the table and the parameters
ABC_FREE( pTableOld );
}

/**Function*************************************************************
Expand Down
11 changes: 9 additions & 2 deletions src/aig/gia/giaHash.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ ABC_NAMESPACE_IMPL_START
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////

// The mixed key is reduced to a bucket with two multiplies rather than with a
// remainder, for the reason given over Aig_Hash() in aigTable.c: a remainder
// by a runtime table size is a hardware divide on every lookup and every
// insert, and this reduction needs no power-of-two table to avoid it.
#define GIA_HASH_MULT ABC_CONST(0x9E3779B97F4A7C15)

/**Function*************************************************************

Synopsis [Returns the place where this node is stored (or should be stored).]
Expand All @@ -44,12 +50,13 @@ ABC_NAMESPACE_IMPL_START
***********************************************************************/
static inline int Gia_ManHashOne( int iLit0, int iLit1, int iLitC, int TableSize )
{
unsigned Key = iLitC * 2011;
unsigned Key = iLitC * 2011, Hash;
Key += Abc_Lit2Var(iLit0) * 7937;
Key += Abc_Lit2Var(iLit1) * 2971;
Key += Abc_LitIsCompl(iLit0) * 911;
Key += Abc_LitIsCompl(iLit1) * 353;
return (int)(Key % TableSize);
Hash = (unsigned)(((word)Key * GIA_HASH_MULT) >> 32);
return (int)(((word)Hash * (word)(unsigned)TableSize) >> 32);
}
static inline int * Gia_ManHashFind( Gia_Man_t * p, int iLit0, int iLit1, int iLitC )
{
Expand Down
Loading