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