used enum
[libfirm] / ir / be / phistat.c
1 #include <stdio.h>
2 #include <string.h>
3
4 #include "config.h"
5
6 #include "irgraph.h"
7 #include "irnode.h"
8 #include "irgwalk.h"
9 #include "irop.h"
10 #include "irprog.h"
11 #include "irmode_t.h"
12 #include "bephicongr_t.h"
13
14
15 #define SUMMARY_FILE_NAME "all.phi"
16
17 #define ARG_CNT_MAX 10
18 #define PHI_CLS_MAX 10
19
20 enum vals_t {
21         I_PHI_CNT   = 0,
22         I_BLK_CNT,
23         I_SPACE3,
24         I_ARG_CNT_S,
25         I_ARG_CNT_E = I_ARG_CNT_S+ARG_CNT_MAX,
26         I_SPACE1,
27         I_PHI_CLS_S,
28         I_PHI_CLS_E = I_PHI_CLS_S+PHI_CLS_MAX,
29         I_SPACE2,
30         I_INTERFP,          /* number of interfering pairs */
31         I_INTERFV,          /* number of interfering values */
32         I_PHICLSCNT,        /* number of phi classes */
33         I_INTERFPHI,        /* number of phi classes which have interfering vals */
34         I_CONST,
35         I_PRED,
36         I_GLOB,
37         ASIZE
38 };
39
40 static int curr_vals[ASIZE];
41
42
43 static void phi_stat_walker(ir_node *node, void *env) {
44         int count, i, size;
45
46         /* count all block nodes */
47         if (is_Block(node))
48                 curr_vals[I_BLK_CNT]++;
49
50         if (!(is_Phi(node) && mode_is_datab(get_irn_mode(node)))) return;
51
52         /* count all phi nodes */
53         curr_vals[I_PHI_CNT]++;
54
55         /* argument count */
56         count = get_irn_arity(node);
57         if (count > ARG_CNT_MAX)
58                 curr_vals[I_ARG_CNT_E]++;
59         else
60                 curr_vals[I_ARG_CNT_S + count]++;
61
62         /* type of argument */
63         for (i = 0; i < count; i++) {
64         ir_node *block_of_arg, *block_ith_pred;
65                 ir_node *arg = get_irn_n(node, i);
66
67                 if (iro_Const == get_irn_opcode(arg)) {
68                         curr_vals[I_CONST]++;
69                         continue;
70                 }
71
72                 block_of_arg = get_nodes_block(arg);
73                 block_ith_pred = get_nodes_block(get_irn_n(get_nodes_block(node), i));
74
75                 if (block_of_arg == block_ith_pred) {
76                         curr_vals[I_PRED]++;
77                         continue;
78                 }
79
80                 curr_vals[I_GLOB]++;
81         }
82
83
84         size = get_phi_class_size(node);
85         /* phi class count */
86         if (size > 0)
87                 curr_vals[I_PHICLSCNT]++;
88
89         /* phi class size */
90         if (size > PHI_CLS_MAX)
91                 curr_vals[I_PHI_CLS_E]++;
92         else
93                 curr_vals[I_PHI_CLS_S + size]++;
94
95         /* count of interfering pairs / values */
96         curr_vals[I_INTERFP] += get_irn_phi_info(node)->interf_pairs;
97         curr_vals[I_INTERFV] += get_irn_phi_info(node)->interf_vals;
98         if (get_irn_phi_info(node)->interf_vals > 0)
99                 curr_vals[I_INTERFPHI]++;
100 }
101
102
103 /**
104  * Dump values and some annotations for current irp
105  */
106 static void dump_files(void) {
107         int i, sum1, sum2, sum3, next;
108         FILE *out;
109         char buf[200];
110
111         sum1 = curr_vals[I_CONST] + curr_vals[I_PRED] + curr_vals[I_GLOB];
112         sum2 = 0;
113         for (i = I_ARG_CNT_S; i<=I_ARG_CNT_E; i++)
114                 sum2 += curr_vals[i];
115         sum3 = 0;
116         for (i = I_PHI_CLS_S; i<=I_PHI_CLS_E; i++)
117                 sum3 += curr_vals[i];
118
119         next = sprintf(buf, get_irp_prog_name());
120         sprintf(buf+next, ".phi.stat");
121         out = fopen(buf, "wt");
122
123         fprintf(out, "Phis %i\n", curr_vals[I_PHI_CNT]);
124         fprintf(out, "Blks %i\n", curr_vals[I_BLK_CNT]);
125
126         fprintf(out, "\nArgument counts\n");
127         for (i = I_ARG_CNT_S; i<=I_ARG_CNT_E; i++)
128                 fprintf(out, "%2i %2.4f\n", i-I_ARG_CNT_S, (double) curr_vals[i] / sum2);
129
130         fprintf(out, "\nPhi class sizes\n");
131         for (i = I_PHI_CLS_S; i<=I_PHI_CLS_E; i++)
132                 fprintf(out, "%2i %2.4f\n", i-I_PHI_CLS_S, (double) curr_vals[i] / sum3);
133
134         fprintf(out, "\n");
135         fprintf(out, "Interf Pairs %d\n", curr_vals[I_INTERFP]);
136         fprintf(out, "Interf Values %d\n", curr_vals[I_INTERFV]);
137         fprintf(out, "PhiCls Count %d\n", curr_vals[I_PHICLSCNT]);
138         fprintf(out, "Interf PhisCl %d\n", curr_vals[I_INTERFPHI]);
139         fprintf(out, "Const %2.2f\n", (double) curr_vals[I_CONST] / sum1);
140         fprintf(out, "Pred %2.2f\n", (double) curr_vals[I_PRED] / sum1);
141         fprintf(out, "Glob %2.2f\n", (double) curr_vals[I_GLOB] / sum1);
142
143         fclose(out);
144 }
145
146
147 /**
148  * Updates the summary file with cumulated values
149  */
150 static void update_all_file(void) {
151     int i;
152         FILE *all;
153         int vals[ASIZE];
154
155         /* read in */
156         all = fopen(SUMMARY_FILE_NAME, "rt");
157     if (all) {
158                 for (i = 0; i<ASIZE; i++)
159                         fscanf(all, "%i\n", &vals[i]);
160             fclose(all);
161         } else {
162                 for (i = 0; i<ASIZE; i++)
163                         vals[i] = 0;
164         }
165
166         /* write out */
167         all = fopen(SUMMARY_FILE_NAME, "wt");
168         for (i = 0; i<ASIZE; i++)
169                 fprintf(all, "%i\n", vals[i]+curr_vals[i]);
170     fclose(all);
171 }
172
173 void do_phi_statistics(void) {
174         int i, n;
175         curr_vals[I_SPACE1] = -1;
176         curr_vals[I_SPACE2] = -1;
177         curr_vals[I_SPACE3] = -1;
178
179         for (i = 0, n = get_irp_n_irgs(); i < n; i++) {
180                 ir_graph *irg = get_irp_irg(i);
181                 irg_walk_graph(irg, phi_stat_walker, NULL, NULL);
182                 curr_vals[I_BLK_CNT] -= 2;
183         }
184
185         dump_files();
186         update_all_file();
187 }