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_MUL_MINUS_1, "algebraic simplification: a * -1 = -a" },
79 { FS_OPT_OR, "algebraic simplification: a | a = a | 0 = 0 | a = a" },
80 { FS_OPT_AND, "algebraic simplification: a & 0b1...1 = 0b1...1 & a = a & a = a" },
81 { FS_OPT_EOR_A_A, "algebraic simplification: a ^ a = 0" },
82 { FS_OPT_EOR_TO_NOT_BOOL,"algebraic simplification: bool ^ 1 = !bool" },
83 { FS_OPT_EOR_TO_NOT, "algebraic simplification: x ^ 0b1..1 = ~x" },
84 { FS_OPT_NOT_CMP, "algebraic simplification: !(a cmp b) = a !cmp b" },
85 { FS_OPT_OR_SHFT_TO_ROT, "algebraic simplification: (x << c) | (x >> (bits - c)) == Rot(x, c)" },
86 { FS_OPT_REASSOC_SHIFT, "algebraic simplification: (x SHF c1) SHF c2 = x SHF (c1+c2)" },
87 { FS_OPT_SHIFT_AND, "algebraic simplification: (a SHF c) AND (b SHF c) = (a AND b) SHF c" },
88 { FS_OPT_SHIFT_OR, "algebraic simplification: (a SHF c) OR (b SHF c) = (a OR b) SHF c" },
89 { FS_OPT_SHIFT_EOR, "algebraic simplification: (a SHF c) XOR (b SHF c) = (a XOR b) SHF c" },
90 { FS_OPT_CONV, "algebraic simplification: Conv could be removed" },
91 { FS_OPT_CAST, "algebraic simplification: a Cast could be removed" },
92 { FS_OPT_MIN_MAX_EQ, "algebraic simplification: Min(a,a) = Max(a,a) = a" },
93 { FS_OPT_MUX_C, "algebraic simplification: Mux(C, f, t) = C ? t : f" },
94 { FS_OPT_MUX_EQ, "algebraic simplification: Mux(v, x, x) = x" },
95 { FS_OPT_MUX_TRANSFORM, "algebraic simplification: Mux(a, b, c) = b OR Mux(a,b, c) = c" },
96 { FS_OPT_MUX_TO_MIN, "algebraic simplification: Mux(a < b, a, b) = Min(a,b)" },
97 { FS_OPT_MUX_TO_MAX, "algebraic simplification: Mux(a > b, a, b) = Max(a,b)" },
98 { FS_OPT_MUX_TO_ABS, "algebraic simplification: Mux(a > b, a, b) = Abs(a,b)" },
99 { FS_OPT_MUX_TO_SHR, "algebraic simplification: Mux(a > b, a, b) = a >> b" },
100 { FS_OPT_IDEM_UNARY, "algebraic simplification: Idempotent unary operation" },
101 { FS_OPT_MINUS_NOT, "algebraic simplification: -(~x) = x + 1" },
102 { FS_OPT_NOT_MINUS_1, "algebraic simplification: ~(x - 1) = -x" },
103 { FS_OPT_NOT_PLUS_1, "algebraic simplification: ~x + 1 = -x" },
104 { FS_OPT_FP_INV_MUL, "algebraic simplification: x / y = x * (1.0/y)" },
105 { FS_OPT_CONST_PHI, "constant evaluation on Phi node" },
106 { FS_BE_IA32_LEA, "ia32 Backend transformation: Lea was created" },
107 { FS_BE_IA32_LOAD_LEA, "ia32 Backend transformation: Load merged with a Lea" },
108 { FS_BE_IA32_STORE_LEA, "ia32 Backend transformation: Store merged with a Lea" },
109 { FS_BE_IA32_AM_S, "ia32 Backend transformation: Source address mode node created" },
110 { FS_BE_IA32_AM_D, "ia32 Backend transformation: Destination address mode node created" },
111 { FS_BE_IA32_CJMP, "ia32 Backend transformation: CJmp created to save a cmp/test" },
112 { FS_BE_IA32_2ADDRCPY, "ia32 Backend transformation: Copy created due to 2-Addresscode constraints" },
113 { FS_BE_IA32_SPILL2ST, "ia32 Backend transformation: Created Store for a Spill" },
114 { FS_BE_IA32_RELOAD2LD, "ia32 Backend transformation: Created Load for a Reload" },
115 { FS_BE_IA32_SUB2NEGADD, "ia32 Backend transformation: Created Neg-Add for a Sub due to 2-Addresscode constraints" },
116 { FS_BE_IA32_LEA2ADD, "ia32 Backend transformation: Transformed Lea back into Add" },
119 static const char *if_conv_names[IF_RESULT_LAST] = {
121 "if conv side effect ",
122 "if conv Phi node found ",
123 "if conv to deep DAG's ",
124 "if conv bad control flow ",
125 "if conv denied by arch ",
129 * dumps a opcode hash into human readable form
131 static void simple_dump_opcode_hash(dumper_t *dmp, pset *set)
135 counter_t f_new_node;
139 cnt_clr(&f_new_node);
142 fprintf(dmp->f, "%-16s %-8s %-8s %-8s\n", "Opcode", "alive", "created", "->Id");
143 foreach_pset(set, entry) {
144 fprintf(dmp->f, "%-16s %8u %8u %8u\n",
145 get_id_str(entry->op->name),
146 cnt_to_uint(&entry->cnt_alive),
147 cnt_to_uint(&entry->new_node),
148 cnt_to_uint(&entry->into_Id)
151 cnt_add(&f_alive, &entry->cnt_alive);
152 cnt_add(&f_new_node, &entry->new_node);
153 cnt_add(&f_Id, &entry->into_Id);
155 fprintf(dmp->f, "-------------------------------------------\n");
156 fprintf(dmp->f, "%-16s %8u %8u %8u\n", "Sum",
157 cnt_to_uint(&f_alive),
158 cnt_to_uint(&f_new_node),
161 } /* simple_dump_opcode_hash */
164 * dumps an optimization hash into human readable form
166 static void simple_dump_opt_hash(dumper_t *dmp, pset *set, int index)
168 assert(index < (int) ARR_SIZE(opt_names) && "index out of range");
169 assert((int) opt_names[index].kind == index && "opt_names broken");
171 if (pset_count(set) > 0) {
174 fprintf(dmp->f, "\n%s:\n", opt_names[index].name);
175 fprintf(dmp->f, "%-16s %-8s\n", "Opcode", "deref");
177 foreach_pset(set, entry) {
178 fprintf(dmp->f, "%-16s %8u\n",
179 get_id_str(entry->op->name), cnt_to_uint(&entry->count));
182 } /* simple_dump_opt_hash */
185 * dumps the register pressure for each block and for each register class
187 static void simple_dump_be_block_reg_pressure(dumper_t *dmp, graph_entry_t *entry)
189 be_block_entry_t *b_entry = pset_first(entry->be_block_hash);
190 reg_pressure_entry_t *rp_entry;
192 /* return if no be statistic information available */
196 fprintf(dmp->f, "\nREG PRESSURE:\n");
197 fprintf(dmp->f, "%12s", "Block Nr");
199 /* print table head (register class names) */
200 foreach_pset(b_entry->reg_pressure, rp_entry)
201 fprintf(dmp->f, "%15s", rp_entry->class_name);
202 fprintf(dmp->f, "\n");
204 /* print the reg pressure for all blocks and register classes */
205 for (/* b_entry is already initialized */ ;
207 b_entry = pset_next(entry->be_block_hash)) {
208 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
210 foreach_pset(b_entry->reg_pressure, rp_entry)
211 fprintf(dmp->f, "%15d", rp_entry->pressure);
212 fprintf(dmp->f, "\n");
214 } /* simple_dump_be_block_reg_pressure */
216 /** prints a distribution entry */
217 static void simple_dump_distrib_entry(const distrib_entry_t *entry, void *env) {
219 fprintf(dmp->f, "%12d", cnt_to_uint(&entry->cnt));
220 } /* simple_dump_distrib_entry */
223 * dumps the distribution of the amount of ready nodes for each block
225 static void simple_dump_be_block_sched_ready(dumper_t *dmp, graph_entry_t *entry)
227 if (pset_count(entry->be_block_hash) > 0) {
228 be_block_entry_t *b_entry;
231 fprintf(dmp->f, "\nSCHEDULING: NUMBER OF READY NODES\n");
232 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s %12s\n",
233 "Block Nr", "1 node", "2 nodes", "3 nodes", "4 nodes", "5 or more", "AVERAGE");
235 foreach_pset(entry->be_block_hash, b_entry) {
236 /* this ensures that all keys from 1 to 5 are in the table */
237 for (i = 1; i < 6; ++i)
238 stat_insert_int_distrib_tbl(b_entry->sched_ready, i);
240 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
241 stat_iterate_distrib_tbl(b_entry->sched_ready, simple_dump_distrib_entry, dmp);
242 fprintf(dmp->f, "%12.2lf", stat_calc_avg_distrib_tbl(b_entry->sched_ready));
243 fprintf(dmp->f, "\n");
246 } /* simple_dump_be_block_sched_ready */
249 * Adds the counter for given entry to another distribution table.
251 static void add_distrib_entry(const distrib_entry_t *entry, void *env) {
252 distrib_tbl_t *sum_tbl = env;
254 stat_add_int_distrib_tbl(sum_tbl, (int)(entry->object), &entry->cnt);
255 } /* add_distrib_entry */
258 * dumps permutation statistics for one and block and one class
260 static void simple_dump_be_block_permstat_class(dumper_t *dmp, perm_class_entry_t *entry)
262 perm_stat_entry_t *ps_ent;
263 distrib_tbl_t *sum_chains = stat_new_int_distrib_tbl();
264 distrib_tbl_t *sum_cycles = stat_new_int_distrib_tbl();
268 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s\n",
277 foreach_pset(entry->perm_stat, ps_ent) {
278 fprintf(dmp->f, "%12d %12d %12d %12d %12d %12d\n",
281 stat_get_count_distrib_tbl(ps_ent->chains),
282 stat_get_count_distrib_tbl(ps_ent->cycles),
287 /* sum up distribution table for chains */
288 stat_iterate_distrib_tbl(ps_ent->chains, add_distrib_entry, sum_chains);
290 /* sum up distribution table for cycles */
291 stat_iterate_distrib_tbl(ps_ent->cycles, add_distrib_entry, sum_cycles);
294 /* print chain distribution for all perms of this class in this block */
295 fprintf(dmp->f, "chain distribution:\n");
297 /* add all missing entries to chain distribution table */
298 for (i = 1; i <= entry->n_regs; i++) {
299 snprintf(buf, sizeof(buf), "length %d", i);
300 fprintf(dmp->f, "%12s", buf);
301 stat_insert_int_distrib_tbl(sum_chains, i);
303 fprintf(dmp->f, "\n");
304 stat_iterate_distrib_tbl(sum_chains, simple_dump_distrib_entry, dmp);
305 fprintf(dmp->f, "\n");
307 /* print cycle distribution for all perms of this class in this block */
308 fprintf(dmp->f, "cycle distribution:\n");
310 /* add all missing entries to cycle distribution table */
311 for (i = 1; i <= entry->n_regs; i++) {
312 snprintf(buf, sizeof(buf), "length %d", i);
313 fprintf(dmp->f, "%12s", buf);
314 stat_insert_int_distrib_tbl(sum_cycles, i);
316 fprintf(dmp->f, "\n");
317 stat_iterate_distrib_tbl(sum_cycles, simple_dump_distrib_entry, dmp);
318 fprintf(dmp->f, "\n");
320 /* delete temporary sum distribution tables */
321 stat_delete_distrib_tbl(sum_chains);
322 stat_delete_distrib_tbl(sum_cycles);
324 } /* simple_dump_be_block_permstat_class */
327 * dumps statistics about perms
329 static void simple_dump_be_block_permstat(dumper_t *dmp, graph_entry_t *entry)
331 if (pset_count(entry->be_block_hash) > 0) {
332 be_block_entry_t *b_entry;
334 fprintf(dmp->f, "\nPERMUTATION STATISTICS BEGIN:\n");
335 foreach_pset(entry->be_block_hash, b_entry) {
336 perm_class_entry_t *pc_ent;
338 fprintf(dmp->f, "BLOCK %ld:\n", b_entry->block_nr);
340 if (b_entry->perm_class_stat) {
341 foreach_pset(b_entry->perm_class_stat, pc_ent) {
342 fprintf(dmp->f, "register class %s:\n", pc_ent->class_name);
343 simple_dump_be_block_permstat_class(dmp, pc_ent);
348 fprintf(dmp->f, "PERMUTATION STATISTICS END\n");
350 } /* simple_dump_be_block_permstat */
353 * dumps the number of real_function_call optimization
355 static void simple_dump_real_func_calls(dumper_t *dmp, counter_t *cnt)
360 if (! cnt_eq(cnt, 0)) {
361 fprintf(dmp->f, "\nReal Function Calls optimized:\n");
362 fprintf(dmp->f, "%-16s %8u\n", "Call", cnt_to_uint(cnt));
364 } /* simple_dump_real_func_calls */
367 * dumps the number of tail_recursion optimization
369 static void simple_dump_tail_recursion(dumper_t *dmp, unsigned num_tail_recursion)
374 if (num_tail_recursion > 0) {
375 fprintf(dmp->f, "\nTail recursion optimized:\n");
376 fprintf(dmp->f, "%-16s %8u\n", "Call", num_tail_recursion);
378 } /* simple_dump_tail_recursion */
381 * dumps the edges count
383 static void simple_dump_edges(dumper_t *dmp, counter_t *cnt)
388 fprintf(dmp->f, "%-16s %8d\n", "Edges", cnt_to_uint(cnt));
389 } /* simple_dump_edges */
394 static void simple_dump_graph(dumper_t *dmp, graph_entry_t *entry)
396 int i, dump_opts = 1;
397 block_entry_t *b_entry;
398 extbb_entry_t *eb_entry;
404 ir_graph *const_irg = get_const_code_irg();
406 if (entry->irg == const_irg)
407 fprintf(dmp->f, "\nConst code Irg %p", (void *)entry->irg);
410 fprintf(dmp->f, "\nEntity %s, Irg %p", get_entity_ld_name(entry->ent), (void *)entry->irg);
412 fprintf(dmp->f, "\nIrg %p", (void *)entry->irg);
415 fprintf(dmp->f, " %swalked %u over blocks %u:\n"
416 " was inlined : %u\n"
417 " got inlined : %u\n"
418 " strength red : %u\n"
419 " leaf function : %s\n"
420 " calls only leaf functions : %s\n"
424 " indirect calls : %u\n",
425 entry->is_deleted ? "DELETED " : "",
426 cnt_to_uint(&entry->cnt[gcnt_acc_walked]), cnt_to_uint(&entry->cnt[gcnt_acc_walked_blocks]),
427 cnt_to_uint(&entry->cnt[gcnt_acc_was_inlined]),
428 cnt_to_uint(&entry->cnt[gcnt_acc_got_inlined]),
429 cnt_to_uint(&entry->cnt[gcnt_acc_strength_red]),
430 entry->is_leaf ? "YES" : "NO",
431 entry->is_leaf_call == LCS_NON_LEAF_CALL ? "NO" : (entry->is_leaf_call == LCS_LEAF_CALL ? "Yes" : "Maybe"),
432 entry->is_recursive ? "YES" : "NO",
433 entry->is_chain_call ? "YES" : "NO",
434 cnt_to_uint(&entry->cnt[gcnt_all_calls]),
435 cnt_to_uint(&entry->cnt[gcnt_indirect_calls])
438 for (i = 0; i < IF_RESULT_LAST; ++i) {
439 fprintf(dmp->f, " %s : %u\n", if_conv_names[i], cnt_to_uint(&entry->cnt[gcnt_if_conv + i]));
442 fprintf(dmp->f, "\nGlobals counts:\n");
443 fprintf(dmp->f, "--------------\n");
449 " pure address calc ops : %u\n"
450 " all address calc ops : %u\n",
451 cnt_to_uint(&entry->cnt[gcnt_pure_adr_ops]),
452 cnt_to_uint(&entry->cnt[gcnt_all_adr_ops])
455 /* Load/Store address classification */
457 " global Ld/St address : %u\n"
458 " local Ld/St address : %u\n"
459 " this Ld/St address : %u\n"
460 " param Ld/St address : %u\n"
461 " other Ld/St address : %u\n",
462 cnt_to_uint(&entry->cnt[gcnt_global_adr]),
463 cnt_to_uint(&entry->cnt[gcnt_local_adr]),
464 cnt_to_uint(&entry->cnt[gcnt_this_adr]),
465 cnt_to_uint(&entry->cnt[gcnt_param_adr]),
466 cnt_to_uint(&entry->cnt[gcnt_other_adr])
469 simple_dump_opcode_hash(dmp, entry->opcode_hash);
470 simple_dump_edges(dmp, &entry->cnt[gcnt_edges]);
472 /* effects of optimizations */
476 simple_dump_real_func_calls(dmp, &entry->cnt[gcnt_acc_real_func_call]);
477 simple_dump_tail_recursion(dmp, entry->num_tail_recursion);
479 for (i = 0; i < sizeof(entry->opt_hash)/sizeof(entry->opt_hash[0]); ++i) {
480 simple_dump_opt_hash(dmp, entry->opt_hash[i], i);
483 /* dump block info */
484 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Block Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
485 foreach_pset(entry->block_hash, b_entry) {
486 fprintf(dmp->f, "BLK %6ld %12u %12u %12u %12u %12u %4.8f\n",
488 cnt_to_uint(&b_entry->cnt[bcnt_nodes]),
489 cnt_to_uint(&b_entry->cnt[bcnt_edges]),
490 cnt_to_uint(&b_entry->cnt[bcnt_in_edges]),
491 cnt_to_uint(&b_entry->cnt[bcnt_out_edges]),
492 cnt_to_uint(&b_entry->cnt[bcnt_phi_data]),
493 cnt_to_dbl(&b_entry->cnt[bcnt_edges]) / cnt_to_dbl(&b_entry->cnt[bcnt_nodes])
497 /* dump block reg pressure */
498 simple_dump_be_block_reg_pressure(dmp, entry);
500 /* dump block ready nodes distribution */
501 simple_dump_be_block_sched_ready(dmp, entry);
503 /* dump block permutation statistics */
504 simple_dump_be_block_permstat(dmp, entry);
506 if (dmp->status->stat_options & FIRMSTAT_COUNT_EXTBB && entry->extbb_hash) {
507 /* dump extended block info */
508 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Extbb Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
509 foreach_pset(entry->extbb_hash, eb_entry) {
510 fprintf(dmp->f, "ExtBB %6ld %12u %12u %12u %12u %12u %4.8f\n",
512 cnt_to_uint(&eb_entry->cnt[bcnt_nodes]),
513 cnt_to_uint(&eb_entry->cnt[bcnt_edges]),
514 cnt_to_uint(&eb_entry->cnt[bcnt_in_edges]),
515 cnt_to_uint(&eb_entry->cnt[bcnt_out_edges]),
516 cnt_to_uint(&eb_entry->cnt[bcnt_phi_data]),
517 cnt_to_dbl(&eb_entry->cnt[bcnt_edges]) / cnt_to_dbl(&eb_entry->cnt[bcnt_nodes])
522 } /* simple_dump_graph */
525 * dumps the constant table
527 static void simple_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
537 fprintf(dmp->f, "\nConstant Information:\n");
538 fprintf(dmp->f, "---------------------\n");
540 fprintf(dmp->f, "\nBit usage for integer constants\n");
541 fprintf(dmp->f, "-------------------------------\n");
543 for (i = 0; i < ARR_SIZE(tbl->int_bits_count); ++i) {
544 fprintf(dmp->f, "%5d %12u\n", i + 1, cnt_to_uint(&tbl->int_bits_count[i]));
545 cnt_add(&sum, &tbl->int_bits_count[i]);
547 fprintf(dmp->f, "-------------------------------\n");
549 fprintf(dmp->f, "\nFloating point constants classification\n");
550 fprintf(dmp->f, "--------------------------------------\n");
551 for (i = 0; i < ARR_SIZE(tbl->floats); ++i) {
552 fprintf(dmp->f, "%-10s %12u\n", stat_fc_name(i), cnt_to_uint(&tbl->floats[i]));
553 cnt_add(&sum, &tbl->floats[i]);
555 fprintf(dmp->f, "--------------------------------------\n");
557 fprintf(dmp->f, "other %12u\n", cnt_to_uint(&tbl->others));
558 cnt_add(&sum, &tbl->others);
559 fprintf(dmp->f, "-------------------------------\n");
561 fprintf(dmp->f, "sum %12u\n", cnt_to_uint(&sum));
562 } /* simple_dump_const_tbl */
565 * Dumps a line of the parameter table
567 static void dump_tbl_line(const distrib_entry_t *entry, void *env) {
570 fprintf(dmp->f, "%d : %u\n", PTR_TO_INT(entry->object), cnt_to_uint(&entry->cnt));
571 } /* dump_tbl_line */
574 * dumps the parameter distribution table
576 static void simple_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
577 fprintf(dmp->f, "\nCall parameter Information:\n");
578 fprintf(dmp->f, "---------------------\n");
580 stat_iterate_distrib_tbl(tbl, dump_tbl_line, dmp);
581 fprintf(dmp->f, "-------------------------------\n");
583 fprintf(dmp->f, "Number of Calls %12u\n", cnt_to_uint(&global->cnt[gcnt_all_calls]));
584 fprintf(dmp->f, "with const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_cnst_arg]));
585 fprintf(dmp->f, "with all const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_all_cnst_arg]));
586 fprintf(dmp->f, "with local var adr params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_local_adr]));
587 } /* simple_dump_param_tbl */
590 * initialize the simple dumper
592 static void simple_init(dumper_t *dmp, const char *name) {
595 snprintf(fname, sizeof(fname), "%s.txt", name);
596 dmp->f = fopen(fname, "w");
603 * finishes the simple dumper
605 static void simple_finish(dumper_t *dmp) {
609 } /* simple_finish */
612 * the simple human readable dumper
614 const dumper_t simple_dumper = {
616 simple_dump_const_tbl,
617 simple_dump_param_tbl,
624 FOURCC('S', 'M', 'P', 'L'),
627 /* ---------------------------------------------------------------------- */
630 * count the nodes as needed:
632 * 1 normal (data) Phi's
637 static void csv_count_nodes(dumper_t *dmp, graph_entry_t *graph, counter_t cnt[])
642 for (i = 0; i < 4; ++i)
645 foreach_pset(graph->opcode_hash, entry) {
646 if (entry->op == op_Phi) {
648 cnt_add(&cnt[1], &entry->cnt_alive);
649 } else if (entry->op == dmp->status->op_PhiM) {
651 cnt_add(&cnt[2], &entry->cnt_alive);
652 } else if (entry->op == op_Proj) {
654 cnt_add(&cnt[3], &entry->cnt_alive);
656 /* all other nodes */
657 cnt_add(&cnt[0], &entry->cnt_alive);
660 } /* csv_count_nodes */
665 static void csv_dump_graph(dumper_t *dmp, graph_entry_t *entry)
673 if (entry->irg && !entry->is_deleted) {
674 ir_graph *const_irg = get_const_code_irg();
676 if (entry->irg == const_irg) {
677 name = "<Const code Irg>";
681 name = get_entity_name(entry->ent);
683 name = "<UNKNOWN IRG>";
686 csv_count_nodes(dmp, entry, cnt);
688 fprintf(dmp->f, "%-40s, %p, %d, %d, %d, %d\n",
691 cnt_to_uint(&cnt[0]),
692 cnt_to_uint(&cnt[1]),
693 cnt_to_uint(&cnt[2]),
697 } /* csv_dump_graph */
702 static void csv_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
707 } /* csv_dump_const_tbl */
710 * dumps the parameter distribution table
712 static void csv_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
717 } /* csv_dump_param_tbl */
720 * initialize the simple dumper
722 static void csv_init(dumper_t *dmp, const char *name)
726 snprintf(fname, sizeof(fname), "%s.csv", name);
727 dmp->f = fopen(fname, "a");
733 * finishes the simple dumper
735 static void csv_finish(dumper_t *dmp)
743 * the simple human readable dumper
745 const dumper_t csv_dumper = {
755 FOURCC('C', 'S', 'V', '\0')