X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=includes%2Frts%2Fprof%2FCCS.h;fp=includes%2Frts%2Fprof%2FCCS.h;h=3512930b7bd7b15c21ce483413c9ed7e81348798;hb=a2a67cd520b9841114d69a87a423dabcb3b4368e;hp=0000000000000000000000000000000000000000;hpb=5d379cbe65e406d5c3a848fe7fcd090cafbfeb78;p=ghc-hetmet.git diff --git a/includes/rts/prof/CCS.h b/includes/rts/prof/CCS.h new file mode 100644 index 0000000..3512930 --- /dev/null +++ b/includes/rts/prof/CCS.h @@ -0,0 +1,238 @@ +/* ----------------------------------------------------------------------------- + * + * (c) The GHC Team, 2004 + * + * Macros for profiling operations in STG code + * + * ---------------------------------------------------------------------------*/ + +#ifndef RTS_PROF_CCS_H +#define RTS_PROF_CCS_H + +/* ----------------------------------------------------------------------------- + * Data Structures + * ---------------------------------------------------------------------------*/ +/* + * NB. be careful to avoid unwanted padding between fields, by + * putting the 8-byte fields on an 8-byte boundary. Padding can + * vary between C compilers, and we don't take into account any + * possible padding when generating CCS and CC decls in the code + * generator (compiler/codeGen/CgProf.hs). + */ + +typedef struct _CostCentre { + StgInt ccID; + + char * label; + char * module; + + /* used for accumulating costs at the end of the run... */ + StgWord time_ticks; + StgWord64 mem_alloc; /* align 8 (see above) */ + + StgInt is_caf; + + struct _CostCentre *link; +} CostCentre; + +typedef struct _CostCentreStack { + StgInt ccsID; + + CostCentre *cc; + struct _CostCentreStack *prevStack; + struct _IndexTable *indexTable; + + StgWord64 scc_count; /* align 8 (see above) */ + StgWord selected; + StgWord time_ticks; + StgWord64 mem_alloc; /* align 8 (see above) */ + StgWord64 inherited_alloc; /* align 8 (see above) */ + StgWord inherited_ticks; + + CostCentre *root; +} CostCentreStack; + + +/* ----------------------------------------------------------------------------- + * The rest is PROFILING only... + * ---------------------------------------------------------------------------*/ + +#if defined(PROFILING) + +/* ----------------------------------------------------------------------------- + * Constants + * ---------------------------------------------------------------------------*/ + +#define EMPTY_STACK NULL +#define EMPTY_TABLE NULL + +/* Constants used to set sumbsumed flag on CostCentres */ + +#define CC_IS_CAF 'c' /* 'c' => *is* a CAF cc */ +#define CC_IS_BORING 'B' /* 'B' => *not* a CAF/sub cc */ + + +/* ----------------------------------------------------------------------------- + * Data Structures + * ---------------------------------------------------------------------------*/ + +typedef struct _IndexTable { + CostCentre *cc; + CostCentreStack *ccs; + struct _IndexTable *next; + unsigned int back_edge; +} IndexTable; + + +/* ----------------------------------------------------------------------------- + Pre-defined cost centres and cost centre stacks + -------------------------------------------------------------------------- */ + +extern CostCentreStack * RTS_VAR(CCCS); /* current CCS */ + +#if IN_STG_CODE + +extern StgWord CC_MAIN[]; +extern StgWord CCS_MAIN[]; /* Top CCS */ + +extern StgWord CC_SYSTEM[]; +extern StgWord CCS_SYSTEM[]; /* RTS costs */ + +extern StgWord CC_GC[]; +extern StgWord CCS_GC[]; /* Garbage collector costs */ + +extern StgWord CC_SUBSUMED[]; +extern StgWord CCS_SUBSUMED[]; /* Costs are subsumed by caller */ + +extern StgWord CC_OVERHEAD[]; +extern StgWord CCS_OVERHEAD[]; /* Profiling overhead */ + +extern StgWord CC_DONT_CARE[]; +extern StgWord CCS_DONT_CARE[]; /* shouldn't ever get set */ + +#else + +extern CostCentre CC_MAIN[]; +extern CostCentreStack CCS_MAIN[]; /* Top CCS */ + +extern CostCentre CC_SYSTEM[]; +extern CostCentreStack CCS_SYSTEM[]; /* RTS costs */ + +extern CostCentre CC_GC[]; +extern CostCentreStack CCS_GC[]; /* Garbage collector costs */ + +extern CostCentre CC_SUBSUMED[]; +extern CostCentreStack CCS_SUBSUMED[]; /* Costs are subsumed by caller */ + +extern CostCentre CC_OVERHEAD[]; +extern CostCentreStack CCS_OVERHEAD[]; /* Profiling overhead */ + +extern CostCentre CC_DONT_CARE[]; +extern CostCentreStack CCS_DONT_CARE[]; /* shouldn't ever get set */ + +#endif /* IN_STG_CODE */ + +extern unsigned int RTS_VAR(CC_ID); /* global ids */ +extern unsigned int RTS_VAR(CCS_ID); +extern unsigned int RTS_VAR(HP_ID); + +extern unsigned int RTS_VAR(era); + +/* ----------------------------------------------------------------------------- + * Functions + * ---------------------------------------------------------------------------*/ + +void EnterFunCCS ( CostCentreStack *ccsfn ); +CostCentreStack *PushCostCentre ( CostCentreStack *, CostCentre * ); +CostCentreStack *AppendCCS ( CostCentreStack *ccs1, CostCentreStack *ccs2 ); + +extern unsigned int RTS_VAR(entering_PAP); + +/* ----------------------------------------------------------------------------- + * Registering CCs + + Cost centres are registered at startup by calling a registering + routine in each module. Each module registers its cost centres and + calls the registering routine for all imported modules. The RTS calls + the registering routine for the module Main. This registering must be + done before initialisation since the evaluation required for + initialisation may use the cost centres. + + As the code for each module uses tail calls we use an auxiliary stack + (in the heap) to record imported modules still to be registered. At + the bottom of the stack is NULL which indicates that + @miniInterpretEnd@ should be resumed. + + @START_REGISTER@ and @END_REGISTER@ are special macros used to + delimit the function. @END_REGISTER@ pops the next registering + routine off the stack and jumps to it. @REGISTER_CC@ registers a cost + centre. @REGISTER_IMPORT@ pushes a modules registering routine onto + the register stack. + + -------------------------------------------------------------------------- */ + +extern CostCentre * RTS_VAR(CC_LIST); /* registered CC list */ +extern CostCentreStack * RTS_VAR(CCS_LIST); /* registered CCS list */ + +#define REGISTER_CC(cc) \ + do { \ + extern CostCentre cc[]; \ + if ((cc)->link == (CostCentre *)0) { \ + (cc)->link = CC_LIST; \ + CC_LIST = (cc); \ + (cc)->ccID = CC_ID++; \ + }} while(0) + +#define REGISTER_CCS(ccs) \ + do { \ + extern CostCentreStack ccs[]; \ + if ((ccs)->prevStack == (CostCentreStack *)0) { \ + (ccs)->prevStack = CCS_LIST; \ + CCS_LIST = (ccs); \ + (ccs)->ccsID = CCS_ID++; \ + }} while(0) + +/* ----------------------------------------------------------------------------- + * Declaring Cost Centres & Cost Centre Stacks. + * -------------------------------------------------------------------------- */ + +# define CC_DECLARE(cc_ident,name,module,caf,is_local) \ + is_local CostCentre cc_ident[1] \ + = {{ 0, \ + name, \ + module, \ + 0, \ + 0, \ + caf, \ + 0 }}; + +# define CCS_DECLARE(ccs_ident,cc_ident,is_local) \ + is_local CostCentreStack ccs_ident[1] \ + = {{ ccsID : 0, \ + cc : cc_ident, \ + prevStack : NULL, \ + indexTable : NULL, \ + selected : 0, \ + scc_count : 0, \ + time_ticks : 0, \ + mem_alloc : 0, \ + inherited_ticks : 0, \ + inherited_alloc : 0, \ + root : 0, \ + }}; + +/* ----------------------------------------------------------------------------- + * Time / Allocation Macros + * ---------------------------------------------------------------------------*/ + +/* eliminate profiling overhead from allocation costs */ +#define CCS_ALLOC(ccs, size) (ccs)->mem_alloc += ((size)-sizeofW(StgProfHeader)) + +#else /* !PROFILING */ + +#define CCS_ALLOC(ccs, amount) doNothing() + +#endif /* PROFILING */ + +#endif /* RTS_PROF_CCS_H */ +