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_CONST_PHI, "constant evaluation on Phi node" },
100 { FS_BE_IA32_LEA, "ia32 Backend transformation: Lea was created" },
101 { FS_BE_IA32_LOAD_LEA, "ia32 Backend transformation: Load merged with a Lea" },
102 { FS_BE_IA32_STORE_LEA, "ia32 Backend transformation: Store merged with a Lea" },
103 { FS_BE_IA32_AM_S, "ia32 Backend transformation: Source address mode node created" },
104 { FS_BE_IA32_AM_D, "ia32 Backend transformation: Destination address mode node created" },
105 { FS_BE_IA32_CJMP, "ia32 Backend transformation: CJmp created to save a cmp/test" },
106 { FS_BE_IA32_2ADDRCPY, "ia32 Backend transformation: Copy created due to 2-Addresscode constraints" },
107 { FS_BE_IA32_SPILL2ST, "ia32 Backend transformation: Created Store for a Spill" },
108 { FS_BE_IA32_RELOAD2LD, "ia32 Backend transformation: Created Load for a Reload" },
109 { FS_BE_IA32_SUB2NEGADD, "ia32 Backend transformation: Created Neg-Add for a Sub due to 2-Addresscode constraints" },
110 { FS_BE_IA32_LEA2ADD, "ia32 Backend transformation: Transformed Lea back into Add" },
113 static const char *if_conv_names[IF_RESULT_LAST] = {
115 "if conv side effect ",
116 "if conv Phi node found ",
117 "if conv to deep DAG's ",
118 "if conv bad control flow ",
119 "if conv denied by arch ",
123 * dumps a opcode hash into human readable form
125 static void simple_dump_opcode_hash(dumper_t *dmp, pset *set)
129 counter_t f_new_node;
133 cnt_clr(&f_new_node);
136 fprintf(dmp->f, "%-16s %-8s %-8s %-8s\n", "Opcode", "alive", "created", "->Id");
137 foreach_pset(set, entry) {
138 fprintf(dmp->f, "%-16s %8u %8u %8u\n",
139 get_id_str(entry->op->name),
140 cnt_to_uint(&entry->cnt_alive),
141 cnt_to_uint(&entry->new_node),
142 cnt_to_uint(&entry->into_Id)
145 cnt_add(&f_alive, &entry->cnt_alive);
146 cnt_add(&f_new_node, &entry->new_node);
147 cnt_add(&f_Id, &entry->into_Id);
149 fprintf(dmp->f, "-------------------------------------------\n");
150 fprintf(dmp->f, "%-16s %8u %8u %8u\n", "Sum",
151 cnt_to_uint(&f_alive),
152 cnt_to_uint(&f_new_node),
155 } /* simple_dump_opcode_hash */
158 * dumps an optimization hash into human readable form
160 static void simple_dump_opt_hash(dumper_t *dmp, pset *set, int index)
162 assert(index < (int) ARR_SIZE(opt_names) && "index out of range");
163 assert((int) opt_names[index].kind == index && "opt_names broken");
165 if (pset_count(set) > 0) {
168 fprintf(dmp->f, "\n%s:\n", opt_names[index].name);
169 fprintf(dmp->f, "%-16s %-8s\n", "Opcode", "deref");
171 foreach_pset(set, entry) {
172 fprintf(dmp->f, "%-16s %8u\n",
173 get_id_str(entry->op->name), cnt_to_uint(&entry->count));
176 } /* simple_dump_opt_hash */
179 * dumps the register pressure for each block and for each register class
181 static void simple_dump_be_block_reg_pressure(dumper_t *dmp, graph_entry_t *entry)
183 be_block_entry_t *b_entry = pset_first(entry->be_block_hash);
184 reg_pressure_entry_t *rp_entry;
186 /* return if no be statistic information available */
190 fprintf(dmp->f, "\nREG PRESSURE:\n");
191 fprintf(dmp->f, "%12s", "Block Nr");
193 /* print table head (register class names) */
194 foreach_pset(b_entry->reg_pressure, rp_entry)
195 fprintf(dmp->f, "%15s", rp_entry->class_name);
196 fprintf(dmp->f, "\n");
198 /* print the reg pressure for all blocks and register classes */
199 for (/* b_entry is already initialized */ ;
201 b_entry = pset_next(entry->be_block_hash)) {
202 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
204 foreach_pset(b_entry->reg_pressure, rp_entry)
205 fprintf(dmp->f, "%15d", rp_entry->pressure);
206 fprintf(dmp->f, "\n");
208 } /* simple_dump_be_block_reg_pressure */
210 /** prints a distribution entry */
211 static void simple_dump_distrib_entry(const distrib_entry_t *entry, void *env) {
213 fprintf(dmp->f, "%12d", cnt_to_uint(&entry->cnt));
214 } /* simple_dump_distrib_entry */
217 * dumps the distribution of the amount of ready nodes for each block
219 static void simple_dump_be_block_sched_ready(dumper_t *dmp, graph_entry_t *entry)
221 if (pset_count(entry->be_block_hash) > 0) {
222 be_block_entry_t *b_entry;
225 fprintf(dmp->f, "\nSCHEDULING: NUMBER OF READY NODES\n");
226 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s %12s\n",
227 "Block Nr", "1 node", "2 nodes", "3 nodes", "4 nodes", "5 or more", "AVERAGE");
229 foreach_pset(entry->be_block_hash, b_entry) {
230 /* this ensures that all keys from 1 to 5 are in the table */
231 for (i = 1; i < 6; ++i)
232 stat_insert_int_distrib_tbl(b_entry->sched_ready, i);
234 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
235 stat_iterate_distrib_tbl(b_entry->sched_ready, simple_dump_distrib_entry, dmp);
236 fprintf(dmp->f, "%12.2lf", stat_calc_avg_distrib_tbl(b_entry->sched_ready));
237 fprintf(dmp->f, "\n");
240 } /* simple_dump_be_block_sched_ready */
243 * Adds the counter for given entry to another distribution table.
245 static void add_distrib_entry(const distrib_entry_t *entry, void *env) {
246 distrib_tbl_t *sum_tbl = env;
248 stat_add_int_distrib_tbl(sum_tbl, (int)(entry->object), &entry->cnt);
249 } /* add_distrib_entry */
252 * dumps permutation statistics for one and block and one class
254 static void simple_dump_be_block_permstat_class(dumper_t *dmp, perm_class_entry_t *entry)
256 perm_stat_entry_t *ps_ent;
257 distrib_tbl_t *sum_chains = stat_new_int_distrib_tbl();
258 distrib_tbl_t *sum_cycles = stat_new_int_distrib_tbl();
262 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s\n",
271 foreach_pset(entry->perm_stat, ps_ent) {
272 fprintf(dmp->f, "%12d %12d %12d %12d %12d %12d\n",
275 stat_get_count_distrib_tbl(ps_ent->chains),
276 stat_get_count_distrib_tbl(ps_ent->cycles),
281 /* sum up distribution table for chains */
282 stat_iterate_distrib_tbl(ps_ent->chains, add_distrib_entry, sum_chains);
284 /* sum up distribution table for cycles */
285 stat_iterate_distrib_tbl(ps_ent->cycles, add_distrib_entry, sum_cycles);
288 /* print chain distribution for all perms of this class in this block */
289 fprintf(dmp->f, "chain distribution:\n");
291 /* add all missing entries to chain distribution table */
292 for (i = 1; i <= entry->n_regs; i++) {
293 snprintf(buf, sizeof(buf), "length %d", i);
294 fprintf(dmp->f, "%12s", buf);
295 stat_insert_int_distrib_tbl(sum_chains, i);
297 fprintf(dmp->f, "\n");
298 stat_iterate_distrib_tbl(sum_chains, simple_dump_distrib_entry, dmp);
299 fprintf(dmp->f, "\n");
301 /* print cycle distribution for all perms of this class in this block */
302 fprintf(dmp->f, "cycle distribution:\n");
304 /* add all missing entries to cycle distribution table */
305 for (i = 1; i <= entry->n_regs; i++) {
306 snprintf(buf, sizeof(buf), "length %d", i);
307 fprintf(dmp->f, "%12s", buf);
308 stat_insert_int_distrib_tbl(sum_cycles, i);
310 fprintf(dmp->f, "\n");
311 stat_iterate_distrib_tbl(sum_cycles, simple_dump_distrib_entry, dmp);
312 fprintf(dmp->f, "\n");
314 /* delete temporary sum distribution tables */
315 stat_delete_distrib_tbl(sum_chains);
316 stat_delete_distrib_tbl(sum_cycles);
318 } /* simple_dump_be_block_permstat_class */
321 * dumps statistics about perms
323 static void simple_dump_be_block_permstat(dumper_t *dmp, graph_entry_t *entry)
325 if (pset_count(entry->be_block_hash) > 0) {
326 be_block_entry_t *b_entry;
328 fprintf(dmp->f, "\nPERMUTATION STATISTICS BEGIN:\n");
329 foreach_pset(entry->be_block_hash, b_entry) {
330 perm_class_entry_t *pc_ent;
332 fprintf(dmp->f, "BLOCK %ld:\n", b_entry->block_nr);
334 if (b_entry->perm_class_stat) {
335 foreach_pset(b_entry->perm_class_stat, pc_ent) {
336 fprintf(dmp->f, "register class %s:\n", pc_ent->class_name);
337 simple_dump_be_block_permstat_class(dmp, pc_ent);
342 fprintf(dmp->f, "PERMUTATION STATISTICS END\n");
344 } /* simple_dump_be_block_permstat */
347 * dumps the number of real_function_call optimization
349 static void simple_dump_real_func_calls(dumper_t *dmp, counter_t *cnt)
354 if (! cnt_eq(cnt, 0)) {
355 fprintf(dmp->f, "\nReal Function Calls optimized:\n");
356 fprintf(dmp->f, "%-16s %8u\n", "Call", cnt_to_uint(cnt));
358 } /* simple_dump_real_func_calls */
361 * dumps the number of tail_recursion optimization
363 static void simple_dump_tail_recursion(dumper_t *dmp, unsigned num_tail_recursion)
368 if (num_tail_recursion > 0) {
369 fprintf(dmp->f, "\nTail recursion optimized:\n");
370 fprintf(dmp->f, "%-16s %8u\n", "Call", num_tail_recursion);
372 } /* simple_dump_tail_recursion */
375 * dumps the edges count
377 static void simple_dump_edges(dumper_t *dmp, counter_t *cnt)
382 fprintf(dmp->f, "%-16s %8d\n", "Edges", cnt_to_uint(cnt));
383 } /* simple_dump_edges */
388 static void simple_dump_graph(dumper_t *dmp, graph_entry_t *entry)
390 int i, dump_opts = 1;
391 block_entry_t *b_entry;
392 extbb_entry_t *eb_entry;
398 ir_graph *const_irg = get_const_code_irg();
400 if (entry->irg == const_irg)
401 fprintf(dmp->f, "\nConst code Irg %p", (void *)entry->irg);
404 fprintf(dmp->f, "\nEntity %s, Irg %p", get_entity_ld_name(entry->ent), (void *)entry->irg);
406 fprintf(dmp->f, "\nIrg %p", (void *)entry->irg);
409 fprintf(dmp->f, " %swalked %u over blocks %u:\n"
410 " was inlined : %u\n"
411 " got inlined : %u\n"
412 " strength red : %u\n"
413 " leaf function : %s\n"
414 " calls only leaf functions : %s\n"
418 " indirect calls : %u\n",
419 entry->is_deleted ? "DELETED " : "",
420 cnt_to_uint(&entry->cnt[gcnt_acc_walked]), cnt_to_uint(&entry->cnt[gcnt_acc_walked_blocks]),
421 cnt_to_uint(&entry->cnt[gcnt_acc_was_inlined]),
422 cnt_to_uint(&entry->cnt[gcnt_acc_got_inlined]),
423 cnt_to_uint(&entry->cnt[gcnt_acc_strength_red]),
424 entry->is_leaf ? "YES" : "NO",
425 entry->is_leaf_call == LCS_NON_LEAF_CALL ? "NO" : (entry->is_leaf_call == LCS_LEAF_CALL ? "Yes" : "Maybe"),
426 entry->is_recursive ? "YES" : "NO",
427 entry->is_chain_call ? "YES" : "NO",
428 cnt_to_uint(&entry->cnt[gcnt_all_calls]),
429 cnt_to_uint(&entry->cnt[gcnt_indirect_calls])
432 for (i = 0; i < IF_RESULT_LAST; ++i) {
433 fprintf(dmp->f, " %s : %u\n", if_conv_names[i], cnt_to_uint(&entry->cnt[gcnt_if_conv + i]));
436 fprintf(dmp->f, "\nGlobals counts:\n");
437 fprintf(dmp->f, "--------------\n");
443 " pure address calc ops : %u\n"
444 " all address calc ops : %u\n",
445 cnt_to_uint(&entry->cnt[gcnt_pure_adr_ops]),
446 cnt_to_uint(&entry->cnt[gcnt_all_adr_ops])
449 /* Load/Store address classification */
451 " global Ld/St address : %u\n"
452 " local Ld/St address : %u\n"
453 " this Ld/St address : %u\n"
454 " param Ld/St address : %u\n"
455 " other Ld/St address : %u\n",
456 cnt_to_uint(&entry->cnt[gcnt_global_adr]),
457 cnt_to_uint(&entry->cnt[gcnt_local_adr]),
458 cnt_to_uint(&entry->cnt[gcnt_this_adr]),
459 cnt_to_uint(&entry->cnt[gcnt_param_adr]),
460 cnt_to_uint(&entry->cnt[gcnt_other_adr])
463 simple_dump_opcode_hash(dmp, entry->opcode_hash);
464 simple_dump_edges(dmp, &entry->cnt[gcnt_edges]);
466 /* effects of optimizations */
470 simple_dump_real_func_calls(dmp, &entry->cnt[gcnt_acc_real_func_call]);
471 simple_dump_tail_recursion(dmp, entry->num_tail_recursion);
473 for (i = 0; i < sizeof(entry->opt_hash)/sizeof(entry->opt_hash[0]); ++i) {
474 simple_dump_opt_hash(dmp, entry->opt_hash[i], i);
477 /* dump block info */
478 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Block Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
479 foreach_pset(entry->block_hash, b_entry) {
480 fprintf(dmp->f, "BLK %6ld %12u %12u %12u %12u %12u %4.8f\n",
482 cnt_to_uint(&b_entry->cnt[bcnt_nodes]),
483 cnt_to_uint(&b_entry->cnt[bcnt_edges]),
484 cnt_to_uint(&b_entry->cnt[bcnt_in_edges]),
485 cnt_to_uint(&b_entry->cnt[bcnt_out_edges]),
486 cnt_to_uint(&b_entry->cnt[bcnt_phi_data]),
487 cnt_to_dbl(&b_entry->cnt[bcnt_edges]) / cnt_to_dbl(&b_entry->cnt[bcnt_nodes])
491 /* dump block reg pressure */
492 simple_dump_be_block_reg_pressure(dmp, entry);
494 /* dump block ready nodes distribution */
495 simple_dump_be_block_sched_ready(dmp, entry);
497 /* dump block permutation statistics */
498 simple_dump_be_block_permstat(dmp, entry);
500 if (dmp->status->stat_options & FIRMSTAT_COUNT_EXTBB && entry->extbb_hash) {
501 /* dump extended block info */
502 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Extbb Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
503 foreach_pset(entry->extbb_hash, eb_entry) {
504 fprintf(dmp->f, "ExtBB %6ld %12u %12u %12u %12u %12u %4.8f\n",
506 cnt_to_uint(&eb_entry->cnt[bcnt_nodes]),
507 cnt_to_uint(&eb_entry->cnt[bcnt_edges]),
508 cnt_to_uint(&eb_entry->cnt[bcnt_in_edges]),
509 cnt_to_uint(&eb_entry->cnt[bcnt_out_edges]),
510 cnt_to_uint(&eb_entry->cnt[bcnt_phi_data]),
511 cnt_to_dbl(&eb_entry->cnt[bcnt_edges]) / cnt_to_dbl(&eb_entry->cnt[bcnt_nodes])
516 } /* simple_dump_graph */
519 * dumps the constant table
521 static void simple_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
531 fprintf(dmp->f, "\nConstant Information:\n");
532 fprintf(dmp->f, "---------------------\n");
534 fprintf(dmp->f, "\nBit usage for integer constants\n");
535 fprintf(dmp->f, "-------------------------------\n");
537 for (i = 0; i < ARR_SIZE(tbl->int_bits_count); ++i) {
538 fprintf(dmp->f, "%5d %12u\n", i + 1, cnt_to_uint(&tbl->int_bits_count[i]));
539 cnt_add(&sum, &tbl->int_bits_count[i]);
541 fprintf(dmp->f, "-------------------------------\n");
543 fprintf(dmp->f, "\nFloating point constants classification\n");
544 fprintf(dmp->f, "--------------------------------------\n");
545 for (i = 0; i < ARR_SIZE(tbl->floats); ++i) {
546 fprintf(dmp->f, "%-10s %12u\n", stat_fc_name(i), cnt_to_uint(&tbl->floats[i]));
547 cnt_add(&sum, &tbl->floats[i]);
549 fprintf(dmp->f, "--------------------------------------\n");
551 fprintf(dmp->f, "other %12u\n", cnt_to_uint(&tbl->others));
552 cnt_add(&sum, &tbl->others);
553 fprintf(dmp->f, "-------------------------------\n");
555 fprintf(dmp->f, "sum %12u\n", cnt_to_uint(&sum));
556 } /* simple_dump_const_tbl */
559 * Dumps a line of the parameter table
561 static void dump_tbl_line(const distrib_entry_t *entry, void *env) {
564 fprintf(dmp->f, "%d : %u\n", PTR_TO_INT(entry->object), cnt_to_uint(&entry->cnt));
565 } /* dump_tbl_line */
568 * dumps the parameter distribution table
570 static void simple_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
571 fprintf(dmp->f, "\nCall parameter Information:\n");
572 fprintf(dmp->f, "---------------------\n");
574 stat_iterate_distrib_tbl(tbl, dump_tbl_line, dmp);
575 fprintf(dmp->f, "-------------------------------\n");
577 fprintf(dmp->f, "Number of Calls %12u\n", cnt_to_uint(&global->cnt[gcnt_all_calls]));
578 fprintf(dmp->f, "with const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_cnst_arg]));
579 fprintf(dmp->f, "with all const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_all_cnst_arg]));
580 fprintf(dmp->f, "with local var adr params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_local_adr]));
581 } /* simple_dump_param_tbl */
584 * initialize the simple dumper
586 static void simple_init(dumper_t *dmp, const char *name) {
589 snprintf(fname, sizeof(fname), "%s.txt", name);
590 dmp->f = fopen(fname, "w");
597 * finishes the simple dumper
599 static void simple_finish(dumper_t *dmp) {
603 } /* simple_finish */
606 * the simple human readable dumper
608 const dumper_t simple_dumper = {
610 simple_dump_const_tbl,
611 simple_dump_param_tbl,
618 FOURCC('S', 'M', 'P', 'L'),
621 /* ---------------------------------------------------------------------- */
624 * count the nodes as needed:
626 * 1 normal (data) Phi's
631 static void csv_count_nodes(dumper_t *dmp, graph_entry_t *graph, counter_t cnt[])
636 for (i = 0; i < 4; ++i)
639 foreach_pset(graph->opcode_hash, entry) {
640 if (entry->op == op_Phi) {
642 cnt_add(&cnt[1], &entry->cnt_alive);
643 } else if (entry->op == dmp->status->op_PhiM) {
645 cnt_add(&cnt[2], &entry->cnt_alive);
646 } else if (entry->op == op_Proj) {
648 cnt_add(&cnt[3], &entry->cnt_alive);
650 /* all other nodes */
651 cnt_add(&cnt[0], &entry->cnt_alive);
654 } /* csv_count_nodes */
659 static void csv_dump_graph(dumper_t *dmp, graph_entry_t *entry)
667 if (entry->irg && !entry->is_deleted) {
668 ir_graph *const_irg = get_const_code_irg();
670 if (entry->irg == const_irg) {
671 name = "<Const code Irg>";
675 name = get_entity_name(entry->ent);
677 name = "<UNKNOWN IRG>";
680 csv_count_nodes(dmp, entry, cnt);
682 fprintf(dmp->f, "%-40s, %p, %d, %d, %d, %d\n",
685 cnt_to_uint(&cnt[0]),
686 cnt_to_uint(&cnt[1]),
687 cnt_to_uint(&cnt[2]),
691 } /* csv_dump_graph */
696 static void csv_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
701 } /* csv_dump_const_tbl */
704 * dumps the parameter distribution table
706 static void csv_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
711 } /* csv_dump_param_tbl */
714 * initialize the simple dumper
716 static void csv_init(dumper_t *dmp, const char *name)
720 snprintf(fname, sizeof(fname), "%s.csv", name);
721 dmp->f = fopen(fname, "a");
727 * finishes the simple dumper
729 static void csv_finish(dumper_t *dmp)
737 * the simple human readable dumper
739 const dumper_t csv_dumper = {
749 FOURCC('C', 'S', 'V', '\0')