On Mon, 6 Jul 2026, Tamar Christina wrote:
> At the moment the match.pd machine machinery can only be used globally.
>
> That is we cannot use it's flexibility to perform rewrites that only happen
> at specific passes.
>
> This changes by teaching genmatch about "namespaces" so that we can generate
> the matching code in differently named functions and then modifies
> gimple_simplify to support changing to other namespaces.
>
> For this to work the resolver code is moved into match.pd in
> decision_tree::gen
> so that that code doesn't have to be repeated for every namespace.
>
> I have two use cases for this.
>
> 1. generic isel where my early break patch series will introduce matches
> related to masked vector comparisons
> 2. aarch64 specific isel, where we have some code that can be simplified a lot
> using match.pd and be better maintainable.
>
> Bootstrapped Regtested on aarch64-none-linux-gnu,
> arm-none-linux-gnueabihf, x86_64-pc-linux-gnu
> -m32, -m64 and no issues.
>
> Ok for master?
>
> Thanks,
> Tamar
>
> gcc/ChangeLog:
>
> * genmatch.cc (struct _ns_info): New.
> (write_header_declarations, define_dump_logs,
> capture_info::walk_c_expr, expr::gen_transform,
> dt_node::gen_kids, dt_node::gen_kids_1, dt_operand::gen,
> dt_operand::gen_phi_on_cond, emit_logging_call,
> dt_simplify::gen_1, dt_simplify::gen, write_predicate, usage): Use it.
> (decision_tree::gen): Use namespaced and wire resolver.
> (main): Iniitalize the namespaces.
> * gimple-match-exports.cc (gimple_simplify, gimple_resimplify1,
> gimple_resimplify2, gimple_resimplify3, gimple_resimplify4,
> gimple_resimplify5, gimple_resimplify6, gimple_resimplify7
> ,gimple_match_op::resimplify, maybe_resimplify_conditional_op,
> try_conditional_simplification): Take additional gimplifier function
> pointer for nested calls.
> * gimple-match.h (class gimple_match_op): Likewise.
> (gimple_simplify): New.
>
> ---
> diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc
> index
> 920cf27877d3bf69c8ffcbb3497d9d0b54f662c7..948199c6f0c2a10003919a9ca738bed5d29b1ee9
> 100644
> --- a/gcc/genmatch.cc
> +++ b/gcc/genmatch.cc
> @@ -56,6 +56,14 @@ ggc_free (void *)
>
> /* Global state. */
>
> +/* Structure containing namespace information for printing. */
> +typedef struct _ns_info
> +{
> + char *l; /* Lowercase version of the namespace. */
> + char *u; /* Uppercase version of the namespace. */
> +} ns_info;
As I see we have a single instance of this and it is unchanged
during a genmatch invocation. So can you instead use a global
variable named 'ns' for this?
> +
> +
> /* Verboseness. 0 is quiet, 1 adds some warnings, 2 is for debugging. */
> unsigned verbose;
>
> @@ -878,22 +886,25 @@ fp_decl_done (FILE *f, const char *trailer)
> static vec<int> dbg_line_numbers;
>
> static void
> -write_header_declarations (bool gimple, FILE *f)
> +write_header_declarations (bool gimple, ns_info &ns, FILE *f)
> {
> - fprintf (f, "\nextern void\n%s_dump_logs (const char *file1, int line1_id,
> "
> + fprintf (f, "\nextern void\n%s%s_dump_logs (const char *file1, int
> line1_id, "
> "const char *file2, int line2, bool simplify);\n",
> - gimple ? "gimple" : "generic");
> + gimple ? "gimple" : "generic", ns.l);
> + if (gimple)
> + fprintf (f, "\n#define GIMPLE_MATCH_SIMPLIFIER gimple%s_simplify\n",
> + ns.l);
I know you don't use it for GENERIC, but you don't seem to reject
the --generic --namespace combo either. Please do so.
Also the #define indirection makes the generated code harder to debug.
Please consider using a global var to replace the actual called
function in the genmatch generated code.
We are now indirecting through that? Why? The overall description
is a little shallow on the design - from IRC comms I remember you
want both the "standard" and "namespace" patterns to be used when
the "namespace" simplifier is invoked? How do you achieve that?
> }
>
> static void
> -define_dump_logs (bool gimple, FILE *f)
> +define_dump_logs (bool gimple, ns_info &ns, FILE *f)
> {
> if (dbg_line_numbers.is_empty ())
> return;
>
> - fprintf (f , "void\n%s_dump_logs (const char *file1, int line1_id, "
> + fprintf (f , "void\n%s%s_dump_logs (const char *file1, int line1_id, "
> "const char *file2, int line2, bool simplify)\n{\n",
> - gimple ? "gimple" : "generic");
> + gimple ? "gimple" : "generic", ns.l);
>
> fprintf_indent (f, 2, "static int dbg_line_numbers[%d] = {",
> dbg_line_numbers.length ());
> @@ -2448,10 +2459,10 @@ public:
> unsigned pos);
> dt_node *append_simplify (simplify *, unsigned, dt_operand **);
>
> - virtual void gen (FILE *, int, bool, int) {}
> + virtual void gen (FILE *, int, ns_info &, bool, int) {}
>
> - void gen_kids (FILE *, int, bool, int);
> - void gen_kids_1 (FILE *, int, bool, int,
> + void gen_kids (FILE *, int, ns_info &, bool, int);
> + void gen_kids_1 (FILE *, int, ns_info &, bool, int,
> const vec<dt_operand *> &, const vec<dt_operand *> &,
> const vec<dt_operand *> &, const vec<dt_operand *> &,
> const vec<dt_operand *> &, const vec<dt_node *> &);
> @@ -2475,7 +2486,7 @@ public:
> : dt_node (type, parent_), op (op_), match_dop (match_dop_),
> pos (pos_), value_match (false), for_id (current_id) {}
>
> - void gen (FILE *, int, bool, int) final override;
> + void gen (FILE *, int, ns_info &, bool, int) final override;
> unsigned gen_predicate (FILE *, int, const char *, bool);
> unsigned gen_match_op (FILE *, int, const char *, bool);
>
> @@ -2484,7 +2495,7 @@ public:
>
> char *get_name (char *);
> void gen_opname (char *, unsigned);
> - void gen_phi_on_cond (FILE *, int, int);
> + void gen_phi_on_cond (FILE *, int, int, ns_info &);
> };
>
> /* Leaf node of the decision tree, used for DT_SIMPLIFY. */
> @@ -2501,8 +2512,8 @@ public:
> : dt_node (DT_SIMPLIFY, NULL), s (s_), pattern_no (pattern_no_),
> indexes (indexes_), info (NULL) {}
>
> - void gen_1 (FILE *, int, bool, operand *);
> - void gen (FILE *f, int, bool, int) final override;
> + void gen_1 (FILE *, int, ns_info &, bool, operand *);
> + void gen (FILE *f, int, ns_info &, bool, int) final override;
> };
>
> template<>
> @@ -2533,7 +2544,7 @@ public:
> dt_node *root;
>
> void insert (class simplify *, unsigned);
> - void gen (vec <FILE *> &f, bool gimple);
> + void gen (vec <FILE *> &f, ns_info &ns, bool gimple);
> void print (FILE *f = stderr);
>
> decision_tree () { root = new dt_node (dt_node::DT_NODE, NULL); }
> @@ -3180,7 +3191,6 @@ capture_info::walk_c_expr (c_expr *e)
> }
> }
>
> -
> /* The current label failing the current matched pattern during
> code generation. */
> static char *fail_label;
> @@ -3377,7 +3387,8 @@ expr::gen_transform (FILE *f, int indent, const char
> *dest, bool gimple,
> fprintf_indent (f, indent,
> "tem_op.ops[0] = _r%d;\n", depth);
> fprintf_indent (f, indent,
> - "tem_op.resimplify (%s, valueize);\n",
> + "tem_op.resimplify (%s, valueize, "
> + "GIMPLE_MATCH_SIMPLIFIER);\n",
> !force_leaf ? "lseq" : "NULL");
> indent -= 4;
> fprintf_indent (f, indent + 2, "}\n");
> @@ -3397,7 +3408,8 @@ expr::gen_transform (FILE *f, int indent, const char
> *dest, bool gimple,
> fprintf_indent (f, indent,
> "%s.ops[%u] = _o%d[%u];\n", in_place, i, depth, i);
> fprintf_indent (f, indent,
> - "%s.resimplify (%s, valueize);\n",
> + "%s.resimplify (%s, valueize, "
> + "GIMPLE_MATCH_SIMPLIFIER);\n",
> in_place, !force_leaf ? "lseq" : "NULL");
> indent -= 2;
> fprintf_indent (f, indent, "}\n");
> @@ -3425,7 +3437,8 @@ expr::gen_transform (FILE *f, int indent, const char
> *dest, bool gimple,
> for (unsigned i = 0; i < ops.length (); ++i)
> fprintf (f, ", _o%d[%u]", depth, i);
> fprintf (f, ");\n");
> - fprintf_indent (f, indent, "tem_op.resimplify (%s, valueize);\n",
> + fprintf_indent (f, indent, "tem_op.resimplify (%s, valueize, "
> + "GIMPLE_MATCH_SIMPLIFIER);\n",
> !force_leaf ? "lseq" : "NULL");
> fprintf_indent (f, indent,
> "_r%d = maybe_push_res_to_seq (&tem_op, %s);\n",
> @@ -3845,7 +3858,7 @@ fns_cmp (const void *p1, const void *p2)
> /* Generate matching code for the children of the decision tree node. */
>
> void
> -dt_node::gen_kids (FILE *f, int indent, bool gimple, int depth)
> +dt_node::gen_kids (FILE *f, int indent, ns_info &ns, bool gimple, int depth)
> {
> auto_vec<dt_operand *> gimple_exprs;
> auto_vec<dt_operand *> generic_exprs;
> @@ -3917,10 +3930,10 @@ dt_node::gen_kids (FILE *f, int indent, bool gimple,
> int depth)
> for what we have collected sofar. */
> fns.qsort (fns_cmp);
> generic_fns.qsort (fns_cmp);
> - gen_kids_1 (f, indent, gimple, depth, gimple_exprs, generic_exprs,
> + gen_kids_1 (f, indent, ns, gimple, depth, gimple_exprs, generic_exprs,
> fns, generic_fns, preds, others);
> /* And output the true operand itself. */
> - kids[i]->gen (f, indent, gimple, depth);
> + kids[i]->gen (f, indent, ns, gimple, depth);
> gimple_exprs.truncate (0);
> generic_exprs.truncate (0);
> fns.truncate (0);
> @@ -3935,14 +3948,14 @@ dt_node::gen_kids (FILE *f, int indent, bool gimple,
> int depth)
> /* Generate code for the remains. */
> fns.qsort (fns_cmp);
> generic_fns.qsort (fns_cmp);
> - gen_kids_1 (f, indent, gimple, depth, gimple_exprs, generic_exprs,
> + gen_kids_1 (f, indent, ns, gimple, depth, gimple_exprs, generic_exprs,
> fns, generic_fns, preds, others);
> }
>
> /* Generate matching code for the children of the decision tree node. */
>
> void
> -dt_node::gen_kids_1 (FILE *f, int indent, bool gimple, int depth,
> +dt_node::gen_kids_1 (FILE *f, int indent, ns_info &ns, bool gimple, int
> depth,
> const vec<dt_operand *> &gimple_exprs,
> const vec<dt_operand *> &generic_exprs,
> const vec<dt_operand *> &fns,
> @@ -4014,7 +4027,7 @@ dt_node::gen_kids_1 (FILE *f, int indent, bool gimple,
> int depth,
> fprintf_indent (f, indent, "case %s:\n", op->id);
> }
> fprintf_indent (f, indent, " {\n");
> - gimple_exprs[i]->gen (f, indent + 4, true, depth);
> + gimple_exprs[i]->gen (f, indent + 4, ns, true, depth);
> fprintf_indent (f, indent, " break;\n");
> fprintf_indent (f, indent, " }\n");
> }
> @@ -4035,7 +4048,7 @@ dt_node::gen_kids_1 (FILE *f, int indent, bool gimple,
> int depth,
> {
> expr *e = as_a <expr *> (gimple_exprs[i]->op);
> if (*e->operation == COND_EXPR && e->match_phi)
> - gimple_exprs[i]->gen_phi_on_cond (f, indent, depth);
> + gimple_exprs[i]->gen_phi_on_cond (f, indent, depth, ns);
> }
>
> indent -= 2;
> @@ -4076,7 +4089,7 @@ dt_node::gen_kids_1 (FILE *f, int indent, bool gimple,
> int depth,
> " if (gimple_call_num_args (_c%d) == %d)\n",
> depth, e->ops.length ());
> fprintf_indent (f, indent, " {\n");
> - fns[i]->gen (f, indent + 6, true, depth);
> + fns[i]->gen (f, indent + 6, ns, true, depth);
> fprintf_indent (f, indent, " }\n");
> }
>
> @@ -4098,7 +4111,7 @@ dt_node::gen_kids_1 (FILE *f, int indent, bool gimple,
> int depth,
> if (*op == SSA_NAME && (exprs_len || fns_len))
> {
> fprintf_indent (f, indent + 4, "{\n");
> - generic_exprs[i]->gen (f, indent + 6, gimple, depth);
> + generic_exprs[i]->gen (f, indent + 6, ns, gimple, depth);
> fprintf_indent (f, indent + 4, "}\n");
> }
> }
> @@ -4124,7 +4137,7 @@ dt_node::gen_kids_1 (FILE *f, int indent, bool gimple,
> int depth,
> fprintf_indent (f, indent, "case %s:\n", op->id);
> }
> fprintf_indent (f, indent, " {\n");
> - generic_exprs[i]->gen (f, indent + 4, gimple, depth);
> + generic_exprs[i]->gen (f, indent + 4, ns, gimple, depth);
> fprintf_indent (f, indent, " break;\n");
> fprintf_indent (f, indent, " }\n");
> }
> @@ -4155,7 +4168,7 @@ dt_node::gen_kids_1 (FILE *f, int indent, bool gimple,
> int depth,
> last_op = e->operation;
> fprintf_indent (f, indent, " if (call_expr_nargs (%s) == %d)\n"
> " {\n", kid_opname, e->ops.length ());
> - generic_fns[j]->gen (f, indent + 6, false, depth);
> + generic_fns[j]->gen (f, indent + 6, ns, false, depth);
> fprintf_indent (f, indent, " }\n");
> }
> fprintf_indent (f, indent, " break;\n");
> @@ -4194,20 +4207,20 @@ dt_node::gen_kids_1 (FILE *f, int indent, bool
> gimple, int depth,
> fprintf_indent (f, indent + 4, "tree %s = %s_pops[%d];\n",
> child_opname, kid_opname, j);
> }
> - preds[i]->gen_kids (f, indent + 4, gimple, depth);
> + preds[i]->gen_kids (f, indent + 4, ns, gimple, depth);
> fprintf_indent (f, indent, " }\n");
> indent -= 2;
> fprintf_indent (f, indent, "}\n");
> }
>
> for (unsigned i = 0; i < others.length (); ++i)
> - others[i]->gen (f, indent, gimple, depth);
> + others[i]->gen (f, indent, ns, gimple, depth);
> }
>
> /* Generate matching code for the decision tree operand. */
>
> void
> -dt_operand::gen (FILE *f, int indent, bool gimple, int depth)
> +dt_operand::gen (FILE *f, int indent, ns_info &ns, bool gimple, int depth)
> {
> char opname[20];
> get_name (opname);
> @@ -4239,7 +4252,7 @@ dt_operand::gen (FILE *f, int indent, bool gimple, int
> depth)
> gcc_unreachable ();
>
> indent += 4 * n_braces;
> - gen_kids (f, indent, gimple, depth);
> + gen_kids (f, indent, ns, gimple, depth);
>
> for (unsigned i = 0; i < n_braces; ++i)
> {
> @@ -4253,7 +4266,7 @@ dt_operand::gen (FILE *f, int indent, bool gimple, int
> depth)
> /* Generate matching code for the phi when meet COND_EXPR. */
>
> void
> -dt_operand::gen_phi_on_cond (FILE *f, int indent, int depth)
> +dt_operand::gen_phi_on_cond (FILE *f, int indent, int depth, ns_info &ns)
> {
> char opname_0[20];
> char opname_1[20];
> @@ -4285,7 +4298,7 @@ dt_operand::gen_phi_on_cond (FILE *f, int indent, int
> depth)
> "boolean_type_node, _cond_lhs_%d, _cond_rhs_%d);\n",
> opname_0, depth, depth, depth);
>
> - gen_kids (f, indent, true, depth);
> + gen_kids (f, indent, ns, true, depth);
>
> indent -= 2;
> fprintf_indent (f, indent, "}\n");
> @@ -4296,10 +4309,10 @@ dt_operand::gen_phi_on_cond (FILE *f, int indent, int
> depth)
> either the RESULT location or the S's match location if RESULT is null. */
> static void
> emit_logging_call (FILE *f, int indent, class simplify *s, operand *result,
> - bool gimple)
> + ns_info &ns, bool gimple)
> {
> fprintf_indent (f, indent, "if (UNLIKELY (debug_dump)) "
> - "%s_dump_logs (", gimple ? "gimple" : "generic");
> + "%s%s_dump_logs (", gimple ? "gimple" : "generic", ns.l);
> output_line_directive (f,
> result ? result->location : s->match->location,
> true, true, true);
> @@ -4313,7 +4326,8 @@ emit_logging_call (FILE *f, int indent, class simplify
> *s, operand *result,
> Main recursive worker. */
>
> void
> -dt_simplify::gen_1 (FILE *f, int indent, bool gimple, operand *result)
> +dt_simplify::gen_1 (FILE *f, int indent, ns_info &ns, bool gimple,
> + operand *result)
> {
> if (result)
> {
> @@ -4323,7 +4337,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple,
> operand *result)
> indent += 4;
> output_line_directive (f, w->location);
> w->with->gen_transform (f, indent, NULL, true, 1, "type", NULL);
> - gen_1 (f, indent, gimple, w->subexpr);
> + gen_1 (f, indent, ns, gimple, w->subexpr);
> indent -= 4;
> fprintf_indent (f, indent, "}\n");
> return;
> @@ -4336,7 +4350,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple,
> operand *result)
> fprintf (f, ")\n");
> fprintf_indent (f, indent + 2, "{\n");
> indent += 4;
> - gen_1 (f, indent, gimple, ife->trueexpr);
> + gen_1 (f, indent, ns, gimple, ife->trueexpr);
> indent -= 4;
> fprintf_indent (f, indent + 2, "}\n");
> if (ife->falseexpr)
> @@ -4344,7 +4358,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple,
> operand *result)
> fprintf_indent (f, indent, "else\n");
> fprintf_indent (f, indent + 2, "{\n");
> indent += 4;
> - gen_1 (f, indent, gimple, ife->falseexpr);
> + gen_1 (f, indent, ns, gimple, ife->falseexpr);
> indent -= 4;
> fprintf_indent (f, indent + 2, "}\n");
> }
> @@ -4441,7 +4455,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple,
> operand *result)
> if (!result)
> {
> /* If there is no result then this is a predicate implementation. */
> - emit_logging_call (f, indent, s, result, gimple);
> + emit_logging_call (f, indent, s, result, ns, gimple);
> fprintf_indent (f, indent, "return true;\n");
> }
> else if (gimple)
> @@ -4516,7 +4530,8 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple,
> operand *result)
> "res_op->set_op (%s, type, 1);\n",
> *opr == CONVERT_EXPR ? "NOP_EXPR" : opr->id);
> fprintf_indent (f, indent,
> - "res_op->resimplify (%s, valueize);\n",
> + "res_op->resimplify (%s, valueize, "
> + "GIMPLE_MATCH_SIMPLIFIER);\n",
> !e->force_leaf ? "lseq" : "NULL");
> indent -= 4;
> fprintf_indent (f, indent,
> @@ -4524,7 +4539,8 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple,
> operand *result)
> }
> else
> fprintf_indent (f, indent,
> - "res_op->resimplify (%s, valueize);\n",
> + "res_op->resimplify (%s, valueize, "
> + "GIMPLE_MATCH_SIMPLIFIER);\n",
> !e->force_leaf ? "lseq" : "NULL");
> if (e->force_leaf)
> {
> @@ -4561,7 +4577,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple,
> operand *result)
> }
> else
> gcc_unreachable ();
> - emit_logging_call (f, indent, s, result, gimple);
> + emit_logging_call (f, indent, s, result, ns, gimple);
> fprintf_indent (f, indent, "return true;\n");
> }
> else /* GENERIC */
> @@ -4616,7 +4632,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple,
> operand *result)
> }
> if (is_predicate)
> {
> - emit_logging_call (f, indent, s, result, gimple);
> + emit_logging_call (f, indent, s, result, ns, gimple);
> fprintf_indent (f, indent, "return true;\n");
> }
> else
> @@ -4684,7 +4700,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple,
> operand *result)
> i);
> }
> }
> - emit_logging_call (f, indent, s, result, gimple);
> + emit_logging_call (f, indent, s, result, ns, gimple);
> fprintf_indent (f, indent, "return _r;\n");
> }
> }
> @@ -4700,7 +4716,7 @@ dt_simplify::gen_1 (FILE *f, int indent, bool gimple,
> operand *result)
> that is not part of the decision tree (simplify->match). */
>
> void
> -dt_simplify::gen (FILE *f, int indent, bool gimple, int depth
> ATTRIBUTE_UNUSED)
> +dt_simplify::gen (FILE *f, int indent, ns_info &ns, bool gimple, int depth
> ATTRIBUTE_UNUSED)
> {
> fprintf_indent (f, indent, "{\n");
> indent += 2;
> @@ -4767,7 +4783,7 @@ dt_simplify::gen (FILE *f, int indent, bool gimple, int
> depth ATTRIBUTE_UNUSED)
> else
> gcc_unreachable ();
> }
> - gen_1 (f, indent, gimple, s->result);
> + gen_1 (f, indent, ns, gimple, s->result);
> }
>
> indent -= 2;
> @@ -4860,7 +4876,7 @@ sinfo_hashmap_traits::equal_keys (const key_type &v,
> tree. */
>
> void
> -decision_tree::gen (vec <FILE *> &files, bool gimple)
> +decision_tree::gen (vec <FILE *> &files, ns_info &ns, bool gimple)
> {
> sinfo_map_t si;
>
> @@ -4893,8 +4909,8 @@ decision_tree::gen (vec <FILE *> &files, bool gimple)
> FILE *f = choose_output (files);
>
> /* Generate a split out function with the leaf transform code. */
> - s->fname = xasprintf ("%s_simplify_%u", gimple ? "gimple" : "generic",
> - fcnt++);
> + s->fname = xasprintf ("%s%s_simplify_%u", gimple ? "gimple" :
> "generic",
> + ns.l, fcnt++);
> if (gimple)
> fp_decl (f, "\nbool\n"
> "%s (gimple_match_op *res_op, gimple_seq *seq,\n"
> @@ -4928,7 +4944,7 @@ decision_tree::gen (vec <FILE *> &files, bool gimple)
> fprintf (f, "{\n");
> fprintf_indent (f, 2, "const bool debug_dump = "
> "dump_file && (dump_flags & TDF_FOLDING);\n");
> - s->s->gen_1 (f, 2, gimple, s->s->s->result);
> + s->s->gen_1 (f, 2, ns, gimple, s->s->s->result);
> if (gimple)
> fprintf (f, " return false;\n");
> else
> @@ -4961,25 +4977,25 @@ decision_tree::gen (vec <FILE *> &files, bool gimple)
>
> if (gimple)
> fp_decl (f, "\nbool\n"
> - "gimple_simplify_%s (gimple_match_op *res_op,"
> + "gimple%s_simplify_%s (gimple_match_op *res_op,"
> " gimple_seq *seq,\n"
> " tree (*valueize)(tree) "
> "ATTRIBUTE_UNUSED,\n"
> " code_helper ARG_UNUSED (code), tree "
> "ARG_UNUSED (type)",
> - e->operation->id);
> + ns.l, e->operation->id);
> else
> fp_decl (f, "\ntree\n"
> - "generic_simplify_%s (location_t ARG_UNUSED (loc), enum "
> + "generic%s_simplify_%s (location_t ARG_UNUSED (loc), enum "
> "tree_code ARG_UNUSED (code), const tree ARG_UNUSED
> (type)",
> - e->operation->id);
> + ns.l, e->operation->id);
> for (unsigned i = 0; i < n; ++i)
> fp_decl (f, ", tree _p%d", i);
> fp_decl_done (f, ")");
> fprintf (f, "{\n");
> fprintf_indent (f, 2, "const bool debug_dump = "
> "dump_file && (dump_flags & TDF_FOLDING);\n");
> - dop->gen_kids (f, 2, gimple, 0);
> + dop->gen_kids (f, 2, ns, gimple, 0);
> if (gimple)
> fprintf (f, " return false;\n");
> else
> @@ -4998,13 +5014,13 @@ decision_tree::gen (vec <FILE *> &files, bool gimple)
>
> if (gimple)
> fp_decl (f, "\nbool\n"
> - "gimple_simplify (gimple_match_op*, gimple_seq*,\n"
> + "gimple%s_simplify (gimple_match_op*, gimple_seq*,\n"
> " tree (*)(tree), code_helper,\n"
> - " const tree");
> + " const tree", ns.l);
> else
> fp_decl (f, "\ntree\n"
> - "generic_simplify (location_t, enum tree_code,\n"
> - " const tree");
> + "generic%s_simplify (location_t, enum tree_code,\n"
> + " const tree", ns.l);
> for (unsigned i = 0; i < n; ++i)
> fp_decl (f, ", tree");
> fp_decl_done (f, ")");
> @@ -5025,13 +5041,13 @@ decision_tree::gen (vec <FILE *> &files, bool gimple)
> tail-calls to the split-out functions. */
> if (gimple)
> fp_decl (f, "\nbool\n"
> - "gimple_simplify (gimple_match_op *res_op, gimple_seq *seq,\n"
> + "gimple%s_simplify (gimple_match_op *res_op, gimple_seq
> *seq,\n"
> " tree (*valueize)(tree) ATTRIBUTE_UNUSED,\n"
> - " code_helper code, const tree type");
> + " code_helper code, const tree type", ns.l);
> else
> fp_decl (f, "\ntree\n"
> - "generic_simplify (location_t loc, enum tree_code code, "
> - "const tree type ATTRIBUTE_UNUSED");
> + "generic%s_simplify (location_t loc, enum tree_code code, "
> + "const tree type ATTRIBUTE_UNUSED", ns.l);
> for (unsigned i = 0; i < n; ++i)
> fp_decl (f, ", tree _p%d", i);
> fp_decl_done (f, ")");
> @@ -5064,11 +5080,11 @@ decision_tree::gen (vec <FILE *> &files, bool gimple)
> is_a <fn_id *> (e->operation) ? "-" : "",
> e->operation->id);
> if (gimple)
> - fprintf (f, " return gimple_simplify_%s (res_op, "
> - "seq, valueize, code, type", e->operation->id);
> + fprintf (f, " return gimple%s_simplify_%s (res_op, "
> + "seq, valueize, code, type", ns.l, e->operation->id);
> else
> - fprintf (f, " return generic_simplify_%s (loc, code, type",
> - e->operation->id);
> + fprintf (f, " return generic%s_simplify_%s (loc, code, type",
> + ns.l, e->operation->id);
> for (unsigned j = 0; j < n; ++j)
> fprintf (f, ", _p%d", j);
> fprintf (f, ");\n");
> @@ -5082,15 +5098,42 @@ decision_tree::gen (vec <FILE *> &files, bool gimple)
> fprintf (f, " return NULL_TREE;\n");
> fprintf (f, "}\n");
> }
> +
> + if (gimple)
> + {
> + FILE *f = choose_output (files);
> + fp_decl (f, "\nbool\n"
> + "gimple%s_simplify (gimple_match_op *res_op, gimple_seq *seq,\n"
> + " tree (*valueize)(tree))", ns.l);
> + fp_decl_done (f, "");
> + fprintf (f, "{\n");
> + fprintf_indent (f, 2, "switch (res_op->num_ops)\n");
> + fprintf_indent (f, 4, "{\n");
> + for (unsigned n = 1; n <= 7; ++n)
> + {
> + fprintf_indent (f, 4, "case %u:\n", n);
> + fprintf_indent (f, 6, "return gimple%s_simplify (res_op, seq, "
> + "valueize,\n", ns.l);
> + fprintf_indent (f, 16, "res_op->code, res_op->type");
> + for (unsigned i = 0; i < n; ++i)
> + fprintf (f, ", res_op->ops[%u]", i);
> + fprintf (f, ");\n");
> + }
> + fprintf_indent (f, 4, "default:\n");
> + fprintf_indent (f, 6, "gcc_unreachable ();\n");
> + fprintf_indent (f, 4, "}\n");
> + fprintf (f, "}\n");
> + }
> }
>
> /* Output code to implement the predicate P from the decision tree DT. */
>
> void
> -write_predicate (FILE *f, predicate_id *p, decision_tree &dt, bool gimple)
> +write_predicate (FILE *f, predicate_id *p, decision_tree &dt, ns_info &ns,
> + bool gimple)
> {
> - fp_decl (f, "\nbool\n%s%s (tree t%s%s)",
> - gimple ? "gimple_" : "tree_", p->id,
> + fp_decl (f, "\nbool\n%s%s%s (tree t%s%s)",
> + gimple ? "gimple_" : "tree_", ns.l, p->id,
> p->nargs > 0 ? ", tree *res_ops" : "",
> gimple ? ", tree (*valueize)(tree) ATTRIBUTE_UNUSED" : "");
> fp_decl_done (f, "");
> @@ -5102,7 +5145,7 @@ write_predicate (FILE *f, predicate_id *p,
> decision_tree &dt, bool gimple)
>
> if (!gimple)
> fprintf_indent (f, 2, "if (TREE_SIDE_EFFECTS (t)) return false;\n");
> - dt.root->gen_kids (f, 2, gimple, 0);
> + dt.root->gen_kids (f, 2, ns, gimple, 0);
>
> fprintf_indent (f, 2, "return false;\n"
> "}\n");
> @@ -6271,7 +6314,8 @@ usage ()
> {
> const char *usage = "Usage:\n"
> " %s [--gimple|--generic] [-v[v]] <input>\n"
> - " %s [options] [--include=FILE] --header=FILE <input> <output>...\n";
> + " %s [options] [--include=FILE] [--namespace=NAME] --header=FILE"
> + " <input> <output>...\n";
> fprintf (stderr, usage, progname, progname);
> }
>
> @@ -6300,6 +6344,7 @@ main (int argc, char **argv)
> bool gimple = true;
> char *s_header_file = NULL;
> char *s_include_file = NULL;
> + char *s_namespace = NULL;
> auto_vec <char *> files;
> char *input = NULL;
> int last_file = argc - 1;
> @@ -6313,6 +6358,8 @@ main (int argc, char **argv)
> s_header_file = &argv[i][9];
> else if (strncmp (argv[i], "--include=", 10) == 0)
> s_include_file = &argv[i][10];
> + else if (strncmp (argv[i], "--namespace=", 12) == 0)
> + s_namespace = &argv[i][12];
> else if (strcmp (argv[i], "-v") == 0)
> verbose = 1;
> else if (strcmp (argv[i], "-vv") == 0)
> @@ -6333,6 +6380,31 @@ main (int argc, char **argv)
> return 1;
> }
>
> + /* Initialize priting information. */
> + ns_info ns;
> + if (s_namespace)
> + {
> + int len = strlen (s_namespace) + 1;
> + ns.l = XNEWVEC (char, len + 1);
> + ns.u = XNEWVEC (char, len + 1);
> + ns.l[0] = '_';
> + ns.u[0] = '_';
> + for (int i = 0; i < len; i++)
> + {
> + ns.l[i+1] = TOLOWER (s_namespace[i]);
> + ns.u[i+1] = TOUPPER (s_namespace[i]);
> + }
> + ns.l[len] = '\0';
> + ns.u[len] = '\0';
> + }
> + else
> + {
> + ns.l = XNEW (char);
> + ns.u = XNEW (char);
> + ns.l[0] = '\0';
> + ns.u[0] = '\0';
> + }
> +
> genmatch_diag_selftests ();
>
> if (!s_include_file)
> @@ -6395,7 +6467,7 @@ main (int argc, char **argv)
> parts.quick_push (stdout);
> write_header (stdout, s_include_file);
> write_header_includes (gimple, stdout);
> - write_header_declarations (gimple, stdout);
> + write_header_declarations (gimple, ns, stdout);
> }
> else
> {
> @@ -6406,10 +6478,11 @@ main (int argc, char **argv)
> }
>
> header_file = fopen (s_header_file, "w");
> - fprintf (header_file, "#ifndef GCC_GIMPLE_MATCH_AUTO_H\n"
> - "#define GCC_GIMPLE_MATCH_AUTO_H\n");
> + fprintf (header_file, "#ifndef GCC_GIMPLE_MATCH%s_AUTO_H\n"
> + "#define GCC_GIMPLE_MATCH%s_AUTO_H\n",
> + ns.u, ns.u);
> write_header_includes (gimple, header_file);
> - write_header_declarations (gimple, header_file);
> + write_header_declarations (gimple, ns, header_file);
> }
>
> /* Go over all predicates defined with patterns and perform
> @@ -6433,7 +6506,7 @@ main (int argc, char **argv)
> /* Cycle the file buffers. */
> FILE *f = choose_output (parts);
>
> - write_predicate (f, pred, dt, gimple);
> + write_predicate (f, pred, dt, ns, gimple);
> }
>
> /* Lower the main simplifiers and generate code for them. */
> @@ -6450,9 +6523,9 @@ main (int argc, char **argv)
> if (verbose == 2)
> dt.print (stderr);
>
> - dt.gen (parts, gimple);
> + dt.gen (parts, ns, gimple);
>
> - define_dump_logs (gimple, choose_output (parts));
> + define_dump_logs (gimple, ns, choose_output (parts));
>
> for (FILE *f : parts)
> {
> @@ -6462,7 +6535,8 @@ main (int argc, char **argv)
>
> if (header_file)
> {
> - fprintf (header_file, "\n#endif /* GCC_GIMPLE_MATCH_AUTO_H. */\n");
> + fprintf (header_file, "\n#endif /* GCC_GIMPLE_MATCH%s_AUTO_H. */\n",
> + ns.u);
> fclose (header_file);
> }
>
> @@ -6471,6 +6545,8 @@ main (int argc, char **argv)
> cpp_destroy (r);
>
> delete operators;
> + XDELETE (ns.l);
> + XDELETE (ns.u);
>
> return 0;
> }
> diff --git a/gcc/gimple-match-exports.cc b/gcc/gimple-match-exports.cc
> index
> 74f2c5f19bcfdf2e40435119ac757658a110e471..8626a1990bd81d1f8950e172726c5f9e61abc628
> 100644
> --- a/gcc/gimple-match-exports.cc
> +++ b/gcc/gimple-match-exports.cc
> @@ -66,6 +66,7 @@ extern bool gimple_simplify (gimple_match_op *, gimple_seq
> *, tree (*)(tree),
> extern bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
> code_helper, tree, tree, tree, tree, tree, tree,
> tree, tree);
> +extern bool gimple_simplify (gimple_match_op *, gimple_seq *, tree
> (*)(tree));
>
> /* Functions that are needed by gimple-match but that are exported and used
> in
> other places in the compiler. */
> @@ -90,37 +91,48 @@ tree do_valueize (tree (*)(tree), tree);
> They expect valueized operands in canonical order and do not
> perform simplification of all-constant operands. */
>
> -static bool gimple_resimplify1 (gimple_seq *, gimple_match_op *, tree
> (*)(tree));
> -static bool gimple_resimplify2 (gimple_seq *, gimple_match_op *, tree
> (*)(tree));
> -static bool gimple_resimplify3 (gimple_seq *, gimple_match_op *, tree
> (*)(tree));
> -static bool gimple_resimplify4 (gimple_seq *, gimple_match_op *, tree
> (*)(tree));
> -static bool gimple_resimplify5 (gimple_seq *, gimple_match_op *, tree
> (*)(tree));
> -static bool gimple_resimplify6 (gimple_seq *, gimple_match_op *, tree
> (*)(tree));
> -static bool gimple_resimplify7 (gimple_seq *, gimple_match_op *, tree
> (*)(tree));
> +static bool gimple_resimplify1 (gimple_seq *, gimple_match_op *, tree
> (*)(tree),
> + gimple_match_simplify_fn);
> +static bool gimple_resimplify2 (gimple_seq *, gimple_match_op *, tree
> (*)(tree),
> + gimple_match_simplify_fn);
> +static bool gimple_resimplify3 (gimple_seq *, gimple_match_op *, tree
> (*)(tree),
> + gimple_match_simplify_fn);
> +static bool gimple_resimplify4 (gimple_seq *, gimple_match_op *, tree
> (*)(tree),
> + gimple_match_simplify_fn);
> +static bool gimple_resimplify5 (gimple_seq *, gimple_match_op *, tree
> (*)(tree),
> + gimple_match_simplify_fn);
> +static bool gimple_resimplify6 (gimple_seq *, gimple_match_op *, tree
> (*)(tree),
> + gimple_match_simplify_fn);
> +static bool gimple_resimplify7 (gimple_seq *, gimple_match_op *, tree
> (*)(tree),
> + gimple_match_simplify_fn);
>
> /* Match and simplify the toplevel valueized operation THIS.
> Replaces THIS with a simplified and/or canonicalized result and
> returns whether any change was made. */
>
> bool
> -gimple_match_op::resimplify (gimple_seq *seq, tree (*valueize)(tree))
> +gimple_match_op::resimplify (gimple_seq *seq, tree (*valueize)(tree),
> + gimple_match_simplify_fn simplifier)
> {
> + if (!simplifier)
> + simplifier = gimple_simplify;
> +
> switch (num_ops)
> {
> case 1:
> - return gimple_resimplify1 (seq, this, valueize);
> + return gimple_resimplify1 (seq, this, valueize, simplifier);
> case 2:
> - return gimple_resimplify2 (seq, this, valueize);
> + return gimple_resimplify2 (seq, this, valueize, simplifier);
> case 3:
> - return gimple_resimplify3 (seq, this, valueize);
> + return gimple_resimplify3 (seq, this, valueize, simplifier);
> case 4:
> - return gimple_resimplify4 (seq, this, valueize);
> + return gimple_resimplify4 (seq, this, valueize, simplifier);
> case 5:
> - return gimple_resimplify5 (seq, this, valueize);
> + return gimple_resimplify5 (seq, this, valueize, simplifier);
> case 6:
> - return gimple_resimplify6 (seq, this, valueize);
> + return gimple_resimplify6 (seq, this, valueize, simplifier);
> case 7:
> - return gimple_resimplify7 (seq, this, valueize);
> + return gimple_resimplify7 (seq, this, valueize, simplifier);
> default:
> gcc_unreachable ();
> }
> @@ -303,7 +315,8 @@ build_call_internal (internal_fn fn, gimple_match_op
> *res_op)
>
> static bool
> maybe_resimplify_conditional_op (gimple_seq *seq, gimple_match_op *res_op,
> - tree (*valueize) (tree))
> + tree (*valueize) (tree),
> + gimple_match_simplify_fn simplifier)
> {
> if (!res_op->cond.cond)
> return false;
> @@ -370,7 +383,7 @@ maybe_resimplify_conditional_op (gimple_seq *seq,
> gimple_match_op *res_op,
> res_op->cond.cond, res_op->ops[0],
> res_op->cond.else_value);
> *res_op = new_op;
> - return gimple_resimplify3 (seq, res_op, valueize);
> + return gimple_resimplify3 (seq, res_op, valueize, simplifier);
> }
>
> /* Otherwise try rewriting the operation as an IFN_COND_* call.
> @@ -400,7 +413,8 @@ maybe_resimplify_conditional_op (gimple_seq *seq,
> gimple_match_op *res_op,
>
> static bool
> try_conditional_simplification (internal_fn ifn, gimple_match_op *res_op,
> - gimple_seq *seq, tree (*valueize) (tree))
> + gimple_seq *seq, tree (*valueize) (tree),
> + gimple_match_simplify_fn simplifier)
> {
> code_helper op;
> tree_code code = conditional_internal_fn_code (ifn);
> @@ -431,22 +445,22 @@ try_conditional_simplification (internal_fn ifn,
> gimple_match_op *res_op,
> switch (num_ops - num_cond_ops)
> {
> case 1:
> - if (!gimple_resimplify1 (seq, &cond_op, valueize))
> + if (!gimple_resimplify1 (seq, &cond_op, valueize, simplifier))
> return false;
> break;
> case 2:
> - if (!gimple_resimplify2 (seq, &cond_op, valueize))
> + if (!gimple_resimplify2 (seq, &cond_op, valueize, simplifier))
> return false;
> break;
> case 3:
> - if (!gimple_resimplify3 (seq, &cond_op, valueize))
> + if (!gimple_resimplify3 (seq, &cond_op, valueize, simplifier))
> return false;
> break;
> default:
> gcc_unreachable ();
> }
> *res_op = cond_op;
> - maybe_resimplify_conditional_op (seq, res_op, valueize);
> + maybe_resimplify_conditional_op (seq, res_op, valueize, simplifier);
> return true;
> }
>
> @@ -873,8 +887,12 @@ gimple_extract_op (gimple *stmt, gimple_match_op *res_op)
>
> bool
> gimple_simplify (gimple *stmt, gimple_match_op *res_op, gimple_seq *seq,
> - tree (*valueize)(tree), tree (*top_valueize)(tree))
> + tree (*valueize)(tree), tree (*top_valueize)(tree),
> + gimple_match_simplify_fn simplifier)
> {
> + if (!simplifier)
> + simplifier = gimple_simplify;
> +
> bool valueized = false;
> auto valueize_op = [&](tree op)
> {
> @@ -887,13 +905,14 @@ gimple_simplify (gimple *stmt, gimple_match_op *res_op,
> gimple_seq *seq,
> if (res_op->code.is_internal_fn ())
> {
> internal_fn ifn = internal_fn (res_op->code);
> - if (try_conditional_simplification (ifn, res_op, seq, valueize))
> + if (try_conditional_simplification (ifn, res_op, seq, valueize,
> + simplifier))
> return true;
> }
>
> if (!res_op->reverse
> && res_op->num_ops
> - && res_op->resimplify (seq, valueize))
> + && res_op->resimplify (seq, valueize, simplifier))
> return true;
>
> return valueized;
> @@ -907,7 +926,8 @@ gimple_simplify (gimple *stmt, gimple_match_op *res_op,
> gimple_seq *seq,
>
> static bool
> gimple_resimplify1 (gimple_seq *seq, gimple_match_op *res_op,
> - tree (*valueize)(tree))
> + tree (*valueize)(tree),
> + gimple_match_simplify_fn simplifier)
> {
> if (constant_for_folding (res_op->ops[0]))
> {
> @@ -928,7 +948,7 @@ gimple_resimplify1 (gimple_seq *seq, gimple_match_op
> *res_op,
> if (TREE_OVERFLOW_P (tem))
> tem = drop_tree_overflow (tem);
> res_op->set_value (tem);
> - maybe_resimplify_conditional_op (seq, res_op, valueize);
> + maybe_resimplify_conditional_op (seq, res_op, valueize, simplifier);
> return true;
> }
> }
> @@ -949,8 +969,7 @@ gimple_resimplify1 (gimple_seq *seq, gimple_match_op
> *res_op,
>
> ++depth;
> gimple_match_op res_op2 (*res_op);
> - if (gimple_simplify (&res_op2, seq, valueize,
> - res_op->code, res_op->type, res_op->ops[0]))
> + if (simplifier (&res_op2, seq, valueize))
> {
> --depth;
> *res_op = res_op2;
> @@ -958,7 +977,7 @@ gimple_resimplify1 (gimple_seq *seq, gimple_match_op
> *res_op,
> }
> --depth;
>
> - if (maybe_resimplify_conditional_op (seq, res_op, valueize))
> + if (maybe_resimplify_conditional_op (seq, res_op, valueize, simplifier))
> return true;
>
> return false;
> @@ -972,7 +991,8 @@ gimple_resimplify1 (gimple_seq *seq, gimple_match_op
> *res_op,
>
> static bool
> gimple_resimplify2 (gimple_seq *seq, gimple_match_op *res_op,
> - tree (*valueize)(tree))
> + tree (*valueize)(tree),
> + gimple_match_simplify_fn simplifier)
> {
> if (constant_for_folding (res_op->ops[0])
> && constant_for_folding (res_op->ops[1]))
> @@ -995,7 +1015,7 @@ gimple_resimplify2 (gimple_seq *seq, gimple_match_op
> *res_op,
> if (TREE_OVERFLOW_P (tem))
> tem = drop_tree_overflow (tem);
> res_op->set_value (tem);
> - maybe_resimplify_conditional_op (seq, res_op, valueize);
> + maybe_resimplify_conditional_op (seq, res_op, valueize, simplifier);
> return true;
> }
> }
> @@ -1026,9 +1046,7 @@ gimple_resimplify2 (gimple_seq *seq, gimple_match_op
> *res_op,
>
> ++depth;
> gimple_match_op res_op2 (*res_op);
> - if (gimple_simplify (&res_op2, seq, valueize,
> - res_op->code, res_op->type,
> - res_op->ops[0], res_op->ops[1]))
> + if (simplifier (&res_op2, seq, valueize))
> {
> --depth;
> *res_op = res_op2;
> @@ -1036,7 +1054,7 @@ gimple_resimplify2 (gimple_seq *seq, gimple_match_op
> *res_op,
> }
> --depth;
>
> - if (maybe_resimplify_conditional_op (seq, res_op, valueize))
> + if (maybe_resimplify_conditional_op (seq, res_op, valueize, simplifier))
> return true;
>
> return canonicalized;
> @@ -1050,7 +1068,8 @@ gimple_resimplify2 (gimple_seq *seq, gimple_match_op
> *res_op,
>
> static bool
> gimple_resimplify3 (gimple_seq *seq, gimple_match_op *res_op,
> - tree (*valueize)(tree))
> + tree (*valueize)(tree),
> + gimple_match_simplify_fn simplifier)
> {
> if (constant_for_folding (res_op->ops[0])
> && constant_for_folding (res_op->ops[1])
> @@ -1075,7 +1094,7 @@ gimple_resimplify3 (gimple_seq *seq, gimple_match_op
> *res_op,
> if (TREE_OVERFLOW_P (tem))
> tem = drop_tree_overflow (tem);
> res_op->set_value (tem);
> - maybe_resimplify_conditional_op (seq, res_op, valueize);
> + maybe_resimplify_conditional_op (seq, res_op, valueize, simplifier);
> return true;
> }
> }
> @@ -1102,9 +1121,7 @@ gimple_resimplify3 (gimple_seq *seq, gimple_match_op
> *res_op,
>
> ++depth;
> gimple_match_op res_op2 (*res_op);
> - if (gimple_simplify (&res_op2, seq, valueize,
> - res_op->code, res_op->type,
> - res_op->ops[0], res_op->ops[1], res_op->ops[2]))
> + if (simplifier (&res_op2, seq, valueize))
> {
> --depth;
> *res_op = res_op2;
> @@ -1112,7 +1129,7 @@ gimple_resimplify3 (gimple_seq *seq, gimple_match_op
> *res_op,
> }
> --depth;
>
> - if (maybe_resimplify_conditional_op (seq, res_op, valueize))
> + if (maybe_resimplify_conditional_op (seq, res_op, valueize, simplifier))
> return true;
>
> return canonicalized;
> @@ -1126,7 +1143,8 @@ gimple_resimplify3 (gimple_seq *seq, gimple_match_op
> *res_op,
>
> static bool
> gimple_resimplify4 (gimple_seq *seq, gimple_match_op *res_op,
> - tree (*valueize)(tree))
> + tree (*valueize)(tree),
> + gimple_match_simplify_fn simplifier)
> {
> /* No constant folding is defined for four-operand functions. */
>
> @@ -1152,10 +1170,7 @@ gimple_resimplify4 (gimple_seq *seq, gimple_match_op
> *res_op,
>
> ++depth;
> gimple_match_op res_op2 (*res_op);
> - if (gimple_simplify (&res_op2, seq, valueize,
> - res_op->code, res_op->type,
> - res_op->ops[0], res_op->ops[1], res_op->ops[2],
> - res_op->ops[3]))
> + if (simplifier (&res_op2, seq, valueize))
> {
> --depth;
> *res_op = res_op2;
> @@ -1163,7 +1178,7 @@ gimple_resimplify4 (gimple_seq *seq, gimple_match_op
> *res_op,
> }
> --depth;
>
> - if (maybe_resimplify_conditional_op (seq, res_op, valueize))
> + if (maybe_resimplify_conditional_op (seq, res_op, valueize, simplifier))
> return true;
>
> return canonicalized;
> @@ -1177,7 +1192,8 @@ gimple_resimplify4 (gimple_seq *seq, gimple_match_op
> *res_op,
>
> static bool
> gimple_resimplify5 (gimple_seq *seq, gimple_match_op *res_op,
> - tree (*valueize)(tree))
> + tree (*valueize)(tree),
> + gimple_match_simplify_fn simplifier)
> {
> /* No constant folding is defined for five-operand functions. */
>
> @@ -1192,16 +1208,13 @@ gimple_resimplify5 (gimple_seq *seq, gimple_match_op
> *res_op,
> }
>
> gimple_match_op res_op2 (*res_op);
> - if (gimple_simplify (&res_op2, seq, valueize,
> - res_op->code, res_op->type,
> - res_op->ops[0], res_op->ops[1], res_op->ops[2],
> - res_op->ops[3], res_op->ops[4]))
> + if (simplifier (&res_op2, seq, valueize))
> {
> *res_op = res_op2;
> return true;
> }
>
> - if (maybe_resimplify_conditional_op (seq, res_op, valueize))
> + if (maybe_resimplify_conditional_op (seq, res_op, valueize, simplifier))
> return true;
>
> return canonicalized;
> @@ -1215,7 +1228,8 @@ gimple_resimplify5 (gimple_seq *seq, gimple_match_op
> *res_op,
>
> static bool
> gimple_resimplify6 (gimple_seq *seq, gimple_match_op *res_op,
> - tree (*valueize)(tree))
> + tree (*valueize)(tree),
> + gimple_match_simplify_fn simplifier)
> {
> /* No constant folding is defined for six-operand functions. */
>
> @@ -1230,16 +1244,13 @@ gimple_resimplify6 (gimple_seq *seq, gimple_match_op
> *res_op,
> }
>
> gimple_match_op res_op2 (*res_op);
> - if (gimple_simplify (&res_op2, seq, valueize,
> - res_op->code, res_op->type,
> - res_op->ops[0], res_op->ops[1], res_op->ops[2],
> - res_op->ops[3], res_op->ops[4], res_op->ops[5]))
> + if (simplifier (&res_op2, seq, valueize))
> {
> *res_op = res_op2;
> return true;
> }
>
> - if (maybe_resimplify_conditional_op (seq, res_op, valueize))
> + if (maybe_resimplify_conditional_op (seq, res_op, valueize, simplifier))
> return true;
>
> return canonicalized;
> @@ -1253,7 +1264,8 @@ gimple_resimplify6 (gimple_seq *seq, gimple_match_op
> *res_op,
>
> static bool
> gimple_resimplify7 (gimple_seq *seq, gimple_match_op *res_op,
> - tree (*valueize)(tree))
> + tree (*valueize)(tree),
> + gimple_match_simplify_fn simplifier)
> {
> /* No constant folding is defined for seven-operand functions. */
>
> @@ -1268,17 +1280,13 @@ gimple_resimplify7 (gimple_seq *seq, gimple_match_op
> *res_op,
> }
>
> gimple_match_op res_op2 (*res_op);
> - if (gimple_simplify (&res_op2, seq, valueize,
> - res_op->code, res_op->type,
> - res_op->ops[0], res_op->ops[1], res_op->ops[2],
> - res_op->ops[3], res_op->ops[4], res_op->ops[5],
> - res_op->ops[6]))
> + if (simplifier (&res_op2, seq, valueize))
> {
> *res_op = res_op2;
> return true;
> }
>
> - if (maybe_resimplify_conditional_op (seq, res_op, valueize))
> + if (maybe_resimplify_conditional_op (seq, res_op, valueize, simplifier))
> return true;
>
> return canonicalized;
> diff --git a/gcc/gimple-match.h b/gcc/gimple-match.h
> index
> 8ff58e8cd7f27a1adc2fabf0f76ee940dea09199..5f6a48edfb5883a964537287e0675bfb273e3005
> 100644
> --- a/gcc/gimple-match.h
> +++ b/gcc/gimple-match.h
> @@ -23,6 +23,12 @@ along with GCC; see the file COPYING3. If not see
> #define GCC_GIMPLE_MATCH_H
>
>
> +class gimple_match_op;
> +
> +/* Dispatch to the entry points provided by a generated GIMPLE match file.
> */
> +typedef bool (*gimple_match_simplify_fn) (gimple_match_op *, gimple_seq *,
> + tree (*) (tree));
> +
> /* Represents the condition under which an operation should happen,
> and the value to use otherwise. The condition applies elementwise
> (as for VEC_COND_EXPR) if the values are vectors. */
> @@ -112,7 +118,8 @@ public:
>
> tree op_or_null (unsigned int) const;
>
> - bool resimplify (gimple_seq *, tree (*)(tree));
> + bool resimplify (gimple_seq *, tree (*)(tree),
> + gimple_match_simplify_fn = NULL);
>
> /* The maximum value of NUM_OPS. */
> static const unsigned int MAX_NUM_OPS = 7;
> @@ -408,7 +415,8 @@ extern tree (*mprts_hook) (gimple_match_op *);
>
> bool gimple_extract_op (gimple *, gimple_match_op *);
> bool gimple_simplify (gimple *, gimple_match_op *, gimple_seq *,
> - tree (*)(tree), tree (*)(tree));
> + tree (*)(tree), tree (*)(tree),
> + gimple_match_simplify_fn = NULL);
> tree maybe_push_res_to_seq (gimple_match_op *, gimple_seq *,
> tree res = NULL_TREE);
> void maybe_build_generic_op (gimple_match_op *);
>
>
>
--
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald; (HRB 36809, AG Nuernberg)