Added new arch interface
[libfirm] / ir / be / becopystat.c
1 /**
2  * @author Daniel Grund
3  * @date 19.04.2005
4  */
5 #ifdef HAVE_CONFIG_H
6 #include "config.h"
7 #endif
8
9 #include <string.h>
10 #include "phiclass_t.h"
11 #include "irprog.h"
12 #include "becopyopt.h"
13 #include "becopystat.h"
14 #include "xmalloc.h"
15
16 #ifdef DO_STAT
17
18 static pset *all_phi_nodes;
19 static pset *all_phi_classes;
20 static pset *all_copy_nodes;
21
22 void stat_init(void) {
23         all_phi_nodes = pset_new_ptr_default();
24         all_phi_classes = pset_new_ptr_default();
25         all_copy_nodes = pset_new_ptr_default();
26         phi_class_init();
27 }
28
29 void stat_reset(void) {
30         int i;
31         for (i = 0; i < ASIZE; ++i)
32                 curr_vals[i] = 0;
33 }
34
35 /**
36  * Collect general data
37  */
38 static void stat_walker(ir_node *node, void *env) {
39         curr_vals[I_ALL_NODES]++; /* count all nodes */
40
41         if (is_Block(node)) /* count all blocks */
42                 curr_vals[I_BLOCKS]++;
43
44         if (is_Phi(node)) /* collect phis */
45                 pset_insert_ptr(all_phi_nodes, node);
46
47         if (is_Copy(node))
48                 pset_insert_ptr(all_copy_nodes, node);
49 }
50
51 /**
52  * Collect phi node data
53  */
54 static void stat_phi_node(ir_node *phi) {
55         int arity, i;
56
57         /* count all phi phis */
58         curr_vals[I_PHI_CNT]++;
59
60         /* argument count */
61         arity = get_irn_arity(phi);
62         curr_vals[I_PHI_ARG_CNT] += arity;
63         if (arity > MAX_ARITY)
64                 curr_vals[I_PHI_ARITY_E]++;
65         else
66                 curr_vals[I_PHI_ARITY_S + arity]++;
67
68         /* type of argument {self, const, pred, glob} */
69         for (i = 0; i < arity; i++) {
70         ir_node *block_of_arg, *block_ith_pred;
71                 ir_node *arg = get_irn_n(phi, i);
72
73                 if (arg == phi) {
74                         curr_vals[I_PHI_ARG_SELF]++;
75                         continue;
76                 }
77
78                 curr_vals[I_COPIES_MAX]++; /* if arg!=phi this is a possible copy */
79
80                 if (values_interfere(phi, arg))
81                         curr_vals[I_COPIES_IF]++;
82
83                 if (iro_Const == get_irn_opcode(arg)) {
84                         curr_vals[I_PHI_ARG_CONST]++;
85                         continue;
86                 }
87
88                 block_of_arg = get_nodes_block(arg);
89                 block_ith_pred = get_nodes_block(get_irn_n(get_nodes_block(phi), i));
90                 if (block_of_arg == block_ith_pred) {
91                         curr_vals[I_PHI_ARG_PRED]++;
92                         continue;
93                 }
94
95                 curr_vals[I_PHI_ARG_GLOB]++;
96         }
97 }
98
99 /**
100  * Collect register-constrained node data
101  */
102 //TODO stat_copy_node
103 static void stat_copy_node(ir_node *root) {
104         curr_vals[I_CPY_CNT]++;
105 //      if (values_interfere(root, arg))
106 //              curr_vals[I_COPIES_IF]++;
107 }
108
109 /**
110  * Collect phi class data
111  */
112 static void stat_phi_class(pset *pc) {
113         int i, o, size, if_free;
114         ir_node **members, *p;
115
116         /* phi class count */
117         curr_vals[I_CLS_CNT]++;
118
119         /* phi class size */
120         size = pset_count(pc);
121         if (size > MAX_CLS_SIZE)
122                 curr_vals[I_CLS_SIZE_E]++;
123         else
124                 curr_vals[I_CLS_SIZE_S + size]++;
125
126         /* get an array of all members for double iterating */
127         members = xmalloc(size * sizeof(*members));
128         for (i = 0, p = pset_first(pc); p; p = pset_next(pc))
129                 members[i++] = p;
130         assert(i == size);
131
132         /* determine interference of phi class members */
133         curr_vals[I_CLS_IF_MAX] += size*(size-1)/2;
134         if_free = 1;
135         for (i = 0; i < size-1; ++i)
136                 for (o = i+1; o < size; ++o)
137                         if (values_interfere(members[i], members[o])) {
138                                 if_free = 0;
139                                 curr_vals[I_CLS_IF_CNT]++;
140                         }
141
142         /* Does this phi class have an inner interference? */
143         curr_vals[I_CLS_IF_FREE] += if_free;
144
145         xfree(members);
146 }
147
148 void stat_collect_irg(ir_graph *irg) {
149         ir_node *n;
150         pset *pc;
151
152         irg_walk_graph(irg, stat_walker, NULL, NULL);
153         curr_vals[I_BLOCKS] -= 2; /* substract 2 for start and end block */
154
155         all_phi_classes = phi_class_compute_by_phis(all_phi_nodes);
156
157         for (n = pset_first(all_phi_nodes); n; n = pset_next(all_phi_nodes))
158                 stat_phi_node(n);
159
160         for (n = pset_first(all_copy_nodes); n; n = pset_next(all_copy_nodes))
161                 stat_copy_node(n);
162
163         for (pc = pset_first(all_phi_classes); pc; pc = pset_next(all_phi_classes))
164                 stat_phi_class(pc);
165
166 }
167
168 void stat_dump(ir_graph *irg) {
169         int i;
170         char buf[1024];
171
172         snprintf(buf, sizeof(buf), "%s__%s", get_irp_prog_name(), get_entity_name(get_irg_entity(irg)));
173         FILE *out = ffopen(buf, "stat", "wt");
174
175         fprintf(out, "%s\n", get_irp_prog_name());
176         for (i = 0; i < ASIZE; i++) {
177                 if (i >= I_PHI_ARITY_S && i <= I_PHI_ARITY_E)
178                         fprintf(out, "%i %i\n", curr_vals[i], curr_vals[I_PHI_CNT]);
179                 else if (i >= I_CLS_SIZE_S && i <= I_CLS_SIZE_E)
180                         fprintf(out, "%i %i\n", curr_vals[i], curr_vals[I_CLS_CNT]);
181                 else
182                         fprintf(out, "%i\n", curr_vals[i]);
183         }
184
185     fclose(out);
186 }
187
188 //TODO stat_dump_pretty
189 void stat_dump_pretty(ir_graph *irg) {
190         int i;
191         FILE *out = ffopen(get_entity_name(get_irg_entity(irg)), "pretty", "wt");
192
193         fprintf(out, "\nPhi argument types\n");
194         fprintf(out, "Total     %4d\n", curr_vals[I_PHI_ARG_CNT]);
195         fprintf(out, "Constants %4d\n", curr_vals[I_PHI_ARG_CONST]);
196         fprintf(out, "CF-Pred   %4d\n", curr_vals[I_PHI_ARG_PRED]);
197         fprintf(out, "Others    %4d\n", curr_vals[I_PHI_ARG_GLOB]);
198
199         fprintf(out, "\nPhi class interference\n");
200         fprintf(out, "Blocks         %4d\n", curr_vals[I_BLOCKS]);
201         fprintf(out, "Phis           %4d\n", curr_vals[I_PHI_CNT]);
202
203         fprintf(out, "\nPhi arity\n");
204         for (i = I_PHI_ARITY_S; i<=I_PHI_ARITY_E; i++)
205                 fprintf(out, "%2i %4d\n", i-I_PHI_ARITY_S, curr_vals[i]);
206
207         fprintf(out, "\nPhi class sizes\n");
208         for (i = I_CLS_SIZE_S; i<=I_CLS_SIZE_E; i++)
209                 fprintf(out, "%2i %4d\n", i-I_CLS_SIZE_S, curr_vals[i]);
210
211         fprintf(out, "\n\nTotal nodes:    %4d\n", curr_vals[I_ALL_NODES]);
212
213         fclose(out);
214 }
215
216 #endif