From: Christoph Mallon Date: Wed, 4 Jul 2007 21:43:20 +0000 (+0000) Subject: Split looking for Cmp-Phi-Constant into a separate function. X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=538c4575073ccf7f933f545301b706f610ff7fa0;p=libfirm Split looking for Cmp-Phi-Constant into a separate function. [r14944] --- diff --git a/ir/opt/condeval.c b/ir/opt/condeval.c index c7c66833b..65c4d80f0 100644 --- a/ir/opt/condeval.c +++ b/ir/opt/condeval.c @@ -362,61 +362,23 @@ static ir_node *find_phi_with_const(ir_node *jump, ir_node *value, condeval_env_ } -/** - * Block-walker: searches for the following construct - * - * Const or Phi with constants - * | - * Cmp - * | - * Cond - * / - * ProjX - * / - * Block - */ -static void cond_eval(ir_node* block, void* data) +static int cond_eval_cmp(ir_node* proj_b, ir_node* block, ir_node* projx, ir_node* cond) { - condeval_env_t env; - int *changed = data; ir_graph *irg = current_ir_graph; - ir_node *copy_block; - ir_node *pred; - ir_node *projx; - ir_node *cond; - ir_node *cmp; - ir_node *left; - ir_node *right; - ir_node *cond_block; - pn_Cmp pnc; - - if(get_Block_n_cfgpreds(block) != 1) - return; + ir_node *cmp = get_Proj_pred(proj_b); + ir_node *left; + ir_node *right; + ir_node *cond_block; + ir_node *copy_block; + pn_Cmp pnc; - projx = get_Block_cfgpred(block, 0); - if (!is_Proj(projx)) - return; - assert(get_irn_mode(projx) == mode_X); - - cond = get_Proj_pred(projx); - if (!is_Cond(cond)) - return; - - pred = get_Cond_selector(cond); - // TODO handle switches - if (get_irn_mode(pred) != mode_b) - return; - if (!is_Proj(pred)) - return; - pnc = get_Proj_proj(pred); - - cmp = get_Proj_pred(pred); assert(is_Cmp(cmp)); left = get_Cmp_left(cmp); right = get_Cmp_right(cmp); assert(get_irn_mode(left) == get_irn_mode(right)); + pnc = get_Proj_proj(proj_b); /* we assume that the cond_block is the true case */ if (get_Proj_proj(projx) == pn_Cond_false) { pnc = get_negated_pnc(pnc, get_irn_mode(left)); @@ -433,7 +395,7 @@ static void cond_eval(ir_node* block, void* data) } if(!is_Const(right)) - return; + return 0; cond_block = get_nodes_block(cond); @@ -448,13 +410,11 @@ static void cond_eval(ir_node* block, void* data) pred = new_Bad(); } set_Block_cfgpred(block, 0, pred); - *changed = 1; - set_irg_doms_inconsistent(irg); - set_irg_extblk_inconsistent(irg); - set_irg_loopinfo_inconsistent(irg); } else { + condeval_env_t env; + if(get_nodes_block(left) != cond_block) - return; + return 0; // (recursively) look if a pred of a phi is a constant env.true_block = block; @@ -465,28 +425,72 @@ static void cond_eval(ir_node* block, void* data) copy_block = find_phi_with_const(projx, left, &env); - if(copy_block != NULL) { - /* we have to remove the edge towards the pred as the pred now - * jumps into the true_block. We also have to shorten phis - * in our block because of this */ - const ir_edge_t *edge, *next; - ir_node* bad = new_Bad(); - size_t cnst_pos = env.cnst_pos; + if (copy_block == NULL) + return 0; - /* shorten phis */ - foreach_out_edge_safe(env.cnst_pred, edge, next) { - ir_node *node = get_edge_src_irn(edge); + /* we have to remove the edge towards the pred as the pred now + * jumps into the true_block. We also have to shorten phis + * in our block because of this */ + const ir_edge_t *edge, *next; + ir_node* bad = new_Bad(); + size_t cnst_pos = env.cnst_pos; - if(is_Phi(node)) - set_Phi_pred(node, cnst_pos, bad); - } + /* shorten phis */ + foreach_out_edge_safe(env.cnst_pred, edge, next) { + ir_node *node = get_edge_src_irn(edge); - set_Block_cfgpred(env.cnst_pred, cnst_pos, bad); - - /* the graph is changed now */ - *changed = 1; + if(is_Phi(node)) + set_Phi_pred(node, cnst_pos, bad); } + + set_Block_cfgpred(env.cnst_pred, cnst_pos, bad); } + /* the graph is changed now */ + return 1; +} + + +/** + * Block-walker: searches for the following construct + * + * Const or Phi with constants + * | + * Cmp + * | + * Cond + * / + * ProjX + * / + * Block + */ +static void cond_eval(ir_node* block, void* data) +{ + int *changed = data; + ir_node *pred; + ir_node *projx; + ir_node *cond; + + if(get_Block_n_cfgpreds(block) != 1) + return; + + projx = get_Block_cfgpred(block, 0); + if (!is_Proj(projx)) + return; + assert(get_irn_mode(projx) == mode_X); + + cond = get_Proj_pred(projx); + if (!is_Cond(cond)) + return; + + pred = get_Cond_selector(cond); + // TODO handle switches + if (get_irn_mode(pred) != mode_b) + return; + if (!is_Proj(pred)) + return; + + if (cond_eval_cmp(pred, block, projx, cond)) + *changed = 1; } void opt_cond_eval(ir_graph* irg)