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