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_SUB_C_NOT_X, "algebraic simplification: c - ~a = a + (c+1)" },
79 { FS_OPT_MUL_MINUS_1, "algebraic simplification: a * -1 = -a" },
80 { FS_OPT_OR, "algebraic simplification: a | a = a | 0 = 0 | a = a" },
81 { FS_OPT_AND, "algebraic simplification: a & 0b1...1 = 0b1...1 & a = a & a = (a|X) & a = a" },
82 { FS_OPT_TO_EOR, "algebraic simplification: (a|b) & ~(a&b) = a^b" },
83 { FS_OPT_EOR_A_A, "algebraic simplification: a ^ a = 0" },
84 { FS_OPT_EOR_TO_NOT_BOOL,"algebraic simplification: bool ^ 1 = !bool" },
85 { FS_OPT_EOR_TO_NOT, "algebraic simplification: x ^ 0b1..1 = ~x" },
86 { FS_OPT_NOT_CMP, "algebraic simplification: !(a cmp b) = a !cmp b" },
87 { FS_OPT_OR_SHFT_TO_ROT, "algebraic simplification: (x << c) | (x >> (bits - c)) == Rot(x, c)" },
88 { FS_OPT_REASSOC_SHIFT, "algebraic simplification: (x SHF c1) SHF c2 = x SHF (c1+c2)" },
89 { FS_OPT_SHIFT_AND, "algebraic simplification: (a SHF c) AND (b SHF c) = (a AND b) SHF c" },
90 { FS_OPT_SHIFT_OR, "algebraic simplification: (a SHF c) OR (b SHF c) = (a OR b) SHF c" },
91 { FS_OPT_SHIFT_EOR, "algebraic simplification: (a SHF c) XOR (b SHF c) = (a XOR b) SHF c" },
92 { FS_OPT_CONV, "algebraic simplification: Conv could be removed" },
93 { FS_OPT_CAST, "algebraic simplification: a Cast could be removed" },
94 { FS_OPT_MIN_MAX_EQ, "algebraic simplification: Min(a,a) = Max(a,a) = a" },
95 { FS_OPT_MUX_C, "algebraic simplification: Mux(C, f, t) = C ? t : f" },
96 { FS_OPT_MUX_EQ, "algebraic simplification: Mux(v, x, x) = x" },
97 { FS_OPT_MUX_TRANSFORM, "algebraic simplification: Mux(a, b, c) = b OR Mux(a,b, c) = c" },
98 { FS_OPT_MUX_TO_MIN, "algebraic simplification: Mux(a < b, a, b) = Min(a,b)" },
99 { FS_OPT_MUX_TO_MAX, "algebraic simplification: Mux(a > b, a, b) = Max(a,b)" },
100 { FS_OPT_MUX_TO_ABS, "algebraic simplification: Mux(a > b, a, b) = Abs(a,b)" },
101 { FS_OPT_MUX_TO_SHR, "algebraic simplification: Mux(a > b, a, b) = a >> b" },
102 { FS_OPT_IDEM_UNARY, "algebraic simplification: Idempotent unary operation" },
103 { FS_OPT_MINUS_NOT, "algebraic simplification: -(~x) = x + 1" },
104 { FS_OPT_NOT_MINUS_1, "algebraic simplification: ~(x - 1) = -x" },
105 { FS_OPT_NOT_PLUS_1, "algebraic simplification: ~x + 1 = -x" },
106 { FS_OPT_ADD_X_NOT_X, "algebraic simplification: ~x + x = -1" },
107 { FS_OPT_FP_INV_MUL, "algebraic simplification: x / y = x * (1.0/y)" },
108 { FS_OPT_CONST_PHI, "constant evaluation on Phi node" },
109 { FS_OPT_PREDICATE, "predicate optimization" },
110 { FS_OPT_DEMORGAN, "optimization using DeMorgan's law" },
111 { FS_BE_IA32_LEA, "ia32 Backend transformation: Lea was created" },
112 { FS_BE_IA32_LOAD_LEA, "ia32 Backend transformation: Load merged with a Lea" },
113 { FS_BE_IA32_STORE_LEA, "ia32 Backend transformation: Store merged with a Lea" },
114 { FS_BE_IA32_AM_S, "ia32 Backend transformation: Source address mode node created" },
115 { FS_BE_IA32_AM_D, "ia32 Backend transformation: Destination address mode node created" },
116 { FS_BE_IA32_CJMP, "ia32 Backend transformation: CJmp created to save a cmp/test" },
117 { FS_BE_IA32_2ADDRCPY, "ia32 Backend transformation: Copy created due to 2-Addresscode constraints" },
118 { FS_BE_IA32_SPILL2ST, "ia32 Backend transformation: Created Store for a Spill" },
119 { FS_BE_IA32_RELOAD2LD, "ia32 Backend transformation: Created Load for a Reload" },
120 { FS_BE_IA32_SUB2NEGADD, "ia32 Backend transformation: Created Neg-Add for a Sub due to 2-Addresscode constraints" },
121 { FS_BE_IA32_LEA2ADD, "ia32 Backend transformation: Transformed Lea back into Add" },
124 static const char *if_conv_names[IF_RESULT_LAST] = {
126 "if conv side effect ",
127 "if conv Phi node found ",
128 "if conv to deep DAG's ",
129 "if conv bad control flow ",
130 "if conv denied by arch ",
134 * dumps a opcode hash into human readable form
136 static void simple_dump_opcode_hash(dumper_t *dmp, pset *set)
140 counter_t f_new_node;
144 cnt_clr(&f_new_node);
147 fprintf(dmp->f, "%-16s %-8s %-8s %-8s\n", "Opcode", "alive", "created", "->Id");
148 foreach_pset(set, entry) {
149 fprintf(dmp->f, "%-16s %8u %8u %8u\n",
150 get_id_str(entry->op->name),
151 cnt_to_uint(&entry->cnt_alive),
152 cnt_to_uint(&entry->new_node),
153 cnt_to_uint(&entry->into_Id)
156 cnt_add(&f_alive, &entry->cnt_alive);
157 cnt_add(&f_new_node, &entry->new_node);
158 cnt_add(&f_Id, &entry->into_Id);
160 fprintf(dmp->f, "-------------------------------------------\n");
161 fprintf(dmp->f, "%-16s %8u %8u %8u\n", "Sum",
162 cnt_to_uint(&f_alive),
163 cnt_to_uint(&f_new_node),
166 } /* simple_dump_opcode_hash */
169 * dumps an optimization hash into human readable form
171 static void simple_dump_opt_hash(dumper_t *dmp, pset *set, int index)
173 assert(index < (int) ARR_SIZE(opt_names) && "index out of range");
174 assert((int) opt_names[index].kind == index && "opt_names broken");
176 if (pset_count(set) > 0) {
179 fprintf(dmp->f, "\n%s:\n", opt_names[index].name);
180 fprintf(dmp->f, "%-16s %-8s\n", "Opcode", "deref");
182 foreach_pset(set, entry) {
183 fprintf(dmp->f, "%-16s %8u\n",
184 get_id_str(entry->op->name), cnt_to_uint(&entry->count));
187 } /* simple_dump_opt_hash */
190 * dumps the register pressure for each block and for each register class
192 static void simple_dump_be_block_reg_pressure(dumper_t *dmp, graph_entry_t *entry)
194 be_block_entry_t *b_entry = pset_first(entry->be_block_hash);
195 reg_pressure_entry_t *rp_entry;
197 /* return if no be statistic information available */
201 fprintf(dmp->f, "\nREG PRESSURE:\n");
202 fprintf(dmp->f, "%12s", "Block Nr");
204 /* print table head (register class names) */
205 foreach_pset(b_entry->reg_pressure, rp_entry)
206 fprintf(dmp->f, "%15s", rp_entry->class_name);
207 fprintf(dmp->f, "\n");
209 /* print the reg pressure for all blocks and register classes */
210 for (/* b_entry is already initialized */ ;
212 b_entry = pset_next(entry->be_block_hash)) {
213 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
215 foreach_pset(b_entry->reg_pressure, rp_entry)
216 fprintf(dmp->f, "%15d", rp_entry->pressure);
217 fprintf(dmp->f, "\n");
219 } /* simple_dump_be_block_reg_pressure */
221 /** prints a distribution entry */
222 static void simple_dump_distrib_entry(const distrib_entry_t *entry, void *env) {
224 fprintf(dmp->f, "%12d", cnt_to_uint(&entry->cnt));
225 } /* simple_dump_distrib_entry */
228 * dumps the distribution of the amount of ready nodes for each block
230 static void simple_dump_be_block_sched_ready(dumper_t *dmp, graph_entry_t *entry)
232 if (pset_count(entry->be_block_hash) > 0) {
233 be_block_entry_t *b_entry;
236 fprintf(dmp->f, "\nSCHEDULING: NUMBER OF READY NODES\n");
237 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s %12s\n",
238 "Block Nr", "1 node", "2 nodes", "3 nodes", "4 nodes", "5 or more", "AVERAGE");
240 foreach_pset(entry->be_block_hash, b_entry) {
241 /* this ensures that all keys from 1 to 5 are in the table */
242 for (i = 1; i < 6; ++i)
243 stat_insert_int_distrib_tbl(b_entry->sched_ready, i);
245 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
246 stat_iterate_distrib_tbl(b_entry->sched_ready, simple_dump_distrib_entry, dmp);
247 fprintf(dmp->f, "%12.2lf", stat_calc_avg_distrib_tbl(b_entry->sched_ready));
248 fprintf(dmp->f, "\n");
251 } /* simple_dump_be_block_sched_ready */
254 * Adds the counter for given entry to another distribution table.
256 static void add_distrib_entry(const distrib_entry_t *entry, void *env) {
257 distrib_tbl_t *sum_tbl = env;
259 stat_add_int_distrib_tbl(sum_tbl, (int)(entry->object), &entry->cnt);
260 } /* add_distrib_entry */
263 * dumps permutation statistics for one and block and one class
265 static void simple_dump_be_block_permstat_class(dumper_t *dmp, perm_class_entry_t *entry)
267 perm_stat_entry_t *ps_ent;
268 distrib_tbl_t *sum_chains = stat_new_int_distrib_tbl();
269 distrib_tbl_t *sum_cycles = stat_new_int_distrib_tbl();
273 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s\n",
282 foreach_pset(entry->perm_stat, ps_ent) {
283 fprintf(dmp->f, "%12d %12d %12d %12d %12d %12d\n",
286 stat_get_count_distrib_tbl(ps_ent->chains),
287 stat_get_count_distrib_tbl(ps_ent->cycles),
292 /* sum up distribution table for chains */
293 stat_iterate_distrib_tbl(ps_ent->chains, add_distrib_entry, sum_chains);
295 /* sum up distribution table for cycles */
296 stat_iterate_distrib_tbl(ps_ent->cycles, add_distrib_entry, sum_cycles);
299 /* print chain distribution for all perms of this class in this block */
300 fprintf(dmp->f, "chain distribution:\n");
302 /* add all missing entries to chain distribution table */
303 for (i = 1; i <= entry->n_regs; i++) {
304 snprintf(buf, sizeof(buf), "length %d", i);
305 fprintf(dmp->f, "%12s", buf);
306 stat_insert_int_distrib_tbl(sum_chains, i);
308 fprintf(dmp->f, "\n");
309 stat_iterate_distrib_tbl(sum_chains, simple_dump_distrib_entry, dmp);
310 fprintf(dmp->f, "\n");
312 /* print cycle distribution for all perms of this class in this block */
313 fprintf(dmp->f, "cycle distribution:\n");
315 /* add all missing entries to cycle distribution table */
316 for (i = 1; i <= entry->n_regs; i++) {
317 snprintf(buf, sizeof(buf), "length %d", i);
318 fprintf(dmp->f, "%12s", buf);
319 stat_insert_int_distrib_tbl(sum_cycles, i);
321 fprintf(dmp->f, "\n");
322 stat_iterate_distrib_tbl(sum_cycles, simple_dump_distrib_entry, dmp);
323 fprintf(dmp->f, "\n");
325 /* delete temporary sum distribution tables */
326 stat_delete_distrib_tbl(sum_chains);
327 stat_delete_distrib_tbl(sum_cycles);
329 } /* simple_dump_be_block_permstat_class */
332 * dumps statistics about perms
334 static void simple_dump_be_block_permstat(dumper_t *dmp, graph_entry_t *entry)
336 if (pset_count(entry->be_block_hash) > 0) {
337 be_block_entry_t *b_entry;
339 fprintf(dmp->f, "\nPERMUTATION STATISTICS BEGIN:\n");
340 foreach_pset(entry->be_block_hash, b_entry) {
341 perm_class_entry_t *pc_ent;
343 fprintf(dmp->f, "BLOCK %ld:\n", b_entry->block_nr);
345 if (b_entry->perm_class_stat) {
346 foreach_pset(b_entry->perm_class_stat, pc_ent) {
347 fprintf(dmp->f, "register class %s:\n", pc_ent->class_name);
348 simple_dump_be_block_permstat_class(dmp, pc_ent);
353 fprintf(dmp->f, "PERMUTATION STATISTICS END\n");
355 } /* simple_dump_be_block_permstat */
358 * dumps the number of real_function_call optimization
360 static void simple_dump_real_func_calls(dumper_t *dmp, counter_t *cnt)
365 if (! cnt_eq(cnt, 0)) {
366 fprintf(dmp->f, "\nReal Function Calls optimized:\n");
367 fprintf(dmp->f, "%-16s %8u\n", "Call", cnt_to_uint(cnt));
369 } /* simple_dump_real_func_calls */
372 * dumps the number of tail_recursion optimization
374 static void simple_dump_tail_recursion(dumper_t *dmp, unsigned num_tail_recursion)
379 if (num_tail_recursion > 0) {
380 fprintf(dmp->f, "\nTail recursion optimized:\n");
381 fprintf(dmp->f, "%-16s %8u\n", "Call", num_tail_recursion);
383 } /* simple_dump_tail_recursion */
386 * dumps the edges count
388 static void simple_dump_edges(dumper_t *dmp, counter_t *cnt)
393 fprintf(dmp->f, "%-16s %8d\n", "Edges", cnt_to_uint(cnt));
394 } /* simple_dump_edges */
399 static void simple_dump_graph(dumper_t *dmp, graph_entry_t *entry)
401 int i, dump_opts = 1;
402 block_entry_t *b_entry;
403 extbb_entry_t *eb_entry;
409 ir_graph *const_irg = get_const_code_irg();
411 if (entry->irg == const_irg)
412 fprintf(dmp->f, "\nConst code Irg %p", (void *)entry->irg);
415 fprintf(dmp->f, "\nEntity %s, Irg %p", get_entity_ld_name(entry->ent), (void *)entry->irg);
417 fprintf(dmp->f, "\nIrg %p", (void *)entry->irg);
420 fprintf(dmp->f, " %swalked %u over blocks %u:\n"
421 " was inlined : %u\n"
422 " got inlined : %u\n"
423 " strength red : %u\n"
424 " leaf function : %s\n"
425 " calls only leaf functions : %s\n"
429 " indirect calls : %u\n",
430 entry->is_deleted ? "DELETED " : "",
431 cnt_to_uint(&entry->cnt[gcnt_acc_walked]), cnt_to_uint(&entry->cnt[gcnt_acc_walked_blocks]),
432 cnt_to_uint(&entry->cnt[gcnt_acc_was_inlined]),
433 cnt_to_uint(&entry->cnt[gcnt_acc_got_inlined]),
434 cnt_to_uint(&entry->cnt[gcnt_acc_strength_red]),
435 entry->is_leaf ? "YES" : "NO",
436 entry->is_leaf_call == LCS_NON_LEAF_CALL ? "NO" : (entry->is_leaf_call == LCS_LEAF_CALL ? "Yes" : "Maybe"),
437 entry->is_recursive ? "YES" : "NO",
438 entry->is_chain_call ? "YES" : "NO",
439 cnt_to_uint(&entry->cnt[gcnt_all_calls]),
440 cnt_to_uint(&entry->cnt[gcnt_indirect_calls])
443 for (i = 0; i < IF_RESULT_LAST; ++i) {
444 fprintf(dmp->f, " %s : %u\n", if_conv_names[i], cnt_to_uint(&entry->cnt[gcnt_if_conv + i]));
447 fprintf(dmp->f, "\nGlobals counts:\n");
448 fprintf(dmp->f, "--------------\n");
454 " pure address calc ops : %u\n"
455 " all address calc ops : %u\n",
456 cnt_to_uint(&entry->cnt[gcnt_pure_adr_ops]),
457 cnt_to_uint(&entry->cnt[gcnt_all_adr_ops])
460 /* Load/Store address classification */
462 " global Ld/St address : %u\n"
463 " local Ld/St address : %u\n"
464 " this Ld/St address : %u\n"
465 " param Ld/St address : %u\n"
466 " other Ld/St address : %u\n",
467 cnt_to_uint(&entry->cnt[gcnt_global_adr]),
468 cnt_to_uint(&entry->cnt[gcnt_local_adr]),
469 cnt_to_uint(&entry->cnt[gcnt_this_adr]),
470 cnt_to_uint(&entry->cnt[gcnt_param_adr]),
471 cnt_to_uint(&entry->cnt[gcnt_other_adr])
474 simple_dump_opcode_hash(dmp, entry->opcode_hash);
475 simple_dump_edges(dmp, &entry->cnt[gcnt_edges]);
477 /* effects of optimizations */
481 simple_dump_real_func_calls(dmp, &entry->cnt[gcnt_acc_real_func_call]);
482 simple_dump_tail_recursion(dmp, entry->num_tail_recursion);
484 for (i = 0; i < sizeof(entry->opt_hash)/sizeof(entry->opt_hash[0]); ++i) {
485 simple_dump_opt_hash(dmp, entry->opt_hash[i], i);
488 /* dump block info */
489 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Block Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
490 foreach_pset(entry->block_hash, b_entry) {
491 fprintf(dmp->f, "BLK %6ld %12u %12u %12u %12u %12u %4.8f\n",
493 cnt_to_uint(&b_entry->cnt[bcnt_nodes]),
494 cnt_to_uint(&b_entry->cnt[bcnt_edges]),
495 cnt_to_uint(&b_entry->cnt[bcnt_in_edges]),
496 cnt_to_uint(&b_entry->cnt[bcnt_out_edges]),
497 cnt_to_uint(&b_entry->cnt[bcnt_phi_data]),
498 cnt_to_dbl(&b_entry->cnt[bcnt_edges]) / cnt_to_dbl(&b_entry->cnt[bcnt_nodes])
502 /* dump block reg pressure */
503 simple_dump_be_block_reg_pressure(dmp, entry);
505 /* dump block ready nodes distribution */
506 simple_dump_be_block_sched_ready(dmp, entry);
508 /* dump block permutation statistics */
509 simple_dump_be_block_permstat(dmp, entry);
511 if (dmp->status->stat_options & FIRMSTAT_COUNT_EXTBB && entry->extbb_hash) {
512 /* dump extended block info */
513 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Extbb Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
514 foreach_pset(entry->extbb_hash, eb_entry) {
515 fprintf(dmp->f, "ExtBB %6ld %12u %12u %12u %12u %12u %4.8f\n",
517 cnt_to_uint(&eb_entry->cnt[bcnt_nodes]),
518 cnt_to_uint(&eb_entry->cnt[bcnt_edges]),
519 cnt_to_uint(&eb_entry->cnt[bcnt_in_edges]),
520 cnt_to_uint(&eb_entry->cnt[bcnt_out_edges]),
521 cnt_to_uint(&eb_entry->cnt[bcnt_phi_data]),
522 cnt_to_dbl(&eb_entry->cnt[bcnt_edges]) / cnt_to_dbl(&eb_entry->cnt[bcnt_nodes])
527 } /* simple_dump_graph */
530 * dumps the constant table
532 static void simple_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
542 fprintf(dmp->f, "\nConstant Information:\n");
543 fprintf(dmp->f, "---------------------\n");
545 fprintf(dmp->f, "\nBit usage for integer constants\n");
546 fprintf(dmp->f, "-------------------------------\n");
548 for (i = 0; i < ARR_SIZE(tbl->int_bits_count); ++i) {
549 fprintf(dmp->f, "%5d %12u\n", i + 1, cnt_to_uint(&tbl->int_bits_count[i]));
550 cnt_add(&sum, &tbl->int_bits_count[i]);
552 fprintf(dmp->f, "-------------------------------\n");
554 fprintf(dmp->f, "\nFloating point constants classification\n");
555 fprintf(dmp->f, "--------------------------------------\n");
556 for (i = 0; i < ARR_SIZE(tbl->floats); ++i) {
557 fprintf(dmp->f, "%-10s %12u\n", stat_fc_name(i), cnt_to_uint(&tbl->floats[i]));
558 cnt_add(&sum, &tbl->floats[i]);
560 fprintf(dmp->f, "--------------------------------------\n");
562 fprintf(dmp->f, "other %12u\n", cnt_to_uint(&tbl->others));
563 cnt_add(&sum, &tbl->others);
564 fprintf(dmp->f, "-------------------------------\n");
566 fprintf(dmp->f, "sum %12u\n", cnt_to_uint(&sum));
567 } /* simple_dump_const_tbl */
570 * Dumps a line of the parameter table
572 static void dump_tbl_line(const distrib_entry_t *entry, void *env) {
575 fprintf(dmp->f, "%d : %u\n", PTR_TO_INT(entry->object), cnt_to_uint(&entry->cnt));
576 } /* dump_tbl_line */
579 * dumps the parameter distribution table
581 static void simple_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
582 fprintf(dmp->f, "\nCall parameter Information:\n");
583 fprintf(dmp->f, "---------------------\n");
585 stat_iterate_distrib_tbl(tbl, dump_tbl_line, dmp);
586 fprintf(dmp->f, "-------------------------------\n");
588 fprintf(dmp->f, "Number of Calls %12u\n", cnt_to_uint(&global->cnt[gcnt_all_calls]));
589 fprintf(dmp->f, "with const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_cnst_arg]));
590 fprintf(dmp->f, "with all const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_all_cnst_arg]));
591 fprintf(dmp->f, "with local var adr params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_local_adr]));
592 } /* simple_dump_param_tbl */
595 * initialize the simple dumper
597 static void simple_init(dumper_t *dmp, const char *name) {
600 snprintf(fname, sizeof(fname), "%s.txt", name);
601 dmp->f = fopen(fname, "w");
608 * finishes the simple dumper
610 static void simple_finish(dumper_t *dmp) {
614 } /* simple_finish */
617 * the simple human readable dumper
619 const dumper_t simple_dumper = {
621 simple_dump_const_tbl,
622 simple_dump_param_tbl,
629 FOURCC('S', 'M', 'P', 'L'),
632 /* ---------------------------------------------------------------------- */
635 * count the nodes as needed:
637 * 1 normal (data) Phi's
642 static void csv_count_nodes(dumper_t *dmp, graph_entry_t *graph, counter_t cnt[])
647 for (i = 0; i < 4; ++i)
650 foreach_pset(graph->opcode_hash, entry) {
651 if (entry->op == op_Phi) {
653 cnt_add(&cnt[1], &entry->cnt_alive);
654 } else if (entry->op == dmp->status->op_PhiM) {
656 cnt_add(&cnt[2], &entry->cnt_alive);
657 } else if (entry->op == op_Proj) {
659 cnt_add(&cnt[3], &entry->cnt_alive);
661 /* all other nodes */
662 cnt_add(&cnt[0], &entry->cnt_alive);
665 } /* csv_count_nodes */
670 static void csv_dump_graph(dumper_t *dmp, graph_entry_t *entry)
678 if (entry->irg && !entry->is_deleted) {
679 ir_graph *const_irg = get_const_code_irg();
681 if (entry->irg == const_irg) {
682 name = "<Const code Irg>";
686 name = get_entity_name(entry->ent);
688 name = "<UNKNOWN IRG>";
691 csv_count_nodes(dmp, entry, cnt);
693 fprintf(dmp->f, "%-40s, %p, %d, %d, %d, %d\n",
696 cnt_to_uint(&cnt[0]),
697 cnt_to_uint(&cnt[1]),
698 cnt_to_uint(&cnt[2]),
702 } /* csv_dump_graph */
707 static void csv_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
712 } /* csv_dump_const_tbl */
715 * dumps the parameter distribution table
717 static void csv_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
722 } /* csv_dump_param_tbl */
725 * initialize the simple dumper
727 static void csv_init(dumper_t *dmp, const char *name)
731 snprintf(fname, sizeof(fname), "%s.csv", name);
732 dmp->f = fopen(fname, "a");
738 * finishes the simple dumper
740 static void csv_finish(dumper_t *dmp)
748 * the simple human readable dumper
750 const dumper_t csv_dumper = {
760 FOURCC('C', 'S', 'V', '\0')