[PATCH][match-and-simplify] Make predicate IDs explicit

Richard Biener rguenther@suse.de
Tue Sep 16 10:35:00 GMT 2014


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



More information about the Gcc-patches mailing list