Adapted to new statev
authorSebastian Hack <hack@ipd.info.uni-karlsruhe.de>
Mon, 10 Sep 2007 19:10:10 +0000 (19:10 +0000)
committerSebastian Hack <hack@ipd.info.uni-karlsruhe.de>
Mon, 10 Sep 2007 19:10:10 +0000 (19:10 +0000)
[r15733]

ir/ana/dfs.c
ir/ana/irlivechk.c
ir/be/beilpsched.c
ir/be/beintlive_t.h
ir/be/belive.c
ir/be/belive_t.h
ir/be/bemain.c
ir/be/bessadestr.c

index 6a8cb10..a85064a 100644 (file)
 #include "irprintf.h"
 #include "irdom.h"
 #include "set.h"
+#include "statev.h"
 #include "dfs_t.h"
 
+static const char *edge_names[] = {
+       "anc",
+       "fwd",
+       "cross",
+       "back"
+};
+
 static int cmp_edge(const void *a, const void *b, size_t sz)
 {
        const dfs_edge_t *p = a;
@@ -113,21 +121,38 @@ static void dfs_perform(dfs_t *dfs, void *n, void *anc, int level)
 
 static void classify_edges(dfs_t *dfs)
 {
+       stat_ev_cnt_decl(anc);
+       stat_ev_cnt_decl(back);
+       stat_ev_cnt_decl(fwd);
+       stat_ev_cnt_decl(cross);
        dfs_edge_t *edge;
 
        foreach_set (dfs->edges, edge) {
                dfs_node_t *src = edge->s;
                dfs_node_t *tgt = edge->t;
 
-               if (tgt->ancestor == src)
+               if (tgt->ancestor == src) {
+                       stat_ev_cnt_inc(anc);
                        edge->kind = DFS_EDGE_ANC;
-               else if (_dfs_int_is_ancestor(tgt, src))
+               }
+               else if (_dfs_int_is_ancestor(tgt, src)) {
+                       stat_ev_cnt_inc(back);
                        edge->kind = DFS_EDGE_BACK;
-               else if (_dfs_int_is_ancestor(src, tgt))
+               }
+               else if (_dfs_int_is_ancestor(src, tgt)) {
+                       stat_ev_cnt_inc(fwd);
                        edge->kind = DFS_EDGE_FWD;
-               else
+               }
+               else {
+                       stat_ev_cnt_inc(cross);
                        edge->kind = DFS_EDGE_CROSS;
+               }
        }
+
+       stat_ev_cnt_done(anc,   "dfs_edge_anc");
+       stat_ev_cnt_done(back,  "dfs_edge_back");
+       stat_ev_cnt_done(fwd,   "dfs_edge_fwd");
+       stat_ev_cnt_done(cross, "dfs_edge_cross");
 }
 
 dfs_edge_kind_t dfs_get_edge_kind(const dfs_t *dfs, const void *a, const void *b)
@@ -166,6 +191,8 @@ dfs_t *dfs_new(const absgraph_t *graph_impl, void *graph_self)
                res->post_order[node->post_num] = node;
        }
 
+       stat_ev_dbl("dfs_n_blocks", res->pre_num);
+
        return res;
 }
 
index badaea6..4aa00d8 100644 (file)
@@ -233,6 +233,12 @@ static INLINE void compute_back_edge_chains(lv_chk_t *lv)
                        }
                }
        }
+
+       for (i = 0, n = dfs_get_n_nodes(lv->dfs); i < n; ++i) {
+               const ir_node *bl = dfs_get_post_num_node(lv->dfs, i);
+               bl_info_t *bi     = get_block_info(lv, bl);
+               bitset_set(bi->be_tgt_reach, bi->id);
+       }
 }
 
 lv_chk_t *lv_chk_new(ir_graph *irg, const dfs_t *dfs)
@@ -241,12 +247,12 @@ lv_chk_t *lv_chk_new(ir_graph *irg, const dfs_t *dfs)
        struct obstack *obst;
        int i;
 
+       stat_ev_tim_push();
        phase_init(&res->ph, "liveness check", irg, PHASE_DEFAULT_GROWTH, init_block_data, NULL);
        obst = phase_obst(&res->ph);
 
        FIRM_DBG_REGISTER(res->dbg, "ir.ana.lvchk");
 
-       // res->dfs           = dfs_new(&absgraph_irg_cfg_succ, irg);
        res->dfs           = dfs;
        res->n_blocks      = dfs_get_n_nodes(res->dfs);
        res->back_edge_src = bitset_obstack_alloc(obst, res->n_blocks);
@@ -293,6 +299,7 @@ lv_chk_t *lv_chk_new(ir_graph *irg, const dfs_t *dfs)
        DBG((res->dbg, LEVEL_1, "back edge src: %B\n", res->back_edge_src));
        DBG((res->dbg, LEVEL_1, "back edge tgt: %B\n", res->back_edge_tgt));
 
+       stat_ev_tim_pop("lv_chk_cons_time");
        return res;
 }
 
@@ -497,7 +504,8 @@ unsigned lv_chk_bl_xxx(const lv_chk_t *lv, const ir_node *bl, const ir_node *var
        if (!is_liveness_node(var))
                return 0;
 
-       stat_ev("lv_chk");
+       stat_ev_ctx_push_fmt("lv_chk", "%u", get_irn_idx(var));
+       stat_ev_tim_push();
 
        /* If there is no dominance relation, go out, too */
        def_bl = get_nodes_block(var);
@@ -552,12 +560,12 @@ unsigned lv_chk_bl_xxx(const lv_chk_t *lv, const ir_node *bl, const ir_node *var
         * silently exploited below.
         */
        else {
-               bitset_t *tmp  = bitset_alloca(lv->n_blocks);
-               bitset_t *uses = bitset_alloca(lv->n_blocks);
                bl_info_t *def = get_block_info(lv, def_bl);
                bl_info_t *bli = get_block_info(lv, bl);
+               bitset_t *uses = bitset_alloca(lv->n_blocks);
+               bitset_t *Tq;
 
-               int i, min_dom, max_dom;
+               unsigned i, min_dom, max_dom;
                const ir_edge_t *edge;
 
                /* if the block has no DFS info, it cannot be reached.
@@ -569,6 +577,7 @@ unsigned lv_chk_bl_xxx(const lv_chk_t *lv, const ir_node *bl, const ir_node *var
                if (!bli)
                        goto end;
 
+               (void) def;
                DBG((lv->dbg, LEVEL_2, "lv check %+F (def in %+F #%d) in different block %+F #%d\n",
                                        var, def_bl, def->id, bl, bli->id));
 
@@ -621,20 +630,16 @@ unsigned lv_chk_bl_xxx(const lv_chk_t *lv, const ir_node *bl, const ir_node *var
 
                /* prepare a set with all reachable back edge targets.
                 * this will determine our "looking points" from where
-                * we will search/find the calculated uses.
-                *
-                * Since there might be no reachable back edge targets
-                * we add the current block also since reachability of
-                * uses are then checked from there. */
-               bitset_copy(tmp, bli->be_tgt_reach);
-               bitset_set (tmp, bli->id);
+                * we will search/find the calculated uses. */
+               Tq = bli->be_tgt_reach;
 
                /* now, visit all viewing points in the temporary bitset lying
                 * in the dominance range of the variable. Note that for reducible
                 * flow-graphs the first iteration is sufficient and the loop
                 * will be left. */
-               DBG((lv->dbg, LEVEL_2, "\tbe tgt reach: %B, dom span: [%d, %d]\n", tmp, min_dom, max_dom));
-               for (i = bitset_next_set(tmp, min_dom); i >= 0 && i <= max_dom; i = bitset_next_set(tmp, i + 1)) {
+               DBG((lv->dbg, LEVEL_2, "\tbe tgt reach: %B, dom span: [%d, %d]\n", Tq, min_dom, max_dom));
+               i = bitset_next_set(Tq, min_dom);
+               while(i <= max_dom) {
                        bl_info_t *ti = lv->map[i];
                        int use_in_current_block = bitset_is_set(uses, ti->id);
 
@@ -671,8 +676,6 @@ unsigned lv_chk_bl_xxx(const lv_chk_t *lv, const ir_node *bl, const ir_node *var
                                goto end;
                        }
 
-                       bitset_andnot(tmp, ti->red_reachable);
-
                        /*
                         * if we deleted a use do to the commentary above, we have to
                         * re-add it since it might be visible from further view points
@@ -680,13 +683,17 @@ unsigned lv_chk_bl_xxx(const lv_chk_t *lv, const ir_node *bl, const ir_node *var
                         */
                        if (use_in_current_block)
                                bitset_set(uses, ti->id);
+
+                       i = bitset_next_set(Tq, get_Block_dom_max_subtree_pre_num(ti->block) + 1);
                }
 
        }
 
 end:
+       stat_ev_tim_pop("lv_chk_query_time");
        stat_ev_cnt_done(uses, "lv_chk_uses");
        stat_ev_cnt_done(iter, "lv_chk_iter");
+       stat_ev_ctx_pop("lv_chk");
 
        return res;
 }
index 090e865..08294dd 100644 (file)
@@ -2016,7 +2016,7 @@ void be_ilp_sched(const be_irg_t *birg, be_options_t *be_opts) {
 
        FIRM_DBG_REGISTER(env.dbg, "firm.be.sched.ilp");
 
-       stat_ev_ctx_push("phase", "ilpsched");
+       stat_ev_ctx_push("ilpsched");
 
 //     firm_dbg_set_mask(env.dbg, 1);
 
@@ -2073,7 +2073,7 @@ void be_ilp_sched(const be_irg_t *birg, be_options_t *be_opts) {
        /* notify backend */
        be_ilp_sched_finish_irg_ilp_schedule(sel, birg->irg, env.irg_env);
 
-       stat_ev_ctx_pop();
+       stat_ev_ctx_pop("ilpsched");
 }
 
 /**
index 49827ee..e0871c2 100644 (file)
 #include "irphase_t.h"
 #include "iredges_t.h"
 
+#include "statev.h"
+
 #include "beirg_t.h"
 #include "besched_t.h"
+#include "belive_t.h"
 
 /**
  * Check dominance of two nodes in the same block.
@@ -110,30 +113,36 @@ static INLINE int _lv_values_interfere(const be_lv_t *lv, const ir_node *a, cons
 {
        int a2b = _value_dominates(a, b);
        int b2a = _value_dominates(b, a);
+       int res = 0;
+
+       stat_ev_ctx_push("beintlive");
+
+       /*
+        * Adjust a and b so, that a dominates b if
+        * a dominates b or vice versa.
+        */
+       if(b2a) {
+               const ir_node *t = a;
+               a = b;
+               b = t;
+               a2b = 1;
+       }
 
        /* If there is no dominance relation, they do not interfere. */
-       if((a2b | b2a) > 0) {
+       if(a2b) {
                const ir_edge_t *edge;
-               ir_node *bb;
+               ir_node *bb = get_nodes_block(b);
 
-               /*
-                * Adjust a and b so, that a dominates b if
-                * a dominates b or vice versa.
-                */
-               if(b2a) {
-                       const ir_node *t = a;
-                       a = b;
-                       b = t;
-               }
-
-               bb = get_nodes_block(b);
+               stat_ev_dbl("beintlive_ignore", arch_irn_is(lv->birg->main_env->arch_env, a, ignore));
 
                /*
                 * If a is live end in b's block it is
                 * live at b's definition (a dominates b)
                 */
-               if(be_is_live_end(lv, bb, a))
-                       return 1;
+               if(be_is_live_end(lv, bb, a)) {
+                       res = 1;
+                       goto end;
+               }
 
                /*
                 * Look at all usages of a.
@@ -148,12 +157,16 @@ static INLINE int _lv_values_interfere(const be_lv_t *lv, const ir_node *a, cons
                 */
                foreach_out_edge(a, edge) {
                        const ir_node *user = get_edge_src_irn(edge);
-                       if(get_nodes_block(user) == bb && !is_Phi(user) && _value_strictly_dominates(b, user))
-                               return 1;
+                       if(get_nodes_block(user) == bb && !is_Phi(user) && _value_strictly_dominates(b, user)) {
+                               res = 1;
+                               goto end;
+                       }
                }
        }
 
-       return 0;
+end:
+       stat_ev_ctx_pop("beintlive");
+       return res;
 }
 
 
index 7be9f1a..62e9d91 100644 (file)
@@ -38,6 +38,7 @@
 
 #include "dfs_t.h"
 #include "absgraph.h"
+#include "statev.h"
 
 #include "beutil.h"
 #include "belive_t.h"
@@ -159,8 +160,11 @@ static INLINE unsigned _be_liveness_bsearch(struct _be_lv_info_t *arr, unsigned
 
 struct _be_lv_info_node_t *be_lv_get(const struct _be_lv_t *li, const ir_node *bl, const ir_node *irn)
 {
-       struct _be_lv_info_t *irn_live = phase_get_irn_data(&li->ph, bl);
+       struct _be_lv_info_t *irn_live;
+       struct _be_lv_info_node_t *res = NULL;
 
+       stat_ev_tim_push();
+       irn_live = phase_get_irn_data(&li->ph, bl);
        if(irn_live) {
                unsigned idx = get_irn_idx(irn);
 
@@ -168,14 +172,15 @@ struct _be_lv_info_node_t *be_lv_get(const struct _be_lv_t *li, const ir_node *b
                int pos = _be_liveness_bsearch(irn_live, idx);
 
                /* Get the record in question. 1 must be added, since the first record contains information about the array and must be skipped. */
-               struct _be_lv_info_node_t *res = &irn_live[pos + 1].u.node;
+               struct _be_lv_info_node_t *rec = &irn_live[pos + 1].u.node;
 
                /* Check, if the irn is in deed in the array. */
-               if(res->idx == idx)
-                       return res;
+               if(rec->idx == idx)
+                       res = rec;
        }
+       stat_ev_tim_pop("be_lv_get");
 
-       return NULL;
+       return res;
 }
 
 static struct _be_lv_info_node_t *be_lv_get_or_set(struct _be_lv_t *li, ir_node *bl, ir_node *irn)
@@ -505,6 +510,7 @@ static void compute_liveness(be_lv_t *lv)
        ir_node **nodes;
        int i, n;
 
+       stat_ev_tim_push();
        obstack_init(&obst);
        irg_walk_graph(lv->irg, collect_nodes, NULL, &obst);
        n      = obstack_object_size(&obst) / sizeof(nodes[0]);
@@ -529,6 +535,7 @@ static void compute_liveness(be_lv_t *lv)
 
        obstack_free(&obst, NULL);
        register_hook(hook_node_info, &lv->hook_info);
+       stat_ev_tim_pop("be_lv_sets_cons");
 }
 
 void be_liveness_assure_sets(be_lv_t *lv)
@@ -879,11 +886,12 @@ void be_live_chk_compare(be_lv_t *lv, lv_chk_t *lvc)
        obstack_ptr_grow(&obst, NULL);
        nodes = obstack_finish(&obst);
 
-       for (i = 0; blocks[i]; ++i) {
-               ir_node *bl = blocks[i];
+       stat_ev_ctx_push("be_lv_chk_compare");
+       for (j = 0; nodes[j]; ++j) {
+               ir_node *irn = nodes[j];
+               for (i = 0; blocks[i]; ++i) {
+                       ir_node *bl = blocks[i];
 
-               for (j = 0; nodes[j]; ++j) {
-                       ir_node *irn = nodes[j];
                        if (!is_Block(irn)) {
                                int lvr_in  = be_is_live_in (lv, bl, irn);
                                int lvr_out = be_is_live_out(lv, bl, irn);
@@ -904,7 +912,7 @@ void be_live_chk_compare(be_lv_t *lv, lv_chk_t *lvc)
                        }
                }
        }
-
+       stat_ev_ctx_pop("be_lv_chk_compare");
 
        obstack_free(&obst, NULL);
 }
index 33c24c2..c5379fe 100644 (file)
@@ -31,6 +31,7 @@
 #include "irphase_t.h"
 #include "irhooks.h"
 #include "dfs.h"
+#include "statev.h"
 
 #include "pset.h"
 #include "bitset.h"
@@ -102,18 +103,19 @@ struct _be_lv_info_node_t *be_lv_get(const struct _be_lv_t *li, const ir_node *b
 
 static INLINE int _be_is_live_xxx(const struct _be_lv_t *li, const ir_node *block, const ir_node *irn, unsigned flags)
 {
+       int res;
+
        if (li->nodes) {
                struct _be_lv_info_node_t *info = be_lv_get(li, block, irn);
-               return info ? (info->flags & flags) != 0 : 0;
+               res = info ? (info->flags & flags) != 0 : 0;
        }
 
 #ifdef USE_LIVE_CHK
        else
-               return (lv_chk_bl_xxx(li->lvc, block, irn) & flags) != 0;
-#else
-       assert(li->nodes && "node sets must be computed");
-       return 0;
+               res = (lv_chk_bl_xxx(li->lvc, block, irn) & flags) != 0;
 #endif /* USE_LIVE_CHK */
+
+       return res;
 }
 
 #define be_lv_foreach(lv, bl, flags, i) \
index 09099a2..e661f4a 100644 (file)
@@ -157,7 +157,7 @@ static const lc_opt_table_entry_t be_main_options[] = {
        LC_OPT_ENT_ENUM_PTR ("sched",    "select a scheduler",                                  &sched_var),
 #ifdef FIRM_STATISTICS
        LC_OPT_ENT_BOOL     ("statev",   "dump statistic events",                               &be_options.statev),
-       LC_OPT_ENT_STR      ("printev",  "print (some) statistic events",                       &be_options.printev, sizeof(be_options.printev)),
+       LC_OPT_ENT_STR      ("filtev",   "filter for stat events (regex if support is active",  &be_options.printev, sizeof(be_options.printev)),
 #endif
 
 #ifdef WITH_ILP
@@ -509,11 +509,11 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
                }
 
                /* generate code */
-               stat_ev_ctx_push("bemain_phase", "prepare");
+               stat_ev_ctx_push_str("bemain_phase", "prepare");
                BE_TIMER_PUSH(t_codegen);
                arch_code_generator_prepare_graph(birg->cg);
                BE_TIMER_POP(t_codegen);
-               stat_ev_ctx_pop();
+               stat_ev_ctx_pop("bemain_phase");
 
                /* reset the phi handler. */
                be_phi_handler_reset(env.phi_handler);
@@ -544,11 +544,11 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
                /* be_live_chk_compare(birg); */
 
                /* let backend prepare scheduling */
-               stat_ev_ctx_push("bemain_phase", "before_sched");
+               stat_ev_ctx_push_str("bemain_phase", "before_sched");
                BE_TIMER_PUSH(t_codegen);
                arch_code_generator_before_sched(birg->cg);
                BE_TIMER_POP(t_codegen);
-               stat_ev_ctx_pop();
+               stat_ev_ctx_pop("bemain_phase");
 
                /* schedule the irg */
                BE_TIMER_PUSH(t_sched);
@@ -730,7 +730,7 @@ static void be_main_loop(FILE *file_handle, const char *cup_name)
 #endif /* FIRM_STATISTICS */
                        free_ir_graph(irg);
 #endif /* if 0 */
-               stat_ev_ctx_pop();
+               stat_ev_ctx_pop("bemain_irg");
        }
        be_profile_free();
        be_done_env(&env);
@@ -766,18 +766,15 @@ void be_main(FILE *file_handle, const char *cup_name)
        }
 
 #ifdef FIRM_STATISTICS
-       if (be_options.statev || be_options.printev[0] != '\0') {
+       if (be_options.statev) {
                const char *dot = strrchr(cup_name, '.');
                const char *pos = dot ? dot : cup_name + strlen(cup_name);
                char       *buf = alloca(pos - cup_name + 1);
                strncpy(buf, cup_name, pos - cup_name);
                buf[pos - cup_name] = '\0';
 
-               stat_ev_begin(buf);
-
-               if(be_options.printev[0] != '\0') {
-                       stat_ev_print(be_options.printev);
-               }
+               be_options.statev = 1;
+               stat_ev_begin(buf, be_options.printev);
        }
 #endif
 
index d4a52d0..6137ce4 100644 (file)
@@ -390,7 +390,6 @@ void be_ssa_destruction(be_chordal_env_t *chordal_env) {
        FIRM_DBG_REGISTER(dbg, "ir.be.ssadestr");
 
        be_liveness_invalidate(lv);
-       be_liveness_assure_sets(lv);
 
        /* create a map for fast lookup of perms: block --> perm */
        irg_walk_graph(irg, clear_link, collect_phis_walker, chordal_env);