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); >