9d5b6e8fd659a593b0dc452623d6c956419a560a
[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 /*
18  * 0  to 10 arg-count of phi funct
19  * 11 to 20 phi-congr-class size
20  * 11 # of const args
21  * 12 # of args defined in cf-pred block
22  * 13 # of args defines elsewhere
23  * 14 size of phi congruence class
24  */
25
26 #define ARG_CNT_MAX 10
27 #define PHI_CLS_MAX 10
28
29 #define I_ARG_CNT_S 0
30 #define I_ARG_CNT_E (I_ARG_CNT_S+ARG_CNT_MAX)
31 #define I_PHI_CLS_S (I_ARG_CNT_E+1)
32 #define I_PHI_CLS_E (I_PHI_CLS_S+PHI_CLS_MAX)
33 #define I_CONST (I_PHI_CLS_E+1)
34 #define I_PRED (I_CONST+1)
35 #define I_GLOB (I_PRED+1)
36 #define ASIZE (I_GLOB+1)
37
38 static int curr_vals[ASIZE];
39
40 static void phi_stat_post_walker(ir_node *node, void *env) {
41         int size;
42         if (!(is_Phi(node) && mode_is_datab(get_irn_mode(node)))) return;
43
44         size = get_phi_class_size(node);
45         if (size > PHI_CLS_MAX)
46                 curr_vals[I_PHI_CLS_E]++;
47         else
48                 curr_vals[I_PHI_CLS_S + size]++;
49 }
50
51 static void phi_stat_walker(ir_node *node, void *env) {
52         int count, i;
53
54         if (!(is_Phi(node) && mode_is_datab(get_irn_mode(node)))) return;
55
56         /* argument count */
57         count = get_irn_arity(node);
58         if (count > ARG_CNT_MAX)
59                 curr_vals[I_ARG_CNT_E]++;
60         else
61                 curr_vals[I_ARG_CNT_S + count]++;
62
63         /* type of argument */
64         for (i = 0; i < count; i++) {
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                 ir_node *block_of_arg = get_nodes_block(arg);
73                 ir_node *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         /* phi congruence class */
84         det_phi_congr_class(node);
85 }
86
87
88 static void dump_files(void) {
89         int i, sum1, sum2, next;
90         FILE *out;
91         char buf[200];
92
93         sum1 = curr_vals[I_CONST] + curr_vals[I_PRED] + curr_vals[I_GLOB];
94         sum2 = 0;
95         for (i = I_ARG_CNT_S; i<=I_ARG_CNT_E; i++)
96                 sum2 += curr_vals[i];
97
98         next = sprintf(buf, get_irp_prog_name());
99         sprintf(buf+next, ".phi.argcount");
100
101         out = fopen(buf, "wt");
102         for (i = I_ARG_CNT_S; i<=I_ARG_CNT_E; i++)
103                 fprintf(out, "%2i %2.2f\n", i, (double) curr_vals[i] / sum2);
104         fclose(out);
105
106         sprintf(buf+next, ".phi.defloc");
107         out = fopen(buf, "wt");
108         fopen(buf, "wt");
109         fprintf(out, "Const %2.2f\n", (double) curr_vals[I_CONST] / sum1);
110         fprintf(out, "Pred %2.2f\n", (double) curr_vals[I_PRED] / sum1);
111         fprintf(out, "Glob %2.2f\n", (double) curr_vals[I_GLOB] / sum1);
112         fclose(out);
113 }
114
115
116 static void update_all_file(void) {
117     int i;
118         FILE *all;
119         int vals[ASIZE];
120
121         /* read in */
122         all = fopen(SUMMARY_FILE_NAME, "rt");
123     if (all) {
124                 for (i = 0; i<ASIZE; i++)
125                         fscanf(all, "%i\n", &vals[i]);
126             fclose(all);
127         } else {
128                 for (i = 0; i<ASIZE; i++)
129                         vals[i] = 0;
130         }
131
132         /* write out */
133         all = fopen(SUMMARY_FILE_NAME, "wt");
134         for (i = 0; i<ASIZE; i++)
135                 fprintf(all, "%i\n", vals[i]+curr_vals[i]);
136     fclose(all);
137 }
138
139 void do_phi_statistics(void) {
140         int i, n;
141
142         for (i = 0, n = get_irp_n_irgs(); i < n; i++) {
143                 ir_graph *irg = get_irp_irg(i);
144                 irg_walk_graph(irg, phi_stat_walker, NULL, NULL);
145                 irg_walk_graph(irg, phi_stat_post_walker, NULL, NULL);
146         }
147
148         dump_files();
149         update_all_file();
150 }