d56caf0be4ed392fc382a775ae6ebed72aaa1c3e
[ghc-hetmet.git] / includes / rts / prof / CCS.h
1 /* -----------------------------------------------------------------------------
2  *
3  * (c) The GHC Team, 2004
4  *
5  * Macros for profiling operations in STG code
6  *
7  * ---------------------------------------------------------------------------*/
8
9 #ifndef RTS_PROF_CCS_H
10 #define RTS_PROF_CCS_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         if ((cc)->link == (CostCentre *)0) {            \
180             (cc)->link = CC_LIST;                       \
181             CC_LIST = (cc);                             \
182             (cc)->ccID = CC_ID++;                       \
183         }} while(0)
184
185 #define REGISTER_CCS(ccs)                               \
186         do {                                            \
187         if ((ccs)->prevStack == (CostCentreStack *)0) { \
188           (ccs)->prevStack = CCS_LIST;                  \
189           CCS_LIST = (ccs);                             \
190           (ccs)->ccsID = CCS_ID++;                      \
191         }} while(0)
192
193 /* -----------------------------------------------------------------------------
194  * Declaring Cost Centres & Cost Centre Stacks.
195  * -------------------------------------------------------------------------- */
196
197 # define CC_DECLARE(cc_ident,name,module,caf,is_local)          \
198      is_local CostCentre cc_ident[1]                            \
199         = {{ 0,                                                 \
200              name,                                              \
201              module,                                            \
202              0,                                                 \
203              0,                                                 \
204              caf,                                               \
205              0 }};
206
207 # define CCS_DECLARE(ccs_ident,cc_ident,is_local)               \
208      is_local CostCentreStack ccs_ident[1]                      \
209        = {{ ccsID               : 0,                            \
210             cc                  : cc_ident,                     \
211             prevStack           : NULL,                         \
212             indexTable          : NULL,                         \
213             selected            : 0,                            \
214             scc_count           : 0,                            \
215             time_ticks          : 0,                            \
216             mem_alloc           : 0,                            \
217             inherited_ticks     : 0,                            \
218             inherited_alloc     : 0,                            \
219             root                : 0,                            \
220        }};
221
222 /* -----------------------------------------------------------------------------
223  * Time / Allocation Macros
224  * ---------------------------------------------------------------------------*/
225
226 /* eliminate profiling overhead from allocation costs */
227 #define CCS_ALLOC(ccs, size) (ccs)->mem_alloc += ((size)-sizeofW(StgProfHeader))
228
229 #else /* !PROFILING */
230
231 #define CCS_ALLOC(ccs, amount) doNothing()
232  
233 #endif /* PROFILING */
234
235 #endif /* RTS_PROF_CCS_H */
236