3 * File name: ir/ir/stat_dmp.c
4 * Purpose: Statistics for Firm.
8 * Copyright: (c) 2004 Universität Karlsruhe
9 * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
18 * names of the optimizations
20 static const char *opt_names[] = {
21 "straightening optimization",
23 "constant evaluation",
24 "algebraic simplification",
26 "Write-After-Write optimization",
27 "Write-After-Read optimization",
28 "Read-After-Write optimization",
29 "Read-After-Read optimization",
30 "Read-a-Const optimization",
33 "Common subexpression elimination",
35 "Architecture dependant optimization",
36 "Reassociation optimization",
37 "Polymorphic call optimization",
38 "an if conversion was tried",
42 static const char *if_conv_names[] = {
44 "if conv side effect ",
45 "if conv Phi node found ",
46 "if conv to deep DAG's ",
47 "if conv bad control flow ",
51 * dumps a opcode hash into human readable form
53 static void simple_dump_opcode_hash(dumper_t *dmp, pset *set)
64 fprintf(dmp->f, "%-16s %-8s %-8s %-8s\n", "Opcode", "alive", "created", "->Id");
65 for (entry = pset_first(set); entry; entry = pset_next(set)) {
66 fprintf(dmp->f, "%-16s %8u %8u %8u\n",
67 get_id_str(entry->op->name), entry->cnt_alive.cnt[0], entry->new_node.cnt[0], entry->into_Id.cnt[0]);
69 cnt_add(&f_alive, &entry->cnt_alive);
70 cnt_add(&f_new_node, &entry->new_node);
71 cnt_add(&f_Id, &entry->into_Id);
73 fprintf(dmp->f, "-------------------------------------------\n");
74 fprintf(dmp->f, "%-16s %8u %8u %8u\n", "Sum",
81 * dumps an optimization hash into human readable form
83 static void simple_dump_opt_hash(dumper_t *dmp, pset *set, int index)
85 opt_entry_t *entry = pset_first(set);
88 fprintf(dmp->f, "\n%s:\n", opt_names[index]);
89 fprintf(dmp->f, "%-16s %-8s\n", "Opcode", "deref");
91 for (; entry; entry = pset_next(set)) {
92 fprintf(dmp->f, "%-16s %8u\n",
93 get_id_str(entry->op->name), entry->count.cnt[0]);
99 * dumps the number of real_function_call optimization
101 static void simple_dump_real_func_calls(dumper_t *dmp, counter_t *cnt)
103 if (! cnt_eq(cnt, 0)) {
104 fprintf(dmp->f, "\nReal Function Calls optimized:\n");
105 fprintf(dmp->f, "%-16s %8u\n",
106 "Call", cnt->cnt[0]);
111 * dumps the number of tail_recursion optimization
113 static void simple_dump_tail_recursion(dumper_t *dmp, unsigned num_tail_recursion)
115 if (num_tail_recursion > 0) {
116 fprintf(dmp->f, "\nTail recursion optimized:\n");
117 fprintf(dmp->f, "%-16s %8u\n", "Call", num_tail_recursion);
122 * dumps the edges count
124 static void simple_dump_edges(dumper_t *dmp, counter_t *cnt)
126 fprintf(dmp->f, "%-16s %8d\n", "Edges", cnt->cnt[0]);
132 static void simple_dump_graph(dumper_t *dmp, graph_entry_t *entry)
134 int i, dump_opts = 1;
135 block_entry_t *b_entry;
138 ir_graph *const_irg = get_const_code_irg();
140 if (entry->irg == const_irg) {
141 fprintf(dmp->f, "\nConst code Irg %p", (void *)entry->irg);
145 fprintf(dmp->f, "\nEntity %s, Irg %p", get_entity_ld_name(entry->ent), (void *)entry->irg);
147 fprintf(dmp->f, "\nIrg %p", (void *)entry->irg);
150 fprintf(dmp->f, " %swalked %u over blocks %u:\n"
151 " was inlined : %u\n"
152 " got inlined : %u\n"
153 " strength red : %u\n"
154 " leaf function : %s\n"
155 " calls only leaf functions : %s\n"
159 " indirect calls : %u\n",
160 entry->is_deleted ? "DELETED " : "",
161 entry->cnt_walked.cnt[0], entry->cnt_walked_blocks.cnt[0],
162 entry->cnt_was_inlined.cnt[0],
163 entry->cnt_got_inlined.cnt[0],
164 entry->cnt_strength_red.cnt[0],
165 entry->is_leaf ? "YES" : "NO",
166 entry->is_leaf_call == LCS_NON_LEAF_CALL ? "NO" : (entry->is_leaf_call == LCS_LEAF_CALL ? "Yes" : "Maybe"),
167 entry->is_recursive ? "YES" : "NO",
168 entry->is_chain_call ? "YES" : "NO",
169 entry->cnt_all_calls.cnt[0],
170 entry->cnt_indirect_calls.cnt[0]
173 for (i = 0; i < sizeof(entry->cnt_if_conv)/sizeof(entry->cnt_if_conv[0]); ++i) {
174 fprintf(dmp->f, " %s : %u\n", if_conv_names[i], entry->cnt_if_conv[i].cnt[0]);
179 fprintf(dmp->f, "\nGlobals counts:\n");
180 fprintf(dmp->f, "--------------\n");
184 simple_dump_opcode_hash(dmp, entry->opcode_hash);
185 simple_dump_edges(dmp, &entry->cnt_edges);
187 /* effects of optimizations */
191 simple_dump_real_func_calls(dmp, &entry->cnt_real_func_call);
192 simple_dump_tail_recursion(dmp, entry->num_tail_recursion);
194 for (i = 0; i < sizeof(entry->opt_hash)/sizeof(entry->opt_hash[0]); ++i) {
195 simple_dump_opt_hash(dmp, entry->opt_hash[i], i);
198 /* dump block info */
199 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Block Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
200 for (b_entry = pset_first(entry->block_hash);
202 b_entry = pset_next(entry->block_hash)) {
203 fprintf(dmp->f, "BLK %12ld %12u %12u %12u %12u %12u %4.8f\n",
205 b_entry->cnt_nodes.cnt[0],
206 b_entry->cnt_edges.cnt[0],
207 b_entry->cnt_in_edges.cnt[0],
208 b_entry->cnt_out_edges.cnt[0],
209 b_entry->cnt_phi_data.cnt[0],
210 (double)b_entry->cnt_edges.cnt[0] / (double)b_entry->cnt_nodes.cnt[0]
217 * initialize the simple dumper
219 static void simple_init(dumper_t *dmp, const char *name)
223 snprintf(fname, sizeof(fname), "%s.txt", name);
224 dmp->f = fopen(fname, "w");
228 * finishes the simple dumper
230 static void simple_finish(dumper_t *dmp)
237 * the simple human readable dumper
239 const dumper_t simple_dumper = {
248 /* ---------------------------------------------------------------------- */
251 * count the nodes as needed:
253 * 1 normal (data) Phi's
258 static void csv_count_nodes(dumper_t *dmp, graph_entry_t *graph, counter_t cnt[])
263 for (i = 0; i < 4; ++i)
266 for (entry = pset_first(graph->opcode_hash); entry; entry = pset_next(graph->opcode_hash)) {
267 if (entry->op == op_Phi) {
269 cnt_add(&cnt[1], &entry->cnt_alive);
271 else if (entry->op == dmp->status->op_PhiM) {
273 cnt_add(&cnt[2], &entry->cnt_alive);
275 else if (entry->op == op_Proj) {
277 cnt_add(&cnt[3], &entry->cnt_alive);
280 /* all other nodes */
281 cnt_add(&cnt[0], &entry->cnt_alive);
289 static void csv_dump_graph(dumper_t *dmp, graph_entry_t *entry)
295 if (entry->irg && !entry->is_deleted) {
296 ir_graph *const_irg = get_const_code_irg();
298 if (entry->irg == const_irg) {
299 name = "<Const code Irg>";
304 name = get_entity_name(entry->ent);
306 name = "<UNKNOWN IRG>";
309 csv_count_nodes(dmp, entry, cnt);
311 fprintf(dmp->f, "%-40s, %p, %d, %d, %d, %d\n",
323 * initialize the simple dumper
325 static void csv_init(dumper_t *dmp, const char *name)
329 snprintf(fname, sizeof(fname), "%s.csv", name);
330 dmp->f = fopen(fname, "a");
334 * finishes the simple dumper
336 static void csv_finish(dumper_t *dmp)
343 * the simple human readable dumper
345 const dumper_t csv_dumper = {