From: Richard Biener Date: Wed, 1 Jun 2016 09:00:57 +0000 (+0000) Subject: genmatch.c (comparison_code_p): New predicate. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e04d2a35c884f075ebe12cd6f871e35f6d0362a4;p=gcc.git genmatch.c (comparison_code_p): New predicate. 2016-06-01 Richard Biener * genmatch.c (comparison_code_p): New predicate. (swap_tree_comparison): New function. (commutate): Add for_vec parameter to append new for entries. Support commutating relational operators by swapping it alongside operands. (lower_commutative): Adjust. (dt_simplify::gen): Do not pass artificial operators to gen functions. (decision_tree::gen): Do not add artificial operators as parameters. (parser::parse_expr): Verify operator commutativity when :c is applied. Allow :C to override this. * match.pd: Adjust patterns to use :C instead of :c where required. From-SVN: r236977 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a27cc911359..d9142b9857b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2016-06-01 Richard Biener + + * genmatch.c (comparison_code_p): New predicate. + (swap_tree_comparison): New function. + (commutate): Add for_vec parameter to append new for entries. + Support commutating relational operators by swapping it alongside + operands. + (lower_commutative): Adjust. + (dt_simplify::gen): Do not pass artificial operators to gen + functions. + (decision_tree::gen): Do not add artificial operators as parameters. + (parser::parse_expr): Verify operator commutativity when :c is + applied. Allow :C to override this. + * match.pd: Adjust patterns to use :C instead of :c where required. + 2016-06-01 Patrick Palka PR tree-optimization/71077 diff --git a/gcc/genmatch.c b/gcc/genmatch.c index 2b666ddd6f7..9bb1279dc00 100644 --- a/gcc/genmatch.c +++ b/gcc/genmatch.c @@ -291,6 +291,35 @@ commutative_ternary_tree_code (enum tree_code code) return false; } +/* Return true if CODE is a comparison. */ + +bool +comparison_code_p (enum tree_code code) +{ + switch (code) + { + case EQ_EXPR: + case NE_EXPR: + case ORDERED_EXPR: + case UNORDERED_EXPR: + case LTGT_EXPR: + case UNEQ_EXPR: + case GT_EXPR: + case GE_EXPR: + case LT_EXPR: + case LE_EXPR: + case UNGT_EXPR: + case UNGE_EXPR: + case UNLT_EXPR: + case UNLE_EXPR: + return true; + + default: + break; + } + return false; +} + /* Base class for all identifiers the parser knows. */ @@ -528,6 +557,42 @@ get_operator (const char *id, bool allow_null = false) return operators->find_with_hash (&tem, tem.hashval); } +/* Return the comparison operators that results if the operands are + swapped. This is safe for floating-point. */ + +id_base * +swap_tree_comparison (operator_id *p) +{ + switch (p->code) + { + case EQ_EXPR: + case NE_EXPR: + case ORDERED_EXPR: + case UNORDERED_EXPR: + case LTGT_EXPR: + case UNEQ_EXPR: + return p; + case GT_EXPR: + return get_operator ("LT_EXPR"); + case GE_EXPR: + return get_operator ("LE_EXPR"); + case LT_EXPR: + return get_operator ("GT_EXPR"); + case LE_EXPR: + return get_operator ("GE_EXPR"); + case UNGT_EXPR: + return get_operator ("UNLT_EXPR"); + case UNGE_EXPR: + return get_operator ("UNLE_EXPR"); + case UNLT_EXPR: + return get_operator ("UNGT_EXPR"); + case UNLE_EXPR: + return get_operator ("UNGE_EXPR"); + default: + gcc_unreachable (); + } +} + typedef hash_map cid_map_t; @@ -816,7 +881,7 @@ cartesian_product (const vec< vec >& ops_vector, /* Lower OP to two operands in case it is marked as commutative. */ static vec -commutate (operand *op) +commutate (operand *op, vec > &for_vec) { vec ret = vNULL; @@ -827,7 +892,7 @@ commutate (operand *op) ret.safe_push (op); return ret; } - vec v = commutate (c->what); + vec v = commutate (c->what, for_vec); for (unsigned i = 0; i < v.length (); ++i) { capture *nc = new capture (c->location, c->where, v[i]); @@ -845,7 +910,7 @@ commutate (operand *op) vec< vec > ops_vector = vNULL; for (unsigned i = 0; i < e->ops.length (); ++i) - ops_vector.safe_push (commutate (e->ops[i])); + ops_vector.safe_push (commutate (e->ops[i], for_vec)); auto_vec< vec > result; auto_vec v (e->ops.length ()); @@ -868,6 +933,50 @@ commutate (operand *op) for (unsigned i = 0; i < result.length (); ++i) { expr *ne = new expr (e); + if (operator_id *p = dyn_cast (ne->operation)) + { + if (comparison_code_p (p->code)) + ne->operation = swap_tree_comparison (p); + } + else if (user_id *p = dyn_cast (ne->operation)) + { + bool found_compare = false; + for (unsigned j = 0; j < p->substitutes.length (); ++j) + if (operator_id *q = dyn_cast (p->substitutes[j])) + { + if (comparison_code_p (q->code) + && swap_tree_comparison (q) != q) + { + found_compare = true; + break; + } + } + if (found_compare) + { + user_id *newop = new user_id (""); + for (unsigned j = 0; j < p->substitutes.length (); ++j) + { + id_base *subst = p->substitutes[j]; + if (operator_id *q = dyn_cast (subst)) + { + if (comparison_code_p (q->code)) + subst = swap_tree_comparison (q); + } + newop->substitutes.safe_push (subst); + } + ne->operation = newop; + /* Search for 'p' inside the for vector and push 'newop' + to the same level. */ + for (unsigned j = 0; newop && j < for_vec.length (); ++j) + for (unsigned k = 0; k < for_vec[j].length (); ++k) + if (for_vec[j][k] == p) + { + for_vec[j].safe_push (newop); + newop = NULL; + break; + } + } + } ne->is_commutative = false; // result[i].length () is 2 since e->operation is binary for (unsigned j = result[i].length (); j; --j) @@ -884,7 +993,7 @@ commutate (operand *op) static void lower_commutative (simplify *s, vec& simplifiers) { - vec matchers = commutate (s->match); + vec matchers = commutate (s->match, s->for_vec); for (unsigned i = 0; i < matchers.length (); ++i) { simplify *ns = new simplify (s->kind, matchers[i], s->result, @@ -3248,7 +3357,8 @@ dt_simplify::gen (FILE *f, int indent, bool gimple) fprintf_indent (f, indent, "if (%s (res_code, res_ops, seq, " "valueize, type, captures", info->fname); for (unsigned i = 0; i < s->for_subst_vec.length (); ++i) - fprintf (f, ", %s", s->for_subst_vec[i].second->id); + if (s->for_subst_vec[i].first->used) + fprintf (f, ", %s", s->for_subst_vec[i].second->id); fprintf (f, "))\n"); fprintf_indent (f, indent, " return true;\n"); } @@ -3260,7 +3370,10 @@ dt_simplify::gen (FILE *f, int indent, bool gimple) fprintf (f, ", op%d", i); fprintf (f, ", captures"); for (unsigned i = 0; i < s->for_subst_vec.length (); ++i) - fprintf (f, ", %s", s->for_subst_vec[i].second->id); + { + if (s->for_subst_vec[i].first->used) + fprintf (f, ", %s", s->for_subst_vec[i].second->id); + } fprintf (f, ");\n"); fprintf_indent (f, indent, "if (res) return res;\n"); } @@ -3269,6 +3382,8 @@ dt_simplify::gen (FILE *f, int indent, bool gimple) { for (unsigned i = 0; i < s->for_subst_vec.length (); ++i) { + if (! s->for_subst_vec[i].first->used) + continue; if (is_a (s->for_subst_vec[i].second)) fprintf_indent (f, indent, "enum tree_code %s = %s;\n", s->for_subst_vec[i].first->id, @@ -3425,6 +3540,8 @@ decision_tree::gen (FILE *f, bool gimple) } for (unsigned i = 0; i < s->s->s->for_subst_vec.length (); ++i) { + if (! s->s->s->for_subst_vec[i].first->used) + continue; if (is_a (s->s->s->for_subst_vec[i].second)) fprintf (f, ", enum tree_code ARG_UNUSED (%s)", s->s->s->for_subst_vec[i].first->id); @@ -3885,6 +4002,30 @@ parser::parse_expr () while (*sp) { if (*sp == 'c') + { + if (operator_id *p + = dyn_cast (e->operation)) + { + if (!commutative_tree_code (p->code) + && !comparison_code_p (p->code)) + fatal_at (token, "operation is not commutative"); + } + else if (user_id *p = dyn_cast (e->operation)) + for (unsigned i = 0; + i < p->substitutes.length (); ++i) + { + if (operator_id *q + = dyn_cast (p->substitutes[i])) + { + if (!commutative_tree_code (q->code) + && !comparison_code_p (q->code)) + fatal_at (token, "operation %s is not " + "commutative", q->id); + } + } + is_commutative = true; + } + else if (*sp == 'C') is_commutative = true; else if (*sp == 's') { diff --git a/gcc/match.pd b/gcc/match.pd index 953c0703d92..24e716e6565 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -189,7 +189,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* Optimize -A / A to -1.0 if we don't care about NaNs or Infinities. */ (simplify - (rdiv:c @0 (negate @0)) + (rdiv:C @0 (negate @0)) (if (FLOAT_TYPE_P (type) && ! HONOR_NANS (type) && ! HONOR_INFINITIES (type)) @@ -2830,7 +2830,7 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* cabs(x+0i) or cabs(0+xi) -> abs(x). */ (simplify - (CABS (complex:c @0 real_zerop@1)) + (CABS (complex:C @0 real_zerop@1)) (abs @0)) /* trunc(trunc(x)) -> trunc(x), etc. */