aboutsummaryrefslogtreecommitdiff
path: root/gcc/combine.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-08-30 11:08:44 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-08-30 11:08:44 +0000
commitc94843d2422bdf77e2f86fad0329838f36773b43 (patch)
tree8b8124bc4e42d00aabe44407a57a8b8faa945a60 /gcc/combine.c
parentb77d1a175f94eb49f62a02c4a54fe617e1cd3363 (diff)
downloadgcc-c94843d2422bdf77e2f86fad0329838f36773b43.zip
gcc-c94843d2422bdf77e2f86fad0329838f36773b43.tar.gz
gcc-c94843d2422bdf77e2f86fad0329838f36773b43.tar.bz2
[4/77] Add FOR_EACH iterators for modes
The new iterators are: - FOR_EACH_MODE_IN_CLASS: iterate over all the modes in a mode class. - FOR_EACH_MODE_FROM: iterate over all the modes in a class, starting at a given mode. - FOR_EACH_WIDER_MODE: iterate over all the modes in a class, starting at the next widest mode after a given mode. - FOR_EACH_2XWIDER_MODE: same, but considering only modes that are two times wider than the previous mode. - FOR_EACH_MODE_UNTIL: iterate over all the modes in a class until a given mode is reached. - FOR_EACH_MODE: iterate over all the modes in a class between two given modes, inclusive of the first but not the second. These help with the stronger type checking added by later patches, since every new mode will be in the same class as the previous one. 2017-08-30 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * machmode.h (mode_traits): New structure. (get_narrowest_mode): New function. (mode_iterator::start): Likewise. (mode_iterator::iterate_p): Likewise. (mode_iterator::get_wider): Likewise. (mode_iterator::get_known_wider): Likewise. (mode_iterator::get_2xwider): Likewise. (FOR_EACH_MODE_IN_CLASS): New mode iterator. (FOR_EACH_MODE): Likewise. (FOR_EACH_MODE_FROM): Likewise. (FOR_EACH_MODE_UNTIL): Likewise. (FOR_EACH_WIDER_MODE): Likewise. (FOR_EACH_2XWIDER_MODE): Likewise. * builtins.c (expand_builtin_strlen): Use new mode iterators. * combine.c (simplify_comparison): Likewise * config/i386/i386.c (type_natural_mode): Likewise. * cse.c (cse_insn): Likewise. * dse.c (find_shift_sequence): Likewise. * emit-rtl.c (init_derived_machine_modes): Likewise. (init_emit_once): Likewise. * explow.c (hard_function_value): Likewise. * expmed.c (extract_fixed_bit_field_1): Likewise. (extract_bit_field_1): Likewise. (expand_divmod): Likewise. (emit_store_flag_1): Likewise. * expr.c (init_expr_target): Likewise. (convert_move): Likewise. (alignment_for_piecewise_move): Likewise. (widest_int_mode_for_size): Likewise. (emit_block_move_via_movmem): Likewise. (copy_blkmode_to_reg): Likewise. (set_storage_via_setmem): Likewise. (compress_float_constant): Likewise. * omp-low.c (omp_clause_aligned_alignment): Likewise. * optabs-query.c (get_best_extraction_insn): Likewise. * optabs.c (expand_binop): Likewise. (expand_twoval_unop): Likewise. (expand_twoval_binop): Likewise. (widen_leading): Likewise. (widen_bswap): Likewise. (expand_parity): Likewise. (expand_unop): Likewise. (prepare_cmp_insn): Likewise. (prepare_float_lib_cmp): Likewise. (expand_float): Likewise. (expand_fix): Likewise. (expand_sfix_optab): Likewise. * postreload.c (move2add_use_add2_insn): Likewise. * reg-stack.c (reg_to_stack): Likewise. * reginfo.c (choose_hard_reg_mode): Likewise. * rtlanal.c (init_num_sign_bit_copies_in_rep): Likewise. * stor-layout.c (mode_for_size): Likewise. (smallest_mode_for_size): Likewise. (mode_for_vector): Likewise. (finish_bitfield_representative): Likewise. * tree-ssa-math-opts.c (target_supports_divmod_p): Likewise. * tree-vect-generic.c (type_for_widest_vector_mode): Likewise. * tree-vect-stmts.c (vectorizable_conversion): Likewise. * var-tracking.c (prepare_call_arguments): Likewise. gcc/ada/ * gcc-interface/misc.c (fp_prec_to_size): Use new mode iterators. (fp_size_to_prec): Likewise. gcc/c-family/ * c-common.c (c_common_fixed_point_type_for_size): Use new mode iterators. * c-cppbuiltin.c (c_cpp_builtins): Likewise. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r251455
Diffstat (limited to 'gcc/combine.c')
-rw-r--r--gcc/combine.c142
1 files changed, 73 insertions, 69 deletions
diff --git a/gcc/combine.c b/gcc/combine.c
index b34fb81..46212c5 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -11830,9 +11830,7 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
}
else if (c0 == c1)
- for (tmode = GET_CLASS_NARROWEST_MODE
- (GET_MODE_CLASS (GET_MODE (op0)));
- tmode != GET_MODE (op0); tmode = GET_MODE_WIDER_MODE (tmode))
+ FOR_EACH_MODE_UNTIL (tmode, GET_MODE (op0))
if ((unsigned HOST_WIDE_INT) c0 == GET_MODE_MASK (tmode))
{
op0 = gen_lowpart_or_truncate (tmode, inner_op0);
@@ -12704,75 +12702,81 @@ simplify_comparison (enum rtx_code code, rtx *pop0, rtx *pop1)
if (mode != VOIDmode && GET_MODE_CLASS (mode) == MODE_INT
&& GET_MODE_SIZE (mode) < UNITS_PER_WORD
&& ! have_insn_for (COMPARE, mode))
- for (tmode = GET_MODE_WIDER_MODE (mode);
- (tmode != VOIDmode && HWI_COMPUTABLE_MODE_P (tmode));
- tmode = GET_MODE_WIDER_MODE (tmode))
- if (have_insn_for (COMPARE, tmode))
- {
- int zero_extended;
-
- /* If this is a test for negative, we can make an explicit
- test of the sign bit. Test this first so we can use
- a paradoxical subreg to extend OP0. */
+ FOR_EACH_WIDER_MODE (tmode, mode)
+ {
+ if (!HWI_COMPUTABLE_MODE_P (tmode))
+ break;
+ if (have_insn_for (COMPARE, tmode))
+ {
+ int zero_extended;
- if (op1 == const0_rtx && (code == LT || code == GE)
- && HWI_COMPUTABLE_MODE_P (mode))
- {
- unsigned HOST_WIDE_INT sign
- = HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (mode) - 1);
- op0 = simplify_gen_binary (AND, tmode,
- gen_lowpart (tmode, op0),
- gen_int_mode (sign, tmode));
- code = (code == LT) ? NE : EQ;
- break;
- }
+ /* If this is a test for negative, we can make an explicit
+ test of the sign bit. Test this first so we can use
+ a paradoxical subreg to extend OP0. */
- /* If the only nonzero bits in OP0 and OP1 are those in the
- narrower mode and this is an equality or unsigned comparison,
- we can use the wider mode. Similarly for sign-extended
- values, in which case it is true for all comparisons. */
- zero_extended = ((code == EQ || code == NE
- || code == GEU || code == GTU
- || code == LEU || code == LTU)
- && (nonzero_bits (op0, tmode)
- & ~GET_MODE_MASK (mode)) == 0
- && ((CONST_INT_P (op1)
- || (nonzero_bits (op1, tmode)
- & ~GET_MODE_MASK (mode)) == 0)));
-
- if (zero_extended
- || ((num_sign_bit_copies (op0, tmode)
- > (unsigned int) (GET_MODE_PRECISION (tmode)
- - GET_MODE_PRECISION (mode)))
- && (num_sign_bit_copies (op1, tmode)
- > (unsigned int) (GET_MODE_PRECISION (tmode)
- - GET_MODE_PRECISION (mode)))))
- {
- /* If OP0 is an AND and we don't have an AND in MODE either,
- make a new AND in the proper mode. */
- if (GET_CODE (op0) == AND
- && !have_insn_for (AND, mode))
+ if (op1 == const0_rtx && (code == LT || code == GE)
+ && HWI_COMPUTABLE_MODE_P (mode))
+ {
+ unsigned HOST_WIDE_INT sign
+ = HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (mode) - 1);
op0 = simplify_gen_binary (AND, tmode,
- gen_lowpart (tmode,
- XEXP (op0, 0)),
- gen_lowpart (tmode,
- XEXP (op0, 1)));
- else
- {
- if (zero_extended)
- {
- op0 = simplify_gen_unary (ZERO_EXTEND, tmode, op0, mode);
- op1 = simplify_gen_unary (ZERO_EXTEND, tmode, op1, mode);
- }
- else
- {
- op0 = simplify_gen_unary (SIGN_EXTEND, tmode, op0, mode);
- op1 = simplify_gen_unary (SIGN_EXTEND, tmode, op1, mode);
- }
- break;
- }
- }
- }
+ gen_lowpart (tmode, op0),
+ gen_int_mode (sign, tmode));
+ code = (code == LT) ? NE : EQ;
+ break;
+ }
+
+ /* If the only nonzero bits in OP0 and OP1 are those in the
+ narrower mode and this is an equality or unsigned comparison,
+ we can use the wider mode. Similarly for sign-extended
+ values, in which case it is true for all comparisons. */
+ zero_extended = ((code == EQ || code == NE
+ || code == GEU || code == GTU
+ || code == LEU || code == LTU)
+ && (nonzero_bits (op0, tmode)
+ & ~GET_MODE_MASK (mode)) == 0
+ && ((CONST_INT_P (op1)
+ || (nonzero_bits (op1, tmode)
+ & ~GET_MODE_MASK (mode)) == 0)));
+
+ if (zero_extended
+ || ((num_sign_bit_copies (op0, tmode)
+ > (unsigned int) (GET_MODE_PRECISION (tmode)
+ - GET_MODE_PRECISION (mode)))
+ && (num_sign_bit_copies (op1, tmode)
+ > (unsigned int) (GET_MODE_PRECISION (tmode)
+ - GET_MODE_PRECISION (mode)))))
+ {
+ /* If OP0 is an AND and we don't have an AND in MODE either,
+ make a new AND in the proper mode. */
+ if (GET_CODE (op0) == AND
+ && !have_insn_for (AND, mode))
+ op0 = simplify_gen_binary (AND, tmode,
+ gen_lowpart (tmode,
+ XEXP (op0, 0)),
+ gen_lowpart (tmode,
+ XEXP (op0, 1)));
+ else
+ {
+ if (zero_extended)
+ {
+ op0 = simplify_gen_unary (ZERO_EXTEND, tmode,
+ op0, mode);
+ op1 = simplify_gen_unary (ZERO_EXTEND, tmode,
+ op1, mode);
+ }
+ else
+ {
+ op0 = simplify_gen_unary (SIGN_EXTEND, tmode,
+ op0, mode);
+ op1 = simplify_gen_unary (SIGN_EXTEND, tmode,
+ op1, mode);
+ }
+ break;
+ }
+ }
+ }
+ }
/* We may have changed the comparison operands. Re-canonicalize. */
if (swap_commutative_operands_p (op0, op1))