diff options
Diffstat (limited to 'src/map/if/ifCut.c')
-rw-r--r-- | src/map/if/ifCut.c | 419 |
1 files changed, 144 insertions, 275 deletions
diff --git a/src/map/if/ifCut.c b/src/map/if/ifCut.c index 65627dc2..5b520102 100644 --- a/src/map/if/ifCut.c +++ b/src/map/if/ifCut.c @@ -33,7 +33,7 @@ ABC_NAMESPACE_IMPL_START /**Function************************************************************* - Synopsis [Returns 1 if pDom is contained in pCut.] + Synopsis [Check correctness of cuts.] Description [] @@ -42,24 +42,71 @@ ABC_NAMESPACE_IMPL_START SeeAlso [] ***********************************************************************/ -static inline int If_CutCheckDominance( If_Cut_t * pDom, If_Cut_t * pCut ) +static inline int If_CutVerifyCut( If_Cut_t * pBase, If_Cut_t * pCut ) // check if pCut is contained in pBase { + int nSizeB = pBase->nLeaves; + int nSizeC = pCut->nLeaves; + int * pB = pBase->pLeaves; + int * pC = pCut->pLeaves; int i, k; - for ( i = 0; i < (int)pDom->nLeaves; i++ ) + for ( i = 0; i < nSizeC; i++ ) { - for ( k = 0; k < (int)pCut->nLeaves; k++ ) - if ( pDom->pLeaves[i] == pCut->pLeaves[k] ) + for ( k = 0; k < nSizeB; k++ ) + if ( pC[i] == pB[k] ) break; - if ( k == (int)pCut->nLeaves ) // node i in pDom is not contained in pCut + if ( k == nSizeB ) return 0; } - // every node in pDom is contained in pCut + return 1; +} +int If_CutVerifyCuts( If_Set_t * pCutSet, int fOrdered ) +{ + static int Count = 0; + If_Cut_t * pCut0, * pCut1; + int i, k, m, n, Value; + assert( pCutSet->nCuts > 0 ); + for ( i = 0; i < pCutSet->nCuts; i++ ) + { + pCut0 = pCutSet->ppCuts[i]; + if ( fOrdered ) + { + // check duplicates + for ( m = 1; m < (int)pCut0->nLeaves; m++ ) + assert( pCut0->pLeaves[m-1] < pCut0->pLeaves[m] ); + } + else + { + // check duplicates + for ( m = 0; m < (int)pCut0->nLeaves; m++ ) + for ( n = m+1; n < (int)pCut0->nLeaves; n++ ) + assert( pCut0->pLeaves[m] != pCut0->pLeaves[n] ); + } + // check pairs + for ( k = 0; k < pCutSet->nCuts; k++ ) + { + pCut1 = pCutSet->ppCuts[k]; + if ( pCut0 == pCut1 ) + continue; + Count++; + // check containments + Value = If_CutVerifyCut( pCut0, pCut1 ); +// assert( Value == 0 ); + if ( Value ) + { + assert( pCut0->uSign == If_ObjCutSignCompute(pCut0) ); + assert( pCut1->uSign == If_ObjCutSignCompute(pCut1) ); + If_CutPrint( pCut0 ); + If_CutPrint( pCut1 ); + assert( 0 ); + } + } + } return 1; } /**Function************************************************************* - Synopsis [Returns 1 if pDom is equal to pCut.] + Synopsis [Returns 1 if pDom is contained in pCut.] Description [] @@ -68,14 +115,19 @@ static inline int If_CutCheckDominance( If_Cut_t * pDom, If_Cut_t * pCut ) SeeAlso [] ***********************************************************************/ -static inline int If_CutCheckEquality( If_Cut_t * pDom, If_Cut_t * pCut ) +static inline int If_CutCheckDominance( If_Cut_t * pDom, If_Cut_t * pCut ) { - int i; - if ( (int)pDom->nLeaves != (int)pCut->nLeaves ) - return 0; + int i, k; + assert( pDom->nLeaves <= pCut->nLeaves ); for ( i = 0; i < (int)pDom->nLeaves; i++ ) - if ( pDom->pLeaves[i] != pCut->pLeaves[i] ) + { + for ( k = 0; k < (int)pCut->nLeaves; k++ ) + if ( pDom->pLeaves[i] == pCut->pLeaves[k] ) + break; + if ( k == (int)pCut->nLeaves ) // node i in pDom is not contained in pCut return 0; + } + // every node in pDom is contained in pCut return 1; } @@ -101,7 +153,7 @@ int If_CutFilter( If_Set_t * pCutSet, If_Cut_t * pCut ) if ( pTemp->nLeaves > pCut->nLeaves ) { // do not fiter the first cut - if ( i == 0 ) + if ( i == 0 && pCutSet->nCuts > 1 && pCutSet->ppCuts[1]->fUseless ) continue; // skip the non-contained cuts if ( (pTemp->uSign & pCut->uSign) != pCut->uSign ) @@ -136,93 +188,7 @@ int If_CutFilter( If_Set_t * pCutSet, If_Cut_t * pCut ) /**Function************************************************************* - Synopsis [Merges two cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int If_CutMergeOrderedOld( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC ) -{ - int i, k, c; - assert( pC0->nLeaves >= pC1->nLeaves ); - // the case of the largest cut sizes - if ( pC0->nLeaves == pC->nLimit && pC1->nLeaves == pC->nLimit ) - { - for ( i = 0; i < (int)pC0->nLeaves; i++ ) - if ( pC0->pLeaves[i] != pC1->pLeaves[i] ) - return 0; - for ( i = 0; i < (int)pC0->nLeaves; i++ ) - pC->pLeaves[i] = pC0->pLeaves[i]; - pC->nLeaves = pC0->nLeaves; - return 1; - } - // the case when one of the cuts is the largest - if ( pC0->nLeaves == pC->nLimit ) - { - for ( i = 0; i < (int)pC1->nLeaves; i++ ) - { - for ( k = (int)pC0->nLeaves - 1; k >= 0; k-- ) - if ( pC0->pLeaves[k] == pC1->pLeaves[i] ) - break; - if ( k == -1 ) // did not find - return 0; - } - for ( i = 0; i < (int)pC0->nLeaves; i++ ) - pC->pLeaves[i] = pC0->pLeaves[i]; - pC->nLeaves = pC0->nLeaves; - return 1; - } - - // compare two cuts with different numbers - i = k = 0; - for ( c = 0; c < (int)pC->nLimit; c++ ) - { - if ( k == (int)pC1->nLeaves ) - { - if ( i == (int)pC0->nLeaves ) - { - pC->nLeaves = c; - return 1; - } - pC->pLeaves[c] = pC0->pLeaves[i++]; - continue; - } - if ( i == (int)pC0->nLeaves ) - { - if ( k == (int)pC1->nLeaves ) - { - pC->nLeaves = c; - return 1; - } - pC->pLeaves[c] = pC1->pLeaves[k++]; - continue; - } - if ( pC0->pLeaves[i] < pC1->pLeaves[k] ) - { - pC->pLeaves[c] = pC0->pLeaves[i++]; - continue; - } - if ( pC0->pLeaves[i] > pC1->pLeaves[k] ) - { - pC->pLeaves[c] = pC1->pLeaves[k++]; - continue; - } - pC->pLeaves[c] = pC0->pLeaves[i++]; - k++; - } - if ( i < (int)pC0->nLeaves || k < (int)pC1->nLeaves ) - return 0; - pC->nLeaves = c; - return 1; -} - -/**Function************************************************************* - - Synopsis [Merges two cuts.] + Synopsis [Prepares the object for FPGA mapping.] Description [] @@ -231,33 +197,35 @@ static inline int If_CutMergeOrderedOld( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_ SeeAlso [] ***********************************************************************/ -static inline int If_CutMergeOrdered( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC ) +int If_CutMergeOrdered_( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC ) { int nSizeC0 = pC0->nLeaves; int nSizeC1 = pC1->nLeaves; int nLimit = pC0->nLimit; int i, k, c, s; - // the case when one of the cuts is the largest - if ( nSizeC0 == nLimit ) + // both cuts are the largest + if ( nSizeC0 == nLimit && nSizeC1 == nLimit ) { - // the case of the largest cut sizes - if ( nSizeC1 == nLimit ) + for ( i = 0; i < nSizeC0; i++ ) { - for ( i = 0; i < nSizeC0; i++ ) - { - if ( pC0->pLeaves[i] != pC1->pLeaves[i] ) - return 0; - p->pPerm[0][i] = p->pPerm[1][i] = p->pPerm[2][i] = i; - pC->pLeaves[i] = pC0->pLeaves[i]; - } - pC->nLeaves = nLimit; - return 1; + if ( pC0->pLeaves[i] != pC1->pLeaves[i] ) + return 0; + p->pPerm[0][i] = p->pPerm[1][i] = p->pPerm[2][i] = i; + pC->pLeaves[i] = pC0->pLeaves[i]; } + p->nShared = nLimit; + pC->nLeaves = nLimit; + pC->uSign = pC0->uSign | pC1->uSign; + p->uSharedMask = Abc_InfoMask( nLimit ); + return 1; } // compare two cuts with different numbers i = k = c = s = 0; + p->uSharedMask = 0; + if ( nSizeC0 == 0 ) goto FlushCut1; + if ( nSizeC1 == 0 ) goto FlushCut0; while ( 1 ) { if ( c == nLimit ) return 0; @@ -265,20 +233,21 @@ static inline int If_CutMergeOrdered( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * p { p->pPerm[0][i] = c; pC->pLeaves[c++] = pC0->pLeaves[i++]; - if ( i >= nSizeC0 ) goto FlushCut1; + if ( i == nSizeC0 ) goto FlushCut1; } else if ( pC0->pLeaves[i] > pC1->pLeaves[k] ) { p->pPerm[1][k] = c; pC->pLeaves[c++] = pC1->pLeaves[k++]; - if ( k >= nSizeC1 ) goto FlushCut0; + if ( k == nSizeC1 ) goto FlushCut0; } else { + p->uSharedMask |= (1 << c); p->pPerm[0][i] = p->pPerm[1][k] = p->pPerm[2][s++] = c; pC->pLeaves[c++] = pC0->pLeaves[i++]; k++; - if ( i >= nSizeC0 ) goto FlushCut1; - if ( k >= nSizeC1 ) goto FlushCut0; + if ( i == nSizeC0 ) goto FlushCut1; + if ( k == nSizeC1 ) goto FlushCut0; } } @@ -289,7 +258,10 @@ FlushCut0: p->pPerm[0][i] = c; pC->pLeaves[c++] = pC0->pLeaves[i++]; } + p->nShared = s; pC->nLeaves = c; + pC->uSign = pC0->uSign | pC1->uSign; + assert( c > 0 ); return 1; FlushCut1: @@ -299,91 +271,10 @@ FlushCut1: p->pPerm[1][k] = c; pC->pLeaves[c++] = pC1->pLeaves[k++]; } + p->nShared = s; pC->nLeaves = c; - return 1; -} - -/**Function************************************************************* - - Synopsis [Merges two cuts.] - - Description [Special case when the cut is known to exist.] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -static inline int If_CutMergeOrdered2( If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC ) -{ - int i, k, c; - assert( pC0->nLeaves >= pC1->nLeaves ); - // copy the first cut - for ( i = 0; i < (int)pC0->nLeaves; i++ ) - pC->pLeaves[i] = pC0->pLeaves[i]; - pC->nLeaves = pC0->nLeaves; - // the case when one of the cuts is the largest - if ( pC0->nLeaves == pC->nLimit ) - return 1; - // add nodes of the second cut - k = 0; - for ( i = 0; i < (int)pC1->nLeaves; i++ ) - { - // find k-th node before which i-th node should be added - for ( ; k < (int)pC->nLeaves; k++ ) - if ( pC->pLeaves[k] >= pC1->pLeaves[i] ) - break; - // check the case when this should be the last node - if ( k == (int)pC->nLeaves ) - { - pC->pLeaves[k++] = pC1->pLeaves[i]; - pC->nLeaves++; - continue; - } - // check the case when equal node is found - if ( pC1->pLeaves[i] == pC->pLeaves[k] ) - continue; - // add the node - for ( c = (int)pC->nLeaves; c > k; c-- ) - pC->pLeaves[c] = pC->pLeaves[c-1]; - pC->pLeaves[k++] = pC1->pLeaves[i]; - pC->nLeaves++; - } -/* - assert( pC->nLeaves <= pC->nLimit ); - for ( i = 1; i < (int)pC->nLeaves; i++ ) - assert( pC->pLeaves[i-1] < pC->pLeaves[i] ); -*/ - return 1; -} - -/**Function************************************************************* - - Synopsis [Prepares the object for FPGA mapping.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -int If_CutMerge2( If_Man_t * p, If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * pCut ) -{ - assert( pCut->nLimit > 0 ); - // merge the nodes - if ( pCut0->nLeaves < pCut1->nLeaves ) - { - if ( !If_CutMergeOrdered( p, pCut1, pCut0, pCut ) ) - return 0; - } - else - { - if ( !If_CutMergeOrdered( p, pCut0, pCut1, pCut ) ) - return 0; - } - pCut->uSign = pCut0->uSign | pCut1->uSign; - assert( If_CutCheck( pCut ) ); + pC->uSign = pC0->uSign | pC1->uSign; + assert( c > 0 ); return 1; } @@ -398,7 +289,7 @@ int If_CutMerge2( If_Man_t * p, If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * p SeeAlso [] ***********************************************************************/ -int If_CutMerge( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC ) +int If_CutMergeOrdered( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC ) { int nSizeC0 = pC0->nLeaves; int nSizeC1 = pC1->nLeaves; @@ -412,68 +303,33 @@ int If_CutMerge( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC ) { if ( pC0->pLeaves[i] != pC1->pLeaves[i] ) return 0; - p->pPerm[0][i] = p->pPerm[1][i] = p->pPerm[2][i] = i; pC->pLeaves[i] = pC0->pLeaves[i]; } - p->nShared = nLimit; pC->nLeaves = nLimit; pC->uSign = pC0->uSign | pC1->uSign; - p->uSharedMask = Abc_InfoMask( nLimit ); - return 1; - } - // one cut is empty - if ( nSizeC0 == 0 ) - { - assert( pC0->uSign == 0 ); - for ( i = 0; i < nSizeC1; i++ ) - { - pC->pLeaves[i] = pC1->pLeaves[i]; - p->pPerm[1][i] = i; - } - p->nShared = 0; - pC->nLeaves = nSizeC1; - pC->uSign = pC0->uSign | pC1->uSign; - p->uSharedMask = 0; - return 1; - } - if ( nSizeC1 == 0 ) - { - assert( pC1->uSign == 0 ); - for ( i = 0; i < nSizeC0; i++ ) - { - pC->pLeaves[i] = pC0->pLeaves[i]; - p->pPerm[0][i] = i; - } - p->nShared = 0; - pC->nLeaves = nSizeC0; - pC->uSign = pC0->uSign | pC1->uSign; - p->uSharedMask = 0; return 1; } // compare two cuts with different numbers - i = k = c = s = 0; - p->uSharedMask = 0; + i = k = c = s = 0; p->nShared = 0; + if ( nSizeC0 == 0 ) goto FlushCut1; + if ( nSizeC1 == 0 ) goto FlushCut0; while ( 1 ) { if ( c == nLimit ) return 0; if ( pC0->pLeaves[i] < pC1->pLeaves[k] ) { - p->pPerm[0][i] = c; pC->pLeaves[c++] = pC0->pLeaves[i++]; if ( i == nSizeC0 ) goto FlushCut1; } else if ( pC0->pLeaves[i] > pC1->pLeaves[k] ) { - p->pPerm[1][k] = c; pC->pLeaves[c++] = pC1->pLeaves[k++]; if ( k == nSizeC1 ) goto FlushCut0; } else { - p->uSharedMask |= (1 << c); - p->pPerm[0][i] = p->pPerm[1][k] = p->pPerm[2][s++] = c; - pC->pLeaves[c++] = pC0->pLeaves[i++]; k++; + pC->pLeaves[c++] = pC0->pLeaves[i++]; k++; p->nShared++; if ( i == nSizeC0 ) goto FlushCut1; if ( k == nSizeC1 ) goto FlushCut0; } @@ -482,11 +338,7 @@ int If_CutMerge( If_Man_t * p, If_Cut_t * pC0, If_Cut_t * pC1, If_Cut_t * pC ) FlushCut0: if ( c + nSizeC0 > nLimit + i ) return 0; while ( i < nSizeC0 ) - { - p->pPerm[0][i] = c; pC->pLeaves[c++] = pC0->pLeaves[i++]; - } - p->nShared = s; pC->nLeaves = c; pC->uSign = pC0->uSign | pC1->uSign; return 1; @@ -494,11 +346,7 @@ FlushCut0: FlushCut1: if ( c + nSizeC1 > nLimit + k ) return 0; while ( k < nSizeC1 ) - { - p->pPerm[1][k] = c; pC->pLeaves[c++] = pC1->pLeaves[k++]; - } - p->nShared = s; pC->nLeaves = c; pC->uSign = pC0->uSign | pC1->uSign; return 1; @@ -515,6 +363,51 @@ FlushCut1: SeeAlso [] ***********************************************************************/ +int If_CutMerge( If_Man_t * p, If_Cut_t * pCut0, If_Cut_t * pCut1, If_Cut_t * pCut ) +{ + int nLutSize = pCut0->nLimit; + int nSize0 = pCut0->nLeaves; + int nSize1 = pCut1->nLeaves; + int * pC0 = pCut0->pLeaves; + int * pC1 = pCut1->pLeaves; + int * pC = pCut->pLeaves; + int i, k, c; + // compare two cuts with different numbers + c = nSize0; p->nShared = 0; + for ( i = 0; i < nSize1; i++ ) + { + for ( k = 0; k < nSize0; k++ ) + if ( pC1[i] == pC0[k] ) + break; + if ( k < nSize0 ) + { + p->pPerm[1][i] = k; + p->nShared++; + continue; + } + if ( c == nLutSize ) + return 0; + p->pPerm[1][i] = c; + pC[c++] = pC1[i]; + } + for ( i = 0; i < nSize0; i++ ) + pC[i] = pC0[i]; + pCut->nLeaves = c; + pCut->uSign = pCut0->uSign | pCut1->uSign; + return 1; +} + +/**Function************************************************************* + + Synopsis [Prepares the object for FPGA mapping.] + + Description [] + + SideEffects [] + + SeeAlso [] + +***********************************************************************/ int If_CutCompareDelay( If_Man_t * p, If_Cut_t ** ppC0, If_Cut_t ** ppC1 ) { If_Cut_t * pC0 = *ppC0; @@ -600,30 +493,6 @@ int If_CutCompareArea( If_Man_t * p, If_Cut_t ** ppC0, If_Cut_t ** ppC1 ) /**Function************************************************************* - Synopsis [Sorts the cuts.] - - Description [] - - SideEffects [] - - SeeAlso [] - -***********************************************************************/ -void If_ManSortCuts( If_Man_t * p, int Mode ) -{ -/* - // sort the cuts - if ( Mode || p->pPars->fArea ) // area - qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareArea ); - else if ( p->pPars->fFancy ) - qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareDelayOld ); - else - qsort( p->ppCuts, p->nCuts, sizeof(If_Cut_t *), (int (*)(const void *, const void *))If_CutCompareDelay ); -*/ -} - -/**Function************************************************************* - Synopsis [Comparison function for two cuts.] Description [] |