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_CONV, "algebraic simplification: Conv could be removed" },
87 { FS_OPT_CAST, "algebraic simplification: a Cast could be removed" },
88 { FS_OPT_MIN_MAX_EQ, "algebraic simplification: Min(a,a) = Max(a,a) = a" },
89 { FS_OPT_MUX_C, "algebraic simplification: Mux(C, f, t) = C ? t : f" },
90 { FS_OPT_MUX_EQ, "algebraic simplification: Mux(v, x, x) = x" },
91 { FS_OPT_MUX_TRANSFORM, "algebraic simplification: Mux(a, b, c) = b OR Mux(a,b, c) = c" },
92 { FS_OPT_MUX_TO_MIN, "algebraic simplification: Mux(a < b, a, b) = Min(a,b)" },
93 { FS_OPT_MUX_TO_MAX, "algebraic simplification: Mux(a > b, a, b) = Max(a,b)" },
94 { FS_OPT_MUX_TO_ABS, "algebraic simplification: Mux(a > b, a, b) = Abs(a,b)" },
95 { FS_OPT_MUX_TO_SHR, "algebraic simplification: Mux(a > b, a, b) = a >> b" },
96 { FS_OPT_CONST_PHI, "constant evaluation on Phi node" },
97 { FS_BE_IA32_LEA, "ia32 Backend transformation: Lea was created" },
98 { FS_BE_IA32_LOAD_LEA, "ia32 Backend transformation: Load merged with a Lea" },
99 { FS_BE_IA32_STORE_LEA, "ia32 Backend transformation: Store merged with a Lea" },
100 { FS_BE_IA32_AM_S, "ia32 Backend transformation: Source address mode node created" },
101 { FS_BE_IA32_AM_D, "ia32 Backend transformation: Destination address mode node created" },
102 { FS_BE_IA32_CJMP, "ia32 Backend transformation: CJmp created to save a cmp/test" },
103 { FS_BE_IA32_2ADDRCPY, "ia32 Backend transformation: Copy created due to 2-Addresscode constraints" },
104 { FS_BE_IA32_SPILL2ST, "ia32 Backend transformation: Created Store for a Spill" },
105 { FS_BE_IA32_RELOAD2LD, "ia32 Backend transformation: Created Load for a Reload" },
106 { FS_BE_IA32_SUB2NEGADD, "ia32 Backend transformation: Created Neg-Add for a Sub due to 2-Addresscode constraints" },
107 { FS_BE_IA32_LEA2ADD, "ia32 Backend transformation: Transformed Lea back into Add" },
110 static const char *if_conv_names[IF_RESULT_LAST] = {
112 "if conv side effect ",
113 "if conv Phi node found ",
114 "if conv to deep DAG's ",
115 "if conv bad control flow ",
116 "if conv denied by arch ",
120 * dumps a opcode hash into human readable form
122 static void simple_dump_opcode_hash(dumper_t *dmp, pset *set)
126 counter_t f_new_node;
130 cnt_clr(&f_new_node);
133 fprintf(dmp->f, "%-16s %-8s %-8s %-8s\n", "Opcode", "alive", "created", "->Id");
134 foreach_pset(set, entry) {
135 fprintf(dmp->f, "%-16s %8u %8u %8u\n",
136 get_id_str(entry->op->name),
137 cnt_to_uint(&entry->cnt_alive),
138 cnt_to_uint(&entry->new_node),
139 cnt_to_uint(&entry->into_Id)
142 cnt_add(&f_alive, &entry->cnt_alive);
143 cnt_add(&f_new_node, &entry->new_node);
144 cnt_add(&f_Id, &entry->into_Id);
146 fprintf(dmp->f, "-------------------------------------------\n");
147 fprintf(dmp->f, "%-16s %8u %8u %8u\n", "Sum",
148 cnt_to_uint(&f_alive),
149 cnt_to_uint(&f_new_node),
152 } /* simple_dump_opcode_hash */
155 * dumps an optimization hash into human readable form
157 static void simple_dump_opt_hash(dumper_t *dmp, pset *set, int index)
159 assert(index < (int) ARR_SIZE(opt_names) && "index out of range");
160 assert((int) opt_names[index].kind == index && "opt_names broken");
162 if (pset_count(set) > 0) {
165 fprintf(dmp->f, "\n%s:\n", opt_names[index].name);
166 fprintf(dmp->f, "%-16s %-8s\n", "Opcode", "deref");
168 foreach_pset(set, entry) {
169 fprintf(dmp->f, "%-16s %8u\n",
170 get_id_str(entry->op->name), cnt_to_uint(&entry->count));
173 } /* simple_dump_opt_hash */
176 * dumps the register pressure for each block and for each register class
178 static void simple_dump_be_block_reg_pressure(dumper_t *dmp, graph_entry_t *entry)
180 be_block_entry_t *b_entry = pset_first(entry->be_block_hash);
181 reg_pressure_entry_t *rp_entry;
183 /* return if no be statistic information available */
187 fprintf(dmp->f, "\nREG PRESSURE:\n");
188 fprintf(dmp->f, "%12s", "Block Nr");
190 /* print table head (register class names) */
191 foreach_pset(b_entry->reg_pressure, rp_entry)
192 fprintf(dmp->f, "%15s", rp_entry->class_name);
193 fprintf(dmp->f, "\n");
195 /* print the reg pressure for all blocks and register classes */
196 for (/* b_entry is already initialized */ ;
198 b_entry = pset_next(entry->be_block_hash)) {
199 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
201 foreach_pset(b_entry->reg_pressure, rp_entry)
202 fprintf(dmp->f, "%15d", rp_entry->pressure);
203 fprintf(dmp->f, "\n");
205 } /* simple_dump_be_block_reg_pressure */
207 /** prints a distribution entry */
208 static void simple_dump_distrib_entry(const distrib_entry_t *entry, void *env) {
210 fprintf(dmp->f, "%12d", cnt_to_uint(&entry->cnt));
211 } /* simple_dump_distrib_entry */
214 * dumps the distribution of the amount of ready nodes for each block
216 static void simple_dump_be_block_sched_ready(dumper_t *dmp, graph_entry_t *entry)
218 if (pset_count(entry->be_block_hash) > 0) {
219 be_block_entry_t *b_entry;
222 fprintf(dmp->f, "\nSCHEDULING: NUMBER OF READY NODES\n");
223 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s %12s\n",
224 "Block Nr", "1 node", "2 nodes", "3 nodes", "4 nodes", "5 or more", "AVERAGE");
226 foreach_pset(entry->be_block_hash, b_entry) {
227 /* this ensures that all keys from 1 to 5 are in the table */
228 for (i = 1; i < 6; ++i)
229 stat_insert_int_distrib_tbl(b_entry->sched_ready, i);
231 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
232 stat_iterate_distrib_tbl(b_entry->sched_ready, simple_dump_distrib_entry, dmp);
233 fprintf(dmp->f, "%12.2lf", stat_calc_avg_distrib_tbl(b_entry->sched_ready));
234 fprintf(dmp->f, "\n");
237 } /* simple_dump_be_block_sched_ready */
240 * Adds the counter for given entry to another distribution table.
242 static void add_distrib_entry(const distrib_entry_t *entry, void *env) {
243 distrib_tbl_t *sum_tbl = env;
245 stat_add_int_distrib_tbl(sum_tbl, (int)(entry->object), &entry->cnt);
246 } /* add_distrib_entry */
249 * dumps permutation statistics for one and block and one class
251 static void simple_dump_be_block_permstat_class(dumper_t *dmp, perm_class_entry_t *entry)
253 perm_stat_entry_t *ps_ent;
254 distrib_tbl_t *sum_chains = stat_new_int_distrib_tbl();
255 distrib_tbl_t *sum_cycles = stat_new_int_distrib_tbl();
259 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s\n",
268 foreach_pset(entry->perm_stat, ps_ent) {
269 fprintf(dmp->f, "%12d %12d %12d %12d %12d %12d\n",
272 stat_get_count_distrib_tbl(ps_ent->chains),
273 stat_get_count_distrib_tbl(ps_ent->cycles),
278 /* sum up distribution table for chains */
279 stat_iterate_distrib_tbl(ps_ent->chains, add_distrib_entry, sum_chains);
281 /* sum up distribution table for cycles */
282 stat_iterate_distrib_tbl(ps_ent->cycles, add_distrib_entry, sum_cycles);
285 /* print chain distribution for all perms of this class in this block */
286 fprintf(dmp->f, "chain distribution:\n");
288 /* add all missing entries to chain distribution table */
289 for (i = 1; i <= entry->n_regs; i++) {
290 snprintf(buf, sizeof(buf), "length %d", i);
291 fprintf(dmp->f, "%12s", buf);
292 stat_insert_int_distrib_tbl(sum_chains, i);
294 fprintf(dmp->f, "\n");
295 stat_iterate_distrib_tbl(sum_chains, simple_dump_distrib_entry, dmp);
296 fprintf(dmp->f, "\n");
298 /* print cycle distribution for all perms of this class in this block */
299 fprintf(dmp->f, "cycle distribution:\n");
301 /* add all missing entries to cycle distribution table */
302 for (i = 1; i <= entry->n_regs; i++) {
303 snprintf(buf, sizeof(buf), "length %d", i);
304 fprintf(dmp->f, "%12s", buf);
305 stat_insert_int_distrib_tbl(sum_cycles, i);
307 fprintf(dmp->f, "\n");
308 stat_iterate_distrib_tbl(sum_cycles, simple_dump_distrib_entry, dmp);
309 fprintf(dmp->f, "\n");
311 /* delete temporary sum distribution tables */
312 stat_delete_distrib_tbl(sum_chains);
313 stat_delete_distrib_tbl(sum_cycles);
315 } /* simple_dump_be_block_permstat_class */
318 * dumps statistics about perms
320 static void simple_dump_be_block_permstat(dumper_t *dmp, graph_entry_t *entry)
322 if (pset_count(entry->be_block_hash) > 0) {
323 be_block_entry_t *b_entry;
325 fprintf(dmp->f, "\nPERMUTATION STATISTICS BEGIN:\n");
326 foreach_pset(entry->be_block_hash, b_entry) {
327 perm_class_entry_t *pc_ent;
329 fprintf(dmp->f, "BLOCK %ld:\n", b_entry->block_nr);
331 if (b_entry->perm_class_stat) {
332 foreach_pset(b_entry->perm_class_stat, pc_ent) {
333 fprintf(dmp->f, "register class %s:\n", pc_ent->class_name);
334 simple_dump_be_block_permstat_class(dmp, pc_ent);
339 fprintf(dmp->f, "PERMUTATION STATISTICS END\n");
341 } /* simple_dump_be_block_permstat */
344 * dumps the number of real_function_call optimization
346 static void simple_dump_real_func_calls(dumper_t *dmp, counter_t *cnt)
351 if (! cnt_eq(cnt, 0)) {
352 fprintf(dmp->f, "\nReal Function Calls optimized:\n");
353 fprintf(dmp->f, "%-16s %8u\n", "Call", cnt_to_uint(cnt));
355 } /* simple_dump_real_func_calls */
358 * dumps the number of tail_recursion optimization
360 static void simple_dump_tail_recursion(dumper_t *dmp, unsigned num_tail_recursion)
365 if (num_tail_recursion > 0) {
366 fprintf(dmp->f, "\nTail recursion optimized:\n");
367 fprintf(dmp->f, "%-16s %8u\n", "Call", num_tail_recursion);
369 } /* simple_dump_tail_recursion */
372 * dumps the edges count
374 static void simple_dump_edges(dumper_t *dmp, counter_t *cnt)
379 fprintf(dmp->f, "%-16s %8d\n", "Edges", cnt_to_uint(cnt));
380 } /* simple_dump_edges */
385 static void simple_dump_graph(dumper_t *dmp, graph_entry_t *entry)
387 int i, dump_opts = 1;
388 block_entry_t *b_entry;
389 extbb_entry_t *eb_entry;
395 ir_graph *const_irg = get_const_code_irg();
397 if (entry->irg == const_irg)
398 fprintf(dmp->f, "\nConst code Irg %p", (void *)entry->irg);
401 fprintf(dmp->f, "\nEntity %s, Irg %p", get_entity_ld_name(entry->ent), (void *)entry->irg);
403 fprintf(dmp->f, "\nIrg %p", (void *)entry->irg);
406 fprintf(dmp->f, " %swalked %u over blocks %u:\n"
407 " was inlined : %u\n"
408 " got inlined : %u\n"
409 " strength red : %u\n"
410 " leaf function : %s\n"
411 " calls only leaf functions : %s\n"
415 " indirect calls : %u\n",
416 entry->is_deleted ? "DELETED " : "",
417 cnt_to_uint(&entry->cnt[gcnt_acc_walked]), cnt_to_uint(&entry->cnt[gcnt_acc_walked_blocks]),
418 cnt_to_uint(&entry->cnt[gcnt_acc_was_inlined]),
419 cnt_to_uint(&entry->cnt[gcnt_acc_got_inlined]),
420 cnt_to_uint(&entry->cnt[gcnt_acc_strength_red]),
421 entry->is_leaf ? "YES" : "NO",
422 entry->is_leaf_call == LCS_NON_LEAF_CALL ? "NO" : (entry->is_leaf_call == LCS_LEAF_CALL ? "Yes" : "Maybe"),
423 entry->is_recursive ? "YES" : "NO",
424 entry->is_chain_call ? "YES" : "NO",
425 cnt_to_uint(&entry->cnt[gcnt_all_calls]),
426 cnt_to_uint(&entry->cnt[gcnt_indirect_calls])
429 for (i = 0; i < IF_RESULT_LAST; ++i) {
430 fprintf(dmp->f, " %s : %u\n", if_conv_names[i], cnt_to_uint(&entry->cnt[gcnt_if_conv + i]));
433 fprintf(dmp->f, "\nGlobals counts:\n");
434 fprintf(dmp->f, "--------------\n");
440 " pure address calc ops : %u\n"
441 " all address calc ops : %u\n",
442 cnt_to_uint(&entry->cnt[gcnt_pure_adr_ops]),
443 cnt_to_uint(&entry->cnt[gcnt_all_adr_ops])
446 /* Load/Store address classification */
448 " global Ld/St address : %u\n"
449 " local Ld/St address : %u\n"
450 " this Ld/St address : %u\n"
451 " param Ld/St address : %u\n"
452 " other Ld/St address : %u\n",
453 cnt_to_uint(&entry->cnt[gcnt_global_adr]),
454 cnt_to_uint(&entry->cnt[gcnt_local_adr]),
455 cnt_to_uint(&entry->cnt[gcnt_this_adr]),
456 cnt_to_uint(&entry->cnt[gcnt_param_adr]),
457 cnt_to_uint(&entry->cnt[gcnt_other_adr])
460 simple_dump_opcode_hash(dmp, entry->opcode_hash);
461 simple_dump_edges(dmp, &entry->cnt[gcnt_edges]);
463 /* effects of optimizations */
467 simple_dump_real_func_calls(dmp, &entry->cnt[gcnt_acc_real_func_call]);
468 simple_dump_tail_recursion(dmp, entry->num_tail_recursion);
470 for (i = 0; i < sizeof(entry->opt_hash)/sizeof(entry->opt_hash[0]); ++i) {
471 simple_dump_opt_hash(dmp, entry->opt_hash[i], i);
474 /* dump block info */
475 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Block Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
476 foreach_pset(entry->block_hash, b_entry) {
477 fprintf(dmp->f, "BLK %6ld %12u %12u %12u %12u %12u %4.8f\n",
479 cnt_to_uint(&b_entry->cnt[bcnt_nodes]),
480 cnt_to_uint(&b_entry->cnt[bcnt_edges]),
481 cnt_to_uint(&b_entry->cnt[bcnt_in_edges]),
482 cnt_to_uint(&b_entry->cnt[bcnt_out_edges]),
483 cnt_to_uint(&b_entry->cnt[bcnt_phi_data]),
484 cnt_to_dbl(&b_entry->cnt[bcnt_edges]) / cnt_to_dbl(&b_entry->cnt[bcnt_nodes])
488 /* dump block reg pressure */
489 simple_dump_be_block_reg_pressure(dmp, entry);
491 /* dump block ready nodes distribution */
492 simple_dump_be_block_sched_ready(dmp, entry);
494 /* dump block permutation statistics */
495 simple_dump_be_block_permstat(dmp, entry);
497 if (dmp->status->stat_options & FIRMSTAT_COUNT_EXTBB && entry->extbb_hash) {
498 /* dump extended block info */
499 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Extbb Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
500 foreach_pset(entry->extbb_hash, eb_entry) {
501 fprintf(dmp->f, "ExtBB %6ld %12u %12u %12u %12u %12u %4.8f\n",
503 cnt_to_uint(&eb_entry->cnt[bcnt_nodes]),
504 cnt_to_uint(&eb_entry->cnt[bcnt_edges]),
505 cnt_to_uint(&eb_entry->cnt[bcnt_in_edges]),
506 cnt_to_uint(&eb_entry->cnt[bcnt_out_edges]),
507 cnt_to_uint(&eb_entry->cnt[bcnt_phi_data]),
508 cnt_to_dbl(&eb_entry->cnt[bcnt_edges]) / cnt_to_dbl(&eb_entry->cnt[bcnt_nodes])
513 } /* simple_dump_graph */
516 * dumps the constant table
518 static void simple_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
528 fprintf(dmp->f, "\nConstant Information:\n");
529 fprintf(dmp->f, "---------------------\n");
531 fprintf(dmp->f, "\nBit usage for integer constants\n");
532 fprintf(dmp->f, "-------------------------------\n");
534 for (i = 0; i < ARR_SIZE(tbl->int_bits_count); ++i) {
535 fprintf(dmp->f, "%5d %12u\n", i + 1, cnt_to_uint(&tbl->int_bits_count[i]));
536 cnt_add(&sum, &tbl->int_bits_count[i]);
538 fprintf(dmp->f, "-------------------------------\n");
540 fprintf(dmp->f, "\nFloating point constants classification\n");
541 fprintf(dmp->f, "--------------------------------------\n");
542 for (i = 0; i < ARR_SIZE(tbl->floats); ++i) {
543 fprintf(dmp->f, "%-10s %12u\n", stat_fc_name(i), cnt_to_uint(&tbl->floats[i]));
544 cnt_add(&sum, &tbl->floats[i]);
546 fprintf(dmp->f, "--------------------------------------\n");
548 fprintf(dmp->f, "other %12u\n", cnt_to_uint(&tbl->others));
549 cnt_add(&sum, &tbl->others);
550 fprintf(dmp->f, "-------------------------------\n");
552 fprintf(dmp->f, "sum %12u\n", cnt_to_uint(&sum));
553 } /* simple_dump_const_tbl */
556 * Dumps a line of the parameter table
558 static void dump_tbl_line(const distrib_entry_t *entry, void *env) {
561 fprintf(dmp->f, "%d : %u\n", PTR_TO_INT(entry->object), cnt_to_uint(&entry->cnt));
562 } /* dump_tbl_line */
565 * dumps the parameter distribution table
567 static void simple_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
568 fprintf(dmp->f, "\nCall parameter Information:\n");
569 fprintf(dmp->f, "---------------------\n");
571 stat_iterate_distrib_tbl(tbl, dump_tbl_line, dmp);
572 fprintf(dmp->f, "-------------------------------\n");
574 fprintf(dmp->f, "Number of Calls %12u\n", cnt_to_uint(&global->cnt[gcnt_all_calls]));
575 fprintf(dmp->f, "with const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_cnst_arg]));
576 fprintf(dmp->f, "with all const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_all_cnst_arg]));
577 fprintf(dmp->f, "with local var adr params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_local_adr]));
578 } /* simple_dump_param_tbl */
581 * initialize the simple dumper
583 static void simple_init(dumper_t *dmp, const char *name) {
586 snprintf(fname, sizeof(fname), "%s.txt", name);
587 dmp->f = fopen(fname, "w");
594 * finishes the simple dumper
596 static void simple_finish(dumper_t *dmp) {
600 } /* simple_finish */
603 * the simple human readable dumper
605 const dumper_t simple_dumper = {
607 simple_dump_const_tbl,
608 simple_dump_param_tbl,
615 FOURCC('S', 'M', 'P', 'L'),
618 /* ---------------------------------------------------------------------- */
621 * count the nodes as needed:
623 * 1 normal (data) Phi's
628 static void csv_count_nodes(dumper_t *dmp, graph_entry_t *graph, counter_t cnt[])
633 for (i = 0; i < 4; ++i)
636 foreach_pset(graph->opcode_hash, entry) {
637 if (entry->op == op_Phi) {
639 cnt_add(&cnt[1], &entry->cnt_alive);
640 } else if (entry->op == dmp->status->op_PhiM) {
642 cnt_add(&cnt[2], &entry->cnt_alive);
643 } else if (entry->op == op_Proj) {
645 cnt_add(&cnt[3], &entry->cnt_alive);
647 /* all other nodes */
648 cnt_add(&cnt[0], &entry->cnt_alive);
651 } /* csv_count_nodes */
656 static void csv_dump_graph(dumper_t *dmp, graph_entry_t *entry)
664 if (entry->irg && !entry->is_deleted) {
665 ir_graph *const_irg = get_const_code_irg();
667 if (entry->irg == const_irg) {
668 name = "<Const code Irg>";
672 name = get_entity_name(entry->ent);
674 name = "<UNKNOWN IRG>";
677 csv_count_nodes(dmp, entry, cnt);
679 fprintf(dmp->f, "%-40s, %p, %d, %d, %d, %d\n",
682 cnt_to_uint(&cnt[0]),
683 cnt_to_uint(&cnt[1]),
684 cnt_to_uint(&cnt[2]),
688 } /* csv_dump_graph */
693 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) {
708 } /* csv_dump_param_tbl */
711 * initialize the simple dumper
713 static void csv_init(dumper_t *dmp, const char *name)
717 snprintf(fname, sizeof(fname), "%s.csv", name);
718 dmp->f = fopen(fname, "a");
724 * finishes the simple dumper
726 static void csv_finish(dumper_t *dmp)
734 * the simple human readable dumper
736 const dumper_t csv_dumper = {
746 FOURCC('C', 'S', 'V', '\0')