summaryrefslogtreecommitdiffstats
path: root/src/opt/rwr/rwrEva.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/opt/rwr/rwrEva.c')
-rw-r--r--src/opt/rwr/rwrEva.c254
1 files changed, 98 insertions, 156 deletions
diff --git a/src/opt/rwr/rwrEva.c b/src/opt/rwr/rwrEva.c
index b486785f..735232af 100644
--- a/src/opt/rwr/rwrEva.c
+++ b/src/opt/rwr/rwrEva.c
@@ -25,7 +25,7 @@
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
-static Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Rwr_Cut_t * pCut, int NodeMax, int LevelMax );
+static Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFITIONS ///
@@ -49,37 +49,101 @@ static Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Rwr_Cut_t
SeeAlso []
***********************************************************************/
-int Rwr_NodeRewrite( Rwr_Man_t * p, Abc_Obj_t * pNode )
+int Rwr_NodeRewrite( Rwr_Man_t * p, Cut_Man_t * pManCut, Abc_Obj_t * pNode, int fUseZeros )
{
+ int fVeryVerbose = 0;
Vec_Int_t * vForm;
- Rwr_Cut_t * pCut;
+ Cut_Cut_t * pCut;
+ Abc_Obj_t * pFanin;
+ unsigned uPhase, uTruthBest;
+ char * pPerm;
int Required, nNodesSaved;
- int i, BestGain = -1;
- // compute the cuts for this node
- Rwr_NodeComputeCuts( p, pNode );
+ int i, GainCur, GainBest = -1;
+ int clk;
+
+ p->nNodesConsidered++;
// get the required times
- Required = Vec_IntEntry( p->vReqTimes, pNode->Id );
- // label MFFC with current ID
- nNodesSaved = Abc_NodeMffcLabel( pNode );
+ Required = Abc_NodeReadRequiredLevel( pNode );
+ // get the node's cuts
+clk = clock();
+ pCut = (Cut_Cut_t *)Abc_NodeGetCutsRecursive( pManCut, pNode );
+ assert( pCut != NULL );
+p->timeCut += clock() - clk;
+
// go through the cuts
- for ( pCut = (Rwr_Cut_t *)pNode->pCopy, pCut = pCut->pNext; pCut; pCut = pCut->pNext )
+clk = clock();
+ for ( pCut = pCut->pNext; pCut; pCut = pCut->pNext )
{
+ // consider only 4-input cuts
+ if ( pCut->nLeaves < 4 )
+ continue;
+ // get the fanin permutation
+ pPerm = p->pPerms4[ p->pPerms[pCut->uTruth] ];
+ uPhase = p->pPhases[pCut->uTruth];
+ // collect fanins with the corresponding permutation/phase
+ Vec_PtrClear( p->vFaninsCur );
+ Vec_PtrFill( p->vFaninsCur, (int)pCut->nLeaves, 0 );
+ for ( i = 0; i < (int)pCut->nLeaves; i++ )
+ {
+ pFanin = Abc_NtkObj( pNode->pNtk, pCut->pLeaves[pPerm[i]] );
+ if ( pFanin == NULL )
+ break;
+ pFanin = Abc_ObjNotCond(pFanin, ((uPhase & (1<<i)) > 0) );
+ Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin );
+ }
+ if ( i != (int)pCut->nLeaves )
+ {
+ p->nCutsBad++;
+ continue;
+ }
+ p->nCutsGood++;
+
+ // mark the fanin boundary
+ Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
+ Abc_ObjRegular(pFanin)->vFanouts.nSize++;
+ // label MFFC with current ID
+ Abc_NtkIncrementTravId( pNode->pNtk );
+ nNodesSaved = Abc_NodeMffcLabel( pNode );
+ // unmark the fanin boundary
+ Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
+ Abc_ObjRegular(pFanin)->vFanouts.nSize--;
+
// evaluate the cut
- vForm = Rwr_CutEvaluate( p, pNode, pCut, nNodesSaved, Required );
- // check if the cut is better than the currently best one
- if ( vForm != NULL && BestGain < (int)pCut->Volume )
+ vForm = Rwr_CutEvaluate( p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur );
+
+ // check if the cut is better than the current best one
+ if ( vForm != NULL && GainBest < GainCur )
{
- assert( pCut->Volume >= 0 );
- BestGain = pCut->Volume;
// save this form
- p->vForm = vForm;
- // collect fanins
+ GainBest = GainCur;
+ p->vForm = vForm;
+ p->fCompl = ((uPhase & (1<<4)) > 0);
+ uTruthBest = pCut->uTruth;
+ // collect fanins in the
Vec_PtrClear( p->vFanins );
- for ( i = 0; i < (int)pCut->nLeaves; i++ )
- Vec_PtrPush( p->vFanins, pCut->ppLeaves[i] );
+ Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i )
+ Vec_PtrPush( p->vFanins, pFanin );
}
}
- return BestGain;
+p->timeRes += clock() - clk;
+
+ if ( GainBest == -1 || GainBest == 0 && !fUseZeros )
+ return GainBest;
+
+ p->nScores[p->pMap[uTruthBest]]++;
+ p->nNodesRewritten++;
+ p->nNodesGained += GainBest;
+
+ // report the progress
+ if ( fVeryVerbose )
+ {
+ printf( "Node %6s : ", Abc_ObjName(pNode) );
+ printf( "Fanins = %d. ", p->vFanins->nSize );
+ printf( "Cone = %2d. ", p->vForm->nSize - 4 );
+ printf( "GAIN = %2d. ", GainBest );
+ printf( "\n" );
+ }
+ return GainBest;
}
/**Function*************************************************************
@@ -93,161 +157,39 @@ int Rwr_NodeRewrite( Rwr_Man_t * p, Abc_Obj_t * pNode )
SeeAlso []
***********************************************************************/
-Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Rwr_Cut_t * pCut, int NodeMax, int LevelMax )
+Vec_Int_t * Rwr_CutEvaluate( Rwr_Man_t * p, Abc_Obj_t * pRoot, Cut_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest )
{
- Vec_Ptr_t Vector = {0,0,0}, * vFanins = &Vector;
Vec_Ptr_t * vSubgraphs;
Vec_Int_t * vFormBest;
Rwr_Node_t * pNode;
- int GainCur, GainBest = -1, i;
+ int nNodesAdded, GainBest = -1, i;
+ int clk = clock();
// find the matching class of subgraphs
vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[pCut->uTruth] );
+ p->nSubgraphs += vSubgraphs->nSize;
// determine the best subgraph
Vec_PtrForEachEntry( vSubgraphs, pNode, i )
{
- // create the fanin array
- vFanins->nSize = pCut->nLeaves;
- vFanins->pArray = pCut->ppLeaves;
// detect how many unlabeled nodes will be reused
- GainCur = Abc_NodeStrashDecCount( pRoot->pNtk->pManFunc, pRoot, vFanins, (Vec_Int_t *)pNode->pNext,
- p->vLevNums, NodeMax, LevelMax );
- if ( GainBest < GainCur )
+ nNodesAdded = Abc_NodeStrashDecCount( pRoot->pNtk->pManFunc, pRoot, vFaninsCur,
+ (Vec_Int_t *)pNode->pNext, p->vLevNums, nNodesSaved, LevelMax );
+ if ( nNodesAdded == -1 )
+ continue;
+ assert( nNodesSaved >= nNodesAdded );
+ // count the gain at this node
+ if ( GainBest < nNodesSaved - nNodesAdded )
{
- GainBest = GainCur;
+ GainBest = nNodesSaved - nNodesAdded;
vFormBest = (Vec_Int_t *)pNode->pNext;
}
}
+p->timeEval += clock() - clk;
if ( GainBest == -1 )
return NULL;
- pCut->Volume = GainBest;
+ *pGainBest = GainBest;
return vFormBest;
}
-
-/**Function*************************************************************
-
- Synopsis [Adds one node.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-int Rwr_TravCollect_rec( Rwr_Man_t * p, Rwr_Node_t * pNode, Vec_Int_t * vForm )
-{
- Ft_Node_t Node, NodeA, NodeB;
- int Node0, Node1;
- // elementary variable
- if ( pNode->fUsed )
- return ((pNode->Id - 1) << 1);
- // previously visited node
- if ( pNode->TravId == p->nTravIds )
- return pNode->Volume;
- pNode->TravId = p->nTravIds;
- // solve for children
- Node0 = Rwr_TravCollect_rec( p, Rwr_Regular(pNode->p0), vForm );
- Node1 = Rwr_TravCollect_rec( p, Rwr_Regular(pNode->p1), vForm );
- // create the decomposition node(s)
- if ( pNode->fExor )
- {
- assert( !Rwr_IsComplement(pNode->p0) );
- assert( !Rwr_IsComplement(pNode->p1) );
- NodeA.fIntern = 1;
- NodeA.fConst = 0;
- NodeA.fCompl = 0;
- NodeA.fCompl0 = !(Node0 & 1);
- NodeA.fCompl1 = (Node1 & 1);
- NodeA.iFanin0 = (Node0 >> 1);
- NodeA.iFanin1 = (Node1 >> 1);
- Vec_IntPush( vForm, Ft_Node2Int(NodeA) );
-
- NodeB.fIntern = 1;
- NodeB.fConst = 0;
- NodeB.fCompl = 0;
- NodeB.fCompl0 = (Node0 & 1);
- NodeB.fCompl1 = !(Node1 & 1);
- NodeB.iFanin0 = (Node0 >> 1);
- NodeB.iFanin1 = (Node1 >> 1);
- Vec_IntPush( vForm, Ft_Node2Int(NodeB) );
-
- Node.fIntern = 1;
- Node.fConst = 0;
- Node.fCompl = 0;
- Node.fCompl0 = 1;
- Node.fCompl1 = 1;
- Node.iFanin0 = vForm->nSize - 2;
- Node.iFanin1 = vForm->nSize - 1;
- Vec_IntPush( vForm, Ft_Node2Int(Node) );
- }
- else
- {
- Node.fIntern = 1;
- Node.fConst = 0;
- Node.fCompl = 0;
- Node.fCompl0 = Rwr_IsComplement(pNode->p0) ^ (Node0 & 1);
- Node.fCompl1 = Rwr_IsComplement(pNode->p1) ^ (Node1 & 1);
- Node.iFanin0 = (Node0 >> 1);
- Node.iFanin1 = (Node1 >> 1);
- Vec_IntPush( vForm, Ft_Node2Int(Node) );
- }
- // save the number of this node
- pNode->Volume = ((vForm->nSize - 1) << 1) | pNode->fExor;
- return pNode->Volume;
-}
-
-/**Function*************************************************************
-
- Synopsis [Preprocesses subgraphs rooted at this node.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Rwr_NodePreprocess( Rwr_Man_t * p, Rwr_Node_t * pNode )
-{
- Vec_Int_t * vForm;
- int i, Root;
- vForm = Vec_IntAlloc( 10 );
- for ( i = 0; i < 5; i++ )
- Vec_IntPush( vForm, 0 );
- // collect the nodes
- Rwr_ManIncTravId( p );
- Root = Rwr_TravCollect_rec( p, pNode, vForm );
- if ( Root & 1 )
- Ft_FactorComplement( vForm );
- pNode->pNext = (Rwr_Node_t *)vForm;
-}
-
-/**Function*************************************************************
-
- Synopsis [Preprocesses computed library of subgraphs.]
-
- Description []
-
- SideEffects []
-
- SeeAlso []
-
-***********************************************************************/
-void Rwr_ManPreprocess( Rwr_Man_t * p )
-{
- Rwr_Node_t * pNode;
- int i, k;
- // put the nodes into the structure
- p->vClasses = Vec_VecAlloc( 222 );
- for ( i = 0; i < p->nFuncs; i++ )
- for ( pNode = p->pTable[i]; pNode; pNode = pNode->pNext )
- Vec_VecPush( p->vClasses, p->pMap[pNode->uTruth], pNode );
- // compute decomposition forms for each node
- Vec_VecForEachEntry( p->vClasses, pNode, i, k )
- Rwr_NodePreprocess( p, pNode );
-}
-
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////