Commit 538c4575 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

Split looking for Cmp-Phi-Constant into a separate function.

[r14944]
parent 53991c3a
...@@ -362,61 +362,23 @@ static ir_node *find_phi_with_const(ir_node *jump, ir_node *value, condeval_env_ ...@@ -362,61 +362,23 @@ static ir_node *find_phi_with_const(ir_node *jump, ir_node *value, condeval_env_
} }
/** static int cond_eval_cmp(ir_node* proj_b, ir_node* block, ir_node* projx, ir_node* cond)
* 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)
{ {
condeval_env_t env;
int *changed = data;
ir_graph *irg = current_ir_graph; ir_graph *irg = current_ir_graph;
ir_node *copy_block; ir_node *cmp = get_Proj_pred(proj_b);
ir_node *pred; ir_node *left;
ir_node *projx; ir_node *right;
ir_node *cond; ir_node *cond_block;
ir_node *cmp; ir_node *copy_block;
ir_node *left; pn_Cmp pnc;
ir_node *right;
ir_node *cond_block;
pn_Cmp pnc;
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;
pnc = get_Proj_proj(pred);
cmp = get_Proj_pred(pred);
assert(is_Cmp(cmp)); assert(is_Cmp(cmp));
left = get_Cmp_left(cmp); left = get_Cmp_left(cmp);
right = get_Cmp_right(cmp); right = get_Cmp_right(cmp);
assert(get_irn_mode(left) == get_irn_mode(right)); 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 */ /* we assume that the cond_block is the true case */
if (get_Proj_proj(projx) == pn_Cond_false) { if (get_Proj_proj(projx) == pn_Cond_false) {
pnc = get_negated_pnc(pnc, get_irn_mode(left)); pnc = get_negated_pnc(pnc, get_irn_mode(left));
...@@ -433,7 +395,7 @@ static void cond_eval(ir_node* block, void* data) ...@@ -433,7 +395,7 @@ static void cond_eval(ir_node* block, void* data)
} }
if(!is_Const(right)) if(!is_Const(right))
return; return 0;
cond_block = get_nodes_block(cond); cond_block = get_nodes_block(cond);
...@@ -448,13 +410,11 @@ static void cond_eval(ir_node* block, void* data) ...@@ -448,13 +410,11 @@ static void cond_eval(ir_node* block, void* data)
pred = new_Bad(); pred = new_Bad();
} }
set_Block_cfgpred(block, 0, pred); set_Block_cfgpred(block, 0, pred);
*changed = 1;
set_irg_doms_inconsistent(irg);
set_irg_extblk_inconsistent(irg);
set_irg_loopinfo_inconsistent(irg);
} else { } else {
condeval_env_t env;
if(get_nodes_block(left) != cond_block) if(get_nodes_block(left) != cond_block)
return; return 0;
// (recursively) look if a pred of a phi is a constant // (recursively) look if a pred of a phi is a constant
env.true_block = block; env.true_block = block;
...@@ -465,28 +425,72 @@ static void cond_eval(ir_node* block, void* data) ...@@ -465,28 +425,72 @@ static void cond_eval(ir_node* block, void* data)
copy_block = find_phi_with_const(projx, left, &env); copy_block = find_phi_with_const(projx, left, &env);
if(copy_block != NULL) { if (copy_block == NULL)
/* we have to remove the edge towards the pred as the pred now return 0;
* 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;
/* shorten phis */ /* we have to remove the edge towards the pred as the pred now
foreach_out_edge_safe(env.cnst_pred, edge, next) { * jumps into the true_block. We also have to shorten phis
ir_node *node = get_edge_src_irn(edge); * 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)) /* shorten phis */
set_Phi_pred(node, cnst_pos, bad); 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); if(is_Phi(node))
set_Phi_pred(node, cnst_pos, bad);
/* the graph is changed now */
*changed = 1;
} }
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) void opt_cond_eval(ir_graph* irg)
......
Markdown is supported
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