From 53ad01abe02a0eefd8744cf55e150fa335df2e4d Mon Sep 17 00:00:00 2001 From: Christoph Mallon Date: Tue, 12 Aug 2008 20:56:38 +0000 Subject: [PATCH] Defer decision whether to create Test(x, x) instead of Cmp(x, 0) until peephole optimisation. This improves the code when Cmp(AM, 0) is undone by the flags repair phase. [r21134] --- ir/be/ia32/ia32_optimize.c | 68 ++++++++++++++++++++++++++++--- ir/be/ia32/ia32_transform.c | 79 +++++++++++-------------------------- 2 files changed, 86 insertions(+), 61 deletions(-) diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index fc08bf764..d42eb0169 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -160,6 +160,62 @@ static ir_node *turn_into_mode_t(ir_node *node) return new_node; } +/** + * Replace Cmp(x, 0) by a Test(x, x) + */ +static void peephole_ia32_Cmp(ir_node *const node) +{ + ir_node *right; + ia32_immediate_attr_t const *imm; + dbg_info *dbgi; + ir_graph *irg; + ir_node *block; + ir_node *noreg; + ir_node *nomem; + ir_node *op; + ia32_attr_t const *attr; + int ins_permuted; + int cmp_unsigned; + ir_node *test; + arch_register_t const *reg; + + if (get_ia32_op_type(node) != ia32_Normal) + return; + + right = get_irn_n(node, n_ia32_Cmp_right); + if (!is_ia32_Immediate(right)) + return; + + imm = get_ia32_immediate_attr_const(right); + if (imm->symconst != NULL || imm->offset != 0) + return; + + dbgi = get_irn_dbg_info(node); + irg = current_ir_graph; + block = get_nodes_block(node); + noreg = ia32_new_NoReg_gp(cg); + nomem = get_irg_no_mem(irg); + op = get_irn_n(node, n_ia32_Cmp_left); + attr = get_irn_generic_attr(node); + ins_permuted = attr->data.ins_permuted; + cmp_unsigned = attr->data.cmp_unsigned; + + if (is_ia32_Cmp(node)) { + test = new_rd_ia32_Test(dbgi, irg, block, noreg, noreg, nomem, + op, op, ins_permuted, cmp_unsigned); + } else { + test = new_rd_ia32_Test8Bit(dbgi, irg, block, noreg, noreg, nomem, + op, op, ins_permuted, cmp_unsigned); + } + set_ia32_ls_mode(test, get_ia32_ls_mode(node)); + + reg = arch_get_irn_register(arch_env, node); + arch_set_irn_register(arch_env, test, reg); + + sched_add_before(node, test); + be_peephole_exchange(node, test); +} + /** * Peephole optimization for Test instructions. * We can remove the Test, if a zero flags was produced which is still @@ -1046,12 +1102,14 @@ void ia32_peephole_optimization(ia32_code_gen_t *new_cg) /* register peephole optimisations */ clear_irp_opcodes_generic_func(); - register_peephole_optimisation(op_ia32_Const, peephole_ia32_Const); - register_peephole_optimisation(op_be_IncSP, peephole_be_IncSP); - register_peephole_optimisation(op_ia32_Lea, peephole_ia32_Lea); - register_peephole_optimisation(op_ia32_Test, peephole_ia32_Test); + register_peephole_optimisation(op_ia32_Const, peephole_ia32_Const); + register_peephole_optimisation(op_be_IncSP, peephole_be_IncSP); + register_peephole_optimisation(op_ia32_Lea, peephole_ia32_Lea); + register_peephole_optimisation(op_ia32_Cmp, peephole_ia32_Cmp); + register_peephole_optimisation(op_ia32_Cmp8Bit, peephole_ia32_Cmp); + register_peephole_optimisation(op_ia32_Test, peephole_ia32_Test); register_peephole_optimisation(op_ia32_Test8Bit, peephole_ia32_Test); - register_peephole_optimisation(op_be_Return, peephole_ia32_Return); + register_peephole_optimisation(op_be_Return, peephole_ia32_Return); if (! ia32_cg_config.use_imul_mem_imm32) register_peephole_optimisation(op_ia32_IMul, peephole_ia32_Imul_split); if (ia32_cg_config.use_pxor) diff --git a/ir/be/ia32/ia32_transform.c b/ir/be/ia32/ia32_transform.c index f4301dd1b..52d39471a 100644 --- a/ir/be/ia32/ia32_transform.c +++ b/ir/be/ia32/ia32_transform.c @@ -2723,64 +2723,31 @@ static ir_node *gen_Cmp(ir_node *node) assert(ia32_mode_needs_gp_reg(cmp_mode)); - /* we prefer the Test instruction where possible except cases where - * we can use SourceAM */ + /* Prefer the Test instruction, when encountering (x & y) ==/!= 0 */ cmp_unsigned = !mode_is_signed(cmp_mode); - if (is_Const_0(right)) { - if (is_And(left) && - get_irn_n_edges(left) == 1 && - can_fold_test_and(node)) { - /* Test(and_left, and_right) */ - ir_node *and_left = get_And_left(left); - ir_node *and_right = get_And_right(left); - ir_mode *mode = get_irn_mode(and_left); - - match_arguments(&am, block, and_left, and_right, NULL, - match_commutative | - match_am | match_8bit_am | match_16bit_am | - match_am_and_immediates | match_immediate | - match_8bit | match_16bit); - if (get_mode_size_bits(mode) == 8) { - new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base, - addr->index, addr->mem, am.new_op1, - am.new_op2, am.ins_permuted, - cmp_unsigned); - } else { - new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base, - addr->index, addr->mem, am.new_op1, - am.new_op2, am.ins_permuted, cmp_unsigned); - } + if (is_Const_0(right) && + is_And(left) && + get_irn_n_edges(left) == 1 && + can_fold_test_and(node)) { + /* Test(and_left, and_right) */ + ir_node *and_left = get_And_left(left); + ir_node *and_right = get_And_right(left); + ir_mode *mode = get_irn_mode(and_left); + + match_arguments(&am, block, and_left, and_right, NULL, + match_commutative | + match_am | match_8bit_am | match_16bit_am | + match_am_and_immediates | match_immediate | + match_8bit | match_16bit); + if (get_mode_size_bits(mode) == 8) { + new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base, + addr->index, addr->mem, am.new_op1, + am.new_op2, am.ins_permuted, + cmp_unsigned); } else { - match_arguments(&am, block, NULL, left, NULL, - match_am | match_8bit_am | match_16bit_am | - match_8bit | match_16bit); - if (am.op_type == ia32_AddrModeS) { - /* Cmp(AM, 0) */ - ir_node *imm_zero = try_create_Immediate(right, 0); - if (get_mode_size_bits(cmp_mode) == 8) { - new_node = new_rd_ia32_Cmp8Bit(dbgi, irg, new_block, addr->base, - addr->index, addr->mem, am.new_op2, - imm_zero, am.ins_permuted, - cmp_unsigned); - } else { - new_node = new_rd_ia32_Cmp(dbgi, irg, new_block, addr->base, - addr->index, addr->mem, am.new_op2, - imm_zero, am.ins_permuted, cmp_unsigned); - } - } else { - /* Test(left, left) */ - if (get_mode_size_bits(cmp_mode) == 8) { - new_node = new_rd_ia32_Test8Bit(dbgi, irg, new_block, addr->base, - addr->index, addr->mem, am.new_op2, - am.new_op2, am.ins_permuted, - cmp_unsigned); - } else { - new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base, - addr->index, addr->mem, am.new_op2, - am.new_op2, am.ins_permuted, - cmp_unsigned); - } - } + new_node = new_rd_ia32_Test(dbgi, irg, new_block, addr->base, + addr->index, addr->mem, am.new_op1, + am.new_op2, am.ins_permuted, cmp_unsigned); } } else { /* Cmp(left, right) */ -- 2.20.1