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_SUB_MUL_A_X_A, "algebraic simplification: a * x - a = a * (x - 1)" },
76 { FS_OPT_SUB_SUB_X_Y_Z, "algebraic simplification: (x - y) - z = x - (y + z)" },
77 { FS_OPT_MUL_MINUS_1, "algebraic simplification: a * -1 = -a" },
78 { FS_OPT_OR, "algebraic simplification: a | a = a | 0 = 0 | a = a" },
79 { FS_OPT_AND, "algebraic simplification: a & 0b1...1 = 0b1...1 & a = a & a = a" },
80 { FS_OPT_EOR_A_A, "algebraic simplification: a ^ a = 0" },
81 { FS_OPT_EOR_TO_NOT_BOOL,"algebraic simplification: bool ^ 1 = !bool" },
82 { FS_OPT_EOR_TO_NOT, "algebraic simplification: x ^ 0b1..1 = ~x" },
83 { FS_OPT_NOT_CMP, "algebraic simplification: !(a cmp b) = a !cmp b" },
84 { FS_OPT_OR_SHFT_TO_ROT, "algebraic simplification: (x << c) | (x >> (bits - c)) == Rot(x, c)" },
85 { FS_OPT_REASSOC_SHIFT, "algebraic simplification: (x SHF c1) SHF c2 = x SHF (c1+c2)" },
86 { FS_OPT_SHIFT_AND, "algebraic simplification: (a SHF c) AND (b SHF c) = (a AND b) SHF c" },
87 { FS_OPT_SHIFT_OR, "algebraic simplification: (a SHF c) OR (b SHF c) = (a OR b) SHF c" },
88 { FS_OPT_SHIFT_EOR, "algebraic simplification: (a SHF c) XOR (b SHF c) = (a XOR b) SHF c" },
89 { FS_OPT_CONV, "algebraic simplification: Conv could be removed" },
90 { FS_OPT_CAST, "algebraic simplification: a Cast could be removed" },
91 { FS_OPT_MIN_MAX_EQ, "algebraic simplification: Min(a,a) = Max(a,a) = a" },
92 { FS_OPT_MUX_C, "algebraic simplification: Mux(C, f, t) = C ? t : f" },
93 { FS_OPT_MUX_EQ, "algebraic simplification: Mux(v, x, x) = x" },
94 { FS_OPT_MUX_TRANSFORM, "algebraic simplification: Mux(a, b, c) = b OR Mux(a,b, c) = c" },
95 { FS_OPT_MUX_TO_MIN, "algebraic simplification: Mux(a < b, a, b) = Min(a,b)" },
96 { FS_OPT_MUX_TO_MAX, "algebraic simplification: Mux(a > b, a, b) = Max(a,b)" },
97 { FS_OPT_MUX_TO_ABS, "algebraic simplification: Mux(a > b, a, b) = Abs(a,b)" },
98 { FS_OPT_MUX_TO_SHR, "algebraic simplification: Mux(a > b, a, b) = a >> b" },
99 { FS_OPT_IDEM_UNARY, "algebraic simplification: Idempotent unary operation" },
100 { FS_OPT_MINUS_NOT, "algebraic simplification: -(~x) = x + 1" },
101 { FS_OPT_CONST_PHI, "constant evaluation on Phi node" },
102 { FS_BE_IA32_LEA, "ia32 Backend transformation: Lea was created" },
103 { FS_BE_IA32_LOAD_LEA, "ia32 Backend transformation: Load merged with a Lea" },
104 { FS_BE_IA32_STORE_LEA, "ia32 Backend transformation: Store merged with a Lea" },
105 { FS_BE_IA32_AM_S, "ia32 Backend transformation: Source address mode node created" },
106 { FS_BE_IA32_AM_D, "ia32 Backend transformation: Destination address mode node created" },
107 { FS_BE_IA32_CJMP, "ia32 Backend transformation: CJmp created to save a cmp/test" },
108 { FS_BE_IA32_2ADDRCPY, "ia32 Backend transformation: Copy created due to 2-Addresscode constraints" },
109 { FS_BE_IA32_SPILL2ST, "ia32 Backend transformation: Created Store for a Spill" },
110 { FS_BE_IA32_RELOAD2LD, "ia32 Backend transformation: Created Load for a Reload" },
111 { FS_BE_IA32_SUB2NEGADD, "ia32 Backend transformation: Created Neg-Add for a Sub due to 2-Addresscode constraints" },
112 { FS_BE_IA32_LEA2ADD, "ia32 Backend transformation: Transformed Lea back into Add" },
115 static const char *if_conv_names[IF_RESULT_LAST] = {
117 "if conv side effect ",
118 "if conv Phi node found ",
119 "if conv to deep DAG's ",
120 "if conv bad control flow ",
121 "if conv denied by arch ",
125 * dumps a opcode hash into human readable form
127 static void simple_dump_opcode_hash(dumper_t *dmp, pset *set)
131 counter_t f_new_node;
135 cnt_clr(&f_new_node);
138 fprintf(dmp->f, "%-16s %-8s %-8s %-8s\n", "Opcode", "alive", "created", "->Id");
139 foreach_pset(set, entry) {
140 fprintf(dmp->f, "%-16s %8u %8u %8u\n",
141 get_id_str(entry->op->name),
142 cnt_to_uint(&entry->cnt_alive),
143 cnt_to_uint(&entry->new_node),
144 cnt_to_uint(&entry->into_Id)
147 cnt_add(&f_alive, &entry->cnt_alive);
148 cnt_add(&f_new_node, &entry->new_node);
149 cnt_add(&f_Id, &entry->into_Id);
151 fprintf(dmp->f, "-------------------------------------------\n");
152 fprintf(dmp->f, "%-16s %8u %8u %8u\n", "Sum",
153 cnt_to_uint(&f_alive),
154 cnt_to_uint(&f_new_node),
157 } /* simple_dump_opcode_hash */
160 * dumps an optimization hash into human readable form
162 static void simple_dump_opt_hash(dumper_t *dmp, pset *set, int index)
164 assert(index < (int) ARR_SIZE(opt_names) && "index out of range");
165 assert((int) opt_names[index].kind == index && "opt_names broken");
167 if (pset_count(set) > 0) {
170 fprintf(dmp->f, "\n%s:\n", opt_names[index].name);
171 fprintf(dmp->f, "%-16s %-8s\n", "Opcode", "deref");
173 foreach_pset(set, entry) {
174 fprintf(dmp->f, "%-16s %8u\n",
175 get_id_str(entry->op->name), cnt_to_uint(&entry->count));
178 } /* simple_dump_opt_hash */
181 * dumps the register pressure for each block and for each register class
183 static void simple_dump_be_block_reg_pressure(dumper_t *dmp, graph_entry_t *entry)
185 be_block_entry_t *b_entry = pset_first(entry->be_block_hash);
186 reg_pressure_entry_t *rp_entry;
188 /* return if no be statistic information available */
192 fprintf(dmp->f, "\nREG PRESSURE:\n");
193 fprintf(dmp->f, "%12s", "Block Nr");
195 /* print table head (register class names) */
196 foreach_pset(b_entry->reg_pressure, rp_entry)
197 fprintf(dmp->f, "%15s", rp_entry->class_name);
198 fprintf(dmp->f, "\n");
200 /* print the reg pressure for all blocks and register classes */
201 for (/* b_entry is already initialized */ ;
203 b_entry = pset_next(entry->be_block_hash)) {
204 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
206 foreach_pset(b_entry->reg_pressure, rp_entry)
207 fprintf(dmp->f, "%15d", rp_entry->pressure);
208 fprintf(dmp->f, "\n");
210 } /* simple_dump_be_block_reg_pressure */
212 /** prints a distribution entry */
213 static void simple_dump_distrib_entry(const distrib_entry_t *entry, void *env) {
215 fprintf(dmp->f, "%12d", cnt_to_uint(&entry->cnt));
216 } /* simple_dump_distrib_entry */
219 * dumps the distribution of the amount of ready nodes for each block
221 static void simple_dump_be_block_sched_ready(dumper_t *dmp, graph_entry_t *entry)
223 if (pset_count(entry->be_block_hash) > 0) {
224 be_block_entry_t *b_entry;
227 fprintf(dmp->f, "\nSCHEDULING: NUMBER OF READY NODES\n");
228 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s %12s\n",
229 "Block Nr", "1 node", "2 nodes", "3 nodes", "4 nodes", "5 or more", "AVERAGE");
231 foreach_pset(entry->be_block_hash, b_entry) {
232 /* this ensures that all keys from 1 to 5 are in the table */
233 for (i = 1; i < 6; ++i)
234 stat_insert_int_distrib_tbl(b_entry->sched_ready, i);
236 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
237 stat_iterate_distrib_tbl(b_entry->sched_ready, simple_dump_distrib_entry, dmp);
238 fprintf(dmp->f, "%12.2lf", stat_calc_avg_distrib_tbl(b_entry->sched_ready));
239 fprintf(dmp->f, "\n");
242 } /* simple_dump_be_block_sched_ready */
245 * Adds the counter for given entry to another distribution table.
247 static void add_distrib_entry(const distrib_entry_t *entry, void *env) {
248 distrib_tbl_t *sum_tbl = env;
250 stat_add_int_distrib_tbl(sum_tbl, (int)(entry->object), &entry->cnt);
251 } /* add_distrib_entry */
254 * dumps permutation statistics for one and block and one class
256 static void simple_dump_be_block_permstat_class(dumper_t *dmp, perm_class_entry_t *entry)
258 perm_stat_entry_t *ps_ent;
259 distrib_tbl_t *sum_chains = stat_new_int_distrib_tbl();
260 distrib_tbl_t *sum_cycles = stat_new_int_distrib_tbl();
264 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s\n",
273 foreach_pset(entry->perm_stat, ps_ent) {
274 fprintf(dmp->f, "%12d %12d %12d %12d %12d %12d\n",
277 stat_get_count_distrib_tbl(ps_ent->chains),
278 stat_get_count_distrib_tbl(ps_ent->cycles),
283 /* sum up distribution table for chains */
284 stat_iterate_distrib_tbl(ps_ent->chains, add_distrib_entry, sum_chains);
286 /* sum up distribution table for cycles */
287 stat_iterate_distrib_tbl(ps_ent->cycles, add_distrib_entry, sum_cycles);
290 /* print chain distribution for all perms of this class in this block */
291 fprintf(dmp->f, "chain distribution:\n");
293 /* add all missing entries to chain distribution table */
294 for (i = 1; i <= entry->n_regs; i++) {
295 snprintf(buf, sizeof(buf), "length %d", i);
296 fprintf(dmp->f, "%12s", buf);
297 stat_insert_int_distrib_tbl(sum_chains, i);
299 fprintf(dmp->f, "\n");
300 stat_iterate_distrib_tbl(sum_chains, simple_dump_distrib_entry, dmp);
301 fprintf(dmp->f, "\n");
303 /* print cycle distribution for all perms of this class in this block */
304 fprintf(dmp->f, "cycle distribution:\n");
306 /* add all missing entries to cycle distribution table */
307 for (i = 1; i <= entry->n_regs; i++) {
308 snprintf(buf, sizeof(buf), "length %d", i);
309 fprintf(dmp->f, "%12s", buf);
310 stat_insert_int_distrib_tbl(sum_cycles, i);
312 fprintf(dmp->f, "\n");
313 stat_iterate_distrib_tbl(sum_cycles, simple_dump_distrib_entry, dmp);
314 fprintf(dmp->f, "\n");
316 /* delete temporary sum distribution tables */
317 stat_delete_distrib_tbl(sum_chains);
318 stat_delete_distrib_tbl(sum_cycles);
320 } /* simple_dump_be_block_permstat_class */
323 * dumps statistics about perms
325 static void simple_dump_be_block_permstat(dumper_t *dmp, graph_entry_t *entry)
327 if (pset_count(entry->be_block_hash) > 0) {
328 be_block_entry_t *b_entry;
330 fprintf(dmp->f, "\nPERMUTATION STATISTICS BEGIN:\n");
331 foreach_pset(entry->be_block_hash, b_entry) {
332 perm_class_entry_t *pc_ent;
334 fprintf(dmp->f, "BLOCK %ld:\n", b_entry->block_nr);
336 if (b_entry->perm_class_stat) {
337 foreach_pset(b_entry->perm_class_stat, pc_ent) {
338 fprintf(dmp->f, "register class %s:\n", pc_ent->class_name);
339 simple_dump_be_block_permstat_class(dmp, pc_ent);
344 fprintf(dmp->f, "PERMUTATION STATISTICS END\n");
346 } /* simple_dump_be_block_permstat */
349 * dumps the number of real_function_call optimization
351 static void simple_dump_real_func_calls(dumper_t *dmp, counter_t *cnt)
356 if (! cnt_eq(cnt, 0)) {
357 fprintf(dmp->f, "\nReal Function Calls optimized:\n");
358 fprintf(dmp->f, "%-16s %8u\n", "Call", cnt_to_uint(cnt));
360 } /* simple_dump_real_func_calls */
363 * dumps the number of tail_recursion optimization
365 static void simple_dump_tail_recursion(dumper_t *dmp, unsigned num_tail_recursion)
370 if (num_tail_recursion > 0) {
371 fprintf(dmp->f, "\nTail recursion optimized:\n");
372 fprintf(dmp->f, "%-16s %8u\n", "Call", num_tail_recursion);
374 } /* simple_dump_tail_recursion */
377 * dumps the edges count
379 static void simple_dump_edges(dumper_t *dmp, counter_t *cnt)
384 fprintf(dmp->f, "%-16s %8d\n", "Edges", cnt_to_uint(cnt));
385 } /* simple_dump_edges */
390 static void simple_dump_graph(dumper_t *dmp, graph_entry_t *entry)
392 int i, dump_opts = 1;
393 block_entry_t *b_entry;
394 extbb_entry_t *eb_entry;
400 ir_graph *const_irg = get_const_code_irg();
402 if (entry->irg == const_irg)
403 fprintf(dmp->f, "\nConst code Irg %p", (void *)entry->irg);
406 fprintf(dmp->f, "\nEntity %s, Irg %p", get_entity_ld_name(entry->ent), (void *)entry->irg);
408 fprintf(dmp->f, "\nIrg %p", (void *)entry->irg);
411 fprintf(dmp->f, " %swalked %u over blocks %u:\n"
412 " was inlined : %u\n"
413 " got inlined : %u\n"
414 " strength red : %u\n"
415 " leaf function : %s\n"
416 " calls only leaf functions : %s\n"
420 " indirect calls : %u\n",
421 entry->is_deleted ? "DELETED " : "",
422 cnt_to_uint(&entry->cnt[gcnt_acc_walked]), cnt_to_uint(&entry->cnt[gcnt_acc_walked_blocks]),
423 cnt_to_uint(&entry->cnt[gcnt_acc_was_inlined]),
424 cnt_to_uint(&entry->cnt[gcnt_acc_got_inlined]),
425 cnt_to_uint(&entry->cnt[gcnt_acc_strength_red]),
426 entry->is_leaf ? "YES" : "NO",
427 entry->is_leaf_call == LCS_NON_LEAF_CALL ? "NO" : (entry->is_leaf_call == LCS_LEAF_CALL ? "Yes" : "Maybe"),
428 entry->is_recursive ? "YES" : "NO",
429 entry->is_chain_call ? "YES" : "NO",
430 cnt_to_uint(&entry->cnt[gcnt_all_calls]),
431 cnt_to_uint(&entry->cnt[gcnt_indirect_calls])
434 for (i = 0; i < IF_RESULT_LAST; ++i) {
435 fprintf(dmp->f, " %s : %u\n", if_conv_names[i], cnt_to_uint(&entry->cnt[gcnt_if_conv + i]));
438 fprintf(dmp->f, "\nGlobals counts:\n");
439 fprintf(dmp->f, "--------------\n");
445 " pure address calc ops : %u\n"
446 " all address calc ops : %u\n",
447 cnt_to_uint(&entry->cnt[gcnt_pure_adr_ops]),
448 cnt_to_uint(&entry->cnt[gcnt_all_adr_ops])
451 /* Load/Store address classification */
453 " global Ld/St address : %u\n"
454 " local Ld/St address : %u\n"
455 " this Ld/St address : %u\n"
456 " param Ld/St address : %u\n"
457 " other Ld/St address : %u\n",
458 cnt_to_uint(&entry->cnt[gcnt_global_adr]),
459 cnt_to_uint(&entry->cnt[gcnt_local_adr]),
460 cnt_to_uint(&entry->cnt[gcnt_this_adr]),
461 cnt_to_uint(&entry->cnt[gcnt_param_adr]),
462 cnt_to_uint(&entry->cnt[gcnt_other_adr])
465 simple_dump_opcode_hash(dmp, entry->opcode_hash);
466 simple_dump_edges(dmp, &entry->cnt[gcnt_edges]);
468 /* effects of optimizations */
472 simple_dump_real_func_calls(dmp, &entry->cnt[gcnt_acc_real_func_call]);
473 simple_dump_tail_recursion(dmp, entry->num_tail_recursion);
475 for (i = 0; i < sizeof(entry->opt_hash)/sizeof(entry->opt_hash[0]); ++i) {
476 simple_dump_opt_hash(dmp, entry->opt_hash[i], i);
479 /* dump block info */
480 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Block Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
481 foreach_pset(entry->block_hash, b_entry) {
482 fprintf(dmp->f, "BLK %6ld %12u %12u %12u %12u %12u %4.8f\n",
484 cnt_to_uint(&b_entry->cnt[bcnt_nodes]),
485 cnt_to_uint(&b_entry->cnt[bcnt_edges]),
486 cnt_to_uint(&b_entry->cnt[bcnt_in_edges]),
487 cnt_to_uint(&b_entry->cnt[bcnt_out_edges]),
488 cnt_to_uint(&b_entry->cnt[bcnt_phi_data]),
489 cnt_to_dbl(&b_entry->cnt[bcnt_edges]) / cnt_to_dbl(&b_entry->cnt[bcnt_nodes])
493 /* dump block reg pressure */
494 simple_dump_be_block_reg_pressure(dmp, entry);
496 /* dump block ready nodes distribution */
497 simple_dump_be_block_sched_ready(dmp, entry);
499 /* dump block permutation statistics */
500 simple_dump_be_block_permstat(dmp, entry);
502 if (dmp->status->stat_options & FIRMSTAT_COUNT_EXTBB && entry->extbb_hash) {
503 /* dump extended block info */
504 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Extbb Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
505 foreach_pset(entry->extbb_hash, eb_entry) {
506 fprintf(dmp->f, "ExtBB %6ld %12u %12u %12u %12u %12u %4.8f\n",
508 cnt_to_uint(&eb_entry->cnt[bcnt_nodes]),
509 cnt_to_uint(&eb_entry->cnt[bcnt_edges]),
510 cnt_to_uint(&eb_entry->cnt[bcnt_in_edges]),
511 cnt_to_uint(&eb_entry->cnt[bcnt_out_edges]),
512 cnt_to_uint(&eb_entry->cnt[bcnt_phi_data]),
513 cnt_to_dbl(&eb_entry->cnt[bcnt_edges]) / cnt_to_dbl(&eb_entry->cnt[bcnt_nodes])
518 } /* simple_dump_graph */
521 * dumps the constant table
523 static void simple_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
533 fprintf(dmp->f, "\nConstant Information:\n");
534 fprintf(dmp->f, "---------------------\n");
536 fprintf(dmp->f, "\nBit usage for integer constants\n");
537 fprintf(dmp->f, "-------------------------------\n");
539 for (i = 0; i < ARR_SIZE(tbl->int_bits_count); ++i) {
540 fprintf(dmp->f, "%5d %12u\n", i + 1, cnt_to_uint(&tbl->int_bits_count[i]));
541 cnt_add(&sum, &tbl->int_bits_count[i]);
543 fprintf(dmp->f, "-------------------------------\n");
545 fprintf(dmp->f, "\nFloating point constants classification\n");
546 fprintf(dmp->f, "--------------------------------------\n");
547 for (i = 0; i < ARR_SIZE(tbl->floats); ++i) {
548 fprintf(dmp->f, "%-10s %12u\n", stat_fc_name(i), cnt_to_uint(&tbl->floats[i]));
549 cnt_add(&sum, &tbl->floats[i]);
551 fprintf(dmp->f, "--------------------------------------\n");
553 fprintf(dmp->f, "other %12u\n", cnt_to_uint(&tbl->others));
554 cnt_add(&sum, &tbl->others);
555 fprintf(dmp->f, "-------------------------------\n");
557 fprintf(dmp->f, "sum %12u\n", cnt_to_uint(&sum));
558 } /* simple_dump_const_tbl */
561 * Dumps a line of the parameter table
563 static void dump_tbl_line(const distrib_entry_t *entry, void *env) {
566 fprintf(dmp->f, "%d : %u\n", PTR_TO_INT(entry->object), cnt_to_uint(&entry->cnt));
567 } /* dump_tbl_line */
570 * dumps the parameter distribution table
572 static void simple_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
573 fprintf(dmp->f, "\nCall parameter Information:\n");
574 fprintf(dmp->f, "---------------------\n");
576 stat_iterate_distrib_tbl(tbl, dump_tbl_line, dmp);
577 fprintf(dmp->f, "-------------------------------\n");
579 fprintf(dmp->f, "Number of Calls %12u\n", cnt_to_uint(&global->cnt[gcnt_all_calls]));
580 fprintf(dmp->f, "with const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_cnst_arg]));
581 fprintf(dmp->f, "with all const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_all_cnst_arg]));
582 fprintf(dmp->f, "with local var adr params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_local_adr]));
583 } /* simple_dump_param_tbl */
586 * initialize the simple dumper
588 static void simple_init(dumper_t *dmp, const char *name) {
591 snprintf(fname, sizeof(fname), "%s.txt", name);
592 dmp->f = fopen(fname, "w");
599 * finishes the simple dumper
601 static void simple_finish(dumper_t *dmp) {
605 } /* simple_finish */
608 * the simple human readable dumper
610 const dumper_t simple_dumper = {
612 simple_dump_const_tbl,
613 simple_dump_param_tbl,
620 FOURCC('S', 'M', 'P', 'L'),
623 /* ---------------------------------------------------------------------- */
626 * count the nodes as needed:
628 * 1 normal (data) Phi's
633 static void csv_count_nodes(dumper_t *dmp, graph_entry_t *graph, counter_t cnt[])
638 for (i = 0; i < 4; ++i)
641 foreach_pset(graph->opcode_hash, entry) {
642 if (entry->op == op_Phi) {
644 cnt_add(&cnt[1], &entry->cnt_alive);
645 } else if (entry->op == dmp->status->op_PhiM) {
647 cnt_add(&cnt[2], &entry->cnt_alive);
648 } else if (entry->op == op_Proj) {
650 cnt_add(&cnt[3], &entry->cnt_alive);
652 /* all other nodes */
653 cnt_add(&cnt[0], &entry->cnt_alive);
656 } /* csv_count_nodes */
661 static void csv_dump_graph(dumper_t *dmp, graph_entry_t *entry)
669 if (entry->irg && !entry->is_deleted) {
670 ir_graph *const_irg = get_const_code_irg();
672 if (entry->irg == const_irg) {
673 name = "<Const code Irg>";
677 name = get_entity_name(entry->ent);
679 name = "<UNKNOWN IRG>";
682 csv_count_nodes(dmp, entry, cnt);
684 fprintf(dmp->f, "%-40s, %p, %d, %d, %d, %d\n",
687 cnt_to_uint(&cnt[0]),
688 cnt_to_uint(&cnt[1]),
689 cnt_to_uint(&cnt[2]),
693 } /* csv_dump_graph */
698 static void csv_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
703 } /* csv_dump_const_tbl */
706 * dumps the parameter distribution table
708 static void csv_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
713 } /* csv_dump_param_tbl */
716 * initialize the simple dumper
718 static void csv_init(dumper_t *dmp, const char *name)
722 snprintf(fname, sizeof(fname), "%s.csv", name);
723 dmp->f = fopen(fname, "a");
729 * finishes the simple dumper
731 static void csv_finish(dumper_t *dmp)
739 * the simple human readable dumper
741 const dumper_t csv_dumper = {
751 FOURCC('C', 'S', 'V', '\0')