From 1b63e1946e0e454a59ddc6eb7df8fe3bc372a10e Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Thu, 19 Aug 2010 15:56:42 +0000 Subject: [PATCH] sparc: new patterns to match comparisons of bitoperations with zero [r27959] --- ir/be/sparc/sparc_spec.pl | 42 ++++++++++++ ir/be/sparc/sparc_transform.c | 122 ++++++++++++++++++---------------- 2 files changed, 107 insertions(+), 57 deletions(-) diff --git a/ir/be/sparc/sparc_spec.pl b/ir/be/sparc/sparc_spec.pl index 53013fce2..ccf0bf215 100644 --- a/ir/be/sparc/sparc_spec.pl +++ b/ir/be/sparc/sparc_spec.pl @@ -460,6 +460,13 @@ And => { constructors => \%binop_operand_constructors, }, +AndCCZero => { + irn_flags => [ "rematerializable", "modifies_flags" ], + emit => '. and %S1, %R2I, %%g0', + mode => $mode_flags, + constructors => \%binopcczero_operand_constructors, +}, + AndN => { irn_flags => [ "rematerializable" ], mode => $mode_gp, @@ -467,6 +474,13 @@ AndN => { constructors => \%binop_operand_constructors, }, +AndNCCZero => { + irn_flags => [ "rematerializable", "modifies_flags" ], + emit => '. andn %S1, %R2I, %%g0', + mode => $mode_flags, + constructors => \%binopcczero_operand_constructors, +}, + Or => { irn_flags => [ "rematerializable" ], mode => $mode_gp, @@ -474,6 +488,13 @@ Or => { constructors => \%binop_operand_constructors, }, +OrCCZero => { + irn_flags => [ "rematerializable", "modifies_flags" ], + emit => '. or %S1, %R2I, %%g0', + mode => $mode_flags, + constructors => \%binopcczero_operand_constructors, +}, + OrN => { irn_flags => [ "rematerializable" ], mode => $mode_gp, @@ -481,6 +502,13 @@ OrN => { constructors => \%binop_operand_constructors, }, +OrNCCZero => { + irn_flags => [ "rematerializable", "modifies_flags" ], + emit => '. orn %S1, %R2I, %%g0', + mode => $mode_flags, + constructors => \%binopcczero_operand_constructors, +}, + Xor => { irn_flags => [ "rematerializable" ], mode => $mode_gp, @@ -488,6 +516,13 @@ Xor => { constructors => \%binop_operand_constructors, }, +XorCCZero => { + irn_flags => [ "rematerializable", "modifies_flags" ], + emit => '. xor %S1, %R2I, %%g0', + mode => $mode_flags, + constructors => \%binopcczero_operand_constructors, +}, + XNor => { irn_flags => [ "rematerializable" ], mode => $mode_gp, @@ -495,6 +530,13 @@ XNor => { constructors => \%binop_operand_constructors, }, +XNorCCZero => { + irn_flags => [ "rematerializable", "modifies_flags" ], + emit => '. xnor %S1, %R2I, %%g0', + mode => $mode_flags, + constructors => \%binopcczero_operand_constructors, +}, + Mul => { irn_flags => [ "rematerializable" ], mode => $mode_gp, diff --git a/ir/be/sparc/sparc_transform.c b/ir/be/sparc/sparc_transform.c index 0f726f4c8..5ae86ab68 100644 --- a/ir/be/sparc/sparc_transform.c +++ b/ir/be/sparc/sparc_transform.c @@ -715,72 +715,54 @@ static ir_node *gen_Not(ir_node *node) return new_bd_sparc_XNor_reg(dbgi, block, zero, new_op); } -static ir_node *gen_And(ir_node *node) +static ir_node *gen_helper_bitop(ir_node *node, + new_binop_reg_func new_reg, + new_binop_imm_func new_imm, + new_binop_reg_func new_not_reg, + new_binop_imm_func new_not_imm) { - ir_node *left = get_And_left(node); - ir_node *right = get_And_right(node); - - if (is_Not(right)) { - ir_node *not_op = get_Not_op(right); - return gen_helper_binop_args(node, left, not_op, MATCH_MODE_NEUTRAL, - new_bd_sparc_AndN_reg, - new_bd_sparc_AndN_imm); + ir_node *op1 = get_binop_left(node); + ir_node *op2 = get_binop_right(node); + if (is_Not(op1)) { + return gen_helper_binop_args(node, get_Not_op(op1), op2, + MATCH_MODE_NEUTRAL, + new_not_reg, new_not_imm); } - if (is_Not(left)) { - ir_node *not_op = get_Not_op(left); - return gen_helper_binop_args(node, right, not_op, MATCH_MODE_NEUTRAL, - new_bd_sparc_AndN_reg, - new_bd_sparc_AndN_imm); + if (is_Not(op2)) { + return gen_helper_binop_args(node, op1, get_Not_op(op2), + MATCH_MODE_NEUTRAL, + new_not_reg, new_not_imm); } + return gen_helper_binop_args(node, op1, op2, + MATCH_MODE_NEUTRAL | MATCH_COMMUTATIVE, + new_reg, new_imm); +} - return gen_helper_binop(node, MATCH_COMMUTATIVE | MATCH_MODE_NEUTRAL, - new_bd_sparc_And_reg, new_bd_sparc_And_imm); +static ir_node *gen_And(ir_node *node) +{ + return gen_helper_bitop(node, + new_bd_sparc_And_reg, + new_bd_sparc_And_imm, + new_bd_sparc_AndN_reg, + new_bd_sparc_AndN_imm); } static ir_node *gen_Or(ir_node *node) { - ir_node *left = get_Or_left(node); - ir_node *right = get_Or_right(node); - - if (is_Not(right)) { - ir_node *not_op = get_Not_op(right); - return gen_helper_binop_args(node, left, not_op, MATCH_MODE_NEUTRAL, - new_bd_sparc_OrN_reg, - new_bd_sparc_OrN_imm); - } - if (is_Not(left)) { - ir_node *not_op = get_Not_op(left); - return gen_helper_binop_args(node, right, not_op, MATCH_MODE_NEUTRAL, - new_bd_sparc_OrN_reg, - new_bd_sparc_OrN_imm); - } - - return gen_helper_binop(node, MATCH_COMMUTATIVE | MATCH_MODE_NEUTRAL, - new_bd_sparc_Or_reg, new_bd_sparc_Or_imm); + return gen_helper_bitop(node, + new_bd_sparc_Or_reg, + new_bd_sparc_Or_imm, + new_bd_sparc_OrN_reg, + new_bd_sparc_OrN_imm); } static ir_node *gen_Eor(ir_node *node) { - ir_node *left = get_Eor_left(node); - ir_node *right = get_Eor_right(node); - - if (is_Not(right)) { - ir_node *not_op = get_Not_op(right); - return gen_helper_binop_args(node, left, not_op, - MATCH_COMMUTATIVE | MATCH_MODE_NEUTRAL, - new_bd_sparc_XNor_reg, - new_bd_sparc_XNor_imm); - } - if (is_Not(left)) { - ir_node *not_op = get_Not_op(left); - return gen_helper_binop_args(node, not_op, right, - MATCH_COMMUTATIVE | MATCH_MODE_NEUTRAL, - new_bd_sparc_XNor_reg, - new_bd_sparc_XNor_imm); - } - - return gen_helper_binop(node, MATCH_COMMUTATIVE | MATCH_MODE_NEUTRAL, - new_bd_sparc_Xor_reg, new_bd_sparc_Xor_imm); + return gen_helper_bitop(node, + new_bd_sparc_Xor_reg, + new_bd_sparc_Xor_imm, + new_bd_sparc_XNor_reg, + new_bd_sparc_XNor_imm); } static ir_node *gen_Shl(ir_node *node) @@ -1008,9 +990,9 @@ static ir_node *gen_Cond(ir_node *node) */ static ir_node *gen_Cmp(ir_node *node) { - ir_node *op1 = get_Cmp_left(node); - ir_node *op2 = get_Cmp_right(node); - ir_mode *cmp_mode = get_irn_mode(op1); + ir_node *op1 = get_Cmp_left(node); + ir_node *op2 = get_Cmp_right(node); + ir_mode *cmp_mode = get_irn_mode(op1); assert(get_irn_mode(op2) == cmp_mode); if (mode_is_float(cmp_mode)) { @@ -1029,6 +1011,32 @@ static ir_node *gen_Cmp(ir_node *node) } } + /* when we compare a bitop like and,or,... with 0 then we can directly use + * the bitopcc variant. + * Currently we only do this when we're the only user of the node... + */ + if (is_Const(op2) && is_Const_null(op2) && get_irn_n_edges(op1) == 1) { + if (is_And(op1)) { + return gen_helper_bitop(op1, + new_bd_sparc_AndCCZero_reg, + new_bd_sparc_AndCCZero_imm, + new_bd_sparc_AndNCCZero_reg, + new_bd_sparc_AndNCCZero_imm); + } else if (is_Or(op1)) { + return gen_helper_bitop(op1, + new_bd_sparc_OrCCZero_reg, + new_bd_sparc_OrCCZero_imm, + new_bd_sparc_OrNCCZero_reg, + new_bd_sparc_OrNCCZero_imm); + } else if (is_Eor(op1)) { + return gen_helper_bitop(op1, + new_bd_sparc_XorCCZero_reg, + new_bd_sparc_XorCCZero_imm, + new_bd_sparc_XNorCCZero_reg, + new_bd_sparc_XNorCCZero_imm); + } + } + /* integer compare */ return gen_helper_binop_args(node, op1, op2, MATCH_NONE, new_bd_sparc_Cmp_reg, new_bd_sparc_Cmp_imm); -- 2.20.1