* just be make some things clear :-), the
* poor man "generics"
*/
-#define HASH_MAP(type) pset_##type
+#define HASH_MAP(type) hmap_##type
-typedef pset pset_node_entry_t;
-typedef pset pset_graph_entry_t;
-typedef pset pset_opt_entry_t;
-typedef pset pset_block_entry_t;
+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_ir_op;
/*
- * An entry for ir_nodes
+ * An entry for ir_nodes, used in ir_graph statistics.
*/
typedef struct _node_entry_t {
counter_t cnt_alive; /**< amount of nodes in this entry */
typedef struct _statistic_info_t {
struct obstack cnts; /**< obstack containing the counters */
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) */
int recursive; /**< flag for detecting recursive hook calls */
int in_dead_node_elim; /**< set, if dead node elimination runs */
ir_op *op_Phi0; /**< needed pseudo op */
return e1->block_nr != e2->block_nr;
}
+/**
+ * compare two elements of the ir_op hash
+ */
+static int opcode_cmp_2(const void *elt, const void *key)
+{
+ const ir_op *e1 = elt;
+ const ir_op *e2 = key;
+
+ return e1->code != e2->code;
+}
+
/**
* Returns the associates node_entry_t for an ir_op
*/
return pset_insert(set, elem, op->code);
}
+/**
+ * Returns the associates ir_op for an opcode
+ */
+static ir_op *opcode_find_entry(opcode code, pset *set)
+{
+ ir_op key;
+
+ key.code = code;
+ return pset_find(set, &key, code);
+}
+
/**
* calculates a hash value for an irg
* Addresses are typically aligned at 32bit, so we ignore the lowest bits
/* count all incoming edges */
for (i = 0; i < arity; ++i) {
ir_node *pred = get_irn_n(node, i);
- ir_node *other_block = get_nodes_Block(pred);
+ ir_node *other_block = get_nodes_block(pred);
block_entry_t *b_entry_other = block_get_entry(get_irn_node_nr(other_block), graph->block_hash);
cnt_inc(&b_entry->cnt_in_edges); /* an edge coming from another block */
// return;
}
- block = get_nodes_Block(node);
+ block = get_nodes_block(node);
b_entry = block_get_entry(get_irn_node_nr(block), graph->block_hash);
/* we have a new nodes */
if (get_irn_op(pred) == op_Block)
continue;
- other_block = get_nodes_Block(pred);
+ other_block = get_nodes_block(pred);
if (other_block == block)
cnt_inc(&b_entry->cnt_edges); /* a in block edge */
/* ---------------------------------------------------------------------- */
+/*
+ * helper: get an ir_op from an opcode
+ */
+ir_op *stat_get_op_from_opcode(opcode code)
+{
+ return opcode_find_entry(code, status->ir_op_hash);
+}
+
/* initialize the statistics module. */
-void stat_init(void)
+void init_stat(unsigned enable_options)
{
#define X(a) a, sizeof(a)-1
int pseudo_id = 0;
/* enable statistics */
- status->enable = 1;
+ status->enable = enable_options & FIRMSTAT_ENABLED;
if (! status->enable)
return;
/* build the pseudo-ops */
_op_Phi0.code = --pseudo_id;
- _op_Phi0.name = id_from_str(X("Phi0"));
+ _op_Phi0.name = new_id_from_chars(X("Phi0"));
_op_PhiM.code = --pseudo_id;
- _op_PhiM.name = id_from_str(X("PhiM"));
+ _op_PhiM.name = new_id_from_chars(X("PhiM"));
/* create the hash-tables */
status->irg_hash = new_pset(graph_cmp, 8);
+ status->ir_op_hash = new_pset(opcode_cmp_2, 1);
status->op_Phi0 = &_op_Phi0;
status->op_PhiM = &_op_PhiM;
stat_register_dumper(&csv_dumper, "firmstat.csv");
/* initialize the pattern hash */
- stat_init_pattern_history(status->enable & 0);
+ stat_init_pattern_history(enable_options & FIRMSTAT_PATTERN_ENABLED);
#undef X
}
/* execute for side effect :-) */
opcode_get_entry(op, graph->opcode_hash);
+
+ pset_insert(status->ir_op_hash, op, op->code);
}
STAT_LEAVE;
}
STAT_LEAVE;
}
+/*
+ * A walk over a graph in block-wise order is initiated. Do not count walks from statistic code.
+ */
+void stat_irg_walk_blkwise(ir_graph *irg, void *pre, void *post)
+{
+ /* for now, do NOT differentiate between blockwise and normal */
+ stat_irg_walk(irg, pre, post);
+}
+
/*
* A walk over the graph's blocks is initiated. Do not count walks from statistic code.
*/
#define FIRM_STATISTICS
#include "firmstat.h"
-void stat_init(void) {}
+void init_stat(unsigned enable_options) {}
void stat_finish(void) {}