From e57d3cce4e4fdf50fa59b807ea43c8b14c5c1711 Mon Sep 17 00:00:00 2001
From: Andre Vieira <andre.simoesdiasvieira@arm.com>
Date: Mon, 19 Aug 2024 09:38:41 +0100
Subject: [PATCH] rtl: Enable the use of rtx values with int and mode
 attributes

The 'code' part of a 'define_code_attr' refers to the type of the key, in other
words, it uses a code_iterator to pick the 'value' from their (key "value") pair
list.

However, rtx_alloc_for_name requires a code_attribute to be used when the
'value' needs to be a type. In other words, no other type of attributes could be
used, before this patch, to produce a rtx typed 'value'.

This patch removes that restriction and allows the backend to use any kind of
attribute as long as that attribute always produces a valid code typed 'value'.

gcc/ChangeLog:

	* read-rtl.cc (rtx_reader::rtx_alloc_for_name): Allow all attribute
	types to produce code 'values'.
	(check_code_attribute): Rename ...
	(check_attribute_codes): ... to this.  And change comments to refer to
	* doc/md.texi: Add paragraph to document that you can use int and mode
	attributes to produce codes.
---
 gcc/doc/md.texi |  5 +++++
 gcc/read-rtl.cc | 21 ++++++++++++++-------
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 5dc0d55edd63..a92591122517 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -12077,6 +12077,11 @@ while the unsigned version uses @code{umax} and @code{umin}.  There
 are no versions that pair @code{smax} with @code{umin} or @code{umax}
 with @code{smin}.
 
+It is also possible to use other types of attributes as codes,
+in a similar way.  For example, an int iterator could be used to
+iterate over @code{unspec} numbers, with an int attribute specifying
+an associated rtx code.  @xref{Int Iterators}.
+
 Here's an example of code iterators in action, taken from the MIPS port:
 
 @smallexample
diff --git a/gcc/read-rtl.cc b/gcc/read-rtl.cc
index 4f09e449c81f..bfce806f9d69 100644
--- a/gcc/read-rtl.cc
+++ b/gcc/read-rtl.cc
@@ -1423,21 +1423,21 @@ check_code_iterator (struct mapping *iterator)
    consistent format.  Return a representative code.  */
 
 static rtx_code
-check_code_attribute (mapping *attr)
+check_attribute_codes (mapping *attr)
 {
   rtx_code bellwether = UNKNOWN;
   for (map_value *v = attr->values; v != 0; v = v->next)
     {
       rtx_code code = maybe_find_code (v->string);
       if (code == UNKNOWN)
-	fatal_with_file_and_line ("code attribute `%s' contains "
+	fatal_with_file_and_line ("attribute `%s' contains "
 				  "unrecognized rtx code `%s'",
 				  attr->name, v->string);
       if (bellwether == UNKNOWN)
 	bellwether = code;
       else if (strcmp (GET_RTX_FORMAT (bellwether),
 		       GET_RTX_FORMAT (code)) != 0)
-	fatal_with_file_and_line ("code attribute `%s' combines "
+	fatal_with_file_and_line ("attribute `%s' combines "
 				  "`%s' and `%s', which have different "
 				  "rtx formats", attr->name,
 				  GET_RTX_NAME (bellwether),
@@ -1604,7 +1604,7 @@ parse_reg_note_name (const char *string)
   fatal_with_file_and_line ("unrecognized REG_NOTE name: `%s'", string);
 }
 
-/* Allocate an rtx for code NAME.  If NAME is a code iterator or code
+/* Allocate an rtx for code NAME.  If NAME is a code iterator or an
    attribute, record its use for later and use one of its possible
    values as an interim rtx code.  */
 
@@ -1627,13 +1627,20 @@ rtx_reader::rtx_alloc_for_name (const char *name)
 	attr = deferred_name;
 
       /* Find the attribute itself.  */
-      mapping *m = (mapping *) htab_find (codes.attrs, &attr);
+      mapping *m = nullptr;
+      for (auto attrs : { codes.attrs, ints.attrs, modes.attrs })
+       if (auto *newm = (mapping *) htab_find (attrs, &attr))
+	 {
+	   if (m)
+	     fatal_with_file_and_line ("ambiguous attribute `%s`", attr);
+	   m = newm;
+	 }
       if (!m)
-	fatal_with_file_and_line ("unknown code attribute `%s'", attr);
+	fatal_with_file_and_line ("unknown attribute `%s'", attr);
 
       /* Pick the first possible code for now, and record the attribute
 	 use for later.  */
-      rtx x = rtx_alloc (check_code_attribute (m));
+      rtx x = rtx_alloc (check_attribute_codes (m));
       record_attribute_use (&codes, get_current_location (),
 			    x, 0, deferred_name);
       return x;
-- 
GitLab