Uncommented missing function
[libfirm] / ir / be / phistat.c
1 /**
2  * @author Daniel Grund
3  * @date 09.12.2004
4  */
5
6 #include <stdio.h>
7 #include <string.h>
8 #include <stdlib.h>
9
10 #include "config.h"
11
12 #include "irgraph.h"
13 #include "irnode.h"
14 #include "irgwalk.h"
15 #include "irop.h"
16 #include "irprog.h"
17 #include "irmode_t.h"
18
19 #include "bechordal.h"
20 #include "phistat.h"
21
22 #define MAX_ARITY 10
23 #define MAX_CLS_SIZE 10
24
25 enum vals_t {
26         I_ARG         = 0,
27         I_CONST,
28         I_PRED,
29         I_GLOB,
30
31         I_SPACE1,
32         I_BLOCKS,
33         I_PHIS,
34         I_PHICLS,
35         I_PHICLSI,
36         I_PAIRS,
37         I_PAIRSI,
38         I_VALUES,
39         I_VALUESI,
40
41         I_SPACE2,
42         I_ARITY_S,
43         I_ARITY_E    = I_ARITY_S+MAX_ARITY,
44
45         I_SPACE3,
46         I_CLS_SIZE_S,
47         I_CLS_SIZE_E = I_CLS_SIZE_S+MAX_CLS_SIZE,
48         I_ALL_NODES,
49         ASIZE
50 };
51
52 /**
53  * Holds current values. Values are added till next
54  * phi_stat_reset
55  */
56 static int curr_vals[ASIZE];
57
58
59 /**
60  * Resets the array holding the data
61  */
62 void phi_stat_reset(void) {
63         int i;
64
65         for (i = 0; i < ASIZE; ++i)
66                 curr_vals[i] = 0;
67         curr_vals[I_SPACE1] = -1;
68         curr_vals[I_SPACE2] = -1;
69         curr_vals[I_SPACE3] = -1;
70 }
71
72
73 /**
74  * Collect general data
75  */
76 static void stat_walker(ir_node *node, void *env) {
77         /* count all nodes */
78         curr_vals[I_ALL_NODES]++;
79
80         /* count all block nodes */
81         if (is_Block(node))
82                 curr_vals[I_BLOCKS]++;
83 }
84
85
86 /**
87  * Collect phi node data
88  */
89 static void phi_node_stat(ir_node *node) {
90         int arity, i;
91
92         /* count all phi nodes */
93         curr_vals[I_PHIS]++;
94
95         /* argument count */
96         arity = get_irn_arity(node);
97         curr_vals[I_ARG] += arity;
98         if (arity > MAX_ARITY)
99                 curr_vals[I_ARITY_E]++;
100         else
101                 curr_vals[I_ARITY_S + arity]++;
102
103         /* type of argument {const, pred, glob} */
104         for (i = 0; i < arity; i++) {
105         ir_node *block_of_arg, *block_ith_pred;
106                 ir_node *arg = get_irn_n(node, i);
107
108                 if (iro_Const == get_irn_opcode(arg)) {
109                         curr_vals[I_CONST]++;
110                         continue;
111                 }
112
113                 block_of_arg = get_nodes_block(arg);
114                 block_ith_pred = get_nodes_block(get_irn_n(get_nodes_block(node), i));
115
116                 if (block_of_arg == block_ith_pred) {
117                         curr_vals[I_PRED]++;
118                         continue;
119                 }
120
121                 curr_vals[I_GLOB]++;
122         }
123 }
124
125
126 /**
127  * Collect phi class data
128  */
129 static void phi_class_stat(pset *pc) {
130         int i, o, size, doit, sth_interfered;
131         ir_node **members, *p;
132
133         /* phi class count */
134         curr_vals[I_PHICLS]++;
135
136         /* phi class size */
137         size = pset_count(pc);
138         if (size > MAX_CLS_SIZE)
139                 curr_vals[I_CLS_SIZE_E]++;
140         else
141                 curr_vals[I_CLS_SIZE_S + size]++;
142
143         /* get an array of all members for double iterating */
144         members = (ir_node **) malloc(size * sizeof(ir_node*));
145         for (i=0, p = (ir_node *)pset_first(pc); p; p = (ir_node *)pset_next(pc))
146                 members[i++] = p;
147         assert(i == size);
148
149         /* determine interference of phi class members */
150         curr_vals[I_VALUES] += size;
151         sth_interfered = 0;
152         for (i = 0; i < size-1; ++i) {
153                 doit = 1;
154                 for (o = i+1; o < size; ++o) {
155                         curr_vals[I_PAIRS]++;
156                         if (phi_ops_interfere(members[i], members[o])) {
157                                 sth_interfered = 1;
158                                 curr_vals[I_PAIRSI]++;
159                                 if (doit) {
160                                         curr_vals[I_VALUESI]++;
161                                         doit = 0;
162                                 }
163                         }
164                 }
165         }
166
167         /* Does this phi class have an inner interference? */
168         curr_vals[I_PHICLSI] += sth_interfered;
169
170         free(members);
171 }
172
173
174 /**
175  * Collect all stat data
176  */
177 void phi_stat_collect(ir_graph *irg, pset *all_phi_nodes, pset *all_phi_classes) {
178         ir_node *n;
179         pset *pc;
180
181         irg_walk_graph(irg, stat_walker, NULL, NULL);
182         curr_vals[I_BLOCKS] -= 2;
183
184         for (n = (ir_node *)pset_first(all_phi_nodes); n; n = (ir_node *)pset_next(all_phi_nodes))
185                 phi_node_stat(n);
186
187         for (pc = (pset *)pset_first(all_phi_classes); pc; pc = (pset *)pset_next(all_phi_classes))
188                 phi_class_stat(pc);
189 }
190
191
192 /**
193  * Dump statistic values in raw format
194  */
195 static void dump_file(char *filename, int stat[ASIZE]) {
196         FILE *file;
197         int i;
198
199         if (! (file = fopen(filename, "wt"))) {
200                 fprintf(stderr, "Cannot open file for writing\n");
201                 return;
202         }
203
204         for (i = 0; i < ASIZE; i++) {
205                 if (i >= I_ARITY_S && i <= I_ARITY_E)
206                         fprintf(file, "%i %i\n", stat[i], stat[I_ALL_NODES]);
207                 else
208                         fprintf(file, "%i\n", stat[i]);
209         }
210
211     fclose(file);
212 }
213
214
215 /**
216  * Updates a cumulative file with the current values.
217  */
218 static void update_file(char *filename) {
219     int i;
220         FILE *all;
221         int vals[ASIZE];
222
223         /* read in */
224         all = fopen(filename, "rt");
225
226     if (all) {
227                 for (i = 0; i < ASIZE; i++) {
228                         if (i >= I_ARITY_S && i <= I_ARITY_E)
229                                 fscanf(all, "%i %i\n", &vals[i], &vals[I_ALL_NODES]);
230                         else
231                                 fscanf(all, "%i\n", &vals[i]);
232                 }
233             fclose(all);
234         } else {
235                 for (i = 0; i < ASIZE; i++)
236                         vals[i] = 0;
237         }
238
239         /* add current values */
240         for (i = 0; i < ASIZE; i++)
241                 vals[i] += curr_vals[i];
242
243         /* write out */
244         dump_file(filename, vals);
245 }
246
247
248 /**
249  * Dumps the current contents of the values array to a file.
250  * Updates a cumulative file.
251  */
252 void phi_stat_dump(char *filename, char *cum_filename) {
253         if (filename)
254                 dump_file(filename, curr_vals);
255         if (cum_filename)
256                 update_file(cum_filename);
257 }
258
259
260 /**
261  * Dumps the current contents of the values array
262  * and annotations to a file.
263  */
264 void phi_stat_dump_pretty(char *filename) {
265         int i;
266         FILE *out;
267
268         if (! (out = fopen(filename, "wt"))) {
269                 fprintf(stderr, "Cannot open file for writing\n");
270                 return;
271         }
272
273         fprintf(out, "\nPhi argument types\n");
274         fprintf(out, "Total     %4d\n", curr_vals[I_ARG]);
275         fprintf(out, "Constants %4d\n", curr_vals[I_CONST]);
276         fprintf(out, "CF-Pred   %4d\n", curr_vals[I_PRED]);
277         fprintf(out, "Others    %4d\n", curr_vals[I_GLOB]);
278
279         fprintf(out, "\nPhi class interference\n");
280         fprintf(out, "Blocks         %4d\n", curr_vals[I_BLOCKS]);
281         fprintf(out, "Phis           %4d\n", curr_vals[I_PHIS]);
282         fprintf(out, "Interf classes %4d of %4d\n", curr_vals[I_PHICLSI], curr_vals[I_PHICLS]);
283         fprintf(out, "Interf pairs   %4d of %4d\n", curr_vals[I_PAIRSI], curr_vals[I_PAIRS]);
284         fprintf(out, "Interf values  %4d of %4d\n", curr_vals[I_PAIRSI], curr_vals[I_VALUES]);
285
286         fprintf(out, "\nPhi arity\n");
287         for (i = I_ARITY_S; i<=I_ARITY_E; i++)
288                 fprintf(out, "%2i %4d\n", i-I_ARITY_S, curr_vals[i]);
289
290         fprintf(out, "\nPhi class sizes\n");
291         for (i = I_CLS_SIZE_S; i<=I_CLS_SIZE_E; i++)
292                 fprintf(out, "%2i %4d\n", i-I_CLS_SIZE_S, curr_vals[i]);
293
294         fprintf(out, "\n\nTotal nodes:    %4d\n", curr_vals[I_ALL_NODES]);
295
296         fclose(out);
297 }