really remove type_id
[libfirm] / ir / stat / firmstat.c
index 103e9d6..e05961f 100644 (file)
  * @author  Michael Beck
  * @version $Id$
  */
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
 
 #ifdef FIRM_STATISTICS
 
 #include <stdio.h>
-
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif
+#include <stdlib.h>
+#include <string.h>
 
 #include "irouts.h"
 #include "irdump.h"
 #include "hashptr.h"
 #include "firmstat_t.h"
+#include "irpass_t.h"
 #include "pattern.h"
 #include "dags.h"
 #include "stat_dmp.h"
@@ -212,10 +206,12 @@ static void opcode_clear_entry(node_entry_t *elem) {
        cnt_clr(&elem->cnt_alive);
        cnt_clr(&elem->new_node);
        cnt_clr(&elem->into_Id);
+       cnt_clr(&elem->normalized);
 }  /* opcode_clear_entry */
 
 /**
- * Returns the associates node_entry_t for an ir_op
+ * Returns the associates node_entry_t for an ir_op (and allocates
+ * one if not yet available).
  *
  * @param op    the IR operation
  * @param hmap  a hash map containing ir_op* -> node_entry_t*
@@ -230,8 +226,7 @@ static node_entry_t *opcode_get_entry(const ir_op *op, hmap_node_entry_t *hmap)
        if (elem)
                return elem;
 
-       elem = obstack_alloc(&status->cnts, sizeof(*elem));
-       memset(elem, 0, sizeof(*elem));
+       elem = OALLOCZ(&status->cnts, node_entry_t);
 
        /* clear counter */
        opcode_clear_entry(elem);
@@ -285,7 +280,7 @@ static void graph_clear_entry(graph_entry_t *elem, int all) {
 /**
  * Returns the associated graph_entry_t for an IR graph.
  *
- * @param irg   the IR graph
+ * @param irg   the IR graph, NULL for the global counter
  * @param hmap  the hash map containing ir_graph* -> graph_entry_t*
  */
 static graph_entry_t *graph_get_entry(ir_graph *irg, hmap_graph_entry_t *hmap)
@@ -307,8 +302,7 @@ static graph_entry_t *graph_get_entry(ir_graph *irg, hmap_graph_entry_t *hmap)
        }  /* if */
 
        /* allocate a new one */
-       elem = obstack_alloc(&status->cnts, sizeof(*elem));
-       memset(elem, 0, sizeof(*elem));
+       elem = OALLOCZ(&status->cnts, graph_entry_t);
        obstack_init(&elem->recalc_cnts);
 
        /* clear counter */
@@ -353,8 +347,7 @@ static opt_entry_t *opt_get_entry(const ir_op *op, hmap_opt_entry_t *hmap)
        if (elem)
                return elem;
 
-       elem = obstack_alloc(&status->cnts, sizeof(*elem));
-       memset(elem, 0, sizeof(*elem));
+       elem = OALLOCZ(&status->cnts, opt_entry_t);
 
        /* clear new counter */
        opt_clear_entry(elem);
@@ -391,8 +384,7 @@ static block_entry_t *block_get_entry(struct obstack *obst, long block_nr, hmap_
        if (elem)
                return elem;
 
-       elem = obstack_alloc(obst, sizeof(*elem));
-       memset(elem, 0, sizeof(*elem));
+       elem = OALLOCZ(obst, block_entry_t);
 
        /* clear new counter */
        block_clear_entry(elem);
@@ -438,8 +430,7 @@ static be_block_entry_t *be_block_get_entry(struct obstack *obst, long block_nr,
        if (elem)
                return elem;
 
-       elem = obstack_alloc(obst, sizeof(*elem));
-       memset(elem, 0, sizeof(*elem));
+       elem = OALLOCZ(obst, be_block_entry_t);
 
        /* clear new counter */
        be_block_clear_entry(elem);
@@ -477,8 +468,7 @@ static perm_class_entry_t *perm_class_get_entry(struct obstack *obst, const char
        if (elem)
                return elem;
 
-       elem = obstack_alloc(obst, sizeof(*elem));
-       memset(elem, 0, sizeof(*elem));
+       elem = OALLOCZ(obst, perm_class_entry_t);
 
        /* clear new counter */
        perm_class_clear_entry(elem);
@@ -519,8 +509,7 @@ static perm_stat_entry_t *perm_stat_get_entry(struct obstack *obst, ir_node *per
        if (elem)
                return elem;
 
-       elem = obstack_alloc(obst, sizeof(*elem));
-       memset(elem, 0, sizeof(*elem));
+       elem = OALLOCZ(obst, perm_stat_entry_t);
 
        /* clear new counter */
        perm_stat_clear_entry(elem);
@@ -970,7 +959,7 @@ static void update_node_stat(ir_node *node, void *env)
        node_entry_t *entry;
 
        ir_op *op = stat_get_irn_op(node);
-       int arity = get_irn_arity(node);
+       int i, arity = get_irn_arity(node);
 
        entry = opcode_get_entry(op, graph->opcode_hash);
 
@@ -1001,6 +990,16 @@ static void update_node_stat(ir_node *node, void *env)
                /* check address properties */
                stat_update_address(get_Store_ptr(node), graph);
                break;
+       case iro_Phi:
+               /* check for non-strict Phi nodes */
+               for (i = arity - 1; i >= 0; --i) {
+                       ir_node *pred = get_Phi_pred(node, i);
+                       if (is_Unknown(pred)) {
+                               /* found an Unknown predecessor, graph is not strict */
+                               graph->is_strict = 0;
+                               break;
+                       }
+               }
        default:
                ;
        }  /* switch */
@@ -1186,6 +1185,7 @@ static void update_graph_stat(graph_entry_t *global, graph_entry_t *graph)
        graph->is_leaf_call  = LCS_UNKNOWN;
        graph->is_recursive  = 0;
        graph->is_chain_call = 1;
+       graph->is_strict     = 1;
 
        /* create new block counter */
        graph->block_hash = new_pset(block_cmp, 5);
@@ -1527,6 +1527,36 @@ static void stat_turn_into_id(void *ctx, ir_node *node) {
        STAT_LEAVE;
 }  /* stat_turn_into_id */
 
+/**
+ * Hook: A node is normalized
+ *
+ * @param ctx   the hook context
+ * @param node  the IR node that was normalized
+ */
+static void stat_normalize(void *ctx, ir_node *node) {
+       (void) ctx;
+       if (! status->stat_options)
+               return;
+
+       STAT_ENTER;
+       {
+               node_entry_t *entry;
+               graph_entry_t *graph;
+               ir_op *op = stat_get_irn_op(node);
+
+               /* increase global value */
+               graph = graph_get_entry(NULL, status->irg_hash);
+               entry = opcode_get_entry(op, graph->opcode_hash);
+               cnt_inc(&entry->normalized);
+
+               /* increase local value */
+               graph = graph_get_entry(current_ir_graph, status->irg_hash);
+               entry = opcode_get_entry(op, graph->opcode_hash);
+               cnt_inc(&entry->normalized);
+       }
+       STAT_LEAVE;
+}  /* stat_normalize */
+
 /**
  * Hook: A new graph was created
  *
@@ -1550,6 +1580,7 @@ static void stat_new_graph(void *ctx, ir_graph *irg, ir_entity *ent) {
                graph->is_leaf_call  = 0;
                graph->is_recursive  = 0;
                graph->is_chain_call = 0;
+               graph->is_strict     = 1;
                graph->is_analyzed   = 0;
        }
        STAT_LEAVE;
@@ -1935,8 +1966,7 @@ void stat_be_block_regpressure(ir_graph *irg, ir_node *block, int pressure, cons
                reg_pressure_entry_t *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    = OALLOCZ(&status->be_data, reg_pressure_entry_t);
 
                rp_ent->class_name = class_name;
                rp_ent->pressure   = pressure;
@@ -2094,10 +2124,10 @@ void stat_dump_snapshot(const char *name, const char *phase)
                        fname[0] = '\0';
                        p = name;
                }  /* if */
-               strncat(fname, "firmstat-", sizeof(fname));
-               strncat(fname, phase, sizeof(fname));
-               strncat(fname, "-", sizeof(fname));
-               strncat(fname, p, sizeof(fname));
+               strncat(fname, "firmstat-", sizeof(fname)-1);
+               strncat(fname, phase, sizeof(fname)-1);
+               strncat(fname, "-", sizeof(fname)-1);
+               strncat(fname, p, sizeof(fname)-1);
 
                stat_dump_init(fname);
 
@@ -2156,7 +2186,7 @@ void stat_dump_snapshot(const char *name, const char *phase)
 
                stat_finish_pattern_history(fname);
 
-               /* clear the global counter here */
+               /* clear the global counters here */
                {
                        node_entry_t *entry;
 
@@ -2164,12 +2194,66 @@ void stat_dump_snapshot(const char *name, const char *phase)
                                opcode_clear_entry(entry);
                        }  /* for */
                        /* clear all global counter */
-                       graph_clear_entry(global, 1);
+                       graph_clear_entry(global, /*all=*/1);
                }
        }
        STAT_LEAVE;
 }  /* stat_dump_snapshot */
 
+struct pass_t {
+       ir_prog_pass_t pass;
+       const char     *fname;
+       const char     *phase;
+};
+
+/**
+ * Wrapper to run stat_dump_snapshot() as a ir_prog wrapper.
+ */
+static int stat_dump_snapshot_wrapper(ir_prog *irp, void *context) {
+       struct pass_t *pass = context;
+
+       (void)irp;
+       stat_dump_snapshot(pass->fname, pass->phase);
+       return 0;
+}  /* stat_dump_snapshot_wrapper */
+
+/**
+ * Ensure that no verifier is run from the wrapper.
+ */
+static int no_verify(ir_prog *prog, void *ctx)
+{
+       (void)prog;
+       (void)ctx;
+       return 0;
+}
+
+/**
+ * Ensure that no dumper is run from the wrapper.
+ */
+static void no_dump(ir_prog *prog, void *ctx, unsigned idx)
+{
+       (void)prog;
+       (void)ctx;
+       (void)idx;
+}
+
+/* create an ir_pog pass */
+ir_prog_pass_t *stat_dump_snapshot_pass(
+       const char *name, const char *fname, const char *phase) {
+       struct pass_t *pass = XMALLOCZ(struct pass_t);
+
+       def_prog_pass_constructor(
+               &pass->pass, name ? name : "stat_snapshot", stat_dump_snapshot_wrapper);
+       pass->fname = fname;
+       pass->phase = phase;
+
+       /* no dump/verify */
+       pass->pass.dump_irprog   = no_dump;
+       pass->pass.verify_irprog = no_verify;
+
+       return &pass->pass;
+}  /* stat_dump_snapshot_pass */
+
 /** the hook entries for the Firm statistics module */
 static hook_entry_t stat_hooks[hook_last];
 
@@ -2194,6 +2278,7 @@ void firm_init_stat(unsigned enable_options)
        HOOK(hook_free_ir_op,                         stat_free_ir_op);
        HOOK(hook_new_node,                           stat_new_node);
        HOOK(hook_turn_into_id,                       stat_turn_into_id);
+       HOOK(hook_normalize,                          stat_normalize);
        HOOK(hook_new_graph,                          stat_new_graph);
        HOOK(hook_free_graph,                         stat_free_graph);
        HOOK(hook_irg_walk,                           stat_irg_walk);