From ff244fb7355c6120cf0f15ba7911b473bb91c64b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Christian=20W=C3=BCrdig?= Date: Fri, 7 Apr 2006 14:03:11 +0000 Subject: [PATCH] added register pressure statistics [r7601] --- ir/stat/firmstat.c | 52 ++++++++++++++++++++++++++++++++++++++++++++ ir/stat/firmstat_t.h | 39 ++++++++++++++++++++++----------- ir/stat/stat_dmp.c | 41 ++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+), 13 deletions(-) diff --git a/ir/stat/firmstat.c b/ir/stat/firmstat.c index 9d1781f5f..aa3a594bb 100644 --- a/ir/stat/firmstat.c +++ b/ir/stat/firmstat.c @@ -129,6 +129,17 @@ static int block_cmp(const void *elt, const void *key) return e1->block_nr != e2->block_nr; } +/** + * compare two elements of the block/extbb hash + */ +static int reg_pressure_cmp(const void *elt, const void *key) +{ + const reg_pressure_entry_t *e1 = elt; + const reg_pressure_entry_t *e2 = key; + + return e1->id_name != e2->id_name; +} + /** * compare two elements of the ir_op hash */ @@ -267,6 +278,9 @@ static graph_entry_t *graph_get_entry(ir_graph *irg, hmap_graph_entry_t *hmap) elem->address_mark = new_set(address_mark_cmp, 5); elem->irg = irg; + /* create hash map for reg pressure */ + elem->rp_block_hash = new_pset(block_cmp, 5); + /* these hash tables are created on demand */ elem->block_hash = NULL; elem->extbb_hash = NULL; @@ -323,6 +337,7 @@ static void block_clear_entry(block_entry_t *elem) cnt_clr(&elem->cnt_in_edges); cnt_clr(&elem->cnt_out_edges); cnt_clr(&elem->cnt_phi_data); + elem->reg_pressure = new_pset(reg_pressure_cmp, 2); } /** @@ -1482,6 +1497,42 @@ 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 pressure the pressure + * @param class_name the ident name of the register class + */ +static void stat_be_block_regpressure(void *ctx, ir_node *block, ir_graph *irg, int pressure, ident *class_name) +{ + if (! status->stat_options) + return; + + STAT_ENTER; + { + graph_entry_t *graph = graph_get_entry(irg, status->irg_hash); + block_entry_t *block_ent; + reg_pressure_entry_t *rp_ent; + + /* create new block counter */ + if (! graph->rp_block_hash) + graph->rp_block_hash = new_pset(block_cmp, 5); + + block_ent = block_get_entry(&graph->recalc_cnts, get_irn_node_nr(block), graph->rp_block_hash); + rp_ent = obstack_alloc(&status->cnts, sizeof(*rp_ent)); + memset(rp_ent, 0, sizeof(*rp_ent)); + + rp_ent->id_name = class_name; + rp_ent->pressure = pressure; + + pset_insert(block_ent->reg_pressure, rp_ent, HASH_PTR(class_name)); + } + STAT_LEAVE; +} + /* Dumps a statistics snapshot */ void stat_dump_snapshot(const char *name, const char *phase) { @@ -1645,6 +1696,7 @@ 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); obstack_init(&status->cnts); diff --git a/ir/stat/firmstat_t.h b/ir/stat/firmstat_t.h index 831b5dd4b..66553c01a 100644 --- a/ir/stat/firmstat_t.h +++ b/ir/stat/firmstat_t.h @@ -25,6 +25,7 @@ #include "irgwalk.h" #include "counter.h" #include "irhooks.h" +#include "ident.h" /* some useful macro. */ #define ARR_SIZE(a) (sizeof(a)/sizeof((a)[0])) @@ -39,6 +40,7 @@ typedef pset hmap_node_entry_t; typedef pset hmap_graph_entry_t; typedef pset hmap_opt_entry_t; typedef pset hmap_block_entry_t; +typedef pset hmap_reg_pressure_entry_t; typedef pset hmap_ir_op; typedef pset hmap_distrib_entry_t; @@ -83,7 +85,8 @@ typedef struct _graph_entry_t { HASH_MAP(node_entry_t) *opcode_hash; /**< hash map containing the opcode counter */ HASH_MAP(block_entry_t) *block_hash; /**< hash map containing the block counter */ HASH_MAP(block_entry_t) *extbb_hash; /**< hash map containing the extended block counter */ - counter_t cnt_walked; /**< walker walked over the graph */ + HASH_MAP(block_entry_t) *rp_block_hash; /**< hash map containing the block reg pressure information */ + counter_t cnt_walked; /**< walker walked over the graph */ counter_t cnt_walked_blocks; /**< walker walked over the graph blocks */ counter_t cnt_was_inlined; /**< number of times other graph were inlined */ counter_t cnt_got_inlined; /**< number of times this graph was inlined */ @@ -115,16 +118,26 @@ typedef struct _opt_entry_t { const ir_op *op; /**< the op for this entry */ } opt_entry_t; +/** + * An entry for register pressure. + */ +typedef struct _reg_pressure_entry_t { + ident *id_name; /**< name of the register class */ + int pressure; /**< the register pressure for this class */ +} reg_pressure_entry_t; + /** * An entry for a block or extended block in a ir-graph */ typedef struct _block_entry_t { - counter_t cnt_nodes; /**< the counter of nodes in this block */ - counter_t cnt_edges; /**< the counter of edges in this block */ - counter_t cnt_in_edges; /**< the counter of edges incoming from other blocks to this block */ - counter_t cnt_out_edges; /**< the counter of edges outgoing from this block to other blocks */ - counter_t cnt_phi_data; /**< the counter of data Phi nodes in this block */ - long block_nr; /**< block nr */ + counter_t cnt_nodes; /**< the counter of nodes in this block */ + counter_t cnt_edges; /**< the counter of edges in this block */ + counter_t cnt_in_edges; /**< the counter of edges incoming from other blocks to this block */ + counter_t cnt_out_edges; /**< the counter of edges outgoing from this block to other blocks */ + counter_t cnt_phi_data; /**< the counter of data Phi nodes in this block */ + long block_nr; /**< block nr */ + /**< the highest register pressures for this block for each register class */ + HASH_MAP(reg_pressure_entry_t) *reg_pressure; } block_entry_t; /** An entry for an extended block in a ir-graph */ @@ -232,8 +245,8 @@ ir_op *stat_get_op_from_opcode(opcode code); * An entry in a distribution table */ typedef struct _distrib_entry_t { - counter_t cnt; /**< the current count */ - const void *object; /**< the object which is counted */ + counter_t cnt; /**< the current count */ + const void *object; /**< the object which is counted */ } distrib_entry_t; /** The type of the hash function for objects in distribution tables. */ @@ -243,10 +256,10 @@ typedef unsigned (*distrib_hash_fun)(const void *object); * The distribution table. */ typedef struct _distrib_tbl_t { - struct obstack cnts; /**< obstack containing the distrib_entry_t entries */ - HASH_MAP(distrib_entry_t) *hash_map; /**< the hash map containing the distribution */ - distrib_hash_fun hash_func; /**< the hash function for object in this distribution */ - unsigned int_dist; /**< non-zero, if it's a integer distribution */ + struct obstack cnts; /**< obstack containing the distrib_entry_t entries */ + HASH_MAP(distrib_entry_t) *hash_map; /**< the hash map containing the distribution */ + distrib_hash_fun hash_func; /**< the hash function for object in this distribution */ + unsigned int_dist; /**< non-zero, if it's a integer distribution */ } distrib_tbl_t; /* API for distribution tables */ diff --git a/ir/stat/stat_dmp.c b/ir/stat/stat_dmp.c index d33184c26..caf4b3076 100644 --- a/ir/stat/stat_dmp.c +++ b/ir/stat/stat_dmp.c @@ -148,6 +148,44 @@ static void simple_dump_opt_hash(dumper_t *dmp, pset *set, int index) } } +/** + * dumps the register pressure for each block and for each register class + */ +static void simple_dump_be_block_reg_pressure(dumper_t *dmp, graph_entry_t *entry) { + block_entry_t *b_entry = pset_first(entry->rp_block_hash); + reg_pressure_entry_t *rp_entry; + + /* return if no reg pressure information available */ + if (! b_entry) + return; + + /* print table head (register classes) */ + fprintf(dmp->f, "\nREG PRESSURE:\n"); + fprintf(dmp->f, "%12s", "Block Nr"); + for (rp_entry = pset_first(b_entry->reg_pressure); + rp_entry; + rp_entry = pset_next(b_entry->reg_pressure)) + { + fprintf(dmp->f, "%15s", get_id_str(rp_entry->id_name)); + } + fprintf(dmp->f, "\n"); + + /* print the reg pressure for all blocks and register classes */ + for (/* b_entry is already initialized */ ; + b_entry; + b_entry = pset_next(entry->rp_block_hash)) + { + fprintf(dmp->f, "BLK %6ld", b_entry->block_nr); + for (rp_entry = pset_first(b_entry->reg_pressure); + rp_entry; + rp_entry = pset_next(b_entry->reg_pressure)) + { + fprintf(dmp->f, "%15d", rp_entry->pressure); + } + fprintf(dmp->f, "\n"); + } +} + /** * dumps the number of real_function_call optimization */ @@ -277,6 +315,9 @@ static void simple_dump_graph(dumper_t *dmp, graph_entry_t *entry) ); } + /* dump block reg pressure */ + simple_dump_be_block_reg_pressure(dmp, entry); + if (dmp->status->stat_options & FIRMSTAT_COUNT_EXTBB) { /* dump extended block info */ fprintf(dmp->f, "\n%12s %12s %12s %12s %12s %12s %12s\n", "Extbb Nr", "Nodes", "intern E", "incoming E", "outgoing E", "Phi", "quot"); -- 2.20.1