On 05/11/14 11:49, Richard Sandiford wrote:
> I think these functions only want to iterate over instruction patterns
> rather than whole instructions (which would include things like
> REG_EQUAL notes), since only the patterns are relevant for finding
> dependencies. There's then no need to check for null rtxes.
>
> Tested by making sure there were no code changes for gcc.dg, gcc.c-torture
> and g++.dg for plain arm-linux-gnueabi and aarch64-linux-gnu. Ramana also
> asked me to try -mcpu=cortex-a7, -mcpu=cortex-a9, -mcpu=arm9tdmi and
> -mcpu=cortex-a15. There were differences in:
>
> gcc.c-torture/execute/20060110-2.c
> gcc.c-torture/execute/ashrdi-1.c and
> gcc.dg/tree-ssa/pr24627.c
>
> for -mcpu=cortex-a7 and no differences for the other combinations.
> The A7 differences were due to the way that arm_get_set_operands handles
> multi-set instructions such as:
>
> (set (reg:CC_C 100 cc)
> (compare:CC_C (plus:SI (reg:SI 8 r8 [orig:121 a ] [121])
> (reg:SI 0 r0 [orig:122 b ] [122]))
> (reg:SI 8 r8 [orig:121 a ] [121])))
> (set (reg:SI 2 r2 [orig:120 D.4117 ] [120])
> (plus:SI (reg:SI 8 r8 [orig:121 a ] [121])
> (reg:SI 0 r0 [orig:122 b ] [122])))
>
> for_each_rtx iterates over the subrtxes in forward order, so
> arm_get_set_operands would pick the set of CC. The new iterator pushes
> the contents of a PARALLEL onto a stack and pulls them in reverse order,
> so arm_get_set_operands would pick the set of r2. This means that after
> the patch the code sees a producer/consumer relationship that it
> previously missed. I think the new behaviour is what was intended.
>
> This code shouldn't really be relying on a particular iteration order
> though. There's a dependency if any SET in the potential producer sets
> a register used by the potential consumer. I think any fix for that
> should be done separately from the iterator rewrite.
>
> OK to install?
>
> Thanks,
> Richard
>
>
> gcc/
> * config/arm/aarch-common.c: Include rtl-iter.h.
> (search_term, arm_find_sub_rtx_with_search_term): Delete.
> (arm_find_sub_rtx_with_code): Use FOR_EACH_SUBRTX_VAR.
> (arm_get_set_operands): Pass the insn pattern rather than the
> insn itself.
> (arm_no_early_store_addr_dep): Likewise.
>
OK.
R.
> Index: gcc/config/arm/aarch-common.c
> ===================================================================
> --- gcc/config/arm/aarch-common.c 2014-10-25 09:42:00.631168827 +0100
> +++ gcc/config/arm/aarch-common.c 2014-10-25 09:51:24.212872553 +0100
> @@ -30,6 +30,7 @@
> #include "tree.h"
> #include "c-family/c-common.h"
> #include "rtl.h"
> +#include "rtl-iter.h"
>
> /* In ARMv8-A there's a general expectation that AESE/AESMC
> and AESD/AESIMC sequences of the form:
> @@ -68,13 +69,6 @@ aarch_crypto_can_dual_issue (rtx_insn *p
> return 0;
> }
>
> -typedef struct
> -{
> - rtx_code search_code;
> - rtx search_result;
> - bool find_any_shift;
> -} search_term;
> -
> /* Return TRUE if X is either an arithmetic shift left, or
> is a multiplication by a power of two. */
> bool
> @@ -96,68 +90,32 @@ static rtx_code shift_rtx_codes[] =
> { ASHIFT, ROTATE, ASHIFTRT, LSHIFTRT,
> ROTATERT, ZERO_EXTEND, SIGN_EXTEND };
>
> -/* Callback function for arm_find_sub_rtx_with_code.
> - DATA is safe to treat as a SEARCH_TERM, ST. This will
> - hold a SEARCH_CODE. PATTERN is checked to see if it is an
> - RTX with that code. If it is, write SEARCH_RESULT in ST
> - and return 1. Otherwise, or if we have been passed a NULL_RTX
> - return 0. If ST.FIND_ANY_SHIFT then we are interested in
> - anything which can reasonably be described as a SHIFT RTX. */
> -static int
> -arm_find_sub_rtx_with_search_term (rtx *pattern, void *data)
> -{
> - search_term *st = (search_term *) data;
> - rtx_code pattern_code;
> - int found = 0;
> -
> - gcc_assert (pattern);
> - gcc_assert (st);
> -
> - /* Poorly formed patterns can really ruin our day. */
> - if (*pattern == NULL_RTX)
> - return 0;
> -
> - pattern_code = GET_CODE (*pattern);
> -
> - if (st->find_any_shift)
> - {
> - unsigned i = 0;
> -
> - /* Left shifts might have been canonicalized to a MULT of some
> - power of two. Make sure we catch them. */
> - if (arm_rtx_shift_left_p (*pattern))
> - found = 1;
> - else
> - for (i = 0; i < ARRAY_SIZE (shift_rtx_codes); i++)
> - if (pattern_code == shift_rtx_codes[i])
> - found = 1;
> - }
> -
> - if (pattern_code == st->search_code)
> - found = 1;
> -
> - if (found)
> - st->search_result = *pattern;
> -
> - return found;
> -}
> -
> -/* Traverse PATTERN looking for a sub-rtx with RTX_CODE CODE. */
> +/* Traverse PATTERN looking for a sub-rtx with RTX_CODE CODE.
> + If FIND_ANY_SHIFT then we are interested in anything which can
> + reasonably be described as a SHIFT RTX. */
> static rtx
> arm_find_sub_rtx_with_code (rtx pattern, rtx_code code, bool find_any_shift)
> {
> - search_term st;
> - int result = 0;
> + subrtx_var_iterator::array_type array;
> + FOR_EACH_SUBRTX_VAR (iter, array, pattern, NONCONST)
> + {
> + rtx x = *iter;
> + if (find_any_shift)
> + {
> + /* Left shifts might have been canonicalized to a MULT of some
> + power of two. Make sure we catch them. */
> + if (arm_rtx_shift_left_p (x))
> + return x;
> + else
> + for (unsigned int i = 0; i < ARRAY_SIZE (shift_rtx_codes); i++)
> + if (GET_CODE (x) == shift_rtx_codes[i])
> + return x;
> + }
>
> - gcc_assert (pattern != NULL_RTX);
> - st.search_code = code;
> - st.search_result = NULL_RTX;
> - st.find_any_shift = find_any_shift;
> - result = for_each_rtx (&pattern, arm_find_sub_rtx_with_search_term, &st);
> - if (result)
> - return st.search_result;
> - else
> - return NULL_RTX;
> + if (GET_CODE (x) == code)
> + return x;
> + }
> + return NULL_RTX;
> }
>
> /* Traverse PATTERN looking for any sub-rtx which looks like a shift. */
> @@ -180,8 +138,10 @@ arm_find_shift_sub_rtx (rtx pattern)
> arm_get_set_operands (rtx producer, rtx consumer,
> rtx *set_source, rtx *set_destination)
> {
> - rtx set_producer = arm_find_sub_rtx_with_code (producer, SET, false);
> - rtx set_consumer = arm_find_sub_rtx_with_code (consumer, SET, false);
> + rtx set_producer = arm_find_sub_rtx_with_code (PATTERN (producer),
> + SET, false);
> + rtx set_consumer = arm_find_sub_rtx_with_code (PATTERN (consumer),
> + SET, false);
>
> if (set_producer && set_consumer)
> {
> @@ -353,8 +313,8 @@ arm_no_early_mul_dep (rtx producer, rtx
> int
> arm_no_early_store_addr_dep (rtx producer, rtx consumer)
> {
> - rtx value = arm_find_sub_rtx_with_code (producer, SET, false);
> - rtx addr = arm_find_sub_rtx_with_code (consumer, SET, false);
> + rtx value = arm_find_sub_rtx_with_code (PATTERN (producer), SET, false);
> + rtx addr = arm_find_sub_rtx_with_code (PATTERN (consumer), SET, false);
>
> if (value)
> value = SET_DEST (value);
>