Commit c56025f3 authored by Matthias Braun's avatar Matthias Braun
Browse files

cleanup, use C99

parent dc38d853
...@@ -51,14 +51,8 @@ static ir_node *ssa_second_def; ...@@ -51,14 +51,8 @@ static ir_node *ssa_second_def;
static ir_node *ssa_second_def_block; static ir_node *ssa_second_def_block;
static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode, static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode,
int first) bool first)
{ {
int i;
int n_cfgpreds;
ir_graph *irg;
ir_node *phi;
ir_node *dummy;
/* In case of a bad input to a block we need to return the bad value */ /* In case of a bad input to a block we need to return the bad value */
if (is_Bad(block)) { if (is_Bad(block)) {
ir_graph *irg = get_irn_irg(block); ir_graph *irg = get_irn_irg(block);
...@@ -80,35 +74,35 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode, ...@@ -80,35 +74,35 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode,
return value; return value;
} }
irg = get_irn_irg(block); ir_graph *irg = get_irn_irg(block);
assert(block != get_irg_start_block(irg)); assert(block != get_irg_start_block(irg));
/* a Block with only 1 predecessor needs no Phi */ /* a Block with only 1 predecessor needs no Phi */
n_cfgpreds = get_Block_n_cfgpreds(block); int n_cfgpreds = get_Block_n_cfgpreds(block);
if (n_cfgpreds == 1) { if (n_cfgpreds == 1) {
ir_node *pred_block = get_Block_cfgpred_block(block, 0); ir_node *pred_block = get_Block_cfgpred_block(block, 0);
ir_node *value = search_def_and_create_phis(pred_block, mode, 0); ir_node *value = search_def_and_create_phis(pred_block, mode,
false);
set_irn_link(block, value); set_irn_link(block, value);
mark_irn_visited(block); mark_irn_visited(block);
return value; return value;
} }
/* create a new Phi */ /* create a new Phi */
ir_node **in = ALLOCAN(ir_node*, n_cfgpreds); ir_node **in = ALLOCAN(ir_node*, n_cfgpreds);
dummy = new_r_Dummy(irg, mode); ir_node *dummy = new_r_Dummy(irg, mode);
for (i = 0; i < n_cfgpreds; ++i) for (int i = 0; i < n_cfgpreds; ++i)
in[i] = dummy; in[i] = dummy;
phi = new_r_Phi(block, n_cfgpreds, in, mode); ir_node *phi = new_r_Phi(block, n_cfgpreds, in, mode);
set_irn_link(block, phi); set_irn_link(block, phi);
mark_irn_visited(block); mark_irn_visited(block);
/* set Phi predecessors */ /* set Phi predecessors */
for (i = 0; i < n_cfgpreds; ++i) { for (int i = 0; i < n_cfgpreds; ++i) {
ir_node *pred_block = get_Block_cfgpred_block(block, i); ir_node *pred_block = get_Block_cfgpred_block(block, i);
ir_node *pred_val = search_def_and_create_phis(pred_block, mode, 0); ir_node *pred_val = search_def_and_create_phis(pred_block, mode,
false);
set_irn_n(phi, i, pred_val); set_irn_n(phi, i, pred_val);
} }
...@@ -123,17 +117,14 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode, ...@@ -123,17 +117,14 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode,
static void construct_ssa(ir_node *orig_block, ir_node *orig_val, static void construct_ssa(ir_node *orig_block, ir_node *orig_val,
ir_node *second_block, ir_node *second_val) ir_node *second_block, ir_node *second_val)
{ {
ir_graph *irg;
ir_mode *mode;
/* no need to do anything */ /* no need to do anything */
if (orig_val == second_val) if (orig_val == second_val)
return; return;
irg = get_irn_irg(orig_val); ir_graph *irg = get_irn_irg(orig_val);
inc_irg_visited(irg); inc_irg_visited(irg);
mode = get_irn_mode(orig_val); ir_mode *mode = get_irn_mode(orig_val);
set_irn_link(orig_block, orig_val); set_irn_link(orig_block, orig_val);
mark_irn_visited(orig_block); mark_irn_visited(orig_block);
...@@ -143,26 +134,27 @@ static void construct_ssa(ir_node *orig_block, ir_node *orig_val, ...@@ -143,26 +134,27 @@ static void construct_ssa(ir_node *orig_block, ir_node *orig_val,
/* Only fix the users of the first, i.e. the original node */ /* Only fix the users of the first, i.e. the original node */
foreach_out_edge_safe(orig_val, edge) { foreach_out_edge_safe(orig_val, edge) {
ir_node *user = get_edge_src_irn(edge); ir_node *user = get_edge_src_irn(edge);
int j = get_edge_src_pos(edge);
ir_node *user_block = get_nodes_block(user);
ir_node *newval;
/* ignore keeps */ /* ignore keeps */
if (is_End(user)) if (is_End(user))
continue; continue;
DB((dbg, LEVEL_3, ">>> Fixing user %+F (pred %d == %+F)\n", user, j, get_irn_n(user, j))); int j = get_edge_src_pos(edge);
DB((dbg, LEVEL_3, ">>> Fixing user %+F (pred %d == %+F)\n", user, j,
get_irn_n(user, j)));
ir_node *user_block = get_nodes_block(user);
ir_node *newval;
if (is_Phi(user)) { if (is_Phi(user)) {
ir_node *pred_block = get_Block_cfgpred_block(user_block, j); ir_node *pred_block = get_Block_cfgpred_block(user_block, j);
newval = search_def_and_create_phis(pred_block, mode, 1); newval = search_def_and_create_phis(pred_block, mode, true);
} else { } else {
newval = search_def_and_create_phis(user_block, mode, 1); newval = search_def_and_create_phis(user_block, mode, true);
} }
/* don't fix newly created Phis from the SSA construction */ /* don't fix newly created Phis from the SSA construction */
if (newval != user) { if (newval != user) {
DB((dbg, LEVEL_4, ">>>> Setting input %d of %+F to %+F\n", j, user, newval)); DB((dbg, LEVEL_4, ">>>> Setting input %d of %+F to %+F\n", j, user,
newval));
set_irn_n(user, j, newval); set_irn_n(user, j, newval);
} }
} }
...@@ -180,38 +172,32 @@ static void construct_ssa(ir_node *orig_block, ir_node *orig_val, ...@@ -180,38 +172,32 @@ static void construct_ssa(ir_node *orig_block, ir_node *orig_val,
*/ */
static void split_critical_edge(ir_node *block, int pos) static void split_critical_edge(ir_node *block, int pos)
{ {
ir_graph *irg = get_irn_irg(block); ir_graph *irg = get_irn_irg(block);
ir_node *in[1]; ir_node *in[] = { get_Block_cfgpred(block, pos) };
ir_node *new_block; ir_node *new_block = new_r_Block(irg, ARRAY_SIZE(in), in);
ir_node *new_jmp; ir_node *new_jmp = new_r_Jmp(new_block);
in[0] = get_Block_cfgpred(block, pos);
new_block = new_r_Block(irg, 1, in);
new_jmp = new_r_Jmp(new_block);
set_Block_cfgpred(block, pos, new_jmp); set_Block_cfgpred(block, pos, new_jmp);
} }
typedef struct jumpthreading_env_t { typedef struct jumpthreading_env_t {
ir_node *true_block; ir_node *true_block;
ir_node *cmp; /**< The Compare node that might be partial evaluated */ ir_node *cmp; /**< The Compare node that might be partial
ir_relation relation; /**< The Compare mode of the Compare node. */ evaluated */
ir_node *cnst; ir_relation relation; /**< The Compare mode of the Compare node. */
ir_tarval *tv; ir_node *cnst;
ir_visited_t visited_nr; ir_tarval *tv;
ir_visited_t visited_nr;
ir_node *cnst_pred; /**< the block before the constant */ ir_node *cnst_pred; /**< the block before the constant */
int cnst_pos; /**< the pos to the constant block (needed to int cnst_pos; /**< the pos to the constant block (needed to
kill that edge later) */ kill that edge later) */
} jumpthreading_env_t; } jumpthreading_env_t;
static ir_node *copy_and_fix_node(const jumpthreading_env_t *env, static ir_node *copy_and_fix_node(const jumpthreading_env_t *env,
ir_node *block, ir_node *copy_block, int j, ir_node *block, ir_node *copy_block, int j,
ir_node *node) ir_node *node)
{ {
int i, arity;
ir_node *copy;
/* we can evaluate Phis right now, all other nodes get copied */ /* we can evaluate Phis right now, all other nodes get copied */
ir_node *copy;
if (is_Phi(node)) { if (is_Phi(node)) {
copy = get_Phi_pred(node, j); copy = get_Phi_pred(node, j);
/* we might have to evaluate a Phi-cascade */ /* we might have to evaluate a Phi-cascade */
...@@ -221,17 +207,14 @@ static ir_node *copy_and_fix_node(const jumpthreading_env_t *env, ...@@ -221,17 +207,14 @@ static ir_node *copy_and_fix_node(const jumpthreading_env_t *env,
} else { } else {
copy = exact_copy(node); copy = exact_copy(node);
set_nodes_block(copy, copy_block); set_nodes_block(copy, copy_block);
assert(get_irn_mode(copy) != mode_X); assert(get_irn_mode(copy) != mode_X);
arity = get_irn_arity(copy); for (int i = 0, arity = get_irn_arity(copy); i < arity; ++i) {
for (i = 0; i < arity; ++i) { ir_node *pred = get_irn_n(copy, i);
ir_node *pred = get_irn_n(copy, i);
ir_node *new_pred;
if (get_nodes_block(pred) != block) if (get_nodes_block(pred) != block)
continue; continue;
ir_node *new_pred;
if (get_irn_visited(pred) >= env->visited_nr) { if (get_irn_visited(pred) >= env->visited_nr) {
new_pred = (ir_node*)get_irn_link(pred); new_pred = (ir_node*)get_irn_link(pred);
} else { } else {
...@@ -254,18 +237,14 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block, ...@@ -254,18 +237,14 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
/* Look at all nodes in the cond_block and copy them into pred */ /* Look at all nodes in the cond_block and copy them into pred */
foreach_out_edge(block, edge) { foreach_out_edge(block, edge) {
ir_node *node = get_edge_src_irn(edge); ir_node *node = get_edge_src_irn(edge);
ir_node *copy;
ir_mode *mode;
if (is_End(node)) { if (is_End(node)) {
/* edge is a Keep edge. If the end block is unreachable via normal /* edge is a Keep edge. If the end block is unreachable via normal
* control flow, we must maintain end's reachability with Keeps. * control flow, we must maintain end's reachability with Keeps. */
*/
keep_alive(copy_block); keep_alive(copy_block);
continue; continue;
} }
/* ignore control flow */ /* ignore control flow */
mode = get_irn_mode(node); ir_mode *mode = get_irn_mode(node);
if (mode == mode_X || is_Cond(node) || is_Switch(node)) if (mode == mode_X || is_Cond(node) || is_Switch(node))
continue; continue;
#ifdef AVOID_PHIB #ifdef AVOID_PHIB
...@@ -287,14 +266,13 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block, ...@@ -287,14 +266,13 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
cmp_copy = exact_copy(pred); cmp_copy = exact_copy(pred);
set_nodes_block(cmp_copy, user_block); set_nodes_block(cmp_copy, user_block);
copy = new_r_Proj(cmp_copy, mode_b, pn); ir_node *copy = new_r_Proj(cmp_copy, mode_b, pn);
set_irn_n(user, pos, copy); set_irn_n(user, pos, copy);
} }
continue; continue;
} }
#endif #endif
ir_node *copy = copy_and_fix_node(env, block, copy_block, j, node);
copy = copy_and_fix_node(env, block, copy_block, j, node);
/* we might hit values in blocks that have already been processed by a /* we might hit values in blocks that have already been processed by a
* recursive find_phi_with_const() call */ * recursive find_phi_with_const() call */
...@@ -309,10 +287,7 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block, ...@@ -309,10 +287,7 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
/* fix data-flow (and reconstruct SSA if needed) */ /* fix data-flow (and reconstruct SSA if needed) */
foreach_out_edge(block, edge) { foreach_out_edge(block, edge) {
ir_node *node = get_edge_src_irn(edge); ir_node *node = get_edge_src_irn(edge);
ir_node *copy_node; ir_mode *mode = get_irn_mode(node);
ir_mode *mode;
mode = get_irn_mode(node);
if (mode == mode_X || is_Cond(node) || is_Switch(node)) if (mode == mode_X || is_Cond(node) || is_Switch(node))
continue; continue;
#ifdef AVOID_PHIB #ifdef AVOID_PHIB
...@@ -322,7 +297,7 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block, ...@@ -322,7 +297,7 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
DB((dbg, LEVEL_2, ">> Fixing users of %+F\n", node)); DB((dbg, LEVEL_2, ">> Fixing users of %+F\n", node));
copy_node = (ir_node*)get_irn_link(node); ir_node *copy_node = (ir_node*)get_irn_link(node);
construct_ssa(block, node, copy_block, copy_node); construct_ssa(block, node, copy_block, copy_node);
} }
...@@ -339,12 +314,12 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block, ...@@ -339,12 +314,12 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
} }
/** /**
* returns whether the cmp evaluates to true or false, or can't be evaluated! * Returns whether the cmp evaluates to true or false, or can't be evaluated!
* 1: true, 0: false, -1: can't evaluate
* *
* @param relation the compare mode of the Compare * @param relation the compare mode of the Compare
* @param tv_left the left tarval * @param tv_left the left tarval
* @param tv_right the right tarval * @param tv_right the right tarval
* @returns 1: true, 0: false, -1: can't evaluate
*/ */
static int eval_cmp_tv(ir_relation relation, ir_tarval *tv_left, static int eval_cmp_tv(ir_relation relation, ir_tarval *tv_left,
ir_tarval *tv_right) ir_tarval *tv_right)
...@@ -361,22 +336,22 @@ static int eval_cmp_tv(ir_relation relation, ir_tarval *tv_left, ...@@ -361,22 +336,22 @@ static int eval_cmp_tv(ir_relation relation, ir_tarval *tv_left,
} }
/** /**
* returns whether the cmp evaluates to true or false, or can't be evaluated! * Returns whether the cmp evaluates to true or false, or can't be evaluated!
* 1: true, 0: false, -1: can't evaluate
* *
* @param env the environment * @param env the environment
* @param cand the candidate node, either a Const or a Confirm * @param cand the candidate node, either a Const or a Confirm
* @returns 1: true, 0: false, -1: can't evaluate
*/ */
static int eval_cmp(jumpthreading_env_t *env, ir_node *cand) static int eval_cmp(jumpthreading_env_t *env, ir_node *cand)
{ {
if (is_Const(cand)) { if (is_Const(cand)) {
ir_tarval *tv_cand = get_Const_tarval(cand); ir_tarval *tv_cand = get_Const_tarval(cand);
ir_tarval *tv_cmp = get_Const_tarval(env->cnst); ir_tarval *tv_cmp = get_Const_tarval(env->cnst);
return eval_cmp_tv(env->relation, tv_cand, tv_cmp); return eval_cmp_tv(env->relation, tv_cand, tv_cmp);
} else { /* a Confirm */ } else {
ir_tarval *res = computed_value_Cmp_Confirm(env->cmp, cand, env->cnst, env->relation); assert(is_Confirm(cand));
ir_tarval *res = computed_value_Cmp_Confirm(env->cmp, cand, env->cnst,
env->relation);
if (res == tarval_bad) if (res == tarval_bad)
return -1; return -1;
return res == tarval_b_true; return res == tarval_b_true;
...@@ -386,7 +361,7 @@ static int eval_cmp(jumpthreading_env_t *env, ir_node *cand) ...@@ -386,7 +361,7 @@ static int eval_cmp(jumpthreading_env_t *env, ir_node *cand)
/** /**
* Check for Const or Confirm with Const. * Check for Const or Confirm with Const.
*/ */
static int is_Const_or_Confirm(const ir_node *node) static bool is_Const_or_Confirm(const ir_node *node)
{ {
if (is_Confirm(node)) if (is_Confirm(node))
node = get_Confirm_bound(node); node = get_Confirm_bound(node);
...@@ -398,30 +373,24 @@ static int is_Const_or_Confirm(const ir_node *node) ...@@ -398,30 +373,24 @@ static int is_Const_or_Confirm(const ir_node *node)
*/ */
static ir_tarval *get_Const_or_Confirm_tarval(const ir_node *node) static ir_tarval *get_Const_or_Confirm_tarval(const ir_node *node)
{ {
if (is_Confirm(node)) { if (is_Confirm(node))
if (get_Confirm_bound(node)) node = get_Confirm_bound(node);
node = get_Confirm_bound(node);
}
return get_Const_tarval(node); return get_Const_tarval(node);
} }
static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump, static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump,
ir_node *value) ir_node *value)
{ {
ir_node *block = get_nodes_block(jump);
if (irn_visited_else_mark(value)) if (irn_visited_else_mark(value))
return NULL; return NULL;
ir_node *block = get_nodes_block(jump);
if (is_Const_or_Confirm(value)) { if (is_Const_or_Confirm(value)) {
if (eval_cmp(env, value) <= 0) if (eval_cmp(env, value) <= 0)
return NULL; return NULL;
DB(( DB((dbg, LEVEL_1, "> Found jump threading candidate %+F->%+F\n",
dbg, LEVEL_1, block, env->true_block));
"> Found jump threading candidate %+F->%+F\n",
block, env->true_block
));
/* adjust true_block to point directly towards our jump */ /* adjust true_block to point directly towards our jump */
add_pred(env->true_block, jump); add_pred(env->true_block, jump);
...@@ -430,30 +399,23 @@ static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump, ...@@ -430,30 +399,23 @@ static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump,
/* we need a bigger visited nr when going back */ /* we need a bigger visited nr when going back */
env->visited_nr++; env->visited_nr++;
return block; return block;
} }
if (is_Phi(value)) { if (is_Phi(value)) {
int i, arity;
/* the Phi has to be in the same Block as the Jmp */ /* the Phi has to be in the same Block as the Jmp */
if (get_nodes_block(value) != block) if (get_nodes_block(value) != block)
return NULL; return NULL;
arity = get_irn_arity(value); for (int i = 0, arity = get_irn_arity(value); i < arity; ++i) {
for (i = 0; i < arity; ++i) { ir_node *phi_pred = get_Phi_pred(value, i);
ir_node *copy_block; ir_node *cfgpred = get_Block_cfgpred(block, i);
ir_node *phi_pred = get_Phi_pred(value, i); ir_node *copy_block = find_const_or_confirm(env, cfgpred, phi_pred);
ir_node *cfgpred = get_Block_cfgpred(block, i);
copy_block = find_const_or_confirm(env, cfgpred, phi_pred);
if (copy_block == NULL) if (copy_block == NULL)
continue; continue;
/* copy duplicated nodes in copy_block and fix SSA */ /* copy duplicated nodes in copy_block and fix SSA */
copy_and_fix(env, block, copy_block, i); copy_and_fix(env, block, copy_block, i);
if (copy_block == get_nodes_block(cfgpred)) { if (copy_block == get_nodes_block(cfgpred)) {
env->cnst_pred = block; env->cnst_pred = block;
env->cnst_pos = i; env->cnst_pos = i;
...@@ -470,23 +432,17 @@ static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump, ...@@ -470,23 +432,17 @@ static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump,
static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump, static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
ir_node *value) ir_node *value)
{ {
ir_node *block = get_nodes_block(jump); if (irn_visited_else_mark(value))
if (irn_visited_else_mark(value)) {
return NULL; return NULL;
}
ir_node *block = get_nodes_block(jump);
if (is_Const_or_Confirm(value)) { if (is_Const_or_Confirm(value)) {
ir_tarval *tv = get_Const_or_Confirm_tarval(value); ir_tarval *tv = get_Const_or_Confirm_tarval(value);
if (tv != env->tv) if (tv != env->tv)
return NULL; return NULL;
DB(( DB((dbg, LEVEL_1, "> Found jump threading candidate %+F->%+F\n",
dbg, LEVEL_1, block, env->true_block));
"> Found jump threading candidate %+F->%+F\n",
block, env->true_block
));
/* adjust true_block to point directly towards our jump */ /* adjust true_block to point directly towards our jump */
add_pred(env->true_block, jump); add_pred(env->true_block, jump);
...@@ -495,29 +451,22 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump, ...@@ -495,29 +451,22 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
/* we need a bigger visited nr when going back */ /* we need a bigger visited nr when going back */
env->visited_nr++; env->visited_nr++;
return block; return block;
} }
if (is_Phi(value)) { if (is_Phi(value)) {
int i, arity;
/* the Phi has to be in the same Block as the Jmp */ /* the Phi has to be in the same Block as the Jmp */
if (get_nodes_block(value) != block) if (get_nodes_block(value) != block)
return NULL; return NULL;
arity = get_irn_arity(value); for (int i = 0, arity = get_irn_arity(value); i < arity; ++i) {
for (i = 0; i < arity; ++i) { ir_node *phi_pred = get_Phi_pred(value, i);
ir_node *copy_block; ir_node *cfgpred = get_Block_cfgpred(block, i);
ir_node *phi_pred = get_Phi_pred(value, i); ir_node *copy_block = find_candidate(env, cfgpred, phi_pred);
ir_node *cfgpred = get_Block_cfgpred(block, i);
copy_block = find_candidate(env, cfgpred, phi_pred);
if (copy_block == NULL) if (copy_block == NULL)
continue; continue;
/* copy duplicated nodes in copy_block and fix SSA */ /* copy duplicated nodes in copy_block and fix SSA */
copy_and_fix(env, block, copy_block, i); copy_and_fix(env, block, copy_block, i);
if (copy_block == get_nodes_block(cfgpred)) { if (copy_block == get_nodes_block(cfgpred)) {
env->cnst_pred = block; env->cnst_pred = block;
env->cnst_pos = i; env->cnst_pos = i;
...@@ -550,15 +499,13 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump, ...@@ -550,15 +499,13 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
return NULL; return NULL;
/* negate condition when we're looking for the false block */ /* negate condition when we're looking for the false block */
if (env->tv == tarval_b_false) { if (env->tv == tarval_b_false)
relation = get_negated_relation(relation); relation = get_negated_relation(relation);
}
/* (recursively) look if a pred of a Phi is a constant or a Confirm */ /* (recursively) look if a pred of a Phi is a constant or a Confirm */
env->cmp = cmp; env->cmp = cmp;
env->relation = relation; env->relation = relation;
env->cnst = right;