This is the mail archive of the gcc@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]

[GSoC] outer-if expressions


Hi,
   This patch adds support for outer-if expressions.

Couple of issues:
a) Doesn't interop with for-pattern, since we don't replace identifier
in c-expr yet,
and this gets more complicated with addition of outer-if.

b) I removed ifexpr-locations for now. I am not sure where to output
if-expr locations
when there are multiple if-exprs (one outer and one inner).

* genmatch.c (simplify::ifexpr): Remove.
      (simplify::ifexpr_location): Likewise.
      (simplify::simplify): Adjust to changes in simplify and
                                   add parameter ifexpr_vec_.
      (dt_simplify::gen_gimple): Adjust to changes in simplify.
      (dt_simplify::gen_generic): Likewise.
      (parse_if): New function.
      (parse_pattern): Add call to parse_if.

* match.pd: Use outer-if for plus-minus patterns.

Thanks,
Prathamesh
Index: gcc/genmatch.c
===================================================================
--- gcc/genmatch.c	(revision 212928)
+++ gcc/genmatch.c	(working copy)
@@ -298,18 +298,17 @@ e_operation::e_operation (const char *id
 struct simplify {
   simplify (const char *name_,
 	    operand *match_, source_location match_location_,
-	    struct operand *ifexpr_, source_location ifexpr_location_,
-	    struct operand *result_, source_location result_location_)
+	    struct operand *result_, source_location result_location_, vec<operand *> ifexpr_vec_ = vNULL)
       : name (name_), match (match_), match_location (match_location_),
-      ifexpr (ifexpr_), ifexpr_location (ifexpr_location_),
-      result (result_), result_location (result_location_) {}
+      result (result_), result_location (result_location_),
+      ifexpr_vec (ifexpr_vec_) {}
+
   const char *name;
   operand *match; 
   source_location match_location;
-  struct operand *ifexpr;
-  source_location ifexpr_location;
   struct operand *result;
   source_location result_location;
+  vec<operand *> ifexpr_vec;
 };
 
 struct dt_node
@@ -554,8 +553,7 @@ lower_commutative (simplify *s, vec<simp
   for (unsigned i = 0; i < matchers.length (); ++i)
     {
       simplify *ns = new simplify (s->name, matchers[i], s->match_location,
-				   s->ifexpr, s->ifexpr_location,
-				   s->result, s->result_location);
+				   s->result, s->result_location, s->ifexpr_vec);
       simplifiers.safe_push (ns);
     }
 }
@@ -1452,14 +1450,21 @@ dt_simplify::gen_gimple (FILE *f)
 	fprintf (f, "captures[%u] = %s;\n", i, indexes[i]->get_name (opname));
       }
 
-  if (s->ifexpr)
-	{
-	  output_line_directive (f, s->ifexpr_location);
-	  fprintf (f, "if (");
-	  s->ifexpr->gen_transform (f, NULL, true);
-	  fprintf (f, ")\n");
-	  fprintf (f, "{\n");
+  if (s->ifexpr_vec != vNULL)
+    {
+      fprintf (f, "if (");
+      // we add in LIFO order, so traverse backwards
+      for (unsigned i = s->ifexpr_vec.length (); i; --i)
+	{
+	  fprintf (f, "(");
+	  s->ifexpr_vec[i - 1]->gen_transform (f, NULL, true);
+	  fprintf (f, ")");
+	  if (i > 1)
+	    fprintf (f, " && ");
 	}
+      fprintf (f, ")\n");
+      fprintf (f, "{\n");
+    }
       output_line_directive (f, s->result_location);
 
       if (s->result->type == operand::OP_EXPR)
@@ -1487,7 +1492,7 @@ dt_simplify::gen_gimple (FILE *f)
 	gcc_unreachable ();
 
       fprintf (f, "return true;\n");
-      if (s->ifexpr)
+      if (s->ifexpr_vec != vNULL)
 	fprintf (f, "}\n");
 
   fprintf (f, "}\n");
@@ -1510,14 +1515,22 @@ dt_simplify::gen_generic (FILE *f)
 	fprintf (f, "captures[%u] = %s;\n", i, indexes[i]->get_name (opname));
       }
 
-  if (s->ifexpr)
-	{
-	  output_line_directive (f, s->ifexpr_location);
-	  fprintf (f, "if (");
-	  s->ifexpr->gen_transform (f, NULL, false);
-	  fprintf (f, ")\n");
-	  fprintf (f, "{\n");
-	}
+  if (s->ifexpr_vec != vNULL)
+    {
+      fprintf (f, "if (\n");
+      // we add in LIFO order, so traverse backwards
+      for (unsigned i = s->ifexpr_vec.length (); i; --i)
+        {
+          fprintf (f, "(");
+          s->ifexpr_vec[i - 1]->gen_transform (f, NULL, false);
+          fprintf (f, ")");
+          if (i > 1)
+            fprintf (f, " && ");
+        }
+      fprintf (f, ")\n");
+      fprintf (f, "{\n");
+    }
+
       output_line_directive (f, s->result_location);
 
       if (s->result->type == operand::OP_EXPR)
@@ -1551,7 +1564,7 @@ dt_simplify::gen_generic (FILE *f)
       else
 	gcc_unreachable ();
 
-      if (s->ifexpr)
+      if (s->ifexpr_vec != vNULL)
 	fprintf (f, "}\n");
 
   fprintf (f, "}\n");
@@ -2025,7 +2038,7 @@ parse_match_and_simplify (cpp_reader *r,
   token = peek (r);
 
   if (token->type != CPP_OPEN_PAREN)
-    return new simplify (id, match, match_location, 0, 0, parse_op (r), token->src_loc);
+    return new simplify (id, match, match_location, parse_op (r), token->src_loc);
 
   eat_token (r, CPP_OPEN_PAREN);
 
@@ -2037,25 +2050,27 @@ parse_match_and_simplify (cpp_reader *r,
     {
       operand *result = parse_expr (r);
       eat_token (r, CPP_CLOSE_PAREN);
-      return new simplify (id, match, match_location, 0, 0, result, result_loc); 
+      return new simplify (id, match, match_location, result, result_loc); 
     }
 
   // (if c-expr)
-  source_location ifexpr_loc = token->src_loc; 
   eat_ident (r, "if");
   operand *ifexpr = parse_c_expr (r, CPP_OPEN_PAREN);
   eat_token (r, CPP_CLOSE_PAREN);
 
   result_loc = peek (r)->src_loc;
-  return new simplify (id, match, match_location, ifexpr, ifexpr_loc, parse_op (r), result_loc);
+  simplify *s = new simplify (id, match, match_location, parse_op (r), result_loc);
+  s->ifexpr_vec.safe_push (ifexpr);
+  return s;
 }
 
+void parse_pattern (cpp_reader *, vec<simplify *>&);
+
 void
 parse_for (cpp_reader *r, source_location, vec<simplify *>& simplifiers) 
 {
   const char *user_id = get_ident (r);
   eat_ident (r, "in");
-  void parse_pattern (cpp_reader *, vec<simplify *>&);
 
   vec<const char *> opers = vNULL;
 
@@ -2086,8 +2101,7 @@ parse_for (cpp_reader *r, source_locatio
 	      operand *result_op = replace_id (s->result, user_id, opers[i]);
 
 	      simplify *ns = new simplify (s->name, match_op, s->match_location,
-					   s->ifexpr, s->ifexpr_location,
-				       result_op, s->result_location);
+					   result_op, s->result_location, s->ifexpr_vec);
 
 	      simplifiers.safe_push (ns);
 	    }
@@ -2095,6 +2109,30 @@ parse_for (cpp_reader *r, source_locatio
     }
 }
 
+void
+parse_if (cpp_reader *r, vec<simplify *>& simplifiers)
+{
+  operand *ifexpr = parse_c_expr (r, CPP_OPEN_PAREN);
+
+  unsigned pos = (simplifiers != vNULL) ? simplifiers.length () - 1 : 0;
+
+  const cpp_token *token = peek (r);
+  if (token->type == CPP_CLOSE_PAREN)
+    fatal_at (token, "no pattern defined in if");
+
+  while (1)
+    {
+      const cpp_token *token = peek (r);
+      if (token->type == CPP_CLOSE_PAREN)
+	break;
+    
+      parse_pattern (r, simplifiers);
+    }
+
+  for (unsigned i = pos; i < simplifiers.length (); ++i)
+    simplifiers[i]->ifexpr_vec.safe_push (ifexpr);
+}
+
 static size_t
 round_alloc_size (size_t s)
 {
@@ -2112,6 +2150,8 @@ parse_pattern (cpp_reader *r, vec<simpli
     simplifiers.safe_push (parse_match_and_simplify (r, token->src_loc));
   else if (strcmp (id, "for") == 0)
     parse_for (r, token->src_loc, simplifiers); 
+  else if (strcmp (id, "if") == 0)
+    parse_if (r, simplifiers);
   else
     fatal_at (token, "expected 'match_and_simplify' or 'for'");
 
@@ -2183,7 +2223,7 @@ main(int argc, char **argv)
 
   for (unsigned i = 0; i < simplifiers.length (); ++i)
     check_no_user_id (simplifiers[i]);
-  
+
   vec<simplify *> out_simplifiers = vNULL;
   for (unsigned i = 0; i < simplifiers.length (); ++i)
     lower_commutative (simplifiers[i], out_simplifiers);
Index: gcc/match.pd
===================================================================
--- gcc/match.pd	(revision 212928)
+++ gcc/match.pd	(working copy)
@@ -120,28 +120,24 @@ along with GCC; see the file COPYING3.
    ???  !FLOAT_TYPE_P && !FIXED_POINT_TYPE_P condition missing
    because of saturation to +-Inf.  */
 
-/* (A +- B) - A -> +-B.  */
-(match_and_simplify
-  (minus (plus @0 @1) @0)
-  (if (!TYPE_SATURATING (type)
-      && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type)))
-  @1)
-(match_and_simplify
-  (minus (minus @0 @1) @0)
-  (if (!TYPE_SATURATING (type)
-      && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type)))
-  (negate @1))
-/* (A +- B) -+ B -> A.  */
-(match_and_simplify
-  (minus (plus @0 @1) @1)
-  (if (!TYPE_SATURATING (type)
-      && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type)))
-  @0)
-(match_and_simplify
-  (plus:c (minus @0 @1) @1)
-  (if (!TYPE_SATURATING (type)
-      && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type)))
-  @0)
+(if (!TYPE_SATURATING (type)
+    && !FLOAT_TYPE_P (type) && !FIXED_POINT_TYPE_P (type))
+  (match_and_simplify
+    (minus (plus @0 @1) @0)
+    @1)
+
+  (match_and_simplify
+    (minus (minus @0 @1) @0)
+    (negate @1))
+
+  (match_and_simplify
+    (minus (plus @0 @1) @1)
+    @0)
+
+  (match_and_simplify
+    (plus:c (minus @0 @1) @1)
+    @0))
+
 /* (CST +- A) +- CST -> CST' +- A.  */
 /* match_and_simplify handles constant folding for us so we can
    implement these as re-association patterns.

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