This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[AARCH64] [PATCH 3/3] AArch64 Port


This patch adds an implementation of integer iterators.

Index: gcc/ChangeLog.aarch64

	* read-rtl.c (rtx_list): New data structure.
	(int_iterator_mapping): New data structure.
	(int_iterator_data): New. List of int iterator details.
	(num_int_iterator_data): New.
	(ints): New group list.
	(find_int): New. Find an int iterator in a list.
	(dummy_uses_int_iterator): Dummy handle.
	(dummy_apply_int_iterator): Dummy handle.
	(uses_int_iterator_p): New.
	(apply_iterator_to_rtx): Handle case for rtx field specifier 'i'.
	(initialize_iterators): Initialize int iterators data struts.
	(find_int_iterator): New. Find an Int iterators from a hash-table.
	(add_int_iterator: Add int iterator to database.
	(read_rtx): Parse and read int iterators mapping and attributes.
	Initialize int iterators group's hash-table. Memory management.
	(read_rtx_code): Handle case for rtl field specifier 'i'.
Index: gcc/read-rtl.c
===================================================================
--- gcc/read-rtl.c	(revision 187870)
+++ gcc/read-rtl.c	(working copy)
@@ -94,6 +94,26 @@
 #define BELLWETHER_CODE(CODE) \
   ((CODE) < NUM_RTX_CODE ? CODE : bellwether_codes[CODE - NUM_RTX_CODE])
 
+/* One element in the (rtx, opno) pair list.  */
+struct rtx_list {
+  /* rtx.  */
+  rtx x;
+  /* Position of the operand to replace.  */
+  int opno;
+};
+
+/* A structure to track which rtx uses which int iterator.  */
+struct int_iterator_mapping {
+  /* Iterator.  */
+  struct mapping *iterator;
+  /* list of rtx using ITERATOR.  */
+  struct rtx_list *rtxs;
+  int num_rtx;
+};
+
+static struct int_iterator_mapping *int_iterator_data;
+static int num_int_iterator_data;
+
 static int find_mode (const char *);
 static bool uses_mode_iterator_p (rtx, int);
 static void apply_mode_iterator (rtx, int);
@@ -121,8 +141,8 @@
 static rtx read_nested_rtx (struct map_value **);
 static rtx read_rtx_variadic (struct map_value **, rtx);
 
-/* The mode and code iterator structures.  */
-static struct iterator_group modes, codes;
+/* The mode, code and int iterator structures.  */
+static struct iterator_group modes, codes, ints;
 
 /* Index I is the value of BELLWETHER_CODE (I + NUM_RTX_CODE).  */
 static enum rtx_code *bellwether_codes;
@@ -179,6 +199,59 @@
   PUT_CODE (x, (enum rtx_code) code);
 }
 
+/* Since GCC does not construct a table of valid constants,
+   we have to accept any int as valid.  No cross-checking can
+   be done.  */
+static int
+find_int (const char *name)
+{
+  char *endptr;
+  int ret;
+
+  if (ISDIGIT (*name))
+    {
+      ret = strtol (name, &endptr, 0);
+      gcc_assert (*endptr == '\0');
+      return ret;
+    }
+  else
+    fatal_with_file_and_line ("unknown int `%s'", name);
+}
+
+static bool
+dummy_uses_int_iterator (rtx x ATTRIBUTE_UNUSED, int index ATTRIBUTE_UNUSED)
+{
+  return false;
+}
+
+static void
+dummy_apply_int_iterator (rtx x ATTRIBUTE_UNUSED, int code ATTRIBUTE_UNUSED)
+{
+  /* Do nothing.  */
+}
+
+/* Stand-alone int iterator usage-checking function.  */
+static bool
+uses_int_iterator_p (rtx x, struct mapping *iterator, int opno)
+{
+  int i;
+  for (i=0; i < num_int_iterator_data; i++)
+    if (int_iterator_data[i].iterator->group == iterator->group &&
+	int_iterator_data[i].iterator->index == iterator->index)
+      {
+	/* Found an existing entry. Check if X is in its list.  */
+	struct int_iterator_mapping it = int_iterator_data[i];
+	int j;
+
+	for (j=0; j < it.num_rtx; j++)
+	{
+	  if (it.rtxs[j].x == x && it.rtxs[j].opno == opno)
+	    return true;
+	}
+      }
+  return false;
+}
+
 /* Map a code or mode attribute string P to the underlying string for
    ITERATOR and VALUE.  */
 
@@ -341,7 +414,9 @@
   x = rtx_alloc (bellwether_code);
   memcpy (x, original, RTX_CODE_SIZE (bellwether_code));
 
-  /* Change the mode or code itself.  */
+  /* Change the mode or code itself.
+     For int iterators, apply_iterator () does nothing. This is
+     because we want to apply int iterators to operands below.  */
   group = iterator->group;
   if (group->uses_iterator_p (x, iterator->index + group->num_builtins))
     group->apply_iterator (x, value);
@@ -379,6 +454,10 @@
 							 unknown_mode_attr);
 	  }
 	break;
+      case 'i':
+	if (uses_int_iterator_p (original, iterator, i))
+	  XINT (x, i) = value;
+	break;
 
       default:
 	break;
@@ -419,6 +498,10 @@
 	      return true;
 	break;
 
+      case 'i':
+	if (uses_int_iterator_p (x, iterator, i))
+	  return true;
+
       default:
 	break;
       }
@@ -480,6 +563,7 @@
 
   iterator = (struct mapping *) *slot;
   for (elem = mtd->queue; elem != 0; elem = XEXP (elem, 1))
+  {
     if (uses_iterator_p (XEXP (elem, 0), iterator))
       {
 	/* For each iterator we expand, we set UNKNOWN_MODE_ATTR to NULL.
@@ -509,6 +593,7 @@
 	    XEXP (elem, 0) = x;
 	  }
     }
+  }
   return 1;
 }
 
@@ -553,7 +638,7 @@
   return &value->next;
 }
 
-/* Do one-time initialization of the mode and code attributes.  */
+/* Do one-time initialization of the mode, code and int attributes.  */
 
 static void
 initialize_iterators (void)
@@ -579,6 +664,15 @@
   codes.uses_iterator_p = uses_code_iterator_p;
   codes.apply_iterator = apply_code_iterator;
 
+  ints.attrs = htab_create (13, leading_string_hash, leading_string_eq_p, 0);
+  ints.iterators = htab_create (13, leading_string_hash,
+				leading_string_eq_p, 0);
+  ints.num_builtins = 0;
+  ints.find_builtin = find_int;
+  ints.uses_iterator_p = dummy_uses_int_iterator;
+  ints.apply_iterator = dummy_apply_int_iterator;
+  num_int_iterator_data = 0;
+
   lower = add_mapping (&modes, modes.attrs, "mode");
   upper = add_mapping (&modes, modes.attrs, "MODE");
   lower_ptr = &lower->values;
@@ -728,6 +822,61 @@
   return group->find_builtin (name);
 }
 
+/* We cannot use the same design as code and mode iterators as ints
+   can be any arbitrary number and there is no way to represent each
+   int iterator's placeholder with a unique numeric identifier. Therefore
+   we create a (rtx *, op, iterator *) triplet database.  */
+
+static struct mapping *
+find_int_iterator (struct iterator_group *group, const char *name)
+{
+  struct mapping *m;
+
+  m = (struct mapping *) htab_find (group->iterators, &name);
+  if (m == 0)
+    fatal_with_file_and_line ("invalid iterator \"%s\"\n", name);
+  return m;
+}
+
+/* Add to triplet-database for int iterators.  */
+static void
+add_int_iterator (struct mapping *iterator, rtx x, int opno)
+{
+
+  /* Find iterator in int_iterator_data. If already present,
+     add this R to its list of rtxs. If not present, create
+     a new entry for INT_ITERATOR_DATA and add the R to its
+     rtx list.  */
+  int i;
+  for (i=0; i < num_int_iterator_data; i++)
+    if (int_iterator_data[i].iterator->index == iterator->index)
+      {
+	/* Found an existing entry. Add rtx to this iterator's list.  */
+	int_iterator_data[i].rtxs =
+			XRESIZEVEC (struct rtx_list,
+				    int_iterator_data[i].rtxs,
+				    int_iterator_data[i].num_rtx + 1);
+	int_iterator_data[i].rtxs[int_iterator_data[i].num_rtx].x = x;
+	int_iterator_data[i].rtxs[int_iterator_data[i].num_rtx].opno = opno;
+	int_iterator_data[i].num_rtx++;
+	return;
+      }
+
+  /* New INT_ITERATOR_DATA entry.  */
+  if (num_int_iterator_data == 0)
+    int_iterator_data = XNEWVEC (struct int_iterator_mapping, 1);
+  else
+    int_iterator_data = XRESIZEVEC (struct int_iterator_mapping,
+				    int_iterator_data,
+				    num_int_iterator_data + 1);
+  int_iterator_data[num_int_iterator_data].iterator = iterator;
+  int_iterator_data[num_int_iterator_data].rtxs = XNEWVEC (struct rtx_list, 1);
+  int_iterator_data[num_int_iterator_data].rtxs[0].x = x;
+  int_iterator_data[num_int_iterator_data].rtxs[0].opno = opno;
+  int_iterator_data[num_int_iterator_data].num_rtx = 1;
+  num_int_iterator_data++;
+}
+
 /* Finish reading a declaration of the form:
 
        (define... <name> [<value1> ... <valuen>])
@@ -817,6 +966,7 @@
   static rtx queue_head;
   struct map_value *mode_maps;
   struct iterator_traverse_data mtd;
+  int i;
 
   /* Do one-time initialization.  */
   if (queue_head == 0)
@@ -852,7 +1002,18 @@
       check_code_iterator (read_mapping (&codes, codes.iterators));
       return false;
     }
+  if (strcmp (rtx_name, "define_int_attr") == 0)
+    {
+      read_mapping (&ints, ints.attrs);
+      return false;
+    }
+  if (strcmp (rtx_name, "define_int_iterator") == 0)
+    {
+      read_mapping (&ints, ints.iterators);
+      return false;
+    }
 
+
   mode_maps = 0;
   XEXP (queue_head, 0) = read_rtx_code (rtx_name, &mode_maps);
   XEXP (queue_head, 1) = 0;
@@ -860,6 +1021,15 @@
   mtd.queue = queue_head;
   mtd.mode_maps = mode_maps;
   mtd.unknown_mode_attr = mode_maps ? mode_maps->string : NULL;
+  htab_traverse (ints.iterators, apply_iterator_traverse, &mtd);
+  /* Free used memory from recording int iterator usage.  */
+  for (i=0; i < num_int_iterator_data; i++)
+    if (int_iterator_data[i].num_rtx > 0)
+      XDELETEVEC (int_iterator_data[i].rtxs);
+  if (num_int_iterator_data > 0)
+    XDELETEVEC (int_iterator_data);
+  num_int_iterator_data = 0;
+
   htab_traverse (modes.iterators, apply_iterator_traverse, &mtd);
   htab_traverse (codes.iterators, apply_iterator_traverse, &mtd);
   if (mtd.unknown_mode_attr)
@@ -1057,14 +1227,30 @@
 	XWINT (return_rtx, i) = tmp_wide;
 	break;
 
-      case 'i':
       case 'n':
-	read_name (&name);
 	validate_const_int (name.string);
 	tmp_int = atoi (name.string);
 	XINT (return_rtx, i) = tmp_int;
 	break;
-
+      case 'i':
+	/* Can be an iterator or an integer constant.  */
+	read_name (&name);
+	if (!ISDIGIT (name.string[0]))
+	  {
+	    struct mapping *iterator;
+	    /* An iterator.  */
+	    iterator = find_int_iterator (&ints, name.string);
+	    /* Build (iterator, rtx, op) triplet-database.  */
+	    add_int_iterator (iterator, return_rtx, i);
+	  }
+	else
+	  {
+	    /* A numeric constant.  */
+	    validate_const_int (name.string);
+	    tmp_int = atoi (name.string);
+	    XINT (return_rtx, i) = tmp_int;
+	  }
+	break;
       default:
 	gcc_unreachable ();
       }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]