ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
ifCut.c File Reference
#include "if.h"
Include dependency graph for ifCut.c:

Go to the source code of this file.

Functions

int If_CutVerifyCuts (If_Set_t *pCutSet, int fOrdered)
 
int If_CutFilter (If_Set_t *pCutSet, If_Cut_t *pCut, int fSaveCut0)
 
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 If_CutMerge (If_Man_t *p, If_Cut_t *pCut0, If_Cut_t *pCut1, If_Cut_t *pCut)
 
int If_CutCompareDelay (If_Man_t *p, If_Cut_t **ppC0, If_Cut_t **ppC1)
 
int If_CutCompareDelayOld (If_Man_t *p, If_Cut_t **ppC0, If_Cut_t **ppC1)
 
int If_CutCompareArea (If_Man_t *p, If_Cut_t **ppC0, If_Cut_t **ppC1)
 
void If_CutSort (If_Man_t *p, If_Set_t *pCutSet, If_Cut_t *pCut)
 
void If_CutOrder (If_Cut_t *pCut)
 
int If_CutCheck (If_Cut_t *pCut)
 
void If_CutPrint (If_Cut_t *pCut)
 
void If_CutPrintTiming (If_Man_t *p, If_Cut_t *pCut)
 
void If_CutLift (If_Cut_t *pCut)
 
float If_CutAreaFlow (If_Man_t *p, If_Cut_t *pCut)
 
float If_CutEdgeFlow (If_Man_t *p, If_Cut_t *pCut)
 
float If_CutPowerFlow (If_Man_t *p, If_Cut_t *pCut, If_Obj_t *pRoot)
 
float If_CutAverageRefs (If_Man_t *p, If_Cut_t *pCut)
 
float If_CutAreaDeref (If_Man_t *p, If_Cut_t *pCut)
 
float If_CutAreaRef (If_Man_t *p, If_Cut_t *pCut)
 
float If_CutAreaDerefed (If_Man_t *p, If_Cut_t *pCut)
 
float If_CutAreaRefed (If_Man_t *p, If_Cut_t *pCut)
 
float If_CutEdgeDeref (If_Man_t *p, If_Cut_t *pCut)
 
float If_CutEdgeRef (If_Man_t *p, If_Cut_t *pCut)
 
float If_CutEdgeDerefed (If_Man_t *p, If_Cut_t *pCut)
 
float If_CutEdgeRefed (If_Man_t *p, If_Cut_t *pCut)
 
float If_CutPowerDeref (If_Man_t *p, If_Cut_t *pCut, If_Obj_t *pRoot)
 
float If_CutPowerRef (If_Man_t *p, If_Cut_t *pCut, If_Obj_t *pRoot)
 
float If_CutPowerDerefed (If_Man_t *p, If_Cut_t *pCut, If_Obj_t *pRoot)
 
float If_CutPowerRefed (If_Man_t *p, If_Cut_t *pCut, If_Obj_t *pRoot)
 
int If_CutGetCutMinLevel (If_Man_t *p, If_Cut_t *pCut)
 
int If_CutGetCone_rec (If_Man_t *p, If_Obj_t *pObj, If_Cut_t *pCut)
 
int If_CutGetCones (If_Man_t *p)
 
void If_CutFoundFanins_rec (If_Obj_t *pObj, Vec_Int_t *vLeaves)
 
int If_CutCountTotalFanins (If_Man_t *p)
 
int If_CutFilter2_rec (If_Man_t *p, If_Obj_t *pObj, int LevelMin)
 
int If_CutFilter2 (If_Man_t *p, If_Obj_t *pNode, If_Cut_t *pCut)
 

Function Documentation

◆ If_CutAreaDeref()

float If_CutAreaDeref ( If_Man_t * p,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Computes area of the first level.]

Description [The cut need to be derefed.]

SideEffects []

SeeAlso []

Definition at line 1056 of file ifCut.c.

1057{
1058 If_Obj_t * pLeaf;
1059 float Area;
1060 int i;
1061 Area = If_CutLutArea(p, pCut);
1062 If_CutForEachLeaf( p, pCut, pLeaf, i )
1063 {
1064 assert( pLeaf->nRefs > 0 );
1065 if ( --pLeaf->nRefs > 0 || !If_ObjIsAnd(pLeaf) )
1066 continue;
1067 Area += If_CutAreaDeref( p, If_ObjCutBest(pLeaf) );
1068 }
1069 return Area;
1070}
Cube * p
Definition exorList.c:222
float If_CutAreaDeref(If_Man_t *p, If_Cut_t *pCut)
Definition ifCut.c:1056
#define If_CutForEachLeaf(p, pCut, pLeaf, i)
Definition if.h:503
struct If_Obj_t_ If_Obj_t
Definition if.h:79
int nRefs
Definition if.h:346
#define assert(ex)
Definition util_old.h:213
Here is the call graph for this function:
Here is the caller graph for this function:

◆ If_CutAreaDerefed()

float If_CutAreaDerefed ( If_Man_t * p,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Computes area of the first level.]

Description [The cut need to be derefed.]

SideEffects []

SeeAlso []

Definition at line 1110 of file ifCut.c.

1111{
1112 float aResult, aResult2;
1113 if ( pCut->nLeaves < 2 )
1114 return 0;
1115 aResult2 = If_CutAreaRef( p, pCut );
1116 aResult = If_CutAreaDeref( p, pCut );
1117 assert( aResult > aResult2 - 3*p->fEpsilon );
1118 assert( aResult < aResult2 + 3*p->fEpsilon );
1119 return aResult;
1120}
float If_CutAreaRef(If_Man_t *p, If_Cut_t *pCut)
Definition ifCut.c:1083
unsigned nLeaves
Definition if.h:316
Here is the call graph for this function:
Here is the caller graph for this function:

◆ If_CutAreaFlow()

float If_CutAreaFlow ( If_Man_t * p,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Computes area flow.]

Description []

SideEffects []

SeeAlso []

Definition at line 927 of file ifCut.c.

928{
929 If_Obj_t * pLeaf;
930 float Flow, AddOn;
931 int i;
932 Flow = If_CutLutArea(p, pCut);
933 If_CutForEachLeaf( p, pCut, pLeaf, i )
934 {
935 if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) )
936 AddOn = If_ObjCutBest(pLeaf)->Area;
937 else
938 {
939 assert( pLeaf->EstRefs > p->fEpsilon );
940 AddOn = If_ObjCutBest(pLeaf)->Area / pLeaf->EstRefs;
941 }
942 if ( Flow >= (float)1e32 || AddOn >= (float)1e32 )
943 Flow = (float)1e32;
944 else
945 {
946 Flow += AddOn;
947 if ( Flow > (float)1e32 )
948 Flow = (float)1e32;
949 }
950 }
951 return Flow;
952}
float EstRefs
Definition if.h:352
Here is the caller graph for this function:

◆ If_CutAreaRef()

float If_CutAreaRef ( If_Man_t * p,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Computes area of the first level.]

Description [The cut need to be derefed.]

SideEffects []

SeeAlso []

Definition at line 1083 of file ifCut.c.

1084{
1085 If_Obj_t * pLeaf;
1086 float Area;
1087 int i;
1088 Area = If_CutLutArea(p, pCut);
1089 If_CutForEachLeaf( p, pCut, pLeaf, i )
1090 {
1091 assert( pLeaf->nRefs >= 0 );
1092 if ( pLeaf->nRefs++ > 0 || !If_ObjIsAnd(pLeaf) )
1093 continue;
1094 Area += If_CutAreaRef( p, If_ObjCutBest(pLeaf) );
1095 }
1096 return Area;
1097}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ If_CutAreaRefed()

float If_CutAreaRefed ( If_Man_t * p,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Computes area of the first level.]

Description [The cut need to be derefed.]

SideEffects []

SeeAlso []

Definition at line 1133 of file ifCut.c.

1134{
1135 float aResult, aResult2;
1136 if ( pCut->nLeaves < 2 )
1137 return 0;
1138 aResult2 = If_CutAreaDeref( p, pCut );
1139 aResult = If_CutAreaRef( p, pCut );
1140// assert( aResult > aResult2 - p->fEpsilon );
1141// assert( aResult < aResult2 + p->fEpsilon );
1142 return aResult;
1143}
Here is the call graph for this function:

◆ If_CutAverageRefs()

float If_CutAverageRefs ( If_Man_t * p,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Average number of references of the leaves.]

Description []

SideEffects []

SeeAlso []

Definition at line 1034 of file ifCut.c.

1035{
1036 If_Obj_t * pLeaf;
1037 int nRefsTotal, i;
1038 nRefsTotal = 0;
1039 If_CutForEachLeaf( p, pCut, pLeaf, i )
1040 nRefsTotal += pLeaf->nRefs;
1041 return ((float)nRefsTotal)/pCut->nLeaves;
1042}

◆ If_CutCheck()

int If_CutCheck ( If_Cut_t * pCut)

Function*************************************************************

Synopsis [Checks correctness of the cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 834 of file ifCut.c.

835{
836 int i;
837 assert( pCut->nLeaves <= pCut->nLimit );
838 if ( pCut->nLeaves < 2 )
839 return 1;
840 for ( i = 1; i < (int)pCut->nLeaves; i++ )
841 {
842 if ( pCut->pLeaves[i-1] >= pCut->pLeaves[i] )
843 {
844 Abc_Print( -1, "If_CutCheck(): Cut has wrong ordering of inputs.\n" );
845 return 0;
846 }
847 assert( pCut->pLeaves[i-1] < pCut->pLeaves[i] );
848 }
849 return 1;
850}
int pLeaves[0]
Definition if.h:318
unsigned nLimit
Definition if.h:315

◆ If_CutCompareArea()

int If_CutCompareArea ( If_Man_t * p,
If_Cut_t ** ppC0,
If_Cut_t ** ppC1 )

Function*************************************************************

Synopsis [Prepares the object for FPGA mapping.]

Description []

SideEffects []

SeeAlso []

Definition at line 468 of file ifCut.c.

469{
470 If_Cut_t * pC0 = *ppC0;
471 If_Cut_t * pC1 = *ppC1;
472 if ( pC0->Area < pC1->Area - p->fEpsilon )
473 return -1;
474 if ( pC0->Area > pC1->Area + p->fEpsilon )
475 return 1;
476// if ( pC0->AveRefs > pC1->AveRefs )
477// return -1;
478// if ( pC0->AveRefs < pC1->AveRefs )
479// return 1;
480 if ( pC0->nLeaves < pC1->nLeaves )
481 return -1;
482 if ( pC0->nLeaves > pC1->nLeaves )
483 return 1;
484 if ( pC0->Delay < pC1->Delay - p->fEpsilon )
485 return -1;
486 if ( pC0->Delay > pC1->Delay + p->fEpsilon )
487 return 1;
488 return 0;
489}
Cube ** ppC1
Definition exorList.c:1013
struct If_Cut_t_ If_Cut_t
Definition if.h:80
float Delay
Definition if.h:306
float Area
Definition if.h:303

◆ If_CutCompareDelay()

int If_CutCompareDelay ( If_Man_t * p,
If_Cut_t ** ppC0,
If_Cut_t ** ppC1 )

Function*************************************************************

Synopsis [Prepares the object for FPGA mapping.]

Description []

SideEffects []

SeeAlso []

Definition at line 408 of file ifCut.c.

409{
410 If_Cut_t * pC0 = *ppC0;
411 If_Cut_t * pC1 = *ppC1;
412 if ( pC0->Delay < pC1->Delay - p->fEpsilon )
413 return -1;
414 if ( pC0->Delay > pC1->Delay + p->fEpsilon )
415 return 1;
416 if ( pC0->nLeaves < pC1->nLeaves )
417 return -1;
418 if ( pC0->nLeaves > pC1->nLeaves )
419 return 1;
420 if ( pC0->Area < pC1->Area - p->fEpsilon )
421 return -1;
422 if ( pC0->Area > pC1->Area + p->fEpsilon )
423 return 1;
424 return 0;
425}

◆ If_CutCompareDelayOld()

int If_CutCompareDelayOld ( If_Man_t * p,
If_Cut_t ** ppC0,
If_Cut_t ** ppC1 )

Function*************************************************************

Synopsis [Prepares the object for FPGA mapping.]

Description []

SideEffects []

SeeAlso []

Definition at line 438 of file ifCut.c.

439{
440 If_Cut_t * pC0 = *ppC0;
441 If_Cut_t * pC1 = *ppC1;
442 if ( pC0->Delay < pC1->Delay - p->fEpsilon )
443 return -1;
444 if ( pC0->Delay > pC1->Delay + p->fEpsilon )
445 return 1;
446 if ( pC0->Area < pC1->Area - p->fEpsilon )
447 return -1;
448 if ( pC0->Area > pC1->Area + p->fEpsilon )
449 return 1;
450 if ( pC0->nLeaves < pC1->nLeaves )
451 return -1;
452 if ( pC0->nLeaves > pC1->nLeaves )
453 return 1;
454 return 0;
455}

◆ If_CutCountTotalFanins()

int If_CutCountTotalFanins ( If_Man_t * p)

Function*************************************************************

Synopsis [Computes the cone of the cut in AIG with choices.]

Description []

SideEffects []

SeeAlso []

Definition at line 1469 of file ifCut.c.

1470{
1471 If_Obj_t * pObj;
1472 Vec_Int_t * vLeaves;
1473 int i, nFaninsTotal = 0, Counter = 0;
1474 abctime clk = Abc_Clock();
1475 vLeaves = Vec_IntAlloc( 100 );
1476 If_ManForEachObj( p, pObj, i )
1477 {
1478 if ( If_ObjIsAnd(pObj) && pObj->nRefs )
1479 {
1480 nFaninsTotal += If_ObjCutBest(pObj)->nLeaves;
1481 Vec_IntClear( vLeaves );
1482 If_CutFoundFanins_rec( If_ObjFanin0(pObj), vLeaves );
1483 If_CutFoundFanins_rec( If_ObjFanin1(pObj), vLeaves );
1484 Counter += Vec_IntSize(vLeaves);
1485 }
1486 }
1487 Abc_Print( 1, "Total cut inputs = %d. Total fanins incremental = %d.\n", nFaninsTotal, Counter );
1488 Abc_PrintTime( 1, "Fanins", Abc_Clock() - clk );
1489 Vec_IntFree( vLeaves );
1490 return 1;
1491}
ABC_INT64_T abctime
Definition abc_global.h:332
typedefABC_NAMESPACE_IMPL_START struct Vec_Int_t_ Vec_Int_t
DECLARATIONS ///.
Definition bblif.c:37
void If_CutFoundFanins_rec(If_Obj_t *pObj, Vec_Int_t *vLeaves)
Definition ifCut.c:1447
#define If_ManForEachObj(p, pObj, i)
Definition if.h:491
Here is the call graph for this function:

◆ If_CutEdgeDeref()

float If_CutEdgeDeref ( If_Man_t * p,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Computes area of the first level.]

Description [The cut need to be derefed.]

SideEffects []

SeeAlso []

Definition at line 1157 of file ifCut.c.

1158{
1159 If_Obj_t * pLeaf;
1160 float Edge;
1161 int i;
1162 Edge = pCut->nLeaves;
1163 If_CutForEachLeaf( p, pCut, pLeaf, i )
1164 {
1165 assert( pLeaf->nRefs > 0 );
1166 if ( --pLeaf->nRefs > 0 || !If_ObjIsAnd(pLeaf) )
1167 continue;
1168 Edge += If_CutEdgeDeref( p, If_ObjCutBest(pLeaf) );
1169 }
1170 return Edge;
1171}
float If_CutEdgeDeref(If_Man_t *p, If_Cut_t *pCut)
Definition ifCut.c:1157
Here is the call graph for this function:
Here is the caller graph for this function:

◆ If_CutEdgeDerefed()

float If_CutEdgeDerefed ( If_Man_t * p,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Computes edge of the first level.]

Description [The cut need to be derefed.]

SideEffects []

SeeAlso []

Definition at line 1211 of file ifCut.c.

1212{
1213 float aResult, aResult2;
1214 if ( pCut->nLeaves < 2 )
1215 return pCut->nLeaves;
1216 aResult2 = If_CutEdgeRef( p, pCut );
1217 aResult = If_CutEdgeDeref( p, pCut );
1218// assert( aResult > aResult2 - 3*p->fEpsilon );
1219// assert( aResult < aResult2 + 3*p->fEpsilon );
1220 return aResult;
1221}
float If_CutEdgeRef(If_Man_t *p, If_Cut_t *pCut)
Definition ifCut.c:1184
Here is the call graph for this function:
Here is the caller graph for this function:

◆ If_CutEdgeFlow()

float If_CutEdgeFlow ( If_Man_t * p,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Computes area flow.]

Description []

SideEffects []

SeeAlso []

Definition at line 965 of file ifCut.c.

966{
967 If_Obj_t * pLeaf;
968 float Flow, AddOn;
969 int i;
970 Flow = pCut->nLeaves;
971 If_CutForEachLeaf( p, pCut, pLeaf, i )
972 {
973 if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) )
974 AddOn = If_ObjCutBest(pLeaf)->Edge;
975 else
976 {
977 assert( pLeaf->EstRefs > p->fEpsilon );
978 AddOn = If_ObjCutBest(pLeaf)->Edge / pLeaf->EstRefs;
979 }
980 if ( Flow >= (float)1e32 || AddOn >= (float)1e32 )
981 Flow = (float)1e32;
982 else
983 {
984 Flow += AddOn;
985 if ( Flow > (float)1e32 )
986 Flow = (float)1e32;
987 }
988 }
989 return Flow;
990}
Here is the caller graph for this function:

◆ If_CutEdgeRef()

float If_CutEdgeRef ( If_Man_t * p,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Computes area of the first level.]

Description [The cut need to be derefed.]

SideEffects []

SeeAlso []

Definition at line 1184 of file ifCut.c.

1185{
1186 If_Obj_t * pLeaf;
1187 float Edge;
1188 int i;
1189 Edge = pCut->nLeaves;
1190 If_CutForEachLeaf( p, pCut, pLeaf, i )
1191 {
1192 assert( pLeaf->nRefs >= 0 );
1193 if ( pLeaf->nRefs++ > 0 || !If_ObjIsAnd(pLeaf) )
1194 continue;
1195 Edge += If_CutEdgeRef( p, If_ObjCutBest(pLeaf) );
1196 }
1197 return Edge;
1198}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ If_CutEdgeRefed()

float If_CutEdgeRefed ( If_Man_t * p,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Computes area of the first level.]

Description [The cut need to be derefed.]

SideEffects []

SeeAlso []

Definition at line 1234 of file ifCut.c.

1235{
1236 float aResult, aResult2;
1237 if ( pCut->nLeaves < 2 )
1238 return pCut->nLeaves;
1239 aResult2 = If_CutEdgeDeref( p, pCut );
1240 aResult = If_CutEdgeRef( p, pCut );
1241// assert( aResult > aResult2 - p->fEpsilon );
1242// assert( aResult < aResult2 + p->fEpsilon );
1243 return aResult;
1244}
Here is the call graph for this function:

◆ If_CutFilter()

int If_CutFilter ( If_Set_t * pCutSet,
If_Cut_t * pCut,
int fSaveCut0 )

Function*************************************************************

Synopsis [Returns 1 if the cut is contained.]

Description []

SideEffects []

SeeAlso []

Definition at line 146 of file ifCut.c.

147{
148 If_Cut_t * pTemp;
149 int i, k;
150 assert( pCutSet->ppCuts[pCutSet->nCuts] == pCut );
151 for ( i = 0; i < pCutSet->nCuts; i++ )
152 {
153 pTemp = pCutSet->ppCuts[i];
154 if ( pTemp->nLeaves > pCut->nLeaves )
155 {
156 // do not fiter the first cut
157 if ( i == 0 && ((pCutSet->nCuts > 1 && pCutSet->ppCuts[1]->fUseless) || (fSaveCut0 && pCutSet->nCuts == 1)) )
158 continue;
159 // skip the non-contained cuts
160 if ( (pTemp->uSign & pCut->uSign) != pCut->uSign )
161 continue;
162 // check containment seriously
163 if ( If_CutCheckDominance( pCut, pTemp ) )
164 {
165// p->ppCuts[i] = p->ppCuts[p->nCuts-1];
166// p->ppCuts[p->nCuts-1] = pTemp;
167// p->nCuts--;
168// i--;
169 // remove contained cut
170 for ( k = i; k < pCutSet->nCuts; k++ )
171 pCutSet->ppCuts[k] = pCutSet->ppCuts[k+1];
172 pCutSet->ppCuts[pCutSet->nCuts] = pTemp;
173 pCutSet->nCuts--;
174 i--;
175 }
176 }
177 else
178 {
179 // skip the non-contained cuts
180 if ( (pTemp->uSign & pCut->uSign) != pTemp->uSign )
181 continue;
182 // check containment seriously
183 if ( If_CutCheckDominance( pTemp, pCut ) )
184 return 1;
185 }
186 }
187 return 0;
188}
unsigned fUseless
Definition if.h:313
unsigned uSign
Definition if.h:309
If_Cut_t ** ppCuts
Definition if.h:327
short nCuts
Definition if.h:325
Here is the caller graph for this function:

◆ If_CutFilter2()

int If_CutFilter2 ( If_Man_t * p,
If_Obj_t * pNode,
If_Cut_t * pCut )

Definition at line 1518 of file ifCut.c.

1519{
1520 If_Obj_t * pLeaf, * pTemp; int i, Count = 0;
1521// printf( "Considering node %d and cut {", pNode->Id );
1522// If_CutForEachLeaf( p, pCut, pLeaf, i )
1523// printf( " %d", pLeaf->Id );
1524// printf( " }\n" );
1525 If_CutForEachLeaf( p, pCut, pLeaf, i )
1526 {
1527 int k, iObj, RetValue, nLevelMin = ABC_INFINITY;
1528 Vec_IntClear( p->vVisited2 );
1529 If_CutForEachLeaf( p, pCut, pTemp, k )
1530 {
1531 if ( pTemp == pLeaf )
1532 continue;
1533 nLevelMin = Abc_MinInt( nLevelMin, (int)pTemp->Level );
1534 assert( Vec_StrEntry(p->vMarks, pTemp->Id) == 0 );
1535 Vec_StrWriteEntry( p->vMarks, pTemp->Id, 2 );
1536 Vec_IntPush( p->vVisited2, pTemp->Id );
1537 }
1538 RetValue = If_CutFilter2_rec( p, pLeaf, nLevelMin );
1539 Vec_IntForEachEntry( p->vVisited2, iObj, k )
1540 Vec_StrWriteEntry( p->vMarks, iObj, 0 );
1541 if ( RetValue == 2 )
1542 {
1543 Count++;
1544 pCut->nLeaves--;
1545 for ( k = i; k < (int)pCut->nLeaves; k++ )
1546 pCut->pLeaves[k] = pCut->pLeaves[k+1];
1547 i--;
1548 }
1549 }
1550 //if ( Count )
1551 // printf( "%d", Count );
1552 return 0;
1553}
#define ABC_INFINITY
MACRO DEFINITIONS ///.
Definition abc_global.h:250
int If_CutFilter2_rec(If_Man_t *p, If_Obj_t *pObj, int LevelMin)
Definition ifCut.c:1504
unsigned Level
Definition if.h:343
int Id
Definition if.h:344
#define Vec_IntForEachEntry(vVec, Entry, i)
MACRO DEFINITIONS ///.
Definition vecInt.h:54
Here is the call graph for this function:

◆ If_CutFilter2_rec()

int If_CutFilter2_rec ( If_Man_t * p,
If_Obj_t * pObj,
int LevelMin )

Function*************************************************************

Synopsis []

Description []

SideEffects []

SeeAlso []

Definition at line 1504 of file ifCut.c.

1505{
1506 char * pVisited = Vec_StrEntryP(p->vMarks, pObj->Id);
1507 if ( *pVisited )
1508 return *pVisited;
1509 Vec_IntPush( p->vVisited2, pObj->Id );
1510 if ( (int)pObj->Level <= LevelMin )
1511 return (*pVisited = 1);
1512 if ( If_CutFilter2_rec( p, pObj->pFanin0, LevelMin ) == 1 )
1513 return (*pVisited = 1);
1514 if ( If_CutFilter2_rec( p, pObj->pFanin1, LevelMin ) == 1 )
1515 return (*pVisited = 1);
1516 return (*pVisited = 2);
1517}
If_Obj_t * pFanin1
Definition if.h:350
If_Obj_t * pFanin0
Definition if.h:349
Here is the call graph for this function:
Here is the caller graph for this function:

◆ If_CutFoundFanins_rec()

void If_CutFoundFanins_rec ( If_Obj_t * pObj,
Vec_Int_t * vLeaves )

Function*************************************************************

Synopsis [Computes the cone of the cut in AIG with choices.]

Description []

SideEffects []

SeeAlso []

Definition at line 1447 of file ifCut.c.

1448{
1449 if ( pObj->nRefs || If_ObjIsCi(pObj) )
1450 {
1451 Vec_IntPushUnique( vLeaves, pObj->Id );
1452 return;
1453 }
1454 If_CutFoundFanins_rec( If_ObjFanin0(pObj), vLeaves );
1455 If_CutFoundFanins_rec( If_ObjFanin1(pObj), vLeaves );
1456}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ If_CutGetCone_rec()

int If_CutGetCone_rec ( If_Man_t * p,
If_Obj_t * pObj,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Computes the cone of the cut in AIG with choices.]

Description []

SideEffects []

SeeAlso []

Definition at line 1380 of file ifCut.c.

1381{
1382 If_Obj_t * pTemp;
1383 int i, RetValue;
1384 // check if the node is in the cut
1385 for ( i = 0; i < (int)pCut->nLeaves; i++ )
1386 if ( pCut->pLeaves[i] == pObj->Id )
1387 return 1;
1388 else if ( pCut->pLeaves[i] > pObj->Id )
1389 break;
1390 // return if we reached the boundary
1391 if ( If_ObjIsCi(pObj) )
1392 return 0;
1393 // check the choice node
1394 for ( pTemp = pObj; pTemp; pTemp = pTemp->pEquiv )
1395 {
1396 // check if the node itself is bound
1397 RetValue = If_CutGetCone_rec( p, If_ObjFanin0(pTemp), pCut );
1398 if ( RetValue )
1399 RetValue &= If_CutGetCone_rec( p, If_ObjFanin1(pTemp), pCut );
1400 if ( RetValue )
1401 return 1;
1402 }
1403 return 0;
1404}
int If_CutGetCone_rec(If_Man_t *p, If_Obj_t *pObj, If_Cut_t *pCut)
Definition ifCut.c:1380
If_Obj_t * pEquiv
Definition if.h:351
Here is the call graph for this function:
Here is the caller graph for this function:

◆ If_CutGetCones()

int If_CutGetCones ( If_Man_t * p)

Function*************************************************************

Synopsis [Computes the cone of the cut in AIG with choices.]

Description []

SideEffects []

SeeAlso []

Definition at line 1417 of file ifCut.c.

1418{
1419 If_Obj_t * pObj;
1420 int i, Counter = 0;
1421 abctime clk = Abc_Clock();
1422 If_ManForEachObj( p, pObj, i )
1423 {
1424 if ( If_ObjIsAnd(pObj) && pObj->nRefs )
1425 {
1426 Counter += !If_CutGetCone_rec( p, pObj, If_ObjCutBest(pObj) );
1427// Abc_Print( 1, "%d ", If_CutGetCutMinLevel( p, If_ObjCutBest(pObj) ) );
1428 }
1429 }
1430 Abc_Print( 1, "Cound not find boundary for %d nodes.\n", Counter );
1431 Abc_PrintTime( 1, "Cones", Abc_Clock() - clk );
1432 return 1;
1433}
Here is the call graph for this function:

◆ If_CutGetCutMinLevel()

int If_CutGetCutMinLevel ( If_Man_t * p,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Computes the cone of the cut in AIG with choices.]

Description []

SideEffects []

SeeAlso []

Definition at line 1360 of file ifCut.c.

1361{
1362 If_Obj_t * pLeaf;
1363 int i, nMinLevel = IF_INFINITY;
1364 If_CutForEachLeaf( p, pCut, pLeaf, i )
1365 nMinLevel = IF_MIN( nMinLevel, (int)pLeaf->Level );
1366 return nMinLevel;
1367}
#define IF_MIN(a, b)
MACRO DEFINITIONS ///.
Definition if.h:465
#define IF_INFINITY
Definition if.h:57

◆ If_CutLift()

void If_CutLift ( If_Cut_t * pCut)

Function*************************************************************

Synopsis [Moves the cut over the latch.]

Description []

SideEffects []

SeeAlso []

Definition at line 905 of file ifCut.c.

906{
907 unsigned i;
908 for ( i = 0; i < pCut->nLeaves; i++ )
909 {
910 assert( (pCut->pLeaves[i] & 255) < 255 );
911 pCut->pLeaves[i]++;
912 }
913}

◆ If_CutMerge()

int If_CutMerge ( If_Man_t * p,
If_Cut_t * pCut0,
If_Cut_t * pCut1,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Prepares the object for FPGA mapping.]

Description []

SideEffects []

SeeAlso []

Definition at line 364 of file ifCut.c.

365{
366 int nLutSize = pCut0->nLimit;
367 int nSize0 = pCut0->nLeaves;
368 int nSize1 = pCut1->nLeaves;
369 int * pC0 = pCut0->pLeaves;
370 int * pC1 = pCut1->pLeaves;
371 int * pC = pCut->pLeaves;
372 int i, k, c;
373 // compare two cuts with different numbers
374 c = nSize0;
375 for ( i = 0; i < nSize1; i++ )
376 {
377 for ( k = 0; k < nSize0; k++ )
378 if ( pC1[i] == pC0[k] )
379 break;
380 if ( k < nSize0 )
381 {
382 p->pPerm[1][i] = k;
383 continue;
384 }
385 if ( c == nLutSize )
386 return 0;
387 p->pPerm[1][i] = c;
388 pC[c++] = pC1[i];
389 }
390 for ( i = 0; i < nSize0; i++ )
391 pC[i] = pC0[i];
392 pCut->nLeaves = c;
393 pCut->uSign = pCut0->uSign | pCut1->uSign;
394 return 1;
395}
Here is the caller graph for this function:

◆ If_CutMergeOrdered()

int If_CutMergeOrdered ( If_Man_t * p,
If_Cut_t * pC0,
If_Cut_t * pC1,
If_Cut_t * pC )

Function*************************************************************

Synopsis [Prepares the object for FPGA mapping.]

Description []

SideEffects []

SeeAlso []

Definition at line 290 of file ifCut.c.

291{
292 int nSizeC0 = pC0->nLeaves;
293 int nSizeC1 = pC1->nLeaves;
294 int nLimit = pC0->nLimit;
295 int i, k, c, s;
296
297 // both cuts are the largest
298 if ( nSizeC0 == nLimit && nSizeC1 == nLimit )
299 {
300 for ( i = 0; i < nSizeC0; i++ )
301 {
302 if ( pC0->pLeaves[i] != pC1->pLeaves[i] )
303 return 0;
304 pC->pLeaves[i] = pC0->pLeaves[i];
305 }
306 pC->nLeaves = nLimit;
307 pC->uSign = pC0->uSign | pC1->uSign;
308 return 1;
309 }
310
311 // compare two cuts with different numbers
312 i = k = c = s = 0;
313 if ( nSizeC0 == 0 ) goto FlushCut1;
314 if ( nSizeC1 == 0 ) goto FlushCut0;
315 while ( 1 )
316 {
317 if ( c == nLimit ) return 0;
318 if ( pC0->pLeaves[i] < pC1->pLeaves[k] )
319 {
320 pC->pLeaves[c++] = pC0->pLeaves[i++];
321 if ( i == nSizeC0 ) goto FlushCut1;
322 }
323 else if ( pC0->pLeaves[i] > pC1->pLeaves[k] )
324 {
325 pC->pLeaves[c++] = pC1->pLeaves[k++];
326 if ( k == nSizeC1 ) goto FlushCut0;
327 }
328 else
329 {
330 pC->pLeaves[c++] = pC0->pLeaves[i++]; k++;
331 if ( i == nSizeC0 ) goto FlushCut1;
332 if ( k == nSizeC1 ) goto FlushCut0;
333 }
334 }
335
336FlushCut0:
337 if ( c + nSizeC0 > nLimit + i ) return 0;
338 while ( i < nSizeC0 )
339 pC->pLeaves[c++] = pC0->pLeaves[i++];
340 pC->nLeaves = c;
341 pC->uSign = pC0->uSign | pC1->uSign;
342 return 1;
343
344FlushCut1:
345 if ( c + nSizeC1 > nLimit + k ) return 0;
346 while ( k < nSizeC1 )
347 pC->pLeaves[c++] = pC1->pLeaves[k++];
348 pC->nLeaves = c;
349 pC->uSign = pC0->uSign | pC1->uSign;
350 return 1;
351}
Here is the caller graph for this function:

◆ If_CutMergeOrdered_()

int If_CutMergeOrdered_ ( If_Man_t * p,
If_Cut_t * pC0,
If_Cut_t * pC1,
If_Cut_t * pC )

Function*************************************************************

Synopsis [Prepares the object for FPGA mapping.]

Description []

SideEffects []

SeeAlso []

Definition at line 201 of file ifCut.c.

202{
203 int nSizeC0 = pC0->nLeaves;
204 int nSizeC1 = pC1->nLeaves;
205 int nLimit = pC0->nLimit;
206 int i, k, c, s;
207
208 // both cuts are the largest
209 if ( nSizeC0 == nLimit && nSizeC1 == nLimit )
210 {
211 for ( i = 0; i < nSizeC0; i++ )
212 {
213 if ( pC0->pLeaves[i] != pC1->pLeaves[i] )
214 return 0;
215 p->pPerm[0][i] = p->pPerm[1][i] = p->pPerm[2][i] = i;
216 pC->pLeaves[i] = pC0->pLeaves[i];
217 }
218 pC->nLeaves = nLimit;
219 pC->uSign = pC0->uSign | pC1->uSign;
220 p->uSharedMask = Abc_InfoMask( nLimit );
221 return 1;
222 }
223
224 // compare two cuts with different numbers
225 i = k = c = s = 0;
226 p->uSharedMask = 0;
227 if ( nSizeC0 == 0 ) goto FlushCut1;
228 if ( nSizeC1 == 0 ) goto FlushCut0;
229 while ( 1 )
230 {
231 if ( c == nLimit ) return 0;
232 if ( pC0->pLeaves[i] < pC1->pLeaves[k] )
233 {
234 p->pPerm[0][i] = c;
235 pC->pLeaves[c++] = pC0->pLeaves[i++];
236 if ( i == nSizeC0 ) goto FlushCut1;
237 }
238 else if ( pC0->pLeaves[i] > pC1->pLeaves[k] )
239 {
240 p->pPerm[1][k] = c;
241 pC->pLeaves[c++] = pC1->pLeaves[k++];
242 if ( k == nSizeC1 ) goto FlushCut0;
243 }
244 else
245 {
246 p->uSharedMask |= (1 << c);
247 p->pPerm[0][i] = p->pPerm[1][k] = p->pPerm[2][s++] = c;
248 pC->pLeaves[c++] = pC0->pLeaves[i++]; k++;
249 if ( i == nSizeC0 ) goto FlushCut1;
250 if ( k == nSizeC1 ) goto FlushCut0;
251 }
252 }
253
254FlushCut0:
255 if ( c + nSizeC0 > nLimit + i ) return 0;
256 while ( i < nSizeC0 )
257 {
258 p->pPerm[0][i] = c;
259 pC->pLeaves[c++] = pC0->pLeaves[i++];
260 }
261 pC->nLeaves = c;
262 pC->uSign = pC0->uSign | pC1->uSign;
263 assert( c > 0 );
264 return 1;
265
266FlushCut1:
267 if ( c + nSizeC1 > nLimit + k ) return 0;
268 while ( k < nSizeC1 )
269 {
270 p->pPerm[1][k] = c;
271 pC->pLeaves[c++] = pC1->pLeaves[k++];
272 }
273 pC->nLeaves = c;
274 pC->uSign = pC0->uSign | pC1->uSign;
275 assert( c > 0 );
276 return 1;
277}

◆ If_CutOrder()

void If_CutOrder ( If_Cut_t * pCut)

Function*************************************************************

Synopsis [Orders the leaves of the cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 805 of file ifCut.c.

806{
807 int i, Temp, fChanges;
808 do {
809 fChanges = 0;
810 for ( i = 0; i < (int)pCut->nLeaves - 1; i++ )
811 {
812 assert( pCut->pLeaves[i] != pCut->pLeaves[i+1] );
813 if ( pCut->pLeaves[i] <= pCut->pLeaves[i+1] )
814 continue;
815 Temp = pCut->pLeaves[i];
816 pCut->pLeaves[i] = pCut->pLeaves[i+1];
817 pCut->pLeaves[i+1] = Temp;
818 fChanges = 1;
819 }
820 } while ( fChanges );
821}

◆ If_CutPowerDeref()

float If_CutPowerDeref ( If_Man_t * p,
If_Cut_t * pCut,
If_Obj_t * pRoot )

Function*************************************************************

Synopsis [Computes area of the first level.]

Description [The cut need to be derefed.]

SideEffects []

SeeAlso []

Definition at line 1258 of file ifCut.c.

1259{
1260 If_Obj_t * pLeaf;
1261 float * pSwitching = (float *)p->vSwitching->pArray;
1262 float Power = 0;
1263 int i;
1264 If_CutForEachLeaf( p, pCut, pLeaf, i )
1265 {
1266 Power += pSwitching[pLeaf->Id];
1267 assert( pLeaf->nRefs > 0 );
1268 if ( --pLeaf->nRefs > 0 || !If_ObjIsAnd(pLeaf) )
1269 continue;
1270 Power += If_CutPowerDeref( p, If_ObjCutBest(pLeaf), pRoot );
1271 }
1272 return Power;
1273}
float If_CutPowerDeref(If_Man_t *p, If_Cut_t *pCut, If_Obj_t *pRoot)
Definition ifCut.c:1258
Here is the call graph for this function:
Here is the caller graph for this function:

◆ If_CutPowerDerefed()

float If_CutPowerDerefed ( If_Man_t * p,
If_Cut_t * pCut,
If_Obj_t * pRoot )

Function*************************************************************

Synopsis [Computes Power of the first level.]

Description [The cut need to be derefed.]

SideEffects []

SeeAlso []

Definition at line 1314 of file ifCut.c.

1315{
1316 float aResult, aResult2;
1317 if ( pCut->nLeaves < 2 )
1318 return 0;
1319 aResult2 = If_CutPowerRef( p, pCut, pRoot );
1320 aResult = If_CutPowerDeref( p, pCut, pRoot );
1321 assert( aResult > aResult2 - p->fEpsilon );
1322 assert( aResult < aResult2 + p->fEpsilon );
1323 return aResult;
1324}
float If_CutPowerRef(If_Man_t *p, If_Cut_t *pCut, If_Obj_t *pRoot)
Definition ifCut.c:1286
Here is the call graph for this function:
Here is the caller graph for this function:

◆ If_CutPowerFlow()

float If_CutPowerFlow ( If_Man_t * p,
If_Cut_t * pCut,
If_Obj_t * pRoot )

Function*************************************************************

Synopsis [Computes area flow.]

Description []

SideEffects []

SeeAlso []

Definition at line 1003 of file ifCut.c.

1004{
1005 If_Obj_t * pLeaf;
1006 float * pSwitching = (float *)p->vSwitching->pArray;
1007 float Power = 0;
1008 int i;
1009 If_CutForEachLeaf( p, pCut, pLeaf, i )
1010 {
1011 Power += pSwitching[pLeaf->Id];
1012 if ( pLeaf->nRefs == 0 || If_ObjIsConst1(pLeaf) )
1013 Power += If_ObjCutBest(pLeaf)->Power;
1014 else
1015 {
1016 assert( pLeaf->EstRefs > p->fEpsilon );
1017 Power += If_ObjCutBest(pLeaf)->Power / pLeaf->EstRefs;
1018 }
1019 }
1020 return Power;
1021}
Here is the caller graph for this function:

◆ If_CutPowerRef()

float If_CutPowerRef ( If_Man_t * p,
If_Cut_t * pCut,
If_Obj_t * pRoot )

Function*************************************************************

Synopsis [Computes area of the first level.]

Description [The cut need to be derefed.]

SideEffects []

SeeAlso []

Definition at line 1286 of file ifCut.c.

1287{
1288 If_Obj_t * pLeaf;
1289 float * pSwitching = (float *)p->vSwitching->pArray;
1290 float Power = 0;
1291 int i;
1292 If_CutForEachLeaf( p, pCut, pLeaf, i )
1293 {
1294 Power += pSwitching[pLeaf->Id];
1295 assert( pLeaf->nRefs >= 0 );
1296 if ( pLeaf->nRefs++ > 0 || !If_ObjIsAnd(pLeaf) )
1297 continue;
1298 Power += If_CutPowerRef( p, If_ObjCutBest(pLeaf), pRoot );
1299 }
1300 return Power;
1301}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ If_CutPowerRefed()

float If_CutPowerRefed ( If_Man_t * p,
If_Cut_t * pCut,
If_Obj_t * pRoot )

Function*************************************************************

Synopsis [Computes area of the first level.]

Description [The cut need to be derefed.]

SideEffects []

SeeAlso []

Definition at line 1337 of file ifCut.c.

1338{
1339 float aResult, aResult2;
1340 if ( pCut->nLeaves < 2 )
1341 return 0;
1342 aResult2 = If_CutPowerDeref( p, pCut, pRoot );
1343 aResult = If_CutPowerRef( p, pCut, pRoot );
1344 assert( aResult > aResult2 - p->fEpsilon );
1345 assert( aResult < aResult2 + p->fEpsilon );
1346 return aResult;
1347}
Here is the call graph for this function:

◆ If_CutPrint()

void If_CutPrint ( If_Cut_t * pCut)

Function*************************************************************

Synopsis [Prints one cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 864 of file ifCut.c.

865{
866 unsigned i;
867 Abc_Print( 1, "{" );
868 for ( i = 0; i < pCut->nLeaves; i++ )
869 Abc_Print( 1, " %s%d", If_CutLeafBit(pCut, i) ? "!":"", pCut->pLeaves[i] );
870 Abc_Print( 1, " }\n" );
871}
Here is the caller graph for this function:

◆ If_CutPrintTiming()

void If_CutPrintTiming ( If_Man_t * p,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Prints one cut.]

Description []

SideEffects []

SeeAlso []

Definition at line 884 of file ifCut.c.

885{
886 If_Obj_t * pLeaf;
887 unsigned i;
888 Abc_Print( 1, "{" );
889 If_CutForEachLeaf( p, pCut, pLeaf, i )
890 Abc_Print( 1, " %d(%.2f/%.2f)", pLeaf->Id, If_ObjCutBest(pLeaf)->Delay, pLeaf->Required );
891 Abc_Print( 1, " }\n" );
892}
float Required
Definition if.h:353

◆ If_CutSort()

void If_CutSort ( If_Man_t * p,
If_Set_t * pCutSet,
If_Cut_t * pCut )

Function*************************************************************

Synopsis [Performs incremental sorting of cuts.]

Description [Currently only the trivial sorting is implemented.]

SideEffects []

SeeAlso []

Definition at line 746 of file ifCut.c.

747{
748// int Counter = 0;
749 int i;
750
751 // the new cut is the last one
752 assert( pCutSet->ppCuts[pCutSet->nCuts] == pCut );
753 assert( pCutSet->nCuts <= pCutSet->nCutsMax );
754
755 // cut structure is empty
756 if ( pCutSet->nCuts == 0 )
757 {
758 pCutSet->nCuts++;
759 return;
760 }
761
762 if ( !pCut->fUseless &&
763 (p->pPars->fUseDsd || p->pPars->pFuncCell2 || p->pPars->fUseBat ||
764 p->pPars->pLutStruct || p->pPars->fUserRecLib || p->pPars->fUserSesLib || p->pPars->fUserLutDec || p->pPars->fUserLut2D ||
765 p->pPars->fEnableCheck07 || p->pPars->fUseCofVars || p->pPars->fUseAndVars || p->pPars->fUse34Spec ||
766 p->pPars->fUseDsdTune || p->pPars->fEnableCheck75 || p->pPars->fEnableCheck75u || p->pPars->fUseCheck1 || p->pPars->fUseCheck2) )
767 {
768 If_Cut_t * pFirst = pCutSet->ppCuts[0];
769 if ( pFirst->fUseless || If_ManSortCompare(p, pFirst, pCut) == 1 )
770 {
771 pCutSet->ppCuts[0] = pCut;
772 pCutSet->ppCuts[pCutSet->nCuts] = pFirst;
773 If_CutSort( p, pCutSet, pFirst );
774 return;
775 }
776 }
777
778 // the cut will be added - find its place
779 for ( i = pCutSet->nCuts-1; i >= 0; i-- )
780 {
781// Counter++;
782 if ( If_ManSortCompare( p, pCutSet->ppCuts[i], pCut ) <= 0 || (i == 0 && !pCutSet->ppCuts[0]->fUseless && pCut->fUseless) )
783 break;
784 pCutSet->ppCuts[i+1] = pCutSet->ppCuts[i];
785 pCutSet->ppCuts[i] = pCut;
786 }
787// Abc_Print( 1, "%d ", Counter );
788
789 // update the number of cuts
790 if ( pCutSet->nCuts < pCutSet->nCutsMax )
791 pCutSet->nCuts++;
792}
void If_CutSort(If_Man_t *p, If_Set_t *pCutSet, If_Cut_t *pCut)
Definition ifCut.c:746
short nCutsMax
Definition if.h:324
Here is the call graph for this function:
Here is the caller graph for this function:

◆ If_CutVerifyCuts()

int If_CutVerifyCuts ( If_Set_t * pCutSet,
int fOrdered )

Definition at line 62 of file ifCut.c.

63{
64 static int Count = 0;
65 If_Cut_t * pCut0, * pCut1;
66 int i, k, m, n, Value;
67 assert( pCutSet->nCuts > 0 );
68 for ( i = 0; i < pCutSet->nCuts; i++ )
69 {
70 pCut0 = pCutSet->ppCuts[i];
71 assert( pCut0->uSign == If_ObjCutSignCompute(pCut0) );
72 if ( fOrdered )
73 {
74 // check duplicates
75 for ( m = 1; m < (int)pCut0->nLeaves; m++ )
76 assert( pCut0->pLeaves[m-1] < pCut0->pLeaves[m] );
77 }
78 else
79 {
80 // check duplicates
81 for ( m = 0; m < (int)pCut0->nLeaves; m++ )
82 for ( n = m+1; n < (int)pCut0->nLeaves; n++ )
83 assert( pCut0->pLeaves[m] != pCut0->pLeaves[n] );
84 }
85 // check pairs
86 for ( k = 0; k < pCutSet->nCuts; k++ )
87 {
88 pCut1 = pCutSet->ppCuts[k];
89 if ( pCut0 == pCut1 )
90 continue;
91 Count++;
92 // check containments
93 Value = If_CutVerifyCut( pCut0, pCut1 );
94// assert( Value == 0 );
95 if ( Value )
96 {
97 assert( pCut0->uSign == If_ObjCutSignCompute(pCut0) );
98 assert( pCut1->uSign == If_ObjCutSignCompute(pCut1) );
99 If_CutPrint( pCut0 );
100 If_CutPrint( pCut1 );
101 assert( 0 );
102 }
103 }
104 }
105 return 1;
106}
void If_CutPrint(If_Cut_t *pCut)
Definition ifCut.c:864
Here is the call graph for this function: