This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[match-and-simplify] support operator list


(had sent it earlier by private mail).

The attached patch supports operator-list and it's use in for.
For now, operator-list is rejected in expression.

This patch also allows user-defined operator to be used as operator-list
(user-defined ops are really temporary or "scoped" operator-lists).
(for op (plus minus)
      op2 (op...)
  (simplify
     ...))

Should that be supported or rejected ?

* genmatch.c
  (user_id): Add new member is_oper_list.
  (user_id::user_id): Add new default argument.
  (parser::parse_operator_list): New function.
  (parser::parse_for): Allow operator-list.
  (parser::parse_pattern): Call parser::parse_operator_list.
  (parser::parse_operation): Reject operator-list.

* match-comparison.pd
  Define operator-lists eq_ops and cc and use them in patterns.

Thanks,
Prathamesh
Index: gcc/genmatch.c
===================================================================
--- gcc/genmatch.c	(revision 216916)
+++ gcc/genmatch.c	(working copy)
@@ -234,10 +234,11 @@
 
 struct user_id : public id_base
 {
-  user_id (const char *id_)
-    : id_base (id_base::USER, id_), substitutes (vNULL), used (false) {}
+  user_id (const char *id_, bool is_oper_list_ = false)
+    : id_base (id_base::USER, id_), substitutes (vNULL), used (false), is_oper_list (is_oper_list_) {}
   vec<id_base *> substitutes;
   bool used;
+  bool is_oper_list;
 };
 
 template<>
@@ -2443,6 +2444,7 @@
   void parse_for (source_location);
   void parse_if (source_location);
   void parse_predicates (source_location);
+  void parse_operator_list ();
 
   cpp_reader *r;
   vec<if_or_with> active_ifs;
@@ -2611,6 +2613,11 @@
   id_base *op = get_operator (id);
   if (!op)
     fatal_at (id_tok, "unknown operator %s", id);
+
+  user_id *p = dyn_cast<user_id *> (op);
+  if (p && p->is_oper_list)
+    fatal_at (id_tok, "operator-list not allowed in expression");
+
   return op;
 }
 
@@ -2989,7 +2996,12 @@
 	    fatal_at (token, "operator '%s' with arity %d does not match "
 		      "others with arity %d", oper, idb->nargs, arity);
 
-	  op->substitutes.safe_push (idb);
+	  if (user_id *p = dyn_cast<user_id *> (idb))
+	    for (unsigned si = 0; si < p->substitutes.length (); ++si)
+	      op->substitutes.safe_push (p->substitutes[si]);
+	  else 
+	    op->substitutes.safe_push (idb);
+
 	}
       op->nargs = arity;
       token = expect (CPP_CLOSE_PAREN);
@@ -3045,6 +3057,52 @@
     }
 }
 
+void
+parser::parse_operator_list ()
+{
+  const cpp_token *token = peek (); 
+  const char *id = get_ident ();
+
+  if (get_operator (id) != 0)
+    fatal_at (token, "operator %s already defined", id);
+
+  user_id *op = new user_id (id, true);
+  int arity = -1;
+  
+  while ((token = peek_ident ()) != 0)
+    {
+      token = peek (); 
+      const char *oper = get_ident ();
+      id_base *idb = get_operator (oper);
+      
+      if (idb == 0)
+	fatal_at (token, "no such operator '%s'", oper);
+
+      if (arity == -1)
+	arity = idb->nargs;
+      else if (idb->nargs == -1)
+	;
+      else if (arity != idb->nargs)
+	fatal_at (token, "operator '%s' with arity %d does not match "
+			 "others with arity %d", oper, idb->nargs, arity);
+
+      if (user_id *p = dyn_cast<user_id *> (idb)) // we don't need to check for ->is_oper_list here.
+	for (unsigned i = 0; i < p->substitutes.length (); ++i)
+	  op->substitutes.safe_push (p->substitutes[i]);
+      else
+	op->substitutes.safe_push (idb);
+    }
+
+  if (op->substitutes.length () == 0)
+    fatal_at (token, "operator-list cannot be empty");
+
+  op->nargs = arity;
+  id_base **slot = operators->find_slot_with_hash (op, op->hashval, INSERT);
+  *slot = op;
+}
+
+
+
 /* Parse an outer if expression.
      if = '(' 'if' '(' <c-expr> ')' <pattern> ')'  */
 
@@ -3145,6 +3203,13 @@
 	fatal_at (token, "define_predicates inside if or for is not supported");
       parse_predicates (token->src_loc);
     }
+  else if (strcmp (id, "define_operator_list") == 0)
+    {
+      if (active_ifs.length () > 0
+	  || active_fors.length () > 0)
+	fatal_at (token, "operator-list cannot be defined inside 'for' or 'if'");
+      parse_operator_list ();
+    }
   else
     fatal_at (token, "expected %s'simplify', 'match', 'for' or 'if'",
 	      active_ifs.length () == 0 && active_fors.length () == 0
Index: gcc/match-comparison.pd
===================================================================
--- gcc/match-comparison.pd	(revision 216916)
+++ gcc/match-comparison.pd	(working copy)
@@ -1,5 +1,8 @@
 /* From fold_binary.  */
 
+(define_operator_list eq_ops eq ne)
+(define_operator_list cc eq_ops lt le gt ge)
+
 /* On GIMPLE bool != 0 is simply the canonical way to express a
    condition in COND_EXPRs and GIMPLE_CONDs.
    ???  Of course for assignments we still may want to strip those...  */
@@ -15,7 +18,7 @@
     @0)))
 
 /* Distribute operations in equality compares.  */
-(for op (eq ne)
+(for op (eq_ops)
  /* -exp op CST is exp op -CST.  */
  (simplify
   /* ??? fix fold-const to use negate_expr_p  */
@@ -29,7 +32,7 @@
 /* From fold_comparison, in the order of transforms in there.  */
 
 /* Transform comparisons of the form X +- C1 CMP C2 to X CMP C2 -+ C1.  */
-(for cmp (lt le eq ge gt ne)
+(for cmp (cc)
  (for op (plus minus)
   (simplify
    (cmp (op @0 INTEGER_CST@1) INTEGER_CST@2)
@@ -47,7 +50,7 @@
    is undefined for the type, but performing it here badly interacts
    with the transformation in fold_cond_expr_with_comparison which
    attempts to synthetize ABS_EXPR.  */
-(for cmp (eq ne)
+(for cmp (eq_ops) 
  (simplify
   (cmp (minus @0 @1) integer_zerop)
   (cmp @0 @1)))
@@ -65,7 +68,7 @@
 #endif
 
 /* Simplify X * C1 CMP 0 to X CMP 0 if C1 is not zero.  */
-(for op (lt le eq ne ge gt)
+(for op (cc)
   (simplify
     (op (mult @0 INTEGER_CST@1) integer_zerop@2)
     /* In fold-const.c we have this and the following pattern
@@ -131,13 +134,13 @@
 #endif
 
 /* Fold ~X op ~Y as Y op X.  */
-(for cmp (lt le eq ge gt ne)
+(for cmp (cc)
  (simplify
   (cmp (bit_not @0) (bit_not @1))
   (cmp @1 @0)))
 
 /* Fold ~X op C as X op' ~C, where op' is the swapped comparison.  */
-(for cmp (lt le eq ge gt ne)
+(for cmp (cc)
  (simplify
   (cmp (bit_not @0) @1)
   /* ???  (for cst in INTEGER_CST VECTOR_CST) is not supported yet.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]