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