Commit 9f01c9e7 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

ia32: Clean up and simplify remat_simplifier().

parent a6a3ed14
...@@ -597,94 +597,68 @@ static bool ia32_try_replace_flags(ir_node *consumers, ir_node *flags, ir_node * ...@@ -597,94 +597,68 @@ static bool ia32_try_replace_flags(ir_node *consumers, ir_node *flags, ir_node *
static void remat_simplifier(ir_node *node, void *env) static void remat_simplifier(ir_node *node, void *env)
{ {
(void)env; (void)env;
const arch_register_t *flags_reg = &(ia32_reg_classes[CLASS_ia32_flags].regs[0]);
/* A Sub with unused result is a Cmp. */ /* A Sub with unused result is a Cmp. */
if (is_ia32_Sub(node) && get_irn_mode(node) == mode_T) { if (is_ia32_Sub(node) && get_irn_mode(node) == mode_T) {
bool has_res_users = false; ir_node *projs[] = { [pn_ia32_Sub_M] = NULL };
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) { foreach_out_edge(node, out) {
ir_node *proj = get_edge_src_irn(out); ir_node *const proj = get_edge_src_irn(out);
ir_mode *proj_mode = get_irn_mode(proj); unsigned const num = get_Proj_num(proj);
if (proj_mode == ia32_mode_flags) { assert(num < ARRAY_SIZE(projs));
foreach_out_edge(proj, out2) { assert(!projs[num] && "duplicate Proj");
ir_node *user = get_edge_src_irn(out2); projs[num] = proj;
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));
}
} else {
panic("unexpected mode for %+F", proj);
}
} }
if (!has_res_users) { ir_node *res_keep = NULL;
ir_node *cmp = new_bd_ia32_Cmp( ir_node *const sub_res = projs[pn_ia32_Sub_res];
get_irn_dbg_info(node), if (sub_res) {
get_nodes_block(node), foreach_out_edge(sub_res, out) {
get_irn_n(node, n_ia32_Sub_base), ir_node *const user = get_edge_src_irn(out);
get_irn_n(node, n_ia32_Sub_index), if (be_is_Keep(user)) {
get_irn_n(node, n_ia32_Sub_mem), assert(!res_keep && "Proj has two be_Keep");
get_irn_n(node, n_ia32_Sub_minuend), res_keep = user;
get_irn_n(node, n_ia32_Sub_subtrahend), } else {
false); return;
arch_set_irn_register(cmp, flags_reg);
ia32_copy_am_attrs(cmp, node);
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);
ir_node *const proj_M = be_new_Proj(cmp, 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);
} }
cmp = be_new_Proj(cmp, pn_ia32_Cmp_eflags);
} }
}
for (unsigned i = 0; i < ARR_LEN(flag_users); i++) { dbg_info *const dbgi = get_irn_dbg_info(node);
set_irn_n(flag_users[i], flag_users_pos[i], cmp); ir_node *const block = get_nodes_block(node);
ir_node *const base = get_irn_n(node, n_ia32_Sub_base);
ir_node *const idx = get_irn_n(node, n_ia32_Sub_index);
ir_node *const mem = get_irn_n(node, n_ia32_Sub_mem);
ir_node *const minu = get_irn_n(node, n_ia32_Sub_minuend);
ir_node *const subt = get_irn_n(node, n_ia32_Sub_subtrahend);
ir_node *cmp = new_bd_ia32_Cmp(dbgi, block, base, idx, mem, minu, subt, false);
arch_set_irn_register(cmp, &ia32_registers[REG_EFLAGS]);
ia32_copy_am_attrs(cmp, node);
sched_replace(node, cmp);
if (get_ia32_op_type(node) == ia32_AddrModeS) {
set_ia32_op_type(cmp, ia32_AddrModeS);
set_irn_mode(cmp, mode_T);
ir_node *const sub_mem = projs[pn_ia32_Sub_M];
if (sub_mem) {
ir_node *const proj_M = be_new_Proj(cmp, pn_ia32_Cmp_M);
exchange(sub_mem, proj_M);
} }
if (res_keep) { cmp = be_new_Proj(cmp, pn_ia32_Cmp_eflags);
sched_remove(res_keep); } else {
remove_keep_alive(res_keep); assert(get_ia32_op_type(node) == ia32_Normal);
kill_node(res_keep);
}
kill_node(node);
node = cmp;
} }
DEL_ARR_F(flag_users); exchange(projs[pn_ia32_Sub_flags], cmp);
DEL_ARR_F(flag_users_pos);
DEL_ARR_F(mem_users); if (res_keep) {
DEL_ARR_F(mem_users_pos); sched_remove(res_keep);
remove_keep_alive(res_keep);
kill_node(res_keep);
}
kill_node(node);
} }
} }
......
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