41static inline int Ivy_CutHashValue(
int NodeId ) {
return 1 << (NodeId % 31); }
68 abctime clk, clkStart = Abc_Clock();
76 if ( pManRwt == NULL )
79 if (
p->fFanout == 0 )
82 nNodes = Ivy_ManObjIdMax(
p);
85 assert( !Ivy_ObjIsBuf(pNode) );
86 assert( !Ivy_ObjIsBuf(Ivy_ObjFanin0(pNode)) );
87 assert( !Ivy_ObjIsBuf(Ivy_ObjFanin1(pNode)) );
96 nGain = Ivy_NodeRewriteSeq(
p, pManRwt, pNode, fUseZeroCost );
97 if ( nGain > 0 || (nGain == 0 && fUseZeroCost) )
103 if ( fCompl ) Dec_GraphComplement( pGraph );
104 Ivy_GraphUpdateNetworkSeq(
p, pNode, pGraph, nGain );
105 if ( fCompl ) Dec_GraphComplement( pGraph );
122 printf(
"Ivy_ManRewritePre(): The check has failed.\n" );
147 int fVeryVerbose = 0;
154 unsigned uTruthBest = 0;
158 int nNodesSaveCur = -1;
159 int i, c, GainCur = -1, GainBest = -1;
162 p->nNodesConsidered++;
165 pStore = Ivy_CutComputeForNode( pMan, pNode, 5 );
166p->timeCut += Abc_Clock() - clk;
170 vFanout = Vec_PtrAlloc( 100 );
171 for ( c = 1; c < pStore->
nCuts; c++ )
173 pCut = pStore->
pCuts + c;
175 if ( pCut->
nSize != 4 )
178 for ( i = 0; i < (int)pCut->
nSize; i++ )
179 if ( Ivy_ObjIsBuf( Ivy_ManObj(pMan, Ivy_LeafId(pCut->
pArray[i])) ) )
181 if ( i != pCut->
nSize )
189 uTruth = 0xFFFF & Ivy_CutGetTruth( pMan, pNode, pCut->
pArray, pCut->
nSize );
190p->timeTruth += Abc_Clock() - clk2;
191 pPerm =
p->pPerms4[ (int)
p->pPerms[uTruth] ];
192 uPhase =
p->pPhases[uTruth];
194 Vec_PtrClear(
p->vFaninsCur );
195 Vec_PtrFill(
p->vFaninsCur, (
int)pCut->
nSize, 0 );
196 for ( i = 0; i < (int)pCut->
nSize; i++ )
198 pFanin = Ivy_ManObj( pMan, Ivy_LeafId( pCut->
pArray[(
int)pPerm[i]] ) );
199 assert( Ivy_ObjIsNode(pFanin) || Ivy_ObjIsCi(pFanin) || Ivy_ObjIsConst1(pFanin) );
200 pFanin = Ivy_NotCond(pFanin, ((uPhase & (1<<i)) > 0) );
201 Vec_PtrWriteEntry(
p->vFaninsCur, i, pFanin );
206 Ivy_ObjRefsInc( Ivy_Regular(pFanin) );
215 Ivy_ObjRefsDec( Ivy_Regular(pFanin) );
216p->timeMffc += Abc_Clock() - clk2;
220 pGraph = Rwt_CutEvaluateSeq( pMan,
p, pNode, pCut, pPerm,
p->vFaninsCur, nNodesSaved, &GainCur, uTruth );
221p->timeEval += Abc_Clock() - clk2;
225 if ( pGraph != NULL && GainBest < GainCur )
228 nNodesSaveCur = nNodesSaved;
233 p->fCompl = ((uPhase & (1<<4)) > 0);
236 Vec_PtrClear(
p->vFanins );
238 Vec_PtrPush(
p->vFanins, pFanin );
241 Vec_PtrFree( vFanout );
242p->timeRes += Abc_Clock() - clk;
244 if ( GainBest == -1 )
268 p->nScores[
p->pMap[uTruthBest]]++;
269 p->nNodesGained += GainBest;
270 if ( fUseZeroCost || GainBest > 0 )
271 p->nNodesRewritten++;
285 if ( fVeryVerbose && GainBest > 0 )
287 printf(
"Node %6d : ", Ivy_ObjId(pNode) );
288 printf(
"Fanins = %d. ",
p->vFanins->nSize );
289 printf(
"Save = %d. ", nNodesSaveCur );
290 printf(
"Add = %d. ", nNodesSaveCur-GainBest );
291 printf(
"GAIN = %d. ", GainBest );
292 printf(
"Cone = %d. ",
p->pGraph? Dec_GraphNodeNum((
Dec_Graph_t *)
p->pGraph) : 0 );
293 printf(
"Class = %d. ",
p->pMap[uTruthBest] );
317 int nNodesAdded, GainBest, i;
319 vSubgraphs = Vec_VecEntry(
p->vClasses,
p->pMap[uTruth] );
320 p->nSubgraphs += vSubgraphs->nSize;
333 Ivy_GraphPrepare( pGraphCur, pCut, vFaninsCur, pPerm );
336 nNodesAdded = Ivy_GraphToNetworkSeqCountSeq( pMan, pRoot, pGraphCur, nNodesSaved );
337 if ( nNodesAdded == -1 )
339 assert( nNodesSaved >= nNodesAdded );
341 if ( GainBest < nNodesSaved - nNodesAdded )
343 GainBest = nNodesSaved - nNodesAdded;
344 pGraphBest = pGraphCur;
347 if ( GainBest == -1 )
349 *pGainBest = GainBest;
368 assert( Dec_GraphLeaveNum(pGraph) == pCut->
nSize );
373 pNode->
pFunc = Vec_PtrEntry( vFanins, i );
374 pNode->
nLat2 = Ivy_LeafLat( pCut->
pArray[(
int)pPerm[i]] );
380 pNode0 = Dec_GraphNode( pGraph, pNode->
eEdge0.Node );
381 pNode1 = Dec_GraphNode( pGraph, pNode->
eEdge1.Node );
407 int i, k, Counter, fCompl;
409 if ( Dec_GraphIsConst(pGraph) || Dec_GraphIsVar(pGraph) )
416 pNode0 = Dec_GraphNode( pGraph, pNode->
eEdge0.Node );
417 pNode1 = Dec_GraphNode( pGraph, pNode->
eEdge1.Node );
422 for ( k = 0; pAnd0 && k < (int)pNode->
nLat0; k++ )
424 fCompl = Ivy_IsComplement(pAnd0);
427 pAnd0 = Ivy_NotCond( pAnd0, fCompl );
429 for ( k = 0; pAnd1 && k < (int)pNode->
nLat1; k++ )
431 fCompl = Ivy_IsComplement(pAnd1);
434 pAnd1 = Ivy_NotCond( pAnd1, fCompl );
437 if ( pAnd0 && pAnd1 )
440 pAnd0 = Ivy_NotCond( pAnd0, pNode->
eEdge0.fCompl );
441 pAnd1 = Ivy_NotCond( pAnd1, pNode->
eEdge1.fCompl );
442 assert( !Ivy_ObjIsLatch(Ivy_Regular(pAnd0)) || !Ivy_ObjIsLatch(Ivy_Regular(pAnd1)) );
443 if ( Ivy_Regular(pAnd0) == Ivy_Regular(pAnd1) || Ivy_ObjIsConst1(Ivy_Regular(pAnd0)) || Ivy_ObjIsConst1(Ivy_Regular(pAnd1)) )
448 if ( Ivy_Regular(pAnd) == pRoot )
454 if ( pAnd == NULL || Ivy_ObjIsTravIdCurrent(
p, Ivy_Regular(pAnd)) )
456 if ( ++Counter > NodeMax )
483 if ( Dec_GraphIsConst(pGraph) )
484 return Ivy_NotCond( Ivy_ManConst1(
p), Dec_GraphIsComplement(pGraph) );
486 if ( Dec_GraphIsVar(pGraph) )
489 pNode = Dec_GraphVar(pGraph);
491 for ( k = 0; k < (int)pNode->
nLat2; k++ )
493 return Ivy_NotCond( (
Ivy_Obj_t *)pNode->
pFunc, Dec_GraphIsComplement(pGraph) );
498 pAnd0 = Ivy_NotCond( (
Ivy_Obj_t *)Dec_GraphNode(pGraph, pNode->
eEdge0.Node)->pFunc, pNode->
eEdge0.fCompl );
499 pAnd1 = Ivy_NotCond( (
Ivy_Obj_t *)Dec_GraphNode(pGraph, pNode->
eEdge1.Node)->pFunc, pNode->
eEdge1.fCompl );
501 for ( k = 0; k < (int)pNode->
nLat0; k++ )
503 for ( k = 0; k < (int)pNode->
nLat1; k++ )
509 for ( k = 0; k < (int)pNode->
nLat2; k++ )
512 return Ivy_NotCond( (
Ivy_Obj_t *)pNode->
pFunc, Dec_GraphIsComplement(pGraph) );
529 int nNodesNew, nNodesOld;
530 nNodesOld = Ivy_ManNodeNum(
p);
532 pRootNew = Ivy_GraphToNetworkSeq(
p, pGraph );
535 nNodesNew = Ivy_ManNodeNum(
p);
536 assert( nGain <= nNodesOld - nNodesNew );
562 static unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 };
563 unsigned uTruth0, uTruth1;
566 for ( i = 0; i < nNums; i++ )
567 if ( Leaf == pNums[i] )
569 pObj = Ivy_ManObj(
p, Ivy_LeafId(Leaf) );
570 if ( Ivy_ObjIsLatch(pObj) )
572 assert( !Ivy_ObjFaninC0(pObj) );
573 Leaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pObj), Ivy_LeafLat(Leaf) + 1 );
576 assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj) );
577 Leaf = Ivy_LeafCreate( Ivy_ObjFaninId0(pObj), Ivy_LeafLat(Leaf) );
579 if ( Ivy_ObjFaninC0(pObj) )
581 if ( Ivy_ObjIsBuf(pObj) )
583 Leaf = Ivy_LeafCreate( Ivy_ObjFaninId1(pObj), Ivy_LeafLat(Leaf) );
585 if ( Ivy_ObjFaninC1(pObj) )
587 return uTruth0 & uTruth1;
604 assert( Ivy_ObjIsNode(pObj) );
624static inline int Ivy_CutPrescreen(
Ivy_Cut_t * pCut,
int Id0,
int Id1 )
629 for ( i = 0; i < pCut->
nSize; i++ )
646static inline int Ivy_CutDeriveNew2(
Ivy_Cut_t * pCut,
Ivy_Cut_t * pCutNew,
int IdOld,
int IdNew0,
int IdNew1 )
651 assert( IdNew0 < IdNew1 );
652 for ( i = k = 0; i < pCut->
nSize; i++ )
654 if ( pCut->
pArray[i] == IdOld )
658 if ( IdNew0 <= pCut->pArray[i] )
660 if ( IdNew0 < pCut->pArray[i] )
664 pCutNew->
pArray[ k++ ] = IdNew0;
665 uHash |= Ivy_CutHashValue( IdNew0 );
672 if ( IdNew1 <= pCut->pArray[i] )
674 if ( IdNew1 < pCut->pArray[i] )
678 pCutNew->
pArray[ k++ ] = IdNew1;
679 uHash |= Ivy_CutHashValue( IdNew1 );
687 uHash |= Ivy_CutHashValue( pCut->
pArray[i] );
693 pCutNew->
pArray[ k++ ] = IdNew0;
694 uHash |= Ivy_CutHashValue( IdNew0 );
700 pCutNew->
pArray[ k++ ] = IdNew1;
701 uHash |= Ivy_CutHashValue( IdNew1 );
704 pCutNew->
uHash = uHash;
706 for ( i = 1; i < pCutNew->
nSize; i++ )
722static inline int Ivy_CutDeriveNew(
Ivy_Cut_t * pCut,
Ivy_Cut_t * pCutNew,
int IdOld,
int IdNew0,
int IdNew1 )
727 assert( IdNew0 < IdNew1 );
728 for ( i = k = 0; i < pCut->
nSize; i++ )
730 if ( pCut->
pArray[i] == IdOld )
732 if ( IdNew0 <= pCut->pArray[i] )
734 if ( IdNew0 < pCut->pArray[i] )
736 pCutNew->
pArray[ k++ ] = IdNew0;
737 uHash |= Ivy_CutHashValue( IdNew0 );
741 if ( IdNew1 <= pCut->pArray[i] )
743 if ( IdNew1 < pCut->pArray[i] )
745 pCutNew->
pArray[ k++ ] = IdNew1;
746 uHash |= Ivy_CutHashValue( IdNew1 );
751 uHash |= Ivy_CutHashValue( pCut->
pArray[i] );
753 if ( IdNew0 < 0x7FFFFFFF )
755 pCutNew->
pArray[ k++ ] = IdNew0;
756 uHash |= Ivy_CutHashValue( IdNew0 );
758 if ( IdNew1 < 0x7FFFFFFF )
760 pCutNew->
pArray[ k++ ] = IdNew1;
761 uHash |= Ivy_CutHashValue( IdNew1 );
764 pCutNew->
uHash = uHash;
782static inline unsigned Ivy_NodeCutHash(
Ivy_Cut_t * pCut )
786 for ( i = 0; i < pCut->
nSize; i++ )
802static inline int Ivy_CutDeriveNew3(
Ivy_Cut_t * pCut,
Ivy_Cut_t * pCutNew,
int IdOld,
int IdNew0,
int IdNew1 )
806 assert( IdNew0 < IdNew1 );
807 for ( i = k = 0; i < pCut->
nSize; i++ )
809 if ( pCut->
pArray[i] == IdOld )
811 if ( IdNew0 <= pCut->pArray[i] )
813 if ( IdNew0 < pCut->pArray[i] )
814 pCutNew->
pArray[ k++ ] = IdNew0;
817 if ( IdNew1 <= pCut->pArray[i] )
819 if ( IdNew1 < pCut->pArray[i] )
820 pCutNew->
pArray[ k++ ] = IdNew1;
825 if ( IdNew0 < 0x7FFFFFFF )
826 pCutNew->
pArray[ k++ ] = IdNew0;
827 if ( IdNew1 < 0x7FFFFFFF )
828 pCutNew->
pArray[ k++ ] = IdNew1;
831 Ivy_NodeCutHash( pCutNew );
849 for ( i = 0; i < pDom->
nSize; i++ )
852 for ( k = 0; k < pCut->
nSize; k++ )
855 if ( k == pCut->
nSize )
879 for ( i = 0; i < pCutStore->
nCuts; i++ )
881 pCut = pCutStore->
pCuts + i;
882 if ( pCut->
nSize == 0 )
888 for ( k = 0; k < pCutNew->
nSize; k++ )
891 if ( k == pCutNew->
nSize )
902 if ( Ivy_CutCheckDominance( pCut, pCutNew ) )
912 if ( Ivy_CutCheckDominance( pCutNew, pCut ) )
941 for ( i = k = 0; i < pCutStore->
nCuts; i++ )
943 pCut = pCutStore->
pCuts + i;
944 if ( pCut->
nSize == 0 )
948 pCutStore->
pCuts[k++] = *pCut;
950 pCutStore->
nCuts = k;
968 printf(
"%d : {", pCut->
nSize );
969 for ( i = 0; i < pCut->
nSize; i++ )
970 printf(
" %d", pCut->
pArray[i] );
988 printf(
"Node %d\n", pCutStore->
pCuts[0].
pArray[0] );
989 for ( i = 0; i < pCutStore->
nCuts; i++ )
1004static inline int Ivy_CutReadLeaf(
Ivy_Obj_t * pFanin )
1007 assert( !Ivy_IsComplement(pFanin) );
1008 if ( !Ivy_ObjIsLatch(pFanin) )
1009 return Ivy_LeafCreate( pFanin->
Id, 0 );
1010 iLeaf = Ivy_CutReadLeaf(Ivy_ObjFanin0(pFanin));
1011 nLats = Ivy_LeafLat(iLeaf);
1029 static Ivy_Store_t CutStore, * pCutStore = &CutStore;
1030 Ivy_Cut_t CutNew, * pCutNew = &CutNew, * pCut;
1032 int i, k, Temp, nLats, iLeaf0, iLeaf1;
1037 pCutStore->
nCuts = 0;
1043 pCutNew->
pArray[0] = Ivy_LeafCreate( pObj->
Id, 0 );
1044 pCutNew->
uHash = Ivy_CutHashValue( pCutNew->
pArray[0] );
1046 pCutStore->
pCuts[pCutStore->
nCuts++] = *pCutNew;
1050 for ( i = 0; i < pCutStore->
nCuts; i++ )
1053 pCut = pCutStore->
pCuts + i;
1054 if ( pCut->nSize == 0 )
1056 for ( k = 0; k < pCut->nSize; k++ )
1058 pLeaf = Ivy_ManObj(
p, Ivy_LeafId(pCut->pArray[k]) );
1059 if ( Ivy_ObjIsCi(pLeaf) || Ivy_ObjIsConst1(pLeaf) )
1061 assert( Ivy_ObjIsNode(pLeaf) );
1062 nLats = Ivy_LeafLat(pCut->pArray[k]);
1065 iLeaf0 = Ivy_CutReadLeaf( Ivy_ObjFanin0(pLeaf) );
1066 iLeaf1 = Ivy_CutReadLeaf( Ivy_ObjFanin1(pLeaf) );
1068 iLeaf0 = nLats + iLeaf0;
1069 iLeaf1 = nLats + iLeaf1;
1070 if ( !Ivy_CutPrescreen( pCut, iLeaf0, iLeaf1 ) )
1073 if ( iLeaf0 > iLeaf1 )
1074 Temp = iLeaf0, iLeaf0 = iLeaf1, iLeaf1 = Temp;
1076 if ( !Ivy_CutDeriveNew( pCut, pCutNew, pCut->pArray[k], iLeaf0, iLeaf1 ) )
1112 int i, nCutsTotal, nCutsTotalM, nNodeTotal, nNodeOver;
1116 printf(
"Cannot compute cuts for more than %d inputs.\n",
IVY_CUT_INPUT );
1119 nNodeTotal = nNodeOver = 0;
1120 nCutsTotal = nCutsTotalM = -Ivy_ManNodeNum(
p);
1123 if ( !Ivy_ObjIsNode(pObj) )
1125 pStore = Ivy_CutComputeForNode(
p, pObj, nInputs );
1126 nCutsTotal += pStore->
nCuts;
1127 nCutsTotalM += pStore->
nCutsM;
1128 nNodeOver += pStore->
fSatur;
1131 printf(
"All = %6d. Minus = %6d. Triv = %6d. Node = %6d. Satur = %6d. ",
1132 nCutsTotal, nCutsTotalM, Ivy_ManPiNum(
p) + Ivy_ManNodeNum(
p), nNodeTotal, nNodeOver );
1133 ABC_PRT(
"Time", Abc_Clock() - clk );
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
struct Dec_Node_t_ Dec_Node_t
#define Dec_GraphForEachLeaf(pGraph, pLeaf, i)
ITERATORS ///.
#define Dec_GraphForEachNode(pGraph, pAnd, i)
struct Dec_Graph_t_ Dec_Graph_t
void Ivy_CutComputeAll(Ivy_Man_t *p, int nInputs)
void Ivy_CutCompactAll(Ivy_Store_t *pCutStore)
int Ivy_ManRewriteSeq(Ivy_Man_t *p, int fUseZeroCost, int fVerbose)
FUNCTION DEFINITIONS ///.
void Ivy_CutPrintForNode(Ivy_Cut_t *pCut)
unsigned Ivy_CutGetTruth_rec(Ivy_Man_t *p, int Leaf, int *pNums, int nNums)
int Ivy_CutFindOrAddFilter(Ivy_Store_t *pCutStore, Ivy_Cut_t *pCutNew)
void Ivy_CutPrintForNodes(Ivy_Store_t *pCutStore)
int Ivy_ManCheck(Ivy_Man_t *p)
DECLARATIONS ///.
struct Ivy_Cut_t_ Ivy_Cut_t
int Ivy_ObjMffcLabel(Ivy_Man_t *p, Ivy_Obj_t *pObj)
typedefABC_NAMESPACE_HEADER_START struct Ivy_Man_t_ Ivy_Man_t
INCLUDES ///.
void Ivy_ManIncrementTravId(Ivy_Man_t *p)
DECLARATIONS ///.
Ivy_Obj_t * Ivy_Latch(Ivy_Man_t *p, Ivy_Obj_t *pObj, Ivy_Init_t Init)
#define Ivy_ManForEachLatch(p, pObj, i)
Ivy_Obj_t * Ivy_TableLookup(Ivy_Man_t *p, Ivy_Obj_t *pObj)
FUNCTION DEFINITIONS ///.
void Ivy_ManResetLevels(Ivy_Man_t *p)
#define Ivy_ManForEachObj(p, pObj, i)
#define Ivy_ManForEachNode(p, pObj, i)
#define IVY_MIN(a, b)
MACRO DEFINITIONS ///.
struct Ivy_Store_t_ Ivy_Store_t
struct Ivy_Obj_t_ Ivy_Obj_t
void Ivy_ObjReplace(Ivy_Man_t *p, Ivy_Obj_t *pObjOld, Ivy_Obj_t *pObjNew, int fDeleteOld, int fFreeTop, int fUpdateLevel)
int Ivy_ManPropagateBuffers(Ivy_Man_t *p, int fUpdateLevel)
void Ivy_ManStartFanout(Ivy_Man_t *p)
FUNCTION DEFINITIONS ///.
Ivy_Obj_t * Ivy_And(Ivy_Man_t *p, Ivy_Obj_t *p0, Ivy_Obj_t *p1)
struct Rwt_Man_t_ Rwt_Man_t
void Rwt_ManPrintStats(Rwt_Man_t *p)
struct Rwt_Node_t_ Rwt_Node_t
int Rwt_ManReadCompl(Rwt_Man_t *p)
void Rwt_ManAddTimeUpdate(Rwt_Man_t *p, abctime Time)
void * Rwt_ManReadDecs(Rwt_Man_t *p)
void Rwt_ManAddTimeTotal(Rwt_Man_t *p, abctime Time)
void Rwt_ManStop(Rwt_Man_t *p)
Rwt_Man_t * Rwt_ManStart(int fPrecompute)
int pArray[IVY_CUT_INPUT]
Ivy_Cut_t pCuts[IVY_CUT_LIMIT]
typedefABC_NAMESPACE_HEADER_START struct Vec_Ptr_t_ Vec_Ptr_t
INCLUDES ///.
#define Vec_PtrForEachEntry(Type, vVec, pEntry, i)
MACRO DEFINITIONS ///.