Commit edc739b3 authored by Sebastian Hack's avatar Sebastian Hack
Browse files

Adapted to new statev

[r15733]
parent 6f996fb0
......@@ -37,8 +37,16 @@
#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;
}
......
......@@ -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;
}
......@@ -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");
}
/**
......
......@@ -16,8 +16,11 @@
#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,11 +113,9 @@ 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;
/* If there is no dominance relation, they do not interfere. */
if((a2b | b2a) > 0) {
const ir_edge_t *edge;
ir_node *bb;
stat_ev_ctx_push("beintlive");
/*
* Adjust a and b so, that a dominates b if
......@@ -124,16 +125,24 @@ static INLINE int _lv_values_interfere(const be_lv_t *lv, const ir_node *a, cons
const ir_node *t = a;
a = b;
b = t;
a2b = 1;
}
bb = get_nodes_block(b);
/* If there is no dominance relation, they do not interfere. */
if(a2b) {
const ir_edge_t *edge;
ir_node *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;
}
......
......@@ -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);
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);
}
......
......@@ -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) \
......
......@@ -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
......
......@@ -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);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment