On Thu, 16 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.
>         (gimple_match_op::gimple_match_op): Support new gimplifiers.
>         (gimple_match_op::set_simplifier): New.
>       * gimple-fold.h (gimple_simplify): New.
>       * tree-ssa-sccvn.cc (process_bb): Pass default gimplifier.
>       * tree-vect-patterns.cc: Fix include orders.
> 
> ---
> diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc
> index 
> 920cf27877d3bf69c8ffcbb3497d9d0b54f662c7..aff36596b3a1bf2d8571c853ec42a43df9520334
>  100644
> --- a/gcc/genmatch.cc
> +++ b/gcc/genmatch.cc
> @@ -56,6 +56,16 @@ 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;

This is C++, no need for a typedef?

> +
> +/* Namespace space information for code generation.  */
> +ns_info ns;

It should be a singleton, so possibly

  struct {
...
  } ns;

works as well?

> +
>  /* Verboseness.  0 is quiet, 1 adds some warnings, 2 is for debugging.  */
>  unsigned verbose;
>  
> @@ -880,9 +890,9 @@ static vec<int> dbg_line_numbers;
>  static void
>  write_header_declarations (bool gimple, 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);
>  }
>  
>  static void
> @@ -891,9 +901,9 @@ define_dump_logs (bool gimple, 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 ());
> @@ -3329,6 +3339,8 @@ expr::gen_transform (FILE *f, int indent, const char 
> *dest, bool gimple,
>        fprintf_indent (f, indent,
>                     "gimple_match_op tem_op (res_op->cond.any_else (), "
>                     "ERROR_MARK, error_mark_node, 1);\n");
> +      fprintf_indent (f, indent,
> +                   "tem_op.set_simplifier (gimple%s_simplify);\n", ns.l);

For code-size and compile-time can we elide this for the
"default" namespace and have it default initialized? This would also ...

>      }
>    else
>      fprintf_indent (f, indent,
> @@ -3425,6 +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.set_simplifier "
> +                       "(gimple%s_simplify);\n", ns.l);
>         fprintf_indent (f, indent, "tem_op.resimplify (%s, valueize);\n",
>                         !force_leaf ? "lseq" : "NULL");
>         fprintf_indent (f, indent,
> @@ -4299,7 +4313,7 @@ emit_logging_call (FILE *f, int indent, class simplify 
> *s, operand *result,
>                                 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);
> @@ -4893,8 +4907,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"
> @@ -4961,18 +4975,18 @@ 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, ")");
> @@ -4998,13 +5012,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 +5039,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 +5078,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,6 +5096,32 @@ 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.  */
> @@ -5089,8 +5129,8 @@ decision_tree::gen (vec <FILE *> &files, bool gimple)
>  void
>  write_predicate (FILE *f, predicate_id *p, decision_tree &dt, 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, "");
> @@ -6271,7 +6311,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 +6341,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 +6355,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 +6377,36 @@ main (int argc, char **argv)
>        return 1;
>      }
>  
> +  /* Initialize priting information. */
> +  if (s_namespace)
> +    {
> +      if (!gimple)
> +     {
> +       fatal_at ((location_t)0, "%<--namespace%> not supported for GENERIC");
> +       return 1;
> +     }
> +
> +      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)
> @@ -6406,8 +6480,9 @@ 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);
>      }
> @@ -6462,7 +6537,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 +6547,8 @@ main (int argc, char **argv)
>    cpp_destroy (r);
>  
>    delete operators;
> +  XDELETE (ns.l);
> +  XDELETE (ns.u);
>  
>    return 0;
>  }
> diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
> index 
> 4422a48383d5ce221deacf44c491130130a47d6c..d1da1f00f0fed7765c8785158a915cb9bb3c88c0
>  100644
> --- a/gcc/gimple-fold.cc
> +++ b/gcc/gimple-fold.cc
> @@ -6937,6 +6937,7 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, 
> tree (*valueize) (tree),
>      {
>        gimple_seq seq = NULL;
>        gimple_match_op res_op;
> +      res_op.set_simplifier (gimple_simplify);

... avoid most of these changes.

>        if (gimple_simplify (stmt, &res_op, inplace ? NULL : &seq,
>                          valueize, valueize)
>         && replace_stmt_with_simplification (gsi, &res_op, &seq, inplace,
> @@ -9586,6 +9587,7 @@ gimple_fold_stmt_to_constant_1 (gimple *stmt, tree 
> (*valueize) (tree),
>                               tree (*gvalueize) (tree))
>  {
>    gimple_match_op res_op;
> +  res_op.set_simplifier (gimple_simplify);
>    /* ???  The SSA propagators do not correctly deal with following SSA 
> use-def
>       edges if there are intermediate VARYING defs.  For this reason
>       do not follow SSA edges here even though SCCVN can technically
> @@ -11092,7 +11094,8 @@ gimple_build (gimple_stmt_iterator *gsi,
>    gimple_seq seq = NULL;
>    tree res
>      = gimple_simplify (code, type, op0, &seq,
> -                    gsi->bb ? follow_all_ssa_edges : gimple_build_valueize);
> +                    gsi->bb ? follow_all_ssa_edges : gimple_build_valueize,
> +                    gimple_simplify);
>    if (!res)
>      {
>        res = make_ssa_name (type);
> @@ -11124,7 +11127,8 @@ gimple_build (gimple_stmt_iterator *gsi,
>    gimple_seq seq = NULL;
>    tree res
>      = gimple_simplify (code, type, op0, op1, &seq,
> -                    gsi->bb ? follow_all_ssa_edges : gimple_build_valueize);
> +                    gsi->bb ? follow_all_ssa_edges : gimple_build_valueize,
> +                    gimple_simplify);

And these?

>    if (!res)
>      {
>        res = make_ssa_name (type);
> @@ -11151,7 +11155,8 @@ gimple_build (gimple_stmt_iterator *gsi,
>    gimple_seq seq = NULL;
>    tree res
>      = gimple_simplify (code, type, op0, op1, op2, &seq,
> -                    gsi->bb ? follow_all_ssa_edges : gimple_build_valueize);
> +                    gsi->bb ? follow_all_ssa_edges : gimple_build_valueize,
> +                    gimple_simplify);
>    if (!res)
>      {
>        res = make_ssa_name (type);
> @@ -11212,7 +11217,8 @@ gimple_build (gimple_stmt_iterator *gsi,
>             tree type, tree arg0)
>  {
>    gimple_seq seq = NULL;
> -  tree res = gimple_simplify (fn, type, arg0, &seq, gimple_build_valueize);
> +  tree res = gimple_simplify (fn, type, arg0, &seq, gimple_build_valueize,
> +                           gimple_simplify);
>    if (!res)
>      {
>        gcall *stmt;
> @@ -11249,7 +11255,7 @@ gimple_build (gimple_stmt_iterator *gsi,
>  {
>    gimple_seq seq = NULL;
>    tree res = gimple_simplify (fn, type, arg0, arg1, &seq,
> -                           gimple_build_valueize);
> +                           gimple_build_valueize, gimple_simplify);
>    if (!res)
>      {
>        gcall *stmt;
> @@ -11286,7 +11292,7 @@ gimple_build (gimple_stmt_iterator *gsi,
>  {
>    gimple_seq seq = NULL;
>    tree res = gimple_simplify (fn, type, arg0, arg1, arg2,
> -                           &seq, gimple_build_valueize);
> +                           &seq, gimple_build_valueize, gimple_simplify);
>    if (!res)
>      {
>        gcall *stmt;
> diff --git a/gcc/gimple-fold.h b/gcc/gimple-fold.h
> index 
> f18535607791ea33255e475a9582fd6d797251dd..ca7519c4c8904127ad5a80e1d39101550b397d91
>  100644
> --- a/gcc/gimple-fold.h
> +++ b/gcc/gimple-fold.h
> @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  If not see
>  #define GCC_GIMPLE_FOLD_H
>  
>  #include "tree-pass.h"
> +#include "gimple-match.h"
>  
>  extern tree canonicalize_constructor_val (tree, tree);
>  extern tree get_symbol_constant_value (tree);
> @@ -270,17 +271,23 @@ extern void mark_lhs_in_seq_for_dce (bitmap, 
> gimple_seq);
>  
>  /* In gimple-match.cc.  */
>  extern tree gimple_simplify (enum tree_code, tree, tree,
> -                          gimple_seq *, tree (*)(tree));
> +                          gimple_seq *, tree (*)(tree),
> +                          gimple_match_simplify_fn);
>  extern tree gimple_simplify (enum tree_code, tree, tree, tree,
> -                          gimple_seq *, tree (*)(tree));
> +                          gimple_seq *, tree (*)(tree),
> +                          gimple_match_simplify_fn);
>  extern tree gimple_simplify (enum tree_code, tree, tree, tree, tree,
> -                          gimple_seq *, tree (*)(tree));
> +                          gimple_seq *, tree (*)(tree),
> +                          gimple_match_simplify_fn);
>  extern tree gimple_simplify (combined_fn, tree, tree,
> -                          gimple_seq *, tree (*)(tree));
> +                          gimple_seq *, tree (*)(tree),
> +                          gimple_match_simplify_fn);
>  extern tree gimple_simplify (combined_fn, tree, tree, tree,
> -                          gimple_seq *, tree (*)(tree));
> +                          gimple_seq *, tree (*)(tree),
> +                          gimple_match_simplify_fn);
>  extern tree gimple_simplify (combined_fn, tree, tree, tree, tree,
> -                          gimple_seq *, tree (*)(tree));
> +                          gimple_seq *, tree (*)(tree),
> +                          gimple_match_simplify_fn);
>  
>  /* Returns true if we are doing the fold before expansion to rtl.   */
>  inline bool
> diff --git a/gcc/gimple-match-exports.cc b/gcc/gimple-match-exports.cc
> index 
> 74f2c5f19bcfdf2e40435119ac757658a110e471..0faaa4c4f036a300bc018c2fac306fb939eb7378
>  100644
> --- a/gcc/gimple-match-exports.cc
> +++ b/gcc/gimple-match-exports.cc
> @@ -66,22 +66,23 @@ 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.  */
>  
>  tree gimple_simplify (enum tree_code, tree, tree, gimple_seq *,
> -                  tree (*)(tree));
> +                  tree (*)(tree), gimple_match_simplify_fn);
>  tree gimple_simplify (enum tree_code, tree, tree, tree, gimple_seq *,
> -                  tree (*)(tree));
> +                  tree (*)(tree), gimple_match_simplify_fn);
>  tree gimple_simplify (enum tree_code, tree, tree, tree, tree, gimple_seq *,
> -                  tree (*)(tree));
> +                  tree (*)(tree), gimple_match_simplify_fn);
>  tree gimple_simplify (combined_fn, tree, tree, gimple_seq *,
> -                  tree (*)(tree));
> +                  tree (*)(tree), gimple_match_simplify_fn);
>  tree gimple_simplify (combined_fn, tree, tree, tree, gimple_seq *,
> -                  tree (*)(tree));
> +                  tree (*)(tree), gimple_match_simplify_fn);
>  tree gimple_simplify (combined_fn, tree, tree, tree, tree, gimple_seq *,
> -                  tree (*)(tree));
> +                  tree (*)(tree), gimple_match_simplify_fn);
>  
>  tree do_valueize (tree, tree (*)(tree), bool &);
>  tree do_valueize (tree (*)(tree), tree);
> @@ -349,6 +350,7 @@ maybe_resimplify_conditional_op (gimple_seq *seq, 
> gimple_match_op *res_op,
>       create a (VEC_)COND_EXPR between them, then see if it can be further
>       simplified.  */
>    gimple_match_op new_op;
> +  new_op.set_simplifier (res_op->m_simplifier);
>    if (res_op->cond.else_value
>        && gimple_simplified_result_is_gimple_val (res_op))
>      {
> @@ -426,6 +428,7 @@ try_conditional_simplification (internal_fn ifn, 
> gimple_match_op *res_op,
>    gimple_match_op cond_op (gimple_match_cond (res_op->ops[0],
>                                             else_value, len, bias),
>                          op, res_op->type, num_ops - num_cond_ops);
> +  cond_op.set_simplifier (res_op->m_simplifier);
>  
>    memcpy (cond_op.ops, res_op->ops + 1, (num_ops - 1) * sizeof *cond_op.ops);
>    switch (num_ops - num_cond_ops)
> @@ -586,7 +589,8 @@ maybe_push_res_to_seq (gimple_match_op *res_op, 
> gimple_seq *seq, tree res)
>  tree
>  gimple_simplify (enum tree_code code, tree type,
>                tree op0,
> -              gimple_seq *seq, tree (*valueize)(tree))
> +              gimple_seq *seq, tree (*valueize)(tree),
> +              gimple_match_simplify_fn simplifier)
>  {
>    if (constant_for_folding (op0))
>      {
> @@ -597,6 +601,7 @@ gimple_simplify (enum tree_code code, tree type,
>      }
>  
>    gimple_match_op res_op;
> +  res_op.set_simplifier (simplifier);
>    if (!gimple_simplify (&res_op, seq, valueize, code, type, op0))
>      return NULL_TREE;
>    return maybe_push_res_to_seq (&res_op, seq);
> @@ -607,7 +612,8 @@ gimple_simplify (enum tree_code code, tree type,
>  tree
>  gimple_simplify (enum tree_code code, tree type,
>                tree op0, tree op1,
> -              gimple_seq *seq, tree (*valueize)(tree))
> +              gimple_seq *seq, tree (*valueize)(tree),
> +              gimple_match_simplify_fn simplifier)
>  {
>    if (constant_for_folding (op0) && constant_for_folding (op1))
>      {
> @@ -629,6 +635,7 @@ gimple_simplify (enum tree_code code, tree type,
>      }
>  
>    gimple_match_op res_op;
> +  res_op.set_simplifier (simplifier);
>    if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1))
>      return NULL_TREE;
>    return maybe_push_res_to_seq (&res_op, seq);
> @@ -639,7 +646,8 @@ gimple_simplify (enum tree_code code, tree type,
>  tree
>  gimple_simplify (enum tree_code code, tree type,
>                tree op0, tree op1, tree op2,
> -              gimple_seq *seq, tree (*valueize)(tree))
> +              gimple_seq *seq, tree (*valueize)(tree),
> +              gimple_match_simplify_fn simplifier)
>  {
>    if (constant_for_folding (op0) && constant_for_folding (op1)
>        && constant_for_folding (op2))
> @@ -657,6 +665,7 @@ gimple_simplify (enum tree_code code, tree type,
>      std::swap (op0, op1);
>  
>    gimple_match_op res_op;
> +  res_op.set_simplifier (simplifier);

Convenience for typing probably also asks for extra gimple_match_op
CTORs with the simplifier specified?

>    if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1, op2))
>      return NULL_TREE;
>    return maybe_push_res_to_seq (&res_op, seq);
> @@ -667,7 +676,8 @@ gimple_simplify (enum tree_code code, tree type,
>  tree
>  gimple_simplify (combined_fn fn, tree type,
>                tree arg0,
> -              gimple_seq *seq, tree (*valueize)(tree))
> +              gimple_seq *seq, tree (*valueize)(tree),
> +              gimple_match_simplify_fn simplifier)
>  {
>    if (constant_for_folding (arg0))
>      {
> @@ -677,6 +687,7 @@ gimple_simplify (combined_fn fn, tree type,
>      }
>  
>    gimple_match_op res_op;
> +  res_op.set_simplifier (simplifier);
>    if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0))
>      return NULL_TREE;
>    return maybe_push_res_to_seq (&res_op, seq);
> @@ -687,7 +698,8 @@ gimple_simplify (combined_fn fn, tree type,
>  tree
>  gimple_simplify (combined_fn fn, tree type,
>                tree arg0, tree arg1,
> -              gimple_seq *seq, tree (*valueize)(tree))
> +              gimple_seq *seq, tree (*valueize)(tree),
> +              gimple_match_simplify_fn simplifier)
>  {
>    if (constant_for_folding (arg0)
>        && constant_for_folding (arg1))
> @@ -698,6 +710,7 @@ gimple_simplify (combined_fn fn, tree type,
>      }
>  
>    gimple_match_op res_op;
> +  res_op.set_simplifier (simplifier);
>    if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1))
>      return NULL_TREE;
>    return maybe_push_res_to_seq (&res_op, seq);
> @@ -708,7 +721,8 @@ gimple_simplify (combined_fn fn, tree type,
>  tree
>  gimple_simplify (combined_fn fn, tree type,
>                tree arg0, tree arg1, tree arg2,
> -              gimple_seq *seq, tree (*valueize)(tree))
> +              gimple_seq *seq, tree (*valueize)(tree),
> +              gimple_match_simplify_fn simplifier)
>  {
>    if (constant_for_folding (arg0)
>        && constant_for_folding (arg1)
> @@ -720,6 +734,7 @@ gimple_simplify (combined_fn fn, tree type,
>      }
>  
>    gimple_match_op res_op;
> +  res_op.set_simplifier (simplifier);
>    if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1, arg2))
>      return NULL_TREE;
>    return maybe_push_res_to_seq (&res_op, seq);
> @@ -949,8 +964,8 @@ 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]))
> +  res_op2.set_simplifier (res_op->m_simplifier);

Like I'd have expected the copy CTOR to also copy the simplifier?

> +  if (res_op->m_simplifier (&res_op2, seq, valueize))
>      {
>        --depth;
>        *res_op = res_op2;
> @@ -1026,9 +1041,8 @@ 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]))
> +  res_op2.set_simplifier (res_op->m_simplifier);
> +  if (res_op->m_simplifier (&res_op2, seq, valueize))
>      {
>        --depth;
>        *res_op = res_op2;
> @@ -1102,9 +1116,8 @@ 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]))
> +  res_op2.set_simplifier (res_op->m_simplifier);
> +  if (res_op->m_simplifier (&res_op2, seq, valueize))
>      {
>        --depth;
>        *res_op = res_op2;
> @@ -1152,10 +1165,8 @@ 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]))
> +  res_op2.set_simplifier (res_op->m_simplifier);
> +  if (res_op->m_simplifier (&res_op2, seq, valueize))
>      {
>        --depth;
>        *res_op = res_op2;
> @@ -1192,10 +1203,8 @@ 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]))
> +  res_op2.set_simplifier (res_op->m_simplifier);
> +  if (res_op->m_simplifier (&res_op2, seq, valueize))
>      {
>        *res_op = res_op2;
>        return true;
> @@ -1230,10 +1239,8 @@ 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]))
> +  res_op2.set_simplifier (res_op->m_simplifier);
> +  if (res_op->m_simplifier (&res_op2, seq, valueize))
>      {
>        *res_op = res_op2;
>        return true;
> @@ -1268,11 +1275,8 @@ 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]))
> +  res_op2.set_simplifier (res_op->m_simplifier);
> +  if (res_op->m_simplifier (&res_op2, seq, valueize))
>      {
>        *res_op = res_op2;
>        return true;
> diff --git a/gcc/gimple-match.h b/gcc/gimple-match.h
> index 
> 8ff58e8cd7f27a1adc2fabf0f76ee940dea09199..39bd70b33af2ca44991079b6baf2f3aa524c84cd
>  100644
> --- a/gcc/gimple-match.h
> +++ b/gcc/gimple-match.h
> @@ -23,6 +23,14 @@ 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));
> +/* Default implementation for match.pd.  */
> +extern bool gimple_simplify (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.  */
> @@ -108,6 +116,7 @@ public:
>    void set_op (code_helper, tree, tree, tree, tree, tree, tree);
>    void set_op (code_helper, tree, tree, tree, tree, tree, tree, tree);
>    void set_op (code_helper, tree, tree, tree, tree, tree, tree, tree, tree);
> +  void set_simplifier (gimple_match_simplify_fn);
>    void set_value (tree);
>  
>    tree op_or_null (unsigned int) const;
> @@ -134,6 +143,9 @@ public:
>    /* The number of operands to CODE.  */
>    unsigned int num_ops;
>  
> +  /* The simplifier to use when regimplifying statements.  */
> +  gimple_match_simplify_fn m_simplifier = NULL;
> +

why NSMDI here?

>    /* The operands to CODE.  Only the first NUM_OPS entries are meaningful.  
> */
>    tree ops[MAX_NUM_OPS];
>  
> @@ -143,7 +155,7 @@ public:
>  inline
>  gimple_match_op::gimple_match_op ()
>    : cond (gimple_match_cond::UNCOND), type (NULL_TREE), reverse (false),
> -    num_ops (0)
> +    num_ops (0), m_simplifier (gimple_simplify)
>  {
>  }
>  
> @@ -155,7 +167,7 @@ gimple_match_op::gimple_match_op (const gimple_match_cond 
> &cond_in,
>                                 code_helper code_in, tree type_in,
>                                 unsigned int num_ops_in)
>    : cond (cond_in), code (code_in), type (type_in), reverse (false),
> -    num_ops (num_ops_in)
> +    num_ops (num_ops_in), m_simplifier (gimple_simplify)
>  {
>  }
>  
> @@ -166,7 +178,7 @@ gimple_match_op::gimple_match_op (const gimple_match_cond 
> &cond_in,
>                                 code_helper code_in, tree type_in,
>                                 tree op0)
>    : cond (cond_in), code (code_in), type (type_in), reverse (false),
> -    num_ops (1)
> +    num_ops (1), m_simplifier (gimple_simplify)
>  {
>    ops[0] = op0;
>  }
> @@ -176,7 +188,7 @@ gimple_match_op::gimple_match_op (const gimple_match_cond 
> &cond_in,
>                                 code_helper code_in, tree type_in,
>                                 tree op0, tree op1)
>    : cond (cond_in), code (code_in), type (type_in), reverse (false),
> -    num_ops (2)
> +    num_ops (2), m_simplifier (gimple_simplify)
>  {
>    ops[0] = op0;
>    ops[1] = op1;
> @@ -187,7 +199,7 @@ gimple_match_op::gimple_match_op (const gimple_match_cond 
> &cond_in,
>                                 code_helper code_in, tree type_in,
>                                 tree op0, tree op1, tree op2)
>    : cond (cond_in), code (code_in), type (type_in), reverse (false),
> -    num_ops (3)
> +    num_ops (3), m_simplifier (gimple_simplify)
>  {
>    ops[0] = op0;
>    ops[1] = op1;
> @@ -199,7 +211,7 @@ gimple_match_op::gimple_match_op (const gimple_match_cond 
> &cond_in,
>                                 code_helper code_in, tree type_in,
>                                 tree op0, tree op1, tree op2, tree op3)
>    : cond (cond_in), code (code_in), type (type_in), reverse (false),
> -    num_ops (4)
> +    num_ops (4), m_simplifier (gimple_simplify)
>  {
>    ops[0] = op0;
>    ops[1] = op1;
> @@ -213,7 +225,7 @@ gimple_match_op::gimple_match_op (const gimple_match_cond 
> &cond_in,
>                                 tree op0, tree op1, tree op2, tree op3,
>                                 tree op4)
>    : cond (cond_in), code (code_in), type (type_in), reverse (false),
> -    num_ops (5)
> +    num_ops (5), m_simplifier (gimple_simplify)
>  {
>    ops[0] = op0;
>    ops[1] = op1;
> @@ -228,7 +240,7 @@ gimple_match_op::gimple_match_op (const gimple_match_cond 
> &cond_in,
>                                 tree op0, tree op1, tree op2, tree op3,
>                                 tree op4, tree op5)
>    : cond (cond_in), code (code_in), type (type_in), reverse (false),
> -    num_ops (6)
> +    num_ops (6), m_simplifier (gimple_simplify)
>  {
>    ops[0] = op0;
>    ops[1] = op1;
> @@ -244,7 +256,7 @@ gimple_match_op::gimple_match_op (const gimple_match_cond 
> &cond_in,
>                                 tree op0, tree op1, tree op2, tree op3,
>                                 tree op4, tree op5, tree op6)
>    : cond (cond_in), code (code_in), type (type_in), reverse (false),
> -    num_ops (7)
> +    num_ops (7), m_simplifier (gimple_simplify)
>  {
>    ops[0] = op0;
>    ops[1] = op1;
> @@ -375,6 +387,14 @@ gimple_match_op::set_op (code_helper code_in, tree 
> type_in,
>    ops[6] = op6;
>  }
>  
> +/* Set SIMPLIFIER to use when regimplifying statements.  */
> +
> +inline void
> +gimple_match_op::set_simplifier (gimple_match_simplify_fn simplifier)
> +{
> +  m_simplifier = simplifier;
> +}
> +
>  /* Set the "operation" to be the single value VALUE, such as a constant
>     or SSA_NAME.  */
>  
> diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
> index 
> a95350abccbf4725c8798b3d34e08e0a0e6b5527..45676560693a1d687b6fb05b76c9f2b16eb8c80a
>  100644
> --- a/gcc/tree-ssa-sccvn.cc
> +++ b/gcc/tree-ssa-sccvn.cc
> @@ -79,6 +79,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "ipa-cp.h"
>  #include "ipa-prop.h"
>  #include "target.h"
> +#include "gimple-match.h"
>  
>  /* This algorithm is based on the SCC algorithm presented by Keith
>     Cooper and L. Taylor Simpson in "SCC-Based Value numbering"
> @@ -8532,7 +8533,7 @@ process_bb (rpo_elim &avail, basic_block bb,
>              }
>           tree val = gimple_simplify (cmpcode,
>                                       boolean_type_node, lhs, rhs,
> -                                     NULL, vn_valueize);
> +                                     NULL, vn_valueize, gimple_simplify);
>           /* If the condition didn't simplify see if we have recorded
>              an expression from sofar taken edges.  */
>           if (! val || TREE_CODE (val) != INTEGER_CST)
> diff --git a/gcc/tree-vect-patterns.cc b/gcc/tree-vect-patterns.cc
> index 
> e0fbe25216351c10b7c85b7a53d6cd87957b529e..ab0a5d9c176979f490aaa19008acf281fdaeafa2
>  100644
> --- a/gcc/tree-vect-patterns.cc
> +++ b/gcc/tree-vect-patterns.cc
> @@ -26,10 +26,10 @@ along with GCC; see the file COPYING3.  If not see
>  #include "tree.h"
>  #include "gimple.h"
>  #include "gimple-iterator.h"
> -#include "gimple-fold.h"
>  #include "ssa.h"
>  #include "expmed.h"
>  #include "optabs-tree.h"
> +#include "gimple-fold.h"
>  #include "insn-config.h"
>  #include "recog.h"           /* FIXME: for insn_data */
>  #include "fold-const.h"
> 
> 
> 

-- 
Richard Biener <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Jochen Jaser, Andrew McDonald, Abhinav Puri; (HRB 36809, AG Nuernberg)

Reply via email to