hopTable.c 6.93 KB
Newer Older
Alan Mishchenko committed
1 2
/**CFile****************************************************************

Alan Mishchenko committed
3
  FileName    [hopTable.c]
Alan Mishchenko committed
4 5 6 7 8 9 10 11 12 13 14 15 16

  SystemName  [ABC: Logic synthesis and verification system.]

  PackageName [Minimalistic And-Inverter Graph package.]

  Synopsis    [Structural hashing table.]

  Author      [Alan Mishchenko]
  
  Affiliation [UC Berkeley]

  Date        [Ver. 1.0. Started - May 11, 2006. ]

Alan Mishchenko committed
17
  Revision    [$Id: hopTable.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]
Alan Mishchenko committed
18 19 20

***********************************************************************/

Alan Mishchenko committed
21
#include "hop.h"
Alan Mishchenko committed
22

23 24 25
ABC_NAMESPACE_IMPL_START


Alan Mishchenko committed
26 27 28 29 30
////////////////////////////////////////////////////////////////////////
///                        DECLARATIONS                              ///
////////////////////////////////////////////////////////////////////////

// hashing the node
Alan Mishchenko committed
31
static unsigned long Hop_Hash( Hop_Obj_t * pObj, int TableSize ) 
Alan Mishchenko committed
32
{
Alan Mishchenko committed
33
    unsigned long Key = Hop_ObjIsExor(pObj) * 1699;
Alan Mishchenko committed
34 35
    Key ^= Hop_ObjFanin0(pObj)->Id * 7937;
    Key ^= Hop_ObjFanin1(pObj)->Id * 2971;
Alan Mishchenko committed
36 37
    Key ^= Hop_ObjFaninC0(pObj) * 911;
    Key ^= Hop_ObjFaninC1(pObj) * 353;
Alan Mishchenko committed
38 39 40 41
    return Key % TableSize;
}

// returns the place where this node is stored (or should be stored)
Alan Mishchenko committed
42
static Hop_Obj_t ** Hop_TableFind( Hop_Man_t * p, Hop_Obj_t * pObj )
Alan Mishchenko committed
43
{
Alan Mishchenko committed
44
    Hop_Obj_t ** ppEntry;
Alan Mishchenko committed
45
    assert( Hop_ObjChild0(pObj) && Hop_ObjChild1(pObj) );
Alan Mishchenko committed
46 47 48 49 50 51
    assert( Hop_ObjFanin0(pObj)->Id < Hop_ObjFanin1(pObj)->Id );
    for ( ppEntry = p->pTable + Hop_Hash(pObj, p->nTableSize); *ppEntry; ppEntry = &(*ppEntry)->pNext )
        if ( *ppEntry == pObj )
            return ppEntry;
    assert( *ppEntry == NULL );
    return ppEntry;
Alan Mishchenko committed
52 53
}

Alan Mishchenko committed
54
static void         Hop_TableResize( Hop_Man_t * p );
Alan Mishchenko committed
55 56 57 58 59 60 61

////////////////////////////////////////////////////////////////////////
///                     FUNCTION DEFINITIONS                         ///
////////////////////////////////////////////////////////////////////////
 
/**Function*************************************************************

Alan Mishchenko committed
62
  Synopsis    [Checks if a node with the given attributes is in the hash table.]
Alan Mishchenko committed
63 64 65 66 67 68 69 70

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
71
Hop_Obj_t * Hop_TableLookup( Hop_Man_t * p, Hop_Obj_t * pGhost )
Alan Mishchenko committed
72
{
Alan Mishchenko committed
73
    Hop_Obj_t * pEntry;
Alan Mishchenko committed
74 75
    assert( !Hop_IsComplement(pGhost) );
    assert( Hop_ObjChild0(pGhost) && Hop_ObjChild1(pGhost) );
Alan Mishchenko committed
76
    assert( Hop_ObjFanin0(pGhost)->Id < Hop_ObjFanin1(pGhost)->Id );
Alan Mishchenko committed
77
    if ( p->fRefCount && (!Hop_ObjRefs(Hop_ObjFanin0(pGhost)) || !Hop_ObjRefs(Hop_ObjFanin1(pGhost))) )
Alan Mishchenko committed
78
        return NULL;
Alan Mishchenko committed
79
    for ( pEntry = p->pTable[Hop_Hash(pGhost, p->nTableSize)]; pEntry; pEntry = pEntry->pNext )
Alan Mishchenko committed
80
    {
Alan Mishchenko committed
81 82 83 84
        if ( Hop_ObjChild0(pEntry) == Hop_ObjChild0(pGhost) && 
             Hop_ObjChild1(pEntry) == Hop_ObjChild1(pGhost) && 
             Hop_ObjType(pEntry) == Hop_ObjType(pGhost) )
            return pEntry;
Alan Mishchenko committed
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
    }
    return NULL;
}

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

  Synopsis    [Adds the new node to the hash table.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
100
void Hop_TableInsert( Hop_Man_t * p, Hop_Obj_t * pObj )
Alan Mishchenko committed
101
{
Alan Mishchenko committed
102 103 104
    Hop_Obj_t ** ppPlace;
    assert( !Hop_IsComplement(pObj) );
    assert( Hop_TableLookup(p, pObj) == NULL );
Alan Mishchenko committed
105
    if ( (pObj->Id & 0xFF) == 0 && 2 * p->nTableSize < Hop_ManNodeNum(p) )
Alan Mishchenko committed
106 107
        Hop_TableResize( p );
    ppPlace = Hop_TableFind( p, pObj );
Alan Mishchenko committed
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
    assert( *ppPlace == NULL );
    *ppPlace = pObj;
}

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

  Synopsis    [Deletes the node from the hash table.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
123
void Hop_TableDelete( Hop_Man_t * p, Hop_Obj_t * pObj )
Alan Mishchenko committed
124
{
Alan Mishchenko committed
125
    Hop_Obj_t ** ppPlace;
Alan Mishchenko committed
126 127
    assert( !Hop_IsComplement(pObj) );
    ppPlace = Hop_TableFind( p, pObj );
Alan Mishchenko committed
128
    assert( *ppPlace == pObj ); // node should be in the table
Alan Mishchenko committed
129 130 131
    // remove the node
    *ppPlace = pObj->pNext;
    pObj->pNext = NULL;
Alan Mishchenko committed
132 133 134 135 136 137 138 139 140 141 142 143 144
}

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

  Synopsis    [Count the number of nodes in the table.]

  Description []
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
145
int Hop_TableCountEntries( Hop_Man_t * p )
Alan Mishchenko committed
146
{
Alan Mishchenko committed
147
    Hop_Obj_t * pEntry;
Alan Mishchenko committed
148 149
    int i, Counter = 0;
    for ( i = 0; i < p->nTableSize; i++ )
Alan Mishchenko committed
150 151
        for ( pEntry = p->pTable[i]; pEntry; pEntry = pEntry->pNext )
            Counter++;
Alan Mishchenko committed
152 153 154 155 156 157 158 159 160 161 162 163 164 165
    return Counter;
}

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

  Synopsis    [Resizes the table.]

  Description [Typically this procedure should not be called.]
               
  SideEffects []

  SeeAlso     []

***********************************************************************/
Alan Mishchenko committed
166
void Hop_TableResize( Hop_Man_t * p )
Alan Mishchenko committed
167
{
Alan Mishchenko committed
168
    Hop_Obj_t * pEntry, * pNext;
Alan Mishchenko committed
169
    Hop_Obj_t ** pTableOld, ** ppPlace;
170 171
    int nTableSizeOld, Counter, nEntries, i;
    clock_t clk;
Alan Mishchenko committed
172 173 174 175 176
clk = clock();
    // save the old table
    pTableOld = p->pTable;
    nTableSizeOld = p->nTableSize;
    // get the new table
177
    p->nTableSize = Abc_PrimeCudd( 2 * Hop_ManNodeNum(p) ); 
Alan Mishchenko committed
178
    p->pTable = ABC_ALLOC( Hop_Obj_t *, p->nTableSize );
Alan Mishchenko committed
179
    memset( p->pTable, 0, sizeof(Hop_Obj_t *) * p->nTableSize );
Alan Mishchenko committed
180 181
    // rehash the entries from the old table
    Counter = 0;
Alan Mishchenko committed
182 183
    for ( i = 0; i < nTableSizeOld; i++ )
    for ( pEntry = pTableOld[i], pNext = pEntry? pEntry->pNext : NULL; pEntry; pEntry = pNext, pNext = pEntry? pEntry->pNext : NULL )
Alan Mishchenko committed
184
    {
Alan Mishchenko committed
185 186 187 188 189 190
        // get the place where this entry goes in the table 
        ppPlace = Hop_TableFind( p, pEntry );
        assert( *ppPlace == NULL ); // should not be there
        // add the entry to the list
        *ppPlace = pEntry;
        pEntry->pNext = NULL;
Alan Mishchenko committed
191 192
        Counter++;
    }
Alan Mishchenko committed
193
    nEntries = Hop_ManNodeNum(p);
Alan Mishchenko committed
194
    assert( Counter == nEntries );
Alan Mishchenko committed
195
//    printf( "Increasing the structural table size from %6d to %6d. ", nTableSizeOld, p->nTableSize );
Alan Mishchenko committed
196
//    ABC_PRT( "Time", clock() - clk );
Alan Mishchenko committed
197
    // replace the table and the parameters
Alan Mishchenko committed
198
    ABC_FREE( pTableOld );
Alan Mishchenko committed
199 200 201 202 203 204 205 206 207 208 209 210 211
}

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

  Synopsis    [Profiles the hash table.]

  Description []

  SideEffects []

  SeeAlso     []

******************************************************************************/
Alan Mishchenko committed
212
void Hop_TableProfile( Hop_Man_t * p )
Alan Mishchenko committed
213
{
Alan Mishchenko committed
214 215
    Hop_Obj_t * pEntry;
    int i, Counter;
Alan Mishchenko committed
216 217
    for ( i = 0; i < p->nTableSize; i++ )
    {
Alan Mishchenko committed
218 219
        Counter = 0;
        for ( pEntry = p->pTable[i]; pEntry; pEntry = pEntry->pNext )
Alan Mishchenko committed
220
            Counter++;
Alan Mishchenko committed
221
        if ( Counter ) 
Alan Mishchenko committed
222 223 224 225 226 227 228 229 230
            printf( "%d ", Counter );
    }
}

////////////////////////////////////////////////////////////////////////
///                       END OF FILE                                ///
////////////////////////////////////////////////////////////////////////


231 232
ABC_NAMESPACE_IMPL_END