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_MINUS, "algebraic simplification: a - (-b) = a + b" },
77 { FS_OPT_SUB_MUL_A_X_A, "algebraic simplification: a * x - a = a * (x - 1)" },
78 { FS_OPT_SUB_SUB_X_Y_Z, "algebraic simplification: (x - y) - z = x - (y + z)" },
79 { FS_OPT_SUB_C_NOT_X, "algebraic simplification: c - ~a = a + (c+1)" },
80 { FS_OPT_SUB_TO_ADD, "algebraic simplification: (-a) - b = -(a + b), a - (b - c) = a + (c - b), a - (b * C) -> a + (b * -C)" },
81 { FS_OPT_MUL_MINUS, "algebraic simplification: (-a) * (b - c) -> a * (c - b)" },
82 { FS_OPT_MUL_MINUS_1, "algebraic simplification: a * -1 = -a" },
83 { FS_OPT_MINUS_MUL_C, "algebraic simplification: (-a) * C = a * (-C)" },
84 { FS_OPT_MUL_MINUS_MINUS,"algebraic simplification: (-a) * (-b) = a * b" },
85 { FS_OPT_OR, "algebraic simplification: a | a = a | 0 = 0 | a = a" },
86 { FS_OPT_AND, "algebraic simplification: a & 0b1...1 = 0b1...1 & a = a & a = (a|X) & a = a" },
87 { FS_OPT_TO_EOR, "algebraic simplification: (a|b) & ~(a&b) = a^b" },
88 { FS_OPT_EOR_A_A, "algebraic simplification: a ^ a = 0" },
89 { FS_OPT_EOR_TO_NOT_BOOL,"algebraic simplification: bool ^ 1 = !bool" },
90 { FS_OPT_EOR_TO_NOT, "algebraic simplification: x ^ 0b1..1 = ~x, (a ^ b) & b -> ~a & b" },
91 { FS_OPT_NOT_CMP, "algebraic simplification: !(a cmp b) = a !cmp b" },
92 { FS_OPT_OR_SHFT_TO_ROT, "algebraic simplification: (x << c) | (x >> (bits - c)) == Rot(x, c)" },
93 { FS_OPT_REASSOC_SHIFT, "algebraic simplification: (x SHF c1) SHF c2 = x SHF (c1+c2)" },
94 { FS_OPT_SHIFT_AND, "algebraic simplification: (a SHF c) AND (b SHF c) = (a AND b) SHF c" },
95 { FS_OPT_SHIFT_OR, "algebraic simplification: (a SHF c) OR (b SHF c) = (a OR b) SHF c" },
96 { FS_OPT_SHIFT_EOR, "algebraic simplification: (a SHF c) XOR (b SHF c) = (a XOR b) SHF c" },
97 { FS_OPT_CONV, "algebraic simplification: Conv could be removed" },
98 { FS_OPT_CAST, "algebraic simplification: a Cast could be removed" },
99 { FS_OPT_MIN_MAX_EQ, "algebraic simplification: Min(a,a) = Max(a,a) = a" },
100 { FS_OPT_MUX_C, "algebraic simplification: Mux(C, f, t) = C ? t : f" },
101 { FS_OPT_MUX_EQ, "algebraic simplification: Mux(v, x, x) = x" },
102 { FS_OPT_MUX_TRANSFORM, "algebraic simplification: Mux(a, b, c) = b OR Mux(a,b, c) = c" },
103 { FS_OPT_MUX_TO_MIN, "algebraic simplification: Mux(a < b, a, b) = Min(a,b)" },
104 { FS_OPT_MUX_TO_MAX, "algebraic simplification: Mux(a > b, a, b) = Max(a,b)" },
105 { FS_OPT_MUX_TO_ABS, "algebraic simplification: Mux(a > b, a, b) = Abs(a,b)" },
106 { FS_OPT_MUX_TO_SHR, "algebraic simplification: Mux(a > b, a, b) = a >> b" },
107 { FS_OPT_IDEM_UNARY, "algebraic simplification: Idempotent unary operation" },
108 { FS_OPT_MINUS_NOT, "algebraic simplification: -(~x) = x + 1" },
109 { FS_OPT_NOT_MINUS_1, "algebraic simplification: ~(x - 1) = -x" },
110 { FS_OPT_NOT_PLUS_1, "algebraic simplification: ~x + 1 = -x" },
111 { FS_OPT_ADD_X_NOT_X, "algebraic simplification: ~x + x = -1" },
112 { FS_OPT_FP_INV_MUL, "algebraic simplification: x / y = x * (1.0/y)" },
113 { FS_OPT_CONST_PHI, "constant evaluation on Phi node" },
114 { FS_OPT_PREDICATE, "predicate optimization" },
115 { FS_OPT_DEMORGAN, "optimization using DeMorgan's law" },
116 { FS_BE_IA32_LEA, "ia32 Backend transformation: Lea was created" },
117 { FS_BE_IA32_LOAD_LEA, "ia32 Backend transformation: Load merged with a Lea" },
118 { FS_BE_IA32_STORE_LEA, "ia32 Backend transformation: Store merged with a Lea" },
119 { FS_BE_IA32_AM_S, "ia32 Backend transformation: Source address mode node created" },
120 { FS_BE_IA32_AM_D, "ia32 Backend transformation: Destination address mode node created" },
121 { FS_BE_IA32_CJMP, "ia32 Backend transformation: CJmp created to save a cmp/test" },
122 { FS_BE_IA32_2ADDRCPY, "ia32 Backend transformation: Copy created due to 2-Addresscode constraints" },
123 { FS_BE_IA32_SPILL2ST, "ia32 Backend transformation: Created Store for a Spill" },
124 { FS_BE_IA32_RELOAD2LD, "ia32 Backend transformation: Created Load for a Reload" },
125 { FS_BE_IA32_SUB2NEGADD, "ia32 Backend transformation: Created Neg-Add for a Sub due to 2-Addresscode constraints" },
126 { FS_BE_IA32_LEA2ADD, "ia32 Backend transformation: Transformed Lea back into Add" },
129 static const char *if_conv_names[IF_RESULT_LAST] = {
131 "if conv side effect ",
132 "if conv Phi node found ",
133 "if conv to deep DAG's ",
134 "if conv bad control flow ",
135 "if conv denied by arch ",
139 * dumps a opcode hash into human readable form
141 static void simple_dump_opcode_hash(dumper_t *dmp, pset *set)
145 counter_t f_new_node;
149 cnt_clr(&f_new_node);
152 fprintf(dmp->f, "%-16s %-8s %-8s %-8s\n", "Opcode", "alive", "created", "->Id");
153 foreach_pset(set, entry) {
154 fprintf(dmp->f, "%-16s %8u %8u %8u\n",
155 get_id_str(entry->op->name),
156 cnt_to_uint(&entry->cnt_alive),
157 cnt_to_uint(&entry->new_node),
158 cnt_to_uint(&entry->into_Id)
161 cnt_add(&f_alive, &entry->cnt_alive);
162 cnt_add(&f_new_node, &entry->new_node);
163 cnt_add(&f_Id, &entry->into_Id);
165 fprintf(dmp->f, "-------------------------------------------\n");
166 fprintf(dmp->f, "%-16s %8u %8u %8u\n", "Sum",
167 cnt_to_uint(&f_alive),
168 cnt_to_uint(&f_new_node),
171 } /* simple_dump_opcode_hash */
174 * dumps an optimization hash into human readable form
176 static void simple_dump_opt_hash(dumper_t *dmp, pset *set, int index)
178 assert(index < (int) ARR_SIZE(opt_names) && "index out of range");
179 assert((int) opt_names[index].kind == index && "opt_names broken");
181 if (pset_count(set) > 0) {
184 fprintf(dmp->f, "\n%s:\n", opt_names[index].name);
185 fprintf(dmp->f, "%-16s %-8s\n", "Opcode", "deref");
187 foreach_pset(set, entry) {
188 fprintf(dmp->f, "%-16s %8u\n",
189 get_id_str(entry->op->name), cnt_to_uint(&entry->count));
192 } /* simple_dump_opt_hash */
195 * dumps the register pressure for each block and for each register class
197 static void simple_dump_be_block_reg_pressure(dumper_t *dmp, graph_entry_t *entry)
199 be_block_entry_t *b_entry = pset_first(entry->be_block_hash);
200 reg_pressure_entry_t *rp_entry;
202 /* return if no be statistic information available */
206 fprintf(dmp->f, "\nREG PRESSURE:\n");
207 fprintf(dmp->f, "%12s", "Block Nr");
209 /* print table head (register class names) */
210 foreach_pset(b_entry->reg_pressure, rp_entry)
211 fprintf(dmp->f, "%15s", rp_entry->class_name);
212 fprintf(dmp->f, "\n");
214 /* print the reg pressure for all blocks and register classes */
215 for (/* b_entry is already initialized */ ;
217 b_entry = pset_next(entry->be_block_hash)) {
218 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
220 foreach_pset(b_entry->reg_pressure, rp_entry)
221 fprintf(dmp->f, "%15d", rp_entry->pressure);
222 fprintf(dmp->f, "\n");
224 } /* simple_dump_be_block_reg_pressure */
226 /** prints a distribution entry */
227 static void simple_dump_distrib_entry(const distrib_entry_t *entry, void *env) {
229 fprintf(dmp->f, "%12d", cnt_to_uint(&entry->cnt));
230 } /* simple_dump_distrib_entry */
233 * dumps the distribution of the amount of ready nodes for each block
235 static void simple_dump_be_block_sched_ready(dumper_t *dmp, graph_entry_t *entry)
237 if (pset_count(entry->be_block_hash) > 0) {
238 be_block_entry_t *b_entry;
241 fprintf(dmp->f, "\nSCHEDULING: NUMBER OF READY NODES\n");
242 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s %12s\n",
243 "Block Nr", "1 node", "2 nodes", "3 nodes", "4 nodes", "5 or more", "AVERAGE");
245 foreach_pset(entry->be_block_hash, b_entry) {
246 /* this ensures that all keys from 1 to 5 are in the table */
247 for (i = 1; i < 6; ++i)
248 stat_insert_int_distrib_tbl(b_entry->sched_ready, i);
250 fprintf(dmp->f, "BLK %6ld", b_entry->block_nr);
251 stat_iterate_distrib_tbl(b_entry->sched_ready, simple_dump_distrib_entry, dmp);
252 fprintf(dmp->f, "%12.2lf", stat_calc_avg_distrib_tbl(b_entry->sched_ready));
253 fprintf(dmp->f, "\n");
256 } /* simple_dump_be_block_sched_ready */
259 * Adds the counter for given entry to another distribution table.
261 static void add_distrib_entry(const distrib_entry_t *entry, void *env) {
262 distrib_tbl_t *sum_tbl = env;
264 stat_add_int_distrib_tbl(sum_tbl, (int)(entry->object), &entry->cnt);
265 } /* add_distrib_entry */
268 * dumps permutation statistics for one and block and one class
270 static void simple_dump_be_block_permstat_class(dumper_t *dmp, perm_class_entry_t *entry)
272 perm_stat_entry_t *ps_ent;
273 distrib_tbl_t *sum_chains = stat_new_int_distrib_tbl();
274 distrib_tbl_t *sum_cycles = stat_new_int_distrib_tbl();
278 fprintf(dmp->f, "%12s %12s %12s %12s %12s %12s\n",
287 foreach_pset(entry->perm_stat, ps_ent) {
288 fprintf(dmp->f, "%12d %12d %12d %12d %12d %12d\n",
291 stat_get_count_distrib_tbl(ps_ent->chains),
292 stat_get_count_distrib_tbl(ps_ent->cycles),
297 /* sum up distribution table for chains */
298 stat_iterate_distrib_tbl(ps_ent->chains, add_distrib_entry, sum_chains);
300 /* sum up distribution table for cycles */
301 stat_iterate_distrib_tbl(ps_ent->cycles, add_distrib_entry, sum_cycles);
304 /* print chain distribution for all perms of this class in this block */
305 fprintf(dmp->f, "chain distribution:\n");
307 /* add all missing entries to chain 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_chains, i);
313 fprintf(dmp->f, "\n");
314 stat_iterate_distrib_tbl(sum_chains, simple_dump_distrib_entry, dmp);
315 fprintf(dmp->f, "\n");
317 /* print cycle distribution for all perms of this class in this block */
318 fprintf(dmp->f, "cycle distribution:\n");
320 /* add all missing entries to cycle distribution table */
321 for (i = 1; i <= entry->n_regs; i++) {
322 snprintf(buf, sizeof(buf), "length %d", i);
323 fprintf(dmp->f, "%12s", buf);
324 stat_insert_int_distrib_tbl(sum_cycles, i);
326 fprintf(dmp->f, "\n");
327 stat_iterate_distrib_tbl(sum_cycles, simple_dump_distrib_entry, dmp);
328 fprintf(dmp->f, "\n");
330 /* delete temporary sum distribution tables */
331 stat_delete_distrib_tbl(sum_chains);
332 stat_delete_distrib_tbl(sum_cycles);
334 } /* simple_dump_be_block_permstat_class */
337 * dumps statistics about perms
339 static void simple_dump_be_block_permstat(dumper_t *dmp, graph_entry_t *entry)
341 if (pset_count(entry->be_block_hash) > 0) {
342 be_block_entry_t *b_entry;
344 fprintf(dmp->f, "\nPERMUTATION STATISTICS BEGIN:\n");
345 foreach_pset(entry->be_block_hash, b_entry) {
346 perm_class_entry_t *pc_ent;
348 fprintf(dmp->f, "BLOCK %ld:\n", b_entry->block_nr);
350 if (b_entry->perm_class_stat) {
351 foreach_pset(b_entry->perm_class_stat, pc_ent) {
352 fprintf(dmp->f, "register class %s:\n", pc_ent->class_name);
353 simple_dump_be_block_permstat_class(dmp, pc_ent);
358 fprintf(dmp->f, "PERMUTATION STATISTICS END\n");
360 } /* simple_dump_be_block_permstat */
363 * dumps the number of real_function_call optimization
365 static void simple_dump_real_func_calls(dumper_t *dmp, counter_t *cnt)
370 if (! cnt_eq(cnt, 0)) {
371 fprintf(dmp->f, "\nReal Function Calls optimized:\n");
372 fprintf(dmp->f, "%-16s %8u\n", "Call", cnt_to_uint(cnt));
374 } /* simple_dump_real_func_calls */
377 * dumps the number of tail_recursion optimization
379 static void simple_dump_tail_recursion(dumper_t *dmp, unsigned num_tail_recursion)
384 if (num_tail_recursion > 0) {
385 fprintf(dmp->f, "\nTail recursion optimized:\n");
386 fprintf(dmp->f, "%-16s %8u\n", "Call", num_tail_recursion);
388 } /* simple_dump_tail_recursion */
391 * dumps the edges count
393 static void simple_dump_edges(dumper_t *dmp, counter_t *cnt)
398 fprintf(dmp->f, "%-16s %8d\n", "Edges", cnt_to_uint(cnt));
399 } /* simple_dump_edges */
404 static void simple_dump_graph(dumper_t *dmp, graph_entry_t *entry)
406 int i, dump_opts = 1;
407 block_entry_t *b_entry;
408 extbb_entry_t *eb_entry;
414 ir_graph *const_irg = get_const_code_irg();
416 if (entry->irg == const_irg)
417 fprintf(dmp->f, "\nConst code Irg %p", (void *)entry->irg);
420 fprintf(dmp->f, "\nEntity %s, Irg %p", get_entity_ld_name(entry->ent), (void *)entry->irg);
422 fprintf(dmp->f, "\nIrg %p", (void *)entry->irg);
425 fprintf(dmp->f, " %swalked %u over blocks %u:\n"
426 " was inlined : %u\n"
427 " got inlined : %u\n"
428 " strength red : %u\n"
429 " leaf function : %s\n"
430 " calls only leaf functions : %s\n"
434 " indirect calls : %u\n",
435 entry->is_deleted ? "DELETED " : "",
436 cnt_to_uint(&entry->cnt[gcnt_acc_walked]), cnt_to_uint(&entry->cnt[gcnt_acc_walked_blocks]),
437 cnt_to_uint(&entry->cnt[gcnt_acc_was_inlined]),
438 cnt_to_uint(&entry->cnt[gcnt_acc_got_inlined]),
439 cnt_to_uint(&entry->cnt[gcnt_acc_strength_red]),
440 entry->is_leaf ? "YES" : "NO",
441 entry->is_leaf_call == LCS_NON_LEAF_CALL ? "NO" : (entry->is_leaf_call == LCS_LEAF_CALL ? "Yes" : "Maybe"),
442 entry->is_recursive ? "YES" : "NO",
443 entry->is_chain_call ? "YES" : "NO",
444 cnt_to_uint(&entry->cnt[gcnt_all_calls]),
445 cnt_to_uint(&entry->cnt[gcnt_indirect_calls])
448 for (i = 0; i < IF_RESULT_LAST; ++i) {
449 fprintf(dmp->f, " %s : %u\n", if_conv_names[i], cnt_to_uint(&entry->cnt[gcnt_if_conv + i]));
452 fprintf(dmp->f, "\nGlobals counts:\n");
453 fprintf(dmp->f, "--------------\n");
459 " pure address calc ops : %u\n"
460 " all address calc ops : %u\n",
461 cnt_to_uint(&entry->cnt[gcnt_pure_adr_ops]),
462 cnt_to_uint(&entry->cnt[gcnt_all_adr_ops])
465 /* Load/Store address classification */
467 " global Ld/St address : %u\n"
468 " local Ld/St address : %u\n"
469 " this Ld/St address : %u\n"
470 " param Ld/St address : %u\n"
471 " other Ld/St address : %u\n",
472 cnt_to_uint(&entry->cnt[gcnt_global_adr]),
473 cnt_to_uint(&entry->cnt[gcnt_local_adr]),
474 cnt_to_uint(&entry->cnt[gcnt_this_adr]),
475 cnt_to_uint(&entry->cnt[gcnt_param_adr]),
476 cnt_to_uint(&entry->cnt[gcnt_other_adr])
479 simple_dump_opcode_hash(dmp, entry->opcode_hash);
480 simple_dump_edges(dmp, &entry->cnt[gcnt_edges]);
482 /* effects of optimizations */
486 simple_dump_real_func_calls(dmp, &entry->cnt[gcnt_acc_real_func_call]);
487 simple_dump_tail_recursion(dmp, entry->num_tail_recursion);
489 for (i = 0; i < sizeof(entry->opt_hash)/sizeof(entry->opt_hash[0]); ++i) {
490 simple_dump_opt_hash(dmp, entry->opt_hash[i], i);
493 /* dump block info */
494 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Block Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
495 foreach_pset(entry->block_hash, b_entry) {
496 fprintf(dmp->f, "BLK %6ld %12u %12u %12u %12u %12u %4.8f\n",
498 cnt_to_uint(&b_entry->cnt[bcnt_nodes]),
499 cnt_to_uint(&b_entry->cnt[bcnt_edges]),
500 cnt_to_uint(&b_entry->cnt[bcnt_in_edges]),
501 cnt_to_uint(&b_entry->cnt[bcnt_out_edges]),
502 cnt_to_uint(&b_entry->cnt[bcnt_phi_data]),
503 cnt_to_dbl(&b_entry->cnt[bcnt_edges]) / cnt_to_dbl(&b_entry->cnt[bcnt_nodes])
507 /* dump block reg pressure */
508 simple_dump_be_block_reg_pressure(dmp, entry);
510 /* dump block ready nodes distribution */
511 simple_dump_be_block_sched_ready(dmp, entry);
513 /* dump block permutation statistics */
514 simple_dump_be_block_permstat(dmp, entry);
516 if (dmp->status->stat_options & FIRMSTAT_COUNT_EXTBB && entry->extbb_hash) {
517 /* dump extended block info */
518 fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Extbb Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot");
519 foreach_pset(entry->extbb_hash, eb_entry) {
520 fprintf(dmp->f, "ExtBB %6ld %12u %12u %12u %12u %12u %4.8f\n",
522 cnt_to_uint(&eb_entry->cnt[bcnt_nodes]),
523 cnt_to_uint(&eb_entry->cnt[bcnt_edges]),
524 cnt_to_uint(&eb_entry->cnt[bcnt_in_edges]),
525 cnt_to_uint(&eb_entry->cnt[bcnt_out_edges]),
526 cnt_to_uint(&eb_entry->cnt[bcnt_phi_data]),
527 cnt_to_dbl(&eb_entry->cnt[bcnt_edges]) / cnt_to_dbl(&eb_entry->cnt[bcnt_nodes])
532 } /* simple_dump_graph */
535 * dumps the constant table
537 static void simple_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
547 fprintf(dmp->f, "\nConstant Information:\n");
548 fprintf(dmp->f, "---------------------\n");
550 fprintf(dmp->f, "\nBit usage for integer constants\n");
551 fprintf(dmp->f, "-------------------------------\n");
553 for (i = 0; i < ARR_SIZE(tbl->int_bits_count); ++i) {
554 fprintf(dmp->f, "%5d %12u\n", i + 1, cnt_to_uint(&tbl->int_bits_count[i]));
555 cnt_add(&sum, &tbl->int_bits_count[i]);
557 fprintf(dmp->f, "-------------------------------\n");
559 fprintf(dmp->f, "\nFloating point constants classification\n");
560 fprintf(dmp->f, "--------------------------------------\n");
561 for (i = 0; i < ARR_SIZE(tbl->floats); ++i) {
562 fprintf(dmp->f, "%-10s %12u\n", stat_fc_name(i), cnt_to_uint(&tbl->floats[i]));
563 cnt_add(&sum, &tbl->floats[i]);
565 fprintf(dmp->f, "--------------------------------------\n");
567 fprintf(dmp->f, "other %12u\n", cnt_to_uint(&tbl->others));
568 cnt_add(&sum, &tbl->others);
569 fprintf(dmp->f, "-------------------------------\n");
571 fprintf(dmp->f, "sum %12u\n", cnt_to_uint(&sum));
572 } /* simple_dump_const_tbl */
575 * Dumps a line of the parameter table
577 static void dump_tbl_line(const distrib_entry_t *entry, void *env) {
580 fprintf(dmp->f, "%d : %u\n", PTR_TO_INT(entry->object), cnt_to_uint(&entry->cnt));
581 } /* dump_tbl_line */
584 * dumps the parameter distribution table
586 static void simple_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
587 fprintf(dmp->f, "\nCall parameter Information:\n");
588 fprintf(dmp->f, "---------------------\n");
590 stat_iterate_distrib_tbl(tbl, dump_tbl_line, dmp);
591 fprintf(dmp->f, "-------------------------------\n");
593 fprintf(dmp->f, "Number of Calls %12u\n", cnt_to_uint(&global->cnt[gcnt_all_calls]));
594 fprintf(dmp->f, "with const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_cnst_arg]));
595 fprintf(dmp->f, "with all const params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_all_cnst_arg]));
596 fprintf(dmp->f, "with local var adr params %12u\n", cnt_to_uint(&global->cnt[gcnt_call_with_local_adr]));
597 } /* simple_dump_param_tbl */
600 * initialize the simple dumper
602 static void simple_init(dumper_t *dmp, const char *name) {
605 snprintf(fname, sizeof(fname), "%s.txt", name);
606 dmp->f = fopen(fname, "w");
613 * finishes the simple dumper
615 static void simple_finish(dumper_t *dmp) {
619 } /* simple_finish */
622 * the simple human readable dumper
624 const dumper_t simple_dumper = {
626 simple_dump_const_tbl,
627 simple_dump_param_tbl,
634 FOURCC('S', 'M', 'P', 'L'),
637 /* ---------------------------------------------------------------------- */
640 * count the nodes as needed:
642 * 1 normal (data) Phi's
647 static void csv_count_nodes(dumper_t *dmp, graph_entry_t *graph, counter_t cnt[])
652 for (i = 0; i < 4; ++i)
655 foreach_pset(graph->opcode_hash, entry) {
656 if (entry->op == op_Phi) {
658 cnt_add(&cnt[1], &entry->cnt_alive);
659 } else if (entry->op == dmp->status->op_PhiM) {
661 cnt_add(&cnt[2], &entry->cnt_alive);
662 } else if (entry->op == op_Proj) {
664 cnt_add(&cnt[3], &entry->cnt_alive);
666 /* all other nodes */
667 cnt_add(&cnt[0], &entry->cnt_alive);
670 } /* csv_count_nodes */
675 static void csv_dump_graph(dumper_t *dmp, graph_entry_t *entry)
683 if (entry->irg && !entry->is_deleted) {
684 ir_graph *const_irg = get_const_code_irg();
686 if (entry->irg == const_irg) {
687 name = "<Const code Irg>";
691 name = get_entity_name(entry->ent);
693 name = "<UNKNOWN IRG>";
696 csv_count_nodes(dmp, entry, cnt);
698 fprintf(dmp->f, "%-40s, %p, %d, %d, %d, %d\n",
701 cnt_to_uint(&cnt[0]),
702 cnt_to_uint(&cnt[1]),
703 cnt_to_uint(&cnt[2]),
707 } /* csv_dump_graph */
712 static void csv_dump_const_tbl(dumper_t *dmp, const constant_info_t *tbl)
717 } /* csv_dump_const_tbl */
720 * dumps the parameter distribution table
722 static void csv_dump_param_tbl(dumper_t *dmp, const distrib_tbl_t *tbl, graph_entry_t *global) {
727 } /* csv_dump_param_tbl */
730 * initialize the simple dumper
732 static void csv_init(dumper_t *dmp, const char *name)
736 snprintf(fname, sizeof(fname), "%s.csv", name);
737 dmp->f = fopen(fname, "a");
743 * finishes the simple dumper
745 static void csv_finish(dumper_t *dmp)
753 * the simple human readable dumper
755 const dumper_t csv_dumper = {
765 FOURCC('C', 'S', 'V', '\0')