This means that we know when accessing the modes that the size is
a compile-time constant, even for SVE.  It also enables stricter
type safety in later patches.

2017-07-13  Richard Sandiford  <richard.sandif...@linaro.org>
            Alan Hayward  <alan.hayw...@arm.com>
            David Sherwood  <david.sherw...@arm.com>

gcc/
        * machmode.h (mode_iterator::start): Provide overload for opt_modes.
        (mode_iterator::iterate_p): Likewise.
        (mode_iterator::get_wider): Likewise.
        * expr.c (init_expr_target): Use opt_scalar_float_mode.

gcc/ada/
        * gcc-interface/misc.c (fp_prec_to_size): Use opt_scalar_float_mode.
        (fp_size_to_prec): Likewise.

gcc/c-family/
        * c-cppbuiltin.c (c_cpp_builtins): Use opt_scalar_float_mode.

gcc/fortran/
        * trans-types.c (gfc_init_kinds): Use opt_scalar_float_mode
        and FOR_EACH_MODE_IN_CLASS.

Index: gcc/machmode.h
===================================================================
--- gcc/machmode.h      2017-07-13 09:18:25.916974620 +0100
+++ gcc/machmode.h      2017-07-13 09:18:26.363931259 +0100
@@ -652,6 +652,16 @@ is_float_mode (machine_mode mode, T *flo
 {
   /* Start mode iterator *ITER at the first mode in class MCLASS, if any.  */
 
+  template<typename T>
+  inline void
+  start (opt_mode<T> *iter, enum mode_class mclass)
+  {
+    if (GET_CLASS_NARROWEST_MODE (mclass) == E_VOIDmode)
+      *iter = opt_mode<T> ();
+    else
+      *iter = as_a<T> (GET_CLASS_NARROWEST_MODE (mclass));
+  }
+
   inline void
   start (machine_mode *iter, enum mode_class mclass)
   {
@@ -660,6 +670,13 @@ is_float_mode (machine_mode mode, T *flo
 
   /* Return true if mode iterator *ITER has not reached the end.  */
 
+  template<typename T>
+  inline bool
+  iterate_p (opt_mode<T> *iter)
+  {
+    return iter->exists ();
+  }
+
   inline bool
   iterate_p (machine_mode *iter)
   {
@@ -669,6 +686,13 @@ is_float_mode (machine_mode mode, T *flo
   /* Set mode iterator *ITER to the next widest mode in the same class,
      if any.  */
 
+  template<typename T>
+  inline void
+  get_wider (opt_mode<T> *iter)
+  {
+    *iter = GET_MODE_WIDER_MODE (**iter);
+  }
+
   inline void
   get_wider (machine_mode *iter)
   {
Index: gcc/expr.c
===================================================================
--- gcc/expr.c  2017-07-13 09:18:22.928278591 +0100
+++ gcc/expr.c  2017-07-13 09:18:26.362931356 +0100
@@ -112,7 +112,6 @@ static HOST_WIDE_INT int_expr_size (tree
 init_expr_target (void)
 {
   rtx pat;
-  machine_mode mode;
   int num_clobbers;
   rtx mem, mem1;
   rtx reg;
@@ -131,7 +130,7 @@ init_expr_target (void)
   pat = gen_rtx_SET (NULL_RTX, NULL_RTX);
   PATTERN (insn) = pat;
 
-  for (mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;
+  for (machine_mode mode = VOIDmode; (int) mode < NUM_MACHINE_MODES;
        mode = (machine_mode) ((int) mode + 1))
     {
       int regno;
@@ -177,9 +176,11 @@ init_expr_target (void)
 
   mem = gen_rtx_MEM (VOIDmode, gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 1));
 
-  FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
+  opt_scalar_float_mode mode_iter;
+  FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_FLOAT)
     {
-      machine_mode srcmode;
+      scalar_float_mode mode = *mode_iter;
+      scalar_float_mode srcmode;
       FOR_EACH_MODE_UNTIL (srcmode, mode)
        {
          enum insn_code ic;
Index: gcc/ada/gcc-interface/misc.c
===================================================================
--- gcc/ada/gcc-interface/misc.c        2017-07-13 09:18:21.521430343 +0100
+++ gcc/ada/gcc-interface/misc.c        2017-07-13 09:18:26.361931453 +0100
@@ -1311,11 +1311,11 @@ enumerate_modes (void (*f) (const char *
 int
 fp_prec_to_size (int prec)
 {
-  machine_mode mode;
+  opt_scalar_float_mode mode;
 
   FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
-    if (GET_MODE_PRECISION (mode) == prec)
-      return GET_MODE_BITSIZE (mode);
+    if (GET_MODE_PRECISION (*mode) == prec)
+      return GET_MODE_BITSIZE (*mode);
 
   gcc_unreachable ();
 }
@@ -1325,11 +1325,11 @@ fp_prec_to_size (int prec)
 int
 fp_size_to_prec (int size)
 {
-  machine_mode mode;
+  opt_scalar_float_mode mode;
 
   FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
-    if (GET_MODE_BITSIZE (mode) == size)
-      return GET_MODE_PRECISION (mode);
+    if (GET_MODE_BITSIZE (*mode) == size)
+      return GET_MODE_PRECISION (*mode);
 
   gcc_unreachable ();
 }
Index: gcc/c-family/c-cppbuiltin.c
===================================================================
--- gcc/c-family/c-cppbuiltin.c 2017-07-13 09:18:21.523430126 +0100
+++ gcc/c-family/c-cppbuiltin.c 2017-07-13 09:18:26.361931453 +0100
@@ -1186,9 +1186,10 @@ c_cpp_builtins (cpp_reader *pfile)
   if (flag_building_libgcc)
     {
       /* Properties of floating-point modes for libgcc2.c.  */
-      machine_mode mode;
-      FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
+      opt_scalar_float_mode mode_iter;
+      FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_FLOAT)
        {
+         scalar_float_mode mode = *mode_iter;
          const char *name = GET_MODE_NAME (mode);
          char *macro_name
            = (char *) alloca (strlen (name)
Index: gcc/fortran/trans-types.c
===================================================================
--- gcc/fortran/trans-types.c   2017-07-13 09:18:20.865501731 +0100
+++ gcc/fortran/trans-types.c   2017-07-13 09:18:26.363931259 +0100
@@ -363,6 +363,7 @@ #define NAMED_SUBROUTINE(a,b,c,d) \
 gfc_init_kinds (void)
 {
   machine_mode mode;
+  opt_scalar_float_mode float_mode_iter;
   int i_index, r_index, kind;
   bool saw_i4 = false, saw_i8 = false;
   bool saw_r4 = false, saw_r8 = false, saw_r10 = false, saw_r16 = false;
@@ -418,11 +419,11 @@ gfc_init_kinds (void)
   /* Set the maximum integer kind.  Used with at least BOZ constants.  */
   gfc_max_integer_kind = gfc_integer_kinds[i_index - 1].kind;
 
-  for (r_index = 0, mode = MIN_MODE_FLOAT; mode <= MAX_MODE_FLOAT;
-       mode = (machine_mode) ((int) mode + 1))
+  r_index = 0;
+  FOR_EACH_MODE_IN_CLASS (float_mode_iter, MODE_FLOAT)
     {
-      const struct real_format *fmt =
-       REAL_MODE_FORMAT (mode);
+      scalar_float_mode mode = *float_mode_iter;
+      const struct real_format *fmt = REAL_MODE_FORMAT (mode);
       int kind;
 
       if (fmt == NULL)
@@ -433,8 +434,7 @@ gfc_init_kinds (void)
       /* Only let float, double, long double and __float128 go through.
         Runtime support for others is not provided, so they would be
         useless.  */
-      if (!targetm.libgcc_floating_mode_supported_p ((machine_mode)
-                                                      mode))
+      if (!targetm.libgcc_floating_mode_supported_p (mode))
        continue;
       if (mode != TYPE_MODE (float_type_node)
            && (mode != TYPE_MODE (double_type_node))

Reply via email to