This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Reuse predicate code analysis for constraints
- From: Richard Sandiford <richard dot sandiford at arm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 22 May 2015 16:42:44 +0100
- Subject: Reuse predicate code analysis for constraints
- Authentication-results: sourceware.org; auth=none
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;