rtlanal.c (generic_subrtx_iterator <T>::add_subrtxes_to_queue): Add the parts of...
authorRichard Sandiford <richard.sandiford@arm.com>
Mon, 13 Oct 2014 07:05:46 +0000 (07:05 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Mon, 13 Oct 2014 07:05:46 +0000 (07:05 +0000)
gcc/
* rtlanal.c (generic_subrtx_iterator <T>::add_subrtxes_to_queue):
Add the parts of an insn in reverse order, with the pattern at
the top of the queue.  Detect when we're iterating over a SEQUENCE
pattern and in that case just consider patterns of subinstructions.

From-SVN: r216137

gcc/ChangeLog
gcc/rtlanal.c

index 2ce1ca6823a963469c174d65577cf7db592953d1..e01505f32824d2001fbd6e0885ff925f9229c856 100644 (file)
@@ -1,3 +1,10 @@
+2014-10-13  Richard Sandiford  <richard.sandiford@arm.com>
+
+       * rtlanal.c (generic_subrtx_iterator <T>::add_subrtxes_to_queue):
+       Add the parts of an insn in reverse order, with the pattern at
+       the top of the queue.  Detect when we're iterating over a SEQUENCE
+       pattern and in that case just consider patterns of subinstructions.
+
 2014-10-12  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/59401
index 30634580f2c45ef662eb98477283494bef9ff67d..4651f709f974c9f6d1af7870941b38977f953697 100644 (file)
@@ -128,29 +128,58 @@ generic_subrtx_iterator <T>::add_subrtxes_to_queue (array_type &array,
                                                    value_type *base,
                                                    size_t end, rtx_type x)
 {
-  const char *format = GET_RTX_FORMAT (GET_CODE (x));
+  enum rtx_code code = GET_CODE (x);
+  const char *format = GET_RTX_FORMAT (code);
   size_t orig_end = end;
-  for (int i = 0; format[i]; ++i)
-    if (format[i] == 'e')
-      {
-       value_type subx = T::get_value (x->u.fld[i].rt_rtx);
-       if (__builtin_expect (end < LOCAL_ELEMS, true))
-         base[end++] = subx;
-       else
-         base = add_single_to_queue (array, base, end++, subx);
-      }
-    else if (format[i] == 'E')
-      {
-       int length = GET_NUM_ELEM (x->u.fld[i].rt_rtvec);
-       rtx *vec = x->u.fld[i].rt_rtvec->elem;
-       if (__builtin_expect (end + length <= LOCAL_ELEMS, true))
-         for (int j = 0; j < length; j++)
-           base[end++] = T::get_value (vec[j]);
-       else
-         for (int j = 0; j < length; j++)
-           base = add_single_to_queue (array, base, end++,
-                                       T::get_value (vec[j]));
-      }
+  if (__builtin_expect (INSN_P (x), false))
+    {
+      /* Put the pattern at the top of the queue, since that's what
+        we're likely to want most.  It also allows for the SEQUENCE
+        code below.  */
+      for (int i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; --i)
+       if (format[i] == 'e')
+         {
+           value_type subx = T::get_value (x->u.fld[i].rt_rtx);
+           if (__builtin_expect (end < LOCAL_ELEMS, true))
+             base[end++] = subx;
+           else
+             base = add_single_to_queue (array, base, end++, subx);
+         }
+    }
+  else
+    for (int i = 0; format[i]; ++i)
+      if (format[i] == 'e')
+       {
+         value_type subx = T::get_value (x->u.fld[i].rt_rtx);
+         if (__builtin_expect (end < LOCAL_ELEMS, true))
+           base[end++] = subx;
+         else
+           base = add_single_to_queue (array, base, end++, subx);
+       }
+      else if (format[i] == 'E')
+       {
+         unsigned int length = GET_NUM_ELEM (x->u.fld[i].rt_rtvec);
+         rtx *vec = x->u.fld[i].rt_rtvec->elem;
+         if (__builtin_expect (end + length <= LOCAL_ELEMS, true))
+           for (unsigned int j = 0; j < length; j++)
+             base[end++] = T::get_value (vec[j]);
+         else
+           for (unsigned int j = 0; j < length; j++)
+             base = add_single_to_queue (array, base, end++,
+                                         T::get_value (vec[j]));
+         if (code == SEQUENCE && end == length)
+           /* If the subrtxes of the sequence fill the entire array then
+              we know that no other parts of a containing insn are queued.
+              The caller is therefore iterating over the sequence as a
+              PATTERN (...), so we also want the patterns of the
+              subinstructions.  */
+           for (unsigned int j = 0; j < length; j++)
+             {
+               typename T::rtx_type x = T::get_rtx (base[j]);
+               if (INSN_P (x))
+                 base[j] = T::get_value (PATTERN (x));
+             }
+       }
   return end - orig_end;
 }