1 /* -----------------------------------------------------------------------------
3 * (c) The GHC Team, 2004
5 * Macros for profiling operations in STG code
7 * ---------------------------------------------------------------------------*/
12 /* -----------------------------------------------------------------------------
14 * ---------------------------------------------------------------------------*/
15 // NB. be careful to avoid unwanted padding between fields, by
16 // putting the 8-byte fields on an 8-byte boundary. Padding can
17 // vary between C compilers, and we don't take into account any
18 // possible padding when generating CCS and CC decls in the code
19 // generator (compiler/codeGen/CgProf.hs).
21 typedef struct _CostCentre {
27 /* used for accumulating costs at the end of the run... */
29 StgWord64 mem_alloc; // align 8 (see above)
33 struct _CostCentre *link;
36 typedef struct _CostCentreStack {
40 struct _CostCentreStack *prevStack;
41 struct _IndexTable *indexTable;
43 StgWord64 scc_count; // align 8 (see above)
46 StgWord64 mem_alloc; // align 8 (see above)
47 StgWord64 inherited_alloc; // align 8 (see above)
48 StgWord inherited_ticks;
54 /* -----------------------------------------------------------------------------
55 * The rest is PROFILING only...
56 * ---------------------------------------------------------------------------*/
58 #if defined(PROFILING)
60 /* -----------------------------------------------------------------------------
62 * ---------------------------------------------------------------------------*/
64 #define EMPTY_STACK NULL
65 #define EMPTY_TABLE NULL
67 /* Constants used to set sumbsumed flag on CostCentres */
69 #define CC_IS_CAF 'c' /* 'c' => *is* a CAF cc */
70 #define CC_IS_BORING 'B' /* 'B' => *not* a CAF/sub cc */
73 /* -----------------------------------------------------------------------------
75 * ---------------------------------------------------------------------------*/
77 typedef struct _IndexTable {
80 struct _IndexTable *next;
81 unsigned int back_edge;
85 /* -----------------------------------------------------------------------------
86 Pre-defined cost centres and cost centre stacks
87 -------------------------------------------------------------------------- */
89 extern CostCentreStack * RTS_VAR(CCCS); /* current CCS */
93 extern StgWord CC_MAIN[];
94 extern StgWord CCS_MAIN[]; /* Top CCS */
96 extern StgWord CC_SYSTEM[];
97 extern StgWord CCS_SYSTEM[]; /* RTS costs */
99 extern StgWord CC_GC[];
100 extern StgWord CCS_GC[]; /* Garbage collector costs */
102 extern StgWord CC_SUBSUMED[];
103 extern StgWord CCS_SUBSUMED[]; /* Costs are subsumed by caller */
105 extern StgWord CC_OVERHEAD[];
106 extern StgWord CCS_OVERHEAD[]; /* Profiling overhead */
108 extern StgWord CC_DONT_CARE[];
109 extern StgWord CCS_DONT_CARE[]; /* shouldn't ever get set */
113 extern CostCentre CC_MAIN[];
114 extern CostCentreStack CCS_MAIN[]; /* Top CCS */
116 extern CostCentre CC_SYSTEM[];
117 extern CostCentreStack CCS_SYSTEM[]; /* RTS costs */
119 extern CostCentre CC_GC[];
120 extern CostCentreStack CCS_GC[]; /* Garbage collector costs */
122 extern CostCentre CC_SUBSUMED[];
123 extern CostCentreStack CCS_SUBSUMED[]; /* Costs are subsumed by caller */
125 extern CostCentre CC_OVERHEAD[];
126 extern CostCentreStack CCS_OVERHEAD[]; /* Profiling overhead */
128 extern CostCentre CC_DONT_CARE[];
129 extern CostCentreStack CCS_DONT_CARE[]; /* shouldn't ever get set */
131 #endif // IN_STG_CODE
133 extern unsigned int RTS_VAR(CC_ID); /* global ids */
134 extern unsigned int RTS_VAR(CCS_ID);
135 extern unsigned int RTS_VAR(HP_ID);
137 extern unsigned int RTS_VAR(era);
139 /* -----------------------------------------------------------------------------
141 * ---------------------------------------------------------------------------*/
143 void EnterFunCCS ( CostCentreStack *ccsfn );
144 CostCentreStack *PushCostCentre ( CostCentreStack *, CostCentre * );
145 CostCentreStack *AppendCCS ( CostCentreStack *ccs1, CostCentreStack *ccs2 );
147 extern unsigned int RTS_VAR(entering_PAP);
149 /* -----------------------------------------------------------------------------
152 Cost centres are registered at startup by calling a registering
153 routine in each module. Each module registers its cost centres and
154 calls the registering routine for all imported modules. The RTS calls
155 the registering routine for the module Main. This registering must be
156 done before initialisation since the evaluation required for
157 initialisation may use the cost centres.
159 As the code for each module uses tail calls we use an auxiliary stack
160 (in the heap) to record imported modules still to be registered. At
161 the bottom of the stack is NULL which indicates that
162 @miniInterpretEnd@ should be resumed.
164 @START_REGISTER@ and @END_REGISTER@ are special macros used to
165 delimit the function. @END_REGISTER@ pops the next registering
166 routine off the stack and jumps to it. @REGISTER_CC@ registers a cost
167 centre. @REGISTER_IMPORT@ pushes a modules registering routine onto
170 -------------------------------------------------------------------------- */
172 extern CostCentre * RTS_VAR(CC_LIST); /* registered CC list */
173 extern CostCentreStack * RTS_VAR(CCS_LIST); /* registered CCS list */
175 #define REGISTER_CC(cc) \
177 extern CostCentre cc[]; \
178 if ((cc)->link == (CostCentre *)0) { \
179 (cc)->link = CC_LIST; \
181 (cc)->ccID = CC_ID++; \
184 #define REGISTER_CCS(ccs) \
186 extern CostCentreStack ccs[]; \
187 if ((ccs)->prevStack == (CostCentreStack *)0) { \
188 (ccs)->prevStack = CCS_LIST; \
190 (ccs)->ccsID = CCS_ID++; \
193 /* -----------------------------------------------------------------------------
194 * Declaring Cost Centres & Cost Centre Stacks.
195 * -------------------------------------------------------------------------- */
197 # define CC_DECLARE(cc_ident,name,module,caf,is_local) \
198 is_local CostCentre cc_ident[1] \
207 # define CCS_DECLARE(ccs_ident,cc_ident,is_local) \
208 is_local CostCentreStack ccs_ident[1] \
217 inherited_ticks : 0, \
218 inherited_alloc : 0, \
222 /* -----------------------------------------------------------------------------
223 * Time / Allocation Macros
224 * ---------------------------------------------------------------------------*/
226 /* eliminate profiling overhead from allocation costs */
227 #define CCS_ALLOC(ccs, size) (ccs)->mem_alloc += ((size)-sizeofW(StgProfHeader))
229 #else /* !PROFILING */
231 #define CCS_ALLOC(ccs, amount) doNothing()
233 #endif /* PROFILING */
235 #endif /* STGPROF_H */