X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ir%2Fopt%2Fcondeval.c;h=276c79b66649cc9d3a7f193044d106de5958ed91;hb=7dfcddaf2dfe8322182d100532b16c48e438752d;hp=39bdbfedd7aa914e4f813980b6495304f8f3d6f6;hpb=0792bf86212e92fecf16ad3018a20e7ad46616c7;p=libfirm diff --git a/ir/opt/condeval.c b/ir/opt/condeval.c index 39bdbfedd..276c79b66 100644 --- a/ir/opt/condeval.c +++ b/ir/opt/condeval.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -256,15 +256,22 @@ static void copy_and_fix(const condeval_env_t *env, ir_node *block, foreach_out_edge(block, edge) { ir_node *node = get_edge_src_irn(edge); ir_node *copy; - ir_mode *mode = get_irn_mode(node); + ir_mode *mode; + + if (is_Block(node)) { + /* Block->Block edge, should be the MacroBlock edge */ + assert(get_Block_MacroBlock(node) == block && "Block->Block edge found"); + continue; + } /* ignore control flow */ + mode = get_irn_mode(node); if (mode == mode_X || is_Cond(node)) continue; #ifdef AVOID_PHIB /* we may not copy mode_b nodes, because this could produce phi with * mode_bs which can't be handled in all backends. Instead we duplicate - * the node and move it to it's users */ + * the node and move it to its users */ if (mode == mode_b) { const ir_edge_t *edge, *next; ir_node *pred; @@ -310,8 +317,15 @@ static void copy_and_fix(const condeval_env_t *env, ir_node *block, ir_node *vals[2]; ir_node *blocks[2]; ir_node *node = get_edge_src_irn(edge); - ir_mode *mode = get_irn_mode(node); + ir_mode *mode; + if (is_Block(node)) { + /* Block->Block edge, should be the MacroBlock edge */ + assert(get_Block_MacroBlock(node) == block && "Block->Block edge found"); + continue; + } + + mode = get_irn_mode(node); if (mode == mode_X || is_Cond(node)) continue; #ifdef AVOID_PHIB @@ -329,12 +343,16 @@ static void copy_and_fix(const condeval_env_t *env, ir_node *block, } } +/** + * returns wether the cmp evaluates to true or false, or can't be evaluated! + * 1: true, 0: false, -1: can't evaluate + */ static int eval_cmp(pn_Cmp pnc, tarval *tv1, tarval *tv2) { pn_Cmp cmp_result = tarval_cmp(tv1, tv2); // does the compare evaluate to true? if(cmp_result == pn_Cmp_False) - return 0; + return -1; if((cmp_result & pnc) != cmp_result) return 0; @@ -353,7 +371,7 @@ static ir_node *find_const(condeval_env_t *env, ir_node *jump, ir_node *value) tarval *tv_const = get_Const_tarval(env->cnst); tarval *tv = get_Const_tarval(value); - if(!eval_cmp(env->pnc, tv, tv_const)) { + if(eval_cmp(env->pnc, tv, tv_const) <= 0) { return NULL; } @@ -569,6 +587,8 @@ static void cond_eval(ir_node* block, void* data) tarval *tv_right = get_Const_tarval(right); selector_evaluated = eval_cmp(pnc, tv_left, tv_right); + if(selector_evaluated < 0) + return; } } } else if(is_Const(selector)) { @@ -645,7 +665,7 @@ void opt_cond_eval(ir_graph* irg) edges_assure(irg); set_using_irn_link(irg); - set_using_visited(irg); + set_using_irn_visited(irg); changed = 0; do { @@ -662,6 +682,6 @@ void opt_cond_eval(ir_graph* irg) set_irg_loopinfo_inconsistent(irg); } - clear_using_visited(irg); + clear_using_irn_visited(irg); clear_using_irn_link(irg); }