Message ID | 87382o4o0b.fsf@e105548-lin.cambridge.arm.com |
---|---|
State | New |
Headers | show |
On 05/22/2015 09:42 AM, Richard Sandiford wrote: > This patch adjusts the fix for PR target/65689 along the lines suggested > in https://gcc.gnu.org/ml/gcc-patches/2015-04/msg01559.html. The idea > is to reuse the existing gensupport.c routine to work out the codes > accepted by constraints. > > I'd originally done this with an eye to using compute_test_codes for > the problem that Andreas found on s390. I don't think it's going to > be useful for that after all, but it seems worth having for its on sake. > > Bootstrapped & regression-tested on x86_64-linux-gnu. OK to install? > > Thanks, > Richard > > > gcc/ > * gensupport.h (compute_test_codes): Declare. > * gensupport.c (compute_predicate_codes): Rename to... > (compute_test_codes): ...this. Generalize error message. > (process_define_predicate): Update accordingly. > * genpreds.c (compute_maybe_allows): Delete. > (add_constraint): Use compute_test_codes to determine whether > something can accept a SUBREG, REG or MEM. OK. jeff
Hi Richard, Unfortunately this broke the Power builds: /home/wschmidt/gcc/gcc-mainline-base/gcc/config/rs6000/constraints.md:211: reference to unknown predicate 'mem_operand_gpr' /home/wschmidt/gcc/gcc-mainline-base/gcc/config/rs6000/constraints.md:242: reference to unknown predicate 'small_data_operand' I haven't had time to investigate further -- will be in meetings most of the morning. Thanks, Bill On Fri, 2015-05-22 at 16:42 +0100, Richard Sandiford wrote: > This patch adjusts the fix for PR target/65689 along the lines suggested > in https://gcc.gnu.org/ml/gcc-patches/2015-04/msg01559.html. The idea > is to reuse the existing gensupport.c routine to work out the codes > accepted by constraints. > > I'd originally done this with an eye to using compute_test_codes for > the problem that Andreas found on s390. I don't think it's going to > be useful for that after all, but it seems worth having for its on sake. > > Bootstrapped & regression-tested on x86_64-linux-gnu. OK to install? > > Thanks, > Richard > > > gcc/ > * gensupport.h (compute_test_codes): Declare. > * gensupport.c (compute_predicate_codes): Rename to... > (compute_test_codes): ...this. Generalize error message. > (process_define_predicate): Update accordingly. > * genpreds.c (compute_maybe_allows): Delete. > (add_constraint): Use compute_test_codes to determine whether > something can accept a SUBREG, REG or MEM. > > Index: gcc/gensupport.h > =================================================================== > --- gcc/gensupport.h 2015-05-21 08:45:32.663464769 +0100 > +++ gcc/gensupport.h 2015-05-21 08:45:33.015460604 +0100 > @@ -109,5 +109,6 @@ struct pattern_stats > }; > > extern void get_pattern_stats (struct pattern_stats *ranges, rtvec vec); > +extern void compute_test_codes (rtx, int, char *); > > #endif /* GCC_GENSUPPORT_H */ > Index: gcc/gensupport.c > =================================================================== > --- gcc/gensupport.c 2015-05-21 08:45:32.663464769 +0100 > +++ gcc/gensupport.c 2015-05-21 08:51:12.667438995 +0100 > @@ -204,8 +204,8 @@ #define TRISTATE_NOT(a) \ > predicate expression EXP, writing the result to CODES. LINENO is > the line number on which the directive containing EXP appeared. */ > > -static void > -compute_predicate_codes (rtx exp, int lineno, char codes[NUM_RTX_CODE]) > +void > +compute_test_codes (rtx exp, int lineno, char *codes) > { > char op0_codes[NUM_RTX_CODE]; > char op1_codes[NUM_RTX_CODE]; > @@ -215,29 +215,29 @@ compute_predicate_codes (rtx exp, int li > switch (GET_CODE (exp)) > { > case AND: > - compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes); > - compute_predicate_codes (XEXP (exp, 1), lineno, op1_codes); > + compute_test_codes (XEXP (exp, 0), lineno, op0_codes); > + compute_test_codes (XEXP (exp, 1), lineno, op1_codes); > for (i = 0; i < NUM_RTX_CODE; i++) > codes[i] = TRISTATE_AND (op0_codes[i], op1_codes[i]); > break; > > case IOR: > - compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes); > - compute_predicate_codes (XEXP (exp, 1), lineno, op1_codes); > + compute_test_codes (XEXP (exp, 0), lineno, op0_codes); > + compute_test_codes (XEXP (exp, 1), lineno, op1_codes); > for (i = 0; i < NUM_RTX_CODE; i++) > codes[i] = TRISTATE_OR (op0_codes[i], op1_codes[i]); > break; > case NOT: > - compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes); > + compute_test_codes (XEXP (exp, 0), lineno, op0_codes); > for (i = 0; i < NUM_RTX_CODE; i++) > codes[i] = TRISTATE_NOT (op0_codes[i]); > break; > > case IF_THEN_ELSE: > /* a ? b : c accepts the same codes as (a & b) | (!a & c). */ > - compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes); > - compute_predicate_codes (XEXP (exp, 1), lineno, op1_codes); > - compute_predicate_codes (XEXP (exp, 2), lineno, op2_codes); > + compute_test_codes (XEXP (exp, 0), lineno, op0_codes); > + compute_test_codes (XEXP (exp, 1), lineno, op1_codes); > + compute_test_codes (XEXP (exp, 2), lineno, op2_codes); > for (i = 0; i < NUM_RTX_CODE; i++) > codes[i] = TRISTATE_OR (TRISTATE_AND (op0_codes[i], op1_codes[i]), > TRISTATE_AND (TRISTATE_NOT (op0_codes[i]), > @@ -321,7 +321,7 @@ compute_predicate_codes (rtx exp, int li > > default: > error_with_line (lineno, > - "'%s' cannot be used in a define_predicate expression", > + "'%s' cannot be used in predicates or constraints", > GET_RTX_NAME (GET_CODE (exp))); > memset (codes, I, NUM_RTX_CODE); > break; > @@ -373,7 +373,7 @@ process_define_predicate (rtx desc, int > if (GET_CODE (desc) == DEFINE_SPECIAL_PREDICATE) > pred->special = true; > > - compute_predicate_codes (XEXP (desc, 1), lineno, codes); > + compute_test_codes (XEXP (desc, 1), lineno, codes); > > for (i = 0; i < NUM_RTX_CODE; i++) > if (codes[i] != N) > Index: gcc/genpreds.c > =================================================================== > --- gcc/genpreds.c 2015-05-21 08:45:32.663464769 +0100 > +++ gcc/genpreds.c 2015-05-21 08:45:33.015460604 +0100 > @@ -716,34 +716,6 @@ mangle (const char *name) > return XOBFINISH (rtl_obstack, const char *); > } > > -/* Return a bitmask, bit 1 if EXP maybe allows a REG/SUBREG, 2 if EXP > - maybe allows a MEM. Bits should be clear only when we are sure it > - will not allow a REG/SUBREG or a MEM. */ > -static int > -compute_maybe_allows (rtx exp) > -{ > - switch (GET_CODE (exp)) > - { > - case IF_THEN_ELSE: > - /* Conservative answer is like IOR, of the THEN and ELSE branches. */ > - return compute_maybe_allows (XEXP (exp, 1)) > - | compute_maybe_allows (XEXP (exp, 2)); > - case AND: > - return compute_maybe_allows (XEXP (exp, 0)) > - & compute_maybe_allows (XEXP (exp, 1)); > - case IOR: > - return compute_maybe_allows (XEXP (exp, 0)) > - | compute_maybe_allows (XEXP (exp, 1)); > - case MATCH_CODE: > - if (*XSTR (exp, 1) == '\0') > - return (strstr (XSTR (exp, 0), "reg") != NULL ? 1 : 0) > - | (strstr (XSTR (exp, 0), "mem") != NULL ? 2 : 0); > - /* FALLTHRU */ > - default: > - return 3; > - } > -} > - > /* Add one constraint, of any sort, to the tables. NAME is its name; > REGCLASS is the register class, if any; EXP is the expression to > test, if any; IS_MEMORY and IS_ADDRESS indicate memory and address > @@ -899,12 +871,17 @@ add_constraint (const char *name, const > c->is_extra = !(regclass || is_const_int || is_const_dbl); > c->is_memory = is_memory; > c->is_address = is_address; > - int maybe_allows = 3; > + c->maybe_allows_reg = true; > + c->maybe_allows_mem = true; > if (exp) > - maybe_allows = compute_maybe_allows (exp); > - c->maybe_allows_reg = (maybe_allows & 1) != 0; > - c->maybe_allows_mem = (maybe_allows & 2) != 0; > - > + { > + char codes[NUM_RTX_CODE]; > + compute_test_codes (exp, lineno, codes); > + if (!codes[REG] && !codes[SUBREG]) > + c->maybe_allows_reg = false; > + if (!codes[MEM]) > + c->maybe_allows_mem = false; > + } > c->next_this_letter = *slot; > *slot = c; > >
Bill Schmidt <wschmidt@linux.vnet.ibm.com> writes: > Hi Richard, > > Unfortunately this broke the Power builds: > > /home/wschmidt/gcc/gcc-mainline-base/gcc/config/rs6000/constraints.md:211: > reference to unknown predicate 'mem_operand_gpr' > /home/wschmidt/gcc/gcc-mainline-base/gcc/config/rs6000/constraints.md:242: > reference to unknown predicate 'small_data_operand' > > I haven't had time to investigate further -- will be in meetings most of > the morning. This is because those functions aren't defined as predicates in the .md file, but are being used with match_operand. If they're meant to be "real" predicates, they should be defined in predicates.md rather than rs6000.c. If they're just query functions, you can use match_test instead of match_operand. (In that case there's probably no point passing the mode.) Thanks, Richard
On Tue, May 26, 2015 at 10:51 AM, Richard Sandiford <richard.sandiford@arm.com> wrote: > Bill Schmidt <wschmidt@linux.vnet.ibm.com> writes: >> Hi Richard, >> >> Unfortunately this broke the Power builds: >> >> /home/wschmidt/gcc/gcc-mainline-base/gcc/config/rs6000/constraints.md:211: >> reference to unknown predicate 'mem_operand_gpr' >> /home/wschmidt/gcc/gcc-mainline-base/gcc/config/rs6000/constraints.md:242: >> reference to unknown predicate 'small_data_operand' >> >> I haven't had time to investigate further -- will be in meetings most of >> the morning. > > This is because those functions aren't defined as predicates in the .md file, > but are being used with match_operand. If they're meant to be "real" > predicates, they should be defined in predicates.md rather than rs6000.c. > If they're just query functions, you can use match_test instead of > match_operand. (In that case there's probably no point passing the mode.) I converted them to match_test to get back to bootstrap. mem_operand_gpr should be in predicates.md, but requires a little re-design. - David
David Edelsohn <dje.gcc@gmail.com> writes: > On Tue, May 26, 2015 at 10:51 AM, Richard Sandiford > <richard.sandiford@arm.com> wrote: >> Bill Schmidt <wschmidt@linux.vnet.ibm.com> writes: >>> Hi Richard, >>> >>> Unfortunately this broke the Power builds: >>> >>> /home/wschmidt/gcc/gcc-mainline-base/gcc/config/rs6000/constraints.md:211: >>> reference to unknown predicate 'mem_operand_gpr' >>> /home/wschmidt/gcc/gcc-mainline-base/gcc/config/rs6000/constraints.md:242: >>> reference to unknown predicate 'small_data_operand' >>> >>> I haven't had time to investigate further -- will be in meetings most of >>> the morning. >> >> This is because those functions aren't defined as predicates in the .md file, >> but are being used with match_operand. If they're meant to be "real" >> predicates, they should be defined in predicates.md rather than rs6000.c. >> If they're just query functions, you can use match_test instead of >> match_operand. (In that case there's probably no point passing the mode.) > > I converted them to match_test to get back to bootstrap. > mem_operand_gpr should be in predicates.md, but requires a little > re-design. Thanks David.
Index: gcc/gensupport.h =================================================================== --- gcc/gensupport.h 2015-05-21 08:45:32.663464769 +0100 +++ gcc/gensupport.h 2015-05-21 08:45:33.015460604 +0100 @@ -109,5 +109,6 @@ struct pattern_stats }; extern void get_pattern_stats (struct pattern_stats *ranges, rtvec vec); +extern void compute_test_codes (rtx, int, char *); #endif /* GCC_GENSUPPORT_H */ Index: gcc/gensupport.c =================================================================== --- gcc/gensupport.c 2015-05-21 08:45:32.663464769 +0100 +++ gcc/gensupport.c 2015-05-21 08:51:12.667438995 +0100 @@ -204,8 +204,8 @@ #define TRISTATE_NOT(a) \ predicate expression EXP, writing the result to CODES. LINENO is the line number on which the directive containing EXP appeared. */ -static void -compute_predicate_codes (rtx exp, int lineno, char codes[NUM_RTX_CODE]) +void +compute_test_codes (rtx exp, int lineno, char *codes) { char op0_codes[NUM_RTX_CODE]; char op1_codes[NUM_RTX_CODE]; @@ -215,29 +215,29 @@ compute_predicate_codes (rtx exp, int li switch (GET_CODE (exp)) { case AND: - compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes); - compute_predicate_codes (XEXP (exp, 1), lineno, op1_codes); + compute_test_codes (XEXP (exp, 0), lineno, op0_codes); + compute_test_codes (XEXP (exp, 1), lineno, op1_codes); for (i = 0; i < NUM_RTX_CODE; i++) codes[i] = TRISTATE_AND (op0_codes[i], op1_codes[i]); break; case IOR: - compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes); - compute_predicate_codes (XEXP (exp, 1), lineno, op1_codes); + compute_test_codes (XEXP (exp, 0), lineno, op0_codes); + compute_test_codes (XEXP (exp, 1), lineno, op1_codes); for (i = 0; i < NUM_RTX_CODE; i++) codes[i] = TRISTATE_OR (op0_codes[i], op1_codes[i]); break; case NOT: - compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes); + compute_test_codes (XEXP (exp, 0), lineno, op0_codes); for (i = 0; i < NUM_RTX_CODE; i++) codes[i] = TRISTATE_NOT (op0_codes[i]); break; case IF_THEN_ELSE: /* a ? b : c accepts the same codes as (a & b) | (!a & c). */ - compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes); - compute_predicate_codes (XEXP (exp, 1), lineno, op1_codes); - compute_predicate_codes (XEXP (exp, 2), lineno, op2_codes); + compute_test_codes (XEXP (exp, 0), lineno, op0_codes); + compute_test_codes (XEXP (exp, 1), lineno, op1_codes); + compute_test_codes (XEXP (exp, 2), lineno, op2_codes); for (i = 0; i < NUM_RTX_CODE; i++) codes[i] = TRISTATE_OR (TRISTATE_AND (op0_codes[i], op1_codes[i]), TRISTATE_AND (TRISTATE_NOT (op0_codes[i]), @@ -321,7 +321,7 @@ compute_predicate_codes (rtx exp, int li default: error_with_line (lineno, - "'%s' cannot be used in a define_predicate expression", + "'%s' cannot be used in predicates or constraints", GET_RTX_NAME (GET_CODE (exp))); memset (codes, I, NUM_RTX_CODE); break; @@ -373,7 +373,7 @@ process_define_predicate (rtx desc, int if (GET_CODE (desc) == DEFINE_SPECIAL_PREDICATE) pred->special = true; - compute_predicate_codes (XEXP (desc, 1), lineno, codes); + compute_test_codes (XEXP (desc, 1), lineno, codes); for (i = 0; i < NUM_RTX_CODE; i++) if (codes[i] != N) Index: gcc/genpreds.c =================================================================== --- gcc/genpreds.c 2015-05-21 08:45:32.663464769 +0100 +++ gcc/genpreds.c 2015-05-21 08:45:33.015460604 +0100 @@ -716,34 +716,6 @@ mangle (const char *name) return XOBFINISH (rtl_obstack, const char *); } -/* Return a bitmask, bit 1 if EXP maybe allows a REG/SUBREG, 2 if EXP - maybe allows a MEM. Bits should be clear only when we are sure it - will not allow a REG/SUBREG or a MEM. */ -static int -compute_maybe_allows (rtx exp) -{ - switch (GET_CODE (exp)) - { - case IF_THEN_ELSE: - /* Conservative answer is like IOR, of the THEN and ELSE branches. */ - return compute_maybe_allows (XEXP (exp, 1)) - | compute_maybe_allows (XEXP (exp, 2)); - case AND: - return compute_maybe_allows (XEXP (exp, 0)) - & compute_maybe_allows (XEXP (exp, 1)); - case IOR: - return compute_maybe_allows (XEXP (exp, 0)) - | compute_maybe_allows (XEXP (exp, 1)); - case MATCH_CODE: - if (*XSTR (exp, 1) == '\0') - return (strstr (XSTR (exp, 0), "reg") != NULL ? 1 : 0) - | (strstr (XSTR (exp, 0), "mem") != NULL ? 2 : 0); - /* FALLTHRU */ - default: - return 3; - } -} - /* Add one constraint, of any sort, to the tables. NAME is its name; REGCLASS is the register class, if any; EXP is the expression to test, if any; IS_MEMORY and IS_ADDRESS indicate memory and address @@ -899,12 +871,17 @@ add_constraint (const char *name, const c->is_extra = !(regclass || is_const_int || is_const_dbl); c->is_memory = is_memory; c->is_address = is_address; - int maybe_allows = 3; + c->maybe_allows_reg = true; + c->maybe_allows_mem = true; if (exp) - maybe_allows = compute_maybe_allows (exp); - c->maybe_allows_reg = (maybe_allows & 1) != 0; - c->maybe_allows_mem = (maybe_allows & 2) != 0; - + { + char codes[NUM_RTX_CODE]; + compute_test_codes (exp, lineno, codes); + if (!codes[REG] && !codes[SUBREG]) + c->maybe_allows_reg = false; + if (!codes[MEM]) + c->maybe_allows_mem = false; + } c->next_this_letter = *slot; *slot = c;