X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeuses.c;h=722f83db70e0e5b1cc0bd04dd764cb225079b527;hb=6e3e499d6c68aee0c6a9ada6a99f16c4f6f8445b;hp=9d2c7dadc683dc00f17cc4be381aed4391838f53;hpb=1013579946ac0cdb7e1461a6b52006e01d87716b;p=libfirm diff --git a/ir/be/beuses.c b/ir/be/beuses.c index 9d2c7dadc..722f83db7 100644 --- a/ir/be/beuses.c +++ b/ir/be/beuses.c @@ -33,10 +33,13 @@ #include "bearch.h" #include "beuses_t.h" +#define DBG_LEVEL SET_LEVEL_0 + typedef struct _be_use_t { - const ir_node *bl; - const ir_node *irn; - unsigned next_use; + const ir_node *bl; + const ir_node *irn; + unsigned next_use; + int is_set; } be_use_t; struct _be_uses_t { @@ -75,11 +78,12 @@ static INLINE be_use_t *get_or_set_use(be_uses_t *uses, templ.bl = bl; templ.irn = irn; templ.next_use = next_use; + templ.is_set = 0; return set_insert(uses->uses, &templ, sizeof(templ), hash); } unsigned be_get_next_use(be_uses_t *uses, const ir_node *from, - unsigned from_step, const ir_node *def); + unsigned from_step, const ir_node *def, int skip_from_uses); static unsigned get_next_use_bl(be_uses_t *uses, const ir_node *bl, const ir_node *def) @@ -87,69 +91,78 @@ static unsigned get_next_use_bl(be_uses_t *uses, const ir_node *bl, be_use_t *u; u = get_or_set_use(uses, bl, def, 0); - if(USES_IS_INIFINITE(u->next_use)) - return u->next_use; - - u->next_use = USES_INFINITY; - u->next_use = be_get_next_use(uses, sched_first(bl), 0, def); + if(!u->is_set) { + u->is_set = 1; + u->next_use = USES_INFINITY; + u->next_use = be_get_next_use(uses, sched_first(bl), 0, def, 0); + } return u->next_use; } -unsigned be_get_next_use(be_uses_t *uses, - const ir_node *from, unsigned from_step, const ir_node *def) +static unsigned get_next_use(be_uses_t *uses, const ir_node *from, unsigned from_step, const ir_node *def, int skip_from_uses, unsigned long visited_nr) { - unsigned next_use = USES_INFINITY; - unsigned step = from_step; - unsigned n = 0; - const ir_node *irn; - const ir_node *bl = get_block(from); - const ir_edge_t *succ_edge; - - sched_foreach_from(from, irn) { - int i, n; - - for(i = 0, n = get_irn_arity(irn); i < n; ++i) { - ir_node *operand = get_irn_n(irn, i); - - if(operand == def) { - DBG((uses->dbg, LEVEL_3, "found use of %+F at %+F\n", operand, irn)); - return step; - } - } - - step++; - } - - next_use = step; - foreach_block_succ(bl, succ_edge) { - const ir_node *succ_bl = succ_edge->src; - if(is_live_in(succ_bl, def)) { - unsigned next = get_next_use_bl(uses, succ_bl, def); - - DBG((uses->dbg, LEVEL_2, "\t\tnext use in succ %+F: %d\n", succ_bl, next)); - next_use = sadd(next_use, next); - n++; - } - } + unsigned next_use = USES_INFINITY; + unsigned step = from_step; + unsigned n = 0; + ir_node *bl = get_nodes_block(from); + const ir_node *irn; + const ir_edge_t *succ_edge; + + set_irn_visited(bl, visited_nr); + + sched_foreach_from(from, irn) { + int i, n; + + if(!skip_from_uses) { + for(i = 0, n = get_irn_arity(irn); i < n; ++i) { + ir_node *operand = get_irn_n(irn, i); + + if(operand == def) { + DBG((uses->dbg, LEVEL_3, "found use of %+F at %+F\n", operand, irn)); + return step; + } + } + } + + skip_from_uses = 0; + step++; + } + + next_use = USES_INFINITY; + foreach_block_succ(bl, succ_edge) { + const ir_node *succ_bl = succ_edge->src; + if(get_irn_visited(succ_bl) < visited_nr && (is_live_in(succ_bl, def) || (get_irn_arity(succ_bl) > 1 && is_live_end(bl, def)))) { + unsigned next = get_next_use_bl(uses, succ_bl, def); + + DBG((uses->dbg, LEVEL_2, "\t\tnext use in succ %+F: %d\n", succ_bl, next)); + next_use = MIN(next_use, next); + n++; + } + } + + return next_use + step; +} - if(n > 1) - next_use = sdiv(next_use, n); +unsigned be_get_next_use(be_uses_t *uses, const ir_node *from, unsigned from_step, const ir_node *def, int skip_from_uses) +{ + unsigned long visited_nr = get_irg_visited(uses->irg) + 1; - return sadd(next_use, step); + set_irg_visited(uses->irg, visited_nr); + return get_next_use(uses, from, from_step, def, skip_from_uses, visited_nr); } -be_uses_t *be_begin_uses( - ir_graph *irg, - const arch_env_t *arch_env, - const arch_register_class_t *cls) + +be_uses_t *be_begin_uses(ir_graph *irg, const arch_env_t *arch_env, const arch_register_class_t *cls) { - be_uses_t *uses = malloc(sizeof(uses[0])); + be_uses_t *uses = xmalloc(sizeof(uses[0])); edges_assure(irg); uses->arch_env = arch_env; uses->uses = new_set(cmp_use, 512); - uses->dbg = firm_dbg_register("be.uses"); + uses->irg = irg; + FIRM_DBG_REGISTER(uses->dbg, "be.uses"); + firm_dbg_set_mask(uses->dbg, DBG_LEVEL); return uses; }