[07/31] RTL: Also support HOST_WIDE_INT with int iterators

Message ID alpine.LFD.2.21.2011200243430.656242@eddie.linux-mips.org
State New
Headers show
Series
  • VAX: Bring the port up to date (yes, MODE_CC conversion is included)
Related show

Commit Message

Maciej W. Rozycki Nov. 20, 2020, 3:34 a.m.
Add wide integer aka 'w' rtx format support to int iterators so that
machine description can iterate over `const_int' expressions.

This is made by expanding standard integer aka 'i' format support,
observing that any standard integer already present in any of our
existing RTL code will also fit into HOST_WIDE_INT, so there is no need
for a separate handler.  Any truncation of the number parsed is made by
the caller.  An assumption is made however that no place relies on
capping out of range values to INT_MAX.

Now the 'p' format is handled explicitly rather than being implied by
rtx being a SUBREG, so actually assert that it is, just to play safe.

	gcc/
	* read-rtl.c: Add a page-feed separator at the start of iterator
	code.
	(struct iterator_group): Change the return type to HOST_WIDE_INT
	for the `find_builtin' member.  Likewise the second parameter
	type for the `apply_iterator' member.
	(atoll) [!HAVE_ATOQ]: Reorder.
	(find_mode, find_code): Change the return type to HOST_WIDE_INT.
	(apply_mode_iterator, apply_code_iterator)
	(apply_subst_iterator): Change the second parameter type to
	HOST_WIDE_INT.
	(find_int): Handle input suitable for HOST_WIDE_INT output.
	(apply_int_iterator): Rewrite in terms of explicit format
	interpretation.
	(rtx_reader::read_rtx_operand) <'w'>: Fold into...
	<'i', 'n', 'p'>: ... this.
	* doc/md.texi (Int Iterators): Document 'w' rtx format support.
---
 gcc/doc/md.texi |  10 ++--
 gcc/read-rtl.c  | 165 ++++++++++++++++++++++++++++++--------------------------
 2 files changed, 93 insertions(+), 82 deletions(-)

-- 
2.11.0

Comments

Martin Sebor via Gcc-patches Nov. 21, 2020, 4:19 a.m. | #1
On 11/19/20 8:34 PM, Maciej W. Rozycki wrote:
> Add wide integer aka 'w' rtx format support to int iterators so that

> machine description can iterate over `const_int' expressions.

>

> This is made by expanding standard integer aka 'i' format support,

> observing that any standard integer already present in any of our

> existing RTL code will also fit into HOST_WIDE_INT, so there is no need

> for a separate handler.  Any truncation of the number parsed is made by

> the caller.  An assumption is made however that no place relies on

> capping out of range values to INT_MAX.

>

> Now the 'p' format is handled explicitly rather than being implied by

> rtx being a SUBREG, so actually assert that it is, just to play safe.

>

> 	gcc/

> 	* read-rtl.c: Add a page-feed separator at the start of iterator

> 	code.

> 	(struct iterator_group): Change the return type to HOST_WIDE_INT

> 	for the `find_builtin' member.  Likewise the second parameter

> 	type for the `apply_iterator' member.

> 	(atoll) [!HAVE_ATOQ]: Reorder.

> 	(find_mode, find_code): Change the return type to HOST_WIDE_INT.

> 	(apply_mode_iterator, apply_code_iterator)

> 	(apply_subst_iterator): Change the second parameter type to

> 	HOST_WIDE_INT.

> 	(find_int): Handle input suitable for HOST_WIDE_INT output.

> 	(apply_int_iterator): Rewrite in terms of explicit format

> 	interpretation.

> 	(rtx_reader::read_rtx_operand) <'w'>: Fold into...

> 	<'i', 'n', 'p'>: ... this.

> 	* doc/md.texi (Int Iterators): Document 'w' rtx format support.

OK
jeff

Patch

diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 813875b973b..762a6cf050e 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -11201,11 +11201,11 @@  The construct:
 @end smallexample
 
 defines a pseudo integer constant @var{name} that can be instantiated as
-@var{inti} if condition @var{condi} is true.  Each @var{int}
-must have the same rtx format.  @xref{RTL Classes}. Int iterators can appear
-in only those rtx fields that have 'i' as the specifier. This means that
-each @var{int} has to be a constant defined using define_constant or
-define_c_enum.
+@var{inti} if condition @var{condi} is true.  Each @var{int} must have the
+same rtx format.  @xref{RTL Classes}.  Int iterators can appear in only
+those rtx fields that have 'i', 'n', 'w', or 'p' as the specifier.  This
+means that each @var{int} has to be a constant defined using define_constant
+or define_c_enum.
 
 As with mode and code iterators, each pattern that uses @var{name} will be
 expanded @var{n} times, once with all uses of @var{name} replaced by
diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c
index 3ec83a60baf..403f254f3cb 100644
--- a/gcc/read-rtl.c
+++ b/gcc/read-rtl.c
@@ -77,12 +77,12 @@  struct iterator_group {
 
   /* Treat the given string as the name of a standard mode, etc., and
      return its integer value.  */
-  int (*find_builtin) (const char *);
+  HOST_WIDE_INT (*find_builtin) (const char *);
 
   /* Make the given rtx use the iterator value given by the third argument.
      If the iterator applies to operands, the second argument gives the
      operand index, otherwise it is ignored.  */
-  void (*apply_iterator) (rtx, unsigned int, int);
+  void (*apply_iterator) (rtx, unsigned int, HOST_WIDE_INT);
 
   /* Return the C token for the given standard mode, code, etc.  */
   const char *(*get_c_token) (int);
@@ -139,7 +139,7 @@  static void one_time_initialization (void);
 
 /* Global singleton.  */
 rtx_reader *rtx_reader_ptr = NULL;
-
+
 /* The mode and code iterator structures.  */
 static struct iterator_group modes, codes, ints, substs;
 
@@ -152,9 +152,49 @@  static vec<iterator_use> iterator_uses;
 /* The list of all attribute uses in the current rtx.  */
 static vec<attribute_use> attribute_uses;
 
+/* Provide a version of a function to read a long long if the system does
+   not provide one.  */
+#if (HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG			\
+     && !HAVE_DECL_ATOLL						\
+     && !defined (HAVE_ATOQ))
+HOST_WIDE_INT atoll (const char *);
+
+HOST_WIDE_INT
+atoll (const char *p)
+{
+  int neg = 0;
+  HOST_WIDE_INT tmp_wide;
+
+  while (ISSPACE (*p))
+    p++;
+  if (*p == '-')
+    neg = 1, p++;
+  else if (*p == '+')
+    p++;
+
+  tmp_wide = 0;
+  while (ISDIGIT (*p))
+    {
+      HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0');
+      if (new_wide < tmp_wide)
+	{
+	  /* Return INT_MAX equiv on overflow.  */
+	  tmp_wide = HOST_WIDE_INT_M1U >> 1;
+	  break;
+	}
+      tmp_wide = new_wide;
+      p++;
+    }
+
+  if (neg)
+    tmp_wide = -tmp_wide;
+  return tmp_wide;
+}
+#endif
+
 /* Implementations of the iterator_group callbacks for modes.  */
 
-static int
+static HOST_WIDE_INT
 find_mode (const char *name)
 {
   int i;
@@ -167,7 +207,7 @@  find_mode (const char *name)
 }
 
 static void
-apply_mode_iterator (rtx x, unsigned int, int mode)
+apply_mode_iterator (rtx x, unsigned int, HOST_WIDE_INT mode)
 {
   PUT_MODE (x, (machine_mode) mode);
 }
@@ -215,7 +255,7 @@  maybe_find_code (const char *name)
 
 /* Implementations of the iterator_group callbacks for codes.  */
 
-static int
+static HOST_WIDE_INT
 find_code (const char *name)
 {
   rtx_code code = maybe_find_code (name);
@@ -225,7 +265,7 @@  find_code (const char *name)
 }
 
 static void
-apply_code_iterator (rtx x, unsigned int, int code)
+apply_code_iterator (rtx x, unsigned int, HOST_WIDE_INT code)
 {
   PUT_CODE (x, (enum rtx_code) code);
 }
@@ -245,20 +285,52 @@  get_code_token (int code)
    we have to accept any int as valid.  No cross-checking can
    be done.  */
 
-static int
+static HOST_WIDE_INT
 find_int (const char *name)
 {
+  HOST_WIDE_INT tmp;
+
   validate_const_int (name);
-  return atoi (name);
+#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
+  tmp = atoi (name);
+#else
+#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
+  tmp = atol (name);
+#else
+  /* Prefer atoll over atoq, since the former is in the ISO C99 standard.
+     But prefer not to use our hand-rolled function above either.  */
+#if HAVE_DECL_ATOLL || !defined(HAVE_ATOQ)
+  tmp = atoll (name);
+#else
+  tmp = atoq (name);
+#endif
+#endif
+#endif
+  return tmp;
 }
 
 static void
-apply_int_iterator (rtx x, unsigned int index, int value)
+apply_int_iterator (rtx x, unsigned int index, HOST_WIDE_INT value)
 {
-  if (GET_CODE (x) == SUBREG)
-    SUBREG_BYTE (x) = value;
-  else
-    XINT (x, index) = value;
+  RTX_CODE code = GET_CODE (x);
+  const char *format_ptr = GET_RTX_FORMAT (code);
+
+  switch (format_ptr[index])
+    {
+    case 'i':
+    case 'n':
+      XINT (x, index) = value;
+      break;
+    case 'w':
+      XWINT (x, index) = value;
+      break;
+    case 'p':
+      gcc_assert (code == SUBREG);
+      SUBREG_BYTE (x) = value;
+      break;
+    default:
+      gcc_unreachable ();
+    }
 }
 
 static const char *
@@ -279,7 +351,7 @@  get_int_token (int value)
    applied.  If such attribute has already been added, then no the
    routine has no effect.  */
 static void
-apply_subst_iterator (rtx rt, unsigned int, int value)
+apply_subst_iterator (rtx rt, unsigned int, HOST_WIDE_INT value)
 {
   rtx new_attr;
   rtvec attrs_vec, new_attrs_vec;
@@ -1003,44 +1075,6 @@  initialize_iterators (void)
     }
 }
 
-/* Provide a version of a function to read a long long if the system does
-   not provide one.  */
-#if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG && !HAVE_DECL_ATOLL && !defined(HAVE_ATOQ)
-HOST_WIDE_INT atoll (const char *);
-
-HOST_WIDE_INT
-atoll (const char *p)
-{
-  int neg = 0;
-  HOST_WIDE_INT tmp_wide;
-
-  while (ISSPACE (*p))
-    p++;
-  if (*p == '-')
-    neg = 1, p++;
-  else if (*p == '+')
-    p++;
-
-  tmp_wide = 0;
-  while (ISDIGIT (*p))
-    {
-      HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0');
-      if (new_wide < tmp_wide)
-	{
-	  /* Return INT_MAX equiv on overflow.  */
-	  tmp_wide = HOST_WIDE_INT_M1U >> 1;
-	  break;
-	}
-      tmp_wide = new_wide;
-      p++;
-    }
-
-  if (neg)
-    tmp_wide = -tmp_wide;
-  return tmp_wide;
-}
-#endif
-
 
 #ifdef GENERATOR_FILE
 /* Process a define_conditions directive, starting with the optional
@@ -1939,32 +1973,9 @@  rtx_reader::read_rtx_operand (rtx return_rtx, int idx)
       }
       break;
 
-    case 'w':
-      {
-	HOST_WIDE_INT tmp_wide;
-	read_name (&name);
-	validate_const_int (name.string);
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
-	tmp_wide = atoi (name.string);
-#else
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
-	tmp_wide = atol (name.string);
-#else
-	/* Prefer atoll over atoq, since the former is in the ISO C99 standard.
-	   But prefer not to use our hand-rolled function above either.  */
-#if HAVE_DECL_ATOLL || !defined(HAVE_ATOQ)
-	tmp_wide = atoll (name.string);
-#else
-	tmp_wide = atoq (name.string);
-#endif
-#endif
-#endif
-	XWINT (return_rtx, idx) = tmp_wide;
-      }
-      break;
-
     case 'i':
     case 'n':
+    case 'w':
     case 'p':
       {
 	/* Can be an iterator or an integer constant.  */