From f56ec028e3585aa134de4c4119a52b9a88de56fe Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Mon, 11 Jun 2007 23:01:50 +0000 Subject: [PATCH] fix bad proj optimisation, fix loads missing the result proj [r14421] --- ir/be/ia32/ia32_optimize.c | 25 ++++++++++++++++++++++++- ir/be/ia32/ia32_spec.pl | 2 ++ ir/be/ia32/ia32_transform.c | 31 +++++++++++++++++-------------- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index 600fb26f6..fb72b6e8d 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -1253,6 +1253,23 @@ static void optimize_load_conv(ia32_code_gen_t *cg, ir_node *node) if(get_mode_size_bits(conv_mode) < get_mode_size_bits(load_mode)) return; + if(get_mode_sign(conv_mode) != get_mode_sign(load_mode)) { + /* change the load if it has only 1 user */ + if(get_irn_n_edges(pred) == 1) { + ir_mode *newmode; + if(get_mode_sign(conv_mode)) { + newmode = find_signed_mode(load_mode); + } else { + newmode = find_unsigned_mode(load_mode); + } + assert(newmode != NULL); + set_ia32_ls_mode(predpred, newmode); + } else { + /* otherwise we have to keep the conv */ + return; + } + } + /* kill the conv */ exchange(node, pred); } @@ -1266,7 +1283,8 @@ static void optimize_conv_conv(ia32_code_gen_t *cg, ir_node *node) if (!is_ia32_Conv_I2I(node) && !is_ia32_Conv_I2I8Bit(node)) return; - pred = get_irn_n(node, 2); + assert(n_ia32_Conv_I2I_val == n_ia32_Conv_I2I8Bit_val); + pred = get_irn_n(node, n_ia32_Conv_I2I_val); if(!is_ia32_Conv_I2I(pred) && !is_ia32_Conv_I2I8Bit(pred)) return; @@ -1277,6 +1295,11 @@ static void optimize_conv_conv(ia32_code_gen_t *cg, ir_node *node) if(get_mode_size_bits(conv_mode) < get_mode_size_bits(pred_mode)) return; + /* we can't eliminate an upconv signed->unsigned */ + if (get_mode_size_bits(conv_mode) != get_mode_size_bits(pred_mode) && + !get_mode_sign(conv_mode) && get_mode_sign(pred_mode)) + return; + /* kill the conv */ exchange(node, pred); } diff --git a/ir/be/ia32/ia32_spec.pl b/ir/be/ia32/ia32_spec.pl index b1d0af6e8..9cc0454fe 100644 --- a/ir/be/ia32/ia32_spec.pl +++ b/ir/be/ia32/ia32_spec.pl @@ -1273,12 +1273,14 @@ CopyB_i => { Conv_I2I => { reg_req => { in => [ "gp", "gp", "gp", "none" ], out => [ "in_r3", "none" ] }, units => [ "GP" ], + ins => [ "base", "index", "val", "mem" ], mode => $mode_gp, modified_flags => $status_flags }, Conv_I2I8Bit => { reg_req => { in => [ "gp", "gp", "eax ebx ecx edx", "none" ], out => [ "in_r3", "none" ] }, + ins => [ "base", "index", "val", "mem" ], units => [ "GP" ], mode => $mode_gp, modified_flags => $status_flags diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index 1bf0084c3..a30b333aa 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -1610,6 +1610,7 @@ static ir_node *gen_Load(ir_node *node) { dbg_info *dbgi = get_irn_dbg_info(node); ir_node *noreg = ia32_new_NoReg_gp(env.cg); ir_mode *mode = get_Load_mode(node); + ir_mode *res_mode; ir_node *lptr = new_ptr; int is_imm = 0; ir_node *new_op; @@ -1618,17 +1619,6 @@ static ir_node *gen_Load(ir_node *node) { ia32_collect_Projs(node, projs, pn_Load_max); - /* - check for special case: the loaded value might not be used (optimized, - volatile, ...) we add a Proj + Keep for volatile loads and ignore all - other cases - */ - if (! be_get_Proj_for_pn(node, pn_Load_res) && get_Load_volatility(node) == volatility_is_volatile) { - /* add a result proj and a Keep to produce a pseudo use */ - ir_node *proj = new_r_Proj(irg, block, node, mode_Iu, pn_ia32_Load_res); - be_new_Keep(arch_get_irn_reg_class(env.cg->arch_env, proj, -1), irg, block, 1, &proj); - } - /* address might be a constant (symconst or absolute address) */ if (is_ia32_Const(new_ptr)) { lptr = noreg; @@ -1638,12 +1628,25 @@ static ir_node *gen_Load(ir_node *node) { if (mode_is_float(mode)) { FP_USED(env.cg); if (USE_SSE2(env.cg)) { - new_op = new_rd_ia32_xLoad(dbgi, irg, block, lptr, noreg, new_mem); + new_op = new_rd_ia32_xLoad(dbgi, irg, block, lptr, noreg, new_mem); + res_mode = mode_xmm; } else { - new_op = new_rd_ia32_vfld(dbgi, irg, block, lptr, noreg, new_mem); + new_op = new_rd_ia32_vfld(dbgi, irg, block, lptr, noreg, new_mem); + res_mode = mode_vfp; } } else { - new_op = new_rd_ia32_Load(dbgi, irg, block, lptr, noreg, new_mem); + new_op = new_rd_ia32_Load(dbgi, irg, block, lptr, noreg, new_mem); + res_mode = mode_Iu; + } + + /* + check for special case: the loaded value might not be used + */ + if (be_get_Proj_for_pn(node, pn_Load_res) == NULL) { + /* add a result proj and a Keep to produce a pseudo use */ + ir_node *proj = new_r_Proj(irg, block, new_op, mode_Iu, + pn_ia32_Load_res); + be_new_Keep(arch_get_irn_reg_class(env.cg->arch_env, proj, -1), irg, block, 1, &proj); } /* base is a constant address */ -- 2.20.1