diff options
Diffstat (limited to 'src/temp/ivy/ivyObj.c')
-rw-r--r-- | src/temp/ivy/ivyObj.c | 324 |
1 files changed, 201 insertions, 123 deletions
diff --git a/src/temp/ivy/ivyObj.c b/src/temp/ivy/ivyObj.c index 703218bb..de67c560 100644 --- a/src/temp/ivy/ivyObj.c +++ b/src/temp/ivy/ivyObj.c @@ -39,36 +39,54 @@ SeeAlso [] ***********************************************************************/ -Ivy_Obj_t * Ivy_ObjCreate( Ivy_Obj_t * pGhost ) +Ivy_Obj_t * Ivy_ObjCreatePi( Ivy_Man_t * p ) +{ + return Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, NULL, NULL, IVY_PI, IVY_INIT_NONE) ); +} + +/**Function************************************************************* + + Synopsis [Create the new node assuming it does not exist.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_ObjCreatePo( Ivy_Man_t * p, Ivy_Obj_t * pDriver ) +{ + return Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, pDriver, NULL, IVY_PO, IVY_INIT_NONE) ); +} + +/**Function************************************************************* + + Synopsis [Create the new node assuming it does not exist.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_ObjCreate( Ivy_Man_t * p, Ivy_Obj_t * pGhost ) { - Ivy_Man_t * p = Ivy_ObjMan(pGhost); Ivy_Obj_t * pObj; assert( !Ivy_IsComplement(pGhost) ); assert( Ivy_ObjIsGhost(pGhost) ); - - assert( Ivy_TableLookup(pGhost) == NULL ); - - // realloc the node array - if ( p->ObjIdNext == p->nObjsAlloc ) - { - printf( "AIG manager is being resized. In the current release, it is not allowed!\n" ); - Ivy_ManGrow( p ); - pGhost = Ivy_ManGhost( p ); - } + assert( Ivy_TableLookup(p, pGhost) == NULL ); // get memory for the new object - if ( Vec_IntSize(p->vFree) > 0 ) - pObj = p->pObjs + Vec_IntPop(p->vFree); - else - pObj = p->pObjs + p->ObjIdNext++; - assert( pObj->Id == pObj - p->pObjs ); + pObj = Ivy_ManFetchMemory( p ); assert( Ivy_ObjIsNone(pObj) ); + pObj->Id = Vec_PtrSize(p->vObjs); + Vec_PtrPush( p->vObjs, pObj ); // add basic info (fanins, compls, type, init) - Ivy_ObjOverwrite( pObj, pGhost ); - // increment references of the fanins - Ivy_ObjRefsInc( Ivy_ObjFanin0(pObj) ); - Ivy_ObjRefsInc( Ivy_ObjFanin1(pObj) ); - // add the node to the structural hash table - Ivy_TableInsert( pObj ); + pObj->Type = pGhost->Type; + pObj->Init = pGhost->Init; + // add connections + Ivy_ObjConnect( p, pObj, pGhost->pFanin0, pGhost->pFanin1 ); // compute level if ( Ivy_ObjIsNode(pObj) ) pObj->Level = Ivy_ObjLevelNew(pObj); @@ -86,9 +104,13 @@ Ivy_Obj_t * Ivy_ObjCreate( Ivy_Obj_t * pGhost ) } // add PIs/POs to the arrays if ( Ivy_ObjIsPi(pObj) ) - Vec_IntPush( p->vPis, pObj->Id ); + Vec_PtrPush( p->vPis, pObj ); else if ( Ivy_ObjIsPo(pObj) ) - Vec_IntPush( p->vPos, pObj->Id ); + Vec_PtrPush( p->vPos, pObj ); +// else if ( Ivy_ObjIsBuf(pObj) ) +// Vec_PtrPush( p->vBufs, pObj ); + if ( p->vRequired && Vec_IntSize(p->vRequired) <= pObj->Id ) + Vec_IntFillExtra( p->vRequired, 2 * Vec_IntSize(p->vRequired), 1000000 ); // update node counters of the manager p->nObjs[Ivy_ObjType(pObj)]++; p->nCreated++; @@ -97,7 +119,7 @@ Ivy_Obj_t * Ivy_ObjCreate( Ivy_Obj_t * pGhost ) /**Function************************************************************* - Synopsis [Create the new node assuming it does not exist.] + Synopsis [Connect the object to the fanin.] Description [] @@ -106,22 +128,28 @@ Ivy_Obj_t * Ivy_ObjCreate( Ivy_Obj_t * pGhost ) SeeAlso [] ***********************************************************************/ -Ivy_Obj_t * Ivy_ObjCreateExt( Ivy_Man_t * p, Ivy_Type_t Type ) +void Ivy_ObjConnect( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFan0, Ivy_Obj_t * pFan1 ) { - Ivy_Obj_t * pObj; - assert( Type == IVY_ANDM || Type == IVY_EXORM || Type == IVY_LUT ); - // realloc the node array - if ( p->ObjIdNext == p->nObjsAlloc ) - Ivy_ManGrow( p ); - // create the new node - pObj = p->pObjs + p->ObjIdNext; - assert( pObj->Id == p->ObjIdNext ); - p->ObjIdNext++; - pObj->Type = Type; - // update node counters of the manager - p->nObjs[Type]++; - p->nCreated++; - return pObj; + assert( !Ivy_IsComplement(pObj) ); + assert( Ivy_ObjIsPi(pObj) || Ivy_ObjIsOneFanin(pObj) || pFan1 != NULL ); + // add the first fanin + pObj->pFanin0 = pFan0; + pObj->pFanin1 = pFan1; + // increment references of the fanins and add their fanouts + if ( Ivy_ObjFanin0(pObj) != NULL ) + { + Ivy_ObjRefsInc( Ivy_ObjFanin0(pObj) ); + if ( p->vFanouts ) + Ivy_ObjAddFanout( p, Ivy_ObjFanin0(pObj), pObj ); + } + if ( Ivy_ObjFanin1(pObj) != NULL ) + { + Ivy_ObjRefsInc( Ivy_ObjFanin1(pObj) ); + if ( p->vFanouts ) + Ivy_ObjAddFanout( p, Ivy_ObjFanin1(pObj), pObj ); + } + // add the node to the structural hash table + Ivy_TableInsert( p, pObj ); } /**Function************************************************************* @@ -135,18 +163,59 @@ Ivy_Obj_t * Ivy_ObjCreateExt( Ivy_Man_t * p, Ivy_Type_t Type ) SeeAlso [] ***********************************************************************/ -void Ivy_ObjConnect( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanin ) +void Ivy_ObjDisconnect( Ivy_Man_t * p, Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); - assert( Ivy_ObjIsOneFanin(pObj) ); - assert( Ivy_ObjFaninId0(pObj) == 0 ); + assert( Ivy_ObjIsPi(pObj) || Ivy_ObjIsOneFanin(pObj) || Ivy_ObjFanin1(pObj) != NULL ); + // remove connections + if ( Ivy_ObjFanin0(pObj) != NULL ) + { + Ivy_ObjRefsDec(Ivy_ObjFanin0(pObj)); + if ( p->vFanouts ) + Ivy_ObjDeleteFanout( p, Ivy_ObjFanin0(pObj), pObj ); + } + if ( Ivy_ObjFanin1(pObj) != NULL ) + { + Ivy_ObjRefsDec(Ivy_ObjFanin1(pObj)); + if ( p->vFanouts ) + Ivy_ObjDeleteFanout( p, Ivy_ObjFanin1(pObj), pObj ); + } + // remove the node from the structural hash table + Ivy_TableDelete( p, pObj ); // add the first fanin - pObj->fComp0 = Ivy_IsComplement(pFanin); - pObj->Fanin0 = Ivy_Regular(pFanin)->Id; - // increment references of the fanins - Ivy_ObjRefsInc( Ivy_ObjFanin0(pObj) ); - // add the node to the structural hash table - Ivy_TableInsert( pObj ); + pObj->pFanin0 = NULL; + pObj->pFanin1 = NULL; +} + +/**Function************************************************************* + + Synopsis [Replaces the first fanin of the node by the new fanin.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ +void Ivy_ObjPatchFanin0( Ivy_Man_t * p, Ivy_Obj_t * pObj, Ivy_Obj_t * pFaninNew ) +{ + Ivy_Obj_t * pFaninOld; + assert( !Ivy_IsComplement(pObj) ); + pFaninOld = Ivy_ObjFanin0(pObj); + // decrement ref and remove fanout + Ivy_ObjRefsDec( pFaninOld ); + if ( p->vFanouts ) + Ivy_ObjDeleteFanout( p, pFaninOld, pObj ); + // increment ref and add fanout + Ivy_ObjRefsInc( Ivy_Regular(pFaninNew) ); + if ( p->vFanouts ) + Ivy_ObjAddFanout( p, Ivy_Regular(pFaninNew), pObj ); + // update the fanin + pObj->pFanin0 = pFaninNew; + // get rid of old fanin + if ( !Ivy_ObjIsPi(pFaninOld) && Ivy_ObjRefs(pFaninOld) == 0 ) + Ivy_ObjDelete_rec( p, pFaninOld, 1 ); } /**Function************************************************************* @@ -160,33 +229,35 @@ void Ivy_ObjConnect( Ivy_Obj_t * pObj, Ivy_Obj_t * pFanin ) SeeAlso [] ***********************************************************************/ -void Ivy_ObjDelete( Ivy_Obj_t * pObj, int fFreeTop ) +void Ivy_ObjDelete( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop ) { - Ivy_Man_t * p; assert( !Ivy_IsComplement(pObj) ); - assert( Ivy_ObjRefs(pObj) == 0 ); - // remove connections - Ivy_ObjRefsDec(Ivy_ObjFanin0(pObj)); - Ivy_ObjRefsDec(Ivy_ObjFanin1(pObj)); - // remove the node from the structural hash table - Ivy_TableDelete( pObj ); + assert( Ivy_ObjRefs(pObj) == 0 || !fFreeTop ); // update node counters of the manager - p = Ivy_ObjMan(pObj); p->nObjs[pObj->Type]--; p->nDeleted++; + // remove connections + Ivy_ObjDisconnect( p, pObj ); // remove PIs/POs from the arrays if ( Ivy_ObjIsPi(pObj) ) - Vec_IntRemove( p->vPis, pObj->Id ); + Vec_PtrRemove( p->vPis, pObj ); else if ( Ivy_ObjIsPo(pObj) ) - Vec_IntRemove( p->vPos, pObj->Id ); - // recorde the deleted node - if ( p->fRecording ) - Ivy_ManUndoRecord( p, pObj ); - // clean the node's memory - Ivy_ObjClean( pObj ); - // remember the entry + Vec_PtrRemove( p->vPos, pObj ); + else if ( p->vFanouts && Ivy_ObjIsBuf(pObj) ) + Vec_PtrRemove( p->vBufs, pObj ); + // clean and recycle the entry if ( fFreeTop ) - Vec_IntPush( p->vFree, pObj->Id ); + { + // free the node + Vec_PtrWriteEntry( p->vObjs, pObj->Id, NULL ); + Ivy_ManRecycleMemory( p, pObj ); + } + else + { + int nRefsOld = pObj->nRefs; + Ivy_ObjClean( pObj ); + pObj->nRefs = nRefsOld; + } } /**Function************************************************************* @@ -200,20 +271,20 @@ void Ivy_ObjDelete( Ivy_Obj_t * pObj, int fFreeTop ) SeeAlso [] ***********************************************************************/ -void Ivy_ObjDelete_rec( Ivy_Obj_t * pObj, int fFreeTop ) +void Ivy_ObjDelete_rec( Ivy_Man_t * p, Ivy_Obj_t * pObj, int fFreeTop ) { Ivy_Obj_t * pFanin0, * pFanin1; assert( !Ivy_IsComplement(pObj) ); - assert( !Ivy_ObjIsPo(pObj) && !Ivy_ObjIsNone(pObj) ); + assert( !Ivy_ObjIsNone(pObj) ); if ( Ivy_ObjIsConst1(pObj) || Ivy_ObjIsPi(pObj) ) return; pFanin0 = Ivy_ObjFanin0(pObj); pFanin1 = Ivy_ObjFanin1(pObj); - Ivy_ObjDelete( pObj, fFreeTop ); - if ( !Ivy_ObjIsNone(pFanin0) && Ivy_ObjRefs(pFanin0) == 0 ) - Ivy_ObjDelete_rec( pFanin0, 1 ); - if ( !Ivy_ObjIsNone(pFanin1) && Ivy_ObjRefs(pFanin1) == 0 ) - Ivy_ObjDelete_rec( pFanin1, 1 ); + Ivy_ObjDelete( p, pObj, fFreeTop ); + if ( pFanin0 && !Ivy_ObjIsNone(pFanin0) && Ivy_ObjRefs(pFanin0) == 0 ) + Ivy_ObjDelete_rec( p, pFanin0, 1 ); + if ( pFanin1 && !Ivy_ObjIsNone(pFanin1) && Ivy_ObjRefs(pFanin1) == 0 ) + Ivy_ObjDelete_rec( p, pFanin1, 1 ); } /**Function************************************************************* @@ -229,66 +300,61 @@ void Ivy_ObjDelete_rec( Ivy_Obj_t * pObj, int fFreeTop ) SeeAlso [] ***********************************************************************/ -void Ivy_ObjReplace( Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop ) +void Ivy_ObjReplace( Ivy_Man_t * p, Ivy_Obj_t * pObjOld, Ivy_Obj_t * pObjNew, int fDeleteOld, int fFreeTop ) { int nRefsOld; // the object to be replaced cannot be complemented assert( !Ivy_IsComplement(pObjOld) ); // the object to be replaced cannot be a terminal - assert( Ivy_ObjIsNone(pObjOld) || !Ivy_ObjIsTerm(pObjOld) ); + assert( Ivy_ObjIsNone(pObjOld) || !Ivy_ObjIsPi(pObjOld) ); // the object to be used cannot be a PO or assert - assert( !Ivy_ObjIsPo(Ivy_Regular(pObjNew)) ); + assert( !Ivy_ObjIsBuf(Ivy_Regular(pObjNew)) ); // the object cannot be the same assert( pObjOld != Ivy_Regular(pObjNew) ); // if the new object is complemented or already used, add the buffer - if ( Ivy_IsComplement(pObjNew) || Ivy_ObjRefs(pObjNew) > 0 || Ivy_ObjIsPi(pObjNew) || Ivy_ObjIsConst1(pObjNew) ) - pObjNew = Ivy_ObjCreate( Ivy_ObjCreateGhost(pObjNew, Ivy_ObjConst1(pObjOld), IVY_BUF, IVY_INIT_NONE) ); + if ( Ivy_IsComplement(pObjNew) || Ivy_ObjIsLatch(pObjNew) || Ivy_ObjRefs(pObjNew) > 0 || Ivy_ObjIsPi(pObjNew) || Ivy_ObjIsConst1(pObjNew) ) + pObjNew = Ivy_ObjCreate( p, Ivy_ObjCreateGhost(p, pObjNew, NULL, IVY_BUF, IVY_INIT_NONE) ); assert( !Ivy_IsComplement(pObjNew) ); - // remember the reference counter - nRefsOld = pObjOld->nRefs; - pObjOld->nRefs = 0; + // if the new node's arrival time is different, recursively update arrival time of the fanouts + if ( p->vFanouts && !Ivy_ObjIsBuf(pObjNew) && pObjOld->Level != pObjNew->Level ) + { + assert( Ivy_ObjIsNode(pObjOld) ); + pObjOld->Level = pObjNew->Level; + Ivy_ObjUpdateLevel_rec( p, pObjOld ); + } + // if the new node's required time has changed, recursively update required time of the fanins + if ( p->vRequired ) + { + int ReqNew = Vec_IntEntry(p->vRequired, pObjOld->Id); + if ( ReqNew < Vec_IntEntry(p->vRequired, pObjNew->Id) ) + { + Vec_IntWriteEntry( p->vRequired, pObjNew->Id, ReqNew ); + Ivy_ObjUpdateLevelR_rec( p, pObjNew, ReqNew ); + } + } // delete the old object if ( fDeleteOld ) - Ivy_ObjDelete_rec( pObjOld, fFreeTop ); + Ivy_ObjDelete_rec( p, pObjOld, fFreeTop ); // transfer the old object assert( Ivy_ObjRefs(pObjNew) == 0 ); + nRefsOld = pObjOld->nRefs; Ivy_ObjOverwrite( pObjOld, pObjNew ); pObjOld->nRefs = nRefsOld; - // update the hash table - Ivy_TableUpdate( pObjNew, pObjOld->Id ); - // create the object that was taken over by pObjOld - Ivy_ObjClean( pObjNew ); - // remember the entry - Vec_IntPush( Ivy_ObjMan(pObjOld)->vFree, pObjNew->Id ); -} - -/**Function************************************************************* - - Synopsis [Returns the first real fanins (not a buffer/inverter).] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_NodeRealFanin_rec( Ivy_Obj_t * pNode, int iFanin ) -{ - if ( iFanin == 0 ) + // patch the fanout of the fanins + if ( p->vFanouts ) { - if ( Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) ) - return Ivy_NotCond( Ivy_NodeRealFanin_rec(Ivy_ObjFanin0(pNode), 0), Ivy_ObjFaninC0(pNode) ); - else - return Ivy_ObjChild0(pNode); - } - else - { - if ( Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) ) - return Ivy_NotCond( Ivy_NodeRealFanin_rec(Ivy_ObjFanin1(pNode), 0), Ivy_ObjFaninC1(pNode) ); - else - return Ivy_ObjChild1(pNode); + Ivy_ObjPatchFanout( p, Ivy_ObjFanin0(pObjOld), pObjNew, pObjOld ); + if ( Ivy_ObjFanin1(pObjOld) ) + Ivy_ObjPatchFanout( p, Ivy_ObjFanin1(pObjOld), pObjNew, pObjOld ); } + // update the hash table + Ivy_TableUpdate( p, pObjNew, pObjOld->Id ); + // recycle the object that was taken over by pObjOld + Vec_PtrWriteEntry( p->vObjs, pObjNew->Id, NULL ); + Ivy_ManRecycleMemory( p, pObjNew ); + // if the new node is the buffer propagate it + if ( p->vFanouts && Ivy_ObjIsBuf(pObjOld) ) + Vec_PtrPush( p->vBufs, pObjOld ); } /**Function************************************************************* @@ -304,19 +370,31 @@ Ivy_Obj_t * Ivy_NodeRealFanin_rec( Ivy_Obj_t * pNode, int iFanin ) SeeAlso [] ***********************************************************************/ -void Ivy_NodeFixBufferFanins( Ivy_Obj_t * pNode ) +void Ivy_NodeFixBufferFanins( Ivy_Man_t * p, Ivy_Obj_t * pNode ) { Ivy_Obj_t * pFanReal0, * pFanReal1, * pResult; - assert( Ivy_ObjIsNode(pNode) ); + if ( Ivy_ObjIsPo(pNode) ) + { + if ( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) ) + return; + pFanReal0 = Ivy_ObjReal( Ivy_ObjChild0(pNode) ); + Ivy_ObjPatchFanin0( p, pNode, pFanReal0 ); + return; + } if ( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) && !Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) ) return; // get the real fanins - pFanReal0 = Ivy_NodeRealFanin_rec( pNode, 0 ); - pFanReal1 = Ivy_NodeRealFanin_rec( pNode, 1 ); + pFanReal0 = Ivy_ObjReal( Ivy_ObjChild0(pNode) ); + pFanReal1 = Ivy_ObjReal( Ivy_ObjChild1(pNode) ); // get the new node - pResult = Ivy_Oper( pFanReal0, pFanReal1, Ivy_ObjType(pNode) ); + if ( Ivy_ObjIsNode(pNode) ) + pResult = Ivy_Oper( p, pFanReal0, pFanReal1, Ivy_ObjType(pNode) ); + else if ( Ivy_ObjIsLatch(pNode) ) + pResult = Ivy_Latch( p, pFanReal0, Ivy_ObjInit(pNode) ); + else + assert( 0 ); // perform the replacement - Ivy_ObjReplace( pNode, pResult, 1, 0 ); + Ivy_ObjReplace( p, pNode, pResult, 1, 0 ); } //////////////////////////////////////////////////////////////////////// |