/**CFile**************************************************************** FileName [gia.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: gia.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] ***********************************************************************/ #include "gia.h" ABC_NAMESPACE_IMPL_START //////////////////////////////////////////////////////////////////////// /// DECLARATIONS /// //////////////////////////////////////////////////////////////////////// static inline int Gia_ObjDom( Gia_Man_t * p, Gia_Obj_t * pObj ) { return Vec_IntEntry(p->vDoms, Gia_ObjId(p, pObj)); } static inline void Gia_ObjSetDom( Gia_Man_t * p, Gia_Obj_t * pObj, int d ) { Vec_IntWriteEntry(p->vDoms, Gia_ObjId(p, pObj), d); } //////////////////////////////////////////////////////////////////////// /// FUNCTION DEFINITIONS /// //////////////////////////////////////////////////////////////////////// /**Function************************************************************* Synopsis [Computes one-node dominators.] Description [For each node, computes the closest one-node dominator, which can be the node itself if the node has no other dominators.] SideEffects [] SeeAlso [] ***********************************************************************/ static inline void Gia_ManAddDom( Gia_Man_t * p, Gia_Obj_t * pObj, int iDom0 ) { int iDom1, iDomNext; if ( Gia_ObjDom(p, pObj) == -1 ) { Gia_ObjSetDom( p, pObj, iDom0 ); return; } iDom1 = Gia_ObjDom( p, pObj ); while ( 1 ) { if ( iDom0 > iDom1 ) { iDomNext = Gia_ObjDom( p, Gia_ManObj(p, iDom1) ); if ( iDomNext == iDom1 ) break; iDom1 = iDomNext; continue; } if ( iDom1 > iDom0 ) { iDomNext = Gia_ObjDom( p, Gia_ManObj(p, iDom0) ); if ( iDomNext == iDom0 ) break; iDom0 = iDomNext; continue; } assert( iDom0 == iDom1 ); Gia_ObjSetDom( p, pObj, iDom0 ); return; } Gia_ObjSetDom( p, pObj, Gia_ObjId(p, pObj) ); } static inline void Gia_ManComputeDoms( Gia_Man_t * p ) { Gia_Obj_t * pObj; int i; if ( p->vDoms == NULL ) p->vDoms = Vec_IntAlloc( 0 ); Vec_IntFill( p->vDoms, Gia_ManObjNum(p), -1 ); Gia_ManForEachObjReverse( p, pObj, i ) { if ( i == 0 || Gia_ObjIsCi(pObj) ) continue; if ( Gia_ObjIsCo(pObj) ) { Gia_ObjSetDom( p, pObj, i ); Gia_ManAddDom( p, Gia_ObjFanin0(pObj), i ); continue; } assert( Gia_ObjIsAnd(pObj) ); Gia_ManAddDom( p, Gia_ObjFanin0(pObj), i ); Gia_ManAddDom( p, Gia_ObjFanin1(pObj), i ); } } /**Function************************************************************* Synopsis [Returns the number of internal nodes in the MFFC.] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ static inline int Gia_NodeDeref_rec( Gia_Man_t * p, Gia_Obj_t * pNode ) { Gia_Obj_t * pFanin; int Counter = 0; if ( Gia_ObjIsCi(pNode) ) return 0; assert( Gia_ObjIsAnd(pNode) ); pFanin = Gia_ObjFanin0(pNode); assert( Gia_ObjRefNum(p, pFanin) > 0 ); if ( Gia_ObjRefDec(p, pFanin) == 0 ) Counter += Gia_NodeDeref_rec( p, pFanin ); pFanin = Gia_ObjFanin1(pNode); assert( Gia_ObjRefNum(p, pFanin) > 0 ); if ( Gia_ObjRefDec(p, pFanin) == 0 ) Counter += Gia_NodeDeref_rec( p, pFanin ); return Counter + 1; } static inline int Gia_NodeRef_rec( Gia_Man_t * p, Gia_Obj_t * pNode ) { Gia_Obj_t * pFanin; int Counter = 0; if ( Gia_ObjIsCi(pNode) ) return 0; assert( Gia_ObjIsAnd(pNode) ); pFanin = Gia_ObjFanin0(pNode); if ( Gia_ObjRefInc(p, pFanin) == 0 ) Counter += Gia_NodeRef_rec( p, pFanin ); pFanin = Gia_ObjFanin1(pNode); if ( Gia_ObjRefInc(p, pFanin) == 0 ) Counter += Gia_NodeRef_rec( p, pFanin ); return Counter + 1; } static inline void Gia_NodeCollect_rec( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSupp, Vec_Int_t * vSuppRefs ) { if ( Gia_ObjIsTravIdCurrent(p, pNode) ) return; Gia_ObjSetTravIdCurrent(p, pNode); if ( Gia_ObjRefNum(p, pNode) || Gia_ObjIsCi(pNode) ) { Vec_IntPush( vSupp, Gia_ObjId(p, pNode) ); Vec_IntPush( vSuppRefs, Gia_ObjRefNum(p, pNode) ); return; } assert( Gia_ObjIsAnd(pNode) ); Gia_NodeCollect_rec( p, Gia_ObjFanin0(pNode), vSupp, vSuppRefs ); Gia_NodeCollect_rec( p, Gia_ObjFanin1(pNode), vSupp, vSuppRefs ); } static inline int Gia_NodeMffcSizeSupp( Gia_Man_t * p, Gia_Obj_t * pNode, Vec_Int_t * vSupp, Vec_Int_t * vSuppRefs ) { int ConeSize1, ConeSize2, i, iObj; assert( !Gia_IsComplement(pNode) ); assert( Gia_ObjIsAnd(pNode) ); Vec_IntClear( vSupp ); Vec_IntClear( vSuppRefs ); Gia_ManIncrementTravId( p ); ConeSize1 = Gia_NodeDeref_rec( p, pNode ); Gia_NodeCollect_rec( p, Gia_ObjFanin0(pNode), vSupp, vSuppRefs ); Gia_NodeCollect_rec( p, Gia_ObjFanin1(pNode), vSupp, vSuppRefs ); ConeSize2 = Gia_NodeRef_rec( p, pNode ); assert( ConeSize1 == ConeSize2 ); assert( ConeSize1 >= 0 ); // record supp refs Vec_IntForEachEntry( vSupp, iObj, i ) Vec_IntAddToEntry( vSuppRefs, i, -Gia_ObjRefNumId(p, iObj) ); return ConeSize1; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ int Gia_ManDomDerive_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pNode ) { if ( Gia_ObjIsTravIdCurrent(p, pNode) ) return pNode->Value; Gia_ObjSetTravIdCurrent(p, pNode); assert( Gia_ObjIsAnd(pNode) ); Gia_ManDomDerive_rec( pNew, p, Gia_ObjFanin0(pNode) ); Gia_ManDomDerive_rec( pNew, p, Gia_ObjFanin1(pNode) ); return pNode->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pNode), Gia_ObjFanin1Copy(pNode) ); } Gia_Man_t * Gia_ManDomDerive( Gia_Man_t * p, Gia_Obj_t * pRoot, Vec_Int_t * vSupp, int nVars ) { Gia_Man_t * pNew, * pTemp; int nMints = 1 << nVars; int i, m, iResLit; assert( nVars >= 0 && nVars <= 5 ); pNew = Gia_ManStart( Gia_ManObjNum(p) ); pNew->pName = Abc_UtilStrsav( p->pName ); pNew->pSpec = Abc_UtilStrsav( p->pSpec ); Gia_ManConst0(p)->Value = 0; Gia_ManHashAlloc( pNew ); for ( i = 0; i < Vec_IntSize(vSupp); i++ ) Gia_ManAppendCi(pNew); for ( m = 0; m < nMints; m++ ) { Gia_Obj_t * pObj; Gia_ManIncrementTravId( p ); Gia_ManForEachObjVec( vSupp, p, pObj, i ) { if ( i < nVars ) pObj->Value = (m >> i) & 1; else pObj->Value = Gia_ObjToLit(pNew, Gia_ManCi(pNew, i)); Gia_ObjSetTravIdCurrent( p, pObj ); } iResLit = Gia_ManDomDerive_rec( pNew, p, pRoot ); Gia_ManAppendCo( pNew, iResLit ); } Gia_ManHashStop( pNew ); pNew = Gia_ManCleanup( pTemp = pNew ); Gia_ManStop( pTemp ); return pNew; } /**Function************************************************************* Synopsis [] Description [] SideEffects [] SeeAlso [] ***********************************************************************/ void Gia_ManComputeDomsTry( Gia_Man_t * p ) { extern void Gia_ManCollapseTestTest( Gia_Man_t * p ); Vec_Int_t * vSupp, * vSuppRefs; Gia_Man_t * pNew; Gia_Obj_t * pObj; int i, nSize, Entry, k; abctime clk = Abc_Clock(); ABC_FREE( p->pRefs ); Gia_ManLevelNum( p ); Gia_ManCreateRefs( p ); Gia_ManComputeDoms( p ); Abc_PrintTime( 1, "Time", Abc_Clock() - clk ); vSupp = Vec_IntAlloc( 1000 ); vSuppRefs = Vec_IntAlloc( 1000 ); Gia_ManForEachObj( p, pObj, i ) { if ( !Gia_ObjIsAnd(pObj) && !Gia_ObjIsCo(pObj) ) continue; if ( Gia_ObjDom(p, pObj) != i ) continue; if ( Gia_ObjIsCo(pObj) ) pObj = Gia_ObjFanin0(pObj); if ( !Gia_ObjIsAnd(pObj) ) continue; nSize = Gia_NodeMffcSizeSupp( p, pObj, vSupp, vSuppRefs ); if ( nSize < 10 )//|| nSize > 100 ) continue; // sort by cost Vec_IntSelectSortCost2( Vec_IntArray(vSupp), Vec_IntSize(vSupp), Vec_IntArray(vSuppRefs) ); printf( "Obj %6d : ", i ); printf( "Cone = %4d ", nSize ); printf( "Supp = %4d ", Vec_IntSize(vSupp) ); // Vec_IntForEachEntry( vSuppRefs, Entry, k ) // printf( "%d(%d) ", -Entry, Gia_ObjLevelId(p, Vec_IntEntry(vSupp, k)) ); printf( "\n" ); // selected k for ( k = 0; k < Vec_IntSize(vSupp); k++ ) if ( Vec_IntEntry(vSuppRefs, k) == 1 ) break; k = Abc_MinInt( k, 3 ); k = 0; // dump pNew = Gia_ManDomDerive( p, pObj, vSupp, k ); Gia_DumpAiger( pNew, "mffc", i, 6 ); Gia_ManCollapseTestTest( pNew ); Gia_ManStop( pNew ); } Vec_IntFree( vSuppRefs ); Vec_IntFree( vSupp ); } //////////////////////////////////////////////////////////////////////// /// END OF FILE /// //////////////////////////////////////////////////////////////////////// ABC_NAMESPACE_IMPL_END