lv_chk_state_through = lv_chk_state_in | lv_chk_state_out | lv_chk_state_end,
} lv_chk_state_t;
+#define LV_CHK_MAX_BINS 32
+typedef struct {
+ int dist_uses_per_var[LV_CHK_MAX_BINS]; /** distribution of uses per variable. */
+ int dist_iterations[LV_CHK_MAX_BINS]; /** distribution of loop iterations. */
+ int n_calls; /** number of total calls to the chk routine. */
+ int n_no_dominance; /** exists due to no existing dominance rel. */
+ int n_false; /** number of times the check returned false. */
+ int n_def_block; /** number of times the queried block was also
+ the definition block of the variable. */
+} lv_chk_stat_t;
+
typedef struct _lv_chk_t lv_chk_t;
/**
*/
extern lv_chk_t *lv_chk_new(ir_graph *irg);
+/**
+ * Get statistic data for the liveness check.
+ * @param lv The liveness check.
+ * @return A record with statistics data or NULL if stats were
+ * not enabled.
+ */
+extern const lv_chk_stat_t *lv_chk_get_stat(const lv_chk_t *lv);
+
/**
* Free liveness check information.
* @param lv The liveness check information.
#include "irlivechk.h"
+#define ENABLE_STATS
+
+#ifdef ENABLE_STATS
+#define STAT_INC(memb) ++lv->stat->memb
+#else
+#define STAT_INC(memb)
+#endif
+
typedef struct _bl_info_t {
ir_node *block; /**< The block. */
bitset_t *back_edge_src;
bitset_t *back_edge_tgt;
bl_info_t **map;
+ lv_chk_stat_t *stat; /**< statistics information. */
+ lv_chk_stat_t stat_data;
};
static void *init_block_data(ir_phase *ph, ir_node *irn, void *old)
res->back_edge_tgt = bitset_obstack_alloc(obst, res->n_blocks);
res->map = obstack_alloc(obst, res->n_blocks * sizeof(res->map[0]));
+#ifdef ENABLE_STATS
+ memset(&res->stat_data, 0, sizeof(res->stat_data));
+ res->stat = &res->stat_data;
+#endif
#if 0
{
char name[256];
xfree(lv);
}
+const lv_chk_stat_t *lv_chk_get_stat(const lv_chk_t *lv)
+{
+#ifdef ENABLE_STATS
+ return lv->stat;
+#else
+ return NULL;
+#endif
+}
+
/**
* Check if a node is live at the end of a block.
* This function is for internal use as its code is shared between
return 0;
what_bl = get_nodes_block(what);
- if (!block_dominates(what_bl, bl))
+ if (!block_dominates(what_bl, bl)) {
+ STAT_INC(n_no_dominance);
return 0;
+ }
/*
* If the block in question is the same as the definition block,
int res = 0;
const ir_edge_t *edge;
+ STAT_INC(n_def_block);
DBG((lv->dbg, LEVEL_2, "lv check same block %+F in %+F\n", what, bl));
foreach_out_edge (what, edge) {
ir_node *use = get_edge_src_irn(edge);