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;
static ir_node *ssa_second_def_block;
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 */
if (is_Bad(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,
return value;
}
irg = get_irn_irg(block);
ir_graph *irg = get_irn_irg(block);
assert(block != get_irg_start_block(irg));
/* 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) {
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);
mark_irn_visited(block);
return value;
}
/* create a new Phi */
ir_node **in = ALLOCAN(ir_node*, n_cfgpreds);
dummy = new_r_Dummy(irg, mode);
for (i = 0; i < n_cfgpreds; ++i)
ir_node **in = ALLOCAN(ir_node*, n_cfgpreds);
ir_node *dummy = new_r_Dummy(irg, mode);
for (int i = 0; i < n_cfgpreds; ++i)
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);
mark_irn_visited(block);
/* 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_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);
}
......@@ -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,
ir_node *second_block, ir_node *second_val)
{
ir_graph *irg;
ir_mode *mode;
/* no need to do anything */
if (orig_val == second_val)
return;
irg = get_irn_irg(orig_val);
ir_graph *irg = get_irn_irg(orig_val);
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);
mark_irn_visited(orig_block);
......@@ -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 */
foreach_out_edge_safe(orig_val, 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 */
if (is_End(user))
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)) {
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 {
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 */
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);
}
}
......@@ -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)
{
ir_graph *irg = get_irn_irg(block);
ir_node *in[1];
ir_node *new_block;
ir_node *new_jmp;
in[0] = get_Block_cfgpred(block, pos);
new_block = new_r_Block(irg, 1, in);
new_jmp = new_r_Jmp(new_block);
ir_graph *irg = get_irn_irg(block);
ir_node *in[] = { get_Block_cfgpred(block, pos) };
ir_node *new_block = new_r_Block(irg, ARRAY_SIZE(in), in);
ir_node *new_jmp = new_r_Jmp(new_block);
set_Block_cfgpred(block, pos, new_jmp);
}
typedef struct jumpthreading_env_t {
ir_node *true_block;
ir_node *cmp; /**< The Compare node that might be partial evaluated */
ir_relation relation; /**< The Compare mode of the Compare node. */
ir_node *cnst;
ir_tarval *tv;
ir_visited_t visited_nr;
ir_node *cnst_pred; /**< the block before the constant */
int cnst_pos; /**< the pos to the constant block (needed to
kill that edge later) */
ir_node *true_block;
ir_node *cmp; /**< The Compare node that might be partial
evaluated */
ir_relation relation; /**< The Compare mode of the Compare node. */
ir_node *cnst;
ir_tarval *tv;
ir_visited_t visited_nr;
ir_node *cnst_pred; /**< the block before the constant */
int cnst_pos; /**< the pos to the constant block (needed to
kill that edge later) */
} jumpthreading_env_t;
static ir_node *copy_and_fix_node(const jumpthreading_env_t *env,
ir_node *block, ir_node *copy_block, int j,
ir_node *node)
{
int i, arity;
ir_node *copy;
/* we can evaluate Phis right now, all other nodes get copied */
ir_node *copy;
if (is_Phi(node)) {
copy = get_Phi_pred(node, j);
/* we might have to evaluate a Phi-cascade */
......@@ -221,17 +207,14 @@ static ir_node *copy_and_fix_node(const jumpthreading_env_t *env,
} else {
copy = exact_copy(node);
set_nodes_block(copy, copy_block);
assert(get_irn_mode(copy) != mode_X);
arity = get_irn_arity(copy);
for (i = 0; i < arity; ++i) {
ir_node *pred = get_irn_n(copy, i);
ir_node *new_pred;
for (int i = 0, arity = get_irn_arity(copy); i < arity; ++i) {
ir_node *pred = get_irn_n(copy, i);
if (get_nodes_block(pred) != block)
continue;
ir_node *new_pred;
if (get_irn_visited(pred) >= env->visited_nr) {
new_pred = (ir_node*)get_irn_link(pred);
} else {
......@@ -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 */
foreach_out_edge(block, edge) {
ir_node *node = get_edge_src_irn(edge);
ir_node *copy;
ir_mode *mode;
if (is_End(node)) {
/* 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);
continue;
}
/* 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))
continue;
#ifdef AVOID_PHIB
......@@ -287,14 +266,13 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
cmp_copy = exact_copy(pred);
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);
}
continue;
}
#endif
copy = copy_and_fix_node(env, block, copy_block, j, node);
ir_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
* recursive find_phi_with_const() call */
......@@ -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) */
foreach_out_edge(block, edge) {
ir_node *node = get_edge_src_irn(edge);
ir_node *copy_node;
ir_mode *mode;
mode = get_irn_mode(node);
ir_mode *mode = get_irn_mode(node);
if (mode == mode_X || is_Cond(node) || is_Switch(node))
continue;
#ifdef AVOID_PHIB
......@@ -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));
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);
}
......@@ -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!
* 1: true, 0: false, -1: can't evaluate
* Returns whether the cmp evaluates to true or false, or can't be evaluated!
*
* @param relation the compare mode of the Compare
* @param tv_left the left 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,
ir_tarval *tv_right)
......@@ -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!
* 1: true, 0: false, -1: can't evaluate
* Returns whether the cmp evaluates to true or false, or can't be evaluated!
*
* @param env the environment
* @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)
{
if (is_Const(cand)) {
ir_tarval *tv_cand = get_Const_tarval(cand);
ir_tarval *tv_cmp = get_Const_tarval(env->cnst);
return eval_cmp_tv(env->relation, tv_cand, tv_cmp);
} else { /* a Confirm */
ir_tarval *res = computed_value_Cmp_Confirm(env->cmp, cand, env->cnst, env->relation);
} else {
assert(is_Confirm(cand));
ir_tarval *res = computed_value_Cmp_Confirm(env->cmp, cand, env->cnst,
env->relation);
if (res == tarval_bad)
return -1;
return res == tarval_b_true;
......@@ -386,7 +361,7 @@ static int eval_cmp(jumpthreading_env_t *env, ir_node *cand)
/**
* 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))
node = get_Confirm_bound(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)
{
if (is_Confirm(node)) {
if (get_Confirm_bound(node))
node = get_Confirm_bound(node);
}
if (is_Confirm(node))
node = get_Confirm_bound(node);
return get_Const_tarval(node);
}
static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump,
ir_node *value)
{
ir_node *block = get_nodes_block(jump);
if (irn_visited_else_mark(value))
return NULL;
ir_node *block = get_nodes_block(jump);
if (is_Const_or_Confirm(value)) {
if (eval_cmp(env, value) <= 0)
return NULL;
DB((
dbg, LEVEL_1,
"> Found jump threading candidate %+F->%+F\n",
block, env->true_block
));
DB((dbg, LEVEL_1, "> Found jump threading candidate %+F->%+F\n",
block, env->true_block));
/* adjust true_block to point directly towards our 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,
/* we need a bigger visited nr when going back */
env->visited_nr++;
return block;
}
if (is_Phi(value)) {
int i, arity;
/* the Phi has to be in the same Block as the Jmp */
if (get_nodes_block(value) != block)
return NULL;
arity = get_irn_arity(value);
for (i = 0; i < arity; ++i) {
ir_node *copy_block;
ir_node *phi_pred = get_Phi_pred(value, i);
ir_node *cfgpred = get_Block_cfgpred(block, i);
copy_block = find_const_or_confirm(env, cfgpred, phi_pred);
for (int i = 0, arity = get_irn_arity(value); i < arity; ++i) {
ir_node *phi_pred = get_Phi_pred(value, i);
ir_node *cfgpred = get_Block_cfgpred(block, i);
ir_node *copy_block = find_const_or_confirm(env, cfgpred, phi_pred);
if (copy_block == NULL)
continue;
/* copy duplicated nodes in copy_block and fix SSA */
copy_and_fix(env, block, copy_block, i);
if (copy_block == get_nodes_block(cfgpred)) {
env->cnst_pred = block;
env->cnst_pos = i;
......@@ -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,
ir_node *value)
{
ir_node *block = get_nodes_block(jump);
if (irn_visited_else_mark(value)) {
if (irn_visited_else_mark(value))
return NULL;
}
ir_node *block = get_nodes_block(jump);
if (is_Const_or_Confirm(value)) {
ir_tarval *tv = get_Const_or_Confirm_tarval(value);
if (tv != env->tv)
return NULL;
DB((
dbg, LEVEL_1,
"> Found jump threading candidate %+F->%+F\n",
block, env->true_block
));
DB((dbg, LEVEL_1, "> Found jump threading candidate %+F->%+F\n",
block, env->true_block));
/* adjust true_block to point directly towards our jump */
add_pred(env->true_block, 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 */
env->visited_nr++;
return block;
}
if (is_Phi(value)) {
int i, arity;
/* the Phi has to be in the same Block as the Jmp */
if (get_nodes_block(value) != block)
return NULL;
arity = get_irn_arity(value);
for (i = 0; i < arity; ++i) {
ir_node *copy_block;
ir_node *phi_pred = get_Phi_pred(value, i);
ir_node *cfgpred = get_Block_cfgpred(block, i);
copy_block = find_candidate(env, cfgpred, phi_pred);
for (int i = 0, arity = get_irn_arity(value); i < arity; ++i) {
ir_node *phi_pred = get_Phi_pred(value, i);
ir_node *cfgpred = get_Block_cfgpred(block, i);
ir_node *copy_block = find_candidate(env, cfgpred, phi_pred);
if (copy_block == NULL)
continue;
/* copy duplicated nodes in copy_block and fix SSA */
copy_and_fix(env, block, copy_block, i);
if (copy_block == get_nodes_block(cfgpred)) {
env->cnst_pred = block;
env->cnst_pos = i;
......@@ -550,15 +499,13 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
return NULL;
/* 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);
}
/* (recursively) look if a pred of a Phi is a constant or a Confirm */
env->cmp = cmp;
env->relation = relation;
env->cnst = right;
return find_const_or_confirm(env, jump, left);
}
......@@ -580,34 +527,24 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
*/
static void thread_jumps(ir_node* block, void* data)
{
jumpthreading_env_t env;
bool *changed = (bool*)data;
ir_node *selector;
ir_node *projx;
ir_node *cond;
ir_node *copy_block;
int selector_evaluated;
ir_graph *irg;
ir_node *badX;
int cnst_pos;
/* we do not deal with Phis, so restrict this to exactly one cfgpred */
if (get_Block_n_cfgpreds(block) != 1)
return;
projx = get_Block_cfgpred(block, 0);
ir_node *projx = get_Block_cfgpred(block, 0);
if (!is_Proj(projx))
return;
assert(get_irn_mode(projx) == mode_X);
cond = get_Proj_pred(projx);
ir_node *cond = get_Proj_pred(projx);
/* TODO handle switch Conds */
if (!is_Cond(cond))
return;
/* handle cases that can be immediately evaluated */
selector = get_Cond_selector(cond);
selector_evaluated = -1;
ir_node *selector = get_Cond_selector(cond);
int selector_evaluated = -1;
if (is_Cmp(selector)) {
ir_node *left = get_Cmp_left(selector);
ir_node *right = get_Cmp_right(selector);
......@@ -628,6 +565,7 @@ static void thread_jumps(ir_node* block, void* data)
}
}
jumpthreading_env_t env;
env.cnst_pred = NULL;
if (get_Proj_proj(projx) == pn_Cond_false) {
env.tv = tarval_b_false;
......@@ -654,11 +592,11 @@ static void thread_jumps(ir_node* block, void* data)
/* (recursively) look if a pred of a Phi is a constant or a Confirm */
env.true_block = block;
irg = get_irn_irg(block);
ir_graph *irg = get_irn_irg(block);
inc_irg_visited(irg);
env.visited_nr = get_irg_visited(irg);
copy_block = find_candidate(&env, projx, selector);
ir_node *copy_block = find_candidate(&env, projx, selector);
if (copy_block == NULL)
return;
......@@ -669,8 +607,8 @@ static void thread_jumps(ir_node* block, void* data)
/* 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 */
badX = new_r_Bad(irg, mode_X);
cnst_pos = env.cnst_pos;
ir_node *badX = new_r_Bad(irg, mode_X);
int cnst_pos = env.cnst_pos;
/* shorten Phis */
foreach_out_edge_safe(env.cnst_pred, edge) {
......@@ -690,9 +628,6 @@ static void thread_jumps(ir_node* block, void* data)
void opt_jumpthreading(ir_graph* irg)
{
bool changed;
bool rerun;
assure_irg_properties(irg,
IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE
| IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES
......@@ -704,7 +639,8 @@ void opt_jumpthreading(ir_graph* irg)
ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_IRN_VISITED);
changed = false;
bool changed = false;
bool rerun;
do {
rerun = false;
irg_block_walk_graph(irg, thread_jumps, NULL, &rerun);
......
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