move the "meat" into the wiki, this file just contains pointers now
[ghc.git] / includes / StgProf.h
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The GHC Team, 2004
4 *
5 * Macros for profiling operations in STG code
6 *
7 * ---------------------------------------------------------------------------*/
8
9 #ifndef STGPROF_H
10 #define STGPROF_H
11
12 /* -----------------------------------------------------------------------------
13 * Data Structures
14 * ---------------------------------------------------------------------------*/
15 /*
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).
21 */
22
23 typedef struct _CostCentre {
24 StgInt ccID;
25
26 char * label;
27 char * module;
28
29 /* used for accumulating costs at the end of the run... */
30 StgWord time_ticks;
31 StgWord64 mem_alloc; /* align 8 (see above) */
32
33 StgInt is_caf;
34
35 struct _CostCentre *link;
36 } CostCentre;
37
38 typedef struct _CostCentreStack {
39 StgInt ccsID;
40
41 CostCentre *cc;
42 struct _CostCentreStack *prevStack;
43 struct _IndexTable *indexTable;
44
45 StgWord64 scc_count; /* align 8 (see above) */
46 StgWord selected;
47 StgWord time_ticks;
48 StgWord64 mem_alloc; /* align 8 (see above) */
49 StgWord64 inherited_alloc; /* align 8 (see above) */
50 StgWord inherited_ticks;
51
52 CostCentre *root;
53 } CostCentreStack;
54
55
56 /* -----------------------------------------------------------------------------
57 * The rest is PROFILING only...
58 * ---------------------------------------------------------------------------*/
59
60 #if defined(PROFILING)
61
62 /* -----------------------------------------------------------------------------
63 * Constants
64 * ---------------------------------------------------------------------------*/
65
66 #define EMPTY_STACK NULL
67 #define EMPTY_TABLE NULL
68
69 /* Constants used to set sumbsumed flag on CostCentres */
70
71 #define CC_IS_CAF 'c' /* 'c' => *is* a CAF cc */
72 #define CC_IS_BORING 'B' /* 'B' => *not* a CAF/sub cc */
73
74
75 /* -----------------------------------------------------------------------------
76 * Data Structures
77 * ---------------------------------------------------------------------------*/
78
79 typedef struct _IndexTable {
80 CostCentre *cc;
81 CostCentreStack *ccs;
82 struct _IndexTable *next;
83 unsigned int back_edge;
84 } IndexTable;
85
86
87 /* -----------------------------------------------------------------------------
88 Pre-defined cost centres and cost centre stacks
89 -------------------------------------------------------------------------- */
90
91 extern CostCentreStack * RTS_VAR(CCCS); /* current CCS */
92
93 #if IN_STG_CODE
94
95 extern StgWord CC_MAIN[];
96 extern StgWord CCS_MAIN[]; /* Top CCS */
97
98 extern StgWord CC_SYSTEM[];
99 extern StgWord CCS_SYSTEM[]; /* RTS costs */
100
101 extern StgWord CC_GC[];
102 extern StgWord CCS_GC[]; /* Garbage collector costs */
103
104 extern StgWord CC_SUBSUMED[];
105 extern StgWord CCS_SUBSUMED[]; /* Costs are subsumed by caller */
106
107 extern StgWord CC_OVERHEAD[];
108 extern StgWord CCS_OVERHEAD[]; /* Profiling overhead */
109
110 extern StgWord CC_DONT_CARE[];
111 extern StgWord CCS_DONT_CARE[]; /* shouldn't ever get set */
112
113 #else
114
115 extern CostCentre CC_MAIN[];
116 extern CostCentreStack CCS_MAIN[]; /* Top CCS */
117
118 extern CostCentre CC_SYSTEM[];
119 extern CostCentreStack CCS_SYSTEM[]; /* RTS costs */
120
121 extern CostCentre CC_GC[];
122 extern CostCentreStack CCS_GC[]; /* Garbage collector costs */
123
124 extern CostCentre CC_SUBSUMED[];
125 extern CostCentreStack CCS_SUBSUMED[]; /* Costs are subsumed by caller */
126
127 extern CostCentre CC_OVERHEAD[];
128 extern CostCentreStack CCS_OVERHEAD[]; /* Profiling overhead */
129
130 extern CostCentre CC_DONT_CARE[];
131 extern CostCentreStack CCS_DONT_CARE[]; /* shouldn't ever get set */
132
133 #endif /* IN_STG_CODE */
134
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);
138
139 extern unsigned int RTS_VAR(era);
140
141 /* -----------------------------------------------------------------------------
142 * Functions
143 * ---------------------------------------------------------------------------*/
144
145 void EnterFunCCS ( CostCentreStack *ccsfn );
146 CostCentreStack *PushCostCentre ( CostCentreStack *, CostCentre * );
147 CostCentreStack *AppendCCS ( CostCentreStack *ccs1, CostCentreStack *ccs2 );
148
149 extern unsigned int RTS_VAR(entering_PAP);
150
151 /* -----------------------------------------------------------------------------
152 * Registering CCs
153
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.
160
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.
165
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
170 the register stack.
171
172 -------------------------------------------------------------------------- */
173
174 extern CostCentre * RTS_VAR(CC_LIST); /* registered CC list */
175 extern CostCentreStack * RTS_VAR(CCS_LIST); /* registered CCS list */
176
177 #define REGISTER_CC(cc) \
178 do { \
179 extern CostCentre cc[]; \
180 if ((cc)->link == (CostCentre *)0) { \
181 (cc)->link = CC_LIST; \
182 CC_LIST = (cc); \
183 (cc)->ccID = CC_ID++; \
184 }} while(0)
185
186 #define REGISTER_CCS(ccs) \
187 do { \
188 extern CostCentreStack ccs[]; \
189 if ((ccs)->prevStack == (CostCentreStack *)0) { \
190 (ccs)->prevStack = CCS_LIST; \
191 CCS_LIST = (ccs); \
192 (ccs)->ccsID = CCS_ID++; \
193 }} while(0)
194
195 /* -----------------------------------------------------------------------------
196 * Declaring Cost Centres & Cost Centre Stacks.
197 * -------------------------------------------------------------------------- */
198
199 # define CC_DECLARE(cc_ident,name,module,caf,is_local) \
200 is_local CostCentre cc_ident[1] \
201 = {{ 0, \
202 name, \
203 module, \
204 0, \
205 0, \
206 caf, \
207 0 }};
208
209 # define CCS_DECLARE(ccs_ident,cc_ident,is_local) \
210 is_local CostCentreStack ccs_ident[1] \
211 = {{ ccsID : 0, \
212 cc : cc_ident, \
213 prevStack : NULL, \
214 indexTable : NULL, \
215 selected : 0, \
216 scc_count : 0, \
217 time_ticks : 0, \
218 mem_alloc : 0, \
219 inherited_ticks : 0, \
220 inherited_alloc : 0, \
221 root : 0, \
222 }};
223
224 /* -----------------------------------------------------------------------------
225 * Time / Allocation Macros
226 * ---------------------------------------------------------------------------*/
227
228 /* eliminate profiling overhead from allocation costs */
229 #define CCS_ALLOC(ccs, size) (ccs)->mem_alloc += ((size)-sizeofW(StgProfHeader))
230
231 #else /* !PROFILING */
232
233 #define CCS_ALLOC(ccs, amount) doNothing()
234
235 #endif /* PROFILING */
236
237 #endif /* STGPROF_H */
238