aboutsummaryrefslogtreecommitdiff
path: root/gcc/rtlanal.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2014-10-13 07:05:46 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2014-10-13 07:05:46 +0000
commit641123eb5e66fc3794eaa102def2da24a36b7da9 (patch)
tree2ce789a065eadcf5490f63a72017e229498de3ba /gcc/rtlanal.c
parenteaa89fd82a53aded2226b88716bfc56adeecf133 (diff)
downloadgcc-641123eb5e66fc3794eaa102def2da24a36b7da9.zip
gcc-641123eb5e66fc3794eaa102def2da24a36b7da9.tar.gz
gcc-641123eb5e66fc3794eaa102def2da24a36b7da9.tar.bz2
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.
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
Diffstat (limited to 'gcc/rtlanal.c')
-rw-r--r--gcc/rtlanal.c73
1 files changed, 51 insertions, 22 deletions
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 3063458..4651f70 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -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;
}