This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][match-and-simplify] Make predicate IDs explicit
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 16 Sep 2014 12:31:57 +0200 (CEST)
- Subject: [PATCH][match-and-simplify] Make predicate IDs explicit
- Authentication-results: sourceware.org; auth=none
The following patch makes the parser know known predicates via
us defining them in match.pd with a new (define_predicates ...)
construct. This will allow (in a followup patch) to define
our own predicates via sth like
(match negate_expr_p
(negate @0))
(match negate_expr_p
INTEGER_CST@0
(if (TYPE_OVERFLOW_WRAPS (type) || may_negate_without_overflow_p (@0))))
...
Committed.
Richard.
2014-09-16 Richard Biener <rguenther@suse.de>
* genmatch.c (id_base::id_kind): Add PREDICATE.
(struct predicate_id): New id_base variant.
(is_a_helper): Add predicate_id support.
(add_predicate): New function.
(struct predicate): Adjust.
(print_operand): Likewise.
(cmp_operand): Likewise.
(dt_operand::gen_predicate): Likewise.
(parse_op): Likewise. Error out on unknown predicates.
(parse_predicates): New function.
(parse_pattern): Call it.
* match.pd: Define used predicates.
Index: gcc/genmatch.c
===================================================================
--- gcc/genmatch.c (revision 215294)
+++ gcc/genmatch.c (working copy)
@@ -132,7 +132,7 @@ END_BUILTINS
struct id_base : typed_free_remove<id_base>
{
- enum id_kind { CODE, FN, USER_DEFINED } kind;
+ enum id_kind { CODE, FN, PREDICATE, USER_DEFINED } kind;
id_base (id_kind, const char *);
@@ -188,6 +188,11 @@ struct fn_id : public id_base
enum built_in_function fn;
};
+struct predicate_id : public id_base
+{
+ predicate_id (const char *id_) : id_base (id_base::PREDICATE, id_) {}
+};
+
template<>
template<>
inline bool
@@ -204,6 +209,24 @@ is_a_helper <operator_id *>::test (id_ba
return id->kind == id_base::CODE;
}
+template<>
+template<>
+inline bool
+is_a_helper <predicate_id *>::test (id_base *id)
+{
+ return id->kind == id_base::PREDICATE;
+}
+
+static void
+add_predicate (const char *id)
+{
+ predicate_id *p = new predicate_id (id);
+ id_base **slot = operators->find_slot_with_hash (p, p->hashval, INSERT);
+ if (*slot)
+ fatal ("duplicate id definition");
+ *slot = p;
+}
+
static void
add_operator (enum tree_code code, const char *id,
const char *tcc, unsigned nargs)
@@ -257,8 +280,8 @@ struct operand {
struct predicate : public operand
{
- predicate (const char *ident_) : operand (OP_PREDICATE), ident (ident_) {}
- const char *ident;
+ predicate (predicate_id *p_) : operand (OP_PREDICATE), p (p_) {}
+ predicate_id *p;
virtual void gen_transform (FILE *, const char *, bool, int, const char *, dt_operand ** = 0)
{ gcc_unreachable (); }
};
@@ -525,7 +548,7 @@ print_operand (operand *o, FILE *f = std
}
else if (predicate *p = dyn_cast<predicate *> (o))
- fprintf (f, "%s", p->ident);
+ fprintf (f, "%s", p->p->id);
else if (is_a<c_expr *> (o))
fprintf (f, "c_expr");
@@ -1116,9 +1139,9 @@ cmp_operand (operand *o1, operand *o2)
if (o1->type == operand::OP_PREDICATE)
{
- predicate *p1 = static_cast<predicate *>(o1);
- predicate *p2 = static_cast<predicate *>(o2);
- return strcmp (p1->ident, p2->ident) == 0;
+ predicate *p1 = as_a<predicate *>(o1);
+ predicate *p2 = as_a<predicate *>(o2);
+ return p1->p == p2->p;
}
else if (o1->type == operand::OP_EXPR)
{
@@ -1381,9 +1404,9 @@ dt_operand::gen_opname (char *name, unsi
unsigned
dt_operand::gen_predicate (FILE *f, const char *opname)
{
- predicate *p = static_cast<predicate *> (op);
+ predicate *p = as_a <predicate *> (op);
- fprintf (f, "if (%s (%s))\n", p->ident, opname);
+ fprintf (f, "if (%s (%s))\n", p->p->id, opname);
fprintf (f, "{\n");
return 1;
}
@@ -2336,23 +2359,21 @@ parse_op (cpp_reader *r)
if (token->type == CPP_NAME)
{
const char *id = get_ident (r);
- /* We support zero-operand operator names as predicates. */
id_base *opr = get_operator (id);
- if (opr)
- {
- if (operator_id *code = dyn_cast <operator_id *> (opr))
- {
- if (code->nargs != 0)
- fatal_at (token, "using an operator with operands as predicate");
- /* Parse the zero-operand operator "predicates" as
- expression. */
- op = new expr (new e_operation (id));
- }
- else
- fatal_at (token, "using an unsupported operator as predicate");
+ if (!opr)
+ fatal_at (token, "expected predicate name");
+ if (operator_id *code = dyn_cast <operator_id *> (opr))
+ {
+ if (code->nargs != 0)
+ fatal_at (token, "using an operator with operands as predicate");
+ /* Parse the zero-operand operator "predicates" as
+ expression. */
+ op = new expr (new e_operation (id));
}
+ else if (predicate_id *p = dyn_cast <predicate_id *> (opr))
+ op = new predicate (p);
else
- op = new predicate (id);
+ fatal_at (token, "using an unsupported operator as predicate");
token = peek (r);
if (token->flags & PREV_WHITE)
return op;
@@ -2612,6 +2633,20 @@ parse_if (cpp_reader *r, source_location
simplifiers[i]->ifexpr_vec.safe_push (if_or_with (ifexpr, loc, false));
}
+static void
+parse_predicates (cpp_reader *r, source_location)
+{
+ do
+ {
+ const cpp_token *token = peek (r);
+ if (token->type != CPP_NAME)
+ break;
+
+ add_predicate (get_ident (r));
+ }
+ while (1);
+}
+
static size_t
round_alloc_size (size_t s)
{
@@ -2631,6 +2666,8 @@ parse_pattern (cpp_reader *r, vec<simpli
parse_for (r, token->src_loc, simplifiers);
else if (strcmp (id, "if") == 0)
parse_if (r, token->src_loc, simplifiers);
+ else if (strcmp (id, "define_predicates") == 0)
+ parse_predicates (r, token->src_loc);
else
fatal_at (token, "expected 'simplify' or 'for' or 'if'");
Index: gcc/match.pd
===================================================================
--- gcc/match.pd (revision 215291)
+++ gcc/match.pd (working copy)
@@ -21,6 +21,15 @@ You should have received a copy of the G
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+
+/* Generic tree predicates we inherit. */
+(define_predicates
+ integral_op_p
+ integer_onep integer_zerop integer_all_onesp
+ real_zerop real_onep
+ CONSTANT_CLASS_P)
+
+
/* tree-ssa/ifc-pr44710.c requires a < b ? c : d to fold to 1.
??? probably runs into issue of recursive folding of a < b op0. */
/* tree-ssa/ssa-ccp-16.c wants to fold "hello"[i_2] to 0