public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-3275] machmode: Introduce GET_MODE_NEXT_MODE with previous GET_MODE_WIDER_MODE meaning, add new GET_MODE_W
@ 2022-10-13 14:24 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2022-10-13 14:24 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:4b7966191a69238c6d6fd5537b3e77c3a4027eb2

commit r13-3275-g4b7966191a69238c6d6fd5537b3e77c3a4027eb2
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Thu Oct 13 16:22:21 2022 +0200

    machmode: Introduce GET_MODE_NEXT_MODE with previous GET_MODE_WIDER_MODE meaning, add new GET_MODE_WIDER_MODE
    
    On Wed, Oct 05, 2022 at 04:02:25PM -0400, Jason Merrill wrote:
    > > > > @@ -5716,7 +5716,13 @@ emit_store_flag_1 (rtx target, enum rtx_
    > > > >        {
    > > > >         machine_mode optab_mode = mclass == MODE_CC ? CCmode : compare_mode;
    > > > >         icode = optab_handler (cstore_optab, optab_mode);
    > > > > -     if (icode != CODE_FOR_nothing)
    > > > > +     if (icode != CODE_FOR_nothing
    > > > > +        /* Don't consider [BH]Fmode as usable wider mode, as neither is
    > > > > +           a subset or superset of the other.  */
    > > > > +        && (compare_mode == mode
    > > > > +            || !SCALAR_FLOAT_MODE_P (compare_mode)
    > > > > +            || maybe_ne (GET_MODE_PRECISION (compare_mode),
    > > > > +                         GET_MODE_PRECISION (mode))))
    > > >
    > > > Why do you need to do this here (and in prepare_cmp_insn, and similarly in
    > > > can_compare_p)?  Shouldn't get_wider skip over modes that are not actually
    > > > wider?
    > >
    > > I'm afraid too many places rely on all modes of a certain class to be
    > > visible when walking from "narrowest" to "widest" mode, say
    > > FOR_EACH_MODE_IN_CLASS/FOR_EACH_MODE/FOR_EACH_MODE_UNTIL/FOR_EACH_WIDER_MODE
    > > etc. wouldn't work at all if GET_MODE_WIDER_MODE (BFmode) == SFmode
    > > && GET_MODE_WIDER_MODE (HFmode) == SFmode.
    >
    > Yes, it seems they need to change now that their assumptions have been
    > violated.  I suppose FOR_EACH_MODE_IN_CLASS would need to change to not use
    > get_wider, and users of FOR_EACH_MODE/FOR_EACH_MODE_UNTIL need to decide
    > whether they want an iteration that uses get_wider (likely with a new name)
    > or not.
    
    Here is a patch which does that.
    
    Though I admit I didn't go carefully through all 24 GET_MODE_WIDER_MODE
    uses, 54 FOR_EACH_MODE_IN_CLASS uses, 3 FOR_EACH_MODE uses, 24
    FOR_EACH_MODE_FROM, 6 FOR_EACH_MODE_UNTIL and 15 FOR_EACH_WIDER_MODE uses.
    It is more important to go through the GET_MODE_WIDER_MODE and
    FOR_EACH_WIDER_MODE uses because the patch changes behavior for those,
    the rest keep their previous meaning and so can be changed incrementally
    if the other meaning is desirable to them (I've of course changed the 3
    spots I had to change in the previous BFmode patch and whatever triggered
    during the bootstraps).
    
    2022-10-13  Jakub Jelinek  <jakub@redhat.com>
    
            * genmodes.cc (emit_mode_wider): Emit previous content of
            mode_wider array into mode_next array and for mode_wider
            emit always VOIDmode for !CLASS_HAS_WIDER_MODES_P classes,
            otherwise skip through modes with the same precision.
            * machmode.h (mode_next): Declare.
            (GET_MODE_NEXT_MODE): New inline function.
            (mode_iterator::get_next, mode_iterator::get_known_next): New
            function templates.
            (FOR_EACH_MODE_IN_CLASS): Use get_next instead of get_wider.
            (FOR_EACH_MODE): Use get_known_next instead of get_known_wider.
            (FOR_EACH_MODE_FROM): Use get_next instead of get_wider.
            (FOR_EACH_WIDER_MODE_FROM): Define.
            (FOR_EACH_NEXT_MODE): Define.
            * expmed.cc (emit_store_flag_1): Use FOR_EACH_WIDER_MODE_FROM
            instead of FOR_EACH_MODE_FROM.
            * optabs.cc (prepare_cmp_insn): Likewise.  Remove redundant
            !CLASS_HAS_WIDER_MODES_P check.
            (prepare_float_lib_cmp): Use FOR_EACH_WIDER_MODE_FROM instead of
            FOR_EACH_MODE_FROM.
            * config/i386/i386-expand.cc (get_mode_wider_vector): Use
            GET_MODE_NEXT_MODE instead of GET_MODE_WIDER_MODE.

Diff:
---
 gcc/config/i386/i386-expand.cc |  2 +-
 gcc/expmed.cc                  |  2 +-
 gcc/genmodes.cc                | 33 +++++++++++++++++++-
 gcc/machmode.h                 | 70 ++++++++++++++++++++++++++++++++++++++----
 gcc/optabs.cc                  |  8 ++---
 5 files changed, 101 insertions(+), 14 deletions(-)

diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 6baff6d0e61..a0f8a98986e 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -14941,7 +14941,7 @@ static machine_mode
 get_mode_wider_vector (machine_mode o)
 {
   /* ??? Rely on the ordering that genmodes.cc gives to vectors.  */
-  machine_mode n = GET_MODE_WIDER_MODE (o).require ();
+  machine_mode n = GET_MODE_NEXT_MODE (o).require ();
   gcc_assert (GET_MODE_NUNITS (o) == GET_MODE_NUNITS (n) * 2);
   gcc_assert (GET_MODE_SIZE (o) == GET_MODE_SIZE (n));
   return n;
diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index 6c02c3bb850..6f7f99ad514 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -5712,7 +5712,7 @@ emit_store_flag_1 (rtx target, enum rtx_code code, rtx op0, rtx op1,
 
   /* Next try expanding this via the backend's cstore<mode>4.  */
   mclass = GET_MODE_CLASS (mode);
-  FOR_EACH_MODE_FROM (compare_mode, mode)
+  FOR_EACH_WIDER_MODE_FROM (compare_mode, mode)
     {
      machine_mode optab_mode = mclass == MODE_CC ? CCmode : compare_mode;
      icode = optab_handler (cstore_optab, optab_mode);
diff --git a/gcc/genmodes.cc b/gcc/genmodes.cc
index 59850bb070a..9f0cc9c317d 100644
--- a/gcc/genmodes.cc
+++ b/gcc/genmodes.cc
@@ -1527,13 +1527,44 @@ emit_mode_wider (void)
   int c;
   struct mode_data *m;
 
-  print_decl ("unsigned char", "mode_wider", "NUM_MACHINE_MODES");
+  print_decl ("unsigned char", "mode_next", "NUM_MACHINE_MODES");
 
   for_all_modes (c, m)
     tagged_printf ("E_%smode",
 		   m->wider ? m->wider->name : void_mode->name,
 		   m->name);
 
+  print_closer ();
+  print_decl ("unsigned char", "mode_wider", "NUM_MACHINE_MODES");
+
+  for_all_modes (c, m)
+    {
+      struct mode_data *m2 = 0;
+
+      if (m->cl == MODE_INT
+	  || m->cl == MODE_PARTIAL_INT
+	  || m->cl == MODE_FLOAT
+	  || m->cl == MODE_DECIMAL_FLOAT
+	  || m->cl == MODE_COMPLEX_FLOAT
+	  || m->cl == MODE_FRACT
+	  || m->cl == MODE_UFRACT
+	  || m->cl == MODE_ACCUM
+	  || m->cl == MODE_UACCUM)
+	for (m2 = m->wider; m2 && m2 != void_mode; m2 = m2->wider)
+	  {
+	    if (m2->bytesize == m->bytesize
+		&& m2->precision == m->precision)
+	      continue;
+	    break;
+	  }
+
+      if (m2 == void_mode)
+	m2 = 0;
+      tagged_printf ("E_%smode",
+		     m2 ? m2->name : void_mode->name,
+		     m->name);
+    }
+
   print_closer ();
   print_decl ("unsigned char", "mode_2xwider", "NUM_MACHINE_MODES");
 
diff --git a/gcc/machmode.h b/gcc/machmode.h
index 45df720df73..99b0e4677d6 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -28,6 +28,7 @@ extern const unsigned char mode_inner[NUM_MACHINE_MODES];
 extern CONST_MODE_NUNITS poly_uint16_pod mode_nunits[NUM_MACHINE_MODES];
 extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];
 extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];
+extern const unsigned char mode_next[NUM_MACHINE_MODES];
 extern const unsigned char mode_wider[NUM_MACHINE_MODES];
 extern const unsigned char mode_2xwider[NUM_MACHINE_MODES];
 
@@ -760,7 +761,23 @@ GET_MODE_NUNITS (const T &mode)
 }
 #endif
 
-/* Get the next wider natural mode (eg, QI -> HI -> SI -> DI -> TI).  */
+/* Get the next natural mode (not narrower, eg, QI -> HI -> SI -> DI -> TI
+   or HF -> BF -> SF -> DF -> XF -> TF).  */
+
+template<typename T>
+ALWAYS_INLINE opt_mode<T>
+GET_MODE_NEXT_MODE (const T &m)
+{
+  return typename opt_mode<T>::from_int (mode_next[m]);
+}
+
+/* Get the next wider mode (eg, QI -> HI -> SI -> DI -> TI
+   or { HF, BF } -> SF -> DF -> XF -> TF).
+   This is similar to GET_MODE_NEXT_MODE, but while GET_MODE_NEXT_MODE
+   can include mode that have the same precision (e.g.
+   GET_MODE_NEXT_MODE (HFmode) can be BFmode even when both have the same
+   precision), this one will skip those.  And always VOIDmode for
+   modes whose class is !CLASS_HAS_WIDER_MODES_P.  */
 
 template<typename T>
 ALWAYS_INLINE opt_mode<T>
@@ -1098,7 +1115,33 @@ namespace mode_iterator
     return *iter != E_VOIDmode;
   }
 
-  /* Set mode iterator *ITER to the next widest mode in the same class,
+  /* Set mode iterator *ITER to the next mode in the same class,
+     if any.  */
+
+  template<typename T>
+  inline void
+  get_next (opt_mode<T> *iter)
+  {
+    *iter = GET_MODE_NEXT_MODE (iter->require ());
+  }
+
+  inline void
+  get_next (machine_mode *iter)
+  {
+    *iter = GET_MODE_NEXT_MODE (*iter).else_void ();
+  }
+
+  /* Set mode iterator *ITER to the next mode in the same class.
+     Such a mode is known to exist.  */
+
+  template<typename T>
+  inline void
+  get_known_next (T *iter)
+  {
+    *iter = GET_MODE_NEXT_MODE (*iter).require ();
+  }
+
+  /* Set mode iterator *ITER to the next wider mode in the same class,
      if any.  */
 
   template<typename T>
@@ -1114,7 +1157,7 @@ namespace mode_iterator
     *iter = GET_MODE_WIDER_MODE (*iter).else_void ();
   }
 
-  /* Set mode iterator *ITER to the next widest mode in the same class.
+  /* Set mode iterator *ITER to the next wider mode in the same class.
      Such a mode is known to exist.  */
 
   template<typename T>
@@ -1146,18 +1189,25 @@ namespace mode_iterator
 #define FOR_EACH_MODE_IN_CLASS(ITERATOR, CLASS)  \
   for (mode_iterator::start (&(ITERATOR), CLASS); \
        mode_iterator::iterate_p (&(ITERATOR)); \
-       mode_iterator::get_wider (&(ITERATOR)))
+       mode_iterator::get_next (&(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)))
+       mode_iterator::get_known_next (&(ITERATOR)))
 
-/* Make ITERATOR iterate over START and all wider modes in the same
+/* Make ITERATOR iterate over START and all non-narrower 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_next (&(ITERATOR)))
+
+/* Make ITERATOR iterate over START and all wider modes in the same
+   class, in order of strictly increasing width.  */
+#define FOR_EACH_WIDER_MODE_FROM(ITERATOR, START) \
   for ((ITERATOR) = (START); \
        mode_iterator::iterate_p (&(ITERATOR)); \
        mode_iterator::get_wider (&(ITERATOR)))
@@ -1168,6 +1218,14 @@ namespace mode_iterator
 #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 non-decreasing width.  Start at next such mode after START,
+   or don't iterate at all if there is no such mode.  */
+#define FOR_EACH_NEXT_MODE(ITERATOR, START) \
+  for ((ITERATOR) = (START), mode_iterator::get_next (&(ITERATOR)); \
+       mode_iterator::iterate_p (&(ITERATOR)); \
+       mode_iterator::get_next (&(ITERATOR)))
+
 /* 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.  */
diff --git a/gcc/optabs.cc b/gcc/optabs.cc
index 165f8d1fa22..c2a6f971d74 100644
--- a/gcc/optabs.cc
+++ b/gcc/optabs.cc
@@ -4384,7 +4384,6 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
   machine_mode mode = *pmode;
   rtx libfunc, test;
   machine_mode cmp_mode;
-  enum mode_class mclass;
 
   /* The other methods are not needed.  */
   gcc_assert (methods == OPTAB_DIRECT || methods == OPTAB_WIDEN
@@ -4490,9 +4489,8 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
       return;
     }
 
-  mclass = GET_MODE_CLASS (mode);
   test = gen_rtx_fmt_ee (comparison, VOIDmode, x, y);
-  FOR_EACH_MODE_FROM (cmp_mode, mode)
+  FOR_EACH_WIDER_MODE_FROM (cmp_mode, mode)
     {
       enum insn_code icode;
       icode = optab_handler (cbranch_optab, cmp_mode);
@@ -4515,7 +4513,7 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
 	  delete_insns_since (last);
 	}
 
-      if (methods == OPTAB_DIRECT || !CLASS_HAS_WIDER_MODES_P (mclass))
+      if (methods == OPTAB_DIRECT)
 	break;
     }
 
@@ -4711,7 +4709,7 @@ prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
   bool reversed_p = false;
   scalar_int_mode cmp_mode = targetm.libgcc_cmp_return_mode ();
 
-  FOR_EACH_MODE_FROM (mode, orig_mode)
+  FOR_EACH_WIDER_MODE_FROM (mode, orig_mode)
     {
       if (code_to_optab (comparison)
 	  && (libfunc = optab_libfunc (code_to_optab (comparison), mode)))

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-10-13 14:24 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-13 14:24 [gcc r13-3275] machmode: Introduce GET_MODE_NEXT_MODE with previous GET_MODE_WIDER_MODE meaning, add new GET_MODE_W Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).