On Mon, 3 Sep 2018, Martin Liška wrote:

> On 09/03/2018 02:54 PM, Martin Liška wrote:
> > On 09/03/2018 02:41 PM, Richard Biener wrote:
> >> On Mon, 3 Sep 2018, Martin Liška wrote:
> >>
> >>> On 04/25/2018 01:42 PM, Richard Biener wrote:
> >>>>
> >>>> The following patch^Whack splits $subject files into three, one
> >>>> for the predicates (due to an implementation detail) and two for
> >>>> the rest - for now into similar LOC size files.
> >>>>
> >>>> I'd like to get help on the makefile changes to make them less
> >>>> verbose, somehow globbing the -[12p] parts.
> >>>>
> >>>> Also you can see the split point is manually chosen which means
> >>>> it will bitrot.  Timings for the stage2 compiles on a x86_64
> >>>> box are
> >>>>
> >>>> gimple-match-p.c   5s
> >>>> generic-match-p.c  3s
> >>>> gimple-match-1.c  85s
> >>>> generic-match-1.c 56s
> >>>> gimple-match-2.c  82s
> >>>> generic-match-2.c 31s
> >>>>
> >>>> the required header files are quite big (and of course everything
> >>>> needs to be exported without the analysis work becoming too cumbersome),
> >>>> it's 3342 LOC for gimple-match-head.h and 1556 LOC for 
> >>>> generic-match-head.h
> >>>>
> >>>> The machine I tested is quite fast so the 80ish second timings are still
> >>>> too slow I guess and thus splitting up into four files for gimple and
> >>>> three files for generic looks better.
> >>>>
> >>>> Note we lose some inlining/cloning capability in the splitting process
> >>>> (I see quite a bit of constprop/isra work being done on the generated 
> >>>> files).  I didn't try to measure the runtime impact though.
> >>>>
> >>>> The patch still needs quite some TLC, it really is a bit hacky but I'd
> >>>> like to get feedback on the approach and I didn't want to spend time
> >>>> on programatically finding optimal split points (so everything is output
> >>>> in the same semi-random order as before).
> >>>>
> >>>> Richard.
> >>>>
> >>>> <insert ChangeLog here>
> >>>>
> >>>> Index: gcc/genmatch.c
> >>>> ===================================================================
> >>>> --- gcc/genmatch.c       (revision 259638)
> >>>> +++ gcc/genmatch.c       (working copy)
> >>>> @@ -1641,7 +1641,7 @@ struct decision_tree
> >>>>    dt_node *root;
> >>>>  
> >>>>    void insert (struct simplify *, unsigned);
> >>>> -  void gen (FILE *f, bool gimple);
> >>>> +  void gen (const char *, FILE *, vec<unsigned long> &, bool gimple);
> >>>>    void print (FILE *f = stderr);
> >>>>  
> >>>>    decision_tree () { root = new dt_node (dt_node::DT_NODE, NULL); }
> >>>> @@ -3608,12 +3608,25 @@ sinfo_hashmap_traits::equal_keys (const
> >>>>    return compare_op (v->s->result, v->s, candidate->s->result, 
> >>>> candidate->s);
> >>>>  }
> >>>>  
> >>>> +/* Write the common header for the GIMPLE/GENERIC IL matching routines. 
> >>>>  */
> >>>> +
> >>>> +static void
> >>>> +write_header (FILE *f, bool gimple)
> >>>> +{
> >>>> +  fprintf (f, "/* Generated automatically by the program `genmatch' 
> >>>> from\n");
> >>>> +  fprintf (f, "   a IL pattern matching and simplification description. 
> >>>>  */\n");
> >>>> +
> >>>> +  /* Include the header instead of writing it awkwardly quoted here.  */
> >>>> +  fprintf (f, "\n#include \"%s-match-head.c\"\n",
> >>>> +           gimple ? "gimple" : "generic");
> >>>> +}
> >>>>  
> >>>>  /* Main entry to generate code for matching GIMPLE IL off the decision
> >>>>     tree.  */
> >>>>  
> >>>>  void
> >>>> -decision_tree::gen (FILE *f, bool gimple)
> >>>> +decision_tree::gen (const char *output, FILE *headerf,
> >>>> +                    vec<unsigned long> &pieces, bool gimple)
> >>>>  {
> >>>>    sinfo_map_t si;
> >>>>  
> >>>> @@ -3624,6 +3637,34 @@ decision_tree::gen (FILE *f, bool gimple
> >>>>             gimple ? "GIMPLE" : "GENERIC", 
> >>>>             root->num_leafs, root->max_level, root->total_size);
> >>>>  
> >>>> +  FILE *f;
> >>>> +  char *outputtem = NULL;
> >>>> +  if (output)
> >>>> +    outputtem = XNEWVEC (char, strlen (output) + strlen ("-1.c") + 1);
> >>>> +
> >>>> +  unsigned do_header = headerf ? 2 : 1;
> >>>> +  unsigned n_per_part = -1U;
> >>>> +  unsigned file_n = output ? 1 : 2;
> >>>> +  do
> >>>> +    {
> >>>> +      unsigned n_fn = 0;
> >>>> +      do_header--;
> >>>> +
> >>>> +      if (do_header)
> >>>> +        f = headerf;
> >>>> +      else if (!output)
> >>>> +        f = stdout;
> >>>> +      else
> >>>> +        {
> >>>> +          sprintf (outputtem, "%s-%d.c", output, file_n++);
> >>>> +          f = fopen (outputtem, "w");
> >>>> +          if (!f)
> >>>> +            {
> >>>> +              perror ("failed to open output file");
> >>>> +              exit(1);
> >>>> +            }
> >>>> +          write_header (f, gimple);
> >>>> +        }
> >>>>    /* First split out the transform part of equal leafs.  */
> >>>>    unsigned rcnt = 0;
> >>>>    unsigned fcnt = 1;
> >>>> @@ -3643,21 +3684,22 @@ decision_tree::gen (FILE *f, bool gimple
> >>>>          }
> >>>>  
> >>>>        /* Generate a split out function with the leaf transform code.  */
> >>>> +      if (do_header || !output)
> >>>>        s->fname = xasprintf ("%s_simplify_%u", gimple ? "gimple" : 
> >>>> "generic",
> >>>>                              fcnt++);
> >>>>        if (gimple)
> >>>> -        fprintf (f, "\nstatic bool\n"
> >>>> +        fprintf (f, "\n%sbool\n"
> >>>>                   "%s (code_helper *res_code, tree *res_ops,\n"
> >>>>                   "                 gimple_seq *seq, tree 
> >>>> (*valueize)(tree) "
> >>>>                   "ATTRIBUTE_UNUSED,\n"
> >>>>                   "                 const tree ARG_UNUSED (type), tree 
> >>>> *ARG_UNUSED "
> >>>>                   "(captures)\n",
> >>>> -                 s->fname);
> >>>> +                 headerf ? "" : "static ", s->fname);
> >>>>        else
> >>>>          {
> >>>> -          fprintf (f, "\nstatic tree\n"
> >>>> +          fprintf (f, "\n%stree\n"
> >>>>                     "%s (location_t ARG_UNUSED (loc), const tree 
> >>>> ARG_UNUSED (type),\n",
> >>>> -                   (*iter).second->fname);
> >>>> +                   headerf ? "" : "static ", (*iter).second->fname);
> >>>>            for (unsigned i = 0;
> >>>>                 i < as_a <expr *>(s->s->s->match)->ops.length (); ++i)
> >>>>              fprintf (f, " tree ARG_UNUSED (op%d),", i);
> >>>> @@ -3674,7 +3716,12 @@ decision_tree::gen (FILE *f, bool gimple
> >>>>              fprintf (f, ", const combined_fn ARG_UNUSED (%s)",
> >>>>                       s->s->s->for_subst_vec[i].first->id);
> >>>>          }
> >>>> -
> >>>> +      n_fn++;
> >>>> +      if (do_header)
> >>>> +        {
> >>>> +          fprintf (f, ");\n");
> >>>> +          continue;
> >>>> +        }
> >>>>        fprintf (f, ")\n{\n");
> >>>>        s->s->gen_1 (f, 2, gimple, s->s->s->result);
> >>>>        if (gimple)
> >>>> @@ -3682,7 +3729,22 @@ decision_tree::gen (FILE *f, bool gimple
> >>>>        else
> >>>>          fprintf (f, "  return NULL_TREE;\n");
> >>>>        fprintf (f, "}\n");
> >>>> +
> >>>> +      if (n_fn == pieces[file_n - 2])
> >>>> +        {
> >>>> +          fclose (f);
> >>>> +          sprintf (outputtem, "%s-%d.c", output, file_n++);
> >>>> +          f = fopen (outputtem, "w");
> >>>> +          if (!f)
> >>>> +            {
> >>>> +              perror ("failed to open output file");
> >>>> +              exit(1);
> >>>> +            }
> >>>> +          write_header (f, gimple);
> >>>> +          n_fn = 0;
> >>>> +        }
> >>>>      }
> >>>> +  if (!do_header)
> >>>>    fprintf (stderr, "removed %u duplicate tails\n", rcnt);
> >>>>  
> >>>>    for (unsigned n = 1; n <= 3; ++n)
> >>>> @@ -3702,20 +3764,26 @@ decision_tree::gen (FILE *f, bool gimple
> >>>>              continue;
> >>>>  
> >>>>            if (gimple)
> >>>> -            fprintf (f, "\nstatic bool\n"
> >>>> +            fprintf (f, "\n%sbool\n"
> >>>>                       "gimple_simplify_%s (code_helper *res_code, tree 
> >>>> *res_ops,\n"
> >>>>                       "                 gimple_seq *seq, tree 
> >>>> (*valueize)(tree) "
> >>>>                       "ATTRIBUTE_UNUSED,\n"
> >>>>                       "                 code_helper ARG_UNUSED (code), 
> >>>> tree "
> >>>>                       "ARG_UNUSED (type)\n",
> >>>> -                     e->operation->id);
> >>>> +                     headerf ? "" : "static ", e->operation->id);
> >>>>            else
> >>>> -            fprintf (f, "\nstatic tree\n"
> >>>> +            fprintf (f, "\n%stree\n"
> >>>>                       "generic_simplify_%s (location_t ARG_UNUSED (loc), 
> >>>> enum "
> >>>>                       "tree_code ARG_UNUSED (code), const tree 
> >>>> ARG_UNUSED (type)",
> >>>> -                     e->operation->id);
> >>>> +                     headerf ? "" : "static ", e->operation->id);
> >>>>            for (unsigned i = 0; i < n; ++i)
> >>>>              fprintf (f, ", tree op%d", i);
> >>>> +          n_fn++;
> >>>> +          if (do_header)
> >>>> +            {
> >>>> +              fprintf (f, ");\n");
> >>>> +              continue;
> >>>> +            }
> >>>>            fprintf (f, ")\n");
> >>>>            fprintf (f, "{\n");
> >>>>            dop->gen_kids (f, 2, gimple);
> >>>> @@ -3724,21 +3792,43 @@ decision_tree::gen (FILE *f, bool gimple
> >>>>            else
> >>>>              fprintf (f, "  return NULL_TREE;\n");
> >>>>            fprintf (f, "}\n");
> >>>> +
> >>>> +      if (n_fn == pieces[file_n - 2])
> >>>> +        {
> >>>> +          fclose (f);
> >>>> +          sprintf (outputtem, "%s-%d.c", output, file_n++);
> >>>> +          f = fopen (outputtem, "w");
> >>>> +          if (!f)
> >>>> +            {
> >>>> +              perror ("failed to open output file");
> >>>> +              exit(1);
> >>>> +            }
> >>>> +          write_header (f, gimple);
> >>>> +          n_fn = 0;
> >>>> +        }
> >>>> +
> >>>>          }
> >>>>  
> >>>>        /* Then generate the main entry with the outermost switch and
> >>>>           tail-calls to the split-out functions.  */
> >>>>        if (gimple)
> >>>> -        fprintf (f, "\nstatic bool\n"
> >>>> +        fprintf (f, "\n%sbool\n"
> >>>>                   "gimple_simplify (code_helper *res_code, tree 
> >>>> *res_ops,\n"
> >>>>                   "                 gimple_seq *seq, tree 
> >>>> (*valueize)(tree),\n"
> >>>> -                 "                 code_helper code, const tree type");
> >>>> +                 "                 code_helper code, const tree type",
> >>>> +                 headerf ? "" : "static ");
> >>>>        else
> >>>>          fprintf (f, "\ntree\n"
> >>>>                   "generic_simplify (location_t loc, enum tree_code 
> >>>> code, "
> >>>>                   "const tree type ATTRIBUTE_UNUSED");
> >>>>        for (unsigned i = 0; i < n; ++i)
> >>>>          fprintf (f, ", tree op%d", i);
> >>>> +      n_fn++;
> >>>> +      if (do_header)
> >>>> +        {
> >>>> +          fprintf (f, ");\n");
> >>>> +          continue;
> >>>> +        }
> >>>>        fprintf (f, ")\n");
> >>>>        fprintf (f, "{\n");
> >>>>  
> >>>> @@ -3786,19 +3876,46 @@ decision_tree::gen (FILE *f, bool gimple
> >>>>        else
> >>>>          fprintf (f, "  return NULL_TREE;\n");
> >>>>        fprintf (f, "}\n");
> >>>> +      if (n_fn == pieces[file_n - 2])
> >>>> +        {
> >>>> +          fclose (f);
> >>>> +          sprintf (outputtem, "%s-%d.c", output, file_n++);
> >>>> +          f = fopen (outputtem, "w");
> >>>> +          if (!f)
> >>>> +            {
> >>>> +              perror ("failed to open output file");
> >>>> +              exit(1);
> >>>> +            }
> >>>> +          write_header (f, gimple);
> >>>> +          n_fn = 0;
> >>>> +        }
> >>>> +    }
> >>>> +
> >>>> +  n_per_part = n_fn / 4 + 1;
> >>>>      }
> >>>> +  while (do_header);
> >>>> +  if (output)
> >>>> +    fclose (f);
> >>>>  }
> >>>>  
> >>>>  /* 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, bool 
> >>>> gimple,
> >>>> +                 bool for_header)
> >>>>  {
> >>>>    fprintf (f, "\nbool\n"
> >>>> -           "%s%s (tree t%s%s)\n"
> >>>> -           "{\n", gimple ? "gimple_" : "tree_", p->id,
> >>>> +           "%s%s (tree t%s%s)",
> >>>> +           gimple ? "gimple_" : "tree_", p->id,
> >>>>             p->nargs > 0 ? ", tree *res_ops" : "",
> >>>>             gimple ? ", tree (*valueize)(tree) ATTRIBUTE_UNUSED" : "");
> >>>> +  if (for_header)
> >>>> +    {
> >>>> +      fprintf (f, ";\n");
> >>>> +      return;
> >>>> +    }
> >>>> +
> >>>> +  fprintf (f, "\n{\n");
> >>>>    /* Conveniently make 'type' available.  */
> >>>>    fprintf_indent (f, 2, "const tree type = TREE_TYPE (t);\n");
> >>>>  
> >>>> @@ -3810,18 +3927,6 @@ write_predicate (FILE *f, predicate_id *
> >>>>             "}\n");
> >>>>  }
> >>>>  
> >>>> -/* Write the common header for the GIMPLE/GENERIC IL matching routines. 
> >>>>  */
> >>>> -
> >>>> -static void
> >>>> -write_header (FILE *f, const char *head)
> >>>> -{
> >>>> -  fprintf (f, "/* Generated automatically by the program `genmatch' 
> >>>> from\n");
> >>>> -  fprintf (f, "   a IL pattern matching and simplification description. 
> >>>>  */\n");
> >>>> -
> >>>> -  /* Include the header instead of writing it awkwardly quoted here.  */
> >>>> -  fprintf (f, "\n#include \"%s\"\n", head);
> >>>> -}
> >>>> -
> >>>>  
> >>>>  
> >>>>  /* AST parsing.  */
> >>>> @@ -4969,6 +5074,9 @@ main (int argc, char **argv)
> >>>>  
> >>>>    bool gimple = true;
> >>>>    char *input = argv[argc-1];
> >>>> +  char *output = NULL;
> >>>> +  char *header = NULL;
> >>>> +  auto_vec<unsigned long> pieces;
> >>>>    for (int i = 1; i < argc - 1; ++i)
> >>>>      {
> >>>>        if (strcmp (argv[i], "--gimple") == 0)
> >>>> @@ -4979,13 +5087,25 @@ main (int argc, char **argv)
> >>>>          verbose = 1;
> >>>>        else if (strcmp (argv[i], "-vv") == 0)
> >>>>          verbose = 2;
> >>>> +      else if (strcmp (argv[i], "-c") == 0)
> >>>> +        {
> >>>> +          char *endp;
> >>>> +          output = argv[++i];
> >>>> +          while (i + 1 < argc - 1
> >>>> +                 && ISDIGIT (argv[i + 1][0]))
> >>>> +            pieces.safe_push (strtoul (argv[++i], &endp, 10));
> >>>> +        }
> >>>> +      else if (strcmp (argv[i], "-h") == 0)
> >>>> +        header = argv[++i];
> >>>>        else
> >>>>          {
> >>>>            fprintf (stderr, "Usage: genmatch "
> >>>> -                   "[--gimple] [--generic] [-v[v]] input\n");
> >>>> +                   "[--gimple] [--generic] [-v[v]] "
> >>>> +                   "[-c output num...] [-h header] input\n");
> >>>>            return 1;
> >>>>          }
> >>>>      }
> >>>> +  pieces.safe_push (-1UL);
> >>>>  
> >>>>    line_table = XCNEW (struct line_maps);
> >>>>    linemap_init (line_table, 0);
> >>>> @@ -5039,10 +5159,32 @@ add_operator (VIEW_CONVERT2, "view_conve
> >>>>    /* Parse ahead!  */
> >>>>    parser p (r);
> >>>>  
> >>>> -  if (gimple)
> >>>> -    write_header (stdout, "gimple-match-head.c");
> >>>> +  FILE *f, *headerf = NULL;
> >>>> +  if (!output)
> >>>> +    f = stdout;
> >>>>    else
> >>>> -    write_header (stdout, "generic-match-head.c");
> >>>> +    {
> >>>> +      char *outputtem = XNEWVEC (char, strlen (output) + strlen 
> >>>> ("-1.c") + 1);
> >>>> +      sprintf (outputtem, "%s-p.c", output);
> >>>> +      f = fopen (outputtem, "w");
> >>>> +      if (!f)
> >>>> +        {
> >>>> +          perror ("failed to open output file");
> >>>> +          exit(1);
> >>>> +        }
> >>>> +    }
> >>>> +  if (header)
> >>>> +    {
> >>>> +      headerf = fopen (header, "w");
> >>>> +      if (!headerf)
> >>>> +        {
> >>>> +          perror ("failed to open output file");
> >>>> +          exit(1);
> >>>> +        }
> >>>> +    }
> >>>> +
> >>>> +  fprintf (f, "#define GENFOO_MAIN_FILE 1\n");
> >>>> +  write_header (f, gimple);
> >>>>  
> >>>>    /* Go over all predicates defined with patterns and perform
> >>>>       lowering and code generation.  */
> >>>> @@ -5062,8 +5204,12 @@ add_operator (VIEW_CONVERT2, "view_conve
> >>>>        if (verbose == 2)
> >>>>          dt.print (stderr);
> >>>>  
> >>>> -      write_predicate (stdout, pred, dt, gimple);
> >>>> +      if (header)
> >>>> +        write_predicate (headerf, pred, dt, gimple, true);
> >>>> +      write_predicate (f, pred, dt, gimple, false);
> >>>>      }
> >>>> +  if (output)
> >>>> +    fclose (f);
> >>>>  
> >>>>    /* Lower the main simplifiers and generate code for them.  */
> >>>>    lower (p.simplifiers, gimple);
> >>>> @@ -5079,7 +5225,10 @@ add_operator (VIEW_CONVERT2, "view_conve
> >>>>    if (verbose == 2)
> >>>>      dt.print (stderr);
> >>>>  
> >>>> -  dt.gen (stdout, gimple);
> >>>> +  dt.gen (output, headerf, pieces, gimple);
> >>>> +
> >>>> +  if (header)
> >>>> +    fclose (headerf);
> >>>>  
> >>>>    /* Finalize.  */
> >>>>    cpp_finish (r, NULL);
> >>>> Index: gcc/gimple-match-head.c
> >>>> ===================================================================
> >>>> --- gcc/gimple-match-head.c      (revision 259638)
> >>>> +++ gcc/gimple-match-head.c      (working copy)
> >>>> @@ -40,21 +40,10 @@ along with GCC; see the file COPYING3.
> >>>>  #include "case-cfn-macros.h"
> >>>>  #include "gimplify.h"
> >>>>  #include "optabs-tree.h"
> >>>> +#include "gimple-match-head.h"
> >>>>  
> >>>>  
> >>>> -/* Forward declarations of the private auto-generated matchers.
> >>>> -   They expect valueized operands in canonical order and do not
> >>>> -   perform simplification of all-constant operands.  */
> >>>> -static bool gimple_simplify (code_helper *, tree *,
> >>>> -                             gimple_seq *, tree (*)(tree),
> >>>> -                             code_helper, tree, tree);
> >>>> -static bool gimple_simplify (code_helper *, tree *,
> >>>> -                             gimple_seq *, tree (*)(tree),
> >>>> -                             code_helper, tree, tree, tree);
> >>>> -static bool gimple_simplify (code_helper *, tree *,
> >>>> -                             gimple_seq *, tree (*)(tree),
> >>>> -                             code_helper, tree, tree, tree, tree);
> >>>> -
> >>>> +#if GENFOO_MAIN_FILE
> >>>>  
> >>>>  /* Return whether T is a constant that we'll dispatch to fold to
> >>>>     evaluate fully constant expressions.  */
> >>>> @@ -772,6 +761,8 @@ gimple_simplify (gimple *stmt,
> >>>>    return false;
> >>>>  }
> >>>>  
> >>>> +#endif
> >>>> +
> >>>>  
> >>>>  /* Helper for the autogenerated code, valueize OP.  */
> >>>>  
> >>>> Index: gcc/generic-match-head.c
> >>>> ===================================================================
> >>>> --- gcc/generic-match-head.c     (revision 259638)
> >>>> +++ gcc/generic-match-head.c     (working copy)
> >>>> @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.
> >>>>  #include "case-cfn-macros.h"
> >>>>  #include "gimplify.h"
> >>>>  #include "optabs-tree.h"
> >>>> +#include "generic-match-head.h"
> >>>>  
> >>>>  
> >>>>  /* Routine to determine if the types T1 and T2 are effectively
> >>>> Index: gcc/Makefile.in
> >>>> ===================================================================
> >>>> --- gcc/Makefile.in      (revision 259638)
> >>>> +++ gcc/Makefile.in      (working copy)
> >>>> @@ -216,8 +216,12 @@ gengtype-lex.o-warn = -Wno-error
> >>>>  libgcov-util.o-warn = -Wno-error
> >>>>  libgcov-driver-tool.o-warn = -Wno-error
> >>>>  libgcov-merge-tool.o-warn = -Wno-error
> >>>> -gimple-match.o-warn = -Wno-unused
> >>>> -generic-match.o-warn = -Wno-unused
> >>>> +gimple-match-p.o-warn = -Wno-unused
> >>>> +gimple-match-1.o-warn = -Wno-unused
> >>>> +gimple-match-2.o-warn = -Wno-unused
> >>>> +generic-match-p.o-warn = -Wno-unused
> >>>> +generic-match-1.o-warn = -Wno-unused
> >>>> +generic-match-2.o-warn = -Wno-unused
> >>>>  dfp.o-warn = -Wno-strict-aliasing
> >>>>  
> >>>>  # All warnings have to be shut off in stage1 if the compiler used then
> >>>> @@ -771,7 +775,7 @@ COMPILERS = @all_compilers@
> >>>>  
> >>>>  # List of things which should already be built whenever we try to use 
> >>>> xgcc
> >>>>  # to compile anything (without linking).
> >>>> -GCC_PASSES=xgcc$(exeext) specs
> >>>> +GCC_PASSES=xgcc$(exeext)
> >>>>  
> >>>>  # Directory to link to, when using the target `maketest'.
> >>>>  DIR = ../gcc
> >>>> @@ -1207,8 +1211,12 @@ C_COMMON_OBJS = c-family/c-common.o c-fa
> >>>>  # will build them sooner, because they are large and otherwise tend to 
> >>>> be
> >>>>  # the last objects to finish building.
> >>>>  OBJS = \
> >>>> -        gimple-match.o \
> >>>> -        generic-match.o \
> >>>> +        gimple-match-p.o \
> >>>> +        generic-match-p.o \
> >>>> +        gimple-match-1.o \
> >>>> +        generic-match-1.o \
> >>>> +        gimple-match-2.o \
> >>>> +        generic-match-2.o \
> >>>>          insn-attrtab.o \
> >>>>          insn-automata.o \
> >>>>          insn-dfatab.o \
> >>>> @@ -1654,7 +1662,9 @@ MOSTLYCLEANFILES = insn-flags.h insn-con
> >>>>   insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \
> >>>>   insn-attr.h insn-attr-common.h insn-attrtab.c insn-dfatab.c \
> >>>>   insn-latencytab.c insn-opinit.c insn-opinit.h insn-preds.c 
> >>>> insn-constants.h \
> >>>> - tm-preds.h tm-constrs.h checksum-options gimple-match.c 
> >>>> generic-match.c \
> >>>> + tm-preds.h tm-constrs.h checksum-options gimple-match-head.h 
> >>>> gimple-match-1.c \
> >>>> + gimple-match-2.c gimple-match-p.c generic-match-head.h 
> >>>> generic-match-1.c \
> >>>> + generic-match-p.c generic-match-2.c \
> >>>>   tree-check.h min-insn-modes.c insn-modes.c insn-modes.h 
> >>>> insn-modes-inline.h \
> >>>>   genrtl.h gt-*.h gtype-*.h gtype-desc.c gtyp-input.list \
> >>>>   case-cfn-macros.h cfn-operators.pd \
> >>>> @@ -1899,7 +1909,7 @@ all.internal: start.encap rest.encap doc
> >>>>  all.cross: native gcc-cross$(exeext) cpp$(exeext) specs \
> >>>>          libgcc-support lang.all.cross doc selftest @GENINSRC@ srcextra
> >>>>  # This is what must be made before installing GCC and converting 
> >>>> libraries.
> >>>> -start.encap: native xgcc$(exeext) cpp$(exeext) specs \
> >>>> +start.encap: native xgcc$(exeext) cpp$(exeext) \
> >>>>          libgcc-support lang.start.encap @GENINSRC@ srcextra
> >>>>  # These can't be made until after GCC can run.
> >>>>  rest.encap: lang.rest.encap
> >>>> @@ -2054,7 +2064,7 @@ checksum-options:
> >>>>  libgcc-support: libgcc.mvars stmp-int-hdrs $(TCONFIG_H) \
> >>>>          $(MACHMODE_H) gcov-iov.h
> >>>>  
> >>>> -libgcc.mvars: config.status Makefile specs xgcc$(exeext)
> >>>> +libgcc.mvars: config.status Makefile xgcc$(exeext)
> >>>>          : > tmp-libgcc.mvars
> >>>>          echo GCC_CFLAGS = '$(GCC_CFLAGS)' >> tmp-libgcc.mvars
> >>>>          echo INHIBIT_LIBC_CFLAGS = '$(INHIBIT_LIBC_CFLAGS)' >> 
> >>>> tmp-libgcc.mvars
> >>>> @@ -2271,8 +2281,9 @@ $(common_out_object_file): $(common_out_
> >>>>  .PRECIOUS: insn-config.h insn-flags.h insn-codes.h insn-constants.h \
> >>>>    insn-emit.c insn-recog.c insn-extract.c insn-output.c insn-peep.c \
> >>>>    insn-attr.h insn-attr-common.h insn-attrtab.c insn-dfatab.c \
> >>>> -  insn-latencytab.c insn-preds.c gimple-match.c generic-match.c \
> >>>> -  insn-target-def.h
> >>>> +  insn-latencytab.c insn-preds.c gimple-match-head.h gimple-match-1.c \
> >>>> +  gimple-match-2.c generic-match-head.h generic-match-1.c 
> >>>> generic-match-2.c \
> >>>> +  gimple-match-p.c generic-match-p.c insn-target-def.h
> >>>>  
> >>>>  # Dependencies for the md file.  The first time through, we just assume
> >>>>  # the md file itself and the generated dependency file (in order to get
> >>>> @@ -2504,18 +2515,36 @@ s-tm-texi: build/genhooks$(build_exeext)
> >>>>            false; \
> >>>>          fi
> >>>>  
> >>>> -gimple-match.c: s-match gimple-match-head.c ; @true
> >>>> -generic-match.c: s-match generic-match-head.c ; @true
> >>>> +gimple-match-p.c: s-match gimple-match-head.c ; @true
> >>>> +gimple-match-1.c: s-match gimple-match-head.c ; @true
> >>>> +gimple-match-2.c: s-match gimple-match-head.c ; @true
> >>>> +generic-match-p.c: s-match generic-match-head.c ; @true
> >>>> +generic-match-1.c: s-match generic-match-head.c ; @true
> >>>> +generic-match-2.c: s-match generic-match-head.c ; @true
> >>>>  
> >>>>  s-match: build/genmatch$(build_exeext) $(srcdir)/match.pd 
> >>>> cfn-operators.pd
> >>>> -        $(RUN_GEN) build/genmatch$(build_exeext) --gimple 
> >>>> $(srcdir)/match.pd \
> >>>> -            > tmp-gimple-match.c
> >>>> -        $(RUN_GEN) build/genmatch$(build_exeext) --generic 
> >>>> $(srcdir)/match.pd \
> >>>> -            > tmp-generic-match.c
> >>>> -        $(SHELL) $(srcdir)/../move-if-change tmp-gimple-match.c \
> >>>> -                                                gimple-match.c
> >>>> -        $(SHELL) $(srcdir)/../move-if-change tmp-generic-match.c \
> >>>> -                                                generic-match.c
> >>>> +        $(RUN_GEN) build/genmatch$(build_exeext) --gimple \
> >>>> +            -h tmp-gimple-match-head.h -c tmp-gimple-match 460 \
> >>>> +            $(srcdir)/match.pd
> >>>> +        $(RUN_GEN) build/genmatch$(build_exeext) --generic \
> >>>> +            -h tmp-generic-match-head.h -c tmp-generic-match 290 \
> >>>> +            $(srcdir)/match.pd
> >>>> +        $(SHELL) $(srcdir)/../move-if-change tmp-gimple-match-head.h \
> >>>> +                                                gimple-match-head.h
> >>>> +        $(SHELL) $(srcdir)/../move-if-change tmp-gimple-match-1.c \
> >>>> +                                                gimple-match-1.c
> >>>> +        $(SHELL) $(srcdir)/../move-if-change tmp-gimple-match-2.c \
> >>>> +                                                gimple-match-2.c
> >>>> +        $(SHELL) $(srcdir)/../move-if-change tmp-gimple-match-p.c \
> >>>> +                                                gimple-match-p.c
> >>>> +        $(SHELL) $(srcdir)/../move-if-change tmp-generic-match-head.h \
> >>>> +                                                generic-match-head.h
> >>>> +        $(SHELL) $(srcdir)/../move-if-change tmp-generic-match-1.c \
> >>>> +                                                generic-match-1.c
> >>>> +        $(SHELL) $(srcdir)/../move-if-change tmp-generic-match-2.c \
> >>>> +                                                generic-match-2.c
> >>>> +        $(SHELL) $(srcdir)/../move-if-change tmp-generic-match-p.c \
> >>>> +                                                generic-match-p.c
> >>>>          $(STAMP) s-match
> >>>>  
> >>>>  GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
> >>>>
> >>>
> >>> Hi.
> >>>
> >>> I took a look at gimple-match.c and what about doing a split in following 
> >>> way:
> >>> - all gimple_simplify_$number going into a separate header file (~12000 
> >>> LOC)
> >>> - all the function can be marked as static inline
> >>> - all other gimple_simplify_$code can be split into arbitrary number of 
> >>> parts
> >>> - we have 287 such functions where each function only calls 
> >>> gimple_simplify_$number and
> >>>   on average there 10 of such calls
> >>> - that would allow to remove most of gimple_simplify_$number functions 
> >>> from the header file
> >>>
> >>> Richi do you think it will be viable?
> >>
> >> That relies on the cgraph code DCEing all unused gimple_simplify_$number
> >> functions from the header fast as they are now effectively duplicated
> >> into all parts, correct?  Also I'm not sure if we actually want to inline
> >> them...  they are split out to get both code size and compile-time
> >> under control.  Unfortunately we have still high max-inline-insns-single
> >> which is used for inline marked functions.
> >>
> >> Eventually doing a "proper" partitioning algorithm is viable, that is,
> >> partition based on gimple_simplify_$code and put gimple_simplify_$number
> >> where they are used.  If they are used across different codes then
> >> merge those partitions.  I guess you'll see that that'll merge the 
> >> biggest _$code parititions :/ (MINUS_EXPR, PLUS_EXPR).
> > 
> > Yes, that should be much better. I'm attaching a 'callgraph' that was done 
> > by grepping.
> > Function starting at the beginning of a line is function definition, with 
> > an indentation
> > one can see calls.
> > 
> > Yes, PLUS and MINUS call ~20 gimple_simplify_$number calls.
> > 
> > Well, generating some simple call graph format for the source file and a 
> > source file
> > annotation of nodes can be input for a partitioning tool that can do the 
> > split.
> > 
> > Issue with the generated files is that one needs to fix the most offenders 
> > (*-match.c, insn-recog.c, insn-emit.c, ..)
> > in order to see some improvement.
> > 
> > Looking at insn-recog.c, maybe similar callgraph-based split can be done 
> > for recog_$number functions?
> > 
> > Martin
> > 
> >>
> >> Richard.
> >>
> > 
> 
> I'm sending SCC components for gimple-match.c. So there are 3 quite big one 
> and rest is small. It's questionable
> whether partitioning based on that will provide desired speed up?

When I experimented split based on # of functions wasn't working well,
only split based on # of lines did.  I'd still expect that eventually
basing the split on the SCC components makes sense if you use say,
the biggest 4 (but measure size in # lines) and merge the rest evenly.

It would be nice if that all would be scriptable instead of coding it
into genmatch.c but that's of course possible as well - just add
some extra "passes" over code-gen as I did in the hac^Wpatch.  You
could use graphds.c routines to compute SCCs for example.  Knowing
# lines beforehand is a bit hard though - code-generating into
a set of character buffers might be possible but I wired everything
to use FILE ... (and no stringstreams in the C library).
And no, please do not convert to C++ streams ;))

Richard.

Reply via email to