2 * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved.
4 * This file is part of libFirm.
6 * This file may be distributed and/or modified under the terms of the
7 * GNU General Public License version 2 as published by the Free Software
8 * Foundation and appearing in the file LICENSE.GPL included in the
9 * packaging of this file.
11 * Licensees holding valid libFirm Professional Edition licenses may use
12 * this file in accordance with the libFirm Commercial License.
13 * Agreement provided with the Software.
15 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * File name: ir/ir/stat_dmp.c
23 * Purpose: Statistics for Firm.
24 * Author: Michael Beck
27 * Copyright: (c) 2004 Universität Karlsruhe
37 * names of the optimizations
43 { HOOK_OPT_DEAD_BLOCK, "dead block elimination" },
44 { HOOK_OPT_STG, "straightening optimization" },
45 { HOOK_OPT_IFSIM, "if simplification" },
46 { HOOK_OPT_CONST_EVAL, "constant evaluation" },
47 { HOOK_OPT_ALGSIM, "algebraic simplification" },
48 { HOOK_OPT_PHI, "Phi optmization" },
49 { HOOK_OPT_SYNC, "Sync optmization" },
50 { HOOK_OPT_WAW, "Write-After-Write optimization" },
51 { HOOK_OPT_WAR, "Write-After-Read optimization" },
52 { HOOK_OPT_RAW, "Read-After-Write optimization" },
53 { HOOK_OPT_RAR, "Read-After-Read optimization" },
54 { HOOK_OPT_RC, "Read-a-Const optimization" },
55 { HOOK_OPT_TUPLE, "Tuple optimization" },
56 { HOOK_OPT_ID, "ID optimization" },
57 { HOOK_OPT_CSE, "Common subexpression elimination" },
58 { HOOK_OPT_STRENGTH_RED, "Strength reduction" },
59 { HOOK_OPT_ARCH_DEP, "Architecture dependant optimization" },
60 { HOOK_OPT_REASSOC, "Reassociation optimization" },
61 { HOOK_OPT_POLY_CALL, "Polymorphic call optimization" },
62 { HOOK_OPT_IF_CONV, "an if conversion was tried" },
63 { HOOK_OPT_FUNC_CALL, "Real function call optimization" },
64 { HOOK_OPT_CONFIRM, "Confirm-based optimization: replacement" },
65 { HOOK_OPT_CONFIRM_C, "Confirm-based optimization: replaced by const" },
66 { HOOK_OPT_CONFIRM_E, "Confirm-based optimization: evaluated" },
67 { HOOK_OPT_EXC_REM, "a exception edge was removed due to a Confirmation prove" },
68 { HOOK_LOWERED, "Lowered" },
69 { HOOK_BACKEND, "Backend transformation" },
70 { FS_OPT_NEUTRAL_0, "algebraic simplification: a op 0 = 0 op a = a" },
71 { FS_OPT_NEUTRAL_1, "algebraic simplification: a op 1 = 1 op a = a" },
72 { FS_OPT_ADD_A_A, "algebraic simplification: a + a = a * 2" },
73 { FS_OPT_ADD_A_MINUS_B, "algebraic simplification: a + -b = a - b" },
74 { FS_OPT_ADD_SUB, "algebraic simplification: (a + x) - x = (a - x) + x = a" },
75 { FS_OPT_ADD_MUL_A_X_A, "algebraic simplification: a * x + a = a * (x + 1)" },
76 { FS_OPT_SUB_0_A, "algebraic simplification: 0 - a = -a" },
77 { FS_OPT_SUB_MUL_A_X_A, "algebraic simplification: a * x - a = a * (x - 1)" },
78 { FS_OPT_SUB_SUB_X_Y_Z, "algebraic simplification: (x - y) - z = x - (y + z)" },
79 { FS_OPT_MUL_MINUS_1, "algebraic simplification: a * -1 = -a" },
80 { FS_OPT_OR, "algebraic simplification: a | a = a | 0 = 0 | a = a" },
81 { FS_OPT_AND, "algebraic simplification: a & 0b1...1 = 0b1...1 & a = a & a = a" },
82 { FS_OPT_EOR_A_A, "algebraic simplification: a ^ a = 0" },
83 { FS_OPT_EOR_TO_NOT_BOOL,"algebraic simplification: bool ^ 1 = !bool" },
84 { FS_OPT_EOR_TO_NOT, "algebraic simplification: x ^ 0b1..1 = ~x" },
85 { FS_OPT_NOT_CMP, "algebraic simplification: !(a cmp b) = a !cmp b" },
86 { FS_OPT_OR_SHFT_TO_ROT, "algebraic simplification: (x << c) | (x >> (bits - c)) == Rot(x, c)" },
87 { FS_OPT_REASSOC_SHIFT, "algebraic simplification: (x SHF c1) SHF c2 = x SHF (c1+c2)" },
88 { FS_OPT_CONV, "algebraic simplification: Conv could be removed" },
89 { FS_OPT_CAST, "algebraic simplification: a Cast could be removed" },
90 { FS_OPT_MIN_MAX_EQ, "algebraic simplification: Min(a,a) = Max(a,a) = a" },
91 { FS_OPT_MUX_C, "algebraic simplification: Mux(C, f, t) = C ? t : f" },
92 { FS_OPT_MUX_EQ, "algebraic simplification: Mux(v, x, x) = x" },
93 { FS_OPT_MUX_TRANSFORM, "algebraic simplification: Mux(a, b, c) = b OR Mux(a,b, c) = c" },
94 { FS_OPT_MUX_TO_MIN, "algebraic simplification: Mux(a < b, a, b) = Min(a,b)" },
95 { FS_OPT_MUX_TO_MAX, "algebraic simplification: Mux(a > b, a, b) = Max(a,b)" },
96 { FS_OPT_MUX_TO_ABS, "algebraic simplification: Mux(a > b, a, b) = Abs(a,b)" },
97 { FS_OPT_MUX_TO_SHR, "algebraic simplification: Mux(a > b, a, b) = a >> b" },
98 { FS_OPT_CONST_PHI, "constant evaluation on Phi node" },
99 { FS_BE_IA32_LEA, "ia32 Backend transformation: Lea was created" },
100 { FS_BE_IA32_LOAD_LEA, "ia32 Backend transformation: Load merged with a Lea" },
101 { FS_BE_IA32_STORE_LEA, "ia32 Backend transformation: Store merged with a Lea" },
102 { FS_BE_IA32_AM_S, "ia32 Backend transformation: Source address mode node created" },
103 { FS_BE_IA32_AM_D, "ia32 Backend transformation: Destination address mode node created" },
104 { FS_BE_IA32_CJMP, "ia32 Backend transformation: CJmp created to save a cmp/test" },
105 { FS_BE_IA32_2ADDRCPY, "ia32 Backend transformation: Copy created due to 2-Addresscode constraints" },
106 { FS_BE_IA32_SPILL2ST, "ia32 Backend transformation: Created Store for a Spill" },
107 { FS_BE_IA32_RELOAD2LD, "ia32 Backend transformation: Created Load for a Reload" },
108 { FS_BE_IA32_SUB2NEGADD, "ia32 Backend transformation: Created Neg-Add for a Sub due to 2-Addresscode constraints" },
109 { FS_BE_IA32_LEA2ADD, "ia32 Backend transformation: Transformed Lea back into Add" },
112 static const char *if_conv_names[IF_RESULT_LAST] = {
114 "if conv side effect ",
115 "if conv Phi node found ",
116 "if conv to deep DAG's ",
117 "if conv bad control flow ",
118 "if conv denied by arch ",
122 * dumps a opcode hash into human readable form
124 static void simple_dump_opcode_hash(dumper_t *dmp, pset *set)
128 counter_t f_new_node;
132 cnt_clr(&f_new_node);
135 fprintf(dmp->f, "%-16s %-8s %-8s %-8s\n", "Opcode", "alive", "created", "->Id");
136 foreach_pset(set, entry) {
137 fprintf(dmp->f, "%-16s %8u %8u %8u\n",
138 get_id_str(entry->op->name),
139 cnt_to_uint(&entry->cnt_alive),
140 cnt_to_uint(&entry->new_node),
141 cnt_to_uint(&entry->into_Id)
144 cnt_add(&f_alive, &entry->cnt_alive);
145 cnt_add(&f_new_node, &entry->new_node);
146 cnt_add(&f_Id, &entry->into_Id);
148 fprintf(dmp->f, "-------------------------------------------\n");
149 fprintf(dmp->f, "%-16s %8u %8u %8u\n", "Sum",
150 cnt_to_uint(&f_alive),
151 cnt_to_uint(&f_new_node),
154 } /* simple_dump_opcode_hash */
157 * dumps an optimization hash into human readable form
159 static void simple_dump_opt_hash(dumper_t *dmp, pset *set, int index)
161 assert(index < ARR_SIZE(opt_names) && "index out of range");
162 assert(opt_names[index].kind == index && "opt_names broken");
164 if (pset_count(set) > 0) {
167 fprintf(dmp->f, "\n%s:\n", opt_names[index].name);
168 fprintf(dmp->f, "%-16s %-8s\n", "Opcode", "deref");
170 foreach_pset(set, entry) {
171 fprintf(dmp->f, "%-16s %8u\n",
172 get_id_str(entry->op->name), cnt_to_uint(&entry->count));
175 } /* simple_dump_opt_hash */
178 * dumps the register pressure for each block and for each register class
180 static void simple_dump_be_block_reg_pressure(dumper_t *dmp, graph_entry_t *entry)
182 be_block_entry_t *b_entry = pset_first(entry->be_block_hash);
183 reg_pressure_entry_t *rp_entry;
185 /* return if no be statistic information available */
189 fprintf(dmp->f, "\nREG PRESSURE:\n");
190 fprintf(dmp->f, "%12s", "Block Nr");
192 /* print table head (register class names) */
193 foreach_pset(b_entry->reg_pressure, rp_entry)
194 fprintf(dmp->f, "%15s", rp_entry->class_name);
195 fprintf(dmp->f, "\n");
197 /* print the reg pressure for all blocks and register classes */
198 for (/* b_entry is already initialized */ ;
200 b_entry = pset_next(entry->be_block_hash)) {
201 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
203 foreach_pset(b_entry->reg_pressure, rp_entry)
204 fprintf(dmp->f, "%15d", rp_entry->pressure);
205 fprintf(dmp->f, "\n");
207 } /* simple_dump_be_block_reg_pressure */
209 /** prints a distribution entry */
210 static void simple_dump_distrib_entry(const distrib_entry_t *entry, void *env) {
212 fprintf(dmp->f, "%12d", cnt_to_uint(&entry->cnt));
213 } /* simple_dump_distrib_entry */
216 * dumps the distribution of the amount of ready nodes for each block
218 static void simple_dump_be_block_sched_ready(dumper_t *dmp, graph_entry_t *entry)
220 if (pset_count(entry->be_block_hash) > 0) {
221 be_block_entry_t *b_entry;
224 fprintf(dmp->f, "\nSCHEDULING: NUMBER OF READY NODES\n");
225 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s %12s\n",
226 "Block Nr", "1 node", "2 nodes", "3 nodes", "4 nodes", "5 or more", "AVERAGE");
228 foreach_pset(entry->be_block_hash, b_entry) {
229 /* this ensures that all keys from 1 to 5 are in the table */
230 for (i = 1; i < 6; ++i)
231 stat_insert_int_distrib_tbl(b_entry->sched_ready, i);
233 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
234 stat_iterate_distrib_tbl(b_entry->sched_ready, simple_dump_distrib_entry, dmp);
235 fprintf(dmp->f, "%12.2lf", stat_calc_avg_distrib_tbl(b_entry->sched_ready));
236 fprintf(dmp->f, "\n");
239 } /* simple_dump_be_block_sched_ready */
242 * Adds the counter for given entry to another distribution table.
244 static void add_distrib_entry(const distrib_entry_t *entry, void *env) {
245 distrib_tbl_t *sum_tbl = env;
247 stat_add_int_distrib_tbl(sum_tbl, (int)(entry->object), &entry->cnt);
248 } /* add_distrib_entry */
251 * dumps permutation statistics for one and block and one class
253 static void simple_dump_be_block_permstat_class(dumper_t *dmp, perm_class_entry_t *entry)
255 perm_stat_entry_t *ps_ent;
256 distrib_tbl_t *sum_chains = stat_new_int_distrib_tbl();
257 distrib_tbl_t *sum_cycles = stat_new_int_distrib_tbl();
261 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s\n",
270 foreach_pset(entry->perm_stat, ps_ent) {
271 fprintf(dmp->f, "%12d %12d %12d %12d %12d %12d\n",
274 stat_get_count_distrib_tbl(ps_ent->chains),
275 stat_get_count_distrib_tbl(ps_ent->cycles),
280 /* sum up distribution table for chains */
281 stat_iterate_distrib_tbl(ps_ent->chains, add_distrib_entry, sum_chains);
283 /* sum up distribution table for cycles */
284 stat_iterate_distrib_tbl(ps_ent->cycles, add_distrib_entry, sum_cycles);
287 /* print chain distribution for all perms of this class in this block */
288 fprintf(dmp->f, "chain distribution:\n");
290 /* add all missing entries to chain distribution table */
291 for (i = 1; i <= entry->n_regs; i++) {
292 snprintf(buf, sizeof(buf), "length %d", i);
293 fprintf(dmp->f, "%12s", buf);
294 stat_insert_int_distrib_tbl(sum_chains, i);
296 fprintf(dmp->f, "\n");
297 stat_iterate_distrib_tbl(sum_chains, simple_dump_distrib_entry, dmp->f);
298 fprintf(dmp->f, "\n");
300 /* print cycle distribution for all perms of this class in this block */
301 fprintf(dmp->f, "cycle distribution:\n");
303 /* add all missing entries to cycle distribution table */
304 for (i = 1; i <= entry->n_regs; i++) {
305 snprintf(buf, sizeof(buf), "length %d", i);
306 fprintf(dmp->f, "%12s", buf);
307 stat_insert_int_distrib_tbl(sum_cycles, i);
309 fprintf(dmp->f, "\n");
310 stat_iterate_distrib_tbl(sum_cycles, simple_dump_distrib_entry, dmp->f);
311 fprintf(dmp->f, "\n");
313 /* delete temporary sum distribution tables */
314 stat_delete_distrib_tbl(sum_chains);
315 stat_delete_distrib_tbl(sum_cycles);
317 } /* simple_dump_be_block_permstat_class */
320 * dumps statistics about perms
322 static void simple_dump_be_block_permstat(dumper_t *dmp, graph_entry_t *entry)
324 if (pset_count(entry->be_block_hash) > 0) {
325 be_block_entry_t *b_entry;
327 fprintf(dmp->f, "\nPERMUTATION STATISTICS BEGIN:\n");
328 foreach_pset(entry->be_block_hash, b_entry) {
329 perm_class_entry_t *pc_ent;
331 fprintf(dmp->f, "BLOCK %ld:\n", b_entry->block_nr);
333 if (b_entry->perm_class_stat) {
334 foreach_pset(b_entry->perm_class_stat, pc_ent) {
335 fprintf(dmp->f, "register class %s:\n", pc_ent->class_name);
336 simple_dump_be_block_permstat_class(dmp, pc_ent);
341 fprintf(dmp->f, "PERMUTATION STATISTICS END\n");
343 } /* simple_dump_be_block_permstat */
346 * dumps the number of real_function_call optimization
348 static void simple_dump_real_func_calls(dumper_t *dmp, counter_t *cnt)
353 if (! cnt_eq(cnt, 0)) {
354 fprintf(dmp->f, "\nReal Function Calls optimized:\n");
355 fprintf(dmp->f, "%-16s %8u\n", "Call", cnt_to_uint(cnt));
357 } /* simple_dump_real_func_calls */
360 * dumps the number of tail_recursion optimization
362 static void simple_dump_tail_recursion(dumper_t *dmp, unsigned num_tail_recursion)
367 if (num_tail_recursion > 0) {
368 fprintf(dmp->f, "\nTail recursion optimized:\n");
369 fprintf(dmp->f, "%-16s %8u\n", "Call", num_tail_recursion);
371 } /* simple_dump_tail_recursion */
374 * dumps the edges count
376 static void simple_dump_edges(dumper_t *dmp, counter_t *cnt)
381 fprintf(dmp->f, "%-16s %8d\n", "Edges", cnt_to_uint(cnt));
382 } /* simple_dump_edges */
387 static void simple_dump_graph(dumper_t *dmp, graph_entry_t *entry)
389 int i, dump_opts = 1;
390 block_entry_t *b_entry;
391 extbb_entry_t *eb_entry;
397 ir_graph *const_irg = get_const_code_irg();
399 if (entry->irg == const_irg)
400 fprintf(dmp->f, "\nConst code Irg %p", (void *)entry->irg);
403 fprintf(dmp->f, "\nEntity %s, Irg %p", get_entity_ld_name(entry->ent), (void *)entry->irg);
405 fprintf(dmp->f, "\nIrg %p", (void *)entry->irg);
408 fprintf(dmp->f, " %swalked %u over blocks %u:\n"
409 " was inlined : %u\n"
410 " got inlined : %u\n"
411 " strength red : %u\n"
412 " leaf function : %s\n"
413 " calls only leaf functions : %s\n"
417 " indirect calls : %u\n",
418 entry->is_deleted ? "DELETED " : "",
419 cnt_to_uint(&entry->cnt[gcnt_acc_walked]), cnt_to_uint(&entry->cnt[gcnt_acc_walked_blocks]),
420 cnt_to_uint(&entry->cnt[gcnt_acc_was_inlined]),
421 cnt_to_uint(&entry->cnt[gcnt_acc_got_inlined]),
422 cnt_to_uint(&entry->cnt[gcnt_acc_strength_red]),
423 entry->is_leaf ? "YES" : "NO",
424 entry->is_leaf_call == LCS_NON_LEAF_CALL ? "NO" : (entry->is_leaf_call == LCS_LEAF_CALL ? "Yes" : "Maybe"),
425 entry->is_recursive ? "YES" : "NO",
426 entry->is_chain_call ? "YES" : "NO",
427 cnt_to_uint(&entry->cnt[gcnt_all_calls]),
428 cnt_to_uint(&entry->cnt[gcnt_indirect_calls])
431 for (i = 0; i < IF_RESULT_LAST; ++i) {
432 fprintf(dmp->f, " %s : %u\n", if_conv_names[i], cnt_to_uint(&entry->cnt[gcnt_if_conv + i]));
435 fprintf(dmp->f, "\nGlobals counts:\n");
436 fprintf(dmp->f, "--------------\n");
442 " pure address calc ops : %u\n"
443 " all address calc ops : %u\n",
444 cnt_to_uint(&entry->cnt[gcnt_pure_adr_ops]),
445 cnt_to_uint(&entry->cnt[gcnt_all_adr_ops])
448 /* Load/Store address classification */
450 " global Ld/St address : %u\n"
451 " local Ld/St address : %u\n"
452 " this Ld/St address : %u\n"
453 " param Ld/St address : %u\n"
454 " other Ld/St address : %u\n",
455 cnt_to_uint(&entry->cnt[gcnt_global_adr]),
456 cnt_to_uint(&entry->cnt[gcnt_local_adr]),
457 cnt_to_uint(&entry->cnt[gcnt_this_adr]),
458 cnt_to_uint(&entry->cnt[gcnt_param_adr]),
459 cnt_to_uint(&entry->cnt[gcnt_other_adr])
462 simple_dump_opcode_hash(dmp, entry->opcode_hash);
463 simple_dump_edges(dmp, &entry->cnt[gcnt_edges]);
465 /* effects of optimizations */
469 simple_dump_real_func_calls(dmp, &entry->cnt[gcnt_acc_real_func_call]);
470 simple_dump_tail_recursion(dmp, entry->num_tail_recursion);
472 for (i = 0; i < sizeof(entry->opt_hash)/sizeof(entry->opt_hash[0]); ++i) {
473 simple_dump_opt_hash(dmp, entry->opt_hash[i], i);
476 /* dump block info */
477 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Block Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
478 foreach_pset(entry->block_hash, b_entry) {
479 fprintf(dmp->f, "BLK %6ld %12u %12u %12u %12u %12u %4.8f\n",
481 cnt_to_uint(&b_entry->cnt[bcnt_nodes]),
482 cnt_to_uint(&b_entry->cnt[bcnt_edges]),
483 cnt_to_uint(&b_entry->cnt[bcnt_in_edges]),
484 cnt_to_uint(&b_entry->cnt[bcnt_out_edges]),
485 cnt_to_uint(&b_entry->cnt[bcnt_phi_data]),
486 cnt_to_dbl(&b_entry->cnt[bcnt_edges]) / cnt_to_dbl(&b_entry->cnt[bcnt_nodes])
490 /* dump block reg pressure */
491 simple_dump_be_block_reg_pressure(dmp, entry);
493 /* dump block ready nodes distribution */
494 simple_dump_be_block_sched_ready(dmp, entry);
496 /* dump block permutation statistics */
497 simple_dump_be_block_permstat(dmp, entry);
499 if (dmp->status->stat_options & FIRMSTAT_COUNT_EXTBB && entry->extbb_hash) {
500 /* dump extended block info */
501 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Extbb Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
502 foreach_pset(entry->extbb_hash, eb_entry) {
503 fprintf(dmp->f, "ExtBB %6ld %12u %12u %12u %12u %12u %4.8f\n",
505 cnt_to_uint(&eb_entry->cnt[bcnt_nodes]),
506 cnt_to_uint(&eb_entry->cnt[bcnt_edges]),
507 cnt_to_uint(&eb_entry->cnt[bcnt_in_edges]),
508 cnt_to_uint(&eb_entry->cnt[bcnt_out_edges]),
509 cnt_to_uint(&eb_entry->cnt[bcnt_phi_data]),
510 cnt_to_dbl(&eb_entry->cnt[bcnt_edges]) / cnt_to_dbl(&eb_entry->cnt[bcnt_nodes])
515 } /* simple_dump_graph */
518 * dumps the constant table
520 static void simple_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
530 fprintf(dmp->f, "\nConstant Information:\n");
531 fprintf(dmp->f, "---------------------\n");
533 fprintf(dmp->f, "\nBit usage for integer constants\n");
534 fprintf(dmp->f, "-------------------------------\n");
536 for (i = 0; i < ARR_SIZE(tbl->int_bits_count); ++i) {
537 fprintf(dmp->f, "%5d %12u\n", i + 1, cnt_to_uint(&tbl->int_bits_count[i]));
538 cnt_add(&sum, &tbl->int_bits_count[i]);
540 fprintf(dmp->f, "-------------------------------\n");
542 fprintf(dmp->f, "\nFloating point constants classification\n");
543 fprintf(dmp->f, "--------------------------------------\n");
544 for (i = 0; i < ARR_SIZE(tbl->floats); ++i) {
545 fprintf(dmp->f, "%-10s %12u\n", stat_fc_name(i), cnt_to_uint(&tbl->floats[i]));
546 cnt_add(&sum, &tbl->floats[i]);
548 fprintf(dmp->f, "--------------------------------------\n");
550 fprintf(dmp->f, "other %12u\n", cnt_to_uint(&tbl->others));
551 cnt_add(&sum, &tbl->others);
552 fprintf(dmp->f, "-------------------------------\n");
554 fprintf(dmp->f, "sum %12u\n", cnt_to_uint(&sum));
555 } /* simple_dump_const_tbl */
558 * Dumps a line of the parameter table
560 static void dump_tbl_line(const distrib_entry_t *entry, void *env) {
563 fprintf(dmp->f, "%d : %u\n", PTR_TO_INT(entry->object), cnt_to_uint(&entry->cnt));
564 } /* dump_tbl_line */
567 * dumps the parameter distribution table
569 static void simple_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
570 fprintf(dmp->f, "\nCall parameter Information:\n");
571 fprintf(dmp->f, "---------------------\n");
573 stat_iterate_distrib_tbl(tbl, dump_tbl_line, dmp);
574 fprintf(dmp->f, "-------------------------------\n");
576 fprintf(dmp->f, "Number of Calls %12u\n", cnt_to_uint(&global->cnt[gcnt_all_calls]));
577 fprintf(dmp->f, "with const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_cnst_arg]));
578 fprintf(dmp->f, "with all const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_all_cnst_arg]));
579 fprintf(dmp->f, "with local var adr params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_local_adr]));
580 } /* simple_dump_param_tbl */
583 * initialize the simple dumper
585 static void simple_init(dumper_t *dmp, const char *name) {
588 snprintf(fname, sizeof(fname), "%s.txt", name);
589 dmp->f = fopen(fname, "w");
596 * finishes the simple dumper
598 static void simple_finish(dumper_t *dmp) {
602 } /* simple_finish */
605 * the simple human readable dumper
607 const dumper_t simple_dumper = {
609 simple_dump_const_tbl,
610 simple_dump_param_tbl,
617 FOURCC('S', 'M', 'P', 'L'),
620 /* ---------------------------------------------------------------------- */
623 * count the nodes as needed:
625 * 1 normal (data) Phi's
630 static void csv_count_nodes(dumper_t *dmp, graph_entry_t *graph, counter_t cnt[])
635 for (i = 0; i < 4; ++i)
638 foreach_pset(graph->opcode_hash, entry) {
639 if (entry->op == op_Phi) {
641 cnt_add(&cnt[1], &entry->cnt_alive);
642 } else if (entry->op == dmp->status->op_PhiM) {
644 cnt_add(&cnt[2], &entry->cnt_alive);
645 } else if (entry->op == op_Proj) {
647 cnt_add(&cnt[3], &entry->cnt_alive);
649 /* all other nodes */
650 cnt_add(&cnt[0], &entry->cnt_alive);
653 } /* csv_count_nodes */
658 static void csv_dump_graph(dumper_t *dmp, graph_entry_t *entry)
666 if (entry->irg && !entry->is_deleted) {
667 ir_graph *const_irg = get_const_code_irg();
669 if (entry->irg == const_irg) {
670 name = "<Const code Irg>";
674 name = get_entity_name(entry->ent);
676 name = "<UNKNOWN IRG>";
679 csv_count_nodes(dmp, entry, cnt);
681 fprintf(dmp->f, "%-40s, %p, %d, %d, %d, %d\n",
684 cnt_to_uint(&cnt[0]),
685 cnt_to_uint(&cnt[1]),
686 cnt_to_uint(&cnt[2]),
690 } /* csv_dump_graph */
695 static void csv_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
698 } /* csv_dump_const_tbl */
701 * dumps the parameter distribution table
703 static void csv_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
705 } /* csv_dump_param_tbl */
708 * initialize the simple dumper
710 static void csv_init(dumper_t *dmp, const char *name)
714 snprintf(fname, sizeof(fname), "%s.csv", name);
715 dmp->f = fopen(fname, "a");
721 * finishes the simple dumper
723 static void csv_finish(dumper_t *dmp)
731 * the simple human readable dumper
733 const dumper_t csv_dumper = {
743 FOURCC('C', 'S', 'V', '\0')