return e1->block_nr != e2->block_nr;
}
+/**
+ * compare two elements of the be_block hash
+ */
+static int be_block_cmp(const void *elt, const void *key)
+{
+ const be_block_entry_t *e1 = elt;
+ const be_block_entry_t *e2 = key;
+
+ return e1->block_nr != e2->block_nr;
+}
+
/**
* compare two elements of the block/extbb hash
*/
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);
+ /* create hash map backend block information */
+ elem->be_block_hash = new_pset(be_block_cmp, 5);
/* these hash tables are created on demand */
elem->block_hash = NULL;
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);
}
/**
return pset_insert(hmap, elem, block_nr);
}
+/**
+ * clears all sets in be_block_entry_t
+ */
+static void be_block_clear_entry(be_block_entry_t *elem)
+{
+ if (elem->reg_pressure)
+ del_pset(elem->reg_pressure);
+
+ elem->reg_pressure = new_pset(reg_pressure_cmp, 5);
+}
+
+/**
+ * Returns the associated be_block_entry_t for an block.
+ *
+ * @param block_nr an IR block number
+ * @param hmap a hash map containing long -> be_block_entry_t
+ */
+static be_block_entry_t *be_block_get_entry(struct obstack *obst, long block_nr, hmap_be_block_entry_t *hmap)
+{
+ be_block_entry_t key;
+ be_block_entry_t *elem;
+
+ key.block_nr = block_nr;
+
+ elem = pset_find(hmap, &key, block_nr);
+ if (elem)
+ return elem;
+
+ elem = obstack_alloc(obst, sizeof(*elem));
+ memset(elem, 0, sizeof(*elem));
+
+ /* clear new counter */
+ be_block_clear_entry(elem);
+
+ elem->block_nr = block_nr;
+
+ return pset_insert(hmap, elem, block_nr);
+}
+
/**
* Returns the ir_op for an IR-node,
STAT_ENTER;
{
graph_entry_t *graph = graph_get_entry(irg, status->irg_hash);
- block_entry_t *block_ent;
+ be_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);
+ /* create new be_block hash */
+ if (! graph->be_block_hash)
+ graph->be_block_hash = new_pset(be_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));
+ 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->id_name = class_name;
HOOK(hook_be_block_regpressure, stat_be_block_regpressure);
obstack_init(&status->cnts);
+ obstack_init(&status->be_data);
/* create the hash-tables */
status->irg_hash = new_pset(graph_cmp, 8);
/* 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);
xfree(status);
status = (stat_info_t *)&status_disable;
}
typedef pset hmap_graph_entry_t;
typedef pset hmap_opt_entry_t;
typedef pset hmap_block_entry_t;
+typedef pset hmap_be_block_entry_t;
typedef pset hmap_reg_pressure_entry_t;
typedef pset hmap_ir_op;
typedef pset hmap_distrib_entry_t;
* An entry for ir_graphs. These numbers are calculated for every IR graph.
*/
typedef struct _graph_entry_t {
- struct obstack recalc_cnts; /**< obstack containing the counters that are recalculated */
- 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 */
- 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 */
- counter_t cnt_strength_red; /**< number of times strength reduction was successful on this graph */
- counter_t cnt_edges; /**< number of DF edges in this graph */
- counter_t cnt_all_calls; /**< number of all calls */
- counter_t cnt_call_with_cnst_arg; /**< number of calls with const args */
- counter_t cnt_indirect_calls; /**< number of indirect calls */
- counter_t cnt_if_conv[IF_RESULT_LAST]; /**< number of if conversions */
- counter_t cnt_real_func_call; /**< number real function call optimization */
- unsigned num_tail_recursion; /**< number of tail recursion optimizations */
- HASH_MAP(opt_entry_t) *opt_hash[FS_OPT_MAX]; /**< hash maps containing opcode counter for optimizations */
- ir_graph *irg; /**< the graph of this object */
- entity *ent; /**< the entity of this graph if one exists */
- set *address_mark; /**< a set containing the address marks of the nodes */
- unsigned is_deleted:1; /**< set if this irg was deleted */
- unsigned is_leaf:1; /**< set, if this irg is a leaf function */
- unsigned is_leaf_call:2; /**< set, if this irg calls only leaf functions */
- unsigned is_recursive:1; /**< set, if this irg has recursive calls */
- unsigned is_chain_call:1; /**< set, if this irg is a chain call */
- unsigned is_analyzed:1; /**< helper: set, if this irg was already analysed */
+ struct obstack recalc_cnts; /**< obstack containing the counters that are recalculated */
+ 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 */
+ HASH_MAP(be_block_entry_t) *be_block_hash; /**< hash map containing backend block 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 */
+ counter_t cnt_strength_red; /**< number of times strength reduction was successful on this graph */
+ counter_t cnt_edges; /**< number of DF edges in this graph */
+ counter_t cnt_all_calls; /**< number of all calls */
+ counter_t cnt_call_with_cnst_arg; /**< number of calls with const args */
+ counter_t cnt_indirect_calls; /**< number of indirect calls */
+ counter_t cnt_if_conv[IF_RESULT_LAST]; /**< number of if conversions */
+ counter_t cnt_real_func_call; /**< number real function call optimization */
+ unsigned num_tail_recursion; /**< number of tail recursion optimizations */
+ HASH_MAP(opt_entry_t) *opt_hash[FS_OPT_MAX]; /**< hash maps containing opcode counter for optimizations */
+ ir_graph *irg; /**< the graph of this object */
+ entity *ent; /**< the entity of this graph if one exists */
+ set *address_mark; /**< a set containing the address marks of the nodes */
+ unsigned is_deleted:1; /**< set if this irg was deleted */
+ unsigned is_leaf:1; /**< set, if this irg is a leaf function */
+ unsigned is_leaf_call:2; /**< set, if this irg calls only leaf functions */
+ unsigned is_recursive:1; /**< set, if this irg has recursive calls */
+ unsigned is_chain_call:1; /**< set, if this irg is a chain call */
+ unsigned is_analyzed:1; /**< helper: set, if this irg was already analysed */
} graph_entry_t;
/**
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 _be_block_entry_t {
+ long block_nr; /**< block nr */
+ /**< the highest register pressures for this block for each register class */
+ HASH_MAP(reg_pressure_entry_t) *reg_pressure;
+} be_block_entry_t;
+
/**
* An entry for a block or extended block in a ir-graph
*/
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 */
typedef struct _statistic_info_t {
unsigned stat_options; /**< statistic options: field must be first */
struct obstack cnts; /**< obstack containing the counters that are incremented */
+ struct obstack be_data; /**< obstack containing backend statistics data */
HASH_MAP(graph_entry_t) *irg_hash; /**< hash map containing the counter for irgs */
HASH_MAP(ir_op) *ir_op_hash; /**< hash map containing all ir_ops (accessible by op_codes) */
pdeq *wait_q; /**< wait queue for leaf call decision */