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_FP_INV_MUL, "algebraic simplification: x / y = x * (1.0/y)" },
104 { FS_OPT_CONST_PHI, "constant evaluation on Phi node" },
105 { FS_BE_IA32_LEA, "ia32 Backend transformation: Lea was created" },
106 { FS_BE_IA32_LOAD_LEA, "ia32 Backend transformation: Load merged with a Lea" },
107 { FS_BE_IA32_STORE_LEA, "ia32 Backend transformation: Store merged with a Lea" },
108 { FS_BE_IA32_AM_S, "ia32 Backend transformation: Source address mode node created" },
109 { FS_BE_IA32_AM_D, "ia32 Backend transformation: Destination address mode node created" },
110 { FS_BE_IA32_CJMP, "ia32 Backend transformation: CJmp created to save a cmp/test" },
111 { FS_BE_IA32_2ADDRCPY, "ia32 Backend transformation: Copy created due to 2-Addresscode constraints" },
112 { FS_BE_IA32_SPILL2ST, "ia32 Backend transformation: Created Store for a Spill" },
113 { FS_BE_IA32_RELOAD2LD, "ia32 Backend transformation: Created Load for a Reload" },
114 { FS_BE_IA32_SUB2NEGADD, "ia32 Backend transformation: Created Neg-Add for a Sub due to 2-Addresscode constraints" },
115 { FS_BE_IA32_LEA2ADD, "ia32 Backend transformation: Transformed Lea back into Add" },
118 static const char *if_conv_names[IF_RESULT_LAST] = {
120 "if conv side effect ",
121 "if conv Phi node found ",
122 "if conv to deep DAG's ",
123 "if conv bad control flow ",
124 "if conv denied by arch ",
128 * dumps a opcode hash into human readable form
130 static void simple_dump_opcode_hash(dumper_t *dmp, pset *set)
134 counter_t f_new_node;
138 cnt_clr(&f_new_node);
141 fprintf(dmp->f, "%-16s %-8s %-8s %-8s\n", "Opcode", "alive", "created", "->Id");
142 foreach_pset(set, entry) {
143 fprintf(dmp->f, "%-16s %8u %8u %8u\n",
144 get_id_str(entry->op->name),
145 cnt_to_uint(&entry->cnt_alive),
146 cnt_to_uint(&entry->new_node),
147 cnt_to_uint(&entry->into_Id)
150 cnt_add(&f_alive, &entry->cnt_alive);
151 cnt_add(&f_new_node, &entry->new_node);
152 cnt_add(&f_Id, &entry->into_Id);
154 fprintf(dmp->f, "-------------------------------------------\n");
155 fprintf(dmp->f, "%-16s %8u %8u %8u\n", "Sum",
156 cnt_to_uint(&f_alive),
157 cnt_to_uint(&f_new_node),
160 } /* simple_dump_opcode_hash */
163 * dumps an optimization hash into human readable form
165 static void simple_dump_opt_hash(dumper_t *dmp, pset *set, int index)
167 assert(index < (int) ARR_SIZE(opt_names) && "index out of range");
168 assert((int) opt_names[index].kind == index && "opt_names broken");
170 if (pset_count(set) > 0) {
173 fprintf(dmp->f, "\n%s:\n", opt_names[index].name);
174 fprintf(dmp->f, "%-16s %-8s\n", "Opcode", "deref");
176 foreach_pset(set, entry) {
177 fprintf(dmp->f, "%-16s %8u\n",
178 get_id_str(entry->op->name), cnt_to_uint(&entry->count));
181 } /* simple_dump_opt_hash */
184 * dumps the register pressure for each block and for each register class
186 static void simple_dump_be_block_reg_pressure(dumper_t *dmp, graph_entry_t *entry)
188 be_block_entry_t *b_entry = pset_first(entry->be_block_hash);
189 reg_pressure_entry_t *rp_entry;
191 /* return if no be statistic information available */
195 fprintf(dmp->f, "\nREG PRESSURE:\n");
196 fprintf(dmp->f, "%12s", "Block Nr");
198 /* print table head (register class names) */
199 foreach_pset(b_entry->reg_pressure, rp_entry)
200 fprintf(dmp->f, "%15s", rp_entry->class_name);
201 fprintf(dmp->f, "\n");
203 /* print the reg pressure for all blocks and register classes */
204 for (/* b_entry is already initialized */ ;
206 b_entry = pset_next(entry->be_block_hash)) {
207 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
209 foreach_pset(b_entry->reg_pressure, rp_entry)
210 fprintf(dmp->f, "%15d", rp_entry->pressure);
211 fprintf(dmp->f, "\n");
213 } /* simple_dump_be_block_reg_pressure */
215 /** prints a distribution entry */
216 static void simple_dump_distrib_entry(const distrib_entry_t *entry, void *env) {
218 fprintf(dmp->f, "%12d", cnt_to_uint(&entry->cnt));
219 } /* simple_dump_distrib_entry */
222 * dumps the distribution of the amount of ready nodes for each block
224 static void simple_dump_be_block_sched_ready(dumper_t *dmp, graph_entry_t *entry)
226 if (pset_count(entry->be_block_hash) > 0) {
227 be_block_entry_t *b_entry;
230 fprintf(dmp->f, "\nSCHEDULING: NUMBER OF READY NODES\n");
231 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s %12s\n",
232 "Block Nr", "1 node", "2 nodes", "3 nodes", "4 nodes", "5 or more", "AVERAGE");
234 foreach_pset(entry->be_block_hash, b_entry) {
235 /* this ensures that all keys from 1 to 5 are in the table */
236 for (i = 1; i < 6; ++i)
237 stat_insert_int_distrib_tbl(b_entry->sched_ready, i);
239 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
240 stat_iterate_distrib_tbl(b_entry->sched_ready, simple_dump_distrib_entry, dmp);
241 fprintf(dmp->f, "%12.2lf", stat_calc_avg_distrib_tbl(b_entry->sched_ready));
242 fprintf(dmp->f, "\n");
245 } /* simple_dump_be_block_sched_ready */
248 * Adds the counter for given entry to another distribution table.
250 static void add_distrib_entry(const distrib_entry_t *entry, void *env) {
251 distrib_tbl_t *sum_tbl = env;
253 stat_add_int_distrib_tbl(sum_tbl, (int)(entry->object), &entry->cnt);
254 } /* add_distrib_entry */
257 * dumps permutation statistics for one and block and one class
259 static void simple_dump_be_block_permstat_class(dumper_t *dmp, perm_class_entry_t *entry)
261 perm_stat_entry_t *ps_ent;
262 distrib_tbl_t *sum_chains = stat_new_int_distrib_tbl();
263 distrib_tbl_t *sum_cycles = stat_new_int_distrib_tbl();
267 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s\n",
276 foreach_pset(entry->perm_stat, ps_ent) {
277 fprintf(dmp->f, "%12d %12d %12d %12d %12d %12d\n",
280 stat_get_count_distrib_tbl(ps_ent->chains),
281 stat_get_count_distrib_tbl(ps_ent->cycles),
286 /* sum up distribution table for chains */
287 stat_iterate_distrib_tbl(ps_ent->chains, add_distrib_entry, sum_chains);
289 /* sum up distribution table for cycles */
290 stat_iterate_distrib_tbl(ps_ent->cycles, add_distrib_entry, sum_cycles);
293 /* print chain distribution for all perms of this class in this block */
294 fprintf(dmp->f, "chain distribution:\n");
296 /* add all missing entries to chain distribution table */
297 for (i = 1; i <= entry->n_regs; i++) {
298 snprintf(buf, sizeof(buf), "length %d", i);
299 fprintf(dmp->f, "%12s", buf);
300 stat_insert_int_distrib_tbl(sum_chains, i);
302 fprintf(dmp->f, "\n");
303 stat_iterate_distrib_tbl(sum_chains, simple_dump_distrib_entry, dmp);
304 fprintf(dmp->f, "\n");
306 /* print cycle distribution for all perms of this class in this block */
307 fprintf(dmp->f, "cycle distribution:\n");
309 /* add all missing entries to cycle distribution table */
310 for (i = 1; i <= entry->n_regs; i++) {
311 snprintf(buf, sizeof(buf), "length %d", i);
312 fprintf(dmp->f, "%12s", buf);
313 stat_insert_int_distrib_tbl(sum_cycles, i);
315 fprintf(dmp->f, "\n");
316 stat_iterate_distrib_tbl(sum_cycles, simple_dump_distrib_entry, dmp);
317 fprintf(dmp->f, "\n");
319 /* delete temporary sum distribution tables */
320 stat_delete_distrib_tbl(sum_chains);
321 stat_delete_distrib_tbl(sum_cycles);
323 } /* simple_dump_be_block_permstat_class */
326 * dumps statistics about perms
328 static void simple_dump_be_block_permstat(dumper_t *dmp, graph_entry_t *entry)
330 if (pset_count(entry->be_block_hash) > 0) {
331 be_block_entry_t *b_entry;
333 fprintf(dmp->f, "\nPERMUTATION STATISTICS BEGIN:\n");
334 foreach_pset(entry->be_block_hash, b_entry) {
335 perm_class_entry_t *pc_ent;
337 fprintf(dmp->f, "BLOCK %ld:\n", b_entry->block_nr);
339 if (b_entry->perm_class_stat) {
340 foreach_pset(b_entry->perm_class_stat, pc_ent) {
341 fprintf(dmp->f, "register class %s:\n", pc_ent->class_name);
342 simple_dump_be_block_permstat_class(dmp, pc_ent);
347 fprintf(dmp->f, "PERMUTATION STATISTICS END\n");
349 } /* simple_dump_be_block_permstat */
352 * dumps the number of real_function_call optimization
354 static void simple_dump_real_func_calls(dumper_t *dmp, counter_t *cnt)
359 if (! cnt_eq(cnt, 0)) {
360 fprintf(dmp->f, "\nReal Function Calls optimized:\n");
361 fprintf(dmp->f, "%-16s %8u\n", "Call", cnt_to_uint(cnt));
363 } /* simple_dump_real_func_calls */
366 * dumps the number of tail_recursion optimization
368 static void simple_dump_tail_recursion(dumper_t *dmp, unsigned num_tail_recursion)
373 if (num_tail_recursion > 0) {
374 fprintf(dmp->f, "\nTail recursion optimized:\n");
375 fprintf(dmp->f, "%-16s %8u\n", "Call", num_tail_recursion);
377 } /* simple_dump_tail_recursion */
380 * dumps the edges count
382 static void simple_dump_edges(dumper_t *dmp, counter_t *cnt)
387 fprintf(dmp->f, "%-16s %8d\n", "Edges", cnt_to_uint(cnt));
388 } /* simple_dump_edges */
393 static void simple_dump_graph(dumper_t *dmp, graph_entry_t *entry)
395 int i, dump_opts = 1;
396 block_entry_t *b_entry;
397 extbb_entry_t *eb_entry;
403 ir_graph *const_irg = get_const_code_irg();
405 if (entry->irg == const_irg)
406 fprintf(dmp->f, "\nConst code Irg %p", (void *)entry->irg);
409 fprintf(dmp->f, "\nEntity %s, Irg %p", get_entity_ld_name(entry->ent), (void *)entry->irg);
411 fprintf(dmp->f, "\nIrg %p", (void *)entry->irg);
414 fprintf(dmp->f, " %swalked %u over blocks %u:\n"
415 " was inlined : %u\n"
416 " got inlined : %u\n"
417 " strength red : %u\n"
418 " leaf function : %s\n"
419 " calls only leaf functions : %s\n"
423 " indirect calls : %u\n",
424 entry->is_deleted ? "DELETED " : "",
425 cnt_to_uint(&entry->cnt[gcnt_acc_walked]), cnt_to_uint(&entry->cnt[gcnt_acc_walked_blocks]),
426 cnt_to_uint(&entry->cnt[gcnt_acc_was_inlined]),
427 cnt_to_uint(&entry->cnt[gcnt_acc_got_inlined]),
428 cnt_to_uint(&entry->cnt[gcnt_acc_strength_red]),
429 entry->is_leaf ? "YES" : "NO",
430 entry->is_leaf_call == LCS_NON_LEAF_CALL ? "NO" : (entry->is_leaf_call == LCS_LEAF_CALL ? "Yes" : "Maybe"),
431 entry->is_recursive ? "YES" : "NO",
432 entry->is_chain_call ? "YES" : "NO",
433 cnt_to_uint(&entry->cnt[gcnt_all_calls]),
434 cnt_to_uint(&entry->cnt[gcnt_indirect_calls])
437 for (i = 0; i < IF_RESULT_LAST; ++i) {
438 fprintf(dmp->f, " %s : %u\n", if_conv_names[i], cnt_to_uint(&entry->cnt[gcnt_if_conv + i]));
441 fprintf(dmp->f, "\nGlobals counts:\n");
442 fprintf(dmp->f, "--------------\n");
448 " pure address calc ops : %u\n"
449 " all address calc ops : %u\n",
450 cnt_to_uint(&entry->cnt[gcnt_pure_adr_ops]),
451 cnt_to_uint(&entry->cnt[gcnt_all_adr_ops])
454 /* Load/Store address classification */
456 " global Ld/St address : %u\n"
457 " local Ld/St address : %u\n"
458 " this Ld/St address : %u\n"
459 " param Ld/St address : %u\n"
460 " other Ld/St address : %u\n",
461 cnt_to_uint(&entry->cnt[gcnt_global_adr]),
462 cnt_to_uint(&entry->cnt[gcnt_local_adr]),
463 cnt_to_uint(&entry->cnt[gcnt_this_adr]),
464 cnt_to_uint(&entry->cnt[gcnt_param_adr]),
465 cnt_to_uint(&entry->cnt[gcnt_other_adr])
468 simple_dump_opcode_hash(dmp, entry->opcode_hash);
469 simple_dump_edges(dmp, &entry->cnt[gcnt_edges]);
471 /* effects of optimizations */
475 simple_dump_real_func_calls(dmp, &entry->cnt[gcnt_acc_real_func_call]);
476 simple_dump_tail_recursion(dmp, entry->num_tail_recursion);
478 for (i = 0; i < sizeof(entry->opt_hash)/sizeof(entry->opt_hash[0]); ++i) {
479 simple_dump_opt_hash(dmp, entry->opt_hash[i], i);
482 /* dump block info */
483 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Block Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
484 foreach_pset(entry->block_hash, b_entry) {
485 fprintf(dmp->f, "BLK %6ld %12u %12u %12u %12u %12u %4.8f\n",
487 cnt_to_uint(&b_entry->cnt[bcnt_nodes]),
488 cnt_to_uint(&b_entry->cnt[bcnt_edges]),
489 cnt_to_uint(&b_entry->cnt[bcnt_in_edges]),
490 cnt_to_uint(&b_entry->cnt[bcnt_out_edges]),
491 cnt_to_uint(&b_entry->cnt[bcnt_phi_data]),
492 cnt_to_dbl(&b_entry->cnt[bcnt_edges]) / cnt_to_dbl(&b_entry->cnt[bcnt_nodes])
496 /* dump block reg pressure */
497 simple_dump_be_block_reg_pressure(dmp, entry);
499 /* dump block ready nodes distribution */
500 simple_dump_be_block_sched_ready(dmp, entry);
502 /* dump block permutation statistics */
503 simple_dump_be_block_permstat(dmp, entry);
505 if (dmp->status->stat_options & FIRMSTAT_COUNT_EXTBB && entry->extbb_hash) {
506 /* dump extended block info */
507 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Extbb Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
508 foreach_pset(entry->extbb_hash, eb_entry) {
509 fprintf(dmp->f, "ExtBB %6ld %12u %12u %12u %12u %12u %4.8f\n",
511 cnt_to_uint(&eb_entry->cnt[bcnt_nodes]),
512 cnt_to_uint(&eb_entry->cnt[bcnt_edges]),
513 cnt_to_uint(&eb_entry->cnt[bcnt_in_edges]),
514 cnt_to_uint(&eb_entry->cnt[bcnt_out_edges]),
515 cnt_to_uint(&eb_entry->cnt[bcnt_phi_data]),
516 cnt_to_dbl(&eb_entry->cnt[bcnt_edges]) / cnt_to_dbl(&eb_entry->cnt[bcnt_nodes])
521 } /* simple_dump_graph */
524 * dumps the constant table
526 static void simple_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
536 fprintf(dmp->f, "\nConstant Information:\n");
537 fprintf(dmp->f, "---------------------\n");
539 fprintf(dmp->f, "\nBit usage for integer constants\n");
540 fprintf(dmp->f, "-------------------------------\n");
542 for (i = 0; i < ARR_SIZE(tbl->int_bits_count); ++i) {
543 fprintf(dmp->f, "%5d %12u\n", i + 1, cnt_to_uint(&tbl->int_bits_count[i]));
544 cnt_add(&sum, &tbl->int_bits_count[i]);
546 fprintf(dmp->f, "-------------------------------\n");
548 fprintf(dmp->f, "\nFloating point constants classification\n");
549 fprintf(dmp->f, "--------------------------------------\n");
550 for (i = 0; i < ARR_SIZE(tbl->floats); ++i) {
551 fprintf(dmp->f, "%-10s %12u\n", stat_fc_name(i), cnt_to_uint(&tbl->floats[i]));
552 cnt_add(&sum, &tbl->floats[i]);
554 fprintf(dmp->f, "--------------------------------------\n");
556 fprintf(dmp->f, "other %12u\n", cnt_to_uint(&tbl->others));
557 cnt_add(&sum, &tbl->others);
558 fprintf(dmp->f, "-------------------------------\n");
560 fprintf(dmp->f, "sum %12u\n", cnt_to_uint(&sum));
561 } /* simple_dump_const_tbl */
564 * Dumps a line of the parameter table
566 static void dump_tbl_line(const distrib_entry_t *entry, void *env) {
569 fprintf(dmp->f, "%d : %u\n", PTR_TO_INT(entry->object), cnt_to_uint(&entry->cnt));
570 } /* dump_tbl_line */
573 * dumps the parameter distribution table
575 static void simple_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
576 fprintf(dmp->f, "\nCall parameter Information:\n");
577 fprintf(dmp->f, "---------------------\n");
579 stat_iterate_distrib_tbl(tbl, dump_tbl_line, dmp);
580 fprintf(dmp->f, "-------------------------------\n");
582 fprintf(dmp->f, "Number of Calls %12u\n", cnt_to_uint(&global->cnt[gcnt_all_calls]));
583 fprintf(dmp->f, "with const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_cnst_arg]));
584 fprintf(dmp->f, "with all const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_all_cnst_arg]));
585 fprintf(dmp->f, "with local var adr params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_local_adr]));
586 } /* simple_dump_param_tbl */
589 * initialize the simple dumper
591 static void simple_init(dumper_t *dmp, const char *name) {
594 snprintf(fname, sizeof(fname), "%s.txt", name);
595 dmp->f = fopen(fname, "w");
602 * finishes the simple dumper
604 static void simple_finish(dumper_t *dmp) {
608 } /* simple_finish */
611 * the simple human readable dumper
613 const dumper_t simple_dumper = {
615 simple_dump_const_tbl,
616 simple_dump_param_tbl,
623 FOURCC('S', 'M', 'P', 'L'),
626 /* ---------------------------------------------------------------------- */
629 * count the nodes as needed:
631 * 1 normal (data) Phi's
636 static void csv_count_nodes(dumper_t *dmp, graph_entry_t *graph, counter_t cnt[])
641 for (i = 0; i < 4; ++i)
644 foreach_pset(graph->opcode_hash, entry) {
645 if (entry->op == op_Phi) {
647 cnt_add(&cnt[1], &entry->cnt_alive);
648 } else if (entry->op == dmp->status->op_PhiM) {
650 cnt_add(&cnt[2], &entry->cnt_alive);
651 } else if (entry->op == op_Proj) {
653 cnt_add(&cnt[3], &entry->cnt_alive);
655 /* all other nodes */
656 cnt_add(&cnt[0], &entry->cnt_alive);
659 } /* csv_count_nodes */
664 static void csv_dump_graph(dumper_t *dmp, graph_entry_t *entry)
672 if (entry->irg && !entry->is_deleted) {
673 ir_graph *const_irg = get_const_code_irg();
675 if (entry->irg == const_irg) {
676 name = "<Const code Irg>";
680 name = get_entity_name(entry->ent);
682 name = "<UNKNOWN IRG>";
685 csv_count_nodes(dmp, entry, cnt);
687 fprintf(dmp->f, "%-40s, %p, %d, %d, %d, %d\n",
690 cnt_to_uint(&cnt[0]),
691 cnt_to_uint(&cnt[1]),
692 cnt_to_uint(&cnt[2]),
696 } /* csv_dump_graph */
701 static void csv_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
706 } /* csv_dump_const_tbl */
709 * dumps the parameter distribution table
711 static void csv_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
716 } /* csv_dump_param_tbl */
719 * initialize the simple dumper
721 static void csv_init(dumper_t *dmp, const char *name)
725 snprintf(fname, sizeof(fname), "%s.csv", name);
726 dmp->f = fopen(fname, "a");
732 * finishes the simple dumper
734 static void csv_finish(dumper_t *dmp)
742 * the simple human readable dumper
744 const dumper_t csv_dumper = {
754 FOURCC('C', 'S', 'V', '\0')