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_BE_IA32_LEA, "ia32 Backend transformation: Lea was created" },
111 { FS_BE_IA32_LOAD_LEA, "ia32 Backend transformation: Load merged with a Lea" },
112 { FS_BE_IA32_STORE_LEA, "ia32 Backend transformation: Store merged with a Lea" },
113 { FS_BE_IA32_AM_S, "ia32 Backend transformation: Source address mode node created" },
114 { FS_BE_IA32_AM_D, "ia32 Backend transformation: Destination address mode node created" },
115 { FS_BE_IA32_CJMP, "ia32 Backend transformation: CJmp created to save a cmp/test" },
116 { FS_BE_IA32_2ADDRCPY, "ia32 Backend transformation: Copy created due to 2-Addresscode constraints" },
117 { FS_BE_IA32_SPILL2ST, "ia32 Backend transformation: Created Store for a Spill" },
118 { FS_BE_IA32_RELOAD2LD, "ia32 Backend transformation: Created Load for a Reload" },
119 { FS_BE_IA32_SUB2NEGADD, "ia32 Backend transformation: Created Neg-Add for a Sub due to 2-Addresscode constraints" },
120 { FS_BE_IA32_LEA2ADD, "ia32 Backend transformation: Transformed Lea back into Add" },
123 static const char *if_conv_names[IF_RESULT_LAST] = {
125 "if conv side effect ",
126 "if conv Phi node found ",
127 "if conv to deep DAG's ",
128 "if conv bad control flow ",
129 "if conv denied by arch ",
133 * dumps a opcode hash into human readable form
135 static void simple_dump_opcode_hash(dumper_t *dmp, pset *set)
139 counter_t f_new_node;
143 cnt_clr(&f_new_node);
146 fprintf(dmp->f, "%-16s %-8s %-8s %-8s\n", "Opcode", "alive", "created", "->Id");
147 foreach_pset(set, entry) {
148 fprintf(dmp->f, "%-16s %8u %8u %8u\n",
149 get_id_str(entry->op->name),
150 cnt_to_uint(&entry->cnt_alive),
151 cnt_to_uint(&entry->new_node),
152 cnt_to_uint(&entry->into_Id)
155 cnt_add(&f_alive, &entry->cnt_alive);
156 cnt_add(&f_new_node, &entry->new_node);
157 cnt_add(&f_Id, &entry->into_Id);
159 fprintf(dmp->f, "-------------------------------------------\n");
160 fprintf(dmp->f, "%-16s %8u %8u %8u\n", "Sum",
161 cnt_to_uint(&f_alive),
162 cnt_to_uint(&f_new_node),
165 } /* simple_dump_opcode_hash */
168 * dumps an optimization hash into human readable form
170 static void simple_dump_opt_hash(dumper_t *dmp, pset *set, int index)
172 assert(index < (int) ARR_SIZE(opt_names) && "index out of range");
173 assert((int) opt_names[index].kind == index && "opt_names broken");
175 if (pset_count(set) > 0) {
178 fprintf(dmp->f, "\n%s:\n", opt_names[index].name);
179 fprintf(dmp->f, "%-16s %-8s\n", "Opcode", "deref");
181 foreach_pset(set, entry) {
182 fprintf(dmp->f, "%-16s %8u\n",
183 get_id_str(entry->op->name), cnt_to_uint(&entry->count));
186 } /* simple_dump_opt_hash */
189 * dumps the register pressure for each block and for each register class
191 static void simple_dump_be_block_reg_pressure(dumper_t *dmp, graph_entry_t *entry)
193 be_block_entry_t *b_entry = pset_first(entry->be_block_hash);
194 reg_pressure_entry_t *rp_entry;
196 /* return if no be statistic information available */
200 fprintf(dmp->f, "\nREG PRESSURE:\n");
201 fprintf(dmp->f, "%12s", "Block Nr");
203 /* print table head (register class names) */
204 foreach_pset(b_entry->reg_pressure, rp_entry)
205 fprintf(dmp->f, "%15s", rp_entry->class_name);
206 fprintf(dmp->f, "\n");
208 /* print the reg pressure for all blocks and register classes */
209 for (/* b_entry is already initialized */ ;
211 b_entry = pset_next(entry->be_block_hash)) {
212 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
214 foreach_pset(b_entry->reg_pressure, rp_entry)
215 fprintf(dmp->f, "%15d", rp_entry->pressure);
216 fprintf(dmp->f, "\n");
218 } /* simple_dump_be_block_reg_pressure */
220 /** prints a distribution entry */
221 static void simple_dump_distrib_entry(const distrib_entry_t *entry, void *env) {
223 fprintf(dmp->f, "%12d", cnt_to_uint(&entry->cnt));
224 } /* simple_dump_distrib_entry */
227 * dumps the distribution of the amount of ready nodes for each block
229 static void simple_dump_be_block_sched_ready(dumper_t *dmp, graph_entry_t *entry)
231 if (pset_count(entry->be_block_hash) > 0) {
232 be_block_entry_t *b_entry;
235 fprintf(dmp->f, "\nSCHEDULING: NUMBER OF READY NODES\n");
236 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s %12s\n",
237 "Block Nr", "1 node", "2 nodes", "3 nodes", "4 nodes", "5 or more", "AVERAGE");
239 foreach_pset(entry->be_block_hash, b_entry) {
240 /* this ensures that all keys from 1 to 5 are in the table */
241 for (i = 1; i < 6; ++i)
242 stat_insert_int_distrib_tbl(b_entry->sched_ready, i);
244 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
245 stat_iterate_distrib_tbl(b_entry->sched_ready, simple_dump_distrib_entry, dmp);
246 fprintf(dmp->f, "%12.2lf", stat_calc_avg_distrib_tbl(b_entry->sched_ready));
247 fprintf(dmp->f, "\n");
250 } /* simple_dump_be_block_sched_ready */
253 * Adds the counter for given entry to another distribution table.
255 static void add_distrib_entry(const distrib_entry_t *entry, void *env) {
256 distrib_tbl_t *sum_tbl = env;
258 stat_add_int_distrib_tbl(sum_tbl, (int)(entry->object), &entry->cnt);
259 } /* add_distrib_entry */
262 * dumps permutation statistics for one and block and one class
264 static void simple_dump_be_block_permstat_class(dumper_t *dmp, perm_class_entry_t *entry)
266 perm_stat_entry_t *ps_ent;
267 distrib_tbl_t *sum_chains = stat_new_int_distrib_tbl();
268 distrib_tbl_t *sum_cycles = stat_new_int_distrib_tbl();
272 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s\n",
281 foreach_pset(entry->perm_stat, ps_ent) {
282 fprintf(dmp->f, "%12d %12d %12d %12d %12d %12d\n",
285 stat_get_count_distrib_tbl(ps_ent->chains),
286 stat_get_count_distrib_tbl(ps_ent->cycles),
291 /* sum up distribution table for chains */
292 stat_iterate_distrib_tbl(ps_ent->chains, add_distrib_entry, sum_chains);
294 /* sum up distribution table for cycles */
295 stat_iterate_distrib_tbl(ps_ent->cycles, add_distrib_entry, sum_cycles);
298 /* print chain distribution for all perms of this class in this block */
299 fprintf(dmp->f, "chain distribution:\n");
301 /* add all missing entries to chain distribution table */
302 for (i = 1; i <= entry->n_regs; i++) {
303 snprintf(buf, sizeof(buf), "length %d", i);
304 fprintf(dmp->f, "%12s", buf);
305 stat_insert_int_distrib_tbl(sum_chains, i);
307 fprintf(dmp->f, "\n");
308 stat_iterate_distrib_tbl(sum_chains, simple_dump_distrib_entry, dmp);
309 fprintf(dmp->f, "\n");
311 /* print cycle distribution for all perms of this class in this block */
312 fprintf(dmp->f, "cycle distribution:\n");
314 /* add all missing entries to cycle distribution table */
315 for (i = 1; i <= entry->n_regs; i++) {
316 snprintf(buf, sizeof(buf), "length %d", i);
317 fprintf(dmp->f, "%12s", buf);
318 stat_insert_int_distrib_tbl(sum_cycles, i);
320 fprintf(dmp->f, "\n");
321 stat_iterate_distrib_tbl(sum_cycles, simple_dump_distrib_entry, dmp);
322 fprintf(dmp->f, "\n");
324 /* delete temporary sum distribution tables */
325 stat_delete_distrib_tbl(sum_chains);
326 stat_delete_distrib_tbl(sum_cycles);
328 } /* simple_dump_be_block_permstat_class */
331 * dumps statistics about perms
333 static void simple_dump_be_block_permstat(dumper_t *dmp, graph_entry_t *entry)
335 if (pset_count(entry->be_block_hash) > 0) {
336 be_block_entry_t *b_entry;
338 fprintf(dmp->f, "\nPERMUTATION STATISTICS BEGIN:\n");
339 foreach_pset(entry->be_block_hash, b_entry) {
340 perm_class_entry_t *pc_ent;
342 fprintf(dmp->f, "BLOCK %ld:\n", b_entry->block_nr);
344 if (b_entry->perm_class_stat) {
345 foreach_pset(b_entry->perm_class_stat, pc_ent) {
346 fprintf(dmp->f, "register class %s:\n", pc_ent->class_name);
347 simple_dump_be_block_permstat_class(dmp, pc_ent);
352 fprintf(dmp->f, "PERMUTATION STATISTICS END\n");
354 } /* simple_dump_be_block_permstat */
357 * dumps the number of real_function_call optimization
359 static void simple_dump_real_func_calls(dumper_t *dmp, counter_t *cnt)
364 if (! cnt_eq(cnt, 0)) {
365 fprintf(dmp->f, "\nReal Function Calls optimized:\n");
366 fprintf(dmp->f, "%-16s %8u\n", "Call", cnt_to_uint(cnt));
368 } /* simple_dump_real_func_calls */
371 * dumps the number of tail_recursion optimization
373 static void simple_dump_tail_recursion(dumper_t *dmp, unsigned num_tail_recursion)
378 if (num_tail_recursion > 0) {
379 fprintf(dmp->f, "\nTail recursion optimized:\n");
380 fprintf(dmp->f, "%-16s %8u\n", "Call", num_tail_recursion);
382 } /* simple_dump_tail_recursion */
385 * dumps the edges count
387 static void simple_dump_edges(dumper_t *dmp, counter_t *cnt)
392 fprintf(dmp->f, "%-16s %8d\n", "Edges", cnt_to_uint(cnt));
393 } /* simple_dump_edges */
398 static void simple_dump_graph(dumper_t *dmp, graph_entry_t *entry)
400 int i, dump_opts = 1;
401 block_entry_t *b_entry;
402 extbb_entry_t *eb_entry;
408 ir_graph *const_irg = get_const_code_irg();
410 if (entry->irg == const_irg)
411 fprintf(dmp->f, "\nConst code Irg %p", (void *)entry->irg);
414 fprintf(dmp->f, "\nEntity %s, Irg %p", get_entity_ld_name(entry->ent), (void *)entry->irg);
416 fprintf(dmp->f, "\nIrg %p", (void *)entry->irg);
419 fprintf(dmp->f, " %swalked %u over blocks %u:\n"
420 " was inlined : %u\n"
421 " got inlined : %u\n"
422 " strength red : %u\n"
423 " leaf function : %s\n"
424 " calls only leaf functions : %s\n"
428 " indirect calls : %u\n",
429 entry->is_deleted ? "DELETED " : "",
430 cnt_to_uint(&entry->cnt[gcnt_acc_walked]), cnt_to_uint(&entry->cnt[gcnt_acc_walked_blocks]),
431 cnt_to_uint(&entry->cnt[gcnt_acc_was_inlined]),
432 cnt_to_uint(&entry->cnt[gcnt_acc_got_inlined]),
433 cnt_to_uint(&entry->cnt[gcnt_acc_strength_red]),
434 entry->is_leaf ? "YES" : "NO",
435 entry->is_leaf_call == LCS_NON_LEAF_CALL ? "NO" : (entry->is_leaf_call == LCS_LEAF_CALL ? "Yes" : "Maybe"),
436 entry->is_recursive ? "YES" : "NO",
437 entry->is_chain_call ? "YES" : "NO",
438 cnt_to_uint(&entry->cnt[gcnt_all_calls]),
439 cnt_to_uint(&entry->cnt[gcnt_indirect_calls])
442 for (i = 0; i < IF_RESULT_LAST; ++i) {
443 fprintf(dmp->f, " %s : %u\n", if_conv_names[i], cnt_to_uint(&entry->cnt[gcnt_if_conv + i]));
446 fprintf(dmp->f, "\nGlobals counts:\n");
447 fprintf(dmp->f, "--------------\n");
453 " pure address calc ops : %u\n"
454 " all address calc ops : %u\n",
455 cnt_to_uint(&entry->cnt[gcnt_pure_adr_ops]),
456 cnt_to_uint(&entry->cnt[gcnt_all_adr_ops])
459 /* Load/Store address classification */
461 " global Ld/St address : %u\n"
462 " local Ld/St address : %u\n"
463 " this Ld/St address : %u\n"
464 " param Ld/St address : %u\n"
465 " other Ld/St address : %u\n",
466 cnt_to_uint(&entry->cnt[gcnt_global_adr]),
467 cnt_to_uint(&entry->cnt[gcnt_local_adr]),
468 cnt_to_uint(&entry->cnt[gcnt_this_adr]),
469 cnt_to_uint(&entry->cnt[gcnt_param_adr]),
470 cnt_to_uint(&entry->cnt[gcnt_other_adr])
473 simple_dump_opcode_hash(dmp, entry->opcode_hash);
474 simple_dump_edges(dmp, &entry->cnt[gcnt_edges]);
476 /* effects of optimizations */
480 simple_dump_real_func_calls(dmp, &entry->cnt[gcnt_acc_real_func_call]);
481 simple_dump_tail_recursion(dmp, entry->num_tail_recursion);
483 for (i = 0; i < sizeof(entry->opt_hash)/sizeof(entry->opt_hash[0]); ++i) {
484 simple_dump_opt_hash(dmp, entry->opt_hash[i], i);
487 /* dump block info */
488 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Block Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
489 foreach_pset(entry->block_hash, b_entry) {
490 fprintf(dmp->f, "BLK %6ld %12u %12u %12u %12u %12u %4.8f\n",
492 cnt_to_uint(&b_entry->cnt[bcnt_nodes]),
493 cnt_to_uint(&b_entry->cnt[bcnt_edges]),
494 cnt_to_uint(&b_entry->cnt[bcnt_in_edges]),
495 cnt_to_uint(&b_entry->cnt[bcnt_out_edges]),
496 cnt_to_uint(&b_entry->cnt[bcnt_phi_data]),
497 cnt_to_dbl(&b_entry->cnt[bcnt_edges]) / cnt_to_dbl(&b_entry->cnt[bcnt_nodes])
501 /* dump block reg pressure */
502 simple_dump_be_block_reg_pressure(dmp, entry);
504 /* dump block ready nodes distribution */
505 simple_dump_be_block_sched_ready(dmp, entry);
507 /* dump block permutation statistics */
508 simple_dump_be_block_permstat(dmp, entry);
510 if (dmp->status->stat_options & FIRMSTAT_COUNT_EXTBB && entry->extbb_hash) {
511 /* dump extended block info */
512 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Extbb Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
513 foreach_pset(entry->extbb_hash, eb_entry) {
514 fprintf(dmp->f, "ExtBB %6ld %12u %12u %12u %12u %12u %4.8f\n",
516 cnt_to_uint(&eb_entry->cnt[bcnt_nodes]),
517 cnt_to_uint(&eb_entry->cnt[bcnt_edges]),
518 cnt_to_uint(&eb_entry->cnt[bcnt_in_edges]),
519 cnt_to_uint(&eb_entry->cnt[bcnt_out_edges]),
520 cnt_to_uint(&eb_entry->cnt[bcnt_phi_data]),
521 cnt_to_dbl(&eb_entry->cnt[bcnt_edges]) / cnt_to_dbl(&eb_entry->cnt[bcnt_nodes])
526 } /* simple_dump_graph */
529 * dumps the constant table
531 static void simple_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
541 fprintf(dmp->f, "\nConstant Information:\n");
542 fprintf(dmp->f, "---------------------\n");
544 fprintf(dmp->f, "\nBit usage for integer constants\n");
545 fprintf(dmp->f, "-------------------------------\n");
547 for (i = 0; i < ARR_SIZE(tbl->int_bits_count); ++i) {
548 fprintf(dmp->f, "%5d %12u\n", i + 1, cnt_to_uint(&tbl->int_bits_count[i]));
549 cnt_add(&sum, &tbl->int_bits_count[i]);
551 fprintf(dmp->f, "-------------------------------\n");
553 fprintf(dmp->f, "\nFloating point constants classification\n");
554 fprintf(dmp->f, "--------------------------------------\n");
555 for (i = 0; i < ARR_SIZE(tbl->floats); ++i) {
556 fprintf(dmp->f, "%-10s %12u\n", stat_fc_name(i), cnt_to_uint(&tbl->floats[i]));
557 cnt_add(&sum, &tbl->floats[i]);
559 fprintf(dmp->f, "--------------------------------------\n");
561 fprintf(dmp->f, "other %12u\n", cnt_to_uint(&tbl->others));
562 cnt_add(&sum, &tbl->others);
563 fprintf(dmp->f, "-------------------------------\n");
565 fprintf(dmp->f, "sum %12u\n", cnt_to_uint(&sum));
566 } /* simple_dump_const_tbl */
569 * Dumps a line of the parameter table
571 static void dump_tbl_line(const distrib_entry_t *entry, void *env) {
574 fprintf(dmp->f, "%d : %u\n", PTR_TO_INT(entry->object), cnt_to_uint(&entry->cnt));
575 } /* dump_tbl_line */
578 * dumps the parameter distribution table
580 static void simple_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
581 fprintf(dmp->f, "\nCall parameter Information:\n");
582 fprintf(dmp->f, "---------------------\n");
584 stat_iterate_distrib_tbl(tbl, dump_tbl_line, dmp);
585 fprintf(dmp->f, "-------------------------------\n");
587 fprintf(dmp->f, "Number of Calls %12u\n", cnt_to_uint(&global->cnt[gcnt_all_calls]));
588 fprintf(dmp->f, "with const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_cnst_arg]));
589 fprintf(dmp->f, "with all const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_all_cnst_arg]));
590 fprintf(dmp->f, "with local var adr params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_local_adr]));
591 } /* simple_dump_param_tbl */
594 * initialize the simple dumper
596 static void simple_init(dumper_t *dmp, const char *name) {
599 snprintf(fname, sizeof(fname), "%s.txt", name);
600 dmp->f = fopen(fname, "w");
607 * finishes the simple dumper
609 static void simple_finish(dumper_t *dmp) {
613 } /* simple_finish */
616 * the simple human readable dumper
618 const dumper_t simple_dumper = {
620 simple_dump_const_tbl,
621 simple_dump_param_tbl,
628 FOURCC('S', 'M', 'P', 'L'),
631 /* ---------------------------------------------------------------------- */
634 * count the nodes as needed:
636 * 1 normal (data) Phi's
641 static void csv_count_nodes(dumper_t *dmp, graph_entry_t *graph, counter_t cnt[])
646 for (i = 0; i < 4; ++i)
649 foreach_pset(graph->opcode_hash, entry) {
650 if (entry->op == op_Phi) {
652 cnt_add(&cnt[1], &entry->cnt_alive);
653 } else if (entry->op == dmp->status->op_PhiM) {
655 cnt_add(&cnt[2], &entry->cnt_alive);
656 } else if (entry->op == op_Proj) {
658 cnt_add(&cnt[3], &entry->cnt_alive);
660 /* all other nodes */
661 cnt_add(&cnt[0], &entry->cnt_alive);
664 } /* csv_count_nodes */
669 static void csv_dump_graph(dumper_t *dmp, graph_entry_t *entry)
677 if (entry->irg && !entry->is_deleted) {
678 ir_graph *const_irg = get_const_code_irg();
680 if (entry->irg == const_irg) {
681 name = "<Const code Irg>";
685 name = get_entity_name(entry->ent);
687 name = "<UNKNOWN IRG>";
690 csv_count_nodes(dmp, entry, cnt);
692 fprintf(dmp->f, "%-40s, %p, %d, %d, %d, %d\n",
695 cnt_to_uint(&cnt[0]),
696 cnt_to_uint(&cnt[1]),
697 cnt_to_uint(&cnt[2]),
701 } /* csv_dump_graph */
706 static void csv_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
711 } /* csv_dump_const_tbl */
714 * dumps the parameter distribution table
716 static void csv_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
721 } /* csv_dump_param_tbl */
724 * initialize the simple dumper
726 static void csv_init(dumper_t *dmp, const char *name)
730 snprintf(fname, sizeof(fname), "%s.csv", name);
731 dmp->f = fopen(fname, "a");
737 * finishes the simple dumper
739 static void csv_finish(dumper_t *dmp)
747 * the simple human readable dumper
749 const dumper_t csv_dumper = {
759 FOURCC('C', 'S', 'V', '\0')