Make mode_for_vector return an opt_mode
authorRichard Sandiford <richard.sandiford@linaro.org>
Tue, 5 Sep 2017 19:57:39 +0000 (19:57 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 5 Sep 2017 19:57:39 +0000 (19:57 +0000)
...following on from the mode_for_size change.  The patch also removes
machmode.h versions of the stor-layout.c comments, since the comments
in the .c file are more complete.

2017-09-05  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
* machmode.h (mode_for_vector): Return an opt_mode.
* stor-layout.c (mode_for_vector): Likewise.
(mode_for_int_vector): Update accordingly.
(layout_type): Likewise.
* config/i386/i386.c (emit_memmov): Likewise.
(ix86_expand_set_or_movmem): Likewise.
(ix86_expand_vector_init): Likewise.
(ix86_get_mask_mode): Likewise.
* config/powerpcspe/powerpcspe.c (rs6000_expand_vec_perm_const_1):
Likewise.
* config/rs6000/rs6000.c (rs6000_expand_vec_perm_const_1): Likewise.
* expmed.c (extract_bit_field_1): Likewise.
* expr.c (expand_expr_real_2): Likewise.
* optabs-query.c (can_vec_perm_p): Likewise.
(can_vec_mask_load_store_p): Likewise.
* optabs.c (expand_vec_perm): Likewise.
* targhooks.c (default_get_mask_mode): Likewise.
* tree-vect-stmts.c (vectorizable_store): Likewise.
(vectorizable_load): Likewise.
(get_vectype_for_scalar_type_and_size): Likewise.

From-SVN: r251730

12 files changed:
gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/powerpcspe/powerpcspe.c
gcc/config/rs6000/rs6000.c
gcc/expmed.c
gcc/expr.c
gcc/machmode.h
gcc/optabs-query.c
gcc/optabs.c
gcc/stor-layout.c
gcc/targhooks.c
gcc/tree-vect-stmts.c

index 03f690fecf4ca9eae3967ef5fe9fab47e187ced4..067040bc98ec5a56027bea7601e859a000dfb459 100644 (file)
@@ -1,3 +1,26 @@
+2017-09-05  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * machmode.h (mode_for_vector): Return an opt_mode.
+       * stor-layout.c (mode_for_vector): Likewise.
+       (mode_for_int_vector): Update accordingly.
+       (layout_type): Likewise.
+       * config/i386/i386.c (emit_memmov): Likewise.
+       (ix86_expand_set_or_movmem): Likewise.
+       (ix86_expand_vector_init): Likewise.
+       (ix86_get_mask_mode): Likewise.
+       * config/powerpcspe/powerpcspe.c (rs6000_expand_vec_perm_const_1):
+       Likewise.
+       * config/rs6000/rs6000.c (rs6000_expand_vec_perm_const_1): Likewise.
+       * expmed.c (extract_bit_field_1): Likewise.
+       * expr.c (expand_expr_real_2): Likewise.
+       * optabs-query.c (can_vec_perm_p): Likewise.
+       (can_vec_mask_load_store_p): Likewise.
+       * optabs.c (expand_vec_perm): Likewise.
+       * targhooks.c (default_get_mask_mode): Likewise.
+       * tree-vect-stmts.c (vectorizable_store): Likewise.
+       (vectorizable_load): Likewise.
+       (get_vectype_for_scalar_type_and_size): Likewise.
+
 2017-09-05  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * machmode.h (mode_for_int_vector): New function.
index 9ceba8088d5833401562284ed3c3a86c375bbdca..8c17da24c1d31face574aa4008bef1257bab95e0 100644 (file)
@@ -27536,9 +27536,8 @@ emit_memmov (rtx destmem, rtx *srcmem, rtx destptr, rtx srcptr,
   if (GET_MODE_SIZE (move_mode) > GET_MODE_SIZE (word_mode))
     {
       int nunits = GET_MODE_SIZE (move_mode) / GET_MODE_SIZE (word_mode);
-      move_mode = mode_for_vector (word_mode, nunits);
-      code = optab_handler (mov_optab, move_mode);
-      if (code == CODE_FOR_nothing)
+      if (!mode_for_vector (word_mode, nunits).exists (&move_mode)
+         || (code = optab_handler (mov_optab, move_mode)) == CODE_FOR_nothing)
        {
          move_mode = word_mode;
          piece_size = GET_MODE_SIZE (move_mode);
@@ -28770,8 +28769,8 @@ ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
       if (GET_MODE_SIZE (move_mode) > GET_MODE_SIZE (word_mode))
        {
          int nunits = GET_MODE_SIZE (move_mode) / GET_MODE_SIZE (word_mode);
-         move_mode = mode_for_vector (word_mode, nunits);
-         if (optab_handler (mov_optab, move_mode) == CODE_FOR_nothing)
+         if (!mode_for_vector (word_mode, nunits).exists (&move_mode)
+             || optab_handler (mov_optab, move_mode) == CODE_FOR_nothing)
            move_mode = word_mode;
        }
       gcc_assert (optab_handler (mov_optab, move_mode) != CODE_FOR_nothing);
@@ -44613,11 +44612,9 @@ ix86_expand_vector_init (bool mmx_ok, rtx target, rtx vals)
          rtx ops[2] = { XVECEXP (vals, 0, 0), XVECEXP (vals, 0, 1) };
          if (inner_mode == QImode || inner_mode == HImode)
            {
-             mode = mode_for_vector (SImode,
-                                     n_elts * GET_MODE_SIZE (inner_mode) / 4);
-             inner_mode
-               = mode_for_vector (SImode,
-                                  n_elts * GET_MODE_SIZE (inner_mode) / 8);
+             unsigned int n_bits = n_elts * GET_MODE_SIZE (inner_mode);
+             mode = mode_for_vector (SImode, n_bits / 4).require ();
+             inner_mode = mode_for_vector (SImode, n_bits / 8).require ();
              ops[0] = gen_lowpart (inner_mode, ops[0]);
              ops[1] = gen_lowpart (inner_mode, ops[1]);
              subtarget = gen_reg_rtx (mode);
@@ -51735,7 +51732,7 @@ ix86_get_mask_mode (unsigned nunits, unsigned vector_size)
 
   gcc_assert (elem_size * nunits == vector_size);
 
-  return mode_for_vector (elem_mode, nunits);
+  return mode_for_vector (elem_mode, nunits).else_blk ();
 }
 
 \f
index 82c36dee6783bc38810304c0ed47e6a671e2aa1f..b964e6ed776bf569ba2c72333430daef1997995f 100644 (file)
@@ -38679,7 +38679,7 @@ rs6000_expand_vec_perm_const_1 (rtx target, rtx op0, rtx op1,
 
       vmode = GET_MODE (target);
       gcc_assert (GET_MODE_NUNITS (vmode) == 2);
-      dmode = mode_for_vector (GET_MODE_INNER (vmode), 4);
+      dmode = mode_for_vector (GET_MODE_INNER (vmode), 4).require ();
       x = gen_rtx_VEC_CONCAT (dmode, op0, op1);
       v = gen_rtvec (2, GEN_INT (perm0), GEN_INT (perm1));
       x = gen_rtx_VEC_SELECT (vmode, x, gen_rtx_PARALLEL (VOIDmode, v));
index 5f3d36133b4287fdb72ee9b62ec08bf2bd90aae5..6d613c38b757cd76229b2c0add41ffac8ff939e1 100644 (file)
@@ -35525,7 +35525,7 @@ rs6000_expand_vec_perm_const_1 (rtx target, rtx op0, rtx op1,
 
       vmode = GET_MODE (target);
       gcc_assert (GET_MODE_NUNITS (vmode) == 2);
-      dmode = mode_for_vector (GET_MODE_INNER (vmode), 4);
+      dmode = mode_for_vector (GET_MODE_INNER (vmode), 4).require ();
       x = gen_rtx_VEC_CONCAT (dmode, op0, op1);
       v = gen_rtvec (2, GEN_INT (perm0), GEN_INT (perm1));
       x = gen_rtx_VEC_SELECT (vmode, x, gen_rtx_PARALLEL (VOIDmode, v));
index 894e3698b32997730e902281f2b1a7e531d3e9c5..7f0cb0a0ec057a73891a6e208b55b6853e8bdc91 100644 (file)
@@ -1578,10 +1578,11 @@ extract_bit_field_1 (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
       machine_mode new_mode = GET_MODE (op0);
       if (GET_MODE_INNER (new_mode) != GET_MODE_INNER (tmode))
        {
-         new_mode = mode_for_vector (GET_MODE_INNER (tmode),
-                                     GET_MODE_BITSIZE (GET_MODE (op0))
-                                     / GET_MODE_UNIT_BITSIZE (tmode));
-         if (!VECTOR_MODE_P (new_mode)
+         scalar_mode inner_mode = GET_MODE_INNER (tmode);
+         unsigned int nunits = (GET_MODE_BITSIZE (GET_MODE (op0))
+                                / GET_MODE_UNIT_BITSIZE (tmode));
+         if (!mode_for_vector (inner_mode, nunits).exists (&new_mode)
+             || !VECTOR_MODE_P (new_mode)
              || GET_MODE_SIZE (new_mode) != GET_MODE_SIZE (GET_MODE (op0))
              || GET_MODE_INNER (new_mode) != GET_MODE_INNER (tmode)
              || !targetm.vector_mode_supported_p (new_mode))
index cc7ec420274a32c446614eb7ac3d6aa2d72aad97..c97f4a63bd2fcb38384766a8546d3fcda2cd6e15 100644 (file)
@@ -9445,7 +9445,7 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
          tree sel_type = TREE_TYPE (treeop2);
          machine_mode vmode
            = mode_for_vector (SCALAR_TYPE_MODE (TREE_TYPE (sel_type)),
-                              TYPE_VECTOR_SUBPARTS (sel_type));
+                              TYPE_VECTOR_SUBPARTS (sel_type)).require ();
          gcc_assert (GET_MODE_CLASS (vmode) == MODE_VECTOR_INT);
          op2 = simplify_subreg (vmode, op2, TYPE_MODE (sel_type), 0);
          gcc_assert (op2 && GET_CODE (op2) == CONST_VECTOR);
index 7dd71e90d3db7bec48c491100ffd5e924cd070d4..ca3092477398a800ba175b508d839b45c4bfd9c4 100644 (file)
@@ -682,8 +682,6 @@ decimal_float_mode_for_size (unsigned int size)
     (mode_for_size (size, MODE_DECIMAL_FLOAT, 0));
 }
 
-/* Similar to mode_for_size, but find the smallest mode for a given width.  */
-
 extern machine_mode smallest_mode_for_size (unsigned int, enum mode_class);
 
 /* Find the narrowest integer mode that contains at least SIZE bits.
@@ -695,17 +693,9 @@ smallest_int_mode_for_size (unsigned int size)
   return as_a <scalar_int_mode> (smallest_mode_for_size (size, MODE_INT));
 }
 
-/* Return an integer mode of exactly the same size as the input mode.  */
-
 extern opt_scalar_int_mode int_mode_for_mode (machine_mode);
-
 extern machine_mode bitwise_mode_for_mode (machine_mode);
-
-/* Return a mode that is suitable for representing a vector,
-   or BLKmode on failure.  */
-
-extern machine_mode mode_for_vector (scalar_mode, unsigned);
-
+extern opt_machine_mode mode_for_vector (scalar_mode, unsigned);
 extern opt_machine_mode mode_for_int_vector (unsigned int, unsigned int);
 
 /* Return the integer vector equivalent of MODE, if one exists.  In other
index f6060731f9351301475f38bf4e8ea4eae3e3e58f..9afdd1fe4f3e93aee118e2f1d623d343d1cab497 100644 (file)
@@ -376,10 +376,9 @@ can_vec_perm_p (machine_mode mode, bool variable,
     return true;
 
   /* We allow fallback to a QI vector mode, and adjust the mask.  */
-  if (GET_MODE_INNER (mode) == QImode)
-    return false;
-  qimode = mode_for_vector (QImode, GET_MODE_SIZE (mode));
-  if (!VECTOR_MODE_P (qimode))
+  if (GET_MODE_INNER (mode) == QImode
+      || !mode_for_vector (QImode, GET_MODE_SIZE (mode)).exists (&qimode)
+      || !VECTOR_MODE_P (qimode))
     return false;
 
   /* ??? For completeness, we ought to check the QImode version of
@@ -547,12 +546,14 @@ can_vec_mask_load_store_p (machine_mode mode,
       vector_sizes &= ~cur;
       if (cur <= GET_MODE_SIZE (smode))
        continue;
-      vmode = mode_for_vector (smode, cur / GET_MODE_SIZE (smode));
-      mask_mode = targetm.vectorize.get_mask_mode (GET_MODE_NUNITS (vmode),
-                                                  cur);
-      if (VECTOR_MODE_P (vmode)
-         && convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing)
-       return true;
+      unsigned int nunits = cur / GET_MODE_SIZE (smode);
+      if (mode_for_vector (smode, nunits).exists (&vmode)
+         && VECTOR_MODE_P (vmode))
+       {
+         mask_mode = targetm.vectorize.get_mask_mode (nunits, cur);
+         if (convert_optab_handler (op, vmode, mask_mode) != CODE_FOR_nothing)
+           return true;
+       }
     }
   return false;
 }
index b65707080eee32385e370580a3039e034b6f66ca..67dfa58ff462b9393bc5d049c526b5f930dd7e25 100644 (file)
@@ -5434,13 +5434,10 @@ expand_vec_perm (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target)
 
   /* Set QIMODE to a different vector mode with byte elements.
      If no such mode, or if MODE already has byte elements, use VOIDmode.  */
-  qimode = VOIDmode;
-  if (GET_MODE_INNER (mode) != QImode)
-    {
-      qimode = mode_for_vector (QImode, w);
-      if (!VECTOR_MODE_P (qimode))
-       qimode = VOIDmode;
-    }
+  if (GET_MODE_INNER (mode) == QImode
+      || !mode_for_vector (QImode, w).exists (&qimode)
+      || !VECTOR_MODE_P (qimode))
+    qimode = VOIDmode;
 
   /* If the input is a constant, expand it specially.  */
   gcc_assert (GET_MODE_CLASS (GET_MODE (sel)) == MODE_VECTOR_INT);
index 6bb7b246c25d03388e6506245aacb1ebdc593900..baaf5f340a5a718477905399ed375089ff1795b9 100644 (file)
@@ -471,11 +471,11 @@ bitwise_type_for_mode (machine_mode mode)
   return inner_type;
 }
 
-/* Find a mode that is suitable for representing a vector with
-   NUNITS elements of mode INNERMODE.  Returns BLKmode if there
-   is no suitable mode.  */
+/* Find a mode that is suitable for representing a vector with NUNITS
+   elements of mode INNERMODE, if one exists.  The returned mode can be
+   either an integer mode or a vector mode.  */
 
-machine_mode
+opt_machine_mode
 mode_for_vector (scalar_mode innermode, unsigned nunits)
 {
   machine_mode mode;
@@ -499,22 +499,18 @@ mode_for_vector (scalar_mode innermode, unsigned nunits)
   FOR_EACH_MODE_FROM (mode, mode)
     if (GET_MODE_NUNITS (mode) == nunits
        && GET_MODE_INNER (mode) == innermode)
-      break;
+      return mode;
 
   /* For integers, try mapping it to a same-sized scalar mode.  */
-  if (mode == VOIDmode
-      && GET_MODE_CLASS (innermode) == MODE_INT)
+  if (GET_MODE_CLASS (innermode) == MODE_INT)
     {
       unsigned int nbits = nunits * GET_MODE_BITSIZE (innermode);
-      mode = int_mode_for_size (nbits, 0).else_blk ();
+      if (int_mode_for_size (nbits, 0).exists (&mode)
+         && have_regs_of_mode[mode])
+       return mode;
     }
 
-  if (mode == VOIDmode
-      || (GET_MODE_CLASS (mode) == MODE_INT
-         && !have_regs_of_mode[mode]))
-    return BLKmode;
-
-  return mode;
+  return opt_machine_mode ();
 }
 
 /* Return the mode for a vector that has NUNITS integer elements of
@@ -525,12 +521,10 @@ opt_machine_mode
 mode_for_int_vector (unsigned int int_bits, unsigned int nunits)
 {
   scalar_int_mode int_mode;
-  if (int_mode_for_size (int_bits, 0).exists (&int_mode))
-    {
-      machine_mode vec_mode = mode_for_vector (int_mode, nunits);
-      if (vec_mode != BLKmode)
-       return vec_mode;
-    }
+  machine_mode vec_mode;
+  if (int_mode_for_size (int_bits, 0).exists (&int_mode)
+      && mode_for_vector (int_mode, nunits).exists (&vec_mode))
+    return vec_mode;
   return opt_machine_mode ();
 }
 
@@ -2264,7 +2258,7 @@ layout_type (tree type)
        if (TYPE_MODE (type) == VOIDmode)
          SET_TYPE_MODE (type,
                         mode_for_vector (SCALAR_TYPE_MODE (innertype),
-                                         nunits));
+                                         nunits).else_blk ());
 
        TYPE_SATURATING (type) = TYPE_SATURATING (TREE_TYPE (type));
         TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
index 0a4274785363ecc5211cb257cabf714f548bec36..078647c191c1995885f1d7fcd8f08fa7d3125fef 100644 (file)
@@ -1210,8 +1210,8 @@ default_get_mask_mode (unsigned nunits, unsigned vector_size)
 
   gcc_assert (elem_size * nunits == vector_size);
 
-  vector_mode = mode_for_vector (elem_mode, nunits);
-  if (!VECTOR_MODE_P (vector_mode)
+  if (!mode_for_vector (elem_mode, nunits).exists (&vector_mode)
+      || !VECTOR_MODE_P (vector_mode)
       || !targetm.vector_mode_supported_p (vector_mode))
     vector_mode = BLKmode;
 
index ce438930c3ff30f31ac5b8c347a616b41801f367..6b12f7a63aa3e2212bec45dfc08726d48798e4f4 100644 (file)
@@ -6038,8 +6038,9 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
              /* First check if vec_extract optab doesn't support extraction
                 of vector elts directly.  */
              scalar_mode elmode = SCALAR_TYPE_MODE (elem_type);
-             machine_mode vmode = mode_for_vector (elmode, group_size);
-             if (! VECTOR_MODE_P (vmode)
+             machine_mode vmode;
+             if (!mode_for_vector (elmode, group_size).exists (&vmode)
+                 || !VECTOR_MODE_P (vmode)
                  || (convert_optab_handler (vec_extract_optab,
                                             TYPE_MODE (vectype), vmode)
                      == CODE_FOR_nothing))
@@ -6052,11 +6053,12 @@ vectorizable_store (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
                  unsigned lsize
                    = group_size * GET_MODE_BITSIZE (elmode);
                  elmode = int_mode_for_size (lsize, 0).require ();
-                 vmode = mode_for_vector (elmode, nunits / group_size);
                  /* If we can't construct such a vector fall back to
                     element extracts from the original vector type and
                     element size stores.  */
-                 if (VECTOR_MODE_P (vmode)
+                 if (mode_for_vector (elmode,
+                                      nunits / group_size).exists (&vmode)
+                     && VECTOR_MODE_P (vmode)
                      && (convert_optab_handler (vec_extract_optab,
                                                 vmode, elmode)
                          != CODE_FOR_nothing))
@@ -7076,8 +7078,9 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
              /* First check if vec_init optab supports construction from
                 vector elts directly.  */
              scalar_mode elmode = SCALAR_TYPE_MODE (TREE_TYPE (vectype));
-             machine_mode vmode = mode_for_vector (elmode, group_size);
-             if (VECTOR_MODE_P (vmode)
+             machine_mode vmode;
+             if (mode_for_vector (elmode, group_size).exists (&vmode)
+                 && VECTOR_MODE_P (vmode)
                  && (convert_optab_handler (vec_init_optab,
                                             TYPE_MODE (vectype), vmode)
                      != CODE_FOR_nothing))
@@ -7098,10 +7101,11 @@ vectorizable_load (gimple *stmt, gimple_stmt_iterator *gsi, gimple **vec_stmt,
                  unsigned lsize
                    = group_size * TYPE_PRECISION (TREE_TYPE (vectype));
                  elmode = int_mode_for_size (lsize, 0).require ();
-                 vmode = mode_for_vector (elmode, nunits / group_size);
                  /* If we can't construct such a vector fall back to
                     element loads of the original vector type.  */
-                 if (VECTOR_MODE_P (vmode)
+                 if (mode_for_vector (elmode,
+                                      nunits / group_size).exists (&vmode)
+                     && VECTOR_MODE_P (vmode)
                      && (convert_optab_handler (vec_init_optab, vmode, elmode)
                          != CODE_FOR_nothing))
                    {
@@ -9104,8 +9108,8 @@ get_vectype_for_scalar_type_and_size (tree scalar_type, unsigned size)
      lookup a vector mode of the specified size.  */
   if (size == 0)
     simd_mode = targetm.vectorize.preferred_simd_mode (inner_mode);
-  else
-    simd_mode = mode_for_vector (inner_mode, size / nbytes);
+  else if (!mode_for_vector (inner_mode, size / nbytes).exists (&simd_mode))
+    return NULL_TREE;
   nunits = GET_MODE_SIZE (simd_mode) / nbytes;
   /* NOTE: nunits == 1 is allowed to support single element vector types.  */
   if (nunits < 1)