| /**CFile**************************************************************** |
| |
| FileName [reoTransfer.c] |
| |
| PackageName [REO: A specialized DD reordering engine.] |
| |
| Synopsis [Transfering a DD from the CUDD manager into REO"s internal data structures and back.] |
| |
| Author [Alan Mishchenko] |
| |
| Affiliation [UC Berkeley] |
| |
| Date [Ver. 1.0. Started - October 15, 2002.] |
| |
| Revision [$Id: reoTransfer.c,v 1.0 2002/15/10 03:00:00 alanmi Exp $] |
| |
| ***********************************************************************/ |
| |
| #include "reo.h" |
| |
| ABC_NAMESPACE_IMPL_START |
| |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// DECLARATIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// FUNCTION DEFINITIONS /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| /**Function************************************************************* |
| |
| Synopsis [Transfers the DD into the internal reordering data structure.] |
| |
| Description [It is important that the hash table is lossless.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| reo_unit * reoTransferNodesToUnits_rec( reo_man * p, DdNode * F ) |
| { |
| DdManager * dd = p->dd; |
| reo_unit * pUnit; |
| int HKey = -1; // Suppress "might be used uninitialized" |
| int fComp; |
| |
| fComp = Cudd_IsComplement(F); |
| F = Cudd_Regular(F); |
| |
| // check the hash-table |
| if ( F->ref != 1 ) |
| { |
| // search cache - use linear probing |
| for ( HKey = hashKey2(p->Signature,F,p->nTableSize); p->HTable[HKey].Sign == p->Signature; HKey = (HKey+1) % p->nTableSize ) |
| if ( p->HTable[HKey].Arg1 == (reo_unit *)F ) |
| { |
| pUnit = p->HTable[HKey].Arg2; |
| assert( pUnit ); |
| // increment the edge counter |
| pUnit->n++; |
| return Unit_NotCond( pUnit, fComp ); |
| } |
| } |
| // the entry in not found in the cache |
| |
| // create a new entry |
| pUnit = reoUnitsGetNextUnit( p ); |
| pUnit->n = 1; |
| if ( cuddIsConstant(F) ) |
| { |
| pUnit->lev = REO_CONST_LEVEL; |
| pUnit->pE = (reo_unit*)(ABC_PTRUINT_T)(cuddV(F)); |
| pUnit->pT = NULL; |
| // check if the diagram that is being reordering has complement edges |
| if ( F != dd->one ) |
| p->fThisIsAdd = 1; |
| // insert the unit into the corresponding plane |
| reoUnitsAddUnitToPlane( &(p->pPlanes[p->nSupp]), pUnit ); // increments the unit counter |
| } |
| else |
| { |
| pUnit->lev = p->pMapToPlanes[F->index]; |
| pUnit->pE = reoTransferNodesToUnits_rec( p, cuddE(F) ); |
| pUnit->pT = reoTransferNodesToUnits_rec( p, cuddT(F) ); |
| // insert the unit into the corresponding plane |
| reoUnitsAddUnitToPlane( &(p->pPlanes[pUnit->lev]), pUnit ); // increments the unit counter |
| } |
| |
| // add to the hash table |
| if ( F->ref != 1 ) |
| { |
| // the next free entry is already found - it is pointed to by HKey |
| // while we traversed the diagram, the hash entry to which HKey points, |
| // might have been used. Make sure that its signature is different. |
| for ( ; p->HTable[HKey].Sign == p->Signature; HKey = (HKey+1) % p->nTableSize ); |
| p->HTable[HKey].Sign = p->Signature; |
| p->HTable[HKey].Arg1 = (reo_unit *)F; |
| p->HTable[HKey].Arg2 = pUnit; |
| } |
| |
| // increment the counter of nodes |
| p->nNodesCur++; |
| return Unit_NotCond( pUnit, fComp ); |
| } |
| |
| /**Function************************************************************* |
| |
| Synopsis [Creates the DD from the internal reordering data structure.] |
| |
| Description [It is important that the hash table is lossless.] |
| |
| SideEffects [] |
| |
| SeeAlso [] |
| |
| ***********************************************************************/ |
| DdNode * reoTransferUnitsToNodes_rec( reo_man * p, reo_unit * pUnit ) |
| { |
| DdManager * dd = p->dd; |
| DdNode * bRes, * E, * T; |
| int HKey = -1; // Suppress "might be used uninitialized" |
| int fComp; |
| |
| fComp = Cudd_IsComplement(pUnit); |
| pUnit = Unit_Regular(pUnit); |
| |
| // check the hash-table |
| if ( pUnit->n != 1 ) |
| { |
| for ( HKey = hashKey2(p->Signature,pUnit,p->nTableSize); p->HTable[HKey].Sign == p->Signature; HKey = (HKey+1) % p->nTableSize ) |
| if ( p->HTable[HKey].Arg1 == pUnit ) |
| { |
| bRes = (DdNode*) p->HTable[HKey].Arg2; |
| assert( bRes ); |
| return Cudd_NotCond( bRes, fComp ); |
| } |
| } |
| |
| // treat the case of constants |
| if ( Unit_IsConstant(pUnit) ) |
| { |
| bRes = cuddUniqueConst( dd, ((double)((int)(ABC_PTRUINT_T)(pUnit->pE))) ); |
| cuddRef( bRes ); |
| } |
| else |
| { |
| // split and recur on children of this node |
| E = reoTransferUnitsToNodes_rec( p, pUnit->pE ); |
| if ( E == NULL ) |
| return NULL; |
| cuddRef(E); |
| |
| T = reoTransferUnitsToNodes_rec( p, pUnit->pT ); |
| if ( T == NULL ) |
| { |
| Cudd_RecursiveDeref(dd, E); |
| return NULL; |
| } |
| cuddRef(T); |
| |
| // consider the case when Res0 and Res1 are the same node |
| assert( E != T ); |
| assert( !Cudd_IsComplement(T) ); |
| |
| bRes = cuddUniqueInter( dd, p->pMapToDdVarsFinal[pUnit->lev], T, E ); |
| if ( bRes == NULL ) |
| { |
| Cudd_RecursiveDeref(dd,E); |
| Cudd_RecursiveDeref(dd,T); |
| return NULL; |
| } |
| cuddRef( bRes ); |
| cuddDeref( E ); |
| cuddDeref( T ); |
| } |
| |
| // do not keep the result if the ref count is only 1, since it will not be visited again |
| if ( pUnit->n != 1 ) |
| { |
| // while we traversed the diagram, the hash entry to which HKey points, |
| // might have been used. Make sure that its signature is different. |
| for ( ; p->HTable[HKey].Sign == p->Signature; HKey = (HKey+1) % p->nTableSize ); |
| p->HTable[HKey].Sign = p->Signature; |
| p->HTable[HKey].Arg1 = pUnit; |
| p->HTable[HKey].Arg2 = (reo_unit *)bRes; |
| |
| // add the DD to the referenced DD list in order to be able to store it in cache |
| p->pRefNodes[p->nRefNodes++] = bRes; Cudd_Ref( bRes ); |
| // no need to do this, because the garbage collection will not take bRes away |
| // it is held by the diagram in the making |
| } |
| // increment the counter of nodes |
| p->nNodesCur++; |
| cuddDeref( bRes ); |
| return Cudd_NotCond( bRes, fComp ); |
| } |
| |
| //////////////////////////////////////////////////////////////////////// |
| /// END OF FILE /// |
| //////////////////////////////////////////////////////////////////////// |
| |
| ABC_NAMESPACE_IMPL_END |
| |