1 /* -----------------------------------------------------------------------------
3 * (c) The GHC Team, 2009
5 * Macros for profiling operations in STG code
7 * Do not #include this file directly: #include "Rts.h" instead.
9 * To understand the structure of the RTS headers, see the wiki:
10 * http://hackage.haskell.org/trac/ghc/wiki/Commentary/SourceTree/Includes
12 * ---------------------------------------------------------------------------*/
14 #ifndef RTS_PROF_CCS_H
15 #define RTS_PROF_CCS_H
17 /* -----------------------------------------------------------------------------
19 * ---------------------------------------------------------------------------*/
21 * NB. be careful to avoid unwanted padding between fields, by
22 * putting the 8-byte fields on an 8-byte boundary. Padding can
23 * vary between C compilers, and we don't take into account any
24 * possible padding when generating CCS and CC decls in the code
25 * generator (compiler/codeGen/CgProf.hs).
28 typedef struct _CostCentre {
34 /* used for accumulating costs at the end of the run... */
36 StgWord64 mem_alloc; /* align 8 (see above) */
40 struct _CostCentre *link;
43 typedef struct _CostCentreStack {
47 struct _CostCentreStack *prevStack;
48 struct _IndexTable *indexTable;
50 StgWord64 scc_count; /* align 8 (see above) */
53 StgWord64 mem_alloc; /* align 8 (see above) */
54 StgWord64 inherited_alloc; /* align 8 (see above) */
55 StgWord inherited_ticks;
61 /* -----------------------------------------------------------------------------
62 * The rest is PROFILING only...
63 * ---------------------------------------------------------------------------*/
65 #if defined(PROFILING)
67 /* -----------------------------------------------------------------------------
69 * ---------------------------------------------------------------------------*/
71 #define EMPTY_STACK NULL
72 #define EMPTY_TABLE NULL
74 /* Constants used to set sumbsumed flag on CostCentres */
76 #define CC_IS_CAF 'c' /* 'c' => *is* a CAF cc */
77 #define CC_IS_BORING 'B' /* 'B' => *not* a CAF/sub cc */
80 /* -----------------------------------------------------------------------------
82 * ---------------------------------------------------------------------------*/
84 typedef struct _IndexTable {
87 struct _IndexTable *next;
88 unsigned int back_edge;
92 /* -----------------------------------------------------------------------------
93 Pre-defined cost centres and cost centre stacks
94 -------------------------------------------------------------------------- */
96 extern CostCentreStack * RTS_VAR(CCCS); /* current CCS */
100 extern StgWord CC_MAIN[];
101 extern StgWord CCS_MAIN[]; /* Top CCS */
103 extern StgWord CC_SYSTEM[];
104 extern StgWord CCS_SYSTEM[]; /* RTS costs */
106 extern StgWord CC_GC[];
107 extern StgWord CCS_GC[]; /* Garbage collector costs */
109 extern StgWord CC_SUBSUMED[];
110 extern StgWord CCS_SUBSUMED[]; /* Costs are subsumed by caller */
112 extern StgWord CC_OVERHEAD[];
113 extern StgWord CCS_OVERHEAD[]; /* Profiling overhead */
115 extern StgWord CC_DONT_CARE[];
116 extern StgWord CCS_DONT_CARE[]; /* shouldn't ever get set */
120 extern CostCentre CC_MAIN[];
121 extern CostCentreStack CCS_MAIN[]; /* Top CCS */
123 extern CostCentre CC_SYSTEM[];
124 extern CostCentreStack CCS_SYSTEM[]; /* RTS costs */
126 extern CostCentre CC_GC[];
127 extern CostCentreStack CCS_GC[]; /* Garbage collector costs */
129 extern CostCentre CC_SUBSUMED[];
130 extern CostCentreStack CCS_SUBSUMED[]; /* Costs are subsumed by caller */
132 extern CostCentre CC_OVERHEAD[];
133 extern CostCentreStack CCS_OVERHEAD[]; /* Profiling overhead */
135 extern CostCentre CC_DONT_CARE[];
136 extern CostCentreStack CCS_DONT_CARE[]; /* shouldn't ever get set */
138 #endif /* IN_STG_CODE */
140 extern unsigned int RTS_VAR(CC_ID); /* global ids */
141 extern unsigned int RTS_VAR(CCS_ID);
142 extern unsigned int RTS_VAR(HP_ID);
144 extern unsigned int RTS_VAR(era);
146 /* -----------------------------------------------------------------------------
148 * ---------------------------------------------------------------------------*/
150 void EnterFunCCS ( CostCentreStack *ccsfn );
151 CostCentreStack *PushCostCentre ( CostCentreStack *, CostCentre * );
152 CostCentreStack *AppendCCS ( CostCentreStack *ccs1, CostCentreStack *ccs2 );
154 extern unsigned int RTS_VAR(entering_PAP);
156 /* -----------------------------------------------------------------------------
159 Cost centres are registered at startup by calling a registering
160 routine in each module. Each module registers its cost centres and
161 calls the registering routine for all imported modules. The RTS calls
162 the registering routine for the module Main. This registering must be
163 done before initialisation since the evaluation required for
164 initialisation may use the cost centres.
166 As the code for each module uses tail calls we use an auxiliary stack
167 (in the heap) to record imported modules still to be registered. At
168 the bottom of the stack is NULL which indicates that
169 @miniInterpretEnd@ should be resumed.
171 @START_REGISTER@ and @END_REGISTER@ are special macros used to
172 delimit the function. @END_REGISTER@ pops the next registering
173 routine off the stack and jumps to it. @REGISTER_CC@ registers a cost
174 centre. @REGISTER_IMPORT@ pushes a modules registering routine onto
177 -------------------------------------------------------------------------- */
179 extern CostCentre * RTS_VAR(CC_LIST); /* registered CC list */
180 extern CostCentreStack * RTS_VAR(CCS_LIST); /* registered CCS list */
182 #define REGISTER_CC(cc) \
184 if ((cc)->link == (CostCentre *)0) { \
185 (cc)->link = CC_LIST; \
187 (cc)->ccID = CC_ID++; \
190 #define REGISTER_CCS(ccs) \
192 if ((ccs)->prevStack == (CostCentreStack *)0) { \
193 (ccs)->prevStack = CCS_LIST; \
195 (ccs)->ccsID = CCS_ID++; \
198 /* -----------------------------------------------------------------------------
199 * Declaring Cost Centres & Cost Centre Stacks.
200 * -------------------------------------------------------------------------- */
202 # define CC_DECLARE(cc_ident,name,module,caf,is_local) \
203 is_local CostCentre cc_ident[1] \
212 # define CCS_DECLARE(ccs_ident,cc_ident,is_local) \
213 is_local CostCentreStack ccs_ident[1] \
222 inherited_ticks : 0, \
223 inherited_alloc : 0, \
227 /* -----------------------------------------------------------------------------
228 * Time / Allocation Macros
229 * ---------------------------------------------------------------------------*/
231 /* eliminate profiling overhead from allocation costs */
232 #define CCS_ALLOC(ccs, size) (ccs)->mem_alloc += ((size)-sizeofW(StgProfHeader))
234 #else /* !PROFILING */
236 #define CCS_ALLOC(ccs, amount) doNothing()
238 #endif /* PROFILING */
240 #endif /* RTS_PROF_CCS_H */