irgmod: Pass the new inputs to turn_into_tuple() instead of initialising them with...
[libfirm] / ir / stat / firmstat_t.h
1 /*
2  * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
3  *
4  * This file is part of libFirm.
5  *
6  * This file may be distributed and/or modified under the terms of the
7  * GNU General Public License version 2 as published by the Free Software
8  * Foundation and appearing in the file LICENSE.GPL included in the
9  * packaging of this file.
10  *
11  * Licensees holding valid libFirm Professional Edition licenses may use
12  * this file in accordance with the libFirm Commercial License.
13  * Agreement provided with the Software.
14  *
15  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE.
18  */
19
20 /**
21  * @file
22  * @brief   Statistics for Firm. Internal data structures.
23  * @author  Michael Beck
24  */
25 #ifndef FIRM_STAT_FIRMSTAT_T_H
26 #define FIRM_STAT_FIRMSTAT_T_H
27
28 #include "firmstat.h"
29
30 #include "irop_t.h"
31 #include "irnode_t.h"
32 #include "irgraph_t.h"
33 #include "pset.h"
34 #include "pdeq.h"
35 #include "irprog.h"
36 #include "irgwalk.h"
37 #include "counter.h"
38 #include "irhooks.h"
39
40 /*
41  * just be make some things clear :-), the
42  * poor man "generics"
43  */
44 #define HASH_MAP(type) hmap_##type
45
46 typedef pset hmap_node_entry_t;
47 typedef pset hmap_graph_entry_t;
48 typedef pset hmap_opt_entry_t;
49 typedef pset hmap_block_entry_t;
50 typedef pset hmap_be_block_entry_t;
51 typedef pset hmap_reg_pressure_entry_t;
52 typedef pset hmap_perm_stat_entry_t;
53 typedef pset hmap_perm_class_entry_t;
54 typedef pset hmap_ir_op;
55 typedef pset hmap_distrib_entry_t;
56
57 /**
58  * Statistic options, can be or'ed.
59  */
60 enum firmstat_options_t {
61         FIRMSTAT_ENABLED         = 0x00000001,    /**< enable statistics */
62         FIRMSTAT_PATTERN_ENABLED = 0x00000002,    /**< enable pattern calculation */
63         FIRMSTAT_COUNT_STRONG_OP = 0x00000004,    /**< if set, count Mul/Div/Mod by constant */
64         FIRMSTAT_COUNT_DAG       = 0x00000008,    /**< if set, count DAG statistics */
65         FIRMSTAT_COUNT_DELETED   = 0x00000010,    /**< if set, count deleted graphs */
66         FIRMSTAT_COUNT_SELS      = 0x00000020,    /**< if set, count Sel(Sel(..)) differently */
67         FIRMSTAT_COUNT_CONSTS    = 0x00000040,    /**< if set, count Const statistics */
68         FIRMSTAT_CSV_OUTPUT      = 0x10000000     /**< CSV output of some mini-statistic */
69 };
70
71 /**
72  * Additional flags for statistics.
73  */
74 enum firmstat_optimizations_t {
75         FS_OPT_NEUTRAL_0  = HOOK_OPT_LAST,        /**< a op 0 = 0 op a = a */
76         FS_OPT_NEUTRAL_1,                         /**< a op 1 = 1 op a = a */
77         FS_OPT_ADD_A_A,                           /**< a + a = a * 2 */
78         FS_OPT_ADD_A_MINUS_B,                     /**< a + -b = a - b */
79         FS_OPT_ADD_SUB,                           /**< (a + x) - x = (a - x) + x */
80         FS_OPT_ADD_MUL_A_X_A,                     /**< a * x + a = a * (x + 1) */
81         FS_OPT_SUB_0_A,                           /**< 0 - a = -a */
82         FS_OPT_MINUS_SUB,                         /**< - (a - b) = b - a */
83         FS_OPT_SUB_MINUS,                         /**< a - (-b) = a + b */
84         FS_OPT_SUB_MUL_A_X_A,                     /**< a * x - a = a * (x - 1) */
85         FS_OPT_SUB_SUB_X_Y_Z,                     /**< (x - y) - z = x - (y + z) */
86         FS_OPT_SUB_C_NOT_X,                       /**< c - ~a = a + (c+1) */
87         FS_OPT_SUB_TO_ADD,                        /**< (-a) - b = -(a + b), a - (b - c) = a + (c - b), a - (b * C) -> a + (b * -C) */
88         FS_OPT_SUB_TO_NOT,                        /**< -1 - x -> ~x on two's complement */
89         FS_OPT_SUB_TO_CONV,                       /**< a - NULL = (int)a */
90         FS_OPT_MUL_MINUS,                         /**< (-a) * (b - c) -> a * (c - b) */
91         FS_OPT_MUL_MINUS_1,                       /**< a * -1 = -a */
92         FS_OPT_MINUS_MUL_C,                       /**< (-a) * C = a * (-C) */
93         FS_OPT_MUL_MINUS_MINUS,                   /**< (-a) * (-b) = a * b */
94         FS_OPT_OR,                                /**< a | a = a | 0 = 0 | a = a */
95         FS_OPT_AND,                               /**< a & 0b1...1 = 0b1...1 & a =  a & a = a */
96         FS_OPT_TO_EOR,                            /**< (a|b) & ~(a&b) = a^b */
97         FS_OPT_EOR_A_A,                           /**< a ^ a = 0 */
98         FS_OPT_EOR_A_B_A,                         /**< (a ^ b) ^ a = b */
99         FS_OPT_EOR_TO_NOT_BOOL,                   /**< bool ^ 1 = !bool */
100         FS_OPT_EOR_TO_NOT,                        /**< x ^ 0b1..1 = ~x, (a ^ b) & b -> ~a & b */
101         FS_OPT_NOT_CMP,                           /**< !(a cmp b) = a !cmp b */
102         FS_OPT_OR_SHFT_TO_ROTL,                   /**< (x << c) | (x >> (bits - c)) == Rotl(x, c) */
103         FS_OPT_REASSOC_SHIFT,                     /**< (x SHF c1) SHF c2 = x SHF (c1+c2) */
104         FS_OPT_SHIFT_AND,                         /**< (a SHF c) AND (b SHF c) = (a AND b) SHF c */
105         FS_OPT_SHIFT_OR,                          /**< (a SHF c) OR (b SHF c) = (a OR b) SHF c */
106         FS_OPT_SHIFT_EOR,                         /**< (a SHF c) XOR (b SHF c) = (a XOR b) SHF c */
107         FS_OPT_CONV,                              /**< a Conv could be removed */
108         FS_OPT_MIN_MAX_EQ,                        /**< Min(a,a) = Max(a,a) = a */
109         FS_OPT_MUX_COMBINE,                       /**< two Mux nodes where combined into one */
110         FS_OPT_MUX_CONV,                          /**< MuxI(sel, 1, 0) = (I)sel */
111         FS_OPT_MUX_BOOL,                          /**< Muxb(sel, true, false) = sel */
112         FS_OPT_MUX_NOT_BOOL,                      /**< Muxb(sel, false, true) = Not(sel) */
113         FS_OPT_MUX_OR_BOOL,                       /**< Muxb(sel, true, x) = Or(sel, x) */
114         FS_OPT_MUX_ORNOT_BOOL,                    /**< Muxb(sel, x, true) = Or(Not(sel), x) */
115         FS_OPT_MUX_AND_BOOL,                      /**< Muxb(sel, x, false) = And(sel, x) */
116         FS_OPT_MUX_ANDNOT_BOOL,                   /**< Muxb(sel, false, x) = And(Not(sel), x) */
117         FS_OPT_MUX_C,                             /**< Mux(C, f, t) = C ? t : f */
118         FS_OPT_MUX_EQ,                            /**< Mux(v, x, x) = x */
119         FS_OPT_MUX_TRANSFORM,                     /**< Mux(t ==/!= f, t, f) = f/t, Mux(t ==/!= 0, -t, t) = -t/t */
120         FS_OPT_MUX_TO_MIN,                        /**< Mux(a < b, a, b) = Min(a,b) */
121         FS_OPT_MUX_TO_MAX,                        /**< Mux(a > b, a, b) = Max(a,b) */
122         FS_OPT_MUX_TO_BITOP,                      /**< Mux((a & 2^x) ==/!= 0, 2^x, 0) = (a & 2^x) (xor 2^x) */
123         FS_OPT_INVOLUTION,                        /**< OP(OP(x)) = x */
124         FS_OPT_MINUS_NOT,                         /**< -(~x) = x + 1 */
125         FS_OPT_NOT_MINUS_1,                       /**< ~(x - 1) = -x */
126         FS_OPT_NOT_PLUS_1,                        /**< ~x + 1 = -x */
127         FS_OPT_ADD_X_NOT_X,                       /**< ~x + x = -1 */
128         FS_OPT_FP_INV_MUL,                        /**< x / y = x * (1.0/y) */
129         FS_OPT_CONST_PHI,                         /**< Constant evaluation on Phi */
130         FS_OPT_PREDICATE,                         /**< Predicate optimization */
131         FS_OPT_DEMORGAN,                          /**< optimization using DeMorgan's law */
132         FS_OPT_CMP_OP_OP,                         /**< CMP optimization: Cmp(OP(x), OP(y)) = Cmp(x, y) */
133         FS_OPT_CMP_OP_C,                          /**< CMP optimization: Cmp(OP(x), c1) = Cmp(x, c2) */
134         FS_OPT_CMP_CONV_CONV,                     /**< CMP optimization: Cmp(Conv(x), Conv(y)) = Cmp(x, y) */
135         FS_OPT_CMP_CONV,                          /**< CMP optimization: Cmp(Conv(x), Conv(y)) = Cmp(Conv(x), y) */
136         FS_OPT_CMP_TO_BOOL,                       /**< CMP optimization: Cmp(x, y) = BoolOP(x, y) */
137         FS_OPT_CMP_CNST_MAGN,                     /**< CMP optimization: reduced magnitude of a const */
138         FS_OPT_CMP_SHF_TO_AND,                    /**< CMP optimization: transformed shift into And */
139         FS_OPT_CMP_MOD_TO_AND,                    /**< CMP optimization: transformed Mod into And */
140         FS_OPT_NOP,                               /**< the operation is a NOP */
141         FS_OPT_GVN_FOLLOWER,                      /**< GVN-PRE: replaced a follower */
142         FS_OPT_GVN_FULLY,                         /**< GVN-PRE: replaced by fully redundant value */
143         FS_OPT_GVN_PARTLY,                        /**< GVN-PRE: replaced by partly redundant value */
144         FS_OPT_COMBO_CONST,                       /**< Combo: evaluated into Constant */
145         FS_OPT_COMBO_CF,                          /**< Combo: removed conditional control flow */
146         FS_OPT_COMBO_FOLLOWER,                    /**< Combo: replaced a follower */
147         FS_OPT_COMBO_CONGRUENT,                   /**< Combo: replaced by congruent */
148         FS_OPT_JUMPTHREADING,                     /**< Jump threading: removed conditional control flow */
149         FS_OPT_RTS_ABS,                           /**< RTS optimization: call to abs() replaced */
150         FS_OPT_RTS_ALLOCA,                        /**< RTS optimization: call to alloca() replaced */
151         FS_OPT_RTS_SQRT,                          /**< RTS optimization: call to sqrt() replaced */
152         FS_OPT_RTS_CBRT,                          /**< RTS optimization: call to cbrt() replaced */
153         FS_OPT_RTS_POW,                           /**< RTS optimization: call to pow() replaced */
154         FS_OPT_RTS_EXP,                           /**< RTS optimization: call to exp() replaced */
155         FS_OPT_RTS_LOG,                           /**< RTS optimization: call to log() replaced */
156         FS_OPT_RTS_SIN,                           /**< RTS optimization: call to sin() replaced */
157         FS_OPT_RTS_COS,                           /**< RTS optimization: call to cos() replaced */
158         FS_OPT_RTS_TAN,                           /**< RTS optimization: call to tan() replaced */
159         FS_OPT_RTS_ASIN,                          /**< RTS optimization: call to asin() replaced */
160         FS_OPT_RTS_ACOS,                          /**< RTS optimization: call to acos() replaced */
161         FS_OPT_RTS_ATAN,                          /**< RTS optimization: call to atan() replaced */
162         FS_OPT_RTS_SINH,                          /**< RTS optimization: call to sinh() replaced */
163         FS_OPT_RTS_COSH,                          /**< RTS optimization: call to cosh() replaced */
164         FS_OPT_RTS_TANH,                          /**< RTS optimization: call to tanh() replaced */
165         FS_OPT_RTS_SYMMETRIC,                     /**< RTS optimization: call to symmetric function f(-x) replaced by f(x) */
166         FS_OPT_RTS_STRCMP,                        /**< RTS optimization: call to strcmp() replaced */
167         FS_OPT_RTS_STRNCMP,                       /**< RTS optimization: call to strncmp() replaced */
168         FS_OPT_RTS_STRCPY,                        /**< RTS optimization: call to strcpy() replaced */
169         FS_OPT_RTS_STRLEN,                        /**< RTS optimization: call to strlen() replaced */
170         FS_OPT_RTS_MEMCPY,                        /**< RTS optimization: call to memcpy() replaced */
171         FS_OPT_RTS_MEMPCPY,                       /**< RTS optimization: call to mempcpy() replaced */
172         FS_OPT_RTS_MEMMOVE,                       /**< RTS optimization: call to memmove() replaced */
173         FS_OPT_RTS_MEMSET,                        /**< RTS optimization: call to memset() replaced */
174         FS_OPT_RTS_MEMCMP,                        /**< RTS optimization: call to memcmp() replaced */
175         FS_BE_IA32_LEA,                           /**< Lea was created */
176         FS_BE_IA32_LOAD_LEA,                      /**< Load merged with a Lea */
177         FS_BE_IA32_STORE_LEA,                     /**< Store merged with a Lea */
178         FS_BE_IA32_AM_S,                          /**< Source address mode node created */
179         FS_BE_IA32_AM_D,                          /**< Destination address mode node created */
180         FS_BE_IA32_CJMP,                          /**< CJmp created to save a cmp/test */
181         FS_BE_IA32_2ADDRCPY,                      /**< Copy created due to 2-Addresscode constraints */
182         FS_BE_IA32_SPILL2ST,                      /**< Created Store for a Spill */
183         FS_BE_IA32_RELOAD2LD,                     /**< Created Load for a Reload */
184         FS_BE_IA32_SUB2NEGADD,                    /**< Created Neg-Add for a Sub due to 2-Addresscode constraints */
185         FS_BE_IA32_LEA2ADD,                       /**< Transformed Lea back into Add */
186         FS_OPT_MAX
187 };
188
189 /**
190  * An entry in a distribution table
191  */
192 typedef struct distrib_entry_t {
193         counter_t   cnt;      /**< the current count */
194         const void *object;   /**< the object which is counted */
195 } distrib_entry_t;
196
197 /** The type of the hash function for objects in distribution tables. */
198 typedef unsigned (*distrib_hash_fun)(const void *object);
199
200 /**
201  * The distribution table.
202  */
203 typedef struct distrib_tbl_t {
204         struct obstack            cnts;       /**< obstack containing the distrib_entry_t entries */
205         HASH_MAP(distrib_entry_t) *hash_map;  /**< the hash map containing the distribution */
206         distrib_hash_fun          hash_func;  /**< the hash function for object in this distribution */
207         unsigned                  int_dist;   /**< non-zero, if it's a integer distribution */
208 } distrib_tbl_t;
209
210 /**
211  * possible address marker values
212  */
213 enum adr_marker_t {
214         MARK_ADDRESS_CALC     = 1,    /**< the node is an address expression */
215         MARK_REF_ADR          = 2,    /**< the node is referenced by an address expression */
216         MARK_REF_NON_ADR      = 4,    /**< the node is referenced by a non-address expression */
217 };
218
219 /**
220  * An entry in the address_mark set
221  */
222 typedef struct address_mark_entry_t {
223   ir_node  *node;               /**< the node which this entry belongs to, needed for compare */
224   unsigned mark;                /**< the mark, a bitmask of enum adr_marker_t */
225 } address_mark_entry_t;
226
227 /**
228  * An entry for ir_nodes, used in ir_graph statistics.
229  */
230 typedef struct node_entry_t {
231         counter_t   cnt_alive;    /**< amount of nodes in this entry */
232         counter_t   new_node;     /**< amount of new nodes for this entry */
233         counter_t   into_Id;      /**< amount of nodes that turned into Id's for this entry */
234         counter_t   normalized;   /**< amount of nodes that normalized for this entry */
235         const ir_op *op;          /**< the op for this entry */
236 } node_entry_t;
237
238 enum leaf_call_state_t {
239         LCS_UNKNOWN       = 0,      /**< state is unknown yet */
240         LCS_LEAF_CALL     = 1,      /**< only leaf functions will be called */
241         LCS_NON_LEAF_CALL = 2,      /**< at least one non-leaf function will be called or indetermined */
242 };
243
244 /**
245  * Graph counter indexes. The first one are accumulated once, the other are always deleted before an
246  * snapshot is taken.
247  */
248 enum graph_counter_names {
249         gcnt_acc_walked,               /**< walker walked over the graph, accumulated */
250         gcnt_acc_walked_blocks,        /**< walker walked over the graph blocks, accumulated */
251         gcnt_acc_was_inlined,          /**< number of times other graph were inlined, accumulated */
252         gcnt_acc_got_inlined,          /**< number of times this graph was inlined, accumulated */
253         gcnt_acc_strength_red,         /**< number of times strength reduction was successful on this graph, accumulated */
254         gcnt_acc_real_func_call,       /**< number real function call optimization, accumulated */
255
256         /* --- non-accumulated values from here */
257         _gcnt_non_acc,                 /**< first non-accumulated counter */
258
259         gcnt_edges = _gcnt_non_acc,    /**< number of DF edges in this graph */
260         gcnt_all_calls,                /**< number of all calls */
261         gcnt_call_with_cnst_arg,       /**< number of calls with const args */
262         gcnt_call_with_all_cnst_arg,   /**< number of calls with all const args */
263         gcnt_call_with_local_adr,      /**< number of calls with address of local var args */
264         gcnt_indirect_calls,           /**< number of indirect calls */
265         gcnt_external_calls,           /**< number of external calls */
266         gcnt_pure_adr_ops,             /**< number of pure address operation */
267         gcnt_all_adr_ops,              /**< number of all address operation */
268         gcnt_global_adr,               /**< number of global load/store addresses. */
269         gcnt_local_adr,                /**< number of local load/store addresses. */
270         gcnt_param_adr,                /**< number of parameter load/store addresses. */
271         gcnt_this_adr,                 /**< number of this load/store addresses. */
272         gcnt_other_adr,                /**< number of other load/store addresses. */
273         gcnt_if_conv,                  /**< number of if conversions */
274
275         /* --- must be the last enum constant --- */
276         _gcnt_last = gcnt_if_conv + IF_RESULT_LAST                 /**< number of counters */
277 };
278
279 /**
280  * An entry for ir_graphs. These numbers are calculated for every IR graph.
281  */
282 typedef struct graph_entry_t {
283         struct obstack             recalc_cnts;                  /**< obstack containing the counters that are recalculated */
284         HASH_MAP(node_entry_t)     *opcode_hash;                 /**< hash map containing the opcode counter */
285         HASH_MAP(block_entry_t)    *block_hash;                  /**< hash map containing the block counter */
286         HASH_MAP(be_block_entry_t) *be_block_hash;               /**< hash map containing backend block information */
287         counter_t                  cnt[_gcnt_last];               /**< counter */
288         unsigned                   num_tail_recursion;           /**< number of tail recursion optimizations */
289         HASH_MAP(opt_entry_t)      *opt_hash[FS_OPT_MAX];        /**< hash maps containing opcode counter for optimizations */
290         ir_graph                   *irg;                         /**< the graph of this object */
291         ir_entity                  *ent;                         /**< the entity of this graph if one exists */
292         set                        *address_mark;                /**< a set containing the address marks of the nodes */
293         unsigned                   is_deleted:1;                 /**< set if this irg was deleted */
294         unsigned                   is_leaf:1;                    /**< set, if this irg is a leaf function */
295         unsigned                   is_leaf_call:2;               /**< set, if this irg calls only leaf functions */
296         unsigned                   is_recursive:1;               /**< set, if this irg has recursive calls */
297         unsigned                   is_chain_call:1;              /**< set, if this irg is a chain call */
298         unsigned                   is_strict:1;                  /**< set, if this irg represents a strict program */
299         unsigned                   is_analyzed:1;                /**< helper: set, if this irg was already analysed */
300 } graph_entry_t;
301
302 /**
303  * An entry for optimized ir_nodes
304  */
305 typedef struct opt_entry_t {
306         counter_t   count;    /**< optimization counter */
307         const ir_op *op;      /**< the op for this entry */
308 } opt_entry_t;
309
310 /**
311  * An entry for register pressure.
312  */
313 typedef struct reg_pressure_entry_t {
314         const char *class_name; /**< name of the register class */
315         int         pressure;   /**< the register pressure for this class */
316 } reg_pressure_entry_t;
317
318 /**
319  * An entry for permutation statistics.
320  */
321 typedef struct perm_stat_entry_t {
322         ir_node       *perm;       /**< the perm node */
323         int            size;       /**< complete size */
324         int            real_size;  /**< number of pairs with different registers */
325         int            n_copies;   /**< number of copies created for lowering */
326         int            n_exchg;    /**< number of exchanges created for lowering */
327         distrib_tbl_t *cycles;     /**< distribution of cycle lengths */
328         distrib_tbl_t *chains;     /**< distribution of chain lengths */
329 } perm_stat_entry_t;
330
331 /**
332  * An entry for permutation statistics per class.
333  */
334 typedef struct perm_class_entry_t {
335         const char                  *class_name; /**< name of the register class */
336         int                          n_regs;     /**< number of register in this class */
337         HASH_MAP(perm_stat_entry_t) *perm_stat;  /**< statistics about all perm nodes of this class */
338 } perm_class_entry_t;
339
340 /**
341  * An entry for a block or extended block in a ir-graph
342  */
343 typedef struct be_block_entry_t {
344         long                           block_nr;         /**< block nr */
345         distrib_tbl_t                  *sched_ready;     /**< distribution of ready nodes per block */
346         /**< the highest register pressures for this block for each register class */
347         HASH_MAP(reg_pressure_entry_t) *reg_pressure;
348         HASH_MAP(perm_class_entry_t)   *perm_class_stat; /**< statistics about perm nodes for each register class */
349 } be_block_entry_t;
350
351 /**
352  * Block counter indexes. The first one are accumulated once, the other are always deleted before an
353  * snapshot is taken.
354  */
355 enum block_counter_names {
356         bcnt_nodes,     /**< the counter of nodes in this block */
357         bcnt_edges,     /**< the counter of edges in this block */
358         bcnt_in_edges,  /**< the counter of edges incoming from other blocks to this block */
359         bcnt_out_edges, /**< the counter of edges outgoing from this block to other blocks */
360         bcnt_phi_data,  /**< the counter of data Phi nodes in this block */
361
362         /* --- must be the last enum constant --- */
363         _bcnt_last      /**< number of counters */
364 };
365
366 /**
367  * An entry for a block or extended block in a ir-graph
368  */
369 typedef struct block_entry_t {
370         counter_t       cnt[_bcnt_last];  /**< counter */
371         long            block_nr;         /**< block nr */
372         unsigned        is_start:1;       /**< set, if it's the Start block. */
373         unsigned        is_end:1;         /**< set, if it's the End block. */
374 } block_entry_t;
375
376 /**
377  * Some potential interesting float values
378  */
379 typedef enum float_classify_t {
380         STAT_FC_0,                /**< the float value 0.0 */
381         STAT_FC_1,                /**< the float value 1.0 */
382         STAT_FC_2,                /**< the float value 2.0 */
383         STAT_FC_0_5,              /**< the float value 0.5 */
384         STAT_FC_POWER_OF_TWO,     /**< another 2^x value */
385         STAT_FC_OTHER,            /**< all other values */
386         STAT_FC_MAX               /**< last value */
387 } float_classify_t;
388
389 /**
390  * constant info
391  */
392 typedef struct constant_info_t {
393         counter_t  int_bits_count[32];  /**< distribution of bit sizes of integer constants */
394         counter_t  floats[STAT_FC_MAX]; /**< floating point constants */
395         counter_t  others;              /**< all other constants */
396 } constant_info_t;
397
398 /** forward */
399 typedef struct dumper_t dumper_t;
400
401 /**
402  * handler for dumping an IRG
403  *
404  * @param dmp   the dumper
405  * @param entry the IR-graph hash map entry
406  */
407 typedef void dump_graph_FUNC(dumper_t *dmp, graph_entry_t *entry);
408
409 /**
410  * handler for dumper a constant info table
411  *
412  * @param dmp   the dumper
413  */
414 typedef void dump_const_table_FUNC(dumper_t *dmp, const constant_info_t *tbl);
415
416 /**
417  * dumps the parameter distribution table
418  */
419 typedef void dump_param_tbl_FUNC(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global);
420
421 /**
422  * dumps the optimizations counter
423  */
424 typedef void dump_opt_cnt_FUNC(dumper_t *dumper, const counter_t *tbl, unsigned len);
425
426 /**
427  * handler for dumper init
428  *
429  * @param dmp   the dumper
430  * @param name  name of the file to dump to
431  */
432 typedef void dump_init_FUNC(dumper_t *dmp, const char *name);
433
434 /**
435  * handler for dumper finish
436  *
437  * @param dmp   the dumper
438  */
439 typedef void dump_finish_FUNC(dumper_t *dmp);
440
441 /**
442  * statistics info
443  */
444 typedef struct statistic_info_t {
445         unsigned                stat_options;        /**< statistic options: field must be first */
446         struct obstack          cnts;                /**< obstack containing the counters that are incremented */
447         struct obstack          be_data;             /**< obstack containing backend statistics data */
448         HASH_MAP(graph_entry_t) *irg_hash;           /**< hash map containing the counter for irgs */
449         HASH_MAP(ir_op)         *ir_op_hash;         /**< hash map containing all ir_ops (accessible by op_codes) */
450         pdeq                    *wait_q;             /**< wait queue for leaf call decision */
451         unsigned                recursive:1;         /**< flag for detecting recursive hook calls */
452         unsigned                in_dead_node_elim:1; /**< flag for dead node elimination runs */
453         ir_op                   *op_Phi0;            /**< pseudo op for Phi0 */
454         ir_op                   *op_PhiM;            /**< pseudo op for memory Phi */
455         ir_op                   *op_ProjM;           /**< pseudo op for memory Proj */
456         ir_op                   *op_MulC;            /**< pseudo op for multiplication by const */
457         ir_op                   *op_DivC;            /**< pseudo op for division by const */
458         ir_op                   *op_ModC;            /**< pseudo op for modulo by const */
459         ir_op                   *op_SelSel;          /**< pseudo op for Sel(Sel) */
460         ir_op                   *op_SelSelSel;       /**< pseudo op for Sel(Sel(Sel)) */
461         dumper_t                *dumper;             /**< list of dumper */
462         int                     reassoc_run;         /**< if set, reassociation is running */
463         constant_info_t         const_info;          /**< statistic info for constants */
464         distrib_tbl_t           *dist_param_cnt;     /**< distribution table for call parameters */
465
466         counter_t               num_opts[FS_OPT_MAX];/**< count optimizations */
467 } stat_info_t;
468
469 /**
470  * a dumper description
471  */
472 struct dumper_t {
473         dump_graph_FUNC       *dump_graph;     /**< handler for dumping an irg */
474         dump_const_table_FUNC *dump_const_tbl; /**< handler for dumping a const table */
475         dump_param_tbl_FUNC   *dump_param_tbl; /**< handler for dumping the Call parameter table */
476         dump_opt_cnt_FUNC     *dump_opt_cnt;   /**< handler for dumping the optimization table. */
477         dump_init_FUNC        *init;           /**< handler for init */
478         dump_finish_FUNC      *finish;         /**< handler for finish */
479         FILE                  *f;             /**< the file to dump to */
480         stat_info_t           *status;        /**< access to the global status */
481         dumper_t              *next;          /**< link to the next dumper */
482         pset                  *func_map;      /**< pset containing all registered functions */
483         unsigned               tag;            /**< the id tag of the dumper */
484 };
485
486 /**
487  * internal init function, mainly registers commandline arguments.
488  * (The use still has to call firm_init_stat() later
489  */
490 void init_stat(void);
491
492 /**
493  * helper: get an ir_op from an opcode
494  */
495 ir_op *stat_get_op_from_opcode(unsigned code);
496
497 /* API for distribution tables */
498
499 /**
500  * creates a new distribution table.
501  *
502  * @param cmp_func   Compare function for objects in the distribution
503  * @param hash_func  Hash function for objects in the distribution
504  */
505 distrib_tbl_t *stat_new_distrib_tbl(pset_cmp_fun cmp_func, distrib_hash_fun hash_func);
506
507 /**
508  * creates a new distribution table for an integer distribution.
509  */
510 distrib_tbl_t *stat_new_int_distrib_tbl(void);
511
512 /**
513  * destroys a distribution table.
514  */
515 void stat_delete_distrib_tbl(distrib_tbl_t *tbl);
516
517 /**
518  * adds a new object count into the distribution table.
519  */
520 void stat_add_distrib_tbl(distrib_tbl_t *tbl, const void *object, const counter_t *cnt);
521
522 /**
523  * adds a new key count into the integer distribution table.
524  */
525 void stat_add_int_distrib_tbl(distrib_tbl_t *tbl, int key, const counter_t *cnt);
526
527 /**
528  * increases object count by one
529  */
530 void stat_inc_distrib_tbl(distrib_tbl_t *tbl, const void *object);
531
532 /**
533  * increases key count by one
534  */
535 void stat_inc_int_distrib_tbl(distrib_tbl_t *tbl, int key);
536
537 /**
538  * inserts a new object with count 0 into the distribution table
539  * if object is already present, nothing happens
540  */
541 void stat_insert_distrib_tbl(distrib_tbl_t *tbl, const void *object);
542
543 /**
544  * inserts a new key with count 0 into the integer distribution table
545  * if key is already present, nothing happens
546  */
547 void stat_insert_int_distrib_tbl(distrib_tbl_t *tbl, int key);
548
549 /**
550  * returns the sum over all counters in a distribution table
551  */
552 int stat_get_count_distrib_tbl(distrib_tbl_t *tbl);
553
554 /**
555  * calculates the mean value of a distribution.
556  */
557 double stat_calc_mean_distrib_tbl(distrib_tbl_t *tbl);
558
559 /**
560  * calculates the average value of a distribution
561  */
562 double stat_calc_avg_distrib_tbl(distrib_tbl_t *tbl);
563
564 /** evaluates each entry of a distribution table. */
565 typedef void (*eval_distrib_entry_fun)(const distrib_entry_t *entry, void *env);
566
567 /**
568  * iterates over all entries in a distribution table
569  */
570 void stat_iterate_distrib_tbl(const distrib_tbl_t *tbl, eval_distrib_entry_fun eval, void *env);
571
572 /**
573  * update info on Consts.
574  *
575  * @param node   The Const node
576  * @param graph  The graph entry containing the call
577  */
578 void stat_update_const(stat_info_t *status, ir_node *node, graph_entry_t *graph);
579
580 /**
581  * clears the const statistics for a new snapshot.
582  */
583 void stat_const_clear(stat_info_t *status);
584
585 /**
586  * initialize the Const statistic.
587  */
588 void stat_init_const_cnt(stat_info_t *status);
589
590 /**
591  * return a human readable name for an float classification
592  */
593 const char *stat_fc_name(float_classify_t classification);
594
595 /**
596  * Update the register pressure of a block
597  *
598  * @param irg        the irg containing the block
599  * @param block      the block for which the reg pressure should be set
600  * @param pressure   the pressure
601  * @param class_name the name of the register class
602  */
603 void stat_be_block_regpressure(ir_graph *irg, ir_node *block, int pressure, const char *class_name);
604
605 /**
606  * Update the distribution of ready nodes of a block
607  *
608  * @param irg        the irg containing the block
609  * @param block      the block for which the reg pressure should be set
610  * @param num_ready  the number of ready nodes
611  */
612 void stat_be_block_sched_ready(ir_graph *irg, ir_node *block, int num_ready);
613
614 /**
615  * Update the permutation statistic of a block
616  *
617  * @param class_name the name of the register class
618  * @param perm       the perm node
619  * @param block      the block containing the perm
620  * @param size       the size of the perm
621  * @param real_size  number of pairs with different registers
622  */
623 void stat_be_block_stat_perm(const char *class_name, int n_regs, ir_node *perm, ir_node *block,
624                              int size, int real_size);
625
626 /**
627  * Update the permutation statistic of a single perm
628  *
629  * @param class_name the name of the register class
630  * @param perm       the perm node
631  * @param block      the block containing the perm
632  * @param is_chain   1 if chain, 0 if cycle
633  * @param size       length of the cycle/chain
634  * @param n_ops      the number of ops representing this cycle/chain after lowering
635  */
636 void stat_be_block_stat_permcycle(const char *class_name, ir_node *perm, ir_node *block,
637                                   int is_chain, int size, int n_ops);
638
639 /**
640  * Register an additional function for all dumper.  This function
641  * is called in dump_snapshot once for each graph_entry and dumper.
642  *
643  * @param func  the dump function to register
644  */
645 void stat_register_dumper_func(dump_graph_FUNC *func);
646
647 #endif /* FIRM_STAT_FIRMSTAT_T_H */