[39/77] Two changes to the get_best_mode interface
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 30 Aug 2017 11:14:49 +0000 (11:14 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 30 Aug 2017 11:14:49 +0000 (11:14 +0000)
get_best_mode always returns a scalar_int_mode on success,
so this patch makes that explicit in the type system.  Also,
the "largest_mode" argument is used simply to provide a maximum
size, and in practice that size is always a compile-time constant,
even when the concept of variable-sized modes is added later.
The patch therefore passes the size directly.

2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* machmode.h (bit_field_mode_iterator::next_mode): Take a pointer
to a scalar_int_mode instead of a machine_mode.
(bit_field_mode_iterator::m_mode): Change type to opt_scalar_int_mode.
(get_best_mode): Return a boolean and use a pointer argument to store
the selected mode.  Replace the limit mode parameter with a bit limit.
* expmed.c (adjust_bit_field_mem_for_reg): Use scalar_int_mode
for the values returned by bit_field_mode_iterator::next_mode.
(store_bit_field): Update call to get_best_mode.
(store_fixed_bit_field): Likewise.
(extract_fixed_bit_field): Likewise.
* expr.c (optimize_bitfield_assignment_op): Likewise.
* fold-const.c (optimize_bit_field_compare): Likewise.
(fold_truth_andor_1): Likewise.
* stor-layout.c (bit_field_mode_iterator::next_mode): As above.
Update for new type of m_mode.
(get_best_mode): As above.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r251491

gcc/ChangeLog
gcc/expmed.c
gcc/expr.c
gcc/fold-const.c
gcc/machmode.h
gcc/stor-layout.c

index 6b028e45276081a2c488418087b1aa6298bc813e..ac4425102014d3b79d71430a47cc9283be0826ea 100644 (file)
@@ -1,3 +1,24 @@
+2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * machmode.h (bit_field_mode_iterator::next_mode): Take a pointer
+       to a scalar_int_mode instead of a machine_mode.
+       (bit_field_mode_iterator::m_mode): Change type to opt_scalar_int_mode.
+       (get_best_mode): Return a boolean and use a pointer argument to store
+       the selected mode.  Replace the limit mode parameter with a bit limit.
+       * expmed.c (adjust_bit_field_mem_for_reg): Use scalar_int_mode
+       for the values returned by bit_field_mode_iterator::next_mode.
+       (store_bit_field): Update call to get_best_mode.
+       (store_fixed_bit_field): Likewise.
+       (extract_fixed_bit_field): Likewise.
+       * expr.c (optimize_bitfield_assignment_op): Likewise.
+       * fold-const.c (optimize_bit_field_compare): Likewise.
+       (fold_truth_andor_1): Likewise.
+       * stor-layout.c (bit_field_mode_iterator::next_mode): As above.
+       Update for new type of m_mode.
+       (get_best_mode): As above.
+
 2017-08-30  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index 051e048e806f25abfc0f8b001ac11bc3b31bc4d7..641bc244a30f1df55b01513f31449f081c74c4d4 100644 (file)
@@ -461,7 +461,7 @@ adjust_bit_field_mem_for_reg (enum extraction_pattern pattern,
   bit_field_mode_iterator iter (bitsize, bitnum, bitregion_start,
                                bitregion_end, MEM_ALIGN (op0),
                                MEM_VOLATILE_P (op0));
-  machine_mode best_mode;
+  scalar_int_mode best_mode;
   if (iter.next_mode (&best_mode))
     {
       /* We can use a memory in BEST_MODE.  See whether this is true for
@@ -479,7 +479,7 @@ adjust_bit_field_mem_for_reg (enum extraction_pattern pattern,
                                            fieldmode))
            limit_mode = insn.field_mode;
 
-         machine_mode wider_mode;
+         scalar_int_mode wider_mode;
          while (iter.next_mode (&wider_mode)
                 && GET_MODE_SIZE (wider_mode) <= GET_MODE_SIZE (limit_mode))
            best_mode = wider_mode;
@@ -1095,7 +1095,8 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
      bit region.  */
   if (MEM_P (str_rtx) && bitregion_start > 0)
     {
-      machine_mode bestmode;
+      scalar_int_mode best_mode;
+      machine_mode addr_mode = VOIDmode;
       HOST_WIDE_INT offset, size;
 
       gcc_assert ((bitregion_start % BITS_PER_UNIT) == 0);
@@ -1105,11 +1106,13 @@ store_bit_field (rtx str_rtx, unsigned HOST_WIDE_INT bitsize,
       size = (bitnum + bitsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
       bitregion_end -= bitregion_start;
       bitregion_start = 0;
-      bestmode = get_best_mode (bitsize, bitnum,
-                               bitregion_start, bitregion_end,
-                               MEM_ALIGN (str_rtx), VOIDmode,
-                               MEM_VOLATILE_P (str_rtx));
-      str_rtx = adjust_bitfield_address_size (str_rtx, bestmode, offset, size);
+      if (get_best_mode (bitsize, bitnum,
+                        bitregion_start, bitregion_end,
+                        MEM_ALIGN (str_rtx), INT_MAX,
+                        MEM_VOLATILE_P (str_rtx), &best_mode))
+       addr_mode = best_mode;
+      str_rtx = adjust_bitfield_address_size (str_rtx, addr_mode,
+                                             offset, size);
     }
 
   if (!store_bit_field_1 (str_rtx, bitsize, bitnum,
@@ -1143,10 +1146,10 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
       if (GET_MODE_BITSIZE (mode) == 0
          || GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (word_mode))
        mode = word_mode;
-      mode = get_best_mode (bitsize, bitnum, bitregion_start, bitregion_end,
-                           MEM_ALIGN (op0), mode, MEM_VOLATILE_P (op0));
-
-      if (mode == VOIDmode)
+      scalar_int_mode best_mode;
+      if (!get_best_mode (bitsize, bitnum, bitregion_start, bitregion_end,
+                         MEM_ALIGN (op0), GET_MODE_BITSIZE (mode),
+                         MEM_VOLATILE_P (op0), &best_mode))
        {
          /* The only way this should occur is if the field spans word
             boundaries.  */
@@ -1155,7 +1158,7 @@ store_fixed_bit_field (rtx op0, unsigned HOST_WIDE_INT bitsize,
          return;
        }
 
-      op0 = narrow_bit_field_mem (op0, mode, bitsize, bitnum, &bitnum);
+      op0 = narrow_bit_field_mem (op0, best_mode, bitsize, bitnum, &bitnum);
     }
 
   store_fixed_bit_field_1 (op0, bitsize, bitnum, value, reverse);
@@ -1998,11 +2001,9 @@ extract_fixed_bit_field (machine_mode tmode, rtx op0,
 {
   if (MEM_P (op0))
     {
-      machine_mode mode
-       = get_best_mode (bitsize, bitnum, 0, 0, MEM_ALIGN (op0), word_mode,
-                        MEM_VOLATILE_P (op0));
-
-      if (mode == VOIDmode)
+      scalar_int_mode mode;
+      if (!get_best_mode (bitsize, bitnum, 0, 0, MEM_ALIGN (op0),
+                         BITS_PER_WORD, MEM_VOLATILE_P (op0), &mode))
        /* The only way this should occur is if the field spans word
           boundaries.  */
        return extract_split_bit_field (op0, bitsize, bitnum, unsignedp,
index 4299df23e14f90338b4d8009abf8b8535d4a73c5..0006377d9891fae72559a3069778a96f7de22e0c 100644 (file)
@@ -4682,13 +4682,14 @@ optimize_bitfield_assignment_op (unsigned HOST_WIDE_INT bitsize,
       unsigned HOST_WIDE_INT offset1;
 
       if (str_bitsize == 0 || str_bitsize > BITS_PER_WORD)
-       str_mode = word_mode;
-      str_mode = get_best_mode (bitsize, bitpos,
-                               bitregion_start, bitregion_end,
-                               MEM_ALIGN (str_rtx), str_mode, 0);
-      if (str_mode == VOIDmode)
+       str_bitsize = BITS_PER_WORD;
+
+      scalar_int_mode best_mode;
+      if (!get_best_mode (bitsize, bitpos, bitregion_start, bitregion_end,
+                         MEM_ALIGN (str_rtx), str_bitsize, false, &best_mode))
        return false;
-      str_bitsize = GET_MODE_BITSIZE (str_mode);
+      str_mode = best_mode;
+      str_bitsize = GET_MODE_BITSIZE (best_mode);
 
       offset1 = bitpos;
       bitpos %= str_bitsize;
index d4d3c444297e3db61dc613c7bc7bd70df202201b..492d7f16169226ac5c0cb6863827df07688879cd 100644 (file)
@@ -3934,7 +3934,8 @@ optimize_bit_field_compare (location_t loc, enum tree_code code,
   tree type = TREE_TYPE (lhs);
   tree unsigned_type;
   int const_p = TREE_CODE (rhs) == INTEGER_CST;
-  machine_mode lmode, rmode, nmode;
+  machine_mode lmode, rmode;
+  scalar_int_mode nmode;
   int lunsignedp, runsignedp;
   int lreversep, rreversep;
   int lvolatilep = 0, rvolatilep = 0;
@@ -3981,12 +3982,11 @@ optimize_bit_field_compare (location_t loc, enum tree_code code,
 
   /* See if we can find a mode to refer to this field.  We should be able to,
      but fail if we can't.  */
-  nmode = get_best_mode (lbitsize, lbitpos, bitstart, bitend,
-                        const_p ? TYPE_ALIGN (TREE_TYPE (linner))
-                        : MIN (TYPE_ALIGN (TREE_TYPE (linner)),
-                               TYPE_ALIGN (TREE_TYPE (rinner))),
-                        word_mode, false);
-  if (nmode == VOIDmode)
+  if (!get_best_mode (lbitsize, lbitpos, bitstart, bitend,
+                     const_p ? TYPE_ALIGN (TREE_TYPE (linner))
+                     : MIN (TYPE_ALIGN (TREE_TYPE (linner)),
+                            TYPE_ALIGN (TREE_TYPE (rinner))),
+                     BITS_PER_WORD, false, &nmode))
     return 0;
 
   /* Set signed and unsigned types of the precision of this mode for the
@@ -5591,7 +5591,7 @@ fold_truth_andor_1 (location_t loc, enum tree_code code, tree truth_type,
   int ll_unsignedp, lr_unsignedp, rl_unsignedp, rr_unsignedp;
   int ll_reversep, lr_reversep, rl_reversep, rr_reversep;
   machine_mode ll_mode, lr_mode, rl_mode, rr_mode;
-  machine_mode lnmode, rnmode;
+  scalar_int_mode lnmode, rnmode;
   tree ll_mask, lr_mask, rl_mask, rr_mask;
   tree ll_and_mask, lr_and_mask, rl_and_mask, rr_and_mask;
   tree l_const, r_const;
@@ -5777,10 +5777,9 @@ fold_truth_andor_1 (location_t loc, enum tree_code code, tree truth_type,
      to be relative to a field of that size.  */
   first_bit = MIN (ll_bitpos, rl_bitpos);
   end_bit = MAX (ll_bitpos + ll_bitsize, rl_bitpos + rl_bitsize);
-  lnmode = get_best_mode (end_bit - first_bit, first_bit, 0, 0,
-                         TYPE_ALIGN (TREE_TYPE (ll_inner)), word_mode,
-                         volatilep);
-  if (lnmode == VOIDmode)
+  if (!get_best_mode (end_bit - first_bit, first_bit, 0, 0,
+                     TYPE_ALIGN (TREE_TYPE (ll_inner)), BITS_PER_WORD,
+                     volatilep, &lnmode))
     return 0;
 
   lnbitsize = GET_MODE_BITSIZE (lnmode);
@@ -5842,10 +5841,9 @@ fold_truth_andor_1 (location_t loc, enum tree_code code, tree truth_type,
 
       first_bit = MIN (lr_bitpos, rr_bitpos);
       end_bit = MAX (lr_bitpos + lr_bitsize, rr_bitpos + rr_bitsize);
-      rnmode = get_best_mode (end_bit - first_bit, first_bit, 0, 0,
-                             TYPE_ALIGN (TREE_TYPE (lr_inner)), word_mode,
-                             volatilep);
-      if (rnmode == VOIDmode)
+      if (!get_best_mode (end_bit - first_bit, first_bit, 0, 0,
+                         TYPE_ALIGN (TREE_TYPE (lr_inner)), BITS_PER_WORD,
+                         volatilep, &rnmode))
        return 0;
 
       rnbitsize = GET_MODE_BITSIZE (rnmode);
index a9fc93a8fd2d8467176d4d7c72d3c74bf9e5dc49..5f3e031324ec4656aa1d4a30cf7abd0eff54093d 100644 (file)
@@ -617,11 +617,11 @@ public:
   bit_field_mode_iterator (HOST_WIDE_INT, HOST_WIDE_INT,
                           HOST_WIDE_INT, HOST_WIDE_INT,
                           unsigned int, bool);
-  bool next_mode (machine_mode *);
+  bool next_mode (scalar_int_mode *);
   bool prefer_smaller_modes ();
 
 private:
-  machine_mode m_mode;
+  opt_scalar_int_mode m_mode;
   /* We use signed values here because the bit position can be negative
      for invalid input such as gcc.dg/pr48335-8.c.  */
   HOST_WIDE_INT m_bitsize;
@@ -635,11 +635,9 @@ private:
 
 /* Find the best mode to use to access a bit field.  */
 
-extern machine_mode get_best_mode (int, int,
-                                       unsigned HOST_WIDE_INT,
-                                       unsigned HOST_WIDE_INT,
-                                       unsigned int,
-                                       machine_mode, bool);
+extern bool get_best_mode (int, int, unsigned HOST_WIDE_INT,
+                          unsigned HOST_WIDE_INT, unsigned int,
+                          unsigned HOST_WIDE_INT, bool, scalar_int_mode *);
 
 /* Determine alignment, 1<=result<=BIGGEST_ALIGNMENT.  */
 
index e37c15f3dad406e508ce96ffae50703a17bf5ae1..707c077f1c9adcd809ad605c575b367052cf6353 100644 (file)
@@ -2748,15 +2748,15 @@ bit_field_mode_iterator
    available, storing it in *OUT_MODE if so.  */
 
 bool
-bit_field_mode_iterator::next_mode (machine_mode *out_mode)
+bit_field_mode_iterator::next_mode (scalar_int_mode *out_mode)
 {
-  for (; m_mode != VOIDmode;
-       m_mode = GET_MODE_WIDER_MODE (m_mode).else_void ())
+  scalar_int_mode mode;
+  for (; m_mode.exists (&mode); m_mode = GET_MODE_WIDER_MODE (mode))
     {
-      unsigned int unit = GET_MODE_BITSIZE (m_mode);
+      unsigned int unit = GET_MODE_BITSIZE (mode);
 
       /* Skip modes that don't have full precision.  */
-      if (unit != GET_MODE_PRECISION (m_mode))
+      if (unit != GET_MODE_PRECISION (mode))
        continue;
 
       /* Stop if the mode is too wide to handle efficiently.  */
@@ -2783,12 +2783,12 @@ bit_field_mode_iterator::next_mode (machine_mode *out_mode)
        break;
 
       /* Stop if the mode requires too much alignment.  */
-      if (GET_MODE_ALIGNMENT (m_mode) > m_align
-         && SLOW_UNALIGNED_ACCESS (m_mode, m_align))
+      if (GET_MODE_ALIGNMENT (mode) > m_align
+         && SLOW_UNALIGNED_ACCESS (mode, m_align))
        break;
 
-      *out_mode = m_mode;
-      m_mode = GET_MODE_WIDER_MODE (m_mode).else_void ();
+      *out_mode = mode;
+      m_mode = GET_MODE_WIDER_MODE (mode);
       m_count++;
       return true;
     }
@@ -2815,12 +2815,14 @@ bit_field_mode_iterator::prefer_smaller_modes ()
    memory access to that range.  Otherwise, we are allowed to touch
    any adjacent non bit-fields.
 
-   The underlying object is known to be aligned to a boundary of ALIGN bits.
-   If LARGEST_MODE is not VOIDmode, it means that we should not use a mode
-   larger than LARGEST_MODE (usually SImode).
+   The chosen mode must have no more than LARGEST_MODE_BITSIZE bits.
+   INT_MAX is a suitable value for LARGEST_MODE_BITSIZE if the caller
+   doesn't want to apply a specific limit.
 
    If no mode meets all these conditions, we return VOIDmode.
 
+   The underlying object is known to be aligned to a boundary of ALIGN bits.
+
    If VOLATILEP is false and SLOW_BYTE_ACCESS is false, we return the
    smallest mode meeting these conditions.
 
@@ -2831,17 +2833,18 @@ bit_field_mode_iterator::prefer_smaller_modes ()
    If VOLATILEP is true the narrow_volatile_bitfields target hook is used to
    decide which of the above modes should be used.  */
 
-machine_mode
+bool
 get_best_mode (int bitsize, int bitpos,
               unsigned HOST_WIDE_INT bitregion_start,
               unsigned HOST_WIDE_INT bitregion_end,
               unsigned int align,
-              machine_mode largest_mode, bool volatilep)
+              unsigned HOST_WIDE_INT largest_mode_bitsize, bool volatilep,
+              scalar_int_mode *best_mode)
 {
   bit_field_mode_iterator iter (bitsize, bitpos, bitregion_start,
                                bitregion_end, align, volatilep);
-  machine_mode widest_mode = VOIDmode;
-  machine_mode mode;
+  scalar_int_mode mode;
+  bool found = false;
   while (iter.next_mode (&mode)
         /* ??? For historical reasons, reject modes that would normally
            receive greater alignment, even if unaligned accesses are
@@ -2900,14 +2903,15 @@ get_best_mode (int bitsize, int bitpos,
            so that the final bitfield reference still has a MEM_EXPR
            and MEM_OFFSET.  */
         && GET_MODE_ALIGNMENT (mode) <= align
-        && (largest_mode == VOIDmode
-            || GET_MODE_SIZE (mode) <= GET_MODE_SIZE (largest_mode)))
+        && GET_MODE_BITSIZE (mode) <= largest_mode_bitsize)
     {
-      widest_mode = mode;
+      *best_mode = mode;
+      found = true;
       if (iter.prefer_smaller_modes ())
        break;
     }
-  return widest_mode;
+
+  return found;
 }
 
 /* Gets minimal and maximal values for MODE (signed or unsigned depending on