From 49945033749cf9da0be928d164653d491fb2d753 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Tue, 24 Oct 2006 12:08:02 +0000 Subject: [PATCH] make statfile available to the whole backend, output timing results to statfile --- ir/be/be_t.h | 3 +- ir/be/bechordal.c | 2 +- ir/be/bechordal_main.c | 54 ++++++----------------------------- ir/be/bemain.c | 19 ++++++++---- ir/be/bestat.c | 46 ++++++++++++++++++++++++++++++ ir/be/bestat.h | 16 +++++++++++ ir/be/bestatevent.c | 65 +++++++++++++++++++++++++++++------------- ir/be/bestatevent.h | 5 +--- 8 files changed, 134 insertions(+), 76 deletions(-) diff --git a/ir/be/be_t.h b/ir/be/be_t.h index 78937aafe..14a632bb7 100644 --- a/ir/be/be_t.h +++ b/ir/be/be_t.h @@ -39,7 +39,7 @@ enum { /** Backend options */ struct _be_options_t { - int dump_flags; /**< backend dumping flags */ + unsigned dump_flags; /**< backend dumping flags */ int timing; /**< time the backend phases */ int opt_profile; /**< instrument code for profiling */ int omit_fp; /**< try to omit the frame pointer */ @@ -47,6 +47,7 @@ struct _be_options_t { int vrfy_option; /**< backend verify option */ char ilp_server[128]; /**< the ilp server name */ char ilp_solver[128]; /**< the ilp solver name */ + char stat_file_name[256]; /**< name of the file where the statistics are put to */ }; struct _be_main_env_t { diff --git a/ir/be/bechordal.c b/ir/be/bechordal.c index 5459ad0ac..1222f832d 100644 --- a/ir/be/bechordal.c +++ b/ir/be/bechordal.c @@ -602,7 +602,7 @@ static ir_node *handle_constraints(be_chordal_alloc_env_t *alloc_env, ir_node *i continue; arch_set_irn_register(aenv, nodes[j], reg); - pset_hinsert_ptr(alloc_env->pre_colored, nodes[j]); + (void) pset_hinsert_ptr(alloc_env->pre_colored, nodes[j]); DBG((dbg, LEVEL_2, "\tsetting %+F to register %s\n", nodes[j], reg->name)); } } diff --git a/ir/be/bechordal_main.c b/ir/be/bechordal_main.c index 62dbe3226..d8a01035c 100644 --- a/ir/be/bechordal_main.c +++ b/ir/be/bechordal_main.c @@ -57,6 +57,7 @@ #include "beifg_impl.h" #include "benode_t.h" #include "bestatevent.h" +#include "bestat.h" #include "bespillbelady.h" #include "bespillmorgan.h" @@ -134,9 +135,6 @@ static be_ra_chordal_opts_t options = { BE_CH_VRFY_WARN, }; -/** The name of the file where the statistics are put to. */ -static char stat_file_name[2048]; - /** Enable extreme live range splitting. */ static int be_elr_split = 0; @@ -230,7 +228,6 @@ static lc_opt_enum_int_var_t be_ch_vrfy_var = { }; static const lc_opt_table_entry_t be_chordal_options[] = { - LC_OPT_ENT_STR ("statfile", "the name of the statisctics file", stat_file_name, sizeof(stat_file_name)), LC_OPT_ENT_ENUM_INT ("spill", "spill method", &spill_var), LC_OPT_ENT_ENUM_PTR ("ifg", "interference graph flavour", &ifg_flavor_var), LC_OPT_ENT_ENUM_PTR ("perm", "perm lowering options", &lower_perm_var), @@ -537,14 +534,6 @@ static void be_init_timer(be_options_t *main_opts) #endif /* WITH_LIBCORE */ -enum { - STAT_TAG_FILE = 0, - STAT_TAG_TIME = 1, - STAT_TAG_IRG = 2, - STAT_TAG_CLS = 3, - STAT_TAG_LAST -}; - /** * Performs chordal register allocation for each register class on given irg. * @@ -558,28 +547,9 @@ static be_ra_timer_t *be_ra_chordal_main(const be_irg_t *bi) ir_graph *irg = bi->irg; be_options_t *main_opts = main_env->options; int splitted = 0; - FILE *stat_file = NULL; - char time_str[32]; - char irg_name[128]; - int j, m, line; + int j, m; be_chordal_env_t chordal_env; - const char *stat_tags[STAT_TAG_LAST]; - - /* if we want to do some statistics, push the environment. */ - if(strlen(stat_file_name) > 0 && (stat_file = fopen(stat_file_name, "at")) != NULL) { - - /* initialize the statistics tags */ - ir_snprintf(time_str, sizeof(time_str),"%u", time(NULL)); - ir_snprintf(irg_name, sizeof(irg_name), "%F", irg); - - stat_tags[STAT_TAG_FILE] = be_retrieve_dbg_info(get_entity_dbg_info(get_irg_entity(irg)), &line); - stat_tags[STAT_TAG_TIME] = time_str; - stat_tags[STAT_TAG_IRG] = irg_name; - stat_tags[STAT_TAG_CLS] = ""; - - be_stat_ev_push(stat_tags, STAT_TAG_LAST, stat_file); - } BE_TIMER_INIT(main_opts); BE_TIMER_PUSH(ra_timer.t_other); @@ -592,7 +562,6 @@ static be_ra_timer_t *be_ra_chordal_main(const be_irg_t *bi) chordal_env.birg = bi; chordal_env.dom_front = be_compute_dominance_frontiers(irg); chordal_env.exec_freq = bi->execfreqs; - /*compute_execfreq(irg, be_loop_weight);*/ chordal_env.lv = be_liveness(irg); FIRM_DBG_REGISTER(chordal_env.dbg, "firm.be.chordal"); @@ -610,10 +579,10 @@ static be_ra_timer_t *be_ra_chordal_main(const be_irg_t *bi) chordal_env.border_heads = pmap_create(); chordal_env.ignore_colors = bitset_malloc(chordal_env.cls->n_regs); - stat_tags[STAT_TAG_CLS] = chordal_env.cls->name; + be_stat_tags[STAT_TAG_CLS] = chordal_env.cls->name; - if(stat_file) { - be_stat_ev_push(stat_tags, STAT_TAG_LAST, stat_file); + if(be_stat_ev_is_active()) { + be_stat_ev_push(be_stat_tags, STAT_TAG_LAST, be_stat_file); /* perform some node statistics. */ node_stats(&chordal_env, &node_stat); @@ -653,7 +622,7 @@ static be_ra_timer_t *be_ra_chordal_main(const be_irg_t *bi) BE_TIMER_POP(ra_timer.t_spill); - if(stat_file) { + if(be_stat_ev_is_active()) { node_stats(&chordal_env, &node_stat); be_stat_ev("phis_after_spill", node_stat.n_phis); be_stat_ev("mem_phis", node_stat.n_mem_phis); @@ -722,7 +691,7 @@ static be_ra_timer_t *be_ra_chordal_main(const be_irg_t *bi) } BE_TIMER_POP(ra_timer.t_ifg); - if(stat_file) { + if(be_stat_ev_is_active()) { be_ifg_stat_t stat; be_ifg_stat(&chordal_env, &stat); be_stat_ev("ifg_nodes", stat.n_nodes); @@ -737,7 +706,7 @@ static be_ra_timer_t *be_ra_chordal_main(const be_irg_t *bi) BE_TIMER_POP(ra_timer.t_verify); - if(stat_file) { + if(be_stat_ev_is_active()) { node_stats(&chordal_env, &node_stat); be_stat_ev("perms_before_coal", node_stat.n_perms); be_stat_ev("copies_before_coal", node_stat.n_copies); @@ -777,7 +746,7 @@ static be_ra_timer_t *be_ra_chordal_main(const be_irg_t *bi) pmap_destroy(chordal_env.border_heads); bitset_free(chordal_env.ignore_colors); - if(stat_file) { + if(be_stat_ev_is_active()) { node_stats(&chordal_env, &node_stat); be_stat_ev("perms_after_coal", node_stat.n_perms); be_stat_ev("copies_after_coal", node_stat.n_copies); @@ -814,16 +783,11 @@ static be_ra_timer_t *be_ra_chordal_main(const be_irg_t *bi) obstack_free(&chordal_env.obst, NULL); be_free_dominance_frontiers(chordal_env.dom_front); be_liveness_free(chordal_env.lv); - //free_execfreq(chordal_env.exec_freq); BE_TIMER_POP(ra_timer.t_epilog); BE_TIMER_POP(ra_timer.t_other); be_stat_ev("insns_after", count_insns(irg)); - be_stat_ev_pop(); - - if(stat_file) - fclose(stat_file); #ifdef WITH_LIBCORE return main_opts->timing == BE_TIME_ON ? &ra_timer : NULL; diff --git a/ir/be/bemain.c b/ir/be/bemain.c index 751c445e2..57012d24b 100644 --- a/ir/be/bemain.c +++ b/ir/be/bemain.c @@ -159,6 +159,7 @@ static const lc_opt_table_entry_t be_main_options[] = { LC_OPT_ENT_ENUM_PTR ("vrfy", "verify the backend irg", &vrfy_var), LC_OPT_ENT_BOOL ("time", "get backend timing statistics", &be_options.timing), LC_OPT_ENT_BOOL ("profile", "instrument the code for execution count profiling", &be_options.opt_profile), + LC_OPT_ENT_STR ("statfile", "append statistics to file statfile", &be_options.stat_file_name, sizeof(be_options.stat_file_name)), #ifdef WITH_ILP LC_OPT_ENT_STR ("ilp.server", "the ilp server name", be_options.ilp_server, sizeof(be_options.ilp_server)), @@ -481,6 +482,8 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) /* set the current graph (this is important for several firm functions) */ current_ir_graph = irg; + be_init_stat_file(be_options.stat_file_name, irg); + /* stop and reset timers */ BE_TIMER_ONLY( LC_STOP_AND_RESET_TIMER(t_abi); @@ -663,8 +666,13 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) BE_TIMER_ONLY(num_nodes_a = get_num_reachable_nodes(irg)); BE_TIMER_POP(t_other); -#define LC_EMIT(timer) printf("%-20s: %.3lf msec\n", lc_timer_get_description(timer), (double)lc_timer_elapsed_usec(timer) / 1000.0) -#define LC_EMIT_RA(timer) printf("\t%-20s: %.3lf msec\n", lc_timer_get_description(timer), (double)lc_timer_elapsed_usec(timer) / 1000.0) +#define LC_EMIT(timer) \ + printf("%-20s: %.3lf msec\n", lc_timer_get_description(timer), (double)lc_timer_elapsed_usec(timer) / 1000.0); \ + be_stat_ev_l(lc_timer_get_name(timer), lc_timer_elapsed_msec(timer)); + +#define LC_EMIT_RA(timer) \ + printf("\t%-20s: %.3lf msec\n", lc_timer_get_description(timer), (double)lc_timer_elapsed_usec(timer) / 1000.0); \ + be_stat_ev_l(lc_timer_get_name(timer), lc_timer_elapsed_msec(timer)); BE_TIMER_ONLY( printf("==>> IRG %s <<==\n", get_entity_name(get_irg_entity(irg))); printf("# nodes at begin: %u\n", num_nodes_b); @@ -699,6 +707,8 @@ static void be_main_loop(FILE *file_handle, const char *cup_name) /* switched off due to statistics (statistic module needs all irgs) */ if (! stat_is_active()) free_ir_graph(irg); + + be_close_stat_file(); } be_profile_free(); be_done_env(&env); @@ -713,9 +723,7 @@ void be_main(FILE *file_handle, const char *cup_name) { #ifdef WITH_LIBCORE lc_timer_t *t = NULL; -#endif /* WITH_LIBCORE */ -#ifdef WITH_LIBCORE /* The user specified another config file to read. do that now. */ if(strlen(config_file) > 0) { FILE *f; @@ -764,6 +772,7 @@ void be_set_debug_retrieve(retrieve_dbg_func func) { const char *be_retrieve_dbg_info(const dbg_info *dbg, unsigned *line) { if (retrieve_dbg) return retrieve_dbg(dbg, line); + *line = 0; return NULL; } @@ -779,6 +788,6 @@ int be_put_ignore_regs(const be_irg_t *birg, const arch_register_class_t *cls, b arch_put_non_ignore_regs(birg->main_env->arch_env, cls, bs); bitset_flip_all(bs); be_abi_put_ignore_regs(birg->abi, cls, bs); - return bitset_popcnt(bs); + return bitset_popcnt(bs); } diff --git a/ir/be/bestat.c b/ir/be/bestat.c index 8ac3d6dba..486fad84e 100644 --- a/ir/be/bestat.c +++ b/ir/be/bestat.c @@ -10,6 +10,8 @@ #ifdef FIRM_STATISTICS +#include + #include "irnode_t.h" #include "irprintf.h" #include "irgwalk.h" @@ -301,6 +303,50 @@ void be_stat_init_irg(const arch_env_t *arch_env, ir_graph *irg) { } } +const char *be_stat_tags[STAT_TAG_LAST]; + +FILE *be_stat_file = NULL; + +void be_init_stat_file(const char *stat_file_name, ir_graph *irg) +{ + unsigned line; + static char time_str[32]; + static char irg_name[128]; + + assert(be_stat_file == NULL); + + /* if we want to do some statistics, push the environment. */ + if(strlen(stat_file_name) == 0) + return; + + be_stat_file = fopen(stat_file_name, "at"); + if(be_stat_file == NULL) { + fprintf(stderr, "Warning couldn't open statfile '%s'\n", stat_file_name); + return; + } + + /* initialize the statistics tags */ + ir_snprintf(time_str, sizeof(time_str),"%u", time(NULL)); + ir_snprintf(irg_name, sizeof(irg_name), "%F", irg); + + be_stat_tags[STAT_TAG_FILE] = be_retrieve_dbg_info(get_entity_dbg_info(get_irg_entity(irg)), &line); + be_stat_tags[STAT_TAG_TIME] = time_str; + be_stat_tags[STAT_TAG_IRG] = irg_name; + be_stat_tags[STAT_TAG_CLS] = ""; + + be_stat_ev_push(be_stat_tags, STAT_TAG_LAST, be_stat_file); +} + +void be_close_stat_file() +{ + be_stat_ev_pop(); + if(be_stat_file != NULL) { + fclose(be_stat_file); + be_stat_file = NULL; + } +} + + #else void (be_stat_init_irg)(const arch_env_t *arch_env, ir_graph *irg) {} diff --git a/ir/be/bestat.h b/ir/be/bestat.h index d57fdc094..3ca4d1a0f 100644 --- a/ir/be/bestat.h +++ b/ir/be/bestat.h @@ -10,6 +10,19 @@ #include "firm_config.h" #include "be_t.h" #include "benodesets.h" +#include "bestatevent.h" + +enum { + STAT_TAG_FILE = 0, /**< tag for source file name */ + STAT_TAG_TIME = 1, /**< tag for time */ + STAT_TAG_IRG = 2, /**< tag for function name (irg) */ + STAT_TAG_CLS = 3, /**< tag for register class (or "") */ + STAT_TAG_LAST +}; + +extern FILE *be_stat_file; +extern const char *be_stat_tags[STAT_TAG_LAST]; + #ifdef FIRM_STATISTICS @@ -63,6 +76,9 @@ void be_do_stat_nodes(ir_graph *irg, const char *phase); */ void be_stat_init_irg(const arch_env_t *arch_env, ir_graph *irg); +void be_init_stat_file(const char *filename, ir_graph *irg); +void be_close_stat_file(void); + #else #define be_stat_init_irg(arch_env, irg) diff --git a/ir/be/bestatevent.c b/ir/be/bestatevent.c index f8854c37b..c0082004f 100644 --- a/ir/be/bestatevent.c +++ b/ir/be/bestatevent.c @@ -4,6 +4,9 @@ * @author Sebastian Hack * @cvs-id $Id$ */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #include #include @@ -18,7 +21,7 @@ typedef struct { } ev_env_t; static ev_env_t envs[STACK_SIZE]; -static int sp = 0; +static unsigned sp = 0; void be_stat_ev_push(const char **tags, int n_tags, FILE *f) { @@ -39,39 +42,61 @@ void be_stat_ev_push(const char **tags, int n_tags, FILE *f) void be_stat_ev_pop(void) { - if(sp > 0) { - envs[--sp].f = NULL; - } + if(sp == 0) + return; + + envs[--sp].f = NULL; } void be_stat_ev(const char *ev, int value) { - if(sp > 0) { - ev_env_t *env = &envs[sp - 1]; - if(env->f) - fprintf(env->f, "%s%s;%d\n", env->tag, ev, value); - } + if(sp == 0) + return; + + ev_env_t *env = &envs[sp - 1]; + if(env->f == NULL) + return; + + fprintf(env->f, "%s%s;%d\n", env->tag, ev, value); +} + +void be_stat_ev_l(const char *ev, long value) +{ + if(sp == 0) + return; + + ev_env_t *env = &envs[sp - 1]; + if(env->f == NULL) + return; + + fprintf(env->f, "%s%s;%ld\n", env->tag, ev, value); } void be_stat_ev_dbl(const char *ev, double value) { - if(sp > 0) { - ev_env_t *env = &envs[sp - 1]; - if(env->f) - fprintf(env->f, "%s%s;%f\n", env->tag, ev, value); - } + if(sp == 0) + return; + + ev_env_t *env = &envs[sp - 1]; + if(env->f == NULL) + return; + + fprintf(env->f, "%s%s;%f\n", env->tag, ev, value); } void be_stat_ev_ull(const char *ev, ulong64 value) { - if(sp > 0) { - ev_env_t *env = &envs[sp - 1]; - if(env->f) - fprintf(env->f, "%s%s;%" ULL_FMT "\n", env->tag, ev, value); - } + if(sp == 0) + return; + + ev_env_t *env = &envs[sp - 1]; + if(env->f == NULL) + return; + + fprintf(env->f, "%s%s;%" ULL_FMT "\n", env->tag, ev, value); } int be_stat_ev_is_active(void) { - return sp > 0 && envs[sp - 1].f; + return sp > 0 && envs[sp - 1].f != NULL; } diff --git a/ir/be/bestatevent.h b/ir/be/bestatevent.h index 93b9acddf..3d092732a 100644 --- a/ir/be/bestatevent.h +++ b/ir/be/bestatevent.h @@ -11,14 +11,11 @@ #include "firm_types.h" -#define BE_STAT_EV_N_INSN "n_insn" -#define BE_STAT_EV_PHI_BEFORE_SPILL "phi_before_spill" -#define BE_STAT_EV_PHI_AFTER_SPILL "phi_after_spill" - void be_stat_ev_push(const char **tags, int n_tags, FILE *f); void be_stat_ev_pop(void); void be_stat_ev(const char *ev, int value); +void be_stat_ev_l(const char *ev, long value); void be_stat_ev_dbl(const char *ev, double value); void be_stat_ev_ull(const char *ev, ulong64 value); -- 2.20.1