Commit 17171ab3 authored by Andreas Fried's avatar Andreas Fried
Browse files

Use a node instead of a block walk for remat_simplifier.

parent e90d4a52
......@@ -680,104 +680,101 @@ static bool ia32_try_replace_flags(ir_node *consumers, ir_node *flags, ir_node *
return false;
}
static void remat_simplifier(ir_node *block, void *env)
static void remat_simplifier(ir_node *node, void *env)
{
(void)env;
const arch_register_t *flags_reg = &(ia32_reg_classes[CLASS_ia32_flags].regs[0]);
sched_foreach(block, node) {
/* A Sub with unused result is a Cmp. */
if (is_ia32_Sub(node) && get_irn_mode(node) == mode_T) {
bool has_res_users = false;
ir_node *res_keep = NULL;
ir_node **flag_users = NEW_ARR_F(ir_node*, 0);
int *flag_users_pos = NEW_ARR_F(int, 0);
ir_node **mem_users = NEW_ARR_F(ir_node*, 0);
int *mem_users_pos = NEW_ARR_F(int, 0);
foreach_out_edge(node, out) {
ir_node *proj = get_edge_src_irn(out);
ir_mode *proj_mode = get_irn_mode(proj);
if (proj_mode == ia32_mode_flags) {
foreach_out_edge(proj, out2) {
ir_node *user = get_edge_src_irn(out2);
ARR_APP1(ir_node*, flag_users, user);
ARR_APP1(int, flag_users_pos, get_edge_src_pos(out2));
}
} else if (proj_mode == ia32_mode_gp) {
foreach_out_edge(proj, out2) {
ir_node *user = get_edge_src_irn(out2);
if (!be_is_Keep(user)) {
has_res_users = true;
} else {
assert(res_keep == NULL && "Proj has two be_Keep");
res_keep = user;
}
}
} else if (proj_mode == mode_M) {
foreach_out_edge(proj, out2) {
ir_node *user = get_edge_src_irn(out2);
ARR_APP1(ir_node*, mem_users, user);
ARR_APP1(int, mem_users_pos, get_edge_src_pos(out2));
/* A Sub with unused result is a Cmp. */
if (is_ia32_Sub(node) && get_irn_mode(node) == mode_T) {
bool has_res_users = false;
ir_node *res_keep = NULL;
ir_node **flag_users = NEW_ARR_F(ir_node*, 0);
int *flag_users_pos = NEW_ARR_F(int, 0);
ir_node **mem_users = NEW_ARR_F(ir_node*, 0);
int *mem_users_pos = NEW_ARR_F(int, 0);
foreach_out_edge(node, out) {
ir_node *proj = get_edge_src_irn(out);
ir_mode *proj_mode = get_irn_mode(proj);
if (proj_mode == ia32_mode_flags) {
foreach_out_edge(proj, out2) {
ir_node *user = get_edge_src_irn(out2);
ARR_APP1(ir_node*, flag_users, user);
ARR_APP1(int, flag_users_pos, get_edge_src_pos(out2));
}
} else if (proj_mode == ia32_mode_gp) {
foreach_out_edge(proj, out2) {
ir_node *user = get_edge_src_irn(out2);
if (!be_is_Keep(user)) {
has_res_users = true;
} else {
assert(res_keep == NULL && "Proj has two be_Keep");
res_keep = user;
}
}
}
if (!has_res_users) {
ir_node *cmp = new_bd_ia32_Cmp(
get_irn_dbg_info(node),
get_nodes_block(node),
get_irn_n(node, n_ia32_Sub_base),
get_irn_n(node, n_ia32_Sub_index),
get_irn_n(node, n_ia32_Sub_mem),
get_irn_n(node, n_ia32_Sub_minuend),
get_irn_n(node, n_ia32_Sub_subtrahend),
false);
arch_set_irn_register(cmp, flags_reg);
sched_replace(node, cmp);
if (get_ia32_op_type(node) == ia32_AddrModeD) {
panic("Unexpected DestAM node %+F", node);
} else if (proj_mode == mode_M) {
foreach_out_edge(proj, out2) {
ir_node *user = get_edge_src_irn(out2);
ARR_APP1(ir_node*, mem_users, user);
ARR_APP1(int, mem_users_pos, get_edge_src_pos(out2));
}
if (get_ia32_op_type(node) == ia32_AddrModeS) {
set_ia32_op_type(cmp, ia32_AddrModeS);
set_irn_mode(cmp, mode_T);
}
}
ir_node *proj_M = new_r_Proj(cmp, mode_M, pn_ia32_Cmp_M);
for(unsigned i = 0; i < ARR_LEN(mem_users); i++) {
set_irn_n(mem_users[i], mem_users_pos[i], proj_M);
}
if (!has_res_users) {
ir_node *cmp = new_bd_ia32_Cmp(
get_irn_dbg_info(node),
get_nodes_block(node),
get_irn_n(node, n_ia32_Sub_base),
get_irn_n(node, n_ia32_Sub_index),
get_irn_n(node, n_ia32_Sub_mem),
get_irn_n(node, n_ia32_Sub_minuend),
get_irn_n(node, n_ia32_Sub_subtrahend),
false);
arch_set_irn_register(cmp, flags_reg);
sched_replace(node, cmp);
if (get_ia32_op_type(node) == ia32_AddrModeD) {
panic("Unexpected DestAM node %+F", node);
}
if (get_ia32_op_type(node) == ia32_AddrModeS) {
set_ia32_op_type(cmp, ia32_AddrModeS);
set_irn_mode(cmp, mode_T);
cmp = new_r_Proj(cmp, mode_M, pn_ia32_Cmp_eflags);
ir_node *proj_M = new_r_Proj(cmp, mode_M, pn_ia32_Cmp_M);
for(unsigned i = 0; i < ARR_LEN(mem_users); i++) {
set_irn_n(mem_users[i], mem_users_pos[i], proj_M);
}
for (unsigned i = 0; i < ARR_LEN(flag_users); i++) {
set_irn_n(flag_users[i], flag_users_pos[i], cmp);
}
cmp = new_r_Proj(cmp, mode_M, pn_ia32_Cmp_eflags);
}
if (res_keep) {
sched_remove(res_keep);
remove_keep_alive(res_keep);
kill_node(res_keep);
}
kill_node(node);
node = cmp;
for (unsigned i = 0; i < ARR_LEN(flag_users); i++) {
set_irn_n(flag_users[i], flag_users_pos[i], cmp);
}
DEL_ARR_F(flag_users);
DEL_ARR_F(flag_users_pos);
DEL_ARR_F(mem_users);
DEL_ARR_F(mem_users_pos);
if (res_keep) {
sched_remove(res_keep);
remove_keep_alive(res_keep);
kill_node(res_keep);
}
kill_node(node);
node = cmp;
}
}
remove_End_Bads_and_doublets(get_irg_end(get_irn_irg(block)));
DEL_ARR_F(flag_users);
DEL_ARR_F(flag_users_pos);
DEL_ARR_F(mem_users);
DEL_ARR_F(mem_users_pos);
}
}
static void simplify_remat_nodes(ir_graph *irg)
{
irg_block_walk_graph(irg, remat_simplifier, NULL, NULL);
irg_walk_graph(irg, remat_simplifier, NULL, NULL);
remove_End_Bads_and_doublets(get_irg_end(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