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)

Reply via email to