1 /* -----------------------------------------------------------------------------
3 * (c) The GHC Team, 2004
5 * Macros for profiling operations in STG code
7 * ---------------------------------------------------------------------------*/
12 /* -----------------------------------------------------------------------------
14 * ---------------------------------------------------------------------------*/
16 * NB. be careful to avoid unwanted padding between fields, by
17 * putting the 8-byte fields on an 8-byte boundary. Padding can
18 * vary between C compilers, and we don't take into account any
19 * possible padding when generating CCS and CC decls in the code
20 * generator (compiler/codeGen/CgProf.hs).
23 typedef struct _CostCentre {
29 /* used for accumulating costs at the end of the run... */
31 StgWord64 mem_alloc; /* align 8 (see above) */
35 struct _CostCentre *link;
38 typedef struct _CostCentreStack {
42 struct _CostCentreStack *prevStack;
43 struct _IndexTable *indexTable;
45 StgWord64 scc_count; /* align 8 (see above) */
48 StgWord64 mem_alloc; /* align 8 (see above) */
49 StgWord64 inherited_alloc; /* align 8 (see above) */
50 StgWord inherited_ticks;
56 /* -----------------------------------------------------------------------------
57 * The rest is PROFILING only...
58 * ---------------------------------------------------------------------------*/
60 #if defined(PROFILING)
62 /* -----------------------------------------------------------------------------
64 * ---------------------------------------------------------------------------*/
66 #define EMPTY_STACK NULL
67 #define EMPTY_TABLE NULL
69 /* Constants used to set sumbsumed flag on CostCentres */
71 #define CC_IS_CAF 'c' /* 'c' => *is* a CAF cc */
72 #define CC_IS_BORING 'B' /* 'B' => *not* a CAF/sub cc */
75 /* -----------------------------------------------------------------------------
77 * ---------------------------------------------------------------------------*/
79 typedef struct _IndexTable {
82 struct _IndexTable *next;
83 unsigned int back_edge;
87 /* -----------------------------------------------------------------------------
88 Pre-defined cost centres and cost centre stacks
89 -------------------------------------------------------------------------- */
91 extern CostCentreStack * RTS_VAR(CCCS); /* current CCS */
95 extern StgWord CC_MAIN[];
96 extern StgWord CCS_MAIN[]; /* Top CCS */
98 extern StgWord CC_SYSTEM[];
99 extern StgWord CCS_SYSTEM[]; /* RTS costs */
101 extern StgWord CC_GC[];
102 extern StgWord CCS_GC[]; /* Garbage collector costs */
104 extern StgWord CC_SUBSUMED[];
105 extern StgWord CCS_SUBSUMED[]; /* Costs are subsumed by caller */
107 extern StgWord CC_OVERHEAD[];
108 extern StgWord CCS_OVERHEAD[]; /* Profiling overhead */
110 extern StgWord CC_DONT_CARE[];
111 extern StgWord CCS_DONT_CARE[]; /* shouldn't ever get set */
115 extern CostCentre CC_MAIN[];
116 extern CostCentreStack CCS_MAIN[]; /* Top CCS */
118 extern CostCentre CC_SYSTEM[];
119 extern CostCentreStack CCS_SYSTEM[]; /* RTS costs */
121 extern CostCentre CC_GC[];
122 extern CostCentreStack CCS_GC[]; /* Garbage collector costs */
124 extern CostCentre CC_SUBSUMED[];
125 extern CostCentreStack CCS_SUBSUMED[]; /* Costs are subsumed by caller */
127 extern CostCentre CC_OVERHEAD[];
128 extern CostCentreStack CCS_OVERHEAD[]; /* Profiling overhead */
130 extern CostCentre CC_DONT_CARE[];
131 extern CostCentreStack CCS_DONT_CARE[]; /* shouldn't ever get set */
133 #endif /* IN_STG_CODE */
135 extern unsigned int RTS_VAR(CC_ID); /* global ids */
136 extern unsigned int RTS_VAR(CCS_ID);
137 extern unsigned int RTS_VAR(HP_ID);
139 extern unsigned int RTS_VAR(era);
141 /* -----------------------------------------------------------------------------
143 * ---------------------------------------------------------------------------*/
145 void EnterFunCCS ( CostCentreStack *ccsfn );
146 CostCentreStack *PushCostCentre ( CostCentreStack *, CostCentre * );
147 CostCentreStack *AppendCCS ( CostCentreStack *ccs1, CostCentreStack *ccs2 );
149 extern unsigned int RTS_VAR(entering_PAP);
151 /* -----------------------------------------------------------------------------
154 Cost centres are registered at startup by calling a registering
155 routine in each module. Each module registers its cost centres and
156 calls the registering routine for all imported modules. The RTS calls
157 the registering routine for the module Main. This registering must be
158 done before initialisation since the evaluation required for
159 initialisation may use the cost centres.
161 As the code for each module uses tail calls we use an auxiliary stack
162 (in the heap) to record imported modules still to be registered. At
163 the bottom of the stack is NULL which indicates that
164 @miniInterpretEnd@ should be resumed.
166 @START_REGISTER@ and @END_REGISTER@ are special macros used to
167 delimit the function. @END_REGISTER@ pops the next registering
168 routine off the stack and jumps to it. @REGISTER_CC@ registers a cost
169 centre. @REGISTER_IMPORT@ pushes a modules registering routine onto
172 -------------------------------------------------------------------------- */
174 extern CostCentre * RTS_VAR(CC_LIST); /* registered CC list */
175 extern CostCentreStack * RTS_VAR(CCS_LIST); /* registered CCS list */
177 #define REGISTER_CC(cc) \
179 extern CostCentre cc[]; \
180 if ((cc)->link == (CostCentre *)0) { \
181 (cc)->link = CC_LIST; \
183 (cc)->ccID = CC_ID++; \
186 #define REGISTER_CCS(ccs) \
188 extern CostCentreStack ccs[]; \
189 if ((ccs)->prevStack == (CostCentreStack *)0) { \
190 (ccs)->prevStack = CCS_LIST; \
192 (ccs)->ccsID = CCS_ID++; \
195 /* -----------------------------------------------------------------------------
196 * Declaring Cost Centres & Cost Centre Stacks.
197 * -------------------------------------------------------------------------- */
199 # define CC_DECLARE(cc_ident,name,module,caf,is_local) \
200 is_local CostCentre cc_ident[1] \
209 # define CCS_DECLARE(ccs_ident,cc_ident,is_local) \
210 is_local CostCentreStack ccs_ident[1] \
219 inherited_ticks : 0, \
220 inherited_alloc : 0, \
224 /* -----------------------------------------------------------------------------
225 * Time / Allocation Macros
226 * ---------------------------------------------------------------------------*/
228 /* eliminate profiling overhead from allocation costs */
229 #define CCS_ALLOC(ccs, size) (ccs)->mem_alloc += ((size)-sizeofW(StgProfHeader))
231 #else /* !PROFILING */
233 #define CCS_ALLOC(ccs, amount) doNothing()
235 #endif /* PROFILING */
237 #endif /* STGPROF_H */