This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
[GSoC] outer-if expressions
- From: Prathamesh Kulkarni <bilbotheelffriend at gmail dot com>
- To: Richard Biener <richard dot guenther at gmail dot com>, Diego Novillo <dnovillo at google dot com>, gcc <gcc at gcc dot gnu dot org>, Maxim Kuvyrkov <maxim dot kuvyrkov at linaro dot org>
- Date: Sun, 27 Jul 2014 02:50:06 +0530
- Subject: [GSoC] outer-if expressions
- Authentication-results: sourceware.org; auth=none
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.