| /**CFile**************************************************************** |
| |
| FileName [giaFanout.c] |
| |
| SystemName [ABC: Logic synthesis and verification system.] |
| |
| PackageName [Scalable AIG package.] |
| |
| Synopsis [] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - June 20, 2005.] |
| |
| Revision [$Id: giaFanout.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "gia.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| // 0: first iFan |
| // 1: prev iFan0 |
| // 2: prev iFan1 |
| // 3: next iFan0 |
| // 4: next iFan1 |
| |
| static inline int Gia_FanoutCreate( int FanId, int Num ) { assert( Num < 2 ); return (FanId << 1) | Num; } |
| static inline int * Gia_FanoutObj( int * pData, int ObjId ) { return pData + 5*ObjId; } |
| static inline int * Gia_FanoutPrev( int * pData, int iFan ) { return pData + 5*(iFan >> 1) + 1 + (iFan & 1); } |
| static inline int * Gia_FanoutNext( int * pData, int iFan ) { return pData + 5*(iFan >> 1) + 3 + (iFan & 1); } |
| |
| // these two procedures are only here for the use inside the iterator |
| static inline int Gia_ObjFanout0Int( Gia_Man_t * p, int ObjId ) { assert(ObjId < p->nFansAlloc); return p->pFanData[5*ObjId]; } |
| static inline int Gia_ObjFanoutNext( Gia_Man_t * p, int iFan ) { assert(iFan/2 < p->nFansAlloc); return p->pFanData[5*(iFan >> 1) + 3 + (iFan & 1)]; } |
| |
| // iterator over the fanouts |
| #define Gia_ObjForEachFanout( p, pObj, pFanout, iFan, i ) \ |
| for ( assert(p->pFanData), i = 0; (i < (int)(pObj)->nRefs) && \ |
| (((iFan) = i? Gia_ObjFanoutNext(p, iFan) : Gia_ObjFanout0Int(p, Gia_ObjId(p, pObj))), 1) && \ |
| (((pFanout) = Gia_ManObj(p, iFan>>1)), 1); i++ ) |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Create fanout for all objects in the manager.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManFanoutStart( Gia_Man_t * p ) |
| { |
| Gia_Obj_t * pObj; |
| int i; |
| // allocate fanout datastructure |
| assert( p->pFanData == NULL ); |
| p->nFansAlloc = 2 * Gia_ManObjNum(p); |
| if ( p->nFansAlloc < (1<<12) ) |
| p->nFansAlloc = (1<<12); |
| p->pFanData = ABC_ALLOC( int, 5 * p->nFansAlloc ); |
| memset( p->pFanData, 0, sizeof(int) * 5 * p->nFansAlloc ); |
| // add fanouts for all objects |
| Gia_ManForEachObj( p, pObj, i ) |
| { |
| if ( Gia_ObjChild0(pObj) ) |
| Gia_ObjAddFanout( p, Gia_ObjFanin0(pObj), pObj ); |
| if ( Gia_ObjChild1(pObj) ) |
| Gia_ObjAddFanout( p, Gia_ObjFanin1(pObj), pObj ); |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Deletes fanout for all objects in the manager.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManFanoutStop( Gia_Man_t * p ) |
| { |
| assert( p->pFanData != NULL ); |
| ABC_FREE( p->pFanData ); |
| p->nFansAlloc = 0; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Adds fanout (pFanout) of node (pObj).] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ObjAddFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ) |
| { |
| int iFan, * pFirst, * pPrevC, * pNextC, * pPrev, * pNext; |
| assert( p->pFanData ); |
| assert( !Gia_IsComplement(pObj) && !Gia_IsComplement(pFanout) ); |
| assert( Gia_ObjId(p, pFanout) > 0 ); |
| if ( Gia_ObjId(p, pObj) >= p->nFansAlloc || Gia_ObjId(p, pFanout) >= p->nFansAlloc ) |
| { |
| int nFansAlloc = 2 * Abc_MaxInt( Gia_ObjId(p, pObj), Gia_ObjId(p, pFanout) ); |
| p->pFanData = ABC_REALLOC( int, p->pFanData, 5 * nFansAlloc ); |
| memset( p->pFanData + 5 * p->nFansAlloc, 0, sizeof(int) * 5 * (nFansAlloc - p->nFansAlloc) ); |
| p->nFansAlloc = nFansAlloc; |
| } |
| assert( Gia_ObjId(p, pObj) < p->nFansAlloc && Gia_ObjId(p, pFanout) < p->nFansAlloc ); |
| iFan = Gia_FanoutCreate( Gia_ObjId(p, pFanout), Gia_ObjWhatFanin(p, pFanout, pObj) ); |
| pPrevC = Gia_FanoutPrev( p->pFanData, iFan ); |
| pNextC = Gia_FanoutNext( p->pFanData, iFan ); |
| pFirst = Gia_FanoutObj( p->pFanData, Gia_ObjId(p, pObj) ); |
| if ( *pFirst == 0 ) |
| { |
| *pFirst = iFan; |
| *pPrevC = iFan; |
| *pNextC = iFan; |
| } |
| else |
| { |
| pPrev = Gia_FanoutPrev( p->pFanData, *pFirst ); |
| pNext = Gia_FanoutNext( p->pFanData, *pPrev ); |
| assert( *pNext == *pFirst ); |
| *pPrevC = *pPrev; |
| *pNextC = *pFirst; |
| *pPrev = iFan; |
| *pNext = iFan; |
| } |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Removes fanout (pFanout) of node (pObj).] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ObjRemoveFanout( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanout ) |
| { |
| int iFan, * pFirst, * pPrevC, * pNextC, * pPrev, * pNext; |
| assert( p->pFanData && Gia_ObjId(p, pObj) < p->nFansAlloc && Gia_ObjId(p, pFanout) < p->nFansAlloc ); |
| assert( !Gia_IsComplement(pObj) && !Gia_IsComplement(pFanout) ); |
| assert( Gia_ObjId(p, pFanout) > 0 ); |
| iFan = Gia_FanoutCreate( Gia_ObjId(p, pFanout), Gia_ObjWhatFanin(p, pFanout, pObj) ); |
| pPrevC = Gia_FanoutPrev( p->pFanData, iFan ); |
| pNextC = Gia_FanoutNext( p->pFanData, iFan ); |
| pPrev = Gia_FanoutPrev( p->pFanData, *pNextC ); |
| pNext = Gia_FanoutNext( p->pFanData, *pPrevC ); |
| assert( *pPrev == iFan ); |
| assert( *pNext == iFan ); |
| pFirst = Gia_FanoutObj( p->pFanData, Gia_ObjId(p, pObj) ); |
| assert( *pFirst > 0 ); |
| if ( *pFirst == iFan ) |
| { |
| if ( *pNextC == iFan ) |
| { |
| *pFirst = 0; |
| *pPrev = 0; |
| *pNext = 0; |
| *pPrevC = 0; |
| *pNextC = 0; |
| return; |
| } |
| *pFirst = *pNextC; |
| } |
| *pPrev = *pPrevC; |
| *pNext = *pNextC; |
| *pPrevC = 0; |
| *pNextC = 0; |
| } |
| |
| |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Compute the map of all edges.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| Vec_Int_t * Gia_ManStartFanoutMap( Gia_Man_t * p, Vec_Int_t * vFanoutNums ) |
| { |
| Vec_Int_t * vEdgeMap; |
| Gia_Obj_t * pObj; |
| int i, iOffset; |
| iOffset = Gia_ManObjNum(p); |
| vEdgeMap = Vec_IntStart( iOffset + Gia_ManMuxNum(p) + 2 * Gia_ManAndNum(p) + Gia_ManCoNum(p) ); |
| Gia_ManForEachObj( p, pObj, i ) |
| { |
| Vec_IntWriteEntry( vEdgeMap, i, iOffset ); |
| iOffset += Vec_IntEntry( vFanoutNums, Gia_ObjId(p, pObj) ); |
| } |
| assert( iOffset <= Vec_IntSize(vEdgeMap) ); |
| return vEdgeMap; |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Allocates static fanout.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManStaticFanoutStart( Gia_Man_t * p ) |
| { |
| Vec_Int_t * vCounts; |
| int * pRefsOld; |
| Gia_Obj_t * pObj, * pFanin; |
| int i, iFanout; |
| assert( p->vFanoutNums == NULL ); |
| assert( p->vFanout == NULL ); |
| // recompute reference counters |
| pRefsOld = p->pRefs; p->pRefs = NULL; |
| Gia_ManCreateRefs(p); |
| p->vFanoutNums = Vec_IntAllocArray( p->pRefs, Gia_ManObjNum(p) ); |
| p->pRefs = pRefsOld; |
| // start the fanout maps |
| p->vFanout = Gia_ManStartFanoutMap( p, p->vFanoutNums ); |
| // incrementally add fanouts |
| vCounts = Vec_IntStart( Gia_ManObjNum(p) ); |
| Gia_ManForEachObj( p, pObj, i ) |
| { |
| if ( Gia_ObjIsAnd(pObj) || Gia_ObjIsCo(pObj) ) |
| { |
| pFanin = Gia_ObjFanin0(pObj); |
| iFanout = Vec_IntEntry( vCounts, Gia_ObjId(p, pFanin) ); |
| Gia_ObjSetFanout( p, pFanin, iFanout, pObj ); |
| Vec_IntAddToEntry( vCounts, Gia_ObjId(p, pFanin), 1 ); |
| } |
| if ( Gia_ObjIsAnd(pObj) ) |
| { |
| |
| pFanin = Gia_ObjFanin1(pObj); |
| iFanout = Vec_IntEntry( vCounts, Gia_ObjId(p, pFanin) ); |
| Gia_ObjSetFanout( p, pFanin, iFanout, pObj ); |
| Vec_IntAddToEntry( vCounts, Gia_ObjId(p, pFanin), 1 ); |
| } |
| if ( Gia_ObjIsMux(p, pObj) ) |
| { |
| |
| pFanin = Gia_ObjFanin2(p, pObj); |
| iFanout = Vec_IntEntry( vCounts, Gia_ObjId(p, pFanin) ); |
| Gia_ObjSetFanout( p, pFanin, iFanout, pObj ); |
| Vec_IntAddToEntry( vCounts, Gia_ObjId(p, pFanin), 1 ); |
| } |
| } |
| // double-check the current number of fanouts added |
| Gia_ManForEachObj( p, pObj, i ) |
| assert( Vec_IntEntry(vCounts, i) == Gia_ObjFanoutNum(p, pObj) ); |
| Vec_IntFree( vCounts ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Deallocates static fanout.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManStaticFanoutStop( Gia_Man_t * p ) |
| { |
| Vec_IntFreeP( &p->vFanoutNums ); |
| Vec_IntFreeP( &p->vFanout ); |
| } |
| |
| |
| /**Function************************************************************* |
| |
| Synopsis [Tests static fanout.] |
| |
| Description [] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| void Gia_ManStaticFanoutTest( Gia_Man_t * p ) |
| { |
| Gia_Obj_t * pObj, * pFanout; |
| int i, k; |
| Gia_ManStaticFanoutStart( p ); |
| Gia_ManForEachObj( p, pObj, i ) |
| { |
| Gia_ObjPrint( p, pObj ); |
| printf( " Fanouts : " ); |
| Gia_ObjForEachFanoutStatic( p, pObj, pFanout, k ) |
| printf( "%5d ", Gia_ObjId(p, pFanout) ); |
| printf( "\n" ); |
| } |
| Gia_ManStaticFanoutStop( p ); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| |
| ABC_NAMESPACE_IMPL_END |
| |