* @file
* @brief Statistics for Firm.
* @author Michael Beck
- * @version $Id$
*/
#include "config.h"
-#ifdef FIRM_STATISTICS
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xmalloc.h"
#include "irhooks.h"
#include "util.h"
+#include "ircons.h"
/*
* need this to be static:
/** The Div by Const node. */
static ir_op _op_ModC;
-/** The Div by Const node. */
-static ir_op _op_DivModC;
-
-/** The Quot by Const node. */
-static ir_op _op_QuotC;
-
/** The memory Proj node. */
static ir_op _op_ProjM;
} /* opt_cmp */
/**
- * Compare two elements of the block/extbb hash.
+ * Compare two elements of the block hash.
*/
static int block_cmp(const void *elt, const void *key)
{
elem->block_hash = NULL;
} /* if */
- if (elem->extbb_hash) {
- del_pset(elem->extbb_hash);
- elem->extbb_hash = NULL;
- } /* if */
-
obstack_free(&elem->recalc_cnts, NULL);
obstack_init(&elem->recalc_cnts);
} /* graph_clear_entry */
key.irg = irg;
- elem = (graph_entry_t*)pset_find(hmap, &key, HASH_PTR(irg));
+ elem = (graph_entry_t*)pset_find(hmap, &key, hash_ptr(irg));
if (elem) {
/* create hash map backend block information */
/* these hash tables are created on demand */
elem->block_hash = NULL;
- elem->extbb_hash = NULL;
- for (i = 0; i < sizeof(elem->opt_hash)/sizeof(elem->opt_hash[0]); ++i)
+ for (i = 0; i != ARRAY_SIZE(elem->opt_hash); ++i)
elem->opt_hash[i] = new_pset(opt_cmp, 4);
- return (graph_entry_t*)pset_insert(hmap, elem, HASH_PTR(irg));
+ return (graph_entry_t*)pset_insert(hmap, elem, hash_ptr(irg));
} /* graph_get_entry */
/**
key.class_name = class_name;
- elem = (perm_class_entry_t*)pset_find(hmap, &key, HASH_PTR(class_name));
+ elem = (perm_class_entry_t*)pset_find(hmap, &key, hash_ptr(class_name));
if (elem)
return elem;
elem->class_name = class_name;
- return (perm_class_entry_t*)pset_insert(hmap, elem, HASH_PTR(class_name));
+ return (perm_class_entry_t*)pset_insert(hmap, elem, hash_ptr(class_name));
} /* perm_class_get_entry */
/**
key.perm = perm;
- elem = (perm_stat_entry_t*)pset_find(hmap, &key, HASH_PTR(perm));
+ elem = (perm_stat_entry_t*)pset_find(hmap, &key, hash_ptr(perm));
if (elem)
return elem;
elem->perm = perm;
- return (perm_stat_entry_t*)pset_insert(hmap, elem, HASH_PTR(perm));
+ return (perm_stat_entry_t*)pset_insert(hmap, elem, hash_ptr(perm));
} /* perm_stat_get_entry */
/**
op = status->op_ModC ? status->op_ModC : op;
} /* if */
break;
- case iro_DivMod:
- if (is_Const(get_DivMod_right(node))) {
- /* special case, a division/modulo by a const, count on extra counter */
- op = status->op_DivModC ? status->op_DivModC : op;
- } /* if */
- break;
- case iro_Quot:
- if (is_Const(get_Quot_right(node))) {
- /* special case, a floating point division by a const, count on extra counter */
- op = status->op_QuotC ? status->op_QuotC : op;
- } /* if */
- break;
case iro_Sel:
if (is_Sel(get_Sel_ptr(node))) {
/* special case, a Sel of a Sel, count on extra counter */
} /* if */
break;
default:
- ;
+ break;
} /* switch */
return op;
} /* for */
} /* undate_block_info */
-/**
- * Update the extended block counter.
- */
-static void update_extbb_info(ir_node *node, graph_entry_t *graph)
-{
- ir_op *op = get_irn_op(node);
- ir_extblk *extbb;
- extbb_entry_t *eb_entry;
- int i, arity;
-
- /* check for block */
- if (op == op_Block) {
- extbb = get_nodes_extbb(node);
- arity = get_irn_arity(node);
- eb_entry = block_get_entry(&graph->recalc_cnts, get_extbb_node_nr(extbb), graph->extbb_hash);
-
- /* count all incoming edges */
- for (i = 0; i < arity; ++i) {
- ir_node *pred = get_irn_n(node, i);
- ir_extblk *other_extbb = get_nodes_extbb(pred);
-
- if (extbb != other_extbb) {
- extbb_entry_t *eb_entry_other = block_get_entry(&graph->recalc_cnts, get_extbb_node_nr(other_extbb), graph->extbb_hash);
-
- cnt_inc(&eb_entry->cnt[bcnt_in_edges]); /* an edge coming from another extbb */
- cnt_inc(&eb_entry_other->cnt[bcnt_out_edges]);
- } /* if */
- } /* for */
- return;
- } /* if */
-
- extbb = get_nodes_extbb(node);
- eb_entry = block_get_entry(&graph->recalc_cnts, get_extbb_node_nr(extbb), graph->extbb_hash);
-
- if (op == op_Phi && mode_is_datab(get_irn_mode(node))) {
- /* count data Phi per extbb */
- cnt_inc(&eb_entry->cnt[bcnt_phi_data]);
- } /* if */
-
- /* we have a new node in our block */
- cnt_inc(&eb_entry->cnt[bcnt_nodes]);
-
- /* don't count keep-alive edges */
- if (is_End(node))
- return;
-
- arity = get_irn_arity(node);
-
- for (i = 0; i < arity; ++i) {
- ir_node *pred = get_irn_n(node, i);
- ir_extblk *other_extbb = get_nodes_extbb(pred);
-
- if (other_extbb == extbb)
- cnt_inc(&eb_entry->cnt[bcnt_edges]); /* a in extbb edge */
- else {
- extbb_entry_t *eb_entry_other = block_get_entry(&graph->recalc_cnts, get_extbb_node_nr(other_extbb), graph->extbb_hash);
-
- cnt_inc(&eb_entry->cnt[bcnt_in_edges]); /* an edge coming from another extbb */
- cnt_inc(&eb_entry_other->cnt[bcnt_out_edges]);
- } /* if */
- } /* for */
-} /* update_extbb_info */
-
/**
* Calculates how many arguments of the call are const, updates
* param distribution.
case iro_Sel:
base = find_base_adr(node);
irg = current_ir_graph;
- if (base == get_irg_tls(irg)) {
- /* a TLS variable, like a global. */
- cnt_inc(&graph->cnt[gcnt_global_adr]);
- } else if (base == get_irg_frame(irg)) {
+ if (base == get_irg_frame(irg)) {
/* a local Variable. */
cnt_inc(&graph->cnt[gcnt_local_adr]);
} else {
} /* if */
} /* if */
default:
- ;
+ break;
} /* switch */
} /* stat_update_address */
/* count block edges */
undate_block_info(node, graph);
- /* count extended block edges */
- if (status->stat_options & FIRMSTAT_COUNT_EXTBB) {
- if (graph->irg != get_const_code_irg())
- update_extbb_info(node, graph);
- } /* if */
-
/* handle statistics for special node types */
switch (op->code) {
}
}
default:
- ;
+ break;
} /* switch */
/* we want to count the constant IN nodes, not the CSE'ed constant's itself */
*/
static unsigned get_adr_mark(graph_entry_t *graph, ir_node *node)
{
- address_mark_entry_t *value = (address_mark_entry_t*)set_find(graph->address_mark, &node, sizeof(*value), HASH_PTR(node));
+ address_mark_entry_t const val = { node, 0 };
+ address_mark_entry_t *value = set_find(address_mark_entry_t, graph->address_mark, &val, sizeof(val), hash_ptr(node));
return value ? value->mark : 0;
} /* get_adr_mark */
*/
static void set_adr_mark(graph_entry_t *graph, ir_node *node, unsigned val)
{
- address_mark_entry_t *value = (address_mark_entry_t*)set_insert(graph->address_mark, &node, sizeof(*value), HASH_PTR(node));
-
- value->mark = val;
+ address_mark_entry_t const value = { node, val };
+ set_insert(address_mark_entry_t, graph->address_mark, &value, sizeof(value), hash_ptr(node));
} /* set_adr_mark */
#undef DUMP_ADR_MODE
return get_Load_mode(node);
case iro_Store:
return get_irn_mode(get_Store_value(node));
- case iro_DivMod:
- return get_irn_mode(get_DivMod_left(node));
case iro_Div:
return get_irn_mode(get_Div_left(node));
case iro_Mod:
*/
static void update_graph_stat(graph_entry_t *global, graph_entry_t *graph)
{
- node_entry_t *entry;
int i;
/* clear first the alive counter in the graph */
/* we need dominator info */
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);
-
- /* create new extbb counter */
- graph->extbb_hash = new_pset(block_cmp, 5);
- } /* if */
} /* if */
/* count the nodes in the graph */
static void stat_register_dumper(const dumper_t *dumper)
{
dumper_t *p = XMALLOC(dumper_t);
-
- memcpy(p, dumper, sizeof(*p));
+ *p = *dumper;
p->next = status->dumper;
p->status = status;
for (dumper = status->dumper; dumper; dumper = dumper->next) {
if (dumper->func_map) {
- dump_graph_FUNC func;
-
- foreach_pset(dumper->func_map, dump_graph_FUNC, func)
+ foreach_pset(dumper->func_map, dump_graph_FUNC*, func)
func(dumper, entry);
} /* if */
} /* for */
/**
* Register an additional function for all dumper.
*/
-void stat_register_dumper_func(dump_graph_FUNC func)
+void stat_register_dumper_func(dump_graph_FUNC *const func)
{
dumper_t *dumper;
/*
* Helper: get an ir_op from an opcode.
*/
-ir_op *stat_get_op_from_opcode(ir_opcode code)
+ir_op *stat_get_op_from_opcode(unsigned code)
{
- return opcode_find_entry(code, status->ir_op_hash);
+ return opcode_find_entry((ir_opcode)code, status->ir_op_hash);
} /* stat_get_op_from_opcode */
/**
rp_ent->class_name = class_name;
rp_ent->pressure = pressure;
- pset_insert(block_ent->reg_pressure, rp_ent, HASH_PTR(class_name));
+ pset_insert(block_ent->reg_pressure, rp_ent, hash_ptr(class_name));
}
STAT_LEAVE;
} /* stat_be_block_regpressure */
STAT_ENTER;
{
- graph_entry_t *entry;
graph_entry_t *global = graph_get_entry(NULL, status->irg_hash);
/*
stat_dump_init(fname);
/* calculate the graph statistics */
- for (entry = (graph_entry_t*)pset_first(status->irg_hash);
- entry != NULL; entry = (graph_entry_t*)pset_next(status->irg_hash)) {
+ foreach_pset(status->irg_hash, graph_entry_t*, entry) {
if (entry->irg == NULL) {
/* special entry for the global count */
continue;
/* some calculations are dependent, we pushed them on the wait_q */
while (! pdeq_empty(status->wait_q)) {
- entry = (graph_entry_t*)pdeq_getr(status->wait_q);
+ graph_entry_t *const entry = (graph_entry_t*)pdeq_getr(status->wait_q);
update_graph_stat_2(global, entry);
} /* while */
/* dump per graph */
- for (entry = (graph_entry_t*)pset_first(status->irg_hash);
- entry != NULL; entry = (graph_entry_t*)pset_next(status->irg_hash)) {
+ foreach_pset(status->irg_hash, graph_entry_t*, entry) {
if (entry->irg == NULL) {
/* special entry for the global count */
continue;
stat_finish_pattern_history(fname);
/* clear the global counters here */
- {
- node_entry_t *entry;
-
- for (entry = (node_entry_t*)pset_first(global->opcode_hash);
- entry != NULL; entry = (node_entry_t*)pset_next(global->opcode_hash)) {
- opcode_clear_entry(entry);
- } /* for */
- /* clear all global counter */
- graph_clear_entry(global, /*all=*/1);
- }
+ foreach_pset(global->opcode_hash, node_entry_t*, entry) {
+ opcode_clear_entry(entry);
+ } /* for */
+ /* clear all global counter */
+ graph_clear_entry(global, /*all=*/1);
}
STAT_LEAVE;
} /* stat_dump_snapshot */
_op_ModC.code = --num;
_op_ModC.name = new_id_from_chars(X("ModC"));
- _op_DivModC.code = --num;
- _op_DivModC.name = new_id_from_chars(X("DivModC"));
-
- _op_QuotC.code = --num;
- _op_QuotC.name = new_id_from_chars(X("QuotC"));
-
status->op_Phi0 = &_op_Phi0;
status->op_PhiM = &_op_PhiM;
status->op_ProjM = &_op_ProjM;
status->op_MulC = &_op_MulC;
status->op_DivC = &_op_DivC;
status->op_ModC = &_op_ModC;
- status->op_DivModC = &_op_DivModC;
- status->op_QuotC = &_op_QuotC;
} else {
status->op_Phi0 = NULL;
status->op_PhiM = NULL;
status->op_MulC = NULL;
status->op_DivC = NULL;
status->op_ModC = NULL;
- status->op_DivModC = NULL;
- status->op_QuotC = NULL;
} /* if */
/* for Florian: count the Sel depth */
{
return status != (stat_info_t *)&status_disable;
} /* stat_is_active */
-
-#else
-
-/* initialize the statistics module. */
-void firm_init_stat(unsigned enable_options) {}
-
-/* Dumps a statistics snapshot */
-void stat_dump_snapshot(const char *name, const char *phase) {}
-
-/* terminates the statistics module, frees all memory */
-void stat_term(void);
-
-#endif /* FIRM_STATISTICS */