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 * @brief Statistics for Firm. Dumping.
23 * @author Michael Beck
35 * names of the optimizations
41 { HOOK_OPT_DEAD_BLOCK, "dead block elimination" },
42 { HOOK_OPT_STG, "straightening optimization" },
43 { HOOK_OPT_IFSIM, "if simplification" },
44 { HOOK_OPT_CONST_EVAL, "constant evaluation" },
45 { HOOK_OPT_ALGSIM, "algebraic simplification" },
46 { HOOK_OPT_PHI, "Phi optmization" },
47 { HOOK_OPT_SYNC, "Sync optmization" },
48 { HOOK_OPT_WAW, "Write-After-Write optimization" },
49 { HOOK_OPT_WAR, "Write-After-Read optimization" },
50 { HOOK_OPT_RAW, "Read-After-Write optimization" },
51 { HOOK_OPT_RAR, "Read-After-Read optimization" },
52 { HOOK_OPT_RC, "Read-a-Const optimization" },
53 { HOOK_OPT_TUPLE, "Tuple optimization" },
54 { HOOK_OPT_ID, "ID optimization" },
55 { HOOK_OPT_CSE, "Common subexpression elimination" },
56 { HOOK_OPT_STRENGTH_RED, "Strength reduction" },
57 { HOOK_OPT_ARCH_DEP, "Architecture dependant optimization" },
58 { HOOK_OPT_REASSOC, "Reassociation optimization" },
59 { HOOK_OPT_POLY_CALL, "Polymorphic call optimization" },
60 { HOOK_OPT_IF_CONV, "an if conversion was tried" },
61 { HOOK_OPT_FUNC_CALL, "Real function call optimization" },
62 { HOOK_OPT_CONFIRM, "Confirm-based optimization: replacement" },
63 { HOOK_OPT_CONFIRM_C, "Confirm-based optimization: replaced by const" },
64 { HOOK_OPT_CONFIRM_E, "Confirm-based optimization: evaluated" },
65 { HOOK_OPT_EXC_REM, "a exception edge was removed due to a Confirmation prove" },
66 { HOOK_LOWERED, "Lowered" },
67 { HOOK_BACKEND, "Backend transformation" },
68 { FS_OPT_NEUTRAL_0, "algebraic simplification: a op 0 = 0 op a = a" },
69 { FS_OPT_NEUTRAL_1, "algebraic simplification: a op 1 = 1 op a = a" },
70 { FS_OPT_ADD_A_A, "algebraic simplification: a + a = a * 2" },
71 { FS_OPT_ADD_A_MINUS_B, "algebraic simplification: a + -b = a - b" },
72 { FS_OPT_ADD_SUB, "algebraic simplification: (a + x) - x = (a - x) + x = a" },
73 { FS_OPT_ADD_MUL_A_X_A, "algebraic simplification: a * x + a = a * (x + 1)" },
74 { FS_OPT_SUB_0_A, "algebraic simplification: 0 - a = -a" },
75 { FS_OPT_MINUS_SUB, "algebraic simplification: -(a - b) = b - a" },
76 { FS_OPT_SUB_MUL_A_X_A, "algebraic simplification: a * x - a = a * (x - 1)" },
77 { FS_OPT_SUB_SUB_X_Y_Z, "algebraic simplification: (x - y) - z = x - (y + z)" },
78 { FS_OPT_SUB_C_NOT_X, "algebraic simplification: c - ~a = a + (c+1)" },
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|X) & a = a" },
82 { FS_OPT_TO_EOR, "algebraic simplification: (a|b) & ~(a&b) = a^b" },
83 { FS_OPT_EOR_A_A, "algebraic simplification: a ^ a = 0" },
84 { FS_OPT_EOR_TO_NOT_BOOL,"algebraic simplification: bool ^ 1 = !bool" },
85 { FS_OPT_EOR_TO_NOT, "algebraic simplification: x ^ 0b1..1 = ~x" },
86 { FS_OPT_NOT_CMP, "algebraic simplification: !(a cmp b) = a !cmp b" },
87 { FS_OPT_OR_SHFT_TO_ROT, "algebraic simplification: (x << c) | (x >> (bits - c)) == Rot(x, c)" },
88 { FS_OPT_REASSOC_SHIFT, "algebraic simplification: (x SHF c1) SHF c2 = x SHF (c1+c2)" },
89 { FS_OPT_SHIFT_AND, "algebraic simplification: (a SHF c) AND (b SHF c) = (a AND b) SHF c" },
90 { FS_OPT_SHIFT_OR, "algebraic simplification: (a SHF c) OR (b SHF c) = (a OR b) SHF c" },
91 { FS_OPT_SHIFT_EOR, "algebraic simplification: (a SHF c) XOR (b SHF c) = (a XOR b) SHF c" },
92 { FS_OPT_CONV, "algebraic simplification: Conv could be removed" },
93 { FS_OPT_CAST, "algebraic simplification: a Cast could be removed" },
94 { FS_OPT_MIN_MAX_EQ, "algebraic simplification: Min(a,a) = Max(a,a) = a" },
95 { FS_OPT_MUX_C, "algebraic simplification: Mux(C, f, t) = C ? t : f" },
96 { FS_OPT_MUX_EQ, "algebraic simplification: Mux(v, x, x) = x" },
97 { FS_OPT_MUX_TRANSFORM, "algebraic simplification: Mux(a, b, c) = b OR Mux(a,b, c) = c" },
98 { FS_OPT_MUX_TO_MIN, "algebraic simplification: Mux(a < b, a, b) = Min(a,b)" },
99 { FS_OPT_MUX_TO_MAX, "algebraic simplification: Mux(a > b, a, b) = Max(a,b)" },
100 { FS_OPT_MUX_TO_ABS, "algebraic simplification: Mux(a > b, a, b) = Abs(a,b)" },
101 { FS_OPT_MUX_TO_SHR, "algebraic simplification: Mux(a > b, a, b) = a >> b" },
102 { FS_OPT_IDEM_UNARY, "algebraic simplification: Idempotent unary operation" },
103 { FS_OPT_MINUS_NOT, "algebraic simplification: -(~x) = x + 1" },
104 { FS_OPT_NOT_MINUS_1, "algebraic simplification: ~(x - 1) = -x" },
105 { FS_OPT_NOT_PLUS_1, "algebraic simplification: ~x + 1 = -x" },
106 { FS_OPT_ADD_X_NOT_X, "algebraic simplification: ~x + x = -1" },
107 { FS_OPT_FP_INV_MUL, "algebraic simplification: x / y = x * (1.0/y)" },
108 { FS_OPT_CONST_PHI, "constant evaluation on Phi node" },
109 { FS_BE_IA32_LEA, "ia32 Backend transformation: Lea was created" },
110 { FS_BE_IA32_LOAD_LEA, "ia32 Backend transformation: Load merged with a Lea" },
111 { FS_BE_IA32_STORE_LEA, "ia32 Backend transformation: Store merged with a Lea" },
112 { FS_BE_IA32_AM_S, "ia32 Backend transformation: Source address mode node created" },
113 { FS_BE_IA32_AM_D, "ia32 Backend transformation: Destination address mode node created" },
114 { FS_BE_IA32_CJMP, "ia32 Backend transformation: CJmp created to save a cmp/test" },
115 { FS_BE_IA32_2ADDRCPY, "ia32 Backend transformation: Copy created due to 2-Addresscode constraints" },
116 { FS_BE_IA32_SPILL2ST, "ia32 Backend transformation: Created Store for a Spill" },
117 { FS_BE_IA32_RELOAD2LD, "ia32 Backend transformation: Created Load for a Reload" },
118 { FS_BE_IA32_SUB2NEGADD, "ia32 Backend transformation: Created Neg-Add for a Sub due to 2-Addresscode constraints" },
119 { FS_BE_IA32_LEA2ADD, "ia32 Backend transformation: Transformed Lea back into Add" },
122 static const char *if_conv_names[IF_RESULT_LAST] = {
124 "if conv side effect ",
125 "if conv Phi node found ",
126 "if conv to deep DAG's ",
127 "if conv bad control flow ",
128 "if conv denied by arch ",
132 * dumps a opcode hash into human readable form
134 static void simple_dump_opcode_hash(dumper_t *dmp, pset *set)
138 counter_t f_new_node;
142 cnt_clr(&f_new_node);
145 fprintf(dmp->f, "%-16s %-8s %-8s %-8s\n", "Opcode", "alive", "created", "->Id");
146 foreach_pset(set, entry) {
147 fprintf(dmp->f, "%-16s %8u %8u %8u\n",
148 get_id_str(entry->op->name),
149 cnt_to_uint(&entry->cnt_alive),
150 cnt_to_uint(&entry->new_node),
151 cnt_to_uint(&entry->into_Id)
154 cnt_add(&f_alive, &entry->cnt_alive);
155 cnt_add(&f_new_node, &entry->new_node);
156 cnt_add(&f_Id, &entry->into_Id);
158 fprintf(dmp->f, "-------------------------------------------\n");
159 fprintf(dmp->f, "%-16s %8u %8u %8u\n", "Sum",
160 cnt_to_uint(&f_alive),
161 cnt_to_uint(&f_new_node),
164 } /* simple_dump_opcode_hash */
167 * dumps an optimization hash into human readable form
169 static void simple_dump_opt_hash(dumper_t *dmp, pset *set, int index)
171 assert(index < (int) ARR_SIZE(opt_names) && "index out of range");
172 assert((int) opt_names[index].kind == index && "opt_names broken");
174 if (pset_count(set) > 0) {
177 fprintf(dmp->f, "\n%s:\n", opt_names[index].name);
178 fprintf(dmp->f, "%-16s %-8s\n", "Opcode", "deref");
180 foreach_pset(set, entry) {
181 fprintf(dmp->f, "%-16s %8u\n",
182 get_id_str(entry->op->name), cnt_to_uint(&entry->count));
185 } /* simple_dump_opt_hash */
188 * dumps the register pressure for each block and for each register class
190 static void simple_dump_be_block_reg_pressure(dumper_t *dmp, graph_entry_t *entry)
192 be_block_entry_t *b_entry = pset_first(entry->be_block_hash);
193 reg_pressure_entry_t *rp_entry;
195 /* return if no be statistic information available */
199 fprintf(dmp->f, "\nREG PRESSURE:\n");
200 fprintf(dmp->f, "%12s", "Block Nr");
202 /* print table head (register class names) */
203 foreach_pset(b_entry->reg_pressure, rp_entry)
204 fprintf(dmp->f, "%15s", rp_entry->class_name);
205 fprintf(dmp->f, "\n");
207 /* print the reg pressure for all blocks and register classes */
208 for (/* b_entry is already initialized */ ;
210 b_entry = pset_next(entry->be_block_hash)) {
211 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
213 foreach_pset(b_entry->reg_pressure, rp_entry)
214 fprintf(dmp->f, "%15d", rp_entry->pressure);
215 fprintf(dmp->f, "\n");
217 } /* simple_dump_be_block_reg_pressure */
219 /** prints a distribution entry */
220 static void simple_dump_distrib_entry(const distrib_entry_t *entry, void *env) {
222 fprintf(dmp->f, "%12d", cnt_to_uint(&entry->cnt));
223 } /* simple_dump_distrib_entry */
226 * dumps the distribution of the amount of ready nodes for each block
228 static void simple_dump_be_block_sched_ready(dumper_t *dmp, graph_entry_t *entry)
230 if (pset_count(entry->be_block_hash) > 0) {
231 be_block_entry_t *b_entry;
234 fprintf(dmp->f, "\nSCHEDULING: NUMBER OF READY NODES\n");
235 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s %12s\n",
236 "Block Nr", "1 node", "2 nodes", "3 nodes", "4 nodes", "5 or more", "AVERAGE");
238 foreach_pset(entry->be_block_hash, b_entry) {
239 /* this ensures that all keys from 1 to 5 are in the table */
240 for (i = 1; i < 6; ++i)
241 stat_insert_int_distrib_tbl(b_entry->sched_ready, i);
243 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
244 stat_iterate_distrib_tbl(b_entry->sched_ready, simple_dump_distrib_entry, dmp);
245 fprintf(dmp->f, "%12.2lf", stat_calc_avg_distrib_tbl(b_entry->sched_ready));
246 fprintf(dmp->f, "\n");
249 } /* simple_dump_be_block_sched_ready */
252 * Adds the counter for given entry to another distribution table.
254 static void add_distrib_entry(const distrib_entry_t *entry, void *env) {
255 distrib_tbl_t *sum_tbl = env;
257 stat_add_int_distrib_tbl(sum_tbl, (int)(entry->object), &entry->cnt);
258 } /* add_distrib_entry */
261 * dumps permutation statistics for one and block and one class
263 static void simple_dump_be_block_permstat_class(dumper_t *dmp, perm_class_entry_t *entry)
265 perm_stat_entry_t *ps_ent;
266 distrib_tbl_t *sum_chains = stat_new_int_distrib_tbl();
267 distrib_tbl_t *sum_cycles = stat_new_int_distrib_tbl();
271 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s\n",
280 foreach_pset(entry->perm_stat, ps_ent) {
281 fprintf(dmp->f, "%12d %12d %12d %12d %12d %12d\n",
284 stat_get_count_distrib_tbl(ps_ent->chains),
285 stat_get_count_distrib_tbl(ps_ent->cycles),
290 /* sum up distribution table for chains */
291 stat_iterate_distrib_tbl(ps_ent->chains, add_distrib_entry, sum_chains);
293 /* sum up distribution table for cycles */
294 stat_iterate_distrib_tbl(ps_ent->cycles, add_distrib_entry, sum_cycles);
297 /* print chain distribution for all perms of this class in this block */
298 fprintf(dmp->f, "chain distribution:\n");
300 /* add all missing entries to chain distribution table */
301 for (i = 1; i <= entry->n_regs; i++) {
302 snprintf(buf, sizeof(buf), "length %d", i);
303 fprintf(dmp->f, "%12s", buf);
304 stat_insert_int_distrib_tbl(sum_chains, i);
306 fprintf(dmp->f, "\n");
307 stat_iterate_distrib_tbl(sum_chains, simple_dump_distrib_entry, dmp);
308 fprintf(dmp->f, "\n");
310 /* print cycle distribution for all perms of this class in this block */
311 fprintf(dmp->f, "cycle distribution:\n");
313 /* add all missing entries to cycle distribution table */
314 for (i = 1; i <= entry->n_regs; i++) {
315 snprintf(buf, sizeof(buf), "length %d", i);
316 fprintf(dmp->f, "%12s", buf);
317 stat_insert_int_distrib_tbl(sum_cycles, i);
319 fprintf(dmp->f, "\n");
320 stat_iterate_distrib_tbl(sum_cycles, simple_dump_distrib_entry, dmp);
321 fprintf(dmp->f, "\n");
323 /* delete temporary sum distribution tables */
324 stat_delete_distrib_tbl(sum_chains);
325 stat_delete_distrib_tbl(sum_cycles);
327 } /* simple_dump_be_block_permstat_class */
330 * dumps statistics about perms
332 static void simple_dump_be_block_permstat(dumper_t *dmp, graph_entry_t *entry)
334 if (pset_count(entry->be_block_hash) > 0) {
335 be_block_entry_t *b_entry;
337 fprintf(dmp->f, "\nPERMUTATION STATISTICS BEGIN:\n");
338 foreach_pset(entry->be_block_hash, b_entry) {
339 perm_class_entry_t *pc_ent;
341 fprintf(dmp->f, "BLOCK %ld:\n", b_entry->block_nr);
343 if (b_entry->perm_class_stat) {
344 foreach_pset(b_entry->perm_class_stat, pc_ent) {
345 fprintf(dmp->f, "register class %s:\n", pc_ent->class_name);
346 simple_dump_be_block_permstat_class(dmp, pc_ent);
351 fprintf(dmp->f, "PERMUTATION STATISTICS END\n");
353 } /* simple_dump_be_block_permstat */
356 * dumps the number of real_function_call optimization
358 static void simple_dump_real_func_calls(dumper_t *dmp, counter_t *cnt)
363 if (! cnt_eq(cnt, 0)) {
364 fprintf(dmp->f, "\nReal Function Calls optimized:\n");
365 fprintf(dmp->f, "%-16s %8u\n", "Call", cnt_to_uint(cnt));
367 } /* simple_dump_real_func_calls */
370 * dumps the number of tail_recursion optimization
372 static void simple_dump_tail_recursion(dumper_t *dmp, unsigned num_tail_recursion)
377 if (num_tail_recursion > 0) {
378 fprintf(dmp->f, "\nTail recursion optimized:\n");
379 fprintf(dmp->f, "%-16s %8u\n", "Call", num_tail_recursion);
381 } /* simple_dump_tail_recursion */
384 * dumps the edges count
386 static void simple_dump_edges(dumper_t *dmp, counter_t *cnt)
391 fprintf(dmp->f, "%-16s %8d\n", "Edges", cnt_to_uint(cnt));
392 } /* simple_dump_edges */
397 static void simple_dump_graph(dumper_t *dmp, graph_entry_t *entry)
399 int i, dump_opts = 1;
400 block_entry_t *b_entry;
401 extbb_entry_t *eb_entry;
407 ir_graph *const_irg = get_const_code_irg();
409 if (entry->irg == const_irg)
410 fprintf(dmp->f, "\nConst code Irg %p", (void *)entry->irg);
413 fprintf(dmp->f, "\nEntity %s, Irg %p", get_entity_ld_name(entry->ent), (void *)entry->irg);
415 fprintf(dmp->f, "\nIrg %p", (void *)entry->irg);
418 fprintf(dmp->f, " %swalked %u over blocks %u:\n"
419 " was inlined : %u\n"
420 " got inlined : %u\n"
421 " strength red : %u\n"
422 " leaf function : %s\n"
423 " calls only leaf functions : %s\n"
427 " indirect calls : %u\n",
428 entry->is_deleted ? "DELETED " : "",
429 cnt_to_uint(&entry->cnt[gcnt_acc_walked]), cnt_to_uint(&entry->cnt[gcnt_acc_walked_blocks]),
430 cnt_to_uint(&entry->cnt[gcnt_acc_was_inlined]),
431 cnt_to_uint(&entry->cnt[gcnt_acc_got_inlined]),
432 cnt_to_uint(&entry->cnt[gcnt_acc_strength_red]),
433 entry->is_leaf ? "YES" : "NO",
434 entry->is_leaf_call == LCS_NON_LEAF_CALL ? "NO" : (entry->is_leaf_call == LCS_LEAF_CALL ? "Yes" : "Maybe"),
435 entry->is_recursive ? "YES" : "NO",
436 entry->is_chain_call ? "YES" : "NO",
437 cnt_to_uint(&entry->cnt[gcnt_all_calls]),
438 cnt_to_uint(&entry->cnt[gcnt_indirect_calls])
441 for (i = 0; i < IF_RESULT_LAST; ++i) {
442 fprintf(dmp->f, " %s : %u\n", if_conv_names[i], cnt_to_uint(&entry->cnt[gcnt_if_conv + i]));
445 fprintf(dmp->f, "\nGlobals counts:\n");
446 fprintf(dmp->f, "--------------\n");
452 " pure address calc ops : %u\n"
453 " all address calc ops : %u\n",
454 cnt_to_uint(&entry->cnt[gcnt_pure_adr_ops]),
455 cnt_to_uint(&entry->cnt[gcnt_all_adr_ops])
458 /* Load/Store address classification */
460 " global Ld/St address : %u\n"
461 " local Ld/St address : %u\n"
462 " this Ld/St address : %u\n"
463 " param Ld/St address : %u\n"
464 " other Ld/St address : %u\n",
465 cnt_to_uint(&entry->cnt[gcnt_global_adr]),
466 cnt_to_uint(&entry->cnt[gcnt_local_adr]),
467 cnt_to_uint(&entry->cnt[gcnt_this_adr]),
468 cnt_to_uint(&entry->cnt[gcnt_param_adr]),
469 cnt_to_uint(&entry->cnt[gcnt_other_adr])
472 simple_dump_opcode_hash(dmp, entry->opcode_hash);
473 simple_dump_edges(dmp, &entry->cnt[gcnt_edges]);
475 /* effects of optimizations */
479 simple_dump_real_func_calls(dmp, &entry->cnt[gcnt_acc_real_func_call]);
480 simple_dump_tail_recursion(dmp, entry->num_tail_recursion);
482 for (i = 0; i < sizeof(entry->opt_hash)/sizeof(entry->opt_hash[0]); ++i) {
483 simple_dump_opt_hash(dmp, entry->opt_hash[i], i);
486 /* dump block info */
487 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Block Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
488 foreach_pset(entry->block_hash, b_entry) {
489 fprintf(dmp->f, "BLK %6ld %12u %12u %12u %12u %12u %4.8f\n",
491 cnt_to_uint(&b_entry->cnt[bcnt_nodes]),
492 cnt_to_uint(&b_entry->cnt[bcnt_edges]),
493 cnt_to_uint(&b_entry->cnt[bcnt_in_edges]),
494 cnt_to_uint(&b_entry->cnt[bcnt_out_edges]),
495 cnt_to_uint(&b_entry->cnt[bcnt_phi_data]),
496 cnt_to_dbl(&b_entry->cnt[bcnt_edges]) / cnt_to_dbl(&b_entry->cnt[bcnt_nodes])
500 /* dump block reg pressure */
501 simple_dump_be_block_reg_pressure(dmp, entry);
503 /* dump block ready nodes distribution */
504 simple_dump_be_block_sched_ready(dmp, entry);
506 /* dump block permutation statistics */
507 simple_dump_be_block_permstat(dmp, entry);
509 if (dmp->status->stat_options & FIRMSTAT_COUNT_EXTBB && entry->extbb_hash) {
510 /* dump extended block info */
511 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Extbb Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
512 foreach_pset(entry->extbb_hash, eb_entry) {
513 fprintf(dmp->f, "ExtBB %6ld %12u %12u %12u %12u %12u %4.8f\n",
515 cnt_to_uint(&eb_entry->cnt[bcnt_nodes]),
516 cnt_to_uint(&eb_entry->cnt[bcnt_edges]),
517 cnt_to_uint(&eb_entry->cnt[bcnt_in_edges]),
518 cnt_to_uint(&eb_entry->cnt[bcnt_out_edges]),
519 cnt_to_uint(&eb_entry->cnt[bcnt_phi_data]),
520 cnt_to_dbl(&eb_entry->cnt[bcnt_edges]) / cnt_to_dbl(&eb_entry->cnt[bcnt_nodes])
525 } /* simple_dump_graph */
528 * dumps the constant table
530 static void simple_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
540 fprintf(dmp->f, "\nConstant Information:\n");
541 fprintf(dmp->f, "---------------------\n");
543 fprintf(dmp->f, "\nBit usage for integer constants\n");
544 fprintf(dmp->f, "-------------------------------\n");
546 for (i = 0; i < ARR_SIZE(tbl->int_bits_count); ++i) {
547 fprintf(dmp->f, "%5d %12u\n", i + 1, cnt_to_uint(&tbl->int_bits_count[i]));
548 cnt_add(&sum, &tbl->int_bits_count[i]);
550 fprintf(dmp->f, "-------------------------------\n");
552 fprintf(dmp->f, "\nFloating point constants classification\n");
553 fprintf(dmp->f, "--------------------------------------\n");
554 for (i = 0; i < ARR_SIZE(tbl->floats); ++i) {
555 fprintf(dmp->f, "%-10s %12u\n", stat_fc_name(i), cnt_to_uint(&tbl->floats[i]));
556 cnt_add(&sum, &tbl->floats[i]);
558 fprintf(dmp->f, "--------------------------------------\n");
560 fprintf(dmp->f, "other %12u\n", cnt_to_uint(&tbl->others));
561 cnt_add(&sum, &tbl->others);
562 fprintf(dmp->f, "-------------------------------\n");
564 fprintf(dmp->f, "sum %12u\n", cnt_to_uint(&sum));
565 } /* simple_dump_const_tbl */
568 * Dumps a line of the parameter table
570 static void dump_tbl_line(const distrib_entry_t *entry, void *env) {
573 fprintf(dmp->f, "%d : %u\n", PTR_TO_INT(entry->object), cnt_to_uint(&entry->cnt));
574 } /* dump_tbl_line */
577 * dumps the parameter distribution table
579 static void simple_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
580 fprintf(dmp->f, "\nCall parameter Information:\n");
581 fprintf(dmp->f, "---------------------\n");
583 stat_iterate_distrib_tbl(tbl, dump_tbl_line, dmp);
584 fprintf(dmp->f, "-------------------------------\n");
586 fprintf(dmp->f, "Number of Calls %12u\n", cnt_to_uint(&global->cnt[gcnt_all_calls]));
587 fprintf(dmp->f, "with const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_cnst_arg]));
588 fprintf(dmp->f, "with all const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_all_cnst_arg]));
589 fprintf(dmp->f, "with local var adr params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_local_adr]));
590 } /* simple_dump_param_tbl */
593 * initialize the simple dumper
595 static void simple_init(dumper_t *dmp, const char *name) {
598 snprintf(fname, sizeof(fname), "%s.txt", name);
599 dmp->f = fopen(fname, "w");
606 * finishes the simple dumper
608 static void simple_finish(dumper_t *dmp) {
612 } /* simple_finish */
615 * the simple human readable dumper
617 const dumper_t simple_dumper = {
619 simple_dump_const_tbl,
620 simple_dump_param_tbl,
627 FOURCC('S', 'M', 'P', 'L'),
630 /* ---------------------------------------------------------------------- */
633 * count the nodes as needed:
635 * 1 normal (data) Phi's
640 static void csv_count_nodes(dumper_t *dmp, graph_entry_t *graph, counter_t cnt[])
645 for (i = 0; i < 4; ++i)
648 foreach_pset(graph->opcode_hash, entry) {
649 if (entry->op == op_Phi) {
651 cnt_add(&cnt[1], &entry->cnt_alive);
652 } else if (entry->op == dmp->status->op_PhiM) {
654 cnt_add(&cnt[2], &entry->cnt_alive);
655 } else if (entry->op == op_Proj) {
657 cnt_add(&cnt[3], &entry->cnt_alive);
659 /* all other nodes */
660 cnt_add(&cnt[0], &entry->cnt_alive);
663 } /* csv_count_nodes */
668 static void csv_dump_graph(dumper_t *dmp, graph_entry_t *entry)
676 if (entry->irg && !entry->is_deleted) {
677 ir_graph *const_irg = get_const_code_irg();
679 if (entry->irg == const_irg) {
680 name = "<Const code Irg>";
684 name = get_entity_name(entry->ent);
686 name = "<UNKNOWN IRG>";
689 csv_count_nodes(dmp, entry, cnt);
691 fprintf(dmp->f, "%-40s, %p, %d, %d, %d, %d\n",
694 cnt_to_uint(&cnt[0]),
695 cnt_to_uint(&cnt[1]),
696 cnt_to_uint(&cnt[2]),
700 } /* csv_dump_graph */
705 static void csv_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
710 } /* csv_dump_const_tbl */
713 * dumps the parameter distribution table
715 static void csv_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
720 } /* csv_dump_param_tbl */
723 * initialize the simple dumper
725 static void csv_init(dumper_t *dmp, const char *name)
729 snprintf(fname, sizeof(fname), "%s.csv", name);
730 dmp->f = fopen(fname, "a");
736 * finishes the simple dumper
738 static void csv_finish(dumper_t *dmp)
746 * the simple human readable dumper
748 const dumper_t csv_dumper = {
758 FOURCC('C', 'S', 'V', '\0')