+
+ /* some calculations are dependent, we pushed them on the wait_q */
+ while (! pdeq_empty(status->wait_q)) {
+ entry = pdeq_getr(status->wait_q);
+
+ update_graph_stat_2(global, entry);
+ }
+
+
+ /* dump per graph */
+ for (entry = pset_first(status->irg_hash); entry; entry = pset_next(status->irg_hash)) {
+
+ if (entry->irg == NULL) {
+ /* special entry for the global count */
+ continue;
+ }
+
+ if (! entry->is_deleted || status->stat_options & FIRMSTAT_COUNT_DELETED) {
+ stat_dump_graph(entry);
+ }
+
+ if (! entry->is_deleted) {
+ /* clear the counter that are not accumulated */
+ graph_clear_entry(entry, 0);
+ }
+ }
+
+ /* dump global */
+ stat_dump_graph(global);
+
+ /* dump the const info */
+ if (status->stat_options & FIRMSTAT_COUNT_CONSTS)
+ stat_dump_consts(&status->const_info);
+
+ stat_dump_finish();
+
+ stat_finish_pattern_history();
+
+ /* clear the global counter here */
+ {
+ node_entry_t *entry;
+
+ for (entry = pset_first(global->opcode_hash); entry; entry = pset_next(global->opcode_hash)) {
+ opcode_clear_entry(entry);
+ }
+ /* clear all global counter */
+ graph_clear_entry(global, 1);
+ }
+ }
+ STAT_LEAVE;
+}
+
+/** the hook entries for the Firm statistics module */
+static hook_entry_t stat_hooks[hook_last];
+
+/* initialize the statistics module. */
+void init_stat(unsigned enable_options)
+{
+#define X(a) a, sizeof(a)-1
+#define HOOK(h, fkt) \
+ stat_hooks[h].hook._##h = fkt; register_hook(h, &stat_hooks[h])
+
+ if (! (enable_options & FIRMSTAT_ENABLED))
+ return;
+
+ status = xmalloc(sizeof(*status));
+ memset(status, 0, sizeof(*status));
+
+ /* enable statistics */
+ status->stat_options = enable_options & FIRMSTAT_ENABLED ? enable_options : 0;
+
+ /* register all hooks */
+ HOOK(hook_new_ir_op, stat_new_ir_op);
+ HOOK(hook_free_ir_op, stat_free_ir_op);
+ HOOK(hook_new_node, stat_new_node);
+ HOOK(hook_turn_into_id, stat_turn_into_id);
+ HOOK(hook_new_graph, stat_new_graph);
+ HOOK(hook_free_graph, stat_free_graph);
+ HOOK(hook_irg_walk, stat_irg_walk);
+ HOOK(hook_irg_walk_blkwise, stat_irg_walk_blkwise);
+ HOOK(hook_irg_block_walk, stat_irg_block_walk);
+ HOOK(hook_merge_nodes, stat_merge_nodes);
+ HOOK(hook_reassociate, stat_reassociate);
+ HOOK(hook_lower, stat_lower);
+ HOOK(hook_inline, stat_inline);
+ HOOK(hook_tail_rec, stat_tail_rec);
+ HOOK(hook_strength_red, stat_strength_red);
+ HOOK(hook_dead_node_elim, stat_dead_node_elim);
+ HOOK(hook_if_conversion, stat_if_conversion);
+ HOOK(hook_func_call, stat_func_call);
+ HOOK(hook_arch_dep_replace_mul_with_shifts, stat_arch_dep_replace_mul_with_shifts);
+ HOOK(hook_arch_dep_replace_division_by_const, stat_arch_dep_replace_division_by_const);
+
+ obstack_init(&status->cnts);
+
+ /* create the hash-tables */
+ status->irg_hash = new_pset(graph_cmp, 8);
+ status->ir_op_hash = new_pset(opcode_cmp_2, 1);
+
+ /* create the wait queue */
+ status->wait_q = new_pdeq();
+
+ if (enable_options & FIRMSTAT_COUNT_STRONG_OP) {
+ /* build the pseudo-ops */
+ _op_Phi0.code = get_next_ir_opcode();
+ _op_Phi0.name = new_id_from_chars(X("Phi0"));
+
+ _op_PhiM.code = get_next_ir_opcode();
+ _op_PhiM.name = new_id_from_chars(X("PhiM"));
+
+ _op_ProjM.code = get_next_ir_opcode();
+ _op_ProjM.name = new_id_from_chars(X("ProjM"));
+
+ _op_MulC.code = get_next_ir_opcode();
+ _op_MulC.name = new_id_from_chars(X("MulC"));
+
+ _op_DivC.code = get_next_ir_opcode();
+ _op_DivC.name = new_id_from_chars(X("DivC"));
+
+ _op_ModC.code = get_next_ir_opcode();
+ _op_ModC.name = new_id_from_chars(X("ModC"));
+
+ _op_DivModC.code = get_next_ir_opcode();
+ _op_DivModC.name = new_id_from_chars(X("DivModC"));
+
+ status->op_Phi0 = &_op_Phi0;
+ status->op_PhiM = &_op_PhiM;
+ status->op_ProjM = &_op_ProjM;
+ status->op_MulC = &_op_MulC;
+ status->op_DivC = &_op_DivC;
+ status->op_ModC = &_op_ModC;
+ status->op_DivModC = &_op_DivModC;