forget one change :-(
[libfirm] / ir / stat / firmstat.c
index 445a9fd..7ecaf62 100644 (file)
  * 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 */
@@ -131,6 +132,7 @@ struct _dumper_t {
 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 */
@@ -216,6 +218,17 @@ static int block_cmp(const void *elt, const void *key)
   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
  */
@@ -242,6 +255,17 @@ static node_entry_t *opcode_get_entry(const ir_op *op, pset *set)
   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
@@ -374,7 +398,7 @@ static void count_block_info(ir_node *node, graph_entry_t *graph)
     /* 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 */
@@ -386,7 +410,7 @@ static void count_block_info(ir_node *node, graph_entry_t *graph)
     // 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 */
@@ -401,7 +425,7 @@ static void count_block_info(ir_node *node, graph_entry_t *graph)
     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 */
@@ -745,15 +769,23 @@ static dumper_t csv_dumper = {
 
 /* ---------------------------------------------------------------------- */
 
+/*
+ * 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;
@@ -762,13 +794,14 @@ void stat_init(void)
 
   /* 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;
@@ -777,7 +810,7 @@ void stat_init(void)
   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
 }
 
@@ -793,6 +826,8 @@ void stat_new_ir_op(const ir_op *op)
 
     /* execute for side effect :-) */
     opcode_get_entry(op, graph->opcode_hash);
+
+    pset_insert(status->ir_op_hash, op, op->code);
   }
   STAT_LEAVE;
 }
@@ -921,6 +956,15 @@ void stat_irg_walk(ir_graph *irg, void *pre, void *post)
   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.
  */
@@ -1087,7 +1131,7 @@ void stat_finish(void)
 #define FIRM_STATISTICS
 #include "firmstat.h"
 
-void stat_init(void) {}
+void init_stat(unsigned enable_options) {}
 
 void stat_finish(void) {}