> -----Original Message-----
> From: Richard Biener <[email protected]>
> Sent: 06 July 2026 14:46
> To: Tamar Christina <[email protected]>
> Cc: [email protected]; nd <[email protected]>
> Subject: Re: [patch 1/2]middle-end: support namespaces in genmatch
>
> 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..948199c6f0c2a10003919a
> 9ca738bed5d29b1ee9 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?
>
Sorry about that. In my excitement to get it out I neglected some explanation.
Will extend on that in v2 using the global state.
Thanks,
Tamar
>
> > }
> >
> > 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..8626a1990bd81d1f8950e
> 172726c5f9e61abc628 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..5f6a48edfb5883a96453728
> 7e0675bfb273e3005 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)