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_NOT_PLUS_1, "algebraic simplification: ~x + 1 = -x" },
103 { FS_OPT_CONST_PHI, "constant evaluation on Phi node" },
104 { FS_BE_IA32_LEA, "ia32 Backend transformation: Lea was created" },
105 { FS_BE_IA32_LOAD_LEA, "ia32 Backend transformation: Load merged with a Lea" },
106 { FS_BE_IA32_STORE_LEA, "ia32 Backend transformation: Store merged with a Lea" },
107 { FS_BE_IA32_AM_S, "ia32 Backend transformation: Source address mode node created" },
108 { FS_BE_IA32_AM_D, "ia32 Backend transformation: Destination address mode node created" },
109 { FS_BE_IA32_CJMP, "ia32 Backend transformation: CJmp created to save a cmp/test" },
110 { FS_BE_IA32_2ADDRCPY, "ia32 Backend transformation: Copy created due to 2-Addresscode constraints" },
111 { FS_BE_IA32_SPILL2ST, "ia32 Backend transformation: Created Store for a Spill" },
112 { FS_BE_IA32_RELOAD2LD, "ia32 Backend transformation: Created Load for a Reload" },
113 { FS_BE_IA32_SUB2NEGADD, "ia32 Backend transformation: Created Neg-Add for a Sub due to 2-Addresscode constraints" },
114 { FS_BE_IA32_LEA2ADD, "ia32 Backend transformation: Transformed Lea back into Add" },
117 static const char *if_conv_names[IF_RESULT_LAST] = {
119 "if conv side effect ",
120 "if conv Phi node found ",
121 "if conv to deep DAG's ",
122 "if conv bad control flow ",
123 "if conv denied by arch ",
127 * dumps a opcode hash into human readable form
129 static void simple_dump_opcode_hash(dumper_t *dmp, pset *set)
133 counter_t f_new_node;
137 cnt_clr(&f_new_node);
140 fprintf(dmp->f, "%-16s %-8s %-8s %-8s\n", "Opcode", "alive", "created", "->Id");
141 foreach_pset(set, entry) {
142 fprintf(dmp->f, "%-16s %8u %8u %8u\n",
143 get_id_str(entry->op->name),
144 cnt_to_uint(&entry->cnt_alive),
145 cnt_to_uint(&entry->new_node),
146 cnt_to_uint(&entry->into_Id)
149 cnt_add(&f_alive, &entry->cnt_alive);
150 cnt_add(&f_new_node, &entry->new_node);
151 cnt_add(&f_Id, &entry->into_Id);
153 fprintf(dmp->f, "-------------------------------------------\n");
154 fprintf(dmp->f, "%-16s %8u %8u %8u\n", "Sum",
155 cnt_to_uint(&f_alive),
156 cnt_to_uint(&f_new_node),
159 } /* simple_dump_opcode_hash */
162 * dumps an optimization hash into human readable form
164 static void simple_dump_opt_hash(dumper_t *dmp, pset *set, int index)
166 assert(index < (int) ARR_SIZE(opt_names) && "index out of range");
167 assert((int) opt_names[index].kind == index && "opt_names broken");
169 if (pset_count(set) > 0) {
172 fprintf(dmp->f, "\n%s:\n", opt_names[index].name);
173 fprintf(dmp->f, "%-16s %-8s\n", "Opcode", "deref");
175 foreach_pset(set, entry) {
176 fprintf(dmp->f, "%-16s %8u\n",
177 get_id_str(entry->op->name), cnt_to_uint(&entry->count));
180 } /* simple_dump_opt_hash */
183 * dumps the register pressure for each block and for each register class
185 static void simple_dump_be_block_reg_pressure(dumper_t *dmp, graph_entry_t *entry)
187 be_block_entry_t *b_entry = pset_first(entry->be_block_hash);
188 reg_pressure_entry_t *rp_entry;
190 /* return if no be statistic information available */
194 fprintf(dmp->f, "\nREG PRESSURE:\n");
195 fprintf(dmp->f, "%12s", "Block Nr");
197 /* print table head (register class names) */
198 foreach_pset(b_entry->reg_pressure, rp_entry)
199 fprintf(dmp->f, "%15s", rp_entry->class_name);
200 fprintf(dmp->f, "\n");
202 /* print the reg pressure for all blocks and register classes */
203 for (/* b_entry is already initialized */ ;
205 b_entry = pset_next(entry->be_block_hash)) {
206 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
208 foreach_pset(b_entry->reg_pressure, rp_entry)
209 fprintf(dmp->f, "%15d", rp_entry->pressure);
210 fprintf(dmp->f, "\n");
212 } /* simple_dump_be_block_reg_pressure */
214 /** prints a distribution entry */
215 static void simple_dump_distrib_entry(const distrib_entry_t *entry, void *env) {
217 fprintf(dmp->f, "%12d", cnt_to_uint(&entry->cnt));
218 } /* simple_dump_distrib_entry */
221 * dumps the distribution of the amount of ready nodes for each block
223 static void simple_dump_be_block_sched_ready(dumper_t *dmp, graph_entry_t *entry)
225 if (pset_count(entry->be_block_hash) > 0) {
226 be_block_entry_t *b_entry;
229 fprintf(dmp->f, "\nSCHEDULING: NUMBER OF READY NODES\n");
230 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s %12s\n",
231 "Block Nr", "1 node", "2 nodes", "3 nodes", "4 nodes", "5 or more", "AVERAGE");
233 foreach_pset(entry->be_block_hash, b_entry) {
234 /* this ensures that all keys from 1 to 5 are in the table */
235 for (i = 1; i < 6; ++i)
236 stat_insert_int_distrib_tbl(b_entry->sched_ready, i);
238 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
239 stat_iterate_distrib_tbl(b_entry->sched_ready, simple_dump_distrib_entry, dmp);
240 fprintf(dmp->f, "%12.2lf", stat_calc_avg_distrib_tbl(b_entry->sched_ready));
241 fprintf(dmp->f, "\n");
244 } /* simple_dump_be_block_sched_ready */
247 * Adds the counter for given entry to another distribution table.
249 static void add_distrib_entry(const distrib_entry_t *entry, void *env) {
250 distrib_tbl_t *sum_tbl = env;
252 stat_add_int_distrib_tbl(sum_tbl, (int)(entry->object), &entry->cnt);
253 } /* add_distrib_entry */
256 * dumps permutation statistics for one and block and one class
258 static void simple_dump_be_block_permstat_class(dumper_t *dmp, perm_class_entry_t *entry)
260 perm_stat_entry_t *ps_ent;
261 distrib_tbl_t *sum_chains = stat_new_int_distrib_tbl();
262 distrib_tbl_t *sum_cycles = stat_new_int_distrib_tbl();
266 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s\n",
275 foreach_pset(entry->perm_stat, ps_ent) {
276 fprintf(dmp->f, "%12d %12d %12d %12d %12d %12d\n",
279 stat_get_count_distrib_tbl(ps_ent->chains),
280 stat_get_count_distrib_tbl(ps_ent->cycles),
285 /* sum up distribution table for chains */
286 stat_iterate_distrib_tbl(ps_ent->chains, add_distrib_entry, sum_chains);
288 /* sum up distribution table for cycles */
289 stat_iterate_distrib_tbl(ps_ent->cycles, add_distrib_entry, sum_cycles);
292 /* print chain distribution for all perms of this class in this block */
293 fprintf(dmp->f, "chain distribution:\n");
295 /* add all missing entries to chain distribution table */
296 for (i = 1; i <= entry->n_regs; i++) {
297 snprintf(buf, sizeof(buf), "length %d", i);
298 fprintf(dmp->f, "%12s", buf);
299 stat_insert_int_distrib_tbl(sum_chains, i);
301 fprintf(dmp->f, "\n");
302 stat_iterate_distrib_tbl(sum_chains, simple_dump_distrib_entry, dmp);
303 fprintf(dmp->f, "\n");
305 /* print cycle distribution for all perms of this class in this block */
306 fprintf(dmp->f, "cycle distribution:\n");
308 /* add all missing entries to cycle distribution table */
309 for (i = 1; i <= entry->n_regs; i++) {
310 snprintf(buf, sizeof(buf), "length %d", i);
311 fprintf(dmp->f, "%12s", buf);
312 stat_insert_int_distrib_tbl(sum_cycles, i);
314 fprintf(dmp->f, "\n");
315 stat_iterate_distrib_tbl(sum_cycles, simple_dump_distrib_entry, dmp);
316 fprintf(dmp->f, "\n");
318 /* delete temporary sum distribution tables */
319 stat_delete_distrib_tbl(sum_chains);
320 stat_delete_distrib_tbl(sum_cycles);
322 } /* simple_dump_be_block_permstat_class */
325 * dumps statistics about perms
327 static void simple_dump_be_block_permstat(dumper_t *dmp, graph_entry_t *entry)
329 if (pset_count(entry->be_block_hash) > 0) {
330 be_block_entry_t *b_entry;
332 fprintf(dmp->f, "\nPERMUTATION STATISTICS BEGIN:\n");
333 foreach_pset(entry->be_block_hash, b_entry) {
334 perm_class_entry_t *pc_ent;
336 fprintf(dmp->f, "BLOCK %ld:\n", b_entry->block_nr);
338 if (b_entry->perm_class_stat) {
339 foreach_pset(b_entry->perm_class_stat, pc_ent) {
340 fprintf(dmp->f, "register class %s:\n", pc_ent->class_name);
341 simple_dump_be_block_permstat_class(dmp, pc_ent);
346 fprintf(dmp->f, "PERMUTATION STATISTICS END\n");
348 } /* simple_dump_be_block_permstat */
351 * dumps the number of real_function_call optimization
353 static void simple_dump_real_func_calls(dumper_t *dmp, counter_t *cnt)
358 if (! cnt_eq(cnt, 0)) {
359 fprintf(dmp->f, "\nReal Function Calls optimized:\n");
360 fprintf(dmp->f, "%-16s %8u\n", "Call", cnt_to_uint(cnt));
362 } /* simple_dump_real_func_calls */
365 * dumps the number of tail_recursion optimization
367 static void simple_dump_tail_recursion(dumper_t *dmp, unsigned num_tail_recursion)
372 if (num_tail_recursion > 0) {
373 fprintf(dmp->f, "\nTail recursion optimized:\n");
374 fprintf(dmp->f, "%-16s %8u\n", "Call", num_tail_recursion);
376 } /* simple_dump_tail_recursion */
379 * dumps the edges count
381 static void simple_dump_edges(dumper_t *dmp, counter_t *cnt)
386 fprintf(dmp->f, "%-16s %8d\n", "Edges", cnt_to_uint(cnt));
387 } /* simple_dump_edges */
392 static void simple_dump_graph(dumper_t *dmp, graph_entry_t *entry)
394 int i, dump_opts = 1;
395 block_entry_t *b_entry;
396 extbb_entry_t *eb_entry;
402 ir_graph *const_irg = get_const_code_irg();
404 if (entry->irg == const_irg)
405 fprintf(dmp->f, "\nConst code Irg %p", (void *)entry->irg);
408 fprintf(dmp->f, "\nEntity %s, Irg %p", get_entity_ld_name(entry->ent), (void *)entry->irg);
410 fprintf(dmp->f, "\nIrg %p", (void *)entry->irg);
413 fprintf(dmp->f, " %swalked %u over blocks %u:\n"
414 " was inlined : %u\n"
415 " got inlined : %u\n"
416 " strength red : %u\n"
417 " leaf function : %s\n"
418 " calls only leaf functions : %s\n"
422 " indirect calls : %u\n",
423 entry->is_deleted ? "DELETED " : "",
424 cnt_to_uint(&entry->cnt[gcnt_acc_walked]), cnt_to_uint(&entry->cnt[gcnt_acc_walked_blocks]),
425 cnt_to_uint(&entry->cnt[gcnt_acc_was_inlined]),
426 cnt_to_uint(&entry->cnt[gcnt_acc_got_inlined]),
427 cnt_to_uint(&entry->cnt[gcnt_acc_strength_red]),
428 entry->is_leaf ? "YES" : "NO",
429 entry->is_leaf_call == LCS_NON_LEAF_CALL ? "NO" : (entry->is_leaf_call == LCS_LEAF_CALL ? "Yes" : "Maybe"),
430 entry->is_recursive ? "YES" : "NO",
431 entry->is_chain_call ? "YES" : "NO",
432 cnt_to_uint(&entry->cnt[gcnt_all_calls]),
433 cnt_to_uint(&entry->cnt[gcnt_indirect_calls])
436 for (i = 0; i < IF_RESULT_LAST; ++i) {
437 fprintf(dmp->f, " %s : %u\n", if_conv_names[i], cnt_to_uint(&entry->cnt[gcnt_if_conv + i]));
440 fprintf(dmp->f, "\nGlobals counts:\n");
441 fprintf(dmp->f, "--------------\n");
447 " pure address calc ops : %u\n"
448 " all address calc ops : %u\n",
449 cnt_to_uint(&entry->cnt[gcnt_pure_adr_ops]),
450 cnt_to_uint(&entry->cnt[gcnt_all_adr_ops])
453 /* Load/Store address classification */
455 " global Ld/St address : %u\n"
456 " local Ld/St address : %u\n"
457 " this Ld/St address : %u\n"
458 " param Ld/St address : %u\n"
459 " other Ld/St address : %u\n",
460 cnt_to_uint(&entry->cnt[gcnt_global_adr]),
461 cnt_to_uint(&entry->cnt[gcnt_local_adr]),
462 cnt_to_uint(&entry->cnt[gcnt_this_adr]),
463 cnt_to_uint(&entry->cnt[gcnt_param_adr]),
464 cnt_to_uint(&entry->cnt[gcnt_other_adr])
467 simple_dump_opcode_hash(dmp, entry->opcode_hash);
468 simple_dump_edges(dmp, &entry->cnt[gcnt_edges]);
470 /* effects of optimizations */
474 simple_dump_real_func_calls(dmp, &entry->cnt[gcnt_acc_real_func_call]);
475 simple_dump_tail_recursion(dmp, entry->num_tail_recursion);
477 for (i = 0; i < sizeof(entry->opt_hash)/sizeof(entry->opt_hash[0]); ++i) {
478 simple_dump_opt_hash(dmp, entry->opt_hash[i], i);
481 /* dump block info */
482 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Block Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
483 foreach_pset(entry->block_hash, b_entry) {
484 fprintf(dmp->f, "BLK %6ld %12u %12u %12u %12u %12u %4.8f\n",
486 cnt_to_uint(&b_entry->cnt[bcnt_nodes]),
487 cnt_to_uint(&b_entry->cnt[bcnt_edges]),
488 cnt_to_uint(&b_entry->cnt[bcnt_in_edges]),
489 cnt_to_uint(&b_entry->cnt[bcnt_out_edges]),
490 cnt_to_uint(&b_entry->cnt[bcnt_phi_data]),
491 cnt_to_dbl(&b_entry->cnt[bcnt_edges]) / cnt_to_dbl(&b_entry->cnt[bcnt_nodes])
495 /* dump block reg pressure */
496 simple_dump_be_block_reg_pressure(dmp, entry);
498 /* dump block ready nodes distribution */
499 simple_dump_be_block_sched_ready(dmp, entry);
501 /* dump block permutation statistics */
502 simple_dump_be_block_permstat(dmp, entry);
504 if (dmp->status->stat_options & FIRMSTAT_COUNT_EXTBB && entry->extbb_hash) {
505 /* dump extended block info */
506 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Extbb Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
507 foreach_pset(entry->extbb_hash, eb_entry) {
508 fprintf(dmp->f, "ExtBB %6ld %12u %12u %12u %12u %12u %4.8f\n",
510 cnt_to_uint(&eb_entry->cnt[bcnt_nodes]),
511 cnt_to_uint(&eb_entry->cnt[bcnt_edges]),
512 cnt_to_uint(&eb_entry->cnt[bcnt_in_edges]),
513 cnt_to_uint(&eb_entry->cnt[bcnt_out_edges]),
514 cnt_to_uint(&eb_entry->cnt[bcnt_phi_data]),
515 cnt_to_dbl(&eb_entry->cnt[bcnt_edges]) / cnt_to_dbl(&eb_entry->cnt[bcnt_nodes])
520 } /* simple_dump_graph */
523 * dumps the constant table
525 static void simple_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
535 fprintf(dmp->f, "\nConstant Information:\n");
536 fprintf(dmp->f, "---------------------\n");
538 fprintf(dmp->f, "\nBit usage for integer constants\n");
539 fprintf(dmp->f, "-------------------------------\n");
541 for (i = 0; i < ARR_SIZE(tbl->int_bits_count); ++i) {
542 fprintf(dmp->f, "%5d %12u\n", i + 1, cnt_to_uint(&tbl->int_bits_count[i]));
543 cnt_add(&sum, &tbl->int_bits_count[i]);
545 fprintf(dmp->f, "-------------------------------\n");
547 fprintf(dmp->f, "\nFloating point constants classification\n");
548 fprintf(dmp->f, "--------------------------------------\n");
549 for (i = 0; i < ARR_SIZE(tbl->floats); ++i) {
550 fprintf(dmp->f, "%-10s %12u\n", stat_fc_name(i), cnt_to_uint(&tbl->floats[i]));
551 cnt_add(&sum, &tbl->floats[i]);
553 fprintf(dmp->f, "--------------------------------------\n");
555 fprintf(dmp->f, "other %12u\n", cnt_to_uint(&tbl->others));
556 cnt_add(&sum, &tbl->others);
557 fprintf(dmp->f, "-------------------------------\n");
559 fprintf(dmp->f, "sum %12u\n", cnt_to_uint(&sum));
560 } /* simple_dump_const_tbl */
563 * Dumps a line of the parameter table
565 static void dump_tbl_line(const distrib_entry_t *entry, void *env) {
568 fprintf(dmp->f, "%d : %u\n", PTR_TO_INT(entry->object), cnt_to_uint(&entry->cnt));
569 } /* dump_tbl_line */
572 * dumps the parameter distribution table
574 static void simple_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
575 fprintf(dmp->f, "\nCall parameter Information:\n");
576 fprintf(dmp->f, "---------------------\n");
578 stat_iterate_distrib_tbl(tbl, dump_tbl_line, dmp);
579 fprintf(dmp->f, "-------------------------------\n");
581 fprintf(dmp->f, "Number of Calls %12u\n", cnt_to_uint(&global->cnt[gcnt_all_calls]));
582 fprintf(dmp->f, "with const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_cnst_arg]));
583 fprintf(dmp->f, "with all const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_all_cnst_arg]));
584 fprintf(dmp->f, "with local var adr params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_local_adr]));
585 } /* simple_dump_param_tbl */
588 * initialize the simple dumper
590 static void simple_init(dumper_t *dmp, const char *name) {
593 snprintf(fname, sizeof(fname), "%s.txt", name);
594 dmp->f = fopen(fname, "w");
601 * finishes the simple dumper
603 static void simple_finish(dumper_t *dmp) {
607 } /* simple_finish */
610 * the simple human readable dumper
612 const dumper_t simple_dumper = {
614 simple_dump_const_tbl,
615 simple_dump_param_tbl,
622 FOURCC('S', 'M', 'P', 'L'),
625 /* ---------------------------------------------------------------------- */
628 * count the nodes as needed:
630 * 1 normal (data) Phi's
635 static void csv_count_nodes(dumper_t *dmp, graph_entry_t *graph, counter_t cnt[])
640 for (i = 0; i < 4; ++i)
643 foreach_pset(graph->opcode_hash, entry) {
644 if (entry->op == op_Phi) {
646 cnt_add(&cnt[1], &entry->cnt_alive);
647 } else if (entry->op == dmp->status->op_PhiM) {
649 cnt_add(&cnt[2], &entry->cnt_alive);
650 } else if (entry->op == op_Proj) {
652 cnt_add(&cnt[3], &entry->cnt_alive);
654 /* all other nodes */
655 cnt_add(&cnt[0], &entry->cnt_alive);
658 } /* csv_count_nodes */
663 static void csv_dump_graph(dumper_t *dmp, graph_entry_t *entry)
671 if (entry->irg && !entry->is_deleted) {
672 ir_graph *const_irg = get_const_code_irg();
674 if (entry->irg == const_irg) {
675 name = "<Const code Irg>";
679 name = get_entity_name(entry->ent);
681 name = "<UNKNOWN IRG>";
684 csv_count_nodes(dmp, entry, cnt);
686 fprintf(dmp->f, "%-40s, %p, %d, %d, %d, %d\n",
689 cnt_to_uint(&cnt[0]),
690 cnt_to_uint(&cnt[1]),
691 cnt_to_uint(&cnt[2]),
695 } /* csv_dump_graph */
700 static void csv_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
705 } /* csv_dump_const_tbl */
708 * dumps the parameter distribution table
710 static void csv_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
715 } /* csv_dump_param_tbl */
718 * initialize the simple dumper
720 static void csv_init(dumper_t *dmp, const char *name)
724 snprintf(fname, sizeof(fname), "%s.csv", name);
725 dmp->f = fopen(fname, "a");
731 * finishes the simple dumper
733 static void csv_finish(dumper_t *dmp)
741 * the simple human readable dumper
743 const dumper_t csv_dumper = {
753 FOURCC('C', 'S', 'V', '\0')