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]

Re: support operator list


Fixed a silly mistake in match-bitwise.pd (I had put ')' at wrong place).
This patch also checks if operator-list is used outside for-pattern
(in parser::parse_operation).

* genmatch.c
    (user_id): Add new member is_oper_list.
    (user_id::user_id): Add new default argument.
    (parser::parse_operator_list): New member function in parser.
    (add_substitute): New function.
    (flatten_substitutes): Likewise.
    (parser::parse_for): Call add_substitute.
    (parser::parse_pattern): Call parser::parse_operator_list.
    (parser::parse_operation): Put check for operator-list.

* match-bitwise.pd
    (bitwise_ors): New operator-list.
    (bitwise_ops): Likewise.
    Use bitwise_ors and bitwise_ops in patterns.

* match-comparison.pd
     (eq_ops): New operator-list.
     (cmp_ops): Likewise.
     Use cmp_ops and eq_ops in patterns.

Thanks,
Prathamesh



On Sat, Oct 25, 2014 at 10:44 PM, Prathamesh Kulkarni
<bilbotheelffriend@gmail.com> wrote:
> Hi,
>     This patch adds support for operator-lists, and uses
> them in match-bitwise.pd and match-comparison.pd
>
> * genmatch.c
>     (parser::parse_operator_list): New member function in parser.
>     (add_substitute): New function.
>     (flatten_substitutes): Likewise.
>     (parser::parse_for): Call add_substitute.
>     (parser::parse_pattern): Call parser::parse_operator_list.
>
> * match-bitwise.pd
>     (bitwise_ors): New operator-list.
>     (bitwise_ops): Likewise.
>     Use bitwise_ors and bitwise_ops in patterns.
>
> * match-comparison.pd
>      (eq_ops): New operator-list.
>      (cmp_ops): Likewise.
>      Use cmp_ops and eq_ops in patterns.
>
> Thanks,
> Prathamesh
Index: gcc/genmatch.c
===================================================================
--- gcc/genmatch.c	(revision 216673)
+++ gcc/genmatch.c	(working copy)
@@ -218,9 +218,10 @@
 
 struct user_id : public id_base
 {
-  user_id (const char *id_)
-    : id_base (id_base::USER, id_), substitutes (vNULL) {}
+  user_id (const char *id_, bool is_oper_list_ = false)
+    : id_base (id_base::USER, id_), substitutes (vNULL), is_oper_list (is_oper_list_) {}
   vec<id_base *> substitutes;
+  bool is_oper_list;
 };
 
 template<>
@@ -2419,6 +2420,7 @@
   void parse_simplify (source_location, vec<simplify *>&, predicate_id *,
 		       expr *);
   void parse_for (source_location);
+  void parse_operator_list ();
   void parse_if (source_location);
   void parse_predicates (source_location);
 
@@ -2582,8 +2584,14 @@
 	   || strcmp  (id, "convert2") == 0)
     fatal_at (id_tok, "expected '?' after conditional operator");
   id_base *op = get_operator (id);
+
   if (!op)
     fatal_at (id_tok, "unknown operator %s", id);
+  
+  user_id *uid;
+  if ((uid = dyn_cast<user_id *> (op)) != 0 && uid->is_oper_list)
+    fatal_at (id_tok, "operator-list '%s' can be used only in for", uid->id);
+
   return op;
 }
 
@@ -2900,6 +2908,20 @@
 
 /* Parsing of the outer control structures.  */
 
+bool
+add_substitute (user_id *op, id_base *idb, int& arity) 
+{
+  if (arity == -1)
+    arity = idb->nargs;
+  else if (idb->nargs == -1)
+    ;
+  else if (idb->nargs != arity)
+    return false;
+
+  op->substitutes.safe_push (idb);
+  return true;
+}
+  
 /* Parse a for expression
      for = '(' 'for' <subst>... <pattern> ')'
      subst = <ident> '(' <ident>... ')'  */
@@ -2938,15 +2960,16 @@
 	  if (*idb == CONVERT0 || *idb == CONVERT1 || *idb == CONVERT2)
 	    fatal_at (token, "conditional operators cannot be used inside for");
 
-	  if (arity == -1)
-	    arity = idb->nargs;
-	  else if (idb->nargs == -1)
-	    ;
-	  else if (idb->nargs != arity)
-	    fatal_at (token, "operator '%s' with arity %d does not match "
-		      "others with arity %d", oper, idb->nargs, arity);
+	  vec<id_base *> substitutes = vNULL;
+	  if (idb->kind == id_base::USER)
+	    substitutes = (as_a<user_id *> (idb))->substitutes;
+	  else
+	    substitutes.safe_push (idb);
 
-	  op->substitutes.safe_push (idb);
+	  for (unsigned si = 0; si < substitutes.length (); ++si)
+	    if (!add_substitute (op, substitutes[si], arity))
+	      fatal_at (token, "operator '%s' with arity %d does not match "
+			       "others with arity %d", oper, idb->nargs, arity);
 	}
       op->nargs = arity;
       token = expect (CPP_CLOSE_PAREN);
@@ -2997,6 +3020,55 @@
     operators->remove_elt (user_ids[i]);
 }
 
+void
+flatten_substitutes (vec<id_base *>& ids, vec<id_base *>& substitutes)
+{
+  user_id *op;
+ 
+  for (unsigned i = 0; i < ids.length (); ++i)
+    if ((op = dyn_cast<user_id *> (ids[i])) != 0)
+      flatten_substitutes (op->substitutes, substitutes);
+    else
+      substitutes.safe_push (ids[i]);
+}
+
+void
+parser::parse_operator_list ()
+{
+  const char *id = get_ident ();
+  user_id *op = new user_id (id, true);
+  vec<const cpp_token *> user_id_tokens = vNULL;
+
+  id_base **slot = operators->find_slot_with_hash (op, op->hashval, INSERT);
+  if (*slot)
+    fatal ("operator %s already defined", id);
+  *slot = op;
+
+  const cpp_token *token;
+  vec<id_base *> ids = vNULL;
+
+  while ((token = peek_ident ()) != 0)
+    {
+      const char *oper = get_ident ();
+      id_base *p = get_operator (oper);
+      if (p == 0)
+	fatal_at (token, "%s is not defined", oper);
+      ids.safe_push (p);
+      user_id_tokens.safe_push (token);
+    }
+
+  if (ids.length () == 0)
+    fatal_at (token, "operator list cannot be empty");
+
+  flatten_substitutes (ids, op->substitutes);
+  int arity = op->substitutes[0]->nargs;
+  for (unsigned i = 1; i < op->substitutes.length (); ++i)
+    if (op->substitutes[i]->nargs != -1 && arity != op->substitutes[i]->nargs)
+      fatal_at (user_id_tokens[i], "operator '%s' with arity %d does not match "
+		       "others with arity %d", op->substitutes[i]->id, op->substitutes[i]->nargs, arity);
+}
+
+
 /* Parse an outer if expression.
      if = '(' 'if' '(' <c-expr> ')' <pattern> ')'  */
 
@@ -3097,6 +3169,8 @@
 	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)
+    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-bitwise.pd
===================================================================
--- gcc/match-bitwise.pd	(revision 216673)
+++ gcc/match-bitwise.pd	(working copy)
@@ -17,6 +17,9 @@
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
+(define_operator_list bitwise_ors bit_ior bit_xor)
+(define_operator_list bitwise_ops bit_and bitwise_ors) 
+
 /* Try to fold (type) X op CST -> (type) (X op ((type-x) CST))
    when profitable.  */
 /* For bitwise binary operations apply operand conversions to the
@@ -23,7 +26,7 @@
    binary operation result instead of to the operands.  This allows
    to combine successive conversions and bitwise binary operations.  */
 /* We combine the above two cases by using a conditional convert.  */
-(for bitop (bit_and bit_ior bit_xor)
+(for bitop (bitwise_ops)
  (simplify
   (bitop (convert @0) (convert? @1))
   (if (((TREE_CODE (@1) == INTEGER_CST
@@ -48,7 +51,7 @@
    (convert (bitop @0 (convert @1))))))
 
 /* Simplify (A & B) OP0 (C & B) to (A OP0 C) & B. */
-(for bitop (bit_and bit_ior bit_xor)
+(for bitop (bitwise_ops)
  (simplify
   (bitop (bit_and:c @0 @1) (bit_and @2 @1))
   (bit_and (bitop @0 @2) @1)))
@@ -59,7 +62,7 @@
   (bit_ior (bit_and @0 @2) (bit_and @1 @2)))
 
 /* Combine successive equal operations with constants.  */
-(for bitop (bit_and bit_ior bit_xor)
+(for bitop (bitwise_ops)
  (simplify
   (bitop (bitop @0 CONSTANT_CLASS_P@1) CONSTANT_CLASS_P@2)
   (bitop @0 (bitop @1 @2))))
@@ -95,7 +98,7 @@
  (bit_and @0 (logical_inverted_value @0))
  { build_zero_cst (type); })
 /* X | !X and X ^ !X -> 1, , if X is truth-valued.  */
-(for op (bit_ior bit_xor)
+(for op (bitwise_ors)
  (simplify
   (op truth_valued_p@0 (logical_inverted_value @0))
   { build_one_cst (type); }))
@@ -110,7 +113,7 @@
   (bit_and:c @0 (bit_not @0))
   { build_zero_cst (type); })
 /* X | ~X -> ~0,  X ^ ~X -> ~0.  */
-(for bitop (bit_ior bit_xor)
+(for bitop (bitwise_ors)
  (simplify
   (bitop:c @0 (bit_not @0))
   { build_all_ones_cst (type); }))
@@ -118,7 +121,7 @@
    Also X != 1 vs. X ^ 1 vs ~X wants canonicalization for truth
    values.  */
 #if 0  /* FIXME.  truth_valued_ssa_name isn't exported either.  */
-(for bitop (bit_and bit_ior bit_xor)
+(for bitop (bitwise_ops)
  /* X & (X == 0) -> 0.  */
  /* X | (X == 0) -> 1.  */
  (simplify
@@ -201,7 +204,7 @@
 /* Simple association cases that cancel one operand.  */
 
 /* ((a OP b) & ~a) -> (b & ~a) OP 0  */
-(for bitop (bit_and bit_ior bit_xor)
+(for bitop (bitwise_ops)
  (simplify
   (bit_and:c (bitop:c @0 @1) (bit_not@2 @0))
   (bitop (bit_and @1 @2) { build_zero_cst (type); })))
@@ -264,7 +267,7 @@
 /* Similar transform for vector permute.
    ???  Missing an easy way to check if a mask is a reverse
    operation of another mask (most masks are not reversible).  */
-(for bitop (bit_xor bit_ior bit_and)
+(for bitop (bitwise_ops)
   (simplify
     (bitop (vec_perm @1 @2 @0) (vec_perm @3 @4 @0))
     (vec_perm (bitop @1 @3) (bitop @2 @4) @0)))
Index: gcc/match-comparison.pd
===================================================================
--- gcc/match-comparison.pd	(revision 216673)
+++ gcc/match-comparison.pd	(working copy)
@@ -1,5 +1,8 @@
 /* From fold_binary.  */
 
+(define_operator_list eq_ops eq ne)
+(define_operator_list cmp_ops 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 (cmp_ops)
  (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 (cmp_ops)
   (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 (cmp_ops)
  (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 (cmp_ops)
  (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]