/* -----------------------------------------------------------------------------
- * $Id: Profiling.h,v 1.6 1999/09/15 13:45:14 simonmar Exp $
+ * $Id: Profiling.h,v 1.7 2000/02/29 16:58:08 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
CostCentre *cc;
CostCentreStack *ccs;
struct _IndexTable *next;
+ unsigned int back_edge;
} IndexTable;
-/*
- * CCSDeclist
- */
-
-typedef struct _CCSDecList {
- CostCentreStack *ccs;
- struct _CCSDecList *nextList;
-} CCSDecList;
-
-
/* -----------------------------------------------------------------------------
Pre-defined cost centres and cost centre stacks
-------------------------------------------------------------------------- */
CostCentreStack *EnterFunCCS ( CostCentreStack *cccs, CostCentreStack *ccsfn );
CostCentreStack *PushCostCentre ( CostCentreStack *, CostCentre * );
CostCentreStack *AppendCCS ( CostCentreStack *ccs1, CostCentreStack *ccs2 );
-CostCentreStack *ActualPush ( CostCentreStack *, CostCentre * );
-CostCentreStack *RemoveCC ( CostCentreStack *, CostCentre * );
-
-CostCentreStack *IsInIndexTable ( IndexTable *, CostCentre * );
-IndexTable *AddToIndexTable ( IndexTable *, CostCentreStack *, CostCentre * );
extern unsigned int entering_PAP;
/* -----------------------------------------------------------------------------
- * $Id: Profiling.c,v 1.12 2000/02/17 17:19:42 simonmar Exp $
+ * $Id: Profiling.c,v 1.13 2000/02/29 16:58:09 simonmar Exp $
*
* (c) The GHC Team, 1998-1999
*
static void count_ticks ( CostCentreStack *ccs );
static void reportCCS ( CostCentreStack *ccs, nat indent );
static void DecCCS ( CostCentreStack *ccs );
+static void DecBackEdge ( CostCentreStack *ccs, CostCentreStack *oldccs );
+static CostCentreStack *CheckLoop ( CostCentreStack *ccs, CostCentre *cc );
static CostCentreStack *pruneCCSTree ( CostCentreStack *ccs );
+
+static CostCentreStack *ActualPush ( CostCentreStack *, CostCentre * );
+static CostCentreStack *IsInIndexTable ( IndexTable *, CostCentre * );
+static IndexTable *AddToIndexTable ( IndexTable *, CostCentreStack *,
+ CostCentre *, unsigned int );
+
#ifdef DEBUG
static void printCCS ( CostCentreStack *ccs );
#endif
if (temp_ccs != EMPTY_STACK)
return temp_ccs;
else {
- /* remove the CC to avoid loops */
- ccs = RemoveCC(ccs,cc);
- /* have a different stack now, need to check the memo table again */
- temp_ccs = IsInIndexTable(ccs->indexTable,cc);
- if (temp_ccs != EMPTY_STACK)
+ temp_ccs = CheckLoop(ccs,cc);
+ if (temp_ccs != NULL) {
+ /* we have recursed to an older CCS. Mark this in
+ * the index table, and emit a "back edge" into the
+ * log file.
+ */
+ ccs->indexTable = AddToIndexTable(ccs->indexTable,temp_ccs,cc,1);
+ DecBackEdge(temp_ccs,ccs);
return temp_ccs;
- else
+ } else {
return ActualPush(ccs,cc);
+ }
}
}
}
}
+static CostCentreStack *
+CheckLoop ( CostCentreStack *ccs, CostCentre *cc )
+{
+ while (ccs != EMPTY_STACK) {
+ if (ccs->cc == cc)
+ return ccs;
+ ccs = ccs->prevStack;
+ }
+ return NULL;
+}
+
/* Append ccs1 to ccs2 (ignoring any CAF cost centre at the root of ccs1 */
#ifdef DEBUG
{
CostCentreStack *ccs = NULL;
- /* Optimisation: if we attempt to append a CCS to itself, we're
- * going to end up with the same ccs after a great deal of pushing
- * and removing of cost centres. Furthermore, we'll generate a lot
- * of intermediate CCSs which would not otherwise be generated. So:
- * let's cope with this common case first.
- */
if (ccs1 == ccs2) {
return ccs1;
}
return PushCostCentre(ccs,ccs2->cc);
}
-CostCentreStack *
+static CostCentreStack *
ActualPush ( CostCentreStack *ccs, CostCentre *cc )
{
CostCentreStack *new_ccs;
new_ccs->mem_alloc = 0;
new_ccs->root = ccs->root;
+ new_ccs->emitted = 0;
/* update the memoization table for the parent stack */
if (ccs != EMPTY_STACK)
- ccs->indexTable = AddToIndexTable(ccs->indexTable, new_ccs, cc);
+ ccs->indexTable = AddToIndexTable(ccs->indexTable, new_ccs, cc,
+ 0/*not a back edge*/);
/* make sure this CC is declared at the next heap/time sample */
DecCCS(new_ccs);
}
-CostCentreStack *
-RemoveCC(CostCentreStack *ccs, CostCentre *cc)
-{
- CostCentreStack *del_ccs;
-
- if (ccs == EMPTY_STACK) {
- return EMPTY_STACK;
- } else {
- if (ccs->cc == cc) {
- return ccs->prevStack;
- } else {
- {
- del_ccs = RemoveCC(ccs->prevStack, cc);
-
- if (del_ccs == EMPTY_STACK)
- return ccs;
- else
- return PushCostCentre(del_ccs,ccs->cc);
- }
- }
- }
-}
-
-
-CostCentreStack *
+static CostCentreStack *
IsInIndexTable(IndexTable *it, CostCentre *cc)
{
while (it!=EMPTY_TABLE)
}
-IndexTable *
-AddToIndexTable(IndexTable *it, CostCentreStack *new_ccs, CostCentre *cc)
+static IndexTable *
+AddToIndexTable(IndexTable *it, CostCentreStack *new_ccs,
+ CostCentre *cc, unsigned int back_edge)
{
IndexTable *new_it;
new_it->cc = cc;
new_it->ccs = new_ccs;
new_it->next = it;
+ new_it->back_edge = back_edge;
return new_it;
}
}
}
+static void
+DecBackEdge( CostCentreStack *ccs, CostCentreStack *oldccs )
+{
+ if (prof_file && RtsFlags.CcFlags.doCostCentres == COST_CENTRES_XML) {
+ if (ccs->prevStack == EMPTY_STACK)
+ fprintf(prof_file, "%d %d 1 %d\n", CCS_UQ,
+ ccs->ccsID, ccs->cc->ccID);
+ else
+ fprintf(prof_file, "%d %d 2 %d %d\n", CCS_UQ,
+ ccs->ccsID, ccs->cc->ccID, oldccs->ccsID);
+ }
+}
+
/* -----------------------------------------------------------------------------
Generating a time & allocation profiling report.
-------------------------------------------------------------------------- */
ccs->cc->time_ticks += ccs->time_ticks;
for (i = ccs->indexTable; i != 0; i = i->next) {
- aggregate_cc_costs(i->ccs);
+ if (!i->back_edge) {
+ aggregate_cc_costs(i->ccs);
+ }
}
}
}
for (i = ccs->indexTable; i != 0; i = i->next) {
- reportCCS(i->ccs, indent+1);
+ if (!i->back_edge) {
+ reportCCS(i->ccs, indent+1);
+ }
}
}
total_prof_ticks += ccs->time_ticks;
}
for (i = ccs->indexTable; i != NULL; i = i->next)
- count_ticks(i->ccs);
+ if (!i->back_edge) {
+ count_ticks(i->ccs);
+ }
}
/* return rtsTrue if it is one of the ones that
prev = &ccs->indexTable;
for (i = ccs->indexTable; i != 0; i = i->next) {
+ if (i->back_edge) { continue; }
+
ccs1 = pruneCCSTree(i->ccs);
if (ccs1 == NULL) {
*prev = i->next;
ccs->ccsID, ccs->scc_count, ccs->time_ticks, ccs->mem_alloc);
for (i = ccs->indexTable; i != 0; i = i->next) {
- reportCCS_XML(i->ccs);
+ if (!i->back_edge) {
+ reportCCS_XML(i->ccs);
+ }
}
}