X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fstat%2Ffirmstat.c;h=42dc887068b4d92b0011be2255cb528b0aec6b84;hb=2ea59d24639602c1e2f1a1a18dd687b2e5c5c2a8;hp=f0080d491b5552e33f1f1d5e17409a12ebee9a66;hpb=523a9d5e56b79c8d9bc3c570d8c0319c40a171e9;p=libfirm diff --git a/ir/stat/firmstat.c b/ir/stat/firmstat.c index f0080d491..42dc88706 100644 --- a/ir/stat/firmstat.c +++ b/ir/stat/firmstat.c @@ -313,9 +313,9 @@ static graph_entry_t *graph_get_entry(ir_graph *irg, hmap_graph_entry_t *hmap) graph_clear_entry(elem, 1); /* new hash table for opcodes here */ - elem->opcode_hash = new_pset(opcode_cmp, 5); - elem->address_mark = new_set(address_mark_cmp, 5); - elem->irg = irg; + elem->opcode_hash = new_pset(opcode_cmp, 5); + elem->address_mark = new_set(address_mark_cmp, 5); + elem->irg = irg; /* these hash tables are created on demand */ elem->block_hash = NULL; @@ -863,7 +863,8 @@ static void update_node_stat(ir_node *node, void *env) /* count extended block edges */ if (status->stat_options & FIRMSTAT_COUNT_EXTBB) { - undate_extbb_info(node, graph); + if (graph->irg != get_const_code_irg()) + undate_extbb_info(node, graph); } /* handle statistics for special node types */ @@ -1006,16 +1007,16 @@ static void update_graph_stat(graph_entry_t *global, graph_entry_t *graph) graph->block_hash = new_pset(block_cmp, 5); /* we need dominator info */ - if (graph->irg != get_const_code_irg()) - if (get_irg_dom_state(graph->irg) != dom_consistent) - compute_doms(graph->irg); + if (graph->irg != get_const_code_irg()) { + assure_doms(graph->irg); - if (status->stat_options & FIRMSTAT_COUNT_EXTBB) { - /* we need extended basic blocks */ - compute_extbb(graph->irg); + if (status->stat_options & FIRMSTAT_COUNT_EXTBB) { + /* we need extended basic blocks */ + compute_extbb(graph->irg); - /* create new extbb counter */ - graph->extbb_hash = new_pset(block_cmp, 5); + /* create new extbb counter */ + graph->extbb_hash = new_pset(block_cmp, 5); + } } /* count the nodes in the graph */ @@ -1114,7 +1115,7 @@ static void stat_register_dumper(const dumper_t *dumper) dumper_t *p = xmalloc(sizeof(*p)); if (p) { - *p = *dumper; + memcpy(p, dumper, sizeof(*p)); p->next = status->dumper; p->status = status; @@ -1137,6 +1138,23 @@ static void stat_dump_graph(graph_entry_t *entry) } } +/** + * calls all registered functions. + */ +static void stat_dump_registered(graph_entry_t *entry) +{ + dumper_t *dumper; + + for (dumper = status->dumper; dumper; dumper = dumper->next) { + if (dumper->func_map) { + dump_graph_FUNC func; + + foreach_pset(dumper->func_map, func) + func(dumper, entry); + } + } +} + /** * dumps a constant table */ @@ -1176,6 +1194,19 @@ static void stat_dump_finish(void) } } +/** + * register an additional function for all dumper + */ +void stat_register_dumper_func(dump_graph_FUNC func) { + dumper_t *dumper; + + for (dumper = status->dumper; dumper; dumper = dumper->next) { + if (! dumper->func_map) + dumper->func_map = pset_new_ptr(3); + pset_insert_ptr(dumper->func_map, func); + } +} + /* ---------------------------------------------------------------------- */ /* @@ -1556,7 +1587,7 @@ static void stat_tail_rec(void *ctx, ir_graph *irg, int n_calls) * * @param ctx the hook context */ -static void stat_strength_red(void *ctx, ir_graph *irg, ir_node *strong, ir_node *cmp) +static void stat_strength_red(void *ctx, ir_graph *irg, ir_node *strong) { if (! status->stat_options) return; @@ -1659,47 +1690,45 @@ static void stat_arch_dep_replace_division_by_const(void *ctx, ir_node *node) STAT_LEAVE; } -/** +/* * Update the register pressure of a block * - * @param ctx the hook context - * @param block the block for which the reg pressure should be set * @param irg the irg containing the block + * @param block the block for which the reg pressure should be set * @param pressure the pressure * @param class_name the name of the register class */ -static void stat_be_block_regpressure(void *ctx, ir_node *block, ir_graph *irg, int pressure, const char *class_name) +void stat_be_block_regpressure(ir_graph *irg, ir_node *block, int pressure, const char *class_name) { - if (! status->stat_options) - return; + if (! status->stat_options) + return; - STAT_ENTER; - { - graph_entry_t *graph = graph_get_entry(irg, status->irg_hash); - be_block_entry_t *block_ent; - reg_pressure_entry_t *rp_ent; + STAT_ENTER; + { + graph_entry_t *graph = graph_get_entry(irg, status->irg_hash); + be_block_entry_t *block_ent; + reg_pressure_entry_t *rp_ent; - block_ent = be_block_get_entry(&status->be_data, get_irn_node_nr(block), graph->be_block_hash); - rp_ent = obstack_alloc(&status->be_data, sizeof(*rp_ent)); - memset(rp_ent, 0, sizeof(*rp_ent)); + block_ent = be_block_get_entry(&status->be_data, get_irn_node_nr(block), graph->be_block_hash); + rp_ent = obstack_alloc(&status->be_data, sizeof(*rp_ent)); + memset(rp_ent, 0, sizeof(*rp_ent)); - rp_ent->class_name = class_name; - rp_ent->pressure = pressure; + rp_ent->class_name = class_name; + rp_ent->pressure = pressure; - pset_insert(block_ent->reg_pressure, rp_ent, HASH_PTR(class_name)); - } - STAT_LEAVE; + pset_insert(block_ent->reg_pressure, rp_ent, HASH_PTR(class_name)); + } + STAT_LEAVE; } /** * Update the distribution of ready nodes of a block * - * @param ctx the hook context - * @param block the block for which the reg pressure should be set * @param irg the irg containing the block + * @param block the block for which the reg pressure should be set * @param num_ready the number of ready nodes */ -static void stat_be_block_sched_ready(void *ctx, ir_node *block, ir_graph *irg, int num_ready) +void stat_be_block_sched_ready(ir_graph *irg, ir_node *block, int num_ready) { if (! status->stat_options) return; @@ -1708,12 +1737,11 @@ static void stat_be_block_sched_ready(void *ctx, ir_node *block, ir_graph *irg, { graph_entry_t *graph = graph_get_entry(irg, status->irg_hash); be_block_entry_t *block_ent; - const counter_t *cnt_1 = cnt_get_1(); block_ent = be_block_get_entry(&status->be_data, get_irn_node_nr(block), graph->be_block_hash); - /* add 1 to the counter of corresponding number of ready nodes */ - stat_add_int_distrib_tbl(block_ent->sched_ready, num_ready, cnt_1); + /* increase the counter of corresponding number of ready nodes */ + stat_inc_int_distrib_tbl(block_ent->sched_ready, num_ready); } STAT_LEAVE; } @@ -1721,14 +1749,14 @@ static void stat_be_block_sched_ready(void *ctx, ir_node *block, ir_graph *irg, /** * Update the permutation statistic of a block * - * @param ctx the hook context * @param class_name the name of the register class + * @param n_regs number of registers in the register class * @param perm the perm node * @param block the block containing the perm * @param size the size of the perm * @param real_size number of pairs with different registers */ -void stat_be_block_stat_perm(void *ctx, const char *class_name, int n_regs, ir_node *perm, ir_node *block, +void stat_be_block_stat_perm(const char *class_name, int n_regs, ir_node *perm, ir_node *block, int size, int real_size) { if (! status->stat_options) @@ -1757,14 +1785,14 @@ void stat_be_block_stat_perm(void *ctx, const char *class_name, int n_regs, ir_n /** * Update the permutation statistic of a single perm * - * @param ctx the hook context * @param class_name the name of the register class * @param perm the perm node * @param block the block containing the perm * @param is_chain 1 if chain, 0 if cycle + * @param size length of the cycle/chain * @param n_ops the number of ops representing this cycle/chain after lowering */ -void stat_be_block_stat_permcycle(void *ctx, const char *class_name, ir_node *perm, ir_node *block, +void stat_be_block_stat_permcycle(const char *class_name, ir_node *perm, ir_node *block, int is_chain, int size, int n_ops) { if (! status->stat_options) @@ -1773,7 +1801,6 @@ void stat_be_block_stat_permcycle(void *ctx, const char *class_name, ir_node *pe STAT_ENTER; { graph_entry_t *graph = graph_get_entry(get_irn_irg(block), status->irg_hash); - const counter_t *cnt_1 = cnt_get_1(); be_block_entry_t *block_ent; perm_class_entry_t *pc_ent; perm_stat_entry_t *ps_ent; @@ -1784,11 +1811,11 @@ void stat_be_block_stat_permcycle(void *ctx, const char *class_name, ir_node *pe if (is_chain) { ps_ent->n_copies += n_ops; - stat_add_int_distrib_tbl(ps_ent->chains, size, cnt_1); + stat_inc_int_distrib_tbl(ps_ent->chains, size); } else { ps_ent->n_exchg += n_ops; - stat_add_int_distrib_tbl(ps_ent->cycles, size, cnt_1); + stat_inc_int_distrib_tbl(ps_ent->cycles, size); } } STAT_LEAVE; @@ -1883,6 +1910,7 @@ void stat_dump_snapshot(const char *name, const char *phase) if (! entry->is_deleted || status->stat_options & FIRMSTAT_COUNT_DELETED) { stat_dump_graph(entry); + stat_dump_registered(entry); } if (! entry->is_deleted) { @@ -1957,10 +1985,6 @@ void firm_init_stat(unsigned enable_options) 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); - HOOK(hook_be_block_regpressure, stat_be_block_regpressure); - HOOK(hook_be_block_sched_ready, stat_be_block_sched_ready); - HOOK(hook_be_block_stat_perm, stat_be_block_stat_perm); - HOOK(hook_be_block_stat_permcycle, stat_be_block_stat_permcycle); obstack_init(&status->cnts); obstack_init(&status->be_data); @@ -2046,16 +2070,41 @@ void firm_init_stat(unsigned enable_options) #undef X } +/** + * Frees all dumper structures; + */ +static void stat_term_dumper() { + dumper_t *dumper, *next_dumper; + + for (dumper = status->dumper; dumper; /* iteration done in loop body */ ) { + if (dumper->func_map) + del_pset(dumper->func_map); + + next_dumper = dumper->next; + free(dumper); + dumper = next_dumper; + } +} + + /* terminates the statistics module, frees all memory */ void stat_term(void) { if (status != (stat_info_t *)&status_disable) { obstack_free(&status->be_data, NULL); obstack_free(&status->cnts, NULL); + + stat_term_dumper(); + xfree(status); status = (stat_info_t *)&status_disable; } } +/* returns 1 if statistics were initialized, 0 otherwise */ +int stat_is_active(void) { + return status != (stat_info_t *)&status_disable; +} + #else /* initialize the statistics module. */