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