From: Richard Biener Date: Fri, 31 Jul 2020 12:24:26 +0000 (+0200) Subject: Amend match.pd syntax with force-simplified results X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=14c35be3bf493859b92c3c6ca7893075212169ab;p=gcc.git Amend match.pd syntax with force-simplified results This adds a ! marker to result expressions that should simplify (and if not fail the simplification). This can for example be used like (simplify (plus (vec_cond:s @0 @1 @2) @3) (vec_cond @0 (plus! @1 @3) (plus! @2 @3))) to make the simplification only apply in case both plus operations in the result end up simplified to a simple operand. 2020-07-31 Richard Biener * genmatch.c (expr::force_leaf): Add and initialize. (expr::gen_transform): Honor force_leaf by passing NULL as sequence argument to maybe_push_res_to_seq. (parser::parse_expr): Allow ! marker on result expression operations. * doc/match-and-simplify.texi: Amend. --- diff --git a/gcc/doc/match-and-simplify.texi b/gcc/doc/match-and-simplify.texi index 1df8b90e7c4..41980acbfe9 100644 --- a/gcc/doc/match-and-simplify.texi +++ b/gcc/doc/match-and-simplify.texi @@ -361,6 +361,21 @@ Usually the types of the generated result expressions are determined from the context, but sometimes like in the above case it is required that you specify them explicitely. +Another modifier for generated expressions is @code{!} which +tells the machinery to only consider the simplification in case +the marked expression simplified to a simple operand. Consider +for example + +@smallexample +(simplify + (plus (vec_cond:s @@0 @@1 @@2) @@3) + (vec_cond @@0 (plus! @@1 @@3) (plus! @@2 @@3))) +@end smallexample + +which moves the outer @code{plus} operation to the inner arms +of the @code{vec_cond} expression but only if the actual plus +operations both simplify. + As intermediate conversions are often optional there is a way to avoid the need to repeat patterns both with and without such conversions. Namely you can mark a conversion as being optional diff --git a/gcc/genmatch.c b/gcc/genmatch.c index 0a8cba62e0c..88459d9686e 100644 --- a/gcc/genmatch.c +++ b/gcc/genmatch.c @@ -697,12 +697,13 @@ public: expr (id_base *operation_, location_t loc, bool is_commutative_ = false) : operand (OP_EXPR, loc), operation (operation_), ops (vNULL), expr_type (NULL), is_commutative (is_commutative_), - is_generic (false), force_single_use (false), opt_grp (0) {} + is_generic (false), force_single_use (false), force_leaf (false), + opt_grp (0) {} expr (expr *e) : operand (OP_EXPR, e->location), operation (e->operation), ops (vNULL), expr_type (e->expr_type), is_commutative (e->is_commutative), is_generic (e->is_generic), force_single_use (e->force_single_use), - opt_grp (e->opt_grp) {} + force_leaf (e->force_leaf), opt_grp (e->opt_grp) {} void append_op (operand *op) { ops.safe_push (op); } /* The operator and its operands. */ id_base *operation; @@ -717,6 +718,9 @@ public: /* Whether pushing any stmt to the sequence should be conditional on this expression having a single-use. */ bool force_single_use; + /* Whether in the result expression this should be a leaf node + with any children simplified down to simple operands. */ + bool force_leaf; /* If non-zero, the group for optional handling. */ unsigned char opt_grp; virtual void gen_transform (FILE *f, int, const char *, bool, int, @@ -2520,7 +2524,8 @@ expr::gen_transform (FILE *f, int indent, const char *dest, bool gimple, fprintf (f, ");\n"); fprintf_indent (f, indent, "tem_op.resimplify (lseq, valueize);\n"); fprintf_indent (f, indent, - "_r%d = maybe_push_res_to_seq (&tem_op, lseq);\n", depth); + "_r%d = maybe_push_res_to_seq (&tem_op, %s);\n", depth, + !force_leaf ? "lseq" : "NULL"); fprintf_indent (f, indent, "if (!_r%d) return false;\n", depth); @@ -4240,6 +4245,14 @@ parser::parse_expr () bool force_capture = false; const char *expr_type = NULL; + if (!parsing_match_operand + && token->type == CPP_NOT + && !(token->flags & PREV_WHITE)) + { + eat_token (CPP_NOT); + e->force_leaf = true; + } + if (token->type == CPP_COLON && !(token->flags & PREV_WHITE)) {