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 // Returns non-zero if the RTS is a profiling version
18 int rts_isProfiled(void);
20 /* -----------------------------------------------------------------------------
22 * ---------------------------------------------------------------------------*/
24 * NB. be careful to avoid unwanted padding between fields, by
25 * putting the 8-byte fields on an 8-byte boundary. Padding can
26 * vary between C compilers, and we don't take into account any
27 * possible padding when generating CCS and CC decls in the code
28 * generator (compiler/codeGen/CgProf.hs).
31 typedef struct _CostCentre {
37 /* used for accumulating costs at the end of the run... */
39 StgWord64 mem_alloc; /* align 8 (see above) */
43 struct _CostCentre *link;
46 typedef struct _CostCentreStack {
50 struct _CostCentreStack *prevStack;
51 struct _IndexTable *indexTable;
53 StgWord64 scc_count; /* align 8 (see above) */
56 StgWord64 mem_alloc; /* align 8 (see above) */
57 StgWord64 inherited_alloc; /* align 8 (see above) */
58 StgWord inherited_ticks;
64 /* -----------------------------------------------------------------------------
65 * The rest is PROFILING only...
66 * ---------------------------------------------------------------------------*/
68 #if defined(PROFILING)
70 /* -----------------------------------------------------------------------------
72 * ---------------------------------------------------------------------------*/
74 #define EMPTY_STACK NULL
75 #define EMPTY_TABLE NULL
77 /* Constants used to set sumbsumed flag on CostCentres */
79 #define CC_IS_CAF 'c' /* 'c' => *is* a CAF cc */
80 #define CC_IS_BORING 'B' /* 'B' => *not* a CAF/sub cc */
83 /* -----------------------------------------------------------------------------
85 * ---------------------------------------------------------------------------*/
87 typedef struct _IndexTable {
90 struct _IndexTable *next;
91 unsigned int back_edge;
95 /* -----------------------------------------------------------------------------
96 Pre-defined cost centres and cost centre stacks
97 -------------------------------------------------------------------------- */
99 extern CostCentreStack * RTS_VAR(CCCS); /* current CCS */
103 extern StgWord CC_MAIN[];
104 extern StgWord CCS_MAIN[]; /* Top CCS */
106 extern StgWord CC_SYSTEM[];
107 extern StgWord CCS_SYSTEM[]; /* RTS costs */
109 extern StgWord CC_GC[];
110 extern StgWord CCS_GC[]; /* Garbage collector costs */
112 extern StgWord CC_SUBSUMED[];
113 extern StgWord CCS_SUBSUMED[]; /* Costs are subsumed by caller */
115 extern StgWord CC_OVERHEAD[];
116 extern StgWord CCS_OVERHEAD[]; /* Profiling overhead */
118 extern StgWord CC_DONT_CARE[];
119 extern StgWord CCS_DONT_CARE[]; /* shouldn't ever get set */
123 extern CostCentre CC_MAIN[];
124 extern CostCentreStack CCS_MAIN[]; /* Top CCS */
126 extern CostCentre CC_SYSTEM[];
127 extern CostCentreStack CCS_SYSTEM[]; /* RTS costs */
129 extern CostCentre CC_GC[];
130 extern CostCentreStack CCS_GC[]; /* Garbage collector costs */
132 extern CostCentre CC_SUBSUMED[];
133 extern CostCentreStack CCS_SUBSUMED[]; /* Costs are subsumed by caller */
135 extern CostCentre CC_OVERHEAD[];
136 extern CostCentreStack CCS_OVERHEAD[]; /* Profiling overhead */
138 extern CostCentre CC_DONT_CARE[];
139 extern CostCentreStack CCS_DONT_CARE[]; /* shouldn't ever get set */
141 #endif /* IN_STG_CODE */
143 extern unsigned int RTS_VAR(CC_ID); /* global ids */
144 extern unsigned int RTS_VAR(CCS_ID);
145 extern unsigned int RTS_VAR(HP_ID);
147 extern unsigned int RTS_VAR(era);
149 /* -----------------------------------------------------------------------------
151 * ---------------------------------------------------------------------------*/
153 void EnterFunCCS ( CostCentreStack *ccsfn );
154 CostCentreStack *PushCostCentre ( CostCentreStack *, CostCentre * );
155 CostCentreStack *AppendCCS ( CostCentreStack *ccs1, CostCentreStack *ccs2 );
157 extern unsigned int RTS_VAR(entering_PAP);
159 /* -----------------------------------------------------------------------------
162 Cost centres are registered at startup by calling a registering
163 routine in each module. Each module registers its cost centres and
164 calls the registering routine for all imported modules. The RTS calls
165 the registering routine for the module Main. This registering must be
166 done before initialisation since the evaluation required for
167 initialisation may use the cost centres.
169 As the code for each module uses tail calls we use an auxiliary stack
170 (in the heap) to record imported modules still to be registered. At
171 the bottom of the stack is NULL which indicates that
172 @miniInterpretEnd@ should be resumed.
174 @START_REGISTER@ and @END_REGISTER@ are special macros used to
175 delimit the function. @END_REGISTER@ pops the next registering
176 routine off the stack and jumps to it. @REGISTER_CC@ registers a cost
177 centre. @REGISTER_IMPORT@ pushes a modules registering routine onto
180 -------------------------------------------------------------------------- */
182 extern CostCentre * RTS_VAR(CC_LIST); /* registered CC list */
183 extern CostCentreStack * RTS_VAR(CCS_LIST); /* registered CCS list */
185 #define REGISTER_CC(cc) \
187 if ((cc)->link == (CostCentre *)0) { \
188 (cc)->link = CC_LIST; \
190 (cc)->ccID = CC_ID++; \
193 #define REGISTER_CCS(ccs) \
195 if ((ccs)->prevStack == (CostCentreStack *)0) { \
196 (ccs)->prevStack = CCS_LIST; \
198 (ccs)->ccsID = CCS_ID++; \
201 /* -----------------------------------------------------------------------------
202 * Declaring Cost Centres & Cost Centre Stacks.
203 * -------------------------------------------------------------------------- */
205 # define CC_DECLARE(cc_ident,name,module,caf,is_local) \
206 is_local CostCentre cc_ident[1] \
215 # define CCS_DECLARE(ccs_ident,cc_ident,is_local) \
216 is_local CostCentreStack ccs_ident[1] \
225 inherited_ticks : 0, \
226 inherited_alloc : 0, \
230 /* -----------------------------------------------------------------------------
231 * Time / Allocation Macros
232 * ---------------------------------------------------------------------------*/
234 /* eliminate profiling overhead from allocation costs */
235 #define CCS_ALLOC(ccs, size) (ccs)->mem_alloc += ((size)-sizeofW(StgProfHeader))
237 #else /* !PROFILING */
239 #define CCS_ALLOC(ccs, amount) doNothing()
241 #endif /* PROFILING */
243 #endif /* RTS_PROF_CCS_H */