X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Fvrp.c;h=8e51b831b94ad0e380a965aeb4df12e5655baab1;hb=971bb3d4ab2da19de4f3edc07e56e4249d765efd;hp=567f3839ace5a966c426a7679f94454b82f0c28a;hpb=ec9bf8c53e9a750f39225ff384fcfad7c0303850;p=libfirm diff --git a/ir/ana/vrp.c b/ir/ana/vrp.c index 567f3839a..8e51b831b 100644 --- a/ir/ana/vrp.c +++ b/ir/ana/vrp.c @@ -19,9 +19,9 @@ /** * @file - * @brief analyze graph to provide value range information - * @author Jonas Fietz - * @version $Id$ + * @brief analyze graph to provide value range information + * @author Jonas Fietz + * @version $Id$ */ #include "config.h" @@ -38,15 +38,15 @@ #include "irop.h" #include "pdeq.h" #include "irphase_t.h" +#include "bitset.h" #include "debug.h" -static char v; -static void *VISITED = &v; +DEBUG_ONLY(static firm_dbg_module_t *dbg); -struct vrp_env_t { - waitq *workqueue; - DEBUG_ONLY(firm_dbg_module_t *dbg); -}; +typedef struct vrp_env_t { + waitq *workqueue; + bitset_t *visited; +} vrp_env_t; static vrp_attr *get_vrp_attr(const ir_node *node) { @@ -55,10 +55,10 @@ static vrp_attr *get_vrp_attr(const ir_node *node) static int vrp_update_node(ir_node *node) { - tarval *new_bits_set = get_tarval_bad(); - tarval *new_bits_not_set = get_tarval_bad(); - tarval *new_range_bottom = get_tarval_bad(); - tarval *new_range_top = get_tarval_bad(); + ir_tarval *new_bits_set = get_tarval_bad(); + ir_tarval *new_bits_not_set = get_tarval_bad(); + ir_tarval *new_range_bottom = get_tarval_bad(); + ir_tarval *new_range_top = get_tarval_bad(); enum range_types new_range_type = VRP_UNDEFINED; int something_changed = 0; vrp_attr *vrp; @@ -73,7 +73,7 @@ static int vrp_update_node(ir_node *node) switch (get_irn_opcode(node)) { case iro_Const: { - tarval *tv = get_Const_tarval(node); + ir_tarval *tv = get_Const_tarval(node); new_bits_set = tv; new_bits_not_set = tv; new_range_bottom = tv; @@ -97,7 +97,7 @@ static int vrp_update_node(ir_node *node) case iro_Add: { int overflow_top, overflow_bottom; - tarval *new_top, *new_bottom; + ir_tarval *new_top, *new_bottom; const vrp_attr *vrp_left, *vrp_right; vrp_left = get_vrp_attr(get_Add_left(node)); vrp_right = get_vrp_attr(get_Add_right(node)); @@ -129,7 +129,7 @@ static int vrp_update_node(ir_node *node) case iro_Sub: { int overflow_top, overflow_bottom; - tarval *new_top, *new_bottom; + ir_tarval *new_top, *new_bottom; const vrp_attr *vrp_left, *vrp_right; vrp_left = get_vrp_attr(get_Sub_left(node)); vrp_right = get_vrp_attr(get_Sub_right(node)); @@ -179,7 +179,7 @@ static int vrp_update_node(ir_node *node) /* We can only compute this if the right value is a constant*/ if (is_Const(right)) { - tarval *bits_set, *bits_not_set; + ir_tarval *bits_set, *bits_not_set; bits_set = tarval_rotl(vrp_left->bits_set, get_Const_tarval(right)); bits_not_set = tarval_rotl(vrp_left->bits_not_set, get_Const_tarval(right)); } @@ -364,10 +364,10 @@ static int vrp_update_node(ir_node *node) /* TODO: Check, if there can be information derived from any of these: is_Abs(node) is_Alloc(node) is_Anchor(node) is_Borrow(node) is_Bound(node) - is_Break(node) is_Builtin(node) is_Call(node) is_CallBegin(node) + is_Break(node) is_Builtin(node) is_Call(node) is_Carry(node) is_Cast(node) is_Cmp(node) is_Cond(node) is_CopyB(node) is_Div(node) is_DivMod(node) is_Dummy(node) - is_End(node) is_EndExcept(node) is_EndReg(node) is_Filter(node) is_Free(node) + is_End(node) is_Free(node) is_IJmp(node) is_InstOf(node) is_Jmp(node) is_Load(node) is_Minus(node) is_Mod(node) is_Mul(node) is_Mulh(node) is_Mux(node) is_NoMem(node) is_Pin(node) is_Proj(node) is_Quot(node) @@ -477,36 +477,33 @@ static int vrp_update_node(ir_node *node) static void vrp_first_pass(ir_node *n, void *e) { - ir_node *succ; int i; - struct vrp_env_t *env = e; + vrp_env_t *env = (vrp_env_t*) e; if (is_Block(n)) return; - set_irn_link(n, VISITED); + bitset_set(env->visited, get_irn_idx(n)); vrp_update_node(n); assure_irg_outs(get_current_ir_graph()); for (i = get_irn_n_outs(n) - 1; i >=0; --i) { - succ = get_irn_out(n, i); - if (get_irn_link(succ) == VISITED) { + ir_node *succ = get_irn_out(n, i); + if (bitset_is_set(env->visited, get_irn_idx(succ))) { /* we found a loop*/ waitq_put(env->workqueue, succ); } } } -static void *vrp_init_node(ir_phase *phase, const ir_node *n, void *old) +static void *vrp_init_node(ir_phase *phase, const ir_node *n) { ir_mode *mode; vrp_attr *vrp; - struct vrp_env_t *env = phase->priv; - DBG((env->dbg, LEVEL_2, "initialized node nr: %d\n", get_irn_node_nr(n))); - assert(old==NULL && "init called for node already initialized"); - vrp = phase_alloc(phase, sizeof(vrp_attr)); + DBG((dbg, LEVEL_2, "initialized node nr: %d\n", get_irn_node_nr(n))); + vrp = (vrp_attr*) phase_alloc(phase, sizeof(vrp_attr)); memset(vrp, 0, sizeof(vrp_attr)); /* Initialize the vrp information to default */ @@ -546,29 +543,32 @@ void set_vrp_data(ir_graph *irg) { ir_node *succ, *node; int i; - struct vrp_env_t *env; + vrp_env_t *env; ir_phase *phase; + FIRM_DBG_REGISTER(dbg, "ir.ana.vrp"); + assure_irg_outs(irg); /* ensure that out edges are consistent*/ phase = irg_get_phase(irg, PHASE_VRP); if (phase == NULL) { /* this is our first run */ phase = new_phase(irg, vrp_init_node); irg_register_phase(irg, PHASE_VRP, phase); - env = phase_alloc(phase, sizeof(*env)); - FIRM_DBG_REGISTER(env->dbg, "ir.ana.vrp"); + env = (vrp_env_t*) phase_alloc(phase, sizeof(*env)); phase->priv = env; } else { - env = phase->priv; + env = (vrp_env_t*) phase->priv; } env->workqueue = new_waitq(); + env->visited = bitset_malloc(get_irg_last_idx(irg)); irg_walk_graph(irg, NULL, vrp_first_pass, env); + bitset_free(env->visited); /* while there are entries in the worklist, continue*/ while (!waitq_empty(env->workqueue)) { - node = waitq_get(env->workqueue); + node = (ir_node*) waitq_get(env->workqueue); if (vrp_update_node(node)) { /* if something changed, add successors to worklist*/ @@ -581,7 +581,6 @@ void set_vrp_data(ir_graph *irg) del_waitq(env->workqueue); } - ir_graph_pass_t *set_vrp_pass(const char *name) { return def_graph_pass(name ? name : "set_vrp", set_vrp_data); @@ -627,9 +626,10 @@ vrp_attr *vrp_get_info(const ir_node *node) return NULL; } - vrp = phase_get_irn_data(phase, node); + vrp = (vrp_attr*) phase_get_irn_data(phase, node); if (vrp && vrp->valid) { return vrp; } + return NULL; }