Commit 49945033 authored by Matthias Braun's avatar Matthias Braun
Browse files

make statfile available to the whole backend, output timing results to statfile

parent 45aaa42d
......@@ -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 {
......
......@@ -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));
}
}
......
......@@ -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] = "<all>";
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;
......
......@@ -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);
}
......@@ -10,6 +10,8 @@
#ifdef FIRM_STATISTICS
#include <time.h>
#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] = "<all>";
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) {}
......
......@@ -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 "<all>") */
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)
......
......@@ -4,6 +4,9 @@
* @author Sebastian Hack
* @cvs-id $Id$
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <assert.h>
#include <string.h>
......@@ -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;
}
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment