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_NOT_MINUS_1, "algebraic simplification: ~(x-1) = -x" },
102 { FS_OPT_CONST_PHI, "constant evaluation on Phi node" },
103 { FS_BE_IA32_LEA, "ia32 Backend transformation: Lea was created" },
104 { FS_BE_IA32_LOAD_LEA, "ia32 Backend transformation: Load merged with a Lea" },
105 { FS_BE_IA32_STORE_LEA, "ia32 Backend transformation: Store merged with a Lea" },
106 { FS_BE_IA32_AM_S, "ia32 Backend transformation: Source address mode node created" },
107 { FS_BE_IA32_AM_D, "ia32 Backend transformation: Destination address mode node created" },
108 { FS_BE_IA32_CJMP, "ia32 Backend transformation: CJmp created to save a cmp/test" },
109 { FS_BE_IA32_2ADDRCPY, "ia32 Backend transformation: Copy created due to 2-Addresscode constraints" },
110 { FS_BE_IA32_SPILL2ST, "ia32 Backend transformation: Created Store for a Spill" },
111 { FS_BE_IA32_RELOAD2LD, "ia32 Backend transformation: Created Load for a Reload" },
112 { FS_BE_IA32_SUB2NEGADD, "ia32 Backend transformation: Created Neg-Add for a Sub due to 2-Addresscode constraints" },
113 { FS_BE_IA32_LEA2ADD, "ia32 Backend transformation: Transformed Lea back into Add" },
116 static const char *if_conv_names[IF_RESULT_LAST] = {
118 "if conv side effect ",
119 "if conv Phi node found ",
120 "if conv to deep DAG's ",
121 "if conv bad control flow ",
122 "if conv denied by arch ",
126 * dumps a opcode hash into human readable form
128 static void simple_dump_opcode_hash(dumper_t *dmp, pset *set)
132 counter_t f_new_node;
136 cnt_clr(&f_new_node);
139 fprintf(dmp->f, "%-16s %-8s %-8s %-8s\n", "Opcode", "alive", "created", "->Id");
140 foreach_pset(set, entry) {
141 fprintf(dmp->f, "%-16s %8u %8u %8u\n",
142 get_id_str(entry->op->name),
143 cnt_to_uint(&entry->cnt_alive),
144 cnt_to_uint(&entry->new_node),
145 cnt_to_uint(&entry->into_Id)
148 cnt_add(&f_alive, &entry->cnt_alive);
149 cnt_add(&f_new_node, &entry->new_node);
150 cnt_add(&f_Id, &entry->into_Id);
152 fprintf(dmp->f, "-------------------------------------------\n");
153 fprintf(dmp->f, "%-16s %8u %8u %8u\n", "Sum",
154 cnt_to_uint(&f_alive),
155 cnt_to_uint(&f_new_node),
158 } /* simple_dump_opcode_hash */
161 * dumps an optimization hash into human readable form
163 static void simple_dump_opt_hash(dumper_t *dmp, pset *set, int index)
165 assert(index < (int) ARR_SIZE(opt_names) && "index out of range");
166 assert((int) opt_names[index].kind == index && "opt_names broken");
168 if (pset_count(set) > 0) {
171 fprintf(dmp->f, "\n%s:\n", opt_names[index].name);
172 fprintf(dmp->f, "%-16s %-8s\n", "Opcode", "deref");
174 foreach_pset(set, entry) {
175 fprintf(dmp->f, "%-16s %8u\n",
176 get_id_str(entry->op->name), cnt_to_uint(&entry->count));
179 } /* simple_dump_opt_hash */
182 * dumps the register pressure for each block and for each register class
184 static void simple_dump_be_block_reg_pressure(dumper_t *dmp, graph_entry_t *entry)
186 be_block_entry_t *b_entry = pset_first(entry->be_block_hash);
187 reg_pressure_entry_t *rp_entry;
189 /* return if no be statistic information available */
193 fprintf(dmp->f, "\nREG PRESSURE:\n");
194 fprintf(dmp->f, "%12s", "Block Nr");
196 /* print table head (register class names) */
197 foreach_pset(b_entry->reg_pressure, rp_entry)
198 fprintf(dmp->f, "%15s", rp_entry->class_name);
199 fprintf(dmp->f, "\n");
201 /* print the reg pressure for all blocks and register classes */
202 for (/* b_entry is already initialized */ ;
204 b_entry = pset_next(entry->be_block_hash)) {
205 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
207 foreach_pset(b_entry->reg_pressure, rp_entry)
208 fprintf(dmp->f, "%15d", rp_entry->pressure);
209 fprintf(dmp->f, "\n");
211 } /* simple_dump_be_block_reg_pressure */
213 /** prints a distribution entry */
214 static void simple_dump_distrib_entry(const distrib_entry_t *entry, void *env) {
216 fprintf(dmp->f, "%12d", cnt_to_uint(&entry->cnt));
217 } /* simple_dump_distrib_entry */
220 * dumps the distribution of the amount of ready nodes for each block
222 static void simple_dump_be_block_sched_ready(dumper_t *dmp, graph_entry_t *entry)
224 if (pset_count(entry->be_block_hash) > 0) {
225 be_block_entry_t *b_entry;
228 fprintf(dmp->f, "\nSCHEDULING: NUMBER OF READY NODES\n");
229 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s %12s\n",
230 "Block Nr", "1 node", "2 nodes", "3 nodes", "4 nodes", "5 or more", "AVERAGE");
232 foreach_pset(entry->be_block_hash, b_entry) {
233 /* this ensures that all keys from 1 to 5 are in the table */
234 for (i = 1; i < 6; ++i)
235 stat_insert_int_distrib_tbl(b_entry->sched_ready, i);
237 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
238 stat_iterate_distrib_tbl(b_entry->sched_ready, simple_dump_distrib_entry, dmp);
239 fprintf(dmp->f, "%12.2lf", stat_calc_avg_distrib_tbl(b_entry->sched_ready));
240 fprintf(dmp->f, "\n");
243 } /* simple_dump_be_block_sched_ready */
246 * Adds the counter for given entry to another distribution table.
248 static void add_distrib_entry(const distrib_entry_t *entry, void *env) {
249 distrib_tbl_t *sum_tbl = env;
251 stat_add_int_distrib_tbl(sum_tbl, (int)(entry->object), &entry->cnt);
252 } /* add_distrib_entry */
255 * dumps permutation statistics for one and block and one class
257 static void simple_dump_be_block_permstat_class(dumper_t *dmp, perm_class_entry_t *entry)
259 perm_stat_entry_t *ps_ent;
260 distrib_tbl_t *sum_chains = stat_new_int_distrib_tbl();
261 distrib_tbl_t *sum_cycles = stat_new_int_distrib_tbl();
265 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s\n",
274 foreach_pset(entry->perm_stat, ps_ent) {
275 fprintf(dmp->f, "%12d %12d %12d %12d %12d %12d\n",
278 stat_get_count_distrib_tbl(ps_ent->chains),
279 stat_get_count_distrib_tbl(ps_ent->cycles),
284 /* sum up distribution table for chains */
285 stat_iterate_distrib_tbl(ps_ent->chains, add_distrib_entry, sum_chains);
287 /* sum up distribution table for cycles */
288 stat_iterate_distrib_tbl(ps_ent->cycles, add_distrib_entry, sum_cycles);
291 /* print chain distribution for all perms of this class in this block */
292 fprintf(dmp->f, "chain distribution:\n");
294 /* add all missing entries to chain distribution table */
295 for (i = 1; i <= entry->n_regs; i++) {
296 snprintf(buf, sizeof(buf), "length %d", i);
297 fprintf(dmp->f, "%12s", buf);
298 stat_insert_int_distrib_tbl(sum_chains, i);
300 fprintf(dmp->f, "\n");
301 stat_iterate_distrib_tbl(sum_chains, simple_dump_distrib_entry, dmp);
302 fprintf(dmp->f, "\n");
304 /* print cycle distribution for all perms of this class in this block */
305 fprintf(dmp->f, "cycle distribution:\n");
307 /* add all missing entries to cycle distribution table */
308 for (i = 1; i <= entry->n_regs; i++) {
309 snprintf(buf, sizeof(buf), "length %d", i);
310 fprintf(dmp->f, "%12s", buf);
311 stat_insert_int_distrib_tbl(sum_cycles, i);
313 fprintf(dmp->f, "\n");
314 stat_iterate_distrib_tbl(sum_cycles, simple_dump_distrib_entry, dmp);
315 fprintf(dmp->f, "\n");
317 /* delete temporary sum distribution tables */
318 stat_delete_distrib_tbl(sum_chains);
319 stat_delete_distrib_tbl(sum_cycles);
321 } /* simple_dump_be_block_permstat_class */
324 * dumps statistics about perms
326 static void simple_dump_be_block_permstat(dumper_t *dmp, graph_entry_t *entry)
328 if (pset_count(entry->be_block_hash) > 0) {
329 be_block_entry_t *b_entry;
331 fprintf(dmp->f, "\nPERMUTATION STATISTICS BEGIN:\n");
332 foreach_pset(entry->be_block_hash, b_entry) {
333 perm_class_entry_t *pc_ent;
335 fprintf(dmp->f, "BLOCK %ld:\n", b_entry->block_nr);
337 if (b_entry->perm_class_stat) {
338 foreach_pset(b_entry->perm_class_stat, pc_ent) {
339 fprintf(dmp->f, "register class %s:\n", pc_ent->class_name);
340 simple_dump_be_block_permstat_class(dmp, pc_ent);
345 fprintf(dmp->f, "PERMUTATION STATISTICS END\n");
347 } /* simple_dump_be_block_permstat */
350 * dumps the number of real_function_call optimization
352 static void simple_dump_real_func_calls(dumper_t *dmp, counter_t *cnt)
357 if (! cnt_eq(cnt, 0)) {
358 fprintf(dmp->f, "\nReal Function Calls optimized:\n");
359 fprintf(dmp->f, "%-16s %8u\n", "Call", cnt_to_uint(cnt));
361 } /* simple_dump_real_func_calls */
364 * dumps the number of tail_recursion optimization
366 static void simple_dump_tail_recursion(dumper_t *dmp, unsigned num_tail_recursion)
371 if (num_tail_recursion > 0) {
372 fprintf(dmp->f, "\nTail recursion optimized:\n");
373 fprintf(dmp->f, "%-16s %8u\n", "Call", num_tail_recursion);
375 } /* simple_dump_tail_recursion */
378 * dumps the edges count
380 static void simple_dump_edges(dumper_t *dmp, counter_t *cnt)
385 fprintf(dmp->f, "%-16s %8d\n", "Edges", cnt_to_uint(cnt));
386 } /* simple_dump_edges */
391 static void simple_dump_graph(dumper_t *dmp, graph_entry_t *entry)
393 int i, dump_opts = 1;
394 block_entry_t *b_entry;
395 extbb_entry_t *eb_entry;
401 ir_graph *const_irg = get_const_code_irg();
403 if (entry->irg == const_irg)
404 fprintf(dmp->f, "\nConst code Irg %p", (void *)entry->irg);
407 fprintf(dmp->f, "\nEntity %s, Irg %p", get_entity_ld_name(entry->ent), (void *)entry->irg);
409 fprintf(dmp->f, "\nIrg %p", (void *)entry->irg);
412 fprintf(dmp->f, " %swalked %u over blocks %u:\n"
413 " was inlined : %u\n"
414 " got inlined : %u\n"
415 " strength red : %u\n"
416 " leaf function : %s\n"
417 " calls only leaf functions : %s\n"
421 " indirect calls : %u\n",
422 entry->is_deleted ? "DELETED " : "",
423 cnt_to_uint(&entry->cnt[gcnt_acc_walked]), cnt_to_uint(&entry->cnt[gcnt_acc_walked_blocks]),
424 cnt_to_uint(&entry->cnt[gcnt_acc_was_inlined]),
425 cnt_to_uint(&entry->cnt[gcnt_acc_got_inlined]),
426 cnt_to_uint(&entry->cnt[gcnt_acc_strength_red]),
427 entry->is_leaf ? "YES" : "NO",
428 entry->is_leaf_call == LCS_NON_LEAF_CALL ? "NO" : (entry->is_leaf_call == LCS_LEAF_CALL ? "Yes" : "Maybe"),
429 entry->is_recursive ? "YES" : "NO",
430 entry->is_chain_call ? "YES" : "NO",
431 cnt_to_uint(&entry->cnt[gcnt_all_calls]),
432 cnt_to_uint(&entry->cnt[gcnt_indirect_calls])
435 for (i = 0; i < IF_RESULT_LAST; ++i) {
436 fprintf(dmp->f, " %s : %u\n", if_conv_names[i], cnt_to_uint(&entry->cnt[gcnt_if_conv + i]));
439 fprintf(dmp->f, "\nGlobals counts:\n");
440 fprintf(dmp->f, "--------------\n");
446 " pure address calc ops : %u\n"
447 " all address calc ops : %u\n",
448 cnt_to_uint(&entry->cnt[gcnt_pure_adr_ops]),
449 cnt_to_uint(&entry->cnt[gcnt_all_adr_ops])
452 /* Load/Store address classification */
454 " global Ld/St address : %u\n"
455 " local Ld/St address : %u\n"
456 " this Ld/St address : %u\n"
457 " param Ld/St address : %u\n"
458 " other Ld/St address : %u\n",
459 cnt_to_uint(&entry->cnt[gcnt_global_adr]),
460 cnt_to_uint(&entry->cnt[gcnt_local_adr]),
461 cnt_to_uint(&entry->cnt[gcnt_this_adr]),
462 cnt_to_uint(&entry->cnt[gcnt_param_adr]),
463 cnt_to_uint(&entry->cnt[gcnt_other_adr])
466 simple_dump_opcode_hash(dmp, entry->opcode_hash);
467 simple_dump_edges(dmp, &entry->cnt[gcnt_edges]);
469 /* effects of optimizations */
473 simple_dump_real_func_calls(dmp, &entry->cnt[gcnt_acc_real_func_call]);
474 simple_dump_tail_recursion(dmp, entry->num_tail_recursion);
476 for (i = 0; i < sizeof(entry->opt_hash)/sizeof(entry->opt_hash[0]); ++i) {
477 simple_dump_opt_hash(dmp, entry->opt_hash[i], i);
480 /* dump block info */
481 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Block Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
482 foreach_pset(entry->block_hash, b_entry) {
483 fprintf(dmp->f, "BLK %6ld %12u %12u %12u %12u %12u %4.8f\n",
485 cnt_to_uint(&b_entry->cnt[bcnt_nodes]),
486 cnt_to_uint(&b_entry->cnt[bcnt_edges]),
487 cnt_to_uint(&b_entry->cnt[bcnt_in_edges]),
488 cnt_to_uint(&b_entry->cnt[bcnt_out_edges]),
489 cnt_to_uint(&b_entry->cnt[bcnt_phi_data]),
490 cnt_to_dbl(&b_entry->cnt[bcnt_edges]) / cnt_to_dbl(&b_entry->cnt[bcnt_nodes])
494 /* dump block reg pressure */
495 simple_dump_be_block_reg_pressure(dmp, entry);
497 /* dump block ready nodes distribution */
498 simple_dump_be_block_sched_ready(dmp, entry);
500 /* dump block permutation statistics */
501 simple_dump_be_block_permstat(dmp, entry);
503 if (dmp->status->stat_options & FIRMSTAT_COUNT_EXTBB && entry->extbb_hash) {
504 /* dump extended block info */
505 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Extbb Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
506 foreach_pset(entry->extbb_hash, eb_entry) {
507 fprintf(dmp->f, "ExtBB %6ld %12u %12u %12u %12u %12u %4.8f\n",
509 cnt_to_uint(&eb_entry->cnt[bcnt_nodes]),
510 cnt_to_uint(&eb_entry->cnt[bcnt_edges]),
511 cnt_to_uint(&eb_entry->cnt[bcnt_in_edges]),
512 cnt_to_uint(&eb_entry->cnt[bcnt_out_edges]),
513 cnt_to_uint(&eb_entry->cnt[bcnt_phi_data]),
514 cnt_to_dbl(&eb_entry->cnt[bcnt_edges]) / cnt_to_dbl(&eb_entry->cnt[bcnt_nodes])
519 } /* simple_dump_graph */
522 * dumps the constant table
524 static void simple_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
534 fprintf(dmp->f, "\nConstant Information:\n");
535 fprintf(dmp->f, "---------------------\n");
537 fprintf(dmp->f, "\nBit usage for integer constants\n");
538 fprintf(dmp->f, "-------------------------------\n");
540 for (i = 0; i < ARR_SIZE(tbl->int_bits_count); ++i) {
541 fprintf(dmp->f, "%5d %12u\n", i + 1, cnt_to_uint(&tbl->int_bits_count[i]));
542 cnt_add(&sum, &tbl->int_bits_count[i]);
544 fprintf(dmp->f, "-------------------------------\n");
546 fprintf(dmp->f, "\nFloating point constants classification\n");
547 fprintf(dmp->f, "--------------------------------------\n");
548 for (i = 0; i < ARR_SIZE(tbl->floats); ++i) {
549 fprintf(dmp->f, "%-10s %12u\n", stat_fc_name(i), cnt_to_uint(&tbl->floats[i]));
550 cnt_add(&sum, &tbl->floats[i]);
552 fprintf(dmp->f, "--------------------------------------\n");
554 fprintf(dmp->f, "other %12u\n", cnt_to_uint(&tbl->others));
555 cnt_add(&sum, &tbl->others);
556 fprintf(dmp->f, "-------------------------------\n");
558 fprintf(dmp->f, "sum %12u\n", cnt_to_uint(&sum));
559 } /* simple_dump_const_tbl */
562 * Dumps a line of the parameter table
564 static void dump_tbl_line(const distrib_entry_t *entry, void *env) {
567 fprintf(dmp->f, "%d : %u\n", PTR_TO_INT(entry->object), cnt_to_uint(&entry->cnt));
568 } /* dump_tbl_line */
571 * dumps the parameter distribution table
573 static void simple_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
574 fprintf(dmp->f, "\nCall parameter Information:\n");
575 fprintf(dmp->f, "---------------------\n");
577 stat_iterate_distrib_tbl(tbl, dump_tbl_line, dmp);
578 fprintf(dmp->f, "-------------------------------\n");
580 fprintf(dmp->f, "Number of Calls %12u\n", cnt_to_uint(&global->cnt[gcnt_all_calls]));
581 fprintf(dmp->f, "with const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_cnst_arg]));
582 fprintf(dmp->f, "with all const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_all_cnst_arg]));
583 fprintf(dmp->f, "with local var adr params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_local_adr]));
584 } /* simple_dump_param_tbl */
587 * initialize the simple dumper
589 static void simple_init(dumper_t *dmp, const char *name) {
592 snprintf(fname, sizeof(fname), "%s.txt", name);
593 dmp->f = fopen(fname, "w");
600 * finishes the simple dumper
602 static void simple_finish(dumper_t *dmp) {
606 } /* simple_finish */
609 * the simple human readable dumper
611 const dumper_t simple_dumper = {
613 simple_dump_const_tbl,
614 simple_dump_param_tbl,
621 FOURCC('S', 'M', 'P', 'L'),
624 /* ---------------------------------------------------------------------- */
627 * count the nodes as needed:
629 * 1 normal (data) Phi's
634 static void csv_count_nodes(dumper_t *dmp, graph_entry_t *graph, counter_t cnt[])
639 for (i = 0; i < 4; ++i)
642 foreach_pset(graph->opcode_hash, entry) {
643 if (entry->op == op_Phi) {
645 cnt_add(&cnt[1], &entry->cnt_alive);
646 } else if (entry->op == dmp->status->op_PhiM) {
648 cnt_add(&cnt[2], &entry->cnt_alive);
649 } else if (entry->op == op_Proj) {
651 cnt_add(&cnt[3], &entry->cnt_alive);
653 /* all other nodes */
654 cnt_add(&cnt[0], &entry->cnt_alive);
657 } /* csv_count_nodes */
662 static void csv_dump_graph(dumper_t *dmp, graph_entry_t *entry)
670 if (entry->irg && !entry->is_deleted) {
671 ir_graph *const_irg = get_const_code_irg();
673 if (entry->irg == const_irg) {
674 name = "<Const code Irg>";
678 name = get_entity_name(entry->ent);
680 name = "<UNKNOWN IRG>";
683 csv_count_nodes(dmp, entry, cnt);
685 fprintf(dmp->f, "%-40s, %p, %d, %d, %d, %d\n",
688 cnt_to_uint(&cnt[0]),
689 cnt_to_uint(&cnt[1]),
690 cnt_to_uint(&cnt[2]),
694 } /* csv_dump_graph */
699 static void csv_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
704 } /* csv_dump_const_tbl */
707 * dumps the parameter distribution table
709 static void csv_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
714 } /* csv_dump_param_tbl */
717 * initialize the simple dumper
719 static void csv_init(dumper_t *dmp, const char *name)
723 snprintf(fname, sizeof(fname), "%s.csv", name);
724 dmp->f = fopen(fname, "a");
730 * finishes the simple dumper
732 static void csv_finish(dumper_t *dmp)
740 * the simple human readable dumper
742 const dumper_t csv_dumper = {
752 FOURCC('C', 'S', 'V', '\0')