[4/77] Add FOR_EACH iterators for modes
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 30 Aug 2017 11:08:44 +0000 (11:08 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 30 Aug 2017 11:08:44 +0000 (11:08 +0000)
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

28 files changed:
gcc/ChangeLog
gcc/ada/ChangeLog
gcc/ada/gcc-interface/misc.c
gcc/builtins.c
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-cppbuiltin.c
gcc/combine.c
gcc/config/i386/i386.c
gcc/cse.c
gcc/dse.c
gcc/emit-rtl.c
gcc/explow.c
gcc/expmed.c
gcc/expr.c
gcc/machmode.h
gcc/omp-low.c
gcc/optabs-query.c
gcc/optabs.c
gcc/postreload.c
gcc/reg-stack.c
gcc/reginfo.c
gcc/rtlanal.c
gcc/stor-layout.c
gcc/tree-ssa-math-opts.c
gcc/tree-vect-generic.c
gcc/tree-vect-stmts.c
gcc/var-tracking.c

index b15b1b7c0bd00176846e958dc84dc16d16255fd1..7742722c1f43a5682b46392f47c4c85b3e9ed429 100644 (file)
@@ -1,3 +1,67 @@
+2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
+            Alan Hayward  <alan.hayward@arm.com>
+            David Sherwood  <david.sherwood@arm.com>
+
+       * 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.
+
 2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index 87091b1c7f5ae1495bea1fad877211efec2600f1..4f7d2bd5ef9553a0b0bd2a29475684aa2fffa0a2 100644 (file)
@@ -1,3 +1,10 @@
+2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
+            Alan Hayward  <alan.hayward@arm.com>
+            David Sherwood  <david.sherwood@arm.com>
+
+       * gcc-interface/misc.c (fp_prec_to_size): Use new mode iterators.
+       (fp_size_to_prec): Likewise.
+
 2017-08-29  Martin Liska  <mliska@suse.cz>
 
        PR other/39851
index 18c825ca13e200fdff70cddeab95f9dc63634a8f..eaacabd5dcfb6a33993e41ad23bed229c69e233c 100644 (file)
@@ -1313,8 +1313,7 @@ fp_prec_to_size (int prec)
 {
   machine_mode mode;
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
     if (GET_MODE_PRECISION (mode) == prec)
       return GET_MODE_BITSIZE (mode);
 
@@ -1328,8 +1327,7 @@ fp_size_to_prec (int size)
 {
   machine_mode mode;
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
     if (GET_MODE_BITSIZE (mode) == size)
       return GET_MODE_PRECISION (mode);
 
index fa0f89c8f336f20051a88a99532a2e6fb3fba7c9..2f361bfde4b4b25e6ff755ae2638fc02f8290ec0 100644 (file)
@@ -2792,7 +2792,7 @@ expand_builtin_strlen (tree exp, rtx target,
       tree src = CALL_EXPR_ARG (exp, 0);
       rtx src_reg;
       rtx_insn *before_strlen;
-      machine_mode insn_mode = target_mode;
+      machine_mode insn_mode;
       enum insn_code icode = CODE_FOR_nothing;
       unsigned int align;
 
@@ -2820,13 +2820,11 @@ expand_builtin_strlen (tree exp, rtx target,
        return NULL_RTX;
 
       /* Bail out if we can't compute strlen in the right mode.  */
-      while (insn_mode != VOIDmode)
+      FOR_EACH_MODE_FROM (insn_mode, target_mode)
        {
          icode = optab_handler (strlen_optab, insn_mode);
          if (icode != CODE_FOR_nothing)
            break;
-
-         insn_mode = GET_MODE_WIDER_MODE (insn_mode);
        }
       if (insn_mode == VOIDmode)
        return NULL_RTX;
index e8bf5c3149314b5810ddcb38394cf2e7c01be501..44857d6197bccc3e6107acb0ff925be8c070a663 100644 (file)
@@ -1,3 +1,11 @@
+2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
+            Alan Hayward  <alan.hayward@arm.com>
+            David Sherwood  <david.sherwood@arm.com>
+
+       * c-common.c (c_common_fixed_point_type_for_size): Use new mode
+       iterators.
+       * c-cppbuiltin.c (c_cpp_builtins): Likewise.
+
 2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index f4f2819aeceee70477613424f80affadba9def61..b4ee2ed2bc825436141f47375bf61c69f98cc0d4 100644 (file)
@@ -2149,13 +2149,14 @@ tree
 c_common_fixed_point_type_for_size (unsigned int ibit, unsigned int fbit,
                                    int unsignedp, int satp)
 {
-  machine_mode mode;
+  enum mode_class mclass;
   if (ibit == 0)
-    mode = unsignedp ? UQQmode : QQmode;
+    mclass = unsignedp ? MODE_UFRACT : MODE_FRACT;
   else
-    mode = unsignedp ? UHAmode : HAmode;
+    mclass = unsignedp ? MODE_UACCUM : MODE_ACCUM;
 
-  for (; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode))
+  machine_mode mode;
+  FOR_EACH_MODE_IN_CLASS (mode, mclass)
     if (GET_MODE_IBIT (mode) >= ibit && GET_MODE_FBIT (mode) >= fbit)
       break;
 
index 6dc1559877b945528901ec1f6f7053b1456bd2b4..4f397a18f4595d6ac921242cefa51965c82cfcf0 100644 (file)
@@ -1186,9 +1186,8 @@ c_cpp_builtins (cpp_reader *pfile)
   if (flag_building_libgcc)
     {
       /* Properties of floating-point modes for libgcc2.c.  */
-      for (machine_mode mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
-          mode != VOIDmode;
-          mode = GET_MODE_WIDER_MODE (mode))
+      machine_mode mode;
+      FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
        {
          const char *name = GET_MODE_NAME (mode);
          char *macro_name
index b34fb81c97a830f8598e84c8d677af9fefe3a290..46212c5ea8455e26303af5d494fe7cb2652e6b81 100644 (file)
@@ -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))
index 69d6be4c3d44817541e8d54f9e75b4509bd63556..f087bce291ba1cb015aeccea4b61e4afca6ba956 100644 (file)
@@ -9110,7 +9110,7 @@ type_natural_mode (const_tree type, const CUMULATIVE_ARGS *cum,
            mode = MIN_MODE_VECTOR_INT;
 
          /* Get the mode which has this inner mode and number of units.  */
-         for (; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode))
+         FOR_EACH_MODE_FROM (mode, mode)
            if (GET_MODE_NUNITS (mode) == TYPE_VECTOR_SUBPARTS (type)
                && GET_MODE_INNER (mode) == innermode)
              {
index 191fd0699fbb4023c56cdd6b6ecc23e9cbb86661..58572e6a093a78c2247c7ef28479ac67a488f24e 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -4845,12 +4845,11 @@ cse_insn (rtx_insn *insn)
        {
          machine_mode wider_mode;
 
-         for (wider_mode = GET_MODE_WIDER_MODE (mode);
-              wider_mode != VOIDmode
-              && GET_MODE_PRECISION (wider_mode) <= BITS_PER_WORD
-              && src_related == 0;
-              wider_mode = GET_MODE_WIDER_MODE (wider_mode))
+         FOR_EACH_WIDER_MODE (wider_mode, mode)
            {
+             if (GET_MODE_PRECISION (wider_mode) > BITS_PER_WORD)
+               break;
+
              struct table_elt *const_elt
                = lookup (src_const, HASH (src_const, wider_mode), wider_mode);
 
@@ -4864,6 +4863,9 @@ cse_insn (rtx_insn *insn)
                    src_related = gen_lowpart (mode, const_elt->exp);
                    break;
                  }
+
+             if (src_related != 0)
+               break;
            }
        }
 
@@ -4880,10 +4882,11 @@ cse_insn (rtx_insn *insn)
          machine_mode tmode;
          rtx new_and = gen_rtx_AND (VOIDmode, NULL_RTX, XEXP (src, 1));
 
-         for (tmode = GET_MODE_WIDER_MODE (mode);
-              GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
-              tmode = GET_MODE_WIDER_MODE (tmode))
+         FOR_EACH_WIDER_MODE (tmode, mode)
            {
+             if (GET_MODE_SIZE (tmode) > UNITS_PER_WORD)
+               break;
+
              rtx inner = gen_lowpart (tmode, XEXP (src, 0));
              struct table_elt *larger_elt;
 
@@ -4930,12 +4933,13 @@ cse_insn (rtx_insn *insn)
          PUT_CODE (memory_extend_rtx, extend_op);
          XEXP (memory_extend_rtx, 0) = src;
 
-         for (tmode = GET_MODE_WIDER_MODE (mode);
-              GET_MODE_SIZE (tmode) <= UNITS_PER_WORD;
-              tmode = GET_MODE_WIDER_MODE (tmode))
+         FOR_EACH_WIDER_MODE (tmode, mode)
            {
              struct table_elt *larger_elt;
 
+             if (GET_MODE_SIZE (tmode) > UNITS_PER_WORD)
+               break;
+
              PUT_MODE (memory_extend_rtx, tmode);
              larger_elt = lookup (memory_extend_rtx,
                                   HASH (memory_extend_rtx, tmode), tmode);
index f87dd50024e8ba17c7c9deca9f127a042f954094..937e6eabd624d8770582d07c0c8d3071fd0da241 100644 (file)
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -1583,15 +1583,17 @@ find_shift_sequence (int access_size,
      justify the value we want to read but is available in one insn on
      the machine.  */
 
-  for (new_mode = smallest_mode_for_size (access_size * BITS_PER_UNIT,
-                                         MODE_INT);
-       GET_MODE_BITSIZE (new_mode) <= BITS_PER_WORD;
-       new_mode = GET_MODE_WIDER_MODE (new_mode))
+  FOR_EACH_MODE_FROM (new_mode,
+                     smallest_mode_for_size (access_size * BITS_PER_UNIT,
+                                             MODE_INT))
     {
       rtx target, new_reg, new_lhs;
       rtx_insn *shift_seq, *insn;
       int cost;
 
+      if (GET_MODE_BITSIZE (new_mode) > BITS_PER_WORD)
+       break;
+
       /* If a constant was stored into memory, try to simplify it here,
         otherwise the cost of the shift might preclude this optimization
         e.g. at -Os, even when no actual shift will be needed.  */
index c1438d66cb38af3bc829684b987acae74c252350..3856ac02d4ea9baba511704ea4923c132e434be0 100644 (file)
@@ -5867,9 +5867,8 @@ init_derived_machine_modes (void)
   byte_mode = VOIDmode;
   word_mode = VOIDmode;
 
-  for (machine_mode mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  machine_mode mode;
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
     {
       if (GET_MODE_BITSIZE (mode) == BITS_PER_UNIT
          && byte_mode == VOIDmode)
@@ -5951,23 +5950,17 @@ init_emit_once (void)
       const REAL_VALUE_TYPE *const r =
        (i == 0 ? &dconst0 : i == 1 ? &dconst1 : &dconst2);
 
-      for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
-          mode != VOIDmode;
-          mode = GET_MODE_WIDER_MODE (mode))
+      FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
        const_tiny_rtx[i][(int) mode] =
          const_double_from_real_value (*r, mode);
 
-      for (mode = GET_CLASS_NARROWEST_MODE (MODE_DECIMAL_FLOAT);
-          mode != VOIDmode;
-          mode = GET_MODE_WIDER_MODE (mode))
+      FOR_EACH_MODE_IN_CLASS (mode, MODE_DECIMAL_FLOAT)
        const_tiny_rtx[i][(int) mode] =
          const_double_from_real_value (*r, mode);
 
       const_tiny_rtx[i][(int) VOIDmode] = GEN_INT (i);
 
-      for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
-          mode != VOIDmode;
-          mode = GET_MODE_WIDER_MODE (mode))
+      FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
        const_tiny_rtx[i][(int) mode] = GEN_INT (i);
 
       for (mode = MIN_MODE_PARTIAL_INT;
@@ -5978,52 +5971,40 @@ init_emit_once (void)
 
   const_tiny_rtx[3][(int) VOIDmode] = constm1_rtx;
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
     const_tiny_rtx[3][(int) mode] = constm1_rtx;
 
   for (mode = MIN_MODE_PARTIAL_INT;
        mode <= MAX_MODE_PARTIAL_INT;
        mode = (machine_mode)((int)(mode) + 1))
     const_tiny_rtx[3][(int) mode] = constm1_rtx;
-      
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_INT);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_COMPLEX_INT)
     {
       rtx inner = const_tiny_rtx[0][(int)GET_MODE_INNER (mode)];
       const_tiny_rtx[0][(int) mode] = gen_rtx_CONCAT (mode, inner, inner);
     }
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_COMPLEX_FLOAT)
     {
       rtx inner = const_tiny_rtx[0][(int)GET_MODE_INNER (mode)];
       const_tiny_rtx[0][(int) mode] = gen_rtx_CONCAT (mode, inner, inner);
     }
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
     {
       const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
       const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
       const_tiny_rtx[3][(int) mode] = gen_const_vector (mode, 3);
     }
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_FLOAT)
     {
       const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
       const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
     }
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_FRACT);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_FRACT)
     {
       FCONST0 (mode).data.high = 0;
       FCONST0 (mode).data.low = 0;
@@ -6032,9 +6013,7 @@ init_emit_once (void)
                                      FCONST0 (mode), mode);
     }
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_UFRACT);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_UFRACT)
     {
       FCONST0 (mode).data.high = 0;
       FCONST0 (mode).data.low = 0;
@@ -6043,9 +6022,7 @@ init_emit_once (void)
                                      FCONST0 (mode), mode);
     }
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_ACCUM);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_ACCUM)
     {
       FCONST0 (mode).data.high = 0;
       FCONST0 (mode).data.low = 0;
@@ -6065,9 +6042,7 @@ init_emit_once (void)
                                      FCONST1 (mode), mode);
     }
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_UACCUM);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_UACCUM)
     {
       FCONST0 (mode).data.high = 0;
       FCONST0 (mode).data.low = 0;
@@ -6087,31 +6062,23 @@ init_emit_once (void)
                                      FCONST1 (mode), mode);
     }
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FRACT);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_FRACT)
     {
       const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
     }
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_UFRACT);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_UFRACT)
     {
       const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
     }
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_ACCUM);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_ACCUM)
     {
       const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
       const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
     }
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_UACCUM);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_UACCUM)
     {
       const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
       const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
@@ -6125,9 +6092,7 @@ init_emit_once (void)
   if (STORE_FLAG_VALUE == 1)
     const_tiny_rtx[1][(int) BImode] = const1_rtx;
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_POINTER_BOUNDS);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_POINTER_BOUNDS)
     {
       wide_int wi_zero = wi::zero (GET_MODE_PRECISION (mode));
       const_tiny_rtx[0][mode] = immed_wide_int_const (wi_zero, mode);
index 50074e281edd5270c76d29feac6b7a92f598d11d..72fb6828379b5b2733568f9fa2e50bdaaab51e32 100644 (file)
@@ -1912,9 +1912,7 @@ hard_function_value (const_tree valtype, const_tree func, const_tree fntype,
         since the value of bytes will then be large enough that no
         mode will match anyway.  */
 
-      for (tmpmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
-          tmpmode != VOIDmode;
-          tmpmode = GET_MODE_WIDER_MODE (tmpmode))
+      FOR_EACH_MODE_IN_CLASS (tmpmode, MODE_INT)
        {
          /* Have we found a large enough mode?  */
          if (GET_MODE_SIZE (tmpmode) >= bytes)
index 7eeadc1d694966c361fcd3778d8da5d4de0f9c21..0219e0dee7692f752f60f77c1021ceecb44ef123 100644 (file)
@@ -1635,7 +1635,7 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
       else
        new_mode = MIN_MODE_VECTOR_INT;
 
-      for (; new_mode != VOIDmode ; new_mode = GET_MODE_WIDER_MODE (new_mode))
+      FOR_EACH_MODE_FROM (new_mode, new_mode)
        if (GET_MODE_SIZE (new_mode) == GET_MODE_SIZE (GET_MODE (op0))
            && GET_MODE_UNIT_SIZE (new_mode) == GET_MODE_SIZE (tmode)
            && targetm.vector_mode_supported_p (new_mode))
@@ -2081,8 +2081,7 @@ extract_fixed_bit_field_1 (machine_mode tmode, rtx op0,
 
   /* Find the narrowest integer mode that contains the field.  */
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
     if (GET_MODE_BITSIZE (mode) >= bitsize + bitnum)
       {
        op0 = convert_to_mode (mode, op0, 0);
@@ -4146,15 +4145,13 @@ expand_divmod (int rem_flag, enum tree_code code, machine_mode mode,
   optab2 = (op1_is_pow2 ? optab1
            : (unsignedp ? udivmod_optab : sdivmod_optab));
 
-  for (compute_mode = mode; compute_mode != VOIDmode;
-       compute_mode = GET_MODE_WIDER_MODE (compute_mode))
+  FOR_EACH_MODE_FROM (compute_mode, mode)
     if (optab_handler (optab1, compute_mode) != CODE_FOR_nothing
        || optab_handler (optab2, compute_mode) != CODE_FOR_nothing)
       break;
 
   if (compute_mode == VOIDmode)
-    for (compute_mode = mode; compute_mode != VOIDmode;
-        compute_mode = GET_MODE_WIDER_MODE (compute_mode))
+    FOR_EACH_MODE_FROM (compute_mode, mode)
       if (optab_libfunc (optab1, compute_mode)
          || optab_libfunc (optab2, compute_mode))
        break;
@@ -5556,8 +5553,7 @@ emit_store_flag_1 (rtx target, enum rtx_code code, rtx op0, rtx op1,
     }
 
   mclass = GET_MODE_CLASS (mode);
-  for (compare_mode = mode; compare_mode != VOIDmode;
-       compare_mode = GET_MODE_WIDER_MODE (compare_mode))
+  FOR_EACH_MODE_FROM (compare_mode, mode)
     {
      machine_mode optab_mode = mclass == MODE_CC ? CCmode : compare_mode;
      icode = optab_handler (cstore_optab, optab_mode);
index 7f34f5d12a7d0d52de94e7af27484f98140fba29..cbec00c64aef5e0cbb8f7ec8a977ccb90236917b 100644 (file)
@@ -177,12 +177,10 @@ init_expr_target (void)
 
   mem = gen_rtx_MEM (VOIDmode, gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1));
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
     {
       machine_mode srcmode;
-      for (srcmode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT); srcmode != mode;
-          srcmode = GET_MODE_WIDER_MODE (srcmode))
+      FOR_EACH_MODE_UNTIL (srcmode, mode)
        {
          enum insn_code ic;
 
@@ -549,8 +547,7 @@ convert_move (rtx to, rtx from, int unsignedp)
          int shift_amount;
 
          /* Search for a mode to convert via.  */
-         for (intermediate = from_mode; intermediate != VOIDmode;
-              intermediate = GET_MODE_WIDER_MODE (intermediate))
+         FOR_EACH_MODE_FROM (intermediate, from_mode)
            if (((can_extend_p (to_mode, intermediate, unsignedp)
                  != CODE_FOR_nothing)
                 || (GET_MODE_SIZE (to_mode) < GET_MODE_SIZE (intermediate)
@@ -702,12 +699,14 @@ alignment_for_piecewise_move (unsigned int max_pieces, unsigned int align)
     {
       machine_mode tmode, xmode;
 
-      for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT), xmode = tmode;
-          tmode != VOIDmode;
-          xmode = tmode, tmode = GET_MODE_WIDER_MODE (tmode))
-       if (GET_MODE_SIZE (tmode) > max_pieces
-           || SLOW_UNALIGNED_ACCESS (tmode, align))
-         break;
+      xmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
+      FOR_EACH_MODE_IN_CLASS (tmode, MODE_INT)
+       {
+         if (GET_MODE_SIZE (tmode) > max_pieces
+             || SLOW_UNALIGNED_ACCESS (tmode, align))
+           break;
+         xmode = tmode;
+       }
 
       align = MAX (align, GET_MODE_ALIGNMENT (xmode));
     }
@@ -723,8 +722,7 @@ widest_int_mode_for_size (unsigned int size)
 {
   machine_mode tmode, mode = VOIDmode;
 
-  for (tmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
-       tmode != VOIDmode; tmode = GET_MODE_WIDER_MODE (tmode))
+  FOR_EACH_MODE_IN_CLASS (tmode, MODE_INT)
     if (GET_MODE_SIZE (tmode) < size)
       mode = tmode;
 
@@ -1728,8 +1726,7 @@ emit_block_move_via_movmem (rtx x, rtx y, rtx size, unsigned int align,
      including more than one in the machine description unless
      the more limited one has some advantage.  */
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
     {
       enum insn_code code = direct_optab_handler (movmem_optab, mode);
 
@@ -2790,9 +2787,7 @@ copy_blkmode_to_reg (machine_mode mode, tree src)
     {
       /* Find the smallest integer mode large enough to hold the
         entire structure.  */
-      for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
-          mode != VOIDmode;
-          mode = GET_MODE_WIDER_MODE (mode))
+      FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
        /* Have we found a large enough mode?  */
        if (GET_MODE_SIZE (mode) >= bytes)
          break;
@@ -3048,8 +3043,7 @@ set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align,
        expected_size = min_size;
     }
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
     {
       enum insn_code code = direct_optab_handler (setmem_optab, mode);
 
@@ -3788,9 +3782,7 @@ compress_float_constant (rtx x, rtx y)
   else
     oldcost = set_src_cost (force_const_mem (dstmode, y), dstmode, speed);
 
-  for (srcmode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (orig_srcmode));
-       srcmode != orig_srcmode;
-       srcmode = GET_MODE_WIDER_MODE (srcmode))
+  FOR_EACH_MODE_UNTIL (srcmode, orig_srcmode)
     {
       enum insn_code ic;
       rtx trunc_y;
index 330fdf9e6b1de1ac82eaf3cb8cbfdc3b1993f4bd..c272888ebf14be1b85339634414190b5440d8956 100644 (file)
@@ -29,6 +29,44 @@ extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];
 extern const unsigned char mode_wider[NUM_MACHINE_MODES];
 extern const unsigned char mode_2xwider[NUM_MACHINE_MODES];
 
+template<typename T>
+struct mode_traits
+{
+  /* For use by the machmode support code only.
+
+     There are cases in which the machmode support code needs to forcibly
+     convert a machine_mode to a specific mode class T, and in which the
+     context guarantees that this is valid without the need for an assert.
+     This can be done using:
+
+       return typename mode_traits<T>::from_int (mode);
+
+     when returning a T and:
+
+       res = T (typename mode_traits<T>::from_int (mode));
+
+     when assigning to a value RES that must be assignment-compatible
+     with (but possibly not the same as) T.
+
+     Here we use an enum type distinct from machine_mode but with the
+     same range as machine_mode.  T should have a constructor that
+     accepts this enum type; it should not have a constructor that
+     accepts machine_mode.
+
+     We use this somewhat indirect approach to avoid too many constructor
+     calls when the compiler is built with -O0.  For example, even in
+     unoptimized code, the return statement above would construct the
+     returned T directly from the numerical value of MODE.  */
+  enum from_int { dummy = MAX_MACHINE_MODE };
+};
+
+template<>
+struct mode_traits<machine_mode>
+{
+  /* machine_mode itself needs no conversion.  */
+  typedef machine_mode from_int;
+};
+
 /* Get the name of mode MODE as a string.  */
 
 extern const char * const mode_name[NUM_MACHINE_MODES];
@@ -395,6 +433,16 @@ extern const unsigned char class_narrowest_mode[MAX_MODE_CLASS];
 #define GET_CLASS_NARROWEST_MODE(CLASS) \
   ((machine_mode) class_narrowest_mode[CLASS])
 
+/* Return the narrowest mode in T's class.  */
+
+template<typename T>
+inline T
+get_narrowest_mode (T mode)
+{
+  return typename mode_traits<T>::from_int
+    (class_narrowest_mode[GET_MODE_CLASS (mode)]);
+}
+
 /* Define the integer modes whose sizes are BITS_PER_UNIT and BITS_PER_WORD
    and the mode whose class is Pmode and whose size is POINTER_SIZE.  */
 
@@ -425,4 +473,95 @@ struct int_n_data_t {
 extern bool int_n_enabled_p[NUM_INT_N_ENTS];
 extern const int_n_data_t int_n_data[NUM_INT_N_ENTS];
 
+namespace mode_iterator
+{
+  /* Start mode iterator *ITER at the first mode in class MCLASS, if any.  */
+
+  inline void
+  start (machine_mode *iter, enum mode_class mclass)
+  {
+    *iter = GET_CLASS_NARROWEST_MODE (mclass);
+  }
+
+  /* Return true if mode iterator *ITER has not reached the end.  */
+
+  inline bool
+  iterate_p (machine_mode *iter)
+  {
+    return *iter != E_VOIDmode;
+  }
+
+  /* Set mode iterator *ITER to the next widest mode in the same class,
+     if any.  */
+
+  inline void
+  get_wider (machine_mode *iter)
+  {
+    *iter = GET_MODE_WIDER_MODE (*iter);
+  }
+
+  /* Set mode iterator *ITER to the next widest mode in the same class.
+     Such a mode is known to exist.  */
+
+  inline void
+  get_known_wider (machine_mode *iter)
+  {
+    *iter = GET_MODE_WIDER_MODE (*iter);
+    gcc_checking_assert (*iter != VOIDmode);
+  }
+
+  /* Set mode iterator *ITER to the mode that is two times wider than the
+     current one, if such a mode exists.  */
+
+  inline void
+  get_2xwider (machine_mode *iter)
+  {
+    *iter = GET_MODE_2XWIDER_MODE (*iter);
+  }
+}
+
+/* Make ITERATOR iterate over all the modes in mode class CLASS,
+   from narrowest to widest.  */
+#define FOR_EACH_MODE_IN_CLASS(ITERATOR, CLASS)  \
+  for (mode_iterator::start (&(ITERATOR), CLASS); \
+       mode_iterator::iterate_p (&(ITERATOR)); \
+       mode_iterator::get_wider (&(ITERATOR)))
+
+/* Make ITERATOR iterate over all the modes in the range [START, END),
+   in order of increasing width.  */
+#define FOR_EACH_MODE(ITERATOR, START, END) \
+  for ((ITERATOR) = (START); \
+       (ITERATOR) != (END); \
+       mode_iterator::get_known_wider (&(ITERATOR)))
+
+/* Make ITERATOR iterate over START and all wider modes in the same
+   class, in order of increasing width.  */
+#define FOR_EACH_MODE_FROM(ITERATOR, START) \
+  for ((ITERATOR) = (START); \
+       mode_iterator::iterate_p (&(ITERATOR)); \
+       mode_iterator::get_wider (&(ITERATOR)))
+
+/* Make ITERATOR iterate over modes in the range [NARROWEST, END)
+   in order of increasing width, where NARROWEST is the narrowest mode
+   in END's class.  */
+#define FOR_EACH_MODE_UNTIL(ITERATOR, END) \
+  FOR_EACH_MODE (ITERATOR, get_narrowest_mode (END), END)
+
+/* Make ITERATOR iterate over modes in the same class as MODE, in order
+   of increasing width.  Start at the first mode wider than START,
+   or don't iterate at all if there is no wider mode.  */
+#define FOR_EACH_WIDER_MODE(ITERATOR, START) \
+  for ((ITERATOR) = (START), mode_iterator::get_wider (&(ITERATOR)); \
+       mode_iterator::iterate_p (&(ITERATOR)); \
+       mode_iterator::get_wider (&(ITERATOR)))
+
+/* Make ITERATOR iterate over modes in the same class as MODE, in order
+   of increasing width, and with each mode being twice the width of the
+   previous mode.  Start at the mode that is two times wider than START,
+   or don't iterate at all if there is no such mode.  */
+#define FOR_EACH_2XWIDER_MODE(ITERATOR, START) \
+  for ((ITERATOR) = (START), mode_iterator::get_2xwider (&(ITERATOR)); \
+       mode_iterator::iterate_p (&(ITERATOR)); \
+       mode_iterator::get_2xwider (&(ITERATOR)))
+
 #endif /* not HAVE_MACHINE_MODES */
index dffdb7704ad6e801995df4fccae13609e78e8919..a36e5f9cbc04ae571da8ced5679835ce0c4f70b0 100644 (file)
@@ -3449,9 +3449,7 @@ omp_clause_aligned_alignment (tree clause)
   static enum mode_class classes[]
     = { MODE_INT, MODE_VECTOR_INT, MODE_FLOAT, MODE_VECTOR_FLOAT };
   for (int i = 0; i < 4; i += 2)
-    for (mode = GET_CLASS_NARROWEST_MODE (classes[i]);
-        mode != VOIDmode;
-        mode = GET_MODE_WIDER_MODE (mode))
+    FOR_EACH_MODE_IN_CLASS (mode, classes[i])
       {
        vmode = targetm.vectorize.preferred_simd_mode (mode);
        if (GET_MODE_CLASS (vmode) != classes[i + 1])
index 4899333096e5d327bcd98fa70ddfb7b2dd386801..ad22f07a395f186e850c20a69e6918cff6ba224d 100644 (file)
@@ -194,21 +194,20 @@ get_best_extraction_insn (extraction_insn *insn,
                          machine_mode field_mode)
 {
   machine_mode mode = smallest_mode_for_size (struct_bits, MODE_INT);
-  while (mode != VOIDmode)
+  FOR_EACH_MODE_FROM (mode, mode)
     {
       if (get_extraction_insn (insn, pattern, type, mode))
        {
-         while (mode != VOIDmode
-                && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (field_mode)
-                && !TRULY_NOOP_TRUNCATION_MODES_P (insn->field_mode,
-                                                   field_mode))
+         FOR_EACH_MODE_FROM (mode, mode)
            {
+             if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (field_mode)
+                 || TRULY_NOOP_TRUNCATION_MODES_P (insn->field_mode,
+                                                   field_mode))
+               break;
              get_extraction_insn (insn, pattern, type, mode);
-             mode = GET_MODE_WIDER_MODE (mode);
            }
          return true;
        }
-      mode = GET_MODE_WIDER_MODE (mode);
     }
   return false;
 }
index 71b74dd5feb579d74ad5f5a8fa1900c66160794b..ce419d361dec49fd3cb486c85b1f231882b364a9 100644 (file)
@@ -1251,9 +1251,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
 
   if (CLASS_HAS_WIDER_MODES_P (mclass)
       && methods != OPTAB_DIRECT && methods != OPTAB_LIB)
-    for (wider_mode = GET_MODE_WIDER_MODE (mode);
-        wider_mode != VOIDmode;
-        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
+    FOR_EACH_WIDER_MODE (wider_mode, mode)
       {
        if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing
            || (binoptab == smul_optab
@@ -1794,9 +1792,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
 
   if (CLASS_HAS_WIDER_MODES_P (mclass))
     {
-      for (wider_mode = GET_MODE_WIDER_MODE (mode);
-          wider_mode != VOIDmode;
-          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
+      FOR_EACH_WIDER_MODE (wider_mode, mode)
        {
          if (find_widening_optab_handler (binoptab, wider_mode, mode, 1)
                  != CODE_FOR_nothing
@@ -1952,9 +1948,7 @@ expand_twoval_unop (optab unoptab, rtx op0, rtx targ0, rtx targ1,
 
   if (CLASS_HAS_WIDER_MODES_P (mclass))
     {
-      for (wider_mode = GET_MODE_WIDER_MODE (mode);
-          wider_mode != VOIDmode;
-          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
+      FOR_EACH_WIDER_MODE (wider_mode, mode)
        {
          if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
            {
@@ -2035,9 +2029,7 @@ expand_twoval_binop (optab binoptab, rtx op0, rtx op1, rtx targ0, rtx targ1,
 
   if (CLASS_HAS_WIDER_MODES_P (mclass))
     {
-      for (wider_mode = GET_MODE_WIDER_MODE (mode);
-          wider_mode != VOIDmode;
-          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
+      FOR_EACH_WIDER_MODE (wider_mode, mode)
        {
          if (optab_handler (binoptab, wider_mode) != CODE_FOR_nothing)
            {
@@ -2139,9 +2131,7 @@ widen_leading (machine_mode mode, rtx op0, rtx target, optab unoptab)
   if (CLASS_HAS_WIDER_MODES_P (mclass))
     {
       machine_mode wider_mode;
-      for (wider_mode = GET_MODE_WIDER_MODE (mode);
-          wider_mode != VOIDmode;
-          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
+      FOR_EACH_WIDER_MODE (wider_mode, mode)
        {
          if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
            {
@@ -2311,9 +2301,7 @@ widen_bswap (machine_mode mode, rtx op0, rtx target)
   if (!CLASS_HAS_WIDER_MODES_P (mclass))
     return NULL_RTX;
 
-  for (wider_mode = GET_MODE_WIDER_MODE (mode);
-       wider_mode != VOIDmode;
-       wider_mode = GET_MODE_WIDER_MODE (wider_mode))
+  FOR_EACH_WIDER_MODE (wider_mode, mode)
     if (optab_handler (bswap_optab, wider_mode) != CODE_FOR_nothing)
       goto found;
   return NULL_RTX;
@@ -2375,8 +2363,7 @@ expand_parity (machine_mode mode, rtx op0, rtx target)
   if (CLASS_HAS_WIDER_MODES_P (mclass))
     {
       machine_mode wider_mode;
-      for (wider_mode = mode; wider_mode != VOIDmode;
-          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
+      FOR_EACH_MODE_FROM (wider_mode, mode)
        {
          if (optab_handler (popcount_optab, wider_mode) != CODE_FOR_nothing)
            {
@@ -2828,9 +2815,7 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
     }
 
   if (CLASS_HAS_WIDER_MODES_P (mclass))
-    for (wider_mode = GET_MODE_WIDER_MODE (mode);
-        wider_mode != VOIDmode;
-        wider_mode = GET_MODE_WIDER_MODE (wider_mode))
+    FOR_EACH_WIDER_MODE (wider_mode, mode)
       {
        if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing)
          {
@@ -2997,9 +2982,7 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
 
   if (CLASS_HAS_WIDER_MODES_P (mclass))
     {
-      for (wider_mode = GET_MODE_WIDER_MODE (mode);
-          wider_mode != VOIDmode;
-          wider_mode = GET_MODE_WIDER_MODE (wider_mode))
+      FOR_EACH_WIDER_MODE (wider_mode, mode)
        {
          if (optab_handler (unoptab, wider_mode) != CODE_FOR_nothing
              || optab_libfunc (unoptab, wider_mode))
@@ -3800,9 +3783,7 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
 
       /* Try to use a memory block compare insn - either cmpstr
         or cmpmem will do.  */
-      for (cmp_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
-          cmp_mode != VOIDmode;
-          cmp_mode = GET_MODE_WIDER_MODE (cmp_mode))
+      FOR_EACH_MODE_IN_CLASS (cmp_mode, MODE_INT)
        {
          cmp_code = direct_optab_handler (cmpmem_optab, cmp_mode);
          if (cmp_code == CODE_FOR_nothing)
@@ -3864,9 +3845,8 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
 
   mclass = GET_MODE_CLASS (mode);
   test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
-  cmp_mode = mode;
-  do
-   {
+  FOR_EACH_MODE_FROM (cmp_mode, mode)
+    {
       enum insn_code icode;
       icode = optab_handler (cbranch_optab, cmp_mode);
       if (icode != CODE_FOR_nothing
@@ -3890,9 +3870,7 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
 
       if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
        break;
-      cmp_mode = GET_MODE_WIDER_MODE (cmp_mode);
     }
-  while (cmp_mode != VOIDmode);
 
   if (methods != OPTAB_LIB_WIDEN)
     goto fail;
@@ -4075,9 +4053,7 @@ prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
   bool reversed_p = false;
   cmp_mode = targetm.libgcc_cmp_return_mode ();
 
-  for (mode = orig_mode;
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_FROM (mode, orig_mode)
     {
       if (code_to_optab (comparison)
          && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))
@@ -4650,10 +4626,8 @@ expand_float (rtx to, rtx from, int unsignedp)
      wider mode.  If the integer mode is wider than the mode of FROM,
      we can do the conversion signed even if the input is unsigned.  */
 
-  for (fmode = GET_MODE (to); fmode != VOIDmode;
-       fmode = GET_MODE_WIDER_MODE (fmode))
-    for (imode = GET_MODE (from); imode != VOIDmode;
-        imode = GET_MODE_WIDER_MODE (imode))
+  FOR_EACH_MODE_FROM (fmode, GET_MODE (to))
+    FOR_EACH_MODE_FROM (imode, GET_MODE (from))
       {
        int doing_unsigned = unsignedp;
 
@@ -4700,8 +4674,7 @@ expand_float (rtx to, rtx from, int unsignedp)
         least as wide as the target.  Using FMODE will avoid rounding woes
         with unsigned values greater than the signed maximum value.  */
 
-      for (fmode = GET_MODE (to);  fmode != VOIDmode;
-          fmode = GET_MODE_WIDER_MODE (fmode))
+      FOR_EACH_MODE_FROM (fmode, GET_MODE (to))
        if (GET_MODE_PRECISION (GET_MODE (from)) < GET_MODE_BITSIZE (fmode)
            && can_float_p (fmode, GET_MODE (from), 0) != CODE_FOR_nothing)
          break;
@@ -4848,10 +4821,8 @@ expand_fix (rtx to, rtx from, int unsignedp)
      this conversion.  If the integer mode is wider than the mode of TO,
      we can do the conversion either signed or unsigned.  */
 
-  for (fmode = GET_MODE (from); fmode != VOIDmode;
-       fmode = GET_MODE_WIDER_MODE (fmode))
-    for (imode = GET_MODE (to); imode != VOIDmode;
-        imode = GET_MODE_WIDER_MODE (imode))
+  FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
+    FOR_EACH_MODE_FROM (imode, GET_MODE (to))
       {
        int doing_unsigned = unsignedp;
 
@@ -4911,8 +4882,7 @@ expand_fix (rtx to, rtx from, int unsignedp)
      simply clears out that bit.  The rest is trivial.  */
 
   if (unsignedp && GET_MODE_PRECISION (GET_MODE (to)) <= HOST_BITS_PER_WIDE_INT)
-    for (fmode = GET_MODE (from); fmode != VOIDmode;
-        fmode = GET_MODE_WIDER_MODE (fmode))
+    FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
       if (CODE_FOR_nothing != can_fix_p (GET_MODE (to), fmode, 0, &must_trunc)
          && (!DECIMAL_FLOAT_MODE_P (fmode)
              || GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (GET_MODE (to))))
@@ -5113,10 +5083,8 @@ expand_sfix_optab (rtx to, rtx from, convert_optab tab)
      this conversion.  If the integer mode is wider than the mode of TO,
      we can do the conversion either signed or unsigned.  */
 
-  for (fmode = GET_MODE (from); fmode != VOIDmode;
-       fmode = GET_MODE_WIDER_MODE (fmode))
-    for (imode = GET_MODE (to); imode != VOIDmode;
-        imode = GET_MODE_WIDER_MODE (imode))
+  FOR_EACH_MODE_FROM (fmode, GET_MODE (from))
+    FOR_EACH_MODE_FROM (imode, GET_MODE (to))
       {
        icode = convert_optab_handler (tab, imode, fmode);
        if (icode != CODE_FOR_nothing)
index e721f2f867da3eb268bc72e3e0f2c5f8686a2fd2..2c6d091a4b453dcffb170f9f1f30f66348b44059 100644 (file)
@@ -1770,10 +1770,7 @@ move2add_use_add2_insn (rtx reg, rtx sym, rtx off, rtx_insn *insn)
       else if (sym == NULL_RTX && GET_MODE (reg) != BImode)
        {
          machine_mode narrow_mode;
-         for (narrow_mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
-              narrow_mode != VOIDmode
-                && narrow_mode != GET_MODE (reg);
-              narrow_mode = GET_MODE_WIDER_MODE (narrow_mode))
+         FOR_EACH_MODE_UNTIL (narrow_mode, GET_MODE (reg))
            {
              if (have_insn_for (STRICT_LOW_PART, narrow_mode)
                  && ((reg_offset[regno] & ~GET_MODE_MASK (narrow_mode))
index 41ae7e4fb9cdba8935b2210dc72396104b1b9a5e..f2381067f5e3885b342d0a6e6c661054ee511fc3 100644 (file)
@@ -3315,13 +3315,9 @@ reg_to_stack (void)
   for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
     {
       machine_mode mode;
-      for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
-          mode != VOIDmode;
-          mode = GET_MODE_WIDER_MODE (mode))
+      FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
        FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
-      for (mode = GET_CLASS_NARROWEST_MODE (MODE_COMPLEX_FLOAT);
-          mode != VOIDmode;
-          mode = GET_MODE_WIDER_MODE (mode))
+      FOR_EACH_MODE_IN_CLASS (mode, MODE_COMPLEX_FLOAT)
        FP_MODE_REG (i, mode) = gen_rtx_REG (mode, i);
     }
 
index a7df02d32741be5dd96b573cca25a3ccc4acd012..4239fa3df4e215a5264ab15deb08bfdb57320b2f 100644 (file)
@@ -632,36 +632,28 @@ choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
      held in REGNO.  If none, we look for the largest floating-point mode.
      If we still didn't find a valid mode, try CCmode.  */
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
     if ((unsigned) hard_regno_nregs[regno][mode] == nregs
        && HARD_REGNO_MODE_OK (regno, mode)
        && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
        && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode))
       found_mode = mode;
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
     if ((unsigned) hard_regno_nregs[regno][mode] == nregs
        && HARD_REGNO_MODE_OK (regno, mode)
        && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
        && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode))
       found_mode = mode;
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_FLOAT)
     if ((unsigned) hard_regno_nregs[regno][mode] == nregs
        && HARD_REGNO_MODE_OK (regno, mode)
        && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
        && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode))
       found_mode = mode;
 
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
-       mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
     if ((unsigned) hard_regno_nregs[regno][mode] == nregs
        && HARD_REGNO_MODE_OK (regno, mode)
        && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
index 0d93b6f416ffe8fbe1f25e503879c9874c72ba61..735d86eda0b527da6f271adf86fa457bff1a8ffe 100644 (file)
@@ -5663,10 +5663,8 @@ init_num_sign_bit_copies_in_rep (void)
 {
   machine_mode mode, in_mode;
 
-  for (in_mode = GET_CLASS_NARROWEST_MODE (MODE_INT); in_mode != VOIDmode;
-       in_mode = GET_MODE_WIDER_MODE (mode))
-    for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != in_mode;
-        mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (in_mode, MODE_INT)
+    FOR_EACH_MODE_UNTIL (mode, in_mode)
       {
        machine_mode i;
 
@@ -5677,7 +5675,7 @@ init_num_sign_bit_copies_in_rep (void)
 
        /* We are in in_mode.  Count how many bits outside of mode
           have to be copies of the sign-bit.  */
-       for (i = mode; i != in_mode; i = GET_MODE_WIDER_MODE (i))
+       FOR_EACH_MODE (i, mode, in_mode)
          {
            machine_mode wider = GET_MODE_WIDER_MODE (i);
 
index 2275bfc3df129deabc0c316e339bde832920d759..b85c97de5c3ed954df3692a08f01204a6af94986 100644 (file)
@@ -306,8 +306,7 @@ mode_for_size (unsigned int size, enum mode_class mclass, int limit)
     return BLKmode;
 
   /* Get the first mode which has this size, in the specified class.  */
-  for (mode = GET_CLASS_NARROWEST_MODE (mclass); mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, mclass)
     if (GET_MODE_PRECISION (mode) == size)
       return mode;
 
@@ -348,8 +347,7 @@ smallest_mode_for_size (unsigned int size, enum mode_class mclass)
 
   /* Get the first mode which has at least this size, in the
      specified class.  */
-  for (mode = GET_CLASS_NARROWEST_MODE (mclass); mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, mclass)
     if (GET_MODE_PRECISION (mode) >= size)
       break;
 
@@ -501,7 +499,7 @@ mode_for_vector (machine_mode innermode, unsigned nunits)
 
   /* Do not check vector_mode_supported_p here.  We'll do that
      later in vector_type_mode.  */
-  for (; mode != VOIDmode ; mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_FROM (mode, mode)
     if (GET_MODE_NUNITS (mode) == nunits
        && GET_MODE_INNER (mode) == innermode)
       break;
@@ -1956,8 +1954,7 @@ finish_bitfield_representative (tree repr, tree field)
   gcc_assert (maxbitsize % BITS_PER_UNIT == 0);
 
   /* Find the smallest nice mode to use.  */
-  for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT); mode != VOIDmode;
-       mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
     if (GET_MODE_BITSIZE (mode) >= bitsize)
       break;
   if (mode != VOIDmode
index df0bcd6d459119243a69fc652e761f90d574ca78..0b1c880ecefa47adaa4d29574d984f69f3420cac 100644 (file)
@@ -3946,9 +3946,8 @@ target_supports_divmod_p (optab divmod_optab, optab div_optab, machine_mode mode
     {
       /* If optab_handler exists for div_optab, perhaps in a wider mode,
         we don't want to use the libfunc even if it exists for given mode.  */ 
-      for (machine_mode div_mode = mode;
-          div_mode != VOIDmode;
-          div_mode = GET_MODE_WIDER_MODE (div_mode))
+      machine_mode div_mode;
+      FOR_EACH_MODE_FROM (div_mode, mode)
        if (optab_handler (div_optab, div_mode) != CODE_FOR_nothing)
          return false;
 
index c1b3c24a0b4de526ae8c6752c30ccfd02e0619a3..2415f9489d8c442dda8ea7c64347fc6798c033f2 100644 (file)
@@ -1154,7 +1154,7 @@ type_for_widest_vector_mode (tree type, optab op)
   else
     mode = MIN_MODE_VECTOR_INT;
 
-  for (; mode != VOIDmode; mode = GET_MODE_WIDER_MODE (mode))
+  FOR_EACH_MODE_FROM (mode, mode)
     if (GET_MODE_INNER (mode) == inner_mode
         && GET_MODE_NUNITS (mode) > best_nunits
        && optab_handler (op, mode) != CODE_FOR_nothing)
index 013fb1fc1660a1d2646b5b54a33f8e6a6e4e9bef..48ee5ba98b9860bcf2646ce317c503f5270d5224 100644 (file)
@@ -4245,12 +4245,12 @@ vectorizable_conversion (gimple *stmt, gimple_stmt_iterator *gsi,
              <= GET_MODE_SIZE (TYPE_MODE (rhs_type))))
        goto unsupported;
 
-      rhs_mode = TYPE_MODE (rhs_type);
       fltsz = GET_MODE_SIZE (TYPE_MODE (lhs_type));
-      for (rhs_mode = GET_MODE_2XWIDER_MODE (TYPE_MODE (rhs_type));
-          rhs_mode != VOIDmode && GET_MODE_SIZE (rhs_mode) <= fltsz;
-          rhs_mode = GET_MODE_2XWIDER_MODE (rhs_mode))
+      FOR_EACH_2XWIDER_MODE (rhs_mode, TYPE_MODE (rhs_type))
        {
+         if (GET_MODE_SIZE (rhs_mode) > fltsz)
+           break;
+
          cvt_type
            = build_nonstandard_integer_type (GET_MODE_BITSIZE (rhs_mode), 0);
          cvt_type = get_same_sized_vectype (cvt_type, vectype_in);
index ef2c6aa4c910b5964d3b6075ea8640bb6d17498f..b107ab491aaf072b3fef78a948f7dccfc2e689d3 100644 (file)
@@ -6306,13 +6306,14 @@ prepare_call_arguments (basic_block bb, rtx_insn *insn)
            else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
                     || GET_MODE_CLASS (GET_MODE (x)) == MODE_PARTIAL_INT)
              {
-               machine_mode mode = GET_MODE (x);
+               machine_mode mode;
 
-               while ((mode = GET_MODE_WIDER_MODE (mode)) != VOIDmode
-                      && GET_MODE_BITSIZE (mode) <= BITS_PER_WORD)
+               FOR_EACH_WIDER_MODE (mode, GET_MODE (x))
                  {
-                   rtx reg = simplify_subreg (mode, x, GET_MODE (x), 0);
+                   if (GET_MODE_BITSIZE (mode) > BITS_PER_WORD)
+                     break;
 
+                   rtx reg = simplify_subreg (mode, x, GET_MODE (x), 0);
                    if (reg == NULL_RTX || !REG_P (reg))
                      continue;
                    val = cselib_lookup (reg, mode, 0, VOIDmode);