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
34 * names of the optimizations
40 { HOOK_OPT_DEAD_BLOCK, "dead block elimination" },
41 { HOOK_OPT_STG, "straightening optimization" },
42 { HOOK_OPT_IFSIM, "if simplification" },
43 { HOOK_OPT_CONST_EVAL, "constant evaluation" },
44 { HOOK_OPT_ALGSIM, "algebraic simplification" },
45 { HOOK_OPT_PHI, "Phi optmization" },
46 { HOOK_OPT_SYNC, "Sync optmization" },
47 { HOOK_OPT_WAW, "Write-After-Write optimization" },
48 { HOOK_OPT_WAR, "Write-After-Read optimization" },
49 { HOOK_OPT_RAW, "Read-After-Write optimization" },
50 { HOOK_OPT_RAR, "Read-After-Read optimization" },
51 { HOOK_OPT_RC, "Read-a-Const optimization" },
52 { HOOK_OPT_TUPLE, "Tuple optimization" },
53 { HOOK_OPT_ID, "ID optimization" },
54 { HOOK_OPT_CSE, "Common subexpression elimination" },
55 { HOOK_OPT_STRENGTH_RED, "Strength reduction" },
56 { HOOK_OPT_ARCH_DEP, "Architecture dependant optimization" },
57 { HOOK_OPT_REASSOC, "Reassociation optimization" },
58 { HOOK_OPT_POLY_CALL, "Polymorphic call optimization" },
59 { HOOK_OPT_IF_CONV, "an if conversion was tried" },
60 { HOOK_OPT_FUNC_CALL, "Real function call optimization" },
61 { HOOK_OPT_CONFIRM, "Confirm-based optimization: replacement" },
62 { HOOK_OPT_CONFIRM_C, "Confirm-based optimization: replaced by const" },
63 { HOOK_OPT_CONFIRM_E, "Confirm-based optimization: evaluated" },
64 { HOOK_OPT_EXC_REM, "a exception edge was removed due to a Confirmation prove" },
65 { HOOK_LOWERED, "Lowered" },
66 { HOOK_BACKEND, "Backend transformation" },
67 { FS_OPT_NEUTRAL_0, "algebraic simplification: a op 0 = 0 op a = a" },
68 { FS_OPT_NEUTRAL_1, "algebraic simplification: a op 1 = 1 op a = a" },
69 { FS_OPT_ADD_A_A, "algebraic simplification: a + a = a * 2" },
70 { FS_OPT_ADD_A_MINUS_B, "algebraic simplification: a + -b = a - b" },
71 { FS_OPT_ADD_SUB, "algebraic simplification: (a + x) - x = (a - x) + x = a" },
72 { FS_OPT_ADD_MUL_A_X_A, "algebraic simplification: a * x + a = a * (x + 1)" },
73 { FS_OPT_SUB_0_A, "algebraic simplification: 0 - a = -a" },
74 { FS_OPT_SUB_MUL_A_X_A, "algebraic simplification: a * x - a = a * (x - 1)" },
75 { FS_OPT_SUB_SUB_X_Y_Z, "algebraic simplification: (x - y) - z = x - (y + z)" },
76 { FS_OPT_MUL_MINUS_1, "algebraic simplification: a * -1 = -a" },
77 { FS_OPT_OR, "algebraic simplification: a | a = a | 0 = 0 | a = a" },
78 { FS_OPT_AND, "algebraic simplification: a & 0b1...1 = 0b1...1 & a = a & a = a" },
79 { FS_OPT_EOR_A_A, "algebraic simplification: a ^ a = 0" },
80 { FS_OPT_EOR_TO_NOT_BOOL,"algebraic simplification: bool ^ 1 = !bool" },
81 { FS_OPT_EOR_TO_NOT, "algebraic simplification: x ^ 0b1..1 = ~x" },
82 { FS_OPT_NOT_CMP, "algebraic simplification: !(a cmp b) = a !cmp b" },
83 { FS_OPT_OR_SHFT_TO_ROT, "algebraic simplification: (x << c) | (x >> (bits - c)) == Rot(x, c)" },
84 { FS_OPT_REASSOC_SHIFT, "algebraic simplification: (x SHF c1) SHF c2 = x SHF (c1+c2)" },
85 { FS_OPT_CONV, "algebraic simplification: Conv could be removed" },
86 { FS_OPT_CAST, "algebraic simplification: a Cast could be removed" },
87 { FS_OPT_MIN_MAX_EQ, "algebraic simplification: Min(a,a) = Max(a,a) = a" },
88 { FS_OPT_MUX_C, "algebraic simplification: Mux(C, f, t) = C ? t : f" },
89 { FS_OPT_MUX_EQ, "algebraic simplification: Mux(v, x, x) = x" },
90 { FS_OPT_MUX_TRANSFORM, "algebraic simplification: Mux(a, b, c) = b OR Mux(a,b, c) = c" },
91 { FS_OPT_MUX_TO_MIN, "algebraic simplification: Mux(a < b, a, b) = Min(a,b)" },
92 { FS_OPT_MUX_TO_MAX, "algebraic simplification: Mux(a > b, a, b) = Max(a,b)" },
93 { FS_OPT_MUX_TO_ABS, "algebraic simplification: Mux(a > b, a, b) = Abs(a,b)" },
94 { FS_OPT_MUX_TO_SHR, "algebraic simplification: Mux(a > b, a, b) = a >> b" },
95 { FS_OPT_CONST_PHI, "constant evaluation on Phi node" },
96 { FS_BE_IA32_LEA, "ia32 Backend transformation: Lea was created" },
97 { FS_BE_IA32_LOAD_LEA, "ia32 Backend transformation: Load merged with a Lea" },
98 { FS_BE_IA32_STORE_LEA, "ia32 Backend transformation: Store merged with a Lea" },
99 { FS_BE_IA32_AM_S, "ia32 Backend transformation: Source address mode node created" },
100 { FS_BE_IA32_AM_D, "ia32 Backend transformation: Destination address mode node created" },
101 { FS_BE_IA32_CJMP, "ia32 Backend transformation: CJmp created to save a cmp/test" },
102 { FS_BE_IA32_2ADDRCPY, "ia32 Backend transformation: Copy created due to 2-Addresscode constraints" },
103 { FS_BE_IA32_SPILL2ST, "ia32 Backend transformation: Created Store for a Spill" },
104 { FS_BE_IA32_RELOAD2LD, "ia32 Backend transformation: Created Load for a Reload" },
105 { FS_BE_IA32_SUB2NEGADD, "ia32 Backend transformation: Created Neg-Add for a Sub due to 2-Addresscode constraints" },
106 { FS_BE_IA32_LEA2ADD, "ia32 Backend transformation: Transformed Lea back into Add" },
109 static const char *if_conv_names[IF_RESULT_LAST] = {
111 "if conv side effect ",
112 "if conv Phi node found ",
113 "if conv to deep DAG's ",
114 "if conv bad control flow ",
115 "if conv denied by arch ",
119 * dumps a opcode hash into human readable form
121 static void simple_dump_opcode_hash(dumper_t *dmp, pset *set)
125 counter_t f_new_node;
129 cnt_clr(&f_new_node);
132 fprintf(dmp->f, "%-16s %-8s %-8s %-8s\n", "Opcode", "alive", "created", "->Id");
133 foreach_pset(set, entry) {
134 fprintf(dmp->f, "%-16s %8u %8u %8u\n",
135 get_id_str(entry->op->name),
136 cnt_to_uint(&entry->cnt_alive),
137 cnt_to_uint(&entry->new_node),
138 cnt_to_uint(&entry->into_Id)
141 cnt_add(&f_alive, &entry->cnt_alive);
142 cnt_add(&f_new_node, &entry->new_node);
143 cnt_add(&f_Id, &entry->into_Id);
145 fprintf(dmp->f, "-------------------------------------------\n");
146 fprintf(dmp->f, "%-16s %8u %8u %8u\n", "Sum",
147 cnt_to_uint(&f_alive),
148 cnt_to_uint(&f_new_node),
151 } /* simple_dump_opcode_hash */
154 * dumps an optimization hash into human readable form
156 static void simple_dump_opt_hash(dumper_t *dmp, pset *set, int index)
158 assert(index < ARR_SIZE(opt_names) && "index out of range");
159 assert(opt_names[index].kind == index && "opt_names broken");
161 if (pset_count(set) > 0) {
164 fprintf(dmp->f, "\n%s:\n", opt_names[index].name);
165 fprintf(dmp->f, "%-16s %-8s\n", "Opcode", "deref");
167 foreach_pset(set, entry) {
168 fprintf(dmp->f, "%-16s %8u\n",
169 get_id_str(entry->op->name), cnt_to_uint(&entry->count));
172 } /* simple_dump_opt_hash */
175 * dumps the register pressure for each block and for each register class
177 static void simple_dump_be_block_reg_pressure(dumper_t *dmp, graph_entry_t *entry)
179 be_block_entry_t *b_entry = pset_first(entry->be_block_hash);
180 reg_pressure_entry_t *rp_entry;
182 /* return if no be statistic information available */
186 fprintf(dmp->f, "\nREG PRESSURE:\n");
187 fprintf(dmp->f, "%12s", "Block Nr");
189 /* print table head (register class names) */
190 foreach_pset(b_entry->reg_pressure, rp_entry)
191 fprintf(dmp->f, "%15s", rp_entry->class_name);
192 fprintf(dmp->f, "\n");
194 /* print the reg pressure for all blocks and register classes */
195 for (/* b_entry is already initialized */ ;
197 b_entry = pset_next(entry->be_block_hash)) {
198 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
200 foreach_pset(b_entry->reg_pressure, rp_entry)
201 fprintf(dmp->f, "%15d", rp_entry->pressure);
202 fprintf(dmp->f, "\n");
204 } /* simple_dump_be_block_reg_pressure */
206 /** prints a distribution entry */
207 static void simple_dump_distrib_entry(const distrib_entry_t *entry, void *env) {
209 fprintf(dmp->f, "%12d", cnt_to_uint(&entry->cnt));
210 } /* simple_dump_distrib_entry */
213 * dumps the distribution of the amount of ready nodes for each block
215 static void simple_dump_be_block_sched_ready(dumper_t *dmp, graph_entry_t *entry)
217 if (pset_count(entry->be_block_hash) > 0) {
218 be_block_entry_t *b_entry;
221 fprintf(dmp->f, "\nSCHEDULING: NUMBER OF READY NODES\n");
222 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s %12s\n",
223 "Block Nr", "1 node", "2 nodes", "3 nodes", "4 nodes", "5 or more", "AVERAGE");
225 foreach_pset(entry->be_block_hash, b_entry) {
226 /* this ensures that all keys from 1 to 5 are in the table */
227 for (i = 1; i < 6; ++i)
228 stat_insert_int_distrib_tbl(b_entry->sched_ready, i);
230 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
231 stat_iterate_distrib_tbl(b_entry->sched_ready, simple_dump_distrib_entry, dmp);
232 fprintf(dmp->f, "%12.2lf", stat_calc_avg_distrib_tbl(b_entry->sched_ready));
233 fprintf(dmp->f, "\n");
236 } /* simple_dump_be_block_sched_ready */
239 * Adds the counter for given entry to another distribution table.
241 static void add_distrib_entry(const distrib_entry_t *entry, void *env) {
242 distrib_tbl_t *sum_tbl = env;
244 stat_add_int_distrib_tbl(sum_tbl, (int)(entry->object), &entry->cnt);
245 } /* add_distrib_entry */
248 * dumps permutation statistics for one and block and one class
250 static void simple_dump_be_block_permstat_class(dumper_t *dmp, perm_class_entry_t *entry)
252 perm_stat_entry_t *ps_ent;
253 distrib_tbl_t *sum_chains = stat_new_int_distrib_tbl();
254 distrib_tbl_t *sum_cycles = stat_new_int_distrib_tbl();
258 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s\n",
267 foreach_pset(entry->perm_stat, ps_ent) {
268 fprintf(dmp->f, "%12d %12d %12d %12d %12d %12d\n",
271 stat_get_count_distrib_tbl(ps_ent->chains),
272 stat_get_count_distrib_tbl(ps_ent->cycles),
277 /* sum up distribution table for chains */
278 stat_iterate_distrib_tbl(ps_ent->chains, add_distrib_entry, sum_chains);
280 /* sum up distribution table for cycles */
281 stat_iterate_distrib_tbl(ps_ent->cycles, add_distrib_entry, sum_cycles);
284 /* print chain distribution for all perms of this class in this block */
285 fprintf(dmp->f, "chain distribution:\n");
287 /* add all missing entries to chain distribution table */
288 for (i = 1; i <= entry->n_regs; i++) {
289 snprintf(buf, sizeof(buf), "length %d", i);
290 fprintf(dmp->f, "%12s", buf);
291 stat_insert_int_distrib_tbl(sum_chains, i);
293 fprintf(dmp->f, "\n");
294 stat_iterate_distrib_tbl(sum_chains, simple_dump_distrib_entry, dmp->f);
295 fprintf(dmp->f, "\n");
297 /* print cycle distribution for all perms of this class in this block */
298 fprintf(dmp->f, "cycle distribution:\n");
300 /* add all missing entries to cycle 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_cycles, i);
306 fprintf(dmp->f, "\n");
307 stat_iterate_distrib_tbl(sum_cycles, simple_dump_distrib_entry, dmp->f);
308 fprintf(dmp->f, "\n");
310 /* delete temporary sum distribution tables */
311 stat_delete_distrib_tbl(sum_chains);
312 stat_delete_distrib_tbl(sum_cycles);
314 } /* simple_dump_be_block_permstat_class */
317 * dumps statistics about perms
319 static void simple_dump_be_block_permstat(dumper_t *dmp, graph_entry_t *entry)
321 if (pset_count(entry->be_block_hash) > 0) {
322 be_block_entry_t *b_entry;
324 fprintf(dmp->f, "\nPERMUTATION STATISTICS BEGIN:\n");
325 foreach_pset(entry->be_block_hash, b_entry) {
326 perm_class_entry_t *pc_ent;
328 fprintf(dmp->f, "BLOCK %ld:\n", b_entry->block_nr);
330 if (b_entry->perm_class_stat) {
331 foreach_pset(b_entry->perm_class_stat, pc_ent) {
332 fprintf(dmp->f, "register class %s:\n", pc_ent->class_name);
333 simple_dump_be_block_permstat_class(dmp, pc_ent);
338 fprintf(dmp->f, "PERMUTATION STATISTICS END\n");
340 } /* simple_dump_be_block_permstat */
343 * dumps the number of real_function_call optimization
345 static void simple_dump_real_func_calls(dumper_t *dmp, counter_t *cnt)
350 if (! cnt_eq(cnt, 0)) {
351 fprintf(dmp->f, "\nReal Function Calls optimized:\n");
352 fprintf(dmp->f, "%-16s %8u\n", "Call", cnt_to_uint(cnt));
354 } /* simple_dump_real_func_calls */
357 * dumps the number of tail_recursion optimization
359 static void simple_dump_tail_recursion(dumper_t *dmp, unsigned num_tail_recursion)
364 if (num_tail_recursion > 0) {
365 fprintf(dmp->f, "\nTail recursion optimized:\n");
366 fprintf(dmp->f, "%-16s %8u\n", "Call", num_tail_recursion);
368 } /* simple_dump_tail_recursion */
371 * dumps the edges count
373 static void simple_dump_edges(dumper_t *dmp, counter_t *cnt)
378 fprintf(dmp->f, "%-16s %8d\n", "Edges", cnt_to_uint(cnt));
379 } /* simple_dump_edges */
384 static void simple_dump_graph(dumper_t *dmp, graph_entry_t *entry)
386 int i, dump_opts = 1;
387 block_entry_t *b_entry;
388 extbb_entry_t *eb_entry;
394 ir_graph *const_irg = get_const_code_irg();
396 if (entry->irg == const_irg)
397 fprintf(dmp->f, "\nConst code Irg %p", (void *)entry->irg);
400 fprintf(dmp->f, "\nEntity %s, Irg %p", get_entity_ld_name(entry->ent), (void *)entry->irg);
402 fprintf(dmp->f, "\nIrg %p", (void *)entry->irg);
405 fprintf(dmp->f, " %swalked %u over blocks %u:\n"
406 " was inlined : %u\n"
407 " got inlined : %u\n"
408 " strength red : %u\n"
409 " leaf function : %s\n"
410 " calls only leaf functions : %s\n"
414 " indirect calls : %u\n",
415 entry->is_deleted ? "DELETED " : "",
416 cnt_to_uint(&entry->cnt[gcnt_acc_walked]), cnt_to_uint(&entry->cnt[gcnt_acc_walked_blocks]),
417 cnt_to_uint(&entry->cnt[gcnt_acc_was_inlined]),
418 cnt_to_uint(&entry->cnt[gcnt_acc_got_inlined]),
419 cnt_to_uint(&entry->cnt[gcnt_acc_strength_red]),
420 entry->is_leaf ? "YES" : "NO",
421 entry->is_leaf_call == LCS_NON_LEAF_CALL ? "NO" : (entry->is_leaf_call == LCS_LEAF_CALL ? "Yes" : "Maybe"),
422 entry->is_recursive ? "YES" : "NO",
423 entry->is_chain_call ? "YES" : "NO",
424 cnt_to_uint(&entry->cnt[gcnt_all_calls]),
425 cnt_to_uint(&entry->cnt[gcnt_indirect_calls])
428 for (i = 0; i < IF_RESULT_LAST; ++i) {
429 fprintf(dmp->f, " %s : %u\n", if_conv_names[i], cnt_to_uint(&entry->cnt[gcnt_if_conv + i]));
432 fprintf(dmp->f, "\nGlobals counts:\n");
433 fprintf(dmp->f, "--------------\n");
439 " pure address calc ops : %u\n"
440 " all address calc ops : %u\n",
441 cnt_to_uint(&entry->cnt[gcnt_pure_adr_ops]),
442 cnt_to_uint(&entry->cnt[gcnt_all_adr_ops])
445 /* Load/Store address classification */
447 " global Ld/St address : %u\n"
448 " local Ld/St address : %u\n"
449 " this Ld/St address : %u\n"
450 " param Ld/St address : %u\n"
451 " other Ld/St address : %u\n",
452 cnt_to_uint(&entry->cnt[gcnt_global_adr]),
453 cnt_to_uint(&entry->cnt[gcnt_local_adr]),
454 cnt_to_uint(&entry->cnt[gcnt_this_adr]),
455 cnt_to_uint(&entry->cnt[gcnt_param_adr]),
456 cnt_to_uint(&entry->cnt[gcnt_other_adr])
459 simple_dump_opcode_hash(dmp, entry->opcode_hash);
460 simple_dump_edges(dmp, &entry->cnt[gcnt_edges]);
462 /* effects of optimizations */
466 simple_dump_real_func_calls(dmp, &entry->cnt[gcnt_acc_real_func_call]);
467 simple_dump_tail_recursion(dmp, entry->num_tail_recursion);
469 for (i = 0; i < sizeof(entry->opt_hash)/sizeof(entry->opt_hash[0]); ++i) {
470 simple_dump_opt_hash(dmp, entry->opt_hash[i], i);
473 /* dump block info */
474 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Block Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
475 foreach_pset(entry->block_hash, b_entry) {
476 fprintf(dmp->f, "BLK %6ld %12u %12u %12u %12u %12u %4.8f\n",
478 cnt_to_uint(&b_entry->cnt[bcnt_nodes]),
479 cnt_to_uint(&b_entry->cnt[bcnt_edges]),
480 cnt_to_uint(&b_entry->cnt[bcnt_in_edges]),
481 cnt_to_uint(&b_entry->cnt[bcnt_out_edges]),
482 cnt_to_uint(&b_entry->cnt[bcnt_phi_data]),
483 cnt_to_dbl(&b_entry->cnt[bcnt_edges]) / cnt_to_dbl(&b_entry->cnt[bcnt_nodes])
487 /* dump block reg pressure */
488 simple_dump_be_block_reg_pressure(dmp, entry);
490 /* dump block ready nodes distribution */
491 simple_dump_be_block_sched_ready(dmp, entry);
493 /* dump block permutation statistics */
494 simple_dump_be_block_permstat(dmp, entry);
496 if (dmp->status->stat_options & FIRMSTAT_COUNT_EXTBB && entry->extbb_hash) {
497 /* dump extended block info */
498 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Extbb Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
499 foreach_pset(entry->extbb_hash, eb_entry) {
500 fprintf(dmp->f, "ExtBB %6ld %12u %12u %12u %12u %12u %4.8f\n",
502 cnt_to_uint(&eb_entry->cnt[bcnt_nodes]),
503 cnt_to_uint(&eb_entry->cnt[bcnt_edges]),
504 cnt_to_uint(&eb_entry->cnt[bcnt_in_edges]),
505 cnt_to_uint(&eb_entry->cnt[bcnt_out_edges]),
506 cnt_to_uint(&eb_entry->cnt[bcnt_phi_data]),
507 cnt_to_dbl(&eb_entry->cnt[bcnt_edges]) / cnt_to_dbl(&eb_entry->cnt[bcnt_nodes])
512 } /* simple_dump_graph */
515 * dumps the constant table
517 static void simple_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
527 fprintf(dmp->f, "\nConstant Information:\n");
528 fprintf(dmp->f, "---------------------\n");
530 fprintf(dmp->f, "\nBit usage for integer constants\n");
531 fprintf(dmp->f, "-------------------------------\n");
533 for (i = 0; i < ARR_SIZE(tbl->int_bits_count); ++i) {
534 fprintf(dmp->f, "%5d %12u\n", i + 1, cnt_to_uint(&tbl->int_bits_count[i]));
535 cnt_add(&sum, &tbl->int_bits_count[i]);
537 fprintf(dmp->f, "-------------------------------\n");
539 fprintf(dmp->f, "\nFloating point constants classification\n");
540 fprintf(dmp->f, "--------------------------------------\n");
541 for (i = 0; i < ARR_SIZE(tbl->floats); ++i) {
542 fprintf(dmp->f, "%-10s %12u\n", stat_fc_name(i), cnt_to_uint(&tbl->floats[i]));
543 cnt_add(&sum, &tbl->floats[i]);
545 fprintf(dmp->f, "--------------------------------------\n");
547 fprintf(dmp->f, "other %12u\n", cnt_to_uint(&tbl->others));
548 cnt_add(&sum, &tbl->others);
549 fprintf(dmp->f, "-------------------------------\n");
551 fprintf(dmp->f, "sum %12u\n", cnt_to_uint(&sum));
552 } /* simple_dump_const_tbl */
555 * Dumps a line of the parameter table
557 static void dump_tbl_line(const distrib_entry_t *entry, void *env) {
560 fprintf(dmp->f, "%d : %u\n", PTR_TO_INT(entry->object), cnt_to_uint(&entry->cnt));
561 } /* dump_tbl_line */
564 * dumps the parameter distribution table
566 static void simple_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
567 fprintf(dmp->f, "\nCall parameter Information:\n");
568 fprintf(dmp->f, "---------------------\n");
570 stat_iterate_distrib_tbl(tbl, dump_tbl_line, dmp);
571 fprintf(dmp->f, "-------------------------------\n");
573 fprintf(dmp->f, "Number of Calls %12u\n", cnt_to_uint(&global->cnt[gcnt_all_calls]));
574 fprintf(dmp->f, "with const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_cnst_arg]));
575 fprintf(dmp->f, "with all const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_all_cnst_arg]));
576 fprintf(dmp->f, "with local var adr params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_local_adr]));
577 } /* simple_dump_param_tbl */
580 * initialize the simple dumper
582 static void simple_init(dumper_t *dmp, const char *name) {
585 snprintf(fname, sizeof(fname), "%s.txt", name);
586 dmp->f = fopen(fname, "w");
593 * finishes the simple dumper
595 static void simple_finish(dumper_t *dmp) {
599 } /* simple_finish */
602 * the simple human readable dumper
604 const dumper_t simple_dumper = {
606 simple_dump_const_tbl,
607 simple_dump_param_tbl,
614 FOURCC('S', 'M', 'P', 'L'),
617 /* ---------------------------------------------------------------------- */
620 * count the nodes as needed:
622 * 1 normal (data) Phi's
627 static void csv_count_nodes(dumper_t *dmp, graph_entry_t *graph, counter_t cnt[])
632 for (i = 0; i < 4; ++i)
635 foreach_pset(graph->opcode_hash, entry) {
636 if (entry->op == op_Phi) {
638 cnt_add(&cnt[1], &entry->cnt_alive);
639 } else if (entry->op == dmp->status->op_PhiM) {
641 cnt_add(&cnt[2], &entry->cnt_alive);
642 } else if (entry->op == op_Proj) {
644 cnt_add(&cnt[3], &entry->cnt_alive);
646 /* all other nodes */
647 cnt_add(&cnt[0], &entry->cnt_alive);
650 } /* csv_count_nodes */
655 static void csv_dump_graph(dumper_t *dmp, graph_entry_t *entry)
663 if (entry->irg && !entry->is_deleted) {
664 ir_graph *const_irg = get_const_code_irg();
666 if (entry->irg == const_irg) {
667 name = "<Const code Irg>";
671 name = get_entity_name(entry->ent);
673 name = "<UNKNOWN IRG>";
676 csv_count_nodes(dmp, entry, cnt);
678 fprintf(dmp->f, "%-40s, %p, %d, %d, %d, %d\n",
681 cnt_to_uint(&cnt[0]),
682 cnt_to_uint(&cnt[1]),
683 cnt_to_uint(&cnt[2]),
687 } /* csv_dump_graph */
692 static void csv_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
695 } /* csv_dump_const_tbl */
698 * dumps the parameter distribution table
700 static void csv_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
702 } /* csv_dump_param_tbl */
705 * initialize the simple dumper
707 static void csv_init(dumper_t *dmp, const char *name)
711 snprintf(fname, sizeof(fname), "%s.csv", name);
712 dmp->f = fopen(fname, "a");
718 * finishes the simple dumper
720 static void csv_finish(dumper_t *dmp)
728 * the simple human readable dumper
730 const dumper_t csv_dumper = {
740 FOURCC('C', 'S', 'V', '\0')