public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFH] split {generic,gimple}-match.c files
@ 2018-04-25 11:44 Richard Biener
  2018-04-25 12:26 ` Richard Biener
                   ` (2 more replies)
  0 siblings, 3 replies; 27+ messages in thread
From: Richard Biener @ 2018-04-25 11:44 UTC (permalink / raw)
  To: gcc-patches


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 \

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2018-04-25 11:44 [RFH] split {generic,gimple}-match.c files Richard Biener
@ 2018-04-25 12:26 ` Richard Biener
  2018-04-25 12:46   ` Richard Biener
  2018-04-25 13:16 ` Martin Liška
  2018-09-03 12:27 ` Martin Liška
  2 siblings, 1 reply; 27+ messages in thread
From: Richard Biener @ 2018-04-25 12:26 UTC (permalink / raw)
  To: gcc-patches

On Wed, 25 Apr 2018, 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

Original timings as requested:

gimple-match.c   172s
generic-match.c  95s

Richard.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2018-04-25 12:26 ` Richard Biener
@ 2018-04-25 12:46   ` Richard Biener
  0 siblings, 0 replies; 27+ messages in thread
From: Richard Biener @ 2018-04-25 12:46 UTC (permalink / raw)
  To: gcc-patches

On Wed, 25 Apr 2018, Richard Biener wrote:

> On Wed, 25 Apr 2018, 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
> 
> Original timings as requested:
> 
> gimple-match.c   172s

With -fno-checking this becomes 95s...

Richard.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2018-04-25 11:44 [RFH] split {generic,gimple}-match.c files Richard Biener
  2018-04-25 12:26 ` Richard Biener
@ 2018-04-25 13:16 ` Martin Liška
  2018-09-03 12:27 ` Martin Liška
  2 siblings, 0 replies; 27+ messages in thread
From: Martin Liška @ 2018-04-25 13:16 UTC (permalink / raw)
  To: Richard Biener, gcc-patches

On 04/25/2018 01:42 PM, Richard Biener wrote:

Hi.

Thanks for working on that.

> 
> 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.

That's true, but once we'll have working backtraces back in GCC 9 with LTO,
then enabling LTO bootstrap will fix that.

> 
> 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).

I'm still thinking about an AWK script that will take original file and
make the separation based on LOC. genmatch.c can generate some placeholders
where split is possible + a common header part. That should be easier
to maintain compared to wired partitioning.

What about doing a param that will drive # of partitions? That would require
more smart Makefile and building on a large machine will benefit from that.

Martin

> 
> 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 \
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2018-04-25 11:44 [RFH] split {generic,gimple}-match.c files Richard Biener
  2018-04-25 12:26 ` Richard Biener
  2018-04-25 13:16 ` Martin Liška
@ 2018-09-03 12:27 ` Martin Liška
  2018-09-03 12:41   ` Richard Biener
  2 siblings, 1 reply; 27+ messages in thread
From: Martin Liška @ 2018-09-03 12:27 UTC (permalink / raw)
  To: Richard Biener, gcc-patches

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?

Martin

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2018-09-03 12:27 ` Martin Liška
@ 2018-09-03 12:41   ` Richard Biener
  2018-09-03 12:54     ` Martin Liška
  0 siblings, 1 reply; 27+ messages in thread
From: Richard Biener @ 2018-09-03 12:41 UTC (permalink / raw)
  To: Martin Liška; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 23835 bytes --]

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).

Richard.

-- 
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2018-09-03 12:41   ` Richard Biener
@ 2018-09-03 12:54     ` Martin Liška
  2018-09-03 13:50       ` Martin Liška
  0 siblings, 1 reply; 27+ messages in thread
From: Martin Liška @ 2018-09-03 12:54 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 24471 bytes --]

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.
> 


[-- Attachment #2: gimple-simplify-callgraph.txt --]
[-- Type: text/plain, Size: 91120 bytes --]

gimple_simplify_ABS_EXPR (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_COSF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_COS (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_COSL (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_COS (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_COSHF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_COSH (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_COSHL (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CCOSF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CCOS (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CCOSL (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CCOSHF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CCOSH (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CCOSHL (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CABSF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CABS (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CABSL (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_BIT_NOT_EXPR (gimple_match_op *res_op, gimple_seq *seq,
				    if (gimple_simplify_61 ...
				    if (gimple_simplify_61 ...
				    if (gimple_simplify_167 ...
				    if (gimple_simplify_167 ...
				    if (gimple_simplify_282 ...
					if (gimple_simplify_207 ...
					if (gimple_simplify_302 ...
					  if (gimple_simplify_123 ...
						    if (gimple_simplify_143 ...
						    if (gimple_simplify_143 ...
								    if (gimple_simplify_126 ...
						    if (gimple_simplify_126 ...
								    if (gimple_simplify_144 ...
						    if (gimple_simplify_144 ...
								    if (gimple_simplify_144 ...
						    if (gimple_simplify_144 ...
		    if (gimple_simplify_282 ...
			if (gimple_simplify_207 ...
			if (gimple_simplify_302 ...
			  if (gimple_simplify_123 ...
				    if (gimple_simplify_143 ...
				    if (gimple_simplify_143 ...
						    if (gimple_simplify_24 ...
				    if (gimple_simplify_24 ...
						    if (gimple_simplify_75 ...
				    if (gimple_simplify_75 ...
						    if (gimple_simplify_75 ...
				    if (gimple_simplify_75 ...
		    if (gimple_simplify_247 ...
		    if (gimple_simplify_247 ...
		    if (gimple_simplify_247 ...
		    if (gimple_simplify_247 ...
		    if (gimple_simplify_247 ...
		    if (gimple_simplify_247 ...
		    if (gimple_simplify_247 ...
		    if (gimple_simplify_247 ...
		    if (gimple_simplify_247 ...
		    if (gimple_simplify_247 ...
		    if (gimple_simplify_247 ...
		    if (gimple_simplify_247 ...
		    if (gimple_simplify_247 ...
		    if (gimple_simplify_247 ...
gimple_simplify_NEGATE_EXPR (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_56 ...
			if (gimple_simplify_56 ...
		    if (gimple_simplify_202 ...
		    if (gimple_simplify_202 ...
		    if (gimple_simplify_202 ...
		    if (gimple_simplify_202 ...
gimple_simplify_CONVERT_EXPR (gimple_match_op *res_op, gimple_seq *seq,
					  if (gimple_simplify_29 ...
					  if (gimple_simplify_29 ...
						    if (gimple_simplify_58 ...
				    if (gimple_simplify_236 ...
						    if (gimple_simplify_58 ...
				    if (gimple_simplify_236 ...
gimple_simplify_VIEW_CONVERT_EXPR (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_FLOAT_EXPR (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_FIX_TRUNC_EXPR (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_PAREN_EXPR (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_REALPART_EXPR (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_IMAGPART_EXPR (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CONJ_EXPR (gimple_match_op *res_op, gimple_seq *seq,
				    if (gimple_simplify_286 ...
		    if (gimple_simplify_286 ...
gimple_simplify_CFN_BUILT_IN_BSWAP16 (gimple_match_op *res_op, gimple_seq *seq,
				    if (gimple_simplify_171 ...
				    if (gimple_simplify_174 ...
				    if (gimple_simplify_174 ...
				    if (gimple_simplify_174 ...
				    if (gimple_simplify_174 ...
				    if (gimple_simplify_174 ...
				    if (gimple_simplify_174 ...
		    if (gimple_simplify_195 ...
gimple_simplify_CFN_BUILT_IN_BSWAP32 (gimple_match_op *res_op, gimple_seq *seq,
				    if (gimple_simplify_171 ...
				    if (gimple_simplify_174 ...
				    if (gimple_simplify_174 ...
				    if (gimple_simplify_174 ...
				    if (gimple_simplify_174 ...
				    if (gimple_simplify_174 ...
				    if (gimple_simplify_174 ...
		    if (gimple_simplify_195 ...
gimple_simplify_CFN_BUILT_IN_BSWAP64 (gimple_match_op *res_op, gimple_seq *seq,
				    if (gimple_simplify_171 ...
				    if (gimple_simplify_174 ...
				    if (gimple_simplify_174 ...
				    if (gimple_simplify_174 ...
				    if (gimple_simplify_174 ...
				    if (gimple_simplify_174 ...
				    if (gimple_simplify_174 ...
		    if (gimple_simplify_195 ...
gimple_simplify_CFN_BUILT_IN_LOGF (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_93 ...
gimple_simplify_CFN_BUILT_IN_LOG (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_93 ...
gimple_simplify_CFN_BUILT_IN_LOGL (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_93 ...
gimple_simplify_CFN_LOG (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_93 ...
gimple_simplify_CFN_BUILT_IN_LOG2F (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_93 ...
gimple_simplify_CFN_BUILT_IN_LOG2 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_93 ...
gimple_simplify_CFN_BUILT_IN_LOG2L (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_93 ...
gimple_simplify_CFN_LOG2 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_93 ...
gimple_simplify_CFN_BUILT_IN_LOG10F (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_93 ...
gimple_simplify_CFN_BUILT_IN_LOG10 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_93 ...
gimple_simplify_CFN_BUILT_IN_LOG10L (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_93 ...
gimple_simplify_CFN_LOG10 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_93 ...
gimple_simplify_CFN_BUILT_IN_EXPF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_EXP (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_EXPL (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_EXP (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_EXP2F (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_EXP2 (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_EXP2L (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_EXP2 (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_EXP10F (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_EXP10 (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_EXP10L (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_EXP10 (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_POW10F (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_POW10 (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_POW10L (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_SQRTF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_SQRT (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_SQRTL (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_SQRT (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CBRTF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CBRT (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CBRTL (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_TANF (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_77 ...
gimple_simplify_CFN_BUILT_IN_TAN (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_77 ...
gimple_simplify_CFN_BUILT_IN_TANL (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_77 ...
gimple_simplify_CFN_TAN (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_77 ...
gimple_simplify_CFN_BUILT_IN_TRUNCF (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_TRUNC (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_297 ...
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_TRUNCL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_177 ...
			if (gimple_simplify_297 ...
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_TRUNCF16 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_TRUNCF32 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_TRUNCF64 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_TRUNCF128 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_TRUNCF32X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_TRUNCF64X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_TRUNCF128X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_TRUNC (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_FLOORF (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
      if (gimple_simplify_25 ...
gimple_simplify_CFN_BUILT_IN_FLOOR (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_297 ...
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
      if (gimple_simplify_25 ...
gimple_simplify_CFN_BUILT_IN_FLOORL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_177 ...
			if (gimple_simplify_297 ...
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
      if (gimple_simplify_25 ...
gimple_simplify_CFN_BUILT_IN_FLOORF16 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
      if (gimple_simplify_25 ...
gimple_simplify_CFN_BUILT_IN_FLOORF32 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
      if (gimple_simplify_25 ...
gimple_simplify_CFN_BUILT_IN_FLOORF64 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
      if (gimple_simplify_25 ...
gimple_simplify_CFN_BUILT_IN_FLOORF128 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
      if (gimple_simplify_25 ...
gimple_simplify_CFN_BUILT_IN_FLOORF32X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
      if (gimple_simplify_25 ...
gimple_simplify_CFN_BUILT_IN_FLOORF64X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
      if (gimple_simplify_25 ...
gimple_simplify_CFN_BUILT_IN_FLOORF128X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
      if (gimple_simplify_25 ...
gimple_simplify_CFN_FLOOR (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
      if (gimple_simplify_25 ...
gimple_simplify_CFN_BUILT_IN_CEILF (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_CEIL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_297 ...
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_CEILL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_177 ...
			if (gimple_simplify_297 ...
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_CEILF16 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_CEILF32 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_CEILF64 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_CEILF128 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_CEILF32X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_CEILF64X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_CEILF128X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_CEIL (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_ROUNDF (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_ROUND (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_297 ...
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_ROUNDL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_177 ...
			if (gimple_simplify_297 ...
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_ROUNDF16 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_ROUNDF32 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_ROUNDF64 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_ROUNDF128 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_ROUNDF32X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_ROUNDF64X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_ROUNDF128X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_ROUND (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_NEARBYINTF (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_NEARBYINT (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_297 ...
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_NEARBYINTL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_177 ...
			if (gimple_simplify_297 ...
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_NEARBYINTF16 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_NEARBYINTF32 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_NEARBYINTF64 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_NEARBYINTF128 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_NEARBYINTF32X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_NEARBYINTF64X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_NEARBYINTF128X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_NEARBYINT (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_RINTF (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_RINT (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_297 ...
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_RINTL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_177 ...
			if (gimple_simplify_297 ...
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_RINTF16 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_RINTF32 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_RINTF64 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_RINTF128 (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_RINTF32X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_RINTF64X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_RINTF128X (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_RINT (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_201 ...
      if (gimple_simplify_113 ...
gimple_simplify_CFN_BUILT_IN_CEXPF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CEXP (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CEXPL (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_IFLOORL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_158 ...
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LFLOORL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_158 ...
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LLFLOORL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_158 ...
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_ICEILL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_158 ...
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LCEILL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_158 ...
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LLCEILL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_158 ...
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_IROUNDL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_158 ...
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LROUNDL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_158 ...
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LLROUNDL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_158 ...
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_IRINTL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_158 ...
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LRINTL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_158 ...
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LLRINTL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_158 ...
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_IFLOOR (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LFLOOR (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LLFLOOR (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_ICEIL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LCEIL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LLCEIL (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_IROUND (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LROUND (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LLROUND (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_IRINT (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LRINT (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_LLRINT (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_205 ...
gimple_simplify_CFN_BUILT_IN_IFLOORF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_LFLOORF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_LLFLOORF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_ICEILF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_LCEILF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_LLCEILF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_IROUNDF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_LROUNDF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_LLROUNDF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_IRINTF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_LRINTF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_LLRINTF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CPROJF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CPROJ (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_CPROJL (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_SIGNBITF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_SIGNBIT (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_SIGNBITL (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_POPCOUNT (gimple_match_op *res_op, gimple_seq *seq,
    if (gimple_simplify_214 ...
gimple_simplify_CFN_BUILT_IN_POPCOUNTL (gimple_match_op *res_op, gimple_seq *seq,
    if (gimple_simplify_214 ...
gimple_simplify_CFN_BUILT_IN_POPCOUNTLL (gimple_match_op *res_op, gimple_seq *seq,
    if (gimple_simplify_214 ...
gimple_simplify_CFN_BUILT_IN_POPCOUNTIMAX (gimple_match_op *res_op, gimple_seq *seq,
    if (gimple_simplify_214 ...
gimple_simplify_PLUS_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_249 ...
									    if (gimple_simplify_153 ...
									    if (gimple_simplify_153 ...
									    if (gimple_simplify_153 ...
									    if (gimple_simplify_153 ...
								    if (gimple_simplify_276 ...
								    if (gimple_simplify_276 ...
			  if (gimple_simplify_69 ...
							if (gimple_simplify_203 ...
							if (gimple_simplify_203 ...
      if (gimple_simplify_249 ...
			if (gimple_simplify_203 ...
			if (gimple_simplify_203 ...
			    if (gimple_simplify_69 ...
					    if (gimple_simplify_221 ...
					    if (gimple_simplify_225 ...
								if (gimple_simplify_182 ...
						if (gimple_simplify_182 ...
					    if (gimple_simplify_221 ...
					    if (gimple_simplify_225 ...
										if (gimple_simplify_182 ...
								if (gimple_simplify_182 ...
				    if (gimple_simplify_99 ...
				    if (gimple_simplify_99 ...
		    if (gimple_simplify_99 ...
		    if (gimple_simplify_99 ...
			if (gimple_simplify_159 ...
					if (gimple_simplify_34 ...
					if (gimple_simplify_34 ...
					if (gimple_simplify_130 ...
					if (gimple_simplify_130 ...
			    if (gimple_simplify_267 ...
			if (gimple_simplify_159 ...
					if (gimple_simplify_34 ...
					if (gimple_simplify_34 ...
					if (gimple_simplify_173 ...
					if (gimple_simplify_173 ...
			if (gimple_simplify_42 ...
			if (gimple_simplify_301 ...
				if (gimple_simplify_271 ...
				if (gimple_simplify_271 ...
			if (gimple_simplify_42 ...
					if (gimple_simplify_301 ...
					if (gimple_simplify_44 ...
					if (gimple_simplify_44 ...
					if (gimple_simplify_44 ...
					if (gimple_simplify_44 ...
			if (gimple_simplify_223 ...
			if (gimple_simplify_223 ...
			if (gimple_simplify_79 ...
			if (gimple_simplify_79 ...
						if (gimple_simplify_116 ...
						if (gimple_simplify_116 ...
			    if (gimple_simplify_116 ...
			    if (gimple_simplify_116 ...
					if (gimple_simplify_298 ...
				    if (gimple_simplify_96 ...
				    if (gimple_simplify_96 ...
				    if (gimple_simplify_96 ...
				    if (gimple_simplify_96 ...
gimple_simplify_POINTER_PLUS_EXPR (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_MINUS_EXPR (gimple_match_op *res_op, gimple_seq *seq,
									    if (gimple_simplify_112 ...
									    if (gimple_simplify_112 ...
							    if (gimple_simplify_112 ...
							    if (gimple_simplify_112 ...
							    if (gimple_simplify_112 ...
							    if (gimple_simplify_112 ...
					    if (gimple_simplify_112 ...
					    if (gimple_simplify_112 ...
							    if (gimple_simplify_148 ...
							    if (gimple_simplify_148 ...
							    if (gimple_simplify_148 ...
							    if (gimple_simplify_148 ...
							    if (gimple_simplify_150 ...
							    if (gimple_simplify_150 ...
							    if (gimple_simplify_150 ...
							    if (gimple_simplify_150 ...
							if (gimple_simplify_238 ...
							if (gimple_simplify_238 ...
					if (gimple_simplify_196 ...
					if (gimple_simplify_196 ...
					if (gimple_simplify_238 ...
					if (gimple_simplify_238 ...
			if (gimple_simplify_196 ...
			if (gimple_simplify_196 ...
				    if (gimple_simplify_244 ...
		    if (gimple_simplify_244 ...
			if (gimple_simplify_114 ...
			if (gimple_simplify_114 ...
			if (gimple_simplify_54 ...
			if (gimple_simplify_54 ...
					if (gimple_simplify_184 ...
					if (gimple_simplify_184 ...
			    if (gimple_simplify_267 ...
					if (gimple_simplify_227 ...
							if (gimple_simplify_102 ...
							if (gimple_simplify_102 ...
					if (gimple_simplify_102 ...
					if (gimple_simplify_102 ...
							if (gimple_simplify_5 ...
							if (gimple_simplify_5 ...
			if (gimple_simplify_227 ...
				if (gimple_simplify_271 ...
				if (gimple_simplify_271 ...
					if (gimple_simplify_5 ...
					if (gimple_simplify_5 ...
									if (gimple_simplify_16 ...
									if (gimple_simplify_16 ...
									if (gimple_simplify_16 ...
									if (gimple_simplify_16 ...
					if (gimple_simplify_44 ...
					if (gimple_simplify_44 ...
					if (gimple_simplify_44 ...
					if (gimple_simplify_44 ...
			if (gimple_simplify_223 ...
			if (gimple_simplify_223 ...
			if (gimple_simplify_79 ...
			if (gimple_simplify_79 ...
						if (gimple_simplify_63 ...
			    if (gimple_simplify_63 ...
					if (gimple_simplify_298 ...
gimple_simplify_BIT_IOR_EXPR (gimple_match_op *res_op, gimple_seq *seq,
					    if (gimple_simplify_215 ...
					    if (gimple_simplify_80 ...
									    if (gimple_simplify_153 ...
									    if (gimple_simplify_153 ...
									    if (gimple_simplify_153 ...
									    if (gimple_simplify_153 ...
								    if (gimple_simplify_276 ...
								    if (gimple_simplify_276 ...
			if (gimple_simplify_43 ...
			if (gimple_simplify_43 ...
							    if (gimple_simplify_87 ...
							    if (gimple_simplify_87 ...
							    if (gimple_simplify_87 ...
							    if (gimple_simplify_87 ...
			if (gimple_simplify_43 ...
			if (gimple_simplify_43 ...
							    if (gimple_simplify_175 ...
							    if (gimple_simplify_175 ...
							    if (gimple_simplify_175 ...
							    if (gimple_simplify_175 ...
					if (gimple_simplify_162 ...
					if (gimple_simplify_162 ...
					if (gimple_simplify_162 ...
					if (gimple_simplify_162 ...
							    if (gimple_simplify_66 ...
							    if (gimple_simplify_66 ...
			if (gimple_simplify_203 ...
					    if (gimple_simplify_296 ...
					    if (gimple_simplify_296 ...
					    if (gimple_simplify_296 ...
					    if (gimple_simplify_296 ...
					if (gimple_simplify_232 ...
					if (gimple_simplify_232 ...
			if (gimple_simplify_232 ...
			if (gimple_simplify_232 ...
					    if (gimple_simplify_279 ...
					    if (gimple_simplify_279 ...
							    if (gimple_simplify_163 ...
							    if (gimple_simplify_163 ...
					    if (gimple_simplify_279 ...
					    if (gimple_simplify_279 ...
							if (gimple_simplify_203 ...
							if (gimple_simplify_203 ...
								    if (gimple_simplify_265 ...
						    if (gimple_simplify_265 ...
									if (gimple_simplify_48 ...
									if (gimple_simplify_48 ...
									if (gimple_simplify_48 ...
									if (gimple_simplify_48 ...
							if (gimple_simplify_232 ...
							if (gimple_simplify_232 ...
					if (gimple_simplify_232 ...
					if (gimple_simplify_232 ...
							if (gimple_simplify_250 ...
							if (gimple_simplify_250 ...
					if (gimple_simplify_250 ...
					if (gimple_simplify_250 ...
			if (gimple_simplify_203 ...
					if (gimple_simplify_133 ...
					if (gimple_simplify_133 ...
	if (gimple_simplify_208 ...
					if (gimple_simplify_133 ...
					if (gimple_simplify_133 ...
					if (gimple_simplify_139 ...
					if (gimple_simplify_139 ...
						    if (gimple_simplify_265 ...
				    if (gimple_simplify_265 ...
					if (gimple_simplify_81 ...
					if (gimple_simplify_81 ...
					    if (gimple_simplify_221 ...
					if (gimple_simplify_48 ...
					if (gimple_simplify_48 ...
					if (gimple_simplify_48 ...
					if (gimple_simplify_48 ...
					    if (gimple_simplify_221 ...
					if (gimple_simplify_250 ...
					if (gimple_simplify_250 ...
			if (gimple_simplify_250 ...
			if (gimple_simplify_250 ...
									if (gimple_simplify_206 ...
									if (gimple_simplify_206 ...
									if (gimple_simplify_206 ...
									if (gimple_simplify_206 ...
							if (gimple_simplify_303 ...
							if (gimple_simplify_303 ...
							if (gimple_simplify_303 ...
							if (gimple_simplify_303 ...
				    if (gimple_simplify_60 ...
		    if (gimple_simplify_60 ...
							if (gimple_simplify_124 ...
							if (gimple_simplify_124 ...
							if (gimple_simplify_124 ...
							if (gimple_simplify_124 ...
					if (gimple_simplify_33 ...
					if (gimple_simplify_33 ...
					if (gimple_simplify_33 ...
					if (gimple_simplify_33 ...
			if (gimple_simplify_277 ...
			if (gimple_simplify_277 ...
					if (gimple_simplify_288 ...
							if (gimple_simplify_17 ...
							if (gimple_simplify_17 ...
					if (gimple_simplify_288 ...
							if (gimple_simplify_17 ...
							if (gimple_simplify_17 ...
							if (gimple_simplify_17 ...
							if (gimple_simplify_17 ...
							if (gimple_simplify_17 ...
							if (gimple_simplify_17 ...
			if (gimple_simplify_277 ...
			if (gimple_simplify_277 ...
					if (gimple_simplify_288 ...
					if (gimple_simplify_288 ...
			    if (gimple_simplify_278 ...
				if (gimple_simplify_292 ...
					    if (gimple_simplify_151 ...
					    if (gimple_simplify_151 ...
					    if (gimple_simplify_97 ...
					    if (gimple_simplify_97 ...
					    if (gimple_simplify_65 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					    if (gimple_simplify_65 ...
					    if (gimple_simplify_65 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					    if (gimple_simplify_65 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					    if (gimple_simplify_65 ...
					    if (gimple_simplify_65 ...
					    if (gimple_simplify_65 ...
					    if (gimple_simplify_65 ...
					    if (gimple_simplify_65 ...
					    if (gimple_simplify_65 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					    if (gimple_simplify_65 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					    if (gimple_simplify_65 ...
		if (gimple_simplify_300 ...
		if (gimple_simplify_300 ...
gimple_simplify_BIT_XOR_EXPR (gimple_match_op *res_op, gimple_seq *seq,
									    if (gimple_simplify_153 ...
									    if (gimple_simplify_153 ...
									    if (gimple_simplify_153 ...
									    if (gimple_simplify_153 ...
								    if (gimple_simplify_276 ...
							if (gimple_simplify_160 ...
								    if (gimple_simplify_276 ...
							if (gimple_simplify_160 ...
							if (gimple_simplify_160 ...
							if (gimple_simplify_160 ...
			if (gimple_simplify_203 ...
							if (gimple_simplify_203 ...
							if (gimple_simplify_203 ...
										if (gimple_simplify_182 ...
								if (gimple_simplify_182 ...
							if (gimple_simplify_98 ...
							if (gimple_simplify_98 ...
					if (gimple_simplify_98 ...
					if (gimple_simplify_98 ...
							if (gimple_simplify_98 ...
							if (gimple_simplify_98 ...
					if (gimple_simplify_98 ...
					if (gimple_simplify_98 ...
			if (gimple_simplify_203 ...
					    if (gimple_simplify_217 ...
					    if (gimple_simplify_221 ...
								if (gimple_simplify_182 ...
						if (gimple_simplify_182 ...
					    if (gimple_simplify_217 ...
					    if (gimple_simplify_218 ...
									    if (gimple_simplify_237 ...
									    if (gimple_simplify_237 ...
									    if (gimple_simplify_237 ...
									    if (gimple_simplify_237 ...
					if (gimple_simplify_98 ...
					if (gimple_simplify_98 ...
			if (gimple_simplify_98 ...
			if (gimple_simplify_98 ...
					    if (gimple_simplify_218 ...
					    if (gimple_simplify_221 ...
					if (gimple_simplify_256 ...
					if (gimple_simplify_256 ...
			if (gimple_simplify_256 ...
			if (gimple_simplify_256 ...
					if (gimple_simplify_98 ...
					if (gimple_simplify_98 ...
			if (gimple_simplify_98 ...
			if (gimple_simplify_98 ...
								    if (gimple_simplify_137 ...
						    if (gimple_simplify_137 ...
					  if (gimple_simplify_280 ...
						    if (gimple_simplify_137 ...
				    if (gimple_simplify_137 ...
			  if (gimple_simplify_280 ...
			if (gimple_simplify_251 ...
			if (gimple_simplify_251 ...
					if (gimple_simplify_48 ...
					if (gimple_simplify_48 ...
					if (gimple_simplify_48 ...
					if (gimple_simplify_48 ...
			if (gimple_simplify_251 ...
			if (gimple_simplify_251 ...
									if (gimple_simplify_48 ...
									if (gimple_simplify_48 ...
									if (gimple_simplify_48 ...
									if (gimple_simplify_48 ...
							if (gimple_simplify_256 ...
							if (gimple_simplify_256 ...
					if (gimple_simplify_256 ...
					if (gimple_simplify_256 ...
							if (gimple_simplify_256 ...
							if (gimple_simplify_256 ...
					if (gimple_simplify_256 ...
					if (gimple_simplify_256 ...
					if (gimple_simplify_256 ...
					if (gimple_simplify_256 ...
			if (gimple_simplify_256 ...
			if (gimple_simplify_256 ...
									if (gimple_simplify_2 ...
									if (gimple_simplify_2 ...
									if (gimple_simplify_2 ...
									if (gimple_simplify_2 ...
							if (gimple_simplify_2 ...
							if (gimple_simplify_2 ...
							if (gimple_simplify_2 ...
							if (gimple_simplify_2 ...
				    if (gimple_simplify_60 ...
		    if (gimple_simplify_60 ...
							if (gimple_simplify_2 ...
							if (gimple_simplify_2 ...
							if (gimple_simplify_2 ...
							if (gimple_simplify_2 ...
					if (gimple_simplify_2 ...
					if (gimple_simplify_2 ...
					if (gimple_simplify_2 ...
					if (gimple_simplify_2 ...
			    if (gimple_simplify_278 ...
		if (gimple_simplify_300 ...
			if (gimple_simplify_19 ...
		if (gimple_simplify_300 ...
			  if (gimple_simplify_19 ...
				if (gimple_simplify_292 ...
			if (gimple_simplify_200 ...
			if (gimple_simplify_200 ...
			if (gimple_simplify_200 ...
			if (gimple_simplify_200 ...
			if (gimple_simplify_200 ...
			if (gimple_simplify_200 ...
			if (gimple_simplify_200 ...
			if (gimple_simplify_200 ...
			if (gimple_simplify_200 ...
			if (gimple_simplify_200 ...
			if (gimple_simplify_200 ...
			if (gimple_simplify_200 ...
			if (gimple_simplify_200 ...
			if (gimple_simplify_200 ...
gimple_simplify_POINTER_DIFF_EXPR (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_MULT_EXPR (gimple_match_op *res_op, gimple_seq *seq,
			    if (gimple_simplify_111 ...
			    if (gimple_simplify_111 ...
			    if (gimple_simplify_111 ...
			    if (gimple_simplify_111 ...
			    if (gimple_simplify_111 ...
			    if (gimple_simplify_111 ...
			    if (gimple_simplify_111 ...
			    if (gimple_simplify_111 ...
			    if (gimple_simplify_111 ...
			    if (gimple_simplify_111 ...
			    if (gimple_simplify_111 ...
			    if (gimple_simplify_92 ...
					    if (gimple_simplify_243 ...
			    if (gimple_simplify_92 ...
					    if (gimple_simplify_243 ...
			    if (gimple_simplify_92 ...
					    if (gimple_simplify_243 ...
			    if (gimple_simplify_92 ...
					    if (gimple_simplify_243 ...
			    if (gimple_simplify_92 ...
					    if (gimple_simplify_243 ...
			    if (gimple_simplify_92 ...
					    if (gimple_simplify_243 ...
			    if (gimple_simplify_92 ...
					    if (gimple_simplify_243 ...
			    if (gimple_simplify_92 ...
					    if (gimple_simplify_243 ...
			    if (gimple_simplify_92 ...
					    if (gimple_simplify_243 ...
			    if (gimple_simplify_92 ...
					    if (gimple_simplify_243 ...
			    if (gimple_simplify_92 ...
					    if (gimple_simplify_243 ...
					    if (gimple_simplify_181 ...
					    if (gimple_simplify_181 ...
					    if (gimple_simplify_181 ...
					    if (gimple_simplify_181 ...
					    if (gimple_simplify_181 ...
					    if (gimple_simplify_181 ...
					    if (gimple_simplify_181 ...
					    if (gimple_simplify_181 ...
					    if (gimple_simplify_181 ...
					    if (gimple_simplify_181 ...
					    if (gimple_simplify_181 ...
      if (gimple_simplify_27 ...
			if (gimple_simplify_128 ...
			if (gimple_simplify_128 ...
			if (gimple_simplify_128 ...
			if (gimple_simplify_128 ...
			if (gimple_simplify_128 ...
			if (gimple_simplify_128 ...
			if (gimple_simplify_128 ...
			if (gimple_simplify_128 ...
			if (gimple_simplify_128 ...
			if (gimple_simplify_128 ...
			if (gimple_simplify_128 ...
					if (gimple_simplify_273 ...
					if (gimple_simplify_273 ...
							if (gimple_simplify_240 ...
				      if (gimple_simplify_240 ...
				    if (gimple_simplify_20 ...
				    if (gimple_simplify_20 ...
				    if (gimple_simplify_20 ...
				    if (gimple_simplify_20 ...
							if (gimple_simplify_141 ...
					if (gimple_simplify_141 ...
						      if (gimple_simplify_240 ...
				      if (gimple_simplify_240 ...
			if (gimple_simplify_273 ...
			if (gimple_simplify_273 ...
					if (gimple_simplify_240 ...
		      if (gimple_simplify_240 ...
					if (gimple_simplify_141 ...
			if (gimple_simplify_141 ...
				      if (gimple_simplify_240 ...
		      if (gimple_simplify_240 ...
			  if (gimple_simplify_35 ...
			  if (gimple_simplify_35 ...
			if (gimple_simplify_129 ...
			if (gimple_simplify_129 ...
			if (gimple_simplify_129 ...
			if (gimple_simplify_129 ...
			if (gimple_simplify_129 ...
			if (gimple_simplify_129 ...
			if (gimple_simplify_129 ...
			if (gimple_simplify_129 ...
			if (gimple_simplify_129 ...
			if (gimple_simplify_129 ...
			if (gimple_simplify_129 ...
			      if (gimple_simplify_26 ...
			      if (gimple_simplify_26 ...
			      if (gimple_simplify_26 ...
			      if (gimple_simplify_26 ...
					if (gimple_simplify_145 ...
					if (gimple_simplify_145 ...
					if (gimple_simplify_145 ...
					if (gimple_simplify_145 ...
					if (gimple_simplify_145 ...
					if (gimple_simplify_145 ...
					if (gimple_simplify_145 ...
					if (gimple_simplify_145 ...
			      if (gimple_simplify_26 ...
			      if (gimple_simplify_26 ...
			      if (gimple_simplify_26 ...
			      if (gimple_simplify_26 ...
					if (gimple_simplify_262 ...
					if (gimple_simplify_18 ...
					if (gimple_simplify_262 ...
					if (gimple_simplify_18 ...
					if (gimple_simplify_262 ...
					if (gimple_simplify_18 ...
					if (gimple_simplify_262 ...
					if (gimple_simplify_18 ...
gimple_simplify_CFN_BUILT_IN_COPYSIGNF (gimple_match_op *res_op, gimple_seq *seq,
	  if (gimple_simplify_38 ...
	  if (gimple_simplify_260 ...
		    if (gimple_simplify_125 ...
	if (gimple_simplify_136 ...
	if (gimple_simplify_49 ...
gimple_simplify_CFN_BUILT_IN_COPYSIGN (gimple_match_op *res_op, gimple_seq *seq,
	  if (gimple_simplify_38 ...
	  if (gimple_simplify_260 ...
		    if (gimple_simplify_125 ...
	if (gimple_simplify_136 ...
	if (gimple_simplify_49 ...
gimple_simplify_CFN_BUILT_IN_COPYSIGNL (gimple_match_op *res_op, gimple_seq *seq,
	  if (gimple_simplify_38 ...
	  if (gimple_simplify_260 ...
		    if (gimple_simplify_125 ...
	if (gimple_simplify_136 ...
	if (gimple_simplify_49 ...
gimple_simplify_CFN_BUILT_IN_COPYSIGNF16 (gimple_match_op *res_op, gimple_seq *seq,
	  if (gimple_simplify_38 ...
	  if (gimple_simplify_260 ...
		    if (gimple_simplify_125 ...
	if (gimple_simplify_136 ...
	if (gimple_simplify_49 ...
gimple_simplify_CFN_BUILT_IN_COPYSIGNF32 (gimple_match_op *res_op, gimple_seq *seq,
	  if (gimple_simplify_38 ...
	  if (gimple_simplify_260 ...
		    if (gimple_simplify_125 ...
	if (gimple_simplify_136 ...
	if (gimple_simplify_49 ...
gimple_simplify_CFN_BUILT_IN_COPYSIGNF64 (gimple_match_op *res_op, gimple_seq *seq,
	  if (gimple_simplify_38 ...
	  if (gimple_simplify_260 ...
		    if (gimple_simplify_125 ...
	if (gimple_simplify_136 ...
	if (gimple_simplify_49 ...
gimple_simplify_CFN_BUILT_IN_COPYSIGNF128 (gimple_match_op *res_op, gimple_seq *seq,
	  if (gimple_simplify_38 ...
	  if (gimple_simplify_260 ...
		    if (gimple_simplify_125 ...
	if (gimple_simplify_136 ...
	if (gimple_simplify_49 ...
gimple_simplify_CFN_BUILT_IN_COPYSIGNF32X (gimple_match_op *res_op, gimple_seq *seq,
	  if (gimple_simplify_38 ...
	  if (gimple_simplify_260 ...
		    if (gimple_simplify_125 ...
	if (gimple_simplify_136 ...
	if (gimple_simplify_49 ...
gimple_simplify_CFN_BUILT_IN_COPYSIGNF64X (gimple_match_op *res_op, gimple_seq *seq,
	  if (gimple_simplify_38 ...
	  if (gimple_simplify_260 ...
		    if (gimple_simplify_125 ...
	if (gimple_simplify_136 ...
	if (gimple_simplify_49 ...
gimple_simplify_CFN_BUILT_IN_COPYSIGNF128X (gimple_match_op *res_op, gimple_seq *seq,
	  if (gimple_simplify_38 ...
	  if (gimple_simplify_260 ...
		    if (gimple_simplify_125 ...
	if (gimple_simplify_136 ...
	if (gimple_simplify_49 ...
gimple_simplify_CFN_COPYSIGN (gimple_match_op *res_op, gimple_seq *seq,
	  if (gimple_simplify_38 ...
	  if (gimple_simplify_260 ...
		    if (gimple_simplify_125 ...
	if (gimple_simplify_136 ...
	if (gimple_simplify_49 ...
gimple_simplify_TRUNC_DIV_EXPR (gimple_match_op *res_op, gimple_seq *seq,
      if (gimple_simplify_27 ...
	if (gimple_simplify_294 ...
	if (gimple_simplify_192 ...
	if (gimple_simplify_222 ...
			if (gimple_simplify_72 ...
			if (gimple_simplify_72 ...
			if (gimple_simplify_132 ...
			if (gimple_simplify_132 ...
				if (gimple_simplify_155 ...
						if (gimple_simplify_189 ...
				if (gimple_simplify_189 ...
			if (gimple_simplify_264 ...
			if (gimple_simplify_264 ...
gimple_simplify_CEIL_DIV_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_27 ...
	if (gimple_simplify_294 ...
	if (gimple_simplify_192 ...
	if (gimple_simplify_222 ...
			if (gimple_simplify_72 ...
			if (gimple_simplify_72 ...
			if (gimple_simplify_132 ...
			if (gimple_simplify_132 ...
						if (gimple_simplify_189 ...
				if (gimple_simplify_189 ...
			if (gimple_simplify_264 ...
			if (gimple_simplify_264 ...
gimple_simplify_FLOOR_DIV_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_27 ...
	if (gimple_simplify_294 ...
	if (gimple_simplify_192 ...
	if (gimple_simplify_222 ...
			if (gimple_simplify_72 ...
			if (gimple_simplify_72 ...
			if (gimple_simplify_132 ...
			if (gimple_simplify_132 ...
						if (gimple_simplify_189 ...
				if (gimple_simplify_189 ...
			if (gimple_simplify_264 ...
			if (gimple_simplify_264 ...
gimple_simplify_ROUND_DIV_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_27 ...
	if (gimple_simplify_294 ...
	if (gimple_simplify_192 ...
	if (gimple_simplify_222 ...
			if (gimple_simplify_72 ...
			if (gimple_simplify_72 ...
			if (gimple_simplify_132 ...
			if (gimple_simplify_132 ...
						if (gimple_simplify_189 ...
				if (gimple_simplify_189 ...
			if (gimple_simplify_264 ...
			if (gimple_simplify_264 ...
gimple_simplify_EXACT_DIV_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_27 ...
	if (gimple_simplify_294 ...
	if (gimple_simplify_192 ...
	if (gimple_simplify_222 ...
			if (gimple_simplify_72 ...
			if (gimple_simplify_72 ...
			if (gimple_simplify_132 ...
			if (gimple_simplify_132 ...
				if (gimple_simplify_155 ...
						if (gimple_simplify_189 ...
				if (gimple_simplify_189 ...
			if (gimple_simplify_264 ...
			if (gimple_simplify_264 ...
gimple_simplify_RDIV_EXPR (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_285 ...
			if (gimple_simplify_285 ...
							if (gimple_simplify_287 ...
							if (gimple_simplify_287 ...
			if (gimple_simplify_287 ...
			if (gimple_simplify_287 ...
					if (gimple_simplify_164 ...
					if (gimple_simplify_4 ...
					if (gimple_simplify_164 ...
					if (gimple_simplify_4 ...
					if (gimple_simplify_164 ...
					if (gimple_simplify_4 ...
					if (gimple_simplify_164 ...
					if (gimple_simplify_4 ...
					if (gimple_simplify_219 ...
					if (gimple_simplify_219 ...
					if (gimple_simplify_219 ...
					if (gimple_simplify_219 ...
					if (gimple_simplify_212 ...
					if (gimple_simplify_212 ...
					if (gimple_simplify_212 ...
					if (gimple_simplify_212 ...
			      if (gimple_simplify_21 ...
			      if (gimple_simplify_21 ...
			      if (gimple_simplify_21 ...
			      if (gimple_simplify_21 ...
		    if (gimple_simplify_255 ...
		    if (gimple_simplify_255 ...
		    if (gimple_simplify_255 ...
		    if (gimple_simplify_255 ...
gimple_simplify_CEIL_MOD_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_213 ...
	if (gimple_simplify_91 ...
	if (gimple_simplify_76 ...
	if (gimple_simplify_194 ...
			if (gimple_simplify_290 ...
				if (gimple_simplify_57 ...
gimple_simplify_FLOOR_MOD_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_213 ...
	if (gimple_simplify_91 ...
	if (gimple_simplify_76 ...
	if (gimple_simplify_194 ...
			if (gimple_simplify_290 ...
				if (gimple_simplify_57 ...
			  if (gimple_simplify_84 ...
	if (gimple_simplify_9 ...
gimple_simplify_ROUND_MOD_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_213 ...
	if (gimple_simplify_91 ...
	if (gimple_simplify_76 ...
	if (gimple_simplify_194 ...
			if (gimple_simplify_290 ...
				if (gimple_simplify_57 ...
gimple_simplify_TRUNC_MOD_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_213 ...
	if (gimple_simplify_91 ...
	if (gimple_simplify_76 ...
	if (gimple_simplify_194 ...
			if (gimple_simplify_290 ...
				if (gimple_simplify_57 ...
				    if (gimple_simplify_131 ...
			if (gimple_simplify_84 ...
		    if (gimple_simplify_131 ...
	if (gimple_simplify_9 ...
gimple_simplify_CFN_BUILT_IN_POWF (gimple_match_op *res_op, gimple_seq *seq,
			  if (gimple_simplify_70 ...
	  if (gimple_simplify_40 ...
      if (gimple_simplify_45 ...
gimple_simplify_CFN_BUILT_IN_POW (gimple_match_op *res_op, gimple_seq *seq,
			  if (gimple_simplify_70 ...
	  if (gimple_simplify_40 ...
      if (gimple_simplify_45 ...
gimple_simplify_CFN_BUILT_IN_POWL (gimple_match_op *res_op, gimple_seq *seq,
			  if (gimple_simplify_70 ...
	  if (gimple_simplify_40 ...
      if (gimple_simplify_45 ...
gimple_simplify_CFN_POW (gimple_match_op *res_op, gimple_seq *seq,
			  if (gimple_simplify_70 ...
	  if (gimple_simplify_40 ...
      if (gimple_simplify_45 ...
gimple_simplify_CFN_BUILT_IN_POWIF (gimple_match_op *res_op, gimple_seq *seq,
      if (gimple_simplify_108 ...
gimple_simplify_CFN_BUILT_IN_POWI (gimple_match_op *res_op, gimple_seq *seq,
      if (gimple_simplify_108 ...
gimple_simplify_CFN_BUILT_IN_POWIL (gimple_match_op *res_op, gimple_seq *seq,
      if (gimple_simplify_108 ...
gimple_simplify_CFN_BUILT_IN_HYPOTF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_HYPOT (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_HYPOTL (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_LSHIFT_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_22 ...
	if (gimple_simplify_179 ...
		    if (gimple_simplify_101 ...
	    if (gimple_simplify_59 ...
	  if (gimple_simplify_170 ...
				if (gimple_simplify_73 ...
						if (gimple_simplify_190 ...
						if (gimple_simplify_190 ...
						if (gimple_simplify_190 ...
				if (gimple_simplify_115 ...
				if (gimple_simplify_115 ...
				if (gimple_simplify_115 ...
gimple_simplify_BIT_AND_EXPR (gimple_match_op *res_op, gimple_seq *seq,
							if (gimple_simplify_242 ...
							if (gimple_simplify_242 ...
			if (gimple_simplify_242 ...
			if (gimple_simplify_242 ...
						if (gimple_simplify_67 ...
						if (gimple_simplify_67 ...
						if (gimple_simplify_67 ...
						if (gimple_simplify_281 ...
						if (gimple_simplify_281 ...
						if (gimple_simplify_281 ...
			  if (gimple_simplify_185 ...
					    if (gimple_simplify_215 ...
					    if (gimple_simplify_80 ...
							    if (gimple_simplify_53 ...
							    if (gimple_simplify_53 ...
							    if (gimple_simplify_53 ...
							    if (gimple_simplify_53 ...
					if (gimple_simplify_133 ...
					if (gimple_simplify_133 ...
						if (gimple_simplify_67 ...
						if (gimple_simplify_67 ...
						if (gimple_simplify_67 ...
						if (gimple_simplify_281 ...
						if (gimple_simplify_281 ...
						if (gimple_simplify_281 ...
			  if (gimple_simplify_185 ...
						if (gimple_simplify_105 ...
						if (gimple_simplify_105 ...
						if (gimple_simplify_105 ...
	if (gimple_simplify_208 ...
					if (gimple_simplify_133 ...
					if (gimple_simplify_133 ...
					if (gimple_simplify_81 ...
					if (gimple_simplify_81 ...
							    if (gimple_simplify_233 ...
							    if (gimple_simplify_109 ...
							    if (gimple_simplify_109 ...
							    if (gimple_simplify_109 ...
							    if (gimple_simplify_109 ...
									    if (gimple_simplify_235 ...
									    if (gimple_simplify_235 ...
									    if (gimple_simplify_235 ...
									    if (gimple_simplify_235 ...
					if (gimple_simplify_139 ...
					if (gimple_simplify_139 ...
							    if (gimple_simplify_233 ...
						    if (gimple_simplify_265 ...
				    if (gimple_simplify_265 ...
							    if (gimple_simplify_109 ...
							    if (gimple_simplify_109 ...
							    if (gimple_simplify_109 ...
							    if (gimple_simplify_109 ...
			if (gimple_simplify_251 ...
			if (gimple_simplify_251 ...
								    if (gimple_simplify_265 ...
						    if (gimple_simplify_265 ...
			if (gimple_simplify_251 ...
			if (gimple_simplify_251 ...
									if (gimple_simplify_48 ...
									if (gimple_simplify_48 ...
									if (gimple_simplify_48 ...
									if (gimple_simplify_48 ...
							if (gimple_simplify_232 ...
							if (gimple_simplify_232 ...
					if (gimple_simplify_232 ...
					if (gimple_simplify_232 ...
							if (gimple_simplify_250 ...
							if (gimple_simplify_250 ...
					if (gimple_simplify_250 ...
					if (gimple_simplify_250 ...
					if (gimple_simplify_48 ...
					if (gimple_simplify_48 ...
					if (gimple_simplify_48 ...
					if (gimple_simplify_48 ...
					if (gimple_simplify_250 ...
					if (gimple_simplify_250 ...
					if (gimple_simplify_232 ...
					if (gimple_simplify_232 ...
							if (gimple_simplify_124 ...
							if (gimple_simplify_124 ...
							if (gimple_simplify_124 ...
							if (gimple_simplify_124 ...
			if (gimple_simplify_232 ...
			if (gimple_simplify_232 ...
					if (gimple_simplify_33 ...
					if (gimple_simplify_33 ...
					if (gimple_simplify_33 ...
					if (gimple_simplify_33 ...
			if (gimple_simplify_250 ...
			if (gimple_simplify_250 ...
									if (gimple_simplify_206 ...
									if (gimple_simplify_206 ...
									if (gimple_simplify_206 ...
									if (gimple_simplify_206 ...
							if (gimple_simplify_303 ...
							if (gimple_simplify_303 ...
							if (gimple_simplify_303 ...
							if (gimple_simplify_303 ...
				    if (gimple_simplify_60 ...
		    if (gimple_simplify_60 ...
			if (gimple_simplify_277 ...
			if (gimple_simplify_277 ...
					if (gimple_simplify_288 ...
					if (gimple_simplify_288 ...
			if (gimple_simplify_277 ...
			if (gimple_simplify_277 ...
					if (gimple_simplify_288 ...
					if (gimple_simplify_288 ...
			    if (gimple_simplify_278 ...
	      if (gimple_simplify_86 ...
			  if (gimple_simplify_30 ...
								if (gimple_simplify_83 ...
						if (gimple_simplify_241 ...
								if (gimple_simplify_83 ...
						if (gimple_simplify_241 ...
	    if (gimple_simplify_86 ...
	  if (gimple_simplify_30 ...
						if (gimple_simplify_156 ...
				if (gimple_simplify_8 ...
						if (gimple_simplify_156 ...
				if (gimple_simplify_8 ...
					    if (gimple_simplify_211 ...
					    if (gimple_simplify_211 ...
					    if (gimple_simplify_226 ...
					    if (gimple_simplify_226 ...
					    if (gimple_simplify_228 ...
					    if (gimple_simplify_228 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					    if (gimple_simplify_228 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					    if (gimple_simplify_228 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					    if (gimple_simplify_228 ...
					    if (gimple_simplify_228 ...
					    if (gimple_simplify_228 ...
					    if (gimple_simplify_228 ...
					    if (gimple_simplify_228 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					    if (gimple_simplify_228 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
					    if (gimple_simplify_228 ...
					    if (gimple_simplify_228 ...
					if (gimple_simplify_85 ...
					if (gimple_simplify_85 ...
							  if (gimple_simplify_62 ...
							  if (gimple_simplify_62 ...
gimple_simplify_LT_EXPR (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_52 ...
					if (gimple_simplify_37 ...
					if (gimple_simplify_37 ...
					if (gimple_simplify_37 ...
					if (gimple_simplify_37 ...
					      if (gimple_simplify_216 ...
				if (gimple_simplify_39 ...
					if (gimple_simplify_154 ...
					if (gimple_simplify_154 ...
					if (gimple_simplify_154 ...
					if (gimple_simplify_154 ...
			if (gimple_simplify_284 ...
			if (gimple_simplify_284 ...
					if (gimple_simplify_157 ...
					if (gimple_simplify_68 ...
					if (gimple_simplify_31 ...
					if (gimple_simplify_47 ...
			if (gimple_simplify_284 ...
			if (gimple_simplify_284 ...
			if (gimple_simplify_188 ...
			if (gimple_simplify_188 ...
				if (gimple_simplify_14 ...
				if (gimple_simplify_14 ...
	  if (gimple_simplify_199 ...
			      if (gimple_simplify_120 ...
	if (gimple_simplify_270 ...
				    if (gimple_simplify_191 ...
		      if (gimple_simplify_210 ...
				    if (gimple_simplify_193 ...
		    if (gimple_simplify_193 ...
	  if (gimple_simplify_23 ...
				if (gimple_simplify_289 ...
				if (gimple_simplify_289 ...
				if (gimple_simplify_263 ...
			  if (gimple_simplify_127 ...
				if (gimple_simplify_10 ...
				    if (gimple_simplify_15 ...
		      if (gimple_simplify_118 ...
				    if (gimple_simplify_110 ...
		    if (gimple_simplify_64 ...
						if (gimple_simplify_138 ...
				if (gimple_simplify_138 ...
			  if (gimple_simplify_121 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				if (gimple_simplify_28 ...
		if (gimple_simplify_28 ...
	  if (gimple_simplify_166 ...
			      if (gimple_simplify_197 ...
				if (gimple_simplify_183 ...
			      if (gimple_simplify_197 ...
			if (gimple_simplify_178 ...
					    if (gimple_simplify_3 ...
					    if (gimple_simplify_95 ...
					    if (gimple_simplify_95 ...
			if (gimple_simplify_135 ...
				if (gimple_simplify_183 ...
gimple_simplify_GE_EXPR (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_52 ...
					if (gimple_simplify_37 ...
					if (gimple_simplify_37 ...
					if (gimple_simplify_37 ...
					if (gimple_simplify_37 ...
					      if (gimple_simplify_216 ...
				if (gimple_simplify_39 ...
					if (gimple_simplify_154 ...
					if (gimple_simplify_154 ...
					if (gimple_simplify_154 ...
					if (gimple_simplify_154 ...
			if (gimple_simplify_284 ...
			if (gimple_simplify_284 ...
					if (gimple_simplify_157 ...
					if (gimple_simplify_68 ...
					if (gimple_simplify_31 ...
					if (gimple_simplify_47 ...
			if (gimple_simplify_284 ...
			if (gimple_simplify_284 ...
			if (gimple_simplify_188 ...
			if (gimple_simplify_188 ...
				if (gimple_simplify_14 ...
				if (gimple_simplify_14 ...
	  if (gimple_simplify_199 ...
			      if (gimple_simplify_120 ...
	if (gimple_simplify_104 ...
				    if (gimple_simplify_191 ...
		      if (gimple_simplify_210 ...
				    if (gimple_simplify_193 ...
		    if (gimple_simplify_193 ...
	  if (gimple_simplify_23 ...
				if (gimple_simplify_289 ...
				if (gimple_simplify_289 ...
				if (gimple_simplify_263 ...
			  if (gimple_simplify_127 ...
				if (gimple_simplify_10 ...
				    if (gimple_simplify_15 ...
		      if (gimple_simplify_118 ...
				    if (gimple_simplify_110 ...
		    if (gimple_simplify_64 ...
						if (gimple_simplify_138 ...
				if (gimple_simplify_138 ...
			  if (gimple_simplify_121 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				if (gimple_simplify_28 ...
		if (gimple_simplify_28 ...
	  if (gimple_simplify_166 ...
			      if (gimple_simplify_197 ...
				if (gimple_simplify_183 ...
			      if (gimple_simplify_197 ...
			if (gimple_simplify_178 ...
					    if (gimple_simplify_3 ...
					    if (gimple_simplify_95 ...
					    if (gimple_simplify_95 ...
			if (gimple_simplify_135 ...
				if (gimple_simplify_183 ...
gimple_simplify_GT_EXPR (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_140 ...
					if (gimple_simplify_37 ...
					if (gimple_simplify_37 ...
					if (gimple_simplify_37 ...
					if (gimple_simplify_37 ...
			      if (gimple_simplify_291 ...
					if (gimple_simplify_154 ...
					if (gimple_simplify_154 ...
					if (gimple_simplify_154 ...
					if (gimple_simplify_154 ...
			if (gimple_simplify_284 ...
			if (gimple_simplify_284 ...
					      if (gimple_simplify_216 ...
				if (gimple_simplify_39 ...
					if (gimple_simplify_157 ...
					if (gimple_simplify_68 ...
					if (gimple_simplify_31 ...
					if (gimple_simplify_47 ...
			if (gimple_simplify_284 ...
			if (gimple_simplify_284 ...
			if (gimple_simplify_188 ...
			if (gimple_simplify_188 ...
				if (gimple_simplify_14 ...
				if (gimple_simplify_14 ...
	  if (gimple_simplify_253 ...
			      if (gimple_simplify_120 ...
	if (gimple_simplify_270 ...
				    if (gimple_simplify_191 ...
		      if (gimple_simplify_210 ...
				    if (gimple_simplify_193 ...
		    if (gimple_simplify_193 ...
	  if (gimple_simplify_23 ...
				if (gimple_simplify_289 ...
				if (gimple_simplify_289 ...
				if (gimple_simplify_263 ...
			  if (gimple_simplify_127 ...
				if (gimple_simplify_10 ...
				if (gimple_simplify_32 ...
				    if (gimple_simplify_15 ...
		      if (gimple_simplify_118 ...
				    if (gimple_simplify_110 ...
		    if (gimple_simplify_64 ...
						if (gimple_simplify_138 ...
				if (gimple_simplify_138 ...
			  if (gimple_simplify_121 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				if (gimple_simplify_28 ...
		if (gimple_simplify_28 ...
	  if (gimple_simplify_166 ...
			      if (gimple_simplify_197 ...
			      if (gimple_simplify_197 ...
			if (gimple_simplify_178 ...
					    if (gimple_simplify_198 ...
					    if (gimple_simplify_134 ...
					    if (gimple_simplify_134 ...
			if (gimple_simplify_78 ...
				if (gimple_simplify_183 ...
				if (gimple_simplify_183 ...
			if (gimple_simplify_258 ...
			if (gimple_simplify_258 ...
			if (gimple_simplify_258 ...
			if (gimple_simplify_258 ...
gimple_simplify_LE_EXPR (gimple_match_op *res_op, gimple_seq *seq,
			if (gimple_simplify_140 ...
					if (gimple_simplify_37 ...
					if (gimple_simplify_37 ...
					if (gimple_simplify_37 ...
					if (gimple_simplify_37 ...
			      if (gimple_simplify_291 ...
					if (gimple_simplify_154 ...
					if (gimple_simplify_154 ...
					if (gimple_simplify_154 ...
					if (gimple_simplify_154 ...
			if (gimple_simplify_284 ...
			if (gimple_simplify_284 ...
					      if (gimple_simplify_216 ...
				if (gimple_simplify_39 ...
					if (gimple_simplify_157 ...
					if (gimple_simplify_68 ...
					if (gimple_simplify_31 ...
					if (gimple_simplify_47 ...
			if (gimple_simplify_284 ...
			if (gimple_simplify_284 ...
			if (gimple_simplify_188 ...
			if (gimple_simplify_188 ...
				if (gimple_simplify_14 ...
				if (gimple_simplify_14 ...
	  if (gimple_simplify_253 ...
			      if (gimple_simplify_120 ...
	if (gimple_simplify_104 ...
				    if (gimple_simplify_191 ...
		      if (gimple_simplify_210 ...
				    if (gimple_simplify_193 ...
		    if (gimple_simplify_193 ...
	  if (gimple_simplify_23 ...
				if (gimple_simplify_289 ...
				if (gimple_simplify_289 ...
				if (gimple_simplify_263 ...
			  if (gimple_simplify_127 ...
				if (gimple_simplify_10 ...
				if (gimple_simplify_32 ...
				    if (gimple_simplify_15 ...
		      if (gimple_simplify_118 ...
				    if (gimple_simplify_110 ...
		    if (gimple_simplify_64 ...
						if (gimple_simplify_138 ...
				if (gimple_simplify_138 ...
			  if (gimple_simplify_121 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				if (gimple_simplify_28 ...
		if (gimple_simplify_28 ...
	  if (gimple_simplify_166 ...
			      if (gimple_simplify_197 ...
			      if (gimple_simplify_197 ...
			if (gimple_simplify_178 ...
					    if (gimple_simplify_198 ...
					    if (gimple_simplify_134 ...
					    if (gimple_simplify_134 ...
			if (gimple_simplify_78 ...
				if (gimple_simplify_183 ...
				if (gimple_simplify_183 ...
			if (gimple_simplify_258 ...
			if (gimple_simplify_258 ...
			if (gimple_simplify_258 ...
			if (gimple_simplify_258 ...
gimple_simplify_EQ_EXPR (gimple_match_op *res_op, gimple_seq *seq,
					if (gimple_simplify_103 ...
					if (gimple_simplify_103 ...
					if (gimple_simplify_103 ...
					if (gimple_simplify_103 ...
					      if (gimple_simplify_94 ...
					      if (gimple_simplify_216 ...
				if (gimple_simplify_39 ...
					if (gimple_simplify_31 ...
					if (gimple_simplify_47 ...
									      if (gimple_simplify_36 ...
							    if (gimple_simplify_6 ...
							    if (gimple_simplify_6 ...
					    if (gimple_simplify_6 ...
					    if (gimple_simplify_6 ...
							    if (gimple_simplify_1 ...
					    if (gimple_simplify_1 ...
									      if (gimple_simplify_36 ...
							      if (gimple_simplify_36 ...
							      if (gimple_simplify_36 ...
					      if (gimple_simplify_36 ...
							      if (gimple_simplify_36 ...
							      if (gimple_simplify_36 ...
					      if (gimple_simplify_36 ...
		if (gimple_simplify_88 ...
							    if (gimple_simplify_6 ...
							    if (gimple_simplify_6 ...
					    if (gimple_simplify_6 ...
					    if (gimple_simplify_6 ...
					    if (gimple_simplify_6 ...
					    if (gimple_simplify_6 ...
			    if (gimple_simplify_6 ...
			    if (gimple_simplify_6 ...
							    if (gimple_simplify_1 ...
					    if (gimple_simplify_1 ...
					    if (gimple_simplify_1 ...
			    if (gimple_simplify_1 ...
		if (gimple_simplify_88 ...
			if (gimple_simplify_188 ...
					    if (gimple_simplify_6 ...
					    if (gimple_simplify_6 ...
			    if (gimple_simplify_6 ...
			    if (gimple_simplify_6 ...
					    if (gimple_simplify_1 ...
			    if (gimple_simplify_1 ...
			if (gimple_simplify_188 ...
							      if (gimple_simplify_36 ...
					      if (gimple_simplify_36 ...
					      if (gimple_simplify_36 ...
			      if (gimple_simplify_36 ...
			if (gimple_simplify_142 ...
							      if (gimple_simplify_36 ...
					      if (gimple_simplify_36 ...
					      if (gimple_simplify_36 ...
			      if (gimple_simplify_36 ...
			if (gimple_simplify_50 ...
			if (gimple_simplify_50 ...
				if (gimple_simplify_186 ...
			if (gimple_simplify_50 ...
			if (gimple_simplify_50 ...
				if (gimple_simplify_55 ...
	      if (gimple_simplify_254 ...
	      if (gimple_simplify_254 ...
			if (gimple_simplify_50 ...
			if (gimple_simplify_50 ...
			if (gimple_simplify_50 ...
			if (gimple_simplify_50 ...
						if (gimple_simplify_41 ...
				if (gimple_simplify_152 ...
			if (gimple_simplify_204 ...
			if (gimple_simplify_146 ...
			      if (gimple_simplify_120 ...
	if (gimple_simplify_104 ...
				    if (gimple_simplify_191 ...
		      if (gimple_simplify_210 ...
				    if (gimple_simplify_193 ...
		    if (gimple_simplify_193 ...
	  if (gimple_simplify_23 ...
				if (gimple_simplify_289 ...
				if (gimple_simplify_289 ...
				if (gimple_simplify_263 ...
			  if (gimple_simplify_127 ...
			  if (gimple_simplify_7 ...
				    if (gimple_simplify_15 ...
		      if (gimple_simplify_118 ...
			if (gimple_simplify_117 ...
				    if (gimple_simplify_110 ...
		    if (gimple_simplify_64 ...
						if (gimple_simplify_230 ...
				if (gimple_simplify_230 ...
			if (gimple_simplify_168 ...
			if (gimple_simplify_169 ...
			if (gimple_simplify_169 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
		if (gimple_simplify_220 ...
			if (gimple_simplify_169 ...
			if (gimple_simplify_169 ...
						if (gimple_simplify_147 ...
						if (gimple_simplify_138 ...
				if (gimple_simplify_138 ...
			    if (gimple_simplify_257 ...
				if (gimple_simplify_147 ...
			    if (gimple_simplify_176 ...
					    if (gimple_simplify_100 ...
			    if (gimple_simplify_12 ...
				if (gimple_simplify_28 ...
		if (gimple_simplify_28 ...
	    if (gimple_simplify_257 ...
    if (gimple_simplify_252 ...
			  if (gimple_simplify_187 ...
				if (gimple_simplify_180 ...
				if (gimple_simplify_180 ...
			if (gimple_simplify_258 ...
			if (gimple_simplify_258 ...
			if (gimple_simplify_258 ...
			if (gimple_simplify_258 ...
gimple_simplify_NE_EXPR (gimple_match_op *res_op, gimple_seq *seq,
					if (gimple_simplify_103 ...
					if (gimple_simplify_103 ...
					if (gimple_simplify_103 ...
					if (gimple_simplify_103 ...
					      if (gimple_simplify_94 ...
					      if (gimple_simplify_216 ...
				if (gimple_simplify_39 ...
					if (gimple_simplify_31 ...
					if (gimple_simplify_47 ...
									      if (gimple_simplify_36 ...
							    if (gimple_simplify_6 ...
							    if (gimple_simplify_6 ...
					    if (gimple_simplify_6 ...
					    if (gimple_simplify_6 ...
							    if (gimple_simplify_1 ...
					    if (gimple_simplify_1 ...
									      if (gimple_simplify_36 ...
							      if (gimple_simplify_36 ...
							      if (gimple_simplify_36 ...
					      if (gimple_simplify_36 ...
							      if (gimple_simplify_36 ...
							      if (gimple_simplify_36 ...
					      if (gimple_simplify_36 ...
		if (gimple_simplify_88 ...
							    if (gimple_simplify_6 ...
							    if (gimple_simplify_6 ...
					    if (gimple_simplify_6 ...
					    if (gimple_simplify_6 ...
					    if (gimple_simplify_6 ...
					    if (gimple_simplify_6 ...
			    if (gimple_simplify_6 ...
			    if (gimple_simplify_6 ...
							    if (gimple_simplify_1 ...
					    if (gimple_simplify_1 ...
					    if (gimple_simplify_1 ...
			    if (gimple_simplify_1 ...
		if (gimple_simplify_88 ...
			if (gimple_simplify_188 ...
					    if (gimple_simplify_6 ...
					    if (gimple_simplify_6 ...
			    if (gimple_simplify_6 ...
			    if (gimple_simplify_6 ...
					    if (gimple_simplify_1 ...
			    if (gimple_simplify_1 ...
			if (gimple_simplify_188 ...
							      if (gimple_simplify_36 ...
					      if (gimple_simplify_36 ...
					      if (gimple_simplify_36 ...
			      if (gimple_simplify_36 ...
			if (gimple_simplify_142 ...
							      if (gimple_simplify_36 ...
					      if (gimple_simplify_36 ...
					      if (gimple_simplify_36 ...
			      if (gimple_simplify_36 ...
			if (gimple_simplify_50 ...
			if (gimple_simplify_50 ...
				if (gimple_simplify_186 ...
			if (gimple_simplify_50 ...
			if (gimple_simplify_50 ...
				if (gimple_simplify_55 ...
	      if (gimple_simplify_254 ...
	      if (gimple_simplify_254 ...
			if (gimple_simplify_50 ...
			if (gimple_simplify_50 ...
			if (gimple_simplify_50 ...
			if (gimple_simplify_50 ...
						if (gimple_simplify_41 ...
				if (gimple_simplify_152 ...
			if (gimple_simplify_204 ...
			if (gimple_simplify_146 ...
			      if (gimple_simplify_120 ...
	if (gimple_simplify_270 ...
				    if (gimple_simplify_191 ...
		      if (gimple_simplify_210 ...
				    if (gimple_simplify_193 ...
		    if (gimple_simplify_193 ...
	  if (gimple_simplify_23 ...
				if (gimple_simplify_289 ...
				if (gimple_simplify_289 ...
				if (gimple_simplify_263 ...
			  if (gimple_simplify_127 ...
			  if (gimple_simplify_7 ...
				    if (gimple_simplify_15 ...
		      if (gimple_simplify_118 ...
			if (gimple_simplify_117 ...
				    if (gimple_simplify_110 ...
		    if (gimple_simplify_64 ...
						if (gimple_simplify_230 ...
				if (gimple_simplify_230 ...
			if (gimple_simplify_168 ...
			if (gimple_simplify_169 ...
			if (gimple_simplify_169 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
				    if (gimple_simplify_293 ...
			  if (gimple_simplify_51 ...
		if (gimple_simplify_220 ...
			if (gimple_simplify_169 ...
			if (gimple_simplify_169 ...
						if (gimple_simplify_147 ...
						if (gimple_simplify_138 ...
				if (gimple_simplify_138 ...
			    if (gimple_simplify_257 ...
				if (gimple_simplify_147 ...
			    if (gimple_simplify_176 ...
					    if (gimple_simplify_100 ...
			    if (gimple_simplify_12 ...
				if (gimple_simplify_28 ...
		if (gimple_simplify_28 ...
	    if (gimple_simplify_257 ...
    if (gimple_simplify_252 ...
			  if (gimple_simplify_187 ...
				if (gimple_simplify_180 ...
				if (gimple_simplify_180 ...
			if (gimple_simplify_258 ...
			if (gimple_simplify_258 ...
			if (gimple_simplify_258 ...
			if (gimple_simplify_258 ...
gimple_simplify_MIN_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
			if (gimple_simplify_11 ...
			if (gimple_simplify_11 ...
			if (gimple_simplify_11 ...
			if (gimple_simplify_11 ...
			if (gimple_simplify_295 ...
			if (gimple_simplify_295 ...
				    if (gimple_simplify_299 ...
gimple_simplify_MAX_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
			if (gimple_simplify_82 ...
			if (gimple_simplify_82 ...
			if (gimple_simplify_82 ...
			if (gimple_simplify_82 ...
			if (gimple_simplify_149 ...
			if (gimple_simplify_149 ...
				    if (gimple_simplify_299 ...
gimple_simplify_CFN_BUILT_IN_FMINF (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_89 ...
gimple_simplify_CFN_BUILT_IN_FMIN (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_89 ...
gimple_simplify_CFN_BUILT_IN_FMINL (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_89 ...
gimple_simplify_CFN_BUILT_IN_FMINF16 (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_89 ...
gimple_simplify_CFN_BUILT_IN_FMINF32 (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_89 ...
gimple_simplify_CFN_BUILT_IN_FMINF64 (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_89 ...
gimple_simplify_CFN_BUILT_IN_FMINF128 (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_89 ...
gimple_simplify_CFN_BUILT_IN_FMINF32X (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_89 ...
gimple_simplify_CFN_BUILT_IN_FMINF64X (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_89 ...
gimple_simplify_CFN_BUILT_IN_FMINF128X (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_89 ...
gimple_simplify_CFN_FMIN (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_89 ...
gimple_simplify_CFN_BUILT_IN_FMAXF (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_248 ...
gimple_simplify_CFN_BUILT_IN_FMAX (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_248 ...
gimple_simplify_CFN_BUILT_IN_FMAXL (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_248 ...
gimple_simplify_CFN_BUILT_IN_FMAXF16 (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_248 ...
gimple_simplify_CFN_BUILT_IN_FMAXF32 (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_248 ...
gimple_simplify_CFN_BUILT_IN_FMAXF64 (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_248 ...
gimple_simplify_CFN_BUILT_IN_FMAXF128 (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_248 ...
gimple_simplify_CFN_BUILT_IN_FMAXF32X (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_248 ...
gimple_simplify_CFN_BUILT_IN_FMAXF64X (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_248 ...
gimple_simplify_CFN_BUILT_IN_FMAXF128X (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_248 ...
gimple_simplify_CFN_FMAX (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_245 ...
	  if (gimple_simplify_246 ...
	  if (gimple_simplify_246 ...
    if (gimple_simplify_248 ...
gimple_simplify_LROTATE_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_107 ...
	if (gimple_simplify_22 ...
	if (gimple_simplify_179 ...
		    if (gimple_simplify_101 ...
	  if (gimple_simplify_170 ...
				if (gimple_simplify_73 ...
gimple_simplify_RROTATE_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_107 ...
	if (gimple_simplify_22 ...
	if (gimple_simplify_179 ...
		    if (gimple_simplify_101 ...
	  if (gimple_simplify_170 ...
				if (gimple_simplify_73 ...
gimple_simplify_RSHIFT_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_22 ...
	if (gimple_simplify_179 ...
		    if (gimple_simplify_101 ...
	    if (gimple_simplify_59 ...
	  if (gimple_simplify_170 ...
				if (gimple_simplify_73 ...
						if (gimple_simplify_190 ...
						if (gimple_simplify_190 ...
						if (gimple_simplify_190 ...
				if (gimple_simplify_115 ...
				if (gimple_simplify_115 ...
				if (gimple_simplify_115 ...
gimple_simplify_COMPLEX_EXPR (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_UNLE_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_90 ...
				    if (gimple_simplify_15 ...
		      if (gimple_simplify_118 ...
	  if (gimple_simplify_172 ...
gimple_simplify_UNGE_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_90 ...
				    if (gimple_simplify_15 ...
		      if (gimple_simplify_118 ...
	  if (gimple_simplify_172 ...
gimple_simplify_UNEQ_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_90 ...
				    if (gimple_simplify_15 ...
		      if (gimple_simplify_118 ...
	  if (gimple_simplify_172 ...
gimple_simplify_UNLT_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_283 ...
				    if (gimple_simplify_15 ...
		      if (gimple_simplify_118 ...
	  if (gimple_simplify_172 ...
gimple_simplify_UNGT_EXPR (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_283 ...
				    if (gimple_simplify_15 ...
		      if (gimple_simplify_118 ...
	  if (gimple_simplify_172 ...
gimple_simplify_LTGT_EXPR (gimple_match_op *res_op, gimple_seq *seq,
				    if (gimple_simplify_15 ...
		      if (gimple_simplify_118 ...
	  if (gimple_simplify_172 ...
gimple_simplify_UNORDERED_EXPR (gimple_match_op *res_op, gimple_seq *seq,
				    if (gimple_simplify_15 ...
		      if (gimple_simplify_118 ...
	  if (gimple_simplify_172 ...
gimple_simplify_ORDERED_EXPR (gimple_match_op *res_op, gimple_seq *seq,
				    if (gimple_simplify_15 ...
		      if (gimple_simplify_118 ...
	  if (gimple_simplify_172 ...
gimple_simplify_CFN_BUILT_IN_LDEXPF (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_46 ...
	if (gimple_simplify_119 ...
gimple_simplify_CFN_BUILT_IN_LDEXP (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_46 ...
	if (gimple_simplify_119 ...
gimple_simplify_CFN_BUILT_IN_LDEXPL (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_46 ...
	if (gimple_simplify_119 ...
gimple_simplify_CFN_LDEXP (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_46 ...
	if (gimple_simplify_119 ...
gimple_simplify_CFN_BUILT_IN_SCALBNF (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_46 ...
	if (gimple_simplify_119 ...
gimple_simplify_CFN_BUILT_IN_SCALBN (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_46 ...
	if (gimple_simplify_119 ...
gimple_simplify_CFN_BUILT_IN_SCALBNL (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_46 ...
	if (gimple_simplify_119 ...
gimple_simplify_CFN_BUILT_IN_SCALBLNF (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_46 ...
	if (gimple_simplify_119 ...
gimple_simplify_CFN_BUILT_IN_SCALBLN (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_46 ...
	if (gimple_simplify_119 ...
gimple_simplify_CFN_BUILT_IN_SCALBLNL (gimple_match_op *res_op, gimple_seq *seq,
	if (gimple_simplify_46 ...
	if (gimple_simplify_119 ...
gimple_simplify_TRUTH_ORIF_EXPR (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_TRUTH_OR_EXPR (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_COND_EXPR (gimple_match_op *res_op, gimple_seq *seq,
								    if (gimple_simplify_13 ...
						    if (gimple_simplify_13 ...
									  if (gimple_simplify_71 ...
									  if (gimple_simplify_71 ...
						    if (gimple_simplify_13 ...
				    if (gimple_simplify_13 ...
							  if (gimple_simplify_71 ...
							  if (gimple_simplify_71 ...
								    if (gimple_simplify_13 ...
						    if (gimple_simplify_13 ...
									  if (gimple_simplify_71 ...
									  if (gimple_simplify_71 ...
						    if (gimple_simplify_13 ...
				    if (gimple_simplify_13 ...
							  if (gimple_simplify_71 ...
							  if (gimple_simplify_71 ...
								    if (gimple_simplify_13 ...
						    if (gimple_simplify_13 ...
									  if (gimple_simplify_71 ...
									  if (gimple_simplify_71 ...
						    if (gimple_simplify_13 ...
				    if (gimple_simplify_13 ...
							  if (gimple_simplify_71 ...
							  if (gimple_simplify_71 ...
								    if (gimple_simplify_13 ...
						    if (gimple_simplify_13 ...
									  if (gimple_simplify_71 ...
									  if (gimple_simplify_71 ...
						    if (gimple_simplify_13 ...
				    if (gimple_simplify_13 ...
							  if (gimple_simplify_71 ...
							  if (gimple_simplify_71 ...
								    if (gimple_simplify_13 ...
						    if (gimple_simplify_13 ...
						    if (gimple_simplify_13 ...
				    if (gimple_simplify_13 ...
								  if (gimple_simplify_13 ...
						  if (gimple_simplify_13 ...
									if (gimple_simplify_71 ...
									if (gimple_simplify_71 ...
						  if (gimple_simplify_13 ...
				  if (gimple_simplify_13 ...
							if (gimple_simplify_71 ...
							if (gimple_simplify_71 ...
								  if (gimple_simplify_13 ...
						  if (gimple_simplify_13 ...
									if (gimple_simplify_71 ...
									if (gimple_simplify_71 ...
						  if (gimple_simplify_13 ...
				  if (gimple_simplify_13 ...
							if (gimple_simplify_71 ...
							if (gimple_simplify_71 ...
								  if (gimple_simplify_13 ...
						  if (gimple_simplify_13 ...
									if (gimple_simplify_71 ...
									if (gimple_simplify_71 ...
						  if (gimple_simplify_13 ...
				  if (gimple_simplify_13 ...
							if (gimple_simplify_71 ...
							if (gimple_simplify_71 ...
								  if (gimple_simplify_13 ...
						  if (gimple_simplify_13 ...
									if (gimple_simplify_71 ...
									if (gimple_simplify_71 ...
						  if (gimple_simplify_13 ...
				  if (gimple_simplify_13 ...
							if (gimple_simplify_71 ...
							if (gimple_simplify_71 ...
								  if (gimple_simplify_13 ...
						  if (gimple_simplify_13 ...
						  if (gimple_simplify_13 ...
				  if (gimple_simplify_13 ...
						      if (gimple_simplify_275 ...
				  if (gimple_simplify_261 ...
						    if (gimple_simplify_275 ...
				if (gimple_simplify_261 ...
gimple_simplify_VEC_COND_EXPR (gimple_match_op *res_op, gimple_seq *seq,
					if (gimple_simplify_161 ...
					if (gimple_simplify_161 ...
					if (gimple_simplify_161 ...
					if (gimple_simplify_161 ...
					if (gimple_simplify_161 ...
					if (gimple_simplify_161 ...
					if (gimple_simplify_161 ...
					if (gimple_simplify_161 ...
					if (gimple_simplify_161 ...
					if (gimple_simplify_161 ...
					if (gimple_simplify_161 ...
		    if (gimple_simplify_161 ...
		    if (gimple_simplify_161 ...
		    if (gimple_simplify_161 ...
		    if (gimple_simplify_161 ...
		    if (gimple_simplify_161 ...
		    if (gimple_simplify_161 ...
		    if (gimple_simplify_161 ...
		    if (gimple_simplify_161 ...
		    if (gimple_simplify_161 ...
		    if (gimple_simplify_161 ...
		    if (gimple_simplify_161 ...
					if (gimple_simplify_269 ...
					if (gimple_simplify_269 ...
					if (gimple_simplify_269 ...
					if (gimple_simplify_269 ...
					if (gimple_simplify_269 ...
					if (gimple_simplify_269 ...
					if (gimple_simplify_269 ...
					if (gimple_simplify_269 ...
					if (gimple_simplify_269 ...
					if (gimple_simplify_269 ...
					if (gimple_simplify_269 ...
		    if (gimple_simplify_269 ...
		    if (gimple_simplify_269 ...
		    if (gimple_simplify_269 ...
		    if (gimple_simplify_269 ...
		    if (gimple_simplify_269 ...
		    if (gimple_simplify_269 ...
		    if (gimple_simplify_269 ...
		    if (gimple_simplify_269 ...
		    if (gimple_simplify_269 ...
		    if (gimple_simplify_269 ...
		    if (gimple_simplify_269 ...
					if (gimple_simplify_122 ...
					if (gimple_simplify_122 ...
					if (gimple_simplify_122 ...
					if (gimple_simplify_122 ...
		    if (gimple_simplify_122 ...
		    if (gimple_simplify_122 ...
		    if (gimple_simplify_122 ...
		    if (gimple_simplify_122 ...
					if (gimple_simplify_266 ...
					if (gimple_simplify_266 ...
					if (gimple_simplify_266 ...
					if (gimple_simplify_266 ...
		    if (gimple_simplify_266 ...
		    if (gimple_simplify_266 ...
		    if (gimple_simplify_266 ...
		    if (gimple_simplify_266 ...
					    if (gimple_simplify_106 ...
					    if (gimple_simplify_106 ...
					    if (gimple_simplify_106 ...
					    if (gimple_simplify_106 ...
					    if (gimple_simplify_106 ...
					    if (gimple_simplify_106 ...
					    if (gimple_simplify_106 ...
					    if (gimple_simplify_106 ...
					    if (gimple_simplify_106 ...
					    if (gimple_simplify_106 ...
					    if (gimple_simplify_106 ...
			if (gimple_simplify_106 ...
			if (gimple_simplify_106 ...
			if (gimple_simplify_106 ...
			if (gimple_simplify_106 ...
			if (gimple_simplify_106 ...
			if (gimple_simplify_106 ...
			if (gimple_simplify_106 ...
			if (gimple_simplify_106 ...
			if (gimple_simplify_106 ...
			if (gimple_simplify_106 ...
			if (gimple_simplify_106 ...
					if (gimple_simplify_209 ...
					if (gimple_simplify_209 ...
					if (gimple_simplify_209 ...
					if (gimple_simplify_209 ...
					if (gimple_simplify_209 ...
					if (gimple_simplify_209 ...
					if (gimple_simplify_209 ...
					if (gimple_simplify_209 ...
					if (gimple_simplify_209 ...
					if (gimple_simplify_209 ...
					if (gimple_simplify_209 ...
		    if (gimple_simplify_209 ...
		    if (gimple_simplify_209 ...
		    if (gimple_simplify_209 ...
		    if (gimple_simplify_209 ...
		    if (gimple_simplify_209 ...
		    if (gimple_simplify_209 ...
		    if (gimple_simplify_209 ...
		    if (gimple_simplify_209 ...
		    if (gimple_simplify_209 ...
		    if (gimple_simplify_209 ...
		    if (gimple_simplify_209 ...
					    if (gimple_simplify_74 ...
					    if (gimple_simplify_74 ...
					    if (gimple_simplify_74 ...
					    if (gimple_simplify_74 ...
			if (gimple_simplify_74 ...
			if (gimple_simplify_74 ...
			if (gimple_simplify_74 ...
			if (gimple_simplify_74 ...
					if (gimple_simplify_165 ...
					if (gimple_simplify_165 ...
					if (gimple_simplify_165 ...
					if (gimple_simplify_165 ...
		    if (gimple_simplify_165 ...
		    if (gimple_simplify_165 ...
		    if (gimple_simplify_165 ...
		    if (gimple_simplify_165 ...
gimple_simplify_BIT_FIELD_REF (gimple_match_op *res_op, gimple_seq *seq,
gimple_simplify_CFN_BUILT_IN_FMAF (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_224 ...
				    if (gimple_simplify_229 ...
		    if (gimple_simplify_224 ...
		    if (gimple_simplify_231 ...
				    if (gimple_simplify_229 ...
gimple_simplify_CFN_BUILT_IN_FMA (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_224 ...
				    if (gimple_simplify_229 ...
		    if (gimple_simplify_224 ...
		    if (gimple_simplify_231 ...
				    if (gimple_simplify_229 ...
gimple_simplify_CFN_BUILT_IN_FMAL (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_224 ...
				    if (gimple_simplify_229 ...
		    if (gimple_simplify_224 ...
		    if (gimple_simplify_231 ...
				    if (gimple_simplify_229 ...
gimple_simplify_CFN_FMA (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_224 ...
				    if (gimple_simplify_229 ...
		    if (gimple_simplify_224 ...
		    if (gimple_simplify_231 ...
				    if (gimple_simplify_229 ...
gimple_simplify_CFN_FMS (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_234 ...
				    if (gimple_simplify_239 ...
		    if (gimple_simplify_234 ...
				    if (gimple_simplify_239 ...
gimple_simplify_CFN_FNMA (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_259 ...
				    if (gimple_simplify_268 ...
		    if (gimple_simplify_259 ...
				    if (gimple_simplify_268 ...
gimple_simplify_CFN_FNMS (gimple_match_op *res_op, gimple_seq *seq,
		    if (gimple_simplify_272 ...
				    if (gimple_simplify_274 ...
		    if (gimple_simplify_272 ...
				    if (gimple_simplify_274 ...

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2018-09-03 12:54     ` Martin Liška
@ 2018-09-03 13:50       ` Martin Liška
  2018-09-03 14:01         ` Richard Biener
  0 siblings, 1 reply; 27+ messages in thread
From: Martin Liška @ 2018-09-03 13:50 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 25376 bytes --]

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?

Martin

[-- Attachment #2: gimple-match-scc.txt --]
[-- Type: text/plain, Size: 17890 bytes --]

total functions: 590

['gimple_simplify_ABS_EXPR']
['gimple_simplify_CFN_BUILT_IN_COSF']
['gimple_simplify_CFN_BUILT_IN_COS']
['gimple_simplify_CFN_BUILT_IN_COSL']
['gimple_simplify_CFN_COS']
['gimple_simplify_CFN_BUILT_IN_COSHF']
['gimple_simplify_CFN_BUILT_IN_COSH']
['gimple_simplify_CFN_BUILT_IN_COSHL']
['gimple_simplify_CFN_BUILT_IN_CCOSF']
['gimple_simplify_CFN_BUILT_IN_CCOS']
['gimple_simplify_CFN_BUILT_IN_CCOSL']
['gimple_simplify_CFN_BUILT_IN_CCOSHF']
['gimple_simplify_CFN_BUILT_IN_CCOSH']
['gimple_simplify_CFN_BUILT_IN_CCOSHL']
['gimple_simplify_CFN_BUILT_IN_CABSF']
['gimple_simplify_CFN_BUILT_IN_CABS']
['gimple_simplify_CFN_BUILT_IN_CABSL']
['gimple_simplify_VIEW_CONVERT_EXPR']
['gimple_simplify_FLOAT_EXPR']
['gimple_simplify_FIX_TRUNC_EXPR']
['gimple_simplify_PAREN_EXPR']
['gimple_simplify_REALPART_EXPR']
['gimple_simplify_IMAGPART_EXPR']
['gimple_simplify_CFN_BUILT_IN_EXPF']
['gimple_simplify_CFN_BUILT_IN_EXP']
['gimple_simplify_CFN_BUILT_IN_EXPL']
['gimple_simplify_CFN_EXP']
['gimple_simplify_CFN_BUILT_IN_EXP2F']
['gimple_simplify_CFN_BUILT_IN_EXP2']
['gimple_simplify_CFN_BUILT_IN_EXP2L']
['gimple_simplify_CFN_EXP2']
['gimple_simplify_CFN_BUILT_IN_EXP10F']
['gimple_simplify_CFN_BUILT_IN_EXP10']
['gimple_simplify_CFN_BUILT_IN_EXP10L']
['gimple_simplify_CFN_EXP10']
['gimple_simplify_CFN_BUILT_IN_POW10F']
['gimple_simplify_CFN_BUILT_IN_POW10']
['gimple_simplify_CFN_BUILT_IN_POW10L']
['gimple_simplify_CFN_BUILT_IN_SQRTF']
['gimple_simplify_CFN_BUILT_IN_SQRT']
['gimple_simplify_CFN_BUILT_IN_SQRTL']
['gimple_simplify_CFN_SQRT']
['gimple_simplify_CFN_BUILT_IN_CBRTF']
['gimple_simplify_CFN_BUILT_IN_CBRT']
['gimple_simplify_CFN_BUILT_IN_CBRTL']
['gimple_simplify_CFN_BUILT_IN_CEXPF']
['gimple_simplify_CFN_BUILT_IN_CEXP']
['gimple_simplify_CFN_BUILT_IN_CEXPL']
['gimple_simplify_CFN_BUILT_IN_IFLOORF']
['gimple_simplify_CFN_BUILT_IN_LFLOORF']
['gimple_simplify_CFN_BUILT_IN_LLFLOORF']
['gimple_simplify_CFN_BUILT_IN_ICEILF']
['gimple_simplify_CFN_BUILT_IN_LCEILF']
['gimple_simplify_CFN_BUILT_IN_LLCEILF']
['gimple_simplify_CFN_BUILT_IN_IROUNDF']
['gimple_simplify_CFN_BUILT_IN_LROUNDF']
['gimple_simplify_CFN_BUILT_IN_LLROUNDF']
['gimple_simplify_CFN_BUILT_IN_IRINTF']
['gimple_simplify_CFN_BUILT_IN_LRINTF']
['gimple_simplify_CFN_BUILT_IN_LLRINTF']
['gimple_simplify_CFN_BUILT_IN_CPROJF']
['gimple_simplify_CFN_BUILT_IN_CPROJ']
['gimple_simplify_CFN_BUILT_IN_CPROJL']
['gimple_simplify_CFN_BUILT_IN_SIGNBITF']
['gimple_simplify_CFN_BUILT_IN_SIGNBIT']
['gimple_simplify_CFN_BUILT_IN_SIGNBITL']
['gimple_simplify_POINTER_PLUS_EXPR']
['gimple_simplify_POINTER_DIFF_EXPR']
['gimple_simplify_CFN_BUILT_IN_HYPOTF']
['gimple_simplify_CFN_BUILT_IN_HYPOT']
['gimple_simplify_CFN_BUILT_IN_HYPOTL']
['gimple_simplify_COMPLEX_EXPR']
['gimple_simplify_TRUTH_ORIF_EXPR']
['gimple_simplify_TRUTH_OR_EXPR']
['gimple_simplify_BIT_FIELD_REF']
['gimple_simplify_CONJ_EXPR', 'gimple_simplify_286']
['gimple_simplify_NEGATE_EXPR', 'gimple_simplify_56', 'gimple_simplify_202']
['gimple_simplify_CFN_FMS', 'gimple_simplify_239', 'gimple_simplify_234']
['gimple_simplify_CFN_FNMA', 'gimple_simplify_268', 'gimple_simplify_259']
['gimple_simplify_CFN_FNMS', 'gimple_simplify_274', 'gimple_simplify_272']
['gimple_simplify_CONVERT_EXPR', 'gimple_simplify_58', 'gimple_simplify_29', 'gimple_simplify_236']
['gimple_simplify_CFN_BUILT_IN_POWIL', 'gimple_simplify_CFN_BUILT_IN_POWIF', 'gimple_simplify_CFN_BUILT_IN_POWI', 'gimple_simplify_108']
['gimple_simplify_CFN_TAN', 'gimple_simplify_CFN_BUILT_IN_TANL', 'gimple_simplify_CFN_BUILT_IN_TANF', 'gimple_simplify_CFN_BUILT_IN_TAN', 'gimple_simplify_77']
['gimple_simplify_CFN_BUILT_IN_POPCOUNTLL', 'gimple_simplify_CFN_BUILT_IN_POPCOUNTL', 'gimple_simplify_CFN_BUILT_IN_POPCOUNTIMAX', 'gimple_simplify_CFN_BUILT_IN_POPCOUNT', 'gimple_simplify_214']
['gimple_simplify_COND_EXPR', 'gimple_simplify_71', 'gimple_simplify_275', 'gimple_simplify_261', 'gimple_simplify_13']
['gimple_simplify_CFN_BUILT_IN_BSWAP64', 'gimple_simplify_CFN_BUILT_IN_BSWAP32', 'gimple_simplify_CFN_BUILT_IN_BSWAP16', 'gimple_simplify_195', 'gimple_simplify_174', 'gimple_simplify_171']
['gimple_simplify_CFN_POW', 'gimple_simplify_CFN_BUILT_IN_POWL', 'gimple_simplify_CFN_BUILT_IN_POWF', 'gimple_simplify_CFN_BUILT_IN_POW', 'gimple_simplify_70', 'gimple_simplify_45', 'gimple_simplify_40']
['gimple_simplify_CFN_FMA', 'gimple_simplify_CFN_BUILT_IN_FMAL', 'gimple_simplify_CFN_BUILT_IN_FMAF', 'gimple_simplify_CFN_BUILT_IN_FMA', 'gimple_simplify_231', 'gimple_simplify_229', 'gimple_simplify_224']
['gimple_simplify_RDIV_EXPR', 'gimple_simplify_4', 'gimple_simplify_287', 'gimple_simplify_285', 'gimple_simplify_255', 'gimple_simplify_219', 'gimple_simplify_212', 'gimple_simplify_21', 'gimple_simplify_164']
['gimple_simplify_VEC_COND_EXPR', 'gimple_simplify_74', 'gimple_simplify_269', 'gimple_simplify_266', 'gimple_simplify_209', 'gimple_simplify_165', 'gimple_simplify_161', 'gimple_simplify_122', 'gimple_simplify_106']
['gimple_simplify_CFN_LDEXP', 'gimple_simplify_CFN_BUILT_IN_SCALBNL', 'gimple_simplify_CFN_BUILT_IN_SCALBNF', 'gimple_simplify_CFN_BUILT_IN_SCALBN', 'gimple_simplify_CFN_BUILT_IN_SCALBLNL', 'gimple_simplify_CFN_BUILT_IN_SCALBLNF', 'gimple_simplify_CFN_BUILT_IN_SCALBLN', 'gimple_simplify_CFN_BUILT_IN_LDEXPL', 'gimple_simplify_CFN_BUILT_IN_LDEXPF', 'gimple_simplify_CFN_BUILT_IN_LDEXP', 'gimple_simplify_46', 'gimple_simplify_119']
['gimple_simplify_BIT_NOT_EXPR', 'gimple_simplify_75', 'gimple_simplify_61', 'gimple_simplify_302', 'gimple_simplify_282', 'gimple_simplify_247', 'gimple_simplify_24', 'gimple_simplify_207', 'gimple_simplify_167', 'gimple_simplify_144', 'gimple_simplify_143', 'gimple_simplify_126', 'gimple_simplify_123']
['gimple_simplify_CFN_LOG2', 'gimple_simplify_CFN_LOG10', 'gimple_simplify_CFN_LOG', 'gimple_simplify_CFN_BUILT_IN_LOGL', 'gimple_simplify_CFN_BUILT_IN_LOGF', 'gimple_simplify_CFN_BUILT_IN_LOG2L', 'gimple_simplify_CFN_BUILT_IN_LOG2F', 'gimple_simplify_CFN_BUILT_IN_LOG2', 'gimple_simplify_CFN_BUILT_IN_LOG10L', 'gimple_simplify_CFN_BUILT_IN_LOG10F', 'gimple_simplify_CFN_BUILT_IN_LOG10', 'gimple_simplify_CFN_BUILT_IN_LOG', 'gimple_simplify_93']
['gimple_simplify_TRUNC_MOD_EXPR', 'gimple_simplify_ROUND_MOD_EXPR', 'gimple_simplify_FLOOR_MOD_EXPR', 'gimple_simplify_CEIL_MOD_EXPR', 'gimple_simplify_91', 'gimple_simplify_9', 'gimple_simplify_84', 'gimple_simplify_76', 'gimple_simplify_57', 'gimple_simplify_290', 'gimple_simplify_213', 'gimple_simplify_194', 'gimple_simplify_131']
['gimple_simplify_RSHIFT_EXPR', 'gimple_simplify_RROTATE_EXPR', 'gimple_simplify_LSHIFT_EXPR', 'gimple_simplify_LROTATE_EXPR', 'gimple_simplify_73', 'gimple_simplify_59', 'gimple_simplify_22', 'gimple_simplify_190', 'gimple_simplify_179', 'gimple_simplify_170', 'gimple_simplify_115', 'gimple_simplify_107', 'gimple_simplify_101']
['gimple_simplify_CFN_COPYSIGN', 'gimple_simplify_CFN_BUILT_IN_COPYSIGNL', 'gimple_simplify_CFN_BUILT_IN_COPYSIGNF64X', 'gimple_simplify_CFN_BUILT_IN_COPYSIGNF64', 'gimple_simplify_CFN_BUILT_IN_COPYSIGNF32X', 'gimple_simplify_CFN_BUILT_IN_COPYSIGNF32', 'gimple_simplify_CFN_BUILT_IN_COPYSIGNF16', 'gimple_simplify_CFN_BUILT_IN_COPYSIGNF128X', 'gimple_simplify_CFN_BUILT_IN_COPYSIGNF128', 'gimple_simplify_CFN_BUILT_IN_COPYSIGNF', 'gimple_simplify_CFN_BUILT_IN_COPYSIGN', 'gimple_simplify_49', 'gimple_simplify_38', 'gimple_simplify_260', 'gimple_simplify_136', 'gimple_simplify_125']
['gimple_simplify_CFN_BUILT_IN_LROUNDL', 'gimple_simplify_CFN_BUILT_IN_LROUND', 'gimple_simplify_CFN_BUILT_IN_LRINTL', 'gimple_simplify_CFN_BUILT_IN_LRINT', 'gimple_simplify_CFN_BUILT_IN_LLROUNDL', 'gimple_simplify_CFN_BUILT_IN_LLROUND', 'gimple_simplify_CFN_BUILT_IN_LLRINTL', 'gimple_simplify_CFN_BUILT_IN_LLRINT', 'gimple_simplify_CFN_BUILT_IN_LLFLOORL', 'gimple_simplify_CFN_BUILT_IN_LLFLOOR', 'gimple_simplify_CFN_BUILT_IN_LLCEILL', 'gimple_simplify_CFN_BUILT_IN_LLCEIL', 'gimple_simplify_CFN_BUILT_IN_LFLOORL', 'gimple_simplify_CFN_BUILT_IN_LFLOOR', 'gimple_simplify_CFN_BUILT_IN_LCEILL', 'gimple_simplify_CFN_BUILT_IN_LCEIL', 'gimple_simplify_CFN_BUILT_IN_IROUNDL', 'gimple_simplify_CFN_BUILT_IN_IROUND', 'gimple_simplify_CFN_BUILT_IN_IRINTL', 'gimple_simplify_CFN_BUILT_IN_IRINT', 'gimple_simplify_CFN_BUILT_IN_IFLOORL', 'gimple_simplify_CFN_BUILT_IN_IFLOOR', 'gimple_simplify_CFN_BUILT_IN_ICEILL', 'gimple_simplify_CFN_BUILT_IN_ICEIL', 'gimple_simplify_205', 'gimple_simplify_158']
['gimple_simplify_TRUNC_DIV_EXPR', 'gimple_simplify_ROUND_DIV_EXPR', 'gimple_simplify_MULT_EXPR', 'gimple_simplify_FLOOR_DIV_EXPR', 'gimple_simplify_EXACT_DIV_EXPR', 'gimple_simplify_CEIL_DIV_EXPR', 'gimple_simplify_92', 'gimple_simplify_72', 'gimple_simplify_35', 'gimple_simplify_294', 'gimple_simplify_273', 'gimple_simplify_27', 'gimple_simplify_264', 'gimple_simplify_262', 'gimple_simplify_26', 'gimple_simplify_243', 'gimple_simplify_240', 'gimple_simplify_222', 'gimple_simplify_20', 'gimple_simplify_192', 'gimple_simplify_189', 'gimple_simplify_181', 'gimple_simplify_18', 'gimple_simplify_155', 'gimple_simplify_145', 'gimple_simplify_141', 'gimple_simplify_132', 'gimple_simplify_129', 'gimple_simplify_128', 'gimple_simplify_111']
['gimple_simplify_MIN_EXPR', 'gimple_simplify_MAX_EXPR', 'gimple_simplify_CFN_FMIN', 'gimple_simplify_CFN_FMAX', 'gimple_simplify_CFN_BUILT_IN_FMINL', 'gimple_simplify_CFN_BUILT_IN_FMINF64X', 'gimple_simplify_CFN_BUILT_IN_FMINF64', 'gimple_simplify_CFN_BUILT_IN_FMINF32X', 'gimple_simplify_CFN_BUILT_IN_FMINF32', 'gimple_simplify_CFN_BUILT_IN_FMINF16', 'gimple_simplify_CFN_BUILT_IN_FMINF128X', 'gimple_simplify_CFN_BUILT_IN_FMINF128', 'gimple_simplify_CFN_BUILT_IN_FMINF', 'gimple_simplify_CFN_BUILT_IN_FMIN', 'gimple_simplify_CFN_BUILT_IN_FMAXL', 'gimple_simplify_CFN_BUILT_IN_FMAXF64X', 'gimple_simplify_CFN_BUILT_IN_FMAXF64', 'gimple_simplify_CFN_BUILT_IN_FMAXF32X', 'gimple_simplify_CFN_BUILT_IN_FMAXF32', 'gimple_simplify_CFN_BUILT_IN_FMAXF16', 'gimple_simplify_CFN_BUILT_IN_FMAXF128X', 'gimple_simplify_CFN_BUILT_IN_FMAXF128', 'gimple_simplify_CFN_BUILT_IN_FMAXF', 'gimple_simplify_CFN_BUILT_IN_FMAX', 'gimple_simplify_89', 'gimple_simplify_82', 'gimple_simplify_299', 'gimple_simplify_295', 'gimple_simplify_248', 'gimple_simplify_246', 'gimple_simplify_245', 'gimple_simplify_149', 'gimple_simplify_11']
['gimple_simplify_CFN_TRUNC', 'gimple_simplify_CFN_ROUND', 'gimple_simplify_CFN_RINT', 'gimple_simplify_CFN_NEARBYINT', 'gimple_simplify_CFN_FLOOR', 'gimple_simplify_CFN_CEIL', 'gimple_simplify_CFN_BUILT_IN_TRUNCL', 'gimple_simplify_CFN_BUILT_IN_TRUNCF64X', 'gimple_simplify_CFN_BUILT_IN_TRUNCF64', 'gimple_simplify_CFN_BUILT_IN_TRUNCF32X', 'gimple_simplify_CFN_BUILT_IN_TRUNCF32', 'gimple_simplify_CFN_BUILT_IN_TRUNCF16', 'gimple_simplify_CFN_BUILT_IN_TRUNCF128X', 'gimple_simplify_CFN_BUILT_IN_TRUNCF128', 'gimple_simplify_CFN_BUILT_IN_TRUNCF', 'gimple_simplify_CFN_BUILT_IN_TRUNC', 'gimple_simplify_CFN_BUILT_IN_ROUNDL', 'gimple_simplify_CFN_BUILT_IN_ROUNDF64X', 'gimple_simplify_CFN_BUILT_IN_ROUNDF64', 'gimple_simplify_CFN_BUILT_IN_ROUNDF32X', 'gimple_simplify_CFN_BUILT_IN_ROUNDF32', 'gimple_simplify_CFN_BUILT_IN_ROUNDF16', 'gimple_simplify_CFN_BUILT_IN_ROUNDF128X', 'gimple_simplify_CFN_BUILT_IN_ROUNDF128', 'gimple_simplify_CFN_BUILT_IN_ROUNDF', 'gimple_simplify_CFN_BUILT_IN_ROUND', 'gimple_simplify_CFN_BUILT_IN_RINTL', 'gimple_simplify_CFN_BUILT_IN_RINTF64X', 'gimple_simplify_CFN_BUILT_IN_RINTF64', 'gimple_simplify_CFN_BUILT_IN_RINTF32X', 'gimple_simplify_CFN_BUILT_IN_RINTF32', 'gimple_simplify_CFN_BUILT_IN_RINTF16', 'gimple_simplify_CFN_BUILT_IN_RINTF128X', 'gimple_simplify_CFN_BUILT_IN_RINTF128', 'gimple_simplify_CFN_BUILT_IN_RINTF', 'gimple_simplify_CFN_BUILT_IN_RINT', 'gimple_simplify_CFN_BUILT_IN_NEARBYINTL', 'gimple_simplify_CFN_BUILT_IN_NEARBYINTF64X', 'gimple_simplify_CFN_BUILT_IN_NEARBYINTF64', 'gimple_simplify_CFN_BUILT_IN_NEARBYINTF32X', 'gimple_simplify_CFN_BUILT_IN_NEARBYINTF32', 'gimple_simplify_CFN_BUILT_IN_NEARBYINTF16', 'gimple_simplify_CFN_BUILT_IN_NEARBYINTF128X', 'gimple_simplify_CFN_BUILT_IN_NEARBYINTF128', 'gimple_simplify_CFN_BUILT_IN_NEARBYINTF', 'gimple_simplify_CFN_BUILT_IN_NEARBYINT', 'gimple_simplify_CFN_BUILT_IN_FLOORL', 'gimple_simplify_CFN_BUILT_IN_FLOORF64X', 'gimple_simplify_CFN_BUILT_IN_FLOORF64', 'gimple_simplify_CFN_BUILT_IN_FLOORF32X', 'gimple_simplify_CFN_BUILT_IN_FLOORF32', 'gimple_simplify_CFN_BUILT_IN_FLOORF16', 'gimple_simplify_CFN_BUILT_IN_FLOORF128X', 'gimple_simplify_CFN_BUILT_IN_FLOORF128', 'gimple_simplify_CFN_BUILT_IN_FLOORF', 'gimple_simplify_CFN_BUILT_IN_FLOOR', 'gimple_simplify_CFN_BUILT_IN_CEILL', 'gimple_simplify_CFN_BUILT_IN_CEILF64X', 'gimple_simplify_CFN_BUILT_IN_CEILF64', 'gimple_simplify_CFN_BUILT_IN_CEILF32X', 'gimple_simplify_CFN_BUILT_IN_CEILF32', 'gimple_simplify_CFN_BUILT_IN_CEILF16', 'gimple_simplify_CFN_BUILT_IN_CEILF128X', 'gimple_simplify_CFN_BUILT_IN_CEILF128', 'gimple_simplify_CFN_BUILT_IN_CEILF', 'gimple_simplify_CFN_BUILT_IN_CEIL', 'gimple_simplify_297', 'gimple_simplify_25', 'gimple_simplify_201', 'gimple_simplify_177', 'gimple_simplify_113']
['gimple_simplify_UNORDERED_EXPR', 'gimple_simplify_UNLT_EXPR', 'gimple_simplify_UNLE_EXPR', 'gimple_simplify_UNGT_EXPR', 'gimple_simplify_UNGE_EXPR', 'gimple_simplify_UNEQ_EXPR', 'gimple_simplify_ORDERED_EXPR', 'gimple_simplify_NE_EXPR', 'gimple_simplify_LT_EXPR', 'gimple_simplify_LTGT_EXPR', 'gimple_simplify_LE_EXPR', 'gimple_simplify_GT_EXPR', 'gimple_simplify_GE_EXPR', 'gimple_simplify_EQ_EXPR', 'gimple_simplify_95', 'gimple_simplify_94', 'gimple_simplify_90', 'gimple_simplify_88', 'gimple_simplify_78', 'gimple_simplify_7', 'gimple_simplify_68', 'gimple_simplify_64', 'gimple_simplify_6', 'gimple_simplify_55', 'gimple_simplify_52', 'gimple_simplify_51', 'gimple_simplify_50', 'gimple_simplify_47', 'gimple_simplify_41', 'gimple_simplify_39', 'gimple_simplify_37', 'gimple_simplify_36', 'gimple_simplify_32', 'gimple_simplify_31', 'gimple_simplify_3', 'gimple_simplify_293', 'gimple_simplify_291', 'gimple_simplify_289', 'gimple_simplify_284', 'gimple_simplify_283', 'gimple_simplify_28', 'gimple_simplify_270', 'gimple_simplify_263', 'gimple_simplify_258', 'gimple_simplify_257', 'gimple_simplify_254', 'gimple_simplify_253', 'gimple_simplify_252', 'gimple_simplify_230', 'gimple_simplify_23', 'gimple_simplify_220', 'gimple_simplify_216', 'gimple_simplify_210', 'gimple_simplify_204', 'gimple_simplify_199', 'gimple_simplify_198', 'gimple_simplify_197', 'gimple_simplify_193', 'gimple_simplify_191', 'gimple_simplify_188', 'gimple_simplify_187', 'gimple_simplify_186', 'gimple_simplify_183', 'gimple_simplify_180', 'gimple_simplify_178', 'gimple_simplify_176', 'gimple_simplify_172', 'gimple_simplify_169', 'gimple_simplify_168', 'gimple_simplify_166', 'gimple_simplify_157', 'gimple_simplify_154', 'gimple_simplify_152', 'gimple_simplify_15', 'gimple_simplify_147', 'gimple_simplify_146', 'gimple_simplify_142', 'gimple_simplify_140', 'gimple_simplify_14', 'gimple_simplify_138', 'gimple_simplify_135', 'gimple_simplify_134', 'gimple_simplify_127', 'gimple_simplify_121', 'gimple_simplify_120', 'gimple_simplify_12', 'gimple_simplify_118', 'gimple_simplify_117', 'gimple_simplify_110', 'gimple_simplify_104', 'gimple_simplify_103', 'gimple_simplify_100', 'gimple_simplify_10', 'gimple_simplify_1']
['gimple_simplify_PLUS_EXPR', 'gimple_simplify_MINUS_EXPR', 'gimple_simplify_BIT_XOR_EXPR', 'gimple_simplify_BIT_IOR_EXPR', 'gimple_simplify_BIT_AND_EXPR', 'gimple_simplify_99', 'gimple_simplify_98', 'gimple_simplify_97', 'gimple_simplify_96', 'gimple_simplify_87', 'gimple_simplify_86', 'gimple_simplify_85', 'gimple_simplify_83', 'gimple_simplify_81', 'gimple_simplify_80', 'gimple_simplify_8', 'gimple_simplify_79', 'gimple_simplify_69', 'gimple_simplify_67', 'gimple_simplify_66', 'gimple_simplify_65', 'gimple_simplify_63', 'gimple_simplify_62', 'gimple_simplify_60', 'gimple_simplify_54', 'gimple_simplify_53', 'gimple_simplify_5', 'gimple_simplify_48', 'gimple_simplify_44', 'gimple_simplify_43', 'gimple_simplify_42', 'gimple_simplify_34', 'gimple_simplify_33', 'gimple_simplify_303', 'gimple_simplify_301', 'gimple_simplify_300', 'gimple_simplify_30', 'gimple_simplify_298', 'gimple_simplify_296', 'gimple_simplify_292', 'gimple_simplify_288', 'gimple_simplify_281', 'gimple_simplify_280', 'gimple_simplify_279', 'gimple_simplify_278', 'gimple_simplify_277', 'gimple_simplify_276', 'gimple_simplify_271', 'gimple_simplify_267', 'gimple_simplify_265', 'gimple_simplify_256', 'gimple_simplify_251', 'gimple_simplify_250', 'gimple_simplify_249', 'gimple_simplify_244', 'gimple_simplify_242', 'gimple_simplify_241', 'gimple_simplify_238', 'gimple_simplify_237', 'gimple_simplify_235', 'gimple_simplify_233', 'gimple_simplify_232', 'gimple_simplify_228', 'gimple_simplify_227', 'gimple_simplify_226', 'gimple_simplify_225', 'gimple_simplify_223', 'gimple_simplify_221', 'gimple_simplify_218', 'gimple_simplify_217', 'gimple_simplify_215', 'gimple_simplify_211', 'gimple_simplify_208', 'gimple_simplify_206', 'gimple_simplify_203', 'gimple_simplify_200', 'gimple_simplify_2', 'gimple_simplify_196', 'gimple_simplify_19', 'gimple_simplify_185', 'gimple_simplify_184', 'gimple_simplify_182', 'gimple_simplify_175', 'gimple_simplify_173', 'gimple_simplify_17', 'gimple_simplify_163', 'gimple_simplify_162', 'gimple_simplify_160', 'gimple_simplify_16', 'gimple_simplify_159', 'gimple_simplify_156', 'gimple_simplify_153', 'gimple_simplify_151', 'gimple_simplify_150', 'gimple_simplify_148', 'gimple_simplify_139', 'gimple_simplify_137', 'gimple_simplify_133', 'gimple_simplify_130', 'gimple_simplify_124', 'gimple_simplify_116', 'gimple_simplify_114', 'gimple_simplify_112', 'gimple_simplify_109', 'gimple_simplify_105', 'gimple_simplify_102']

SCC components size:
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
2
3
3
3
3
4
4
5
5
5
6
7
7
9
9
12
13
13
13
13
16
26
30
33
71
94
106

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2018-09-03 13:50       ` Martin Liška
@ 2018-09-03 14:01         ` Richard Biener
  2018-09-03 14:27           ` Martin Liška
  0 siblings, 1 reply; 27+ messages in thread
From: Richard Biener @ 2018-09-03 14:01 UTC (permalink / raw)
  To: Martin Liška; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 27528 bytes --]

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.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2018-09-03 14:01         ` Richard Biener
@ 2018-09-03 14:27           ` Martin Liška
  2018-09-03 14:43             ` Richard Biener
  0 siblings, 1 reply; 27+ messages in thread
From: Martin Liška @ 2018-09-03 14:27 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

On 09/03/2018 04:00 PM, Richard Biener wrote:
> 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.

I see! Note that shrinking gimple-match.o 4 times will be probably sufficient for general
speed up:
https://gcc.gnu.org/bugzilla/attachment.cgi?id=43440

> 
> 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

That would be my plan, genmatch can mark in C comments function that can be partitioned
and callgraph of these functions.

> 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 ;))

... and a C++ splitter can do the rest: read content, do SCC, split to N parts
and stream out.

I can work on that. Questionable is still Makefile integration of such parallelism?

Martin

> 
> Richard.
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2018-09-03 14:27           ` Martin Liška
@ 2018-09-03 14:43             ` Richard Biener
  2018-09-04 15:07               ` Martin Liška
  0 siblings, 1 reply; 27+ messages in thread
From: Richard Biener @ 2018-09-03 14:43 UTC (permalink / raw)
  To: Martin Liška; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 6266 bytes --]

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

> On 09/03/2018 04:00 PM, Richard Biener wrote:
> > 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.
...
> >>>>> 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.
> 
> I see! Note that shrinking gimple-match.o 4 times will be probably sufficient for general
> speed up:
> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43440
> 
> > 
> > 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
> 
> That would be my plan, genmatch can mark in C comments function that can be partitioned
> and callgraph of these functions.
> 
> > 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 ;))
> 
> ... and a C++ splitter can do the rest: read content, do SCC, split to N parts
> and stream out.
> 
> I can work on that. Questionable is still Makefile integration of such 
> parallelism?

Well, just hard-code the number of pieces and thus the pices to
compile in the end...

Of course we shouldn't add any additional build dependencies
(a "C++ splitter").  Adding additional annotation to the genmatch
generated sources may be OK but then eventually doing everything in
genmatch isn't too complicated (putting aside that # of lines metric...).

Richard.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2018-09-03 14:43             ` Richard Biener
@ 2018-09-04 15:07               ` Martin Liška
  2018-09-10 11:43                 ` Martin Liška
  2019-04-29 14:41                 ` Martin Liška
  0 siblings, 2 replies; 27+ messages in thread
From: Martin Liška @ 2018-09-04 15:07 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 8488 bytes --]

On 09/03/2018 04:43 PM, Richard Biener wrote:
> On Mon, 3 Sep 2018, Martin Liška wrote:
> 
>> On 09/03/2018 04:00 PM, Richard Biener wrote:
>>> 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.
> ...
>>>>>>> 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.
>>
>> I see! Note that shrinking gimple-match.o 4 times will be probably sufficient for general
>> speed up:
>> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43440
>>
>>>
>>> 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
>>
>> That would be my plan, genmatch can mark in C comments function that can be partitioned
>> and callgraph of these functions.
>>
>>> 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 ;))
>>
>> ... and a C++ splitter can do the rest: read content, do SCC, split to N parts
>> and stream out.
>>
>> I can work on that. Questionable is still Makefile integration of such 
>> parallelism?
> 
> Well, just hard-code the number of pieces and thus the pices to
> compile in the end...
> 
> Of course we shouldn't add any additional build dependencies
> (a "C++ splitter").  Adding additional annotation to the genmatch
> generated sources may be OK but then eventually doing everything in
> genmatch isn't too complicated (putting aside that # of lines metric...).
> 
> Richard.
> 

Hi.

There's working solution for {gimple,generic}-match.c. It introduces splitter.cc which
parses annotated generated files and split it according to call graph provided by annotations.
Currently I copied a SCC implementation as graphds.c has quite some dependencies (xrealloc, bitmap,..).
Questionable how to reduce the dependencies?

For gimple-match.c the biggest SCC component contains about 1/4 LOC, which means maximal reasonable number
of parts is equal to 4. Doing that the biggest component is compiled with -O2 14.5s, which the original gimple-match.c
50.0s. That sounds promising:

 l gimple-match-part*.c
-rw-r--r-- 1 marxin users 791442 Sep  4 17:02 gimple-match-part-0.c
-rw-r--r-- 1 marxin users 748610 Sep  4 17:02 gimple-match-part-1.c
-rw-r--r-- 1 marxin users 783749 Sep  4 17:02 gimple-match-part-2.c
-rw-r--r-- 1 marxin users 828990 Sep  4 17:02 gimple-match-part-3.c
-rw-r--r-- 1 marxin users 103130 Sep  4 17:02 gimple-match-part-footer.c

for generic-match.c:

l generic-match-part*.c
-rw-r--r-- 1 marxin users 528712 Sep  4 17:02 generic-match-part-0.c
-rw-r--r-- 1 marxin users 517120 Sep  4 17:02 generic-match-part-1.c
-rw-r--r-- 1 marxin users 519777 Sep  4 17:02 generic-match-part-2.c
-rw-r--r-- 1 marxin users 221971 Sep  4 17:02 generic-match-part-3.c
-rw-r--r-- 1 marxin users  14596 Sep  4 17:02 generic-match-part-footer.c

There are some issues with functions that live in gimple-match-head.c, these
should live in a header file the parts can include. I also renamed
gimple_simplify function that live in gimple-match.c to gimple_simplify_generated
as they clash with these that are in gimple-match-head.c.

There are still various questions:
- how to make the split process optional, how to modify then Makefile?
- SCC implementation should be shared with graphds.c
- splitter.cc should be cleaned up
- in order to achieve real speed up we need to split also other generated (and also dwarf2out.c, i386.c, ..) files:
here I'm most concerned about insn-recog.c, which can't be split the same way without ending up with a single huge SCC component.
Ideas what to do with that file?

Thoughts?

Martin

[-- Attachment #2: 0001-Come-up-with-splitter-for-gimple-and-generic-match-f.patch --]
[-- Type: text/x-patch, Size: 37255 bytes --]

From 0f57bea9576867140846abb8703dba878eb20c70 Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Tue, 4 Sep 2018 14:54:17 +0200
Subject: [PATCH] Come up with splitter for gimple and generic match files.

---
 gcc/Makefile.in                |  49 ++++-
 gcc/genmatch.c                 |  57 ++++--
 gcc/gimple-match-head-common.h | 191 ++++++++++++++++++
 gcc/gimple-match-head.c        | 211 +++----------------
 gcc/splitter.cc                | 357 +++++++++++++++++++++++++++++++++
 5 files changed, 647 insertions(+), 218 deletions(-)
 create mode 100644 gcc/gimple-match-head-common.h
 create mode 100644 gcc/splitter.cc

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index e008f63b2ea..3cae9bcfd8d 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -218,8 +218,16 @@ 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-part-0.o-warn = -Wno-unused
+gimple-match-part-1.o-warn = -Wno-unused
+gimple-match-part-2.o-warn = -Wno-unused
+gimple-match-part-3.o-warn = -Wno-unused
+gimple-match-part-footer.o-warn = -Wno-unused
+generic-match-part-0.o-warn = -Wno-unused
+generic-match-part-1.o-warn = -Wno-unused
+generic-match-part-2.o-warn = -Wno-unused
+generic-match-part-3.o-warn = -Wno-unused
+generic-match-part-footer.o-warn = -Wno-unused
 dfp.o-warn = -Wno-strict-aliasing
 
 # All warnings have to be shut off in stage1 if the compiler used then
@@ -522,7 +530,7 @@ CROSS_SYSTEM_HEADER_DIR = @CROSS_SYSTEM_HEADER_DIR@
 # to directories that might not exist yet.
 # The sed idiom for this is to repeat the search-and-replace until it doesn't match, using :a ... ta.
 # Use single quotes here to avoid nested double- and backquotes, this
-# macro is also used in a double-quoted context.
+# macro is also used inmem_alloc_description a double-quoted context.
 SYSTEM_HEADER_DIR = `echo @SYSTEM_HEADER_DIR@ | sed -e :a -e 's,[^/]*/\.\.\/,,' -e ta`
 
 # Path to the system headers on the build machine.
@@ -1209,8 +1217,17 @@ C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
 # 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-part-0.o \
+	gimple-match-part-1.o \
+	gimple-match-part-2.o \
+	gimple-match-part-3.o \
+	gimple-match-part-footer.o \
+	gimple-match-head.o \
+	generic-match-part-0.o \
+	generic-match-part-1.o \
+	generic-match-part-2.o \
+	generic-match-part-3.o \
+	generic-match-part-footer.o \
 	insn-attrtab.o \
 	insn-automata.o \
 	insn-dfatab.o \
@@ -2507,10 +2524,19 @@ s-tm-texi: build/genhooks$(build_exeext) $(srcdir)/doc/tm.texi.in
 	  false; \
 	fi
 
-gimple-match.c: s-match gimple-match-head.c ; @true
-generic-match.c: s-match generic-match-head.c ; @true
+gimple-match-part-0.c: s-match gimple-match-head.c ; @true
+gimple-match-part-1.c: s-match gimple-match-head.c ; @true
+gimple-match-part-2.c: s-match gimple-match-head.c ; @true
+gimple-match-part-3.c: s-match gimple-match-head.c ; @true
+gimple-match-part-footer.c: s-match gimple-match-head.c ; @true
 
-s-match: build/genmatch$(build_exeext) $(srcdir)/match.pd cfn-operators.pd
+generic-match-part-0.c: s-match generic-match-head.c ; @true
+generic-match-part-1.c: s-match generic-match-head.c ; @true
+generic-match-part-2.c: s-match generic-match-head.c ; @true
+generic-match-part-3.c: s-match generic-match-head.c ; @true
+generic-match-part-footer.c: s-match generic-match-head.c ; @true
+
+s-match: build/genmatch$(build_exeext) $(srcdir)/match.pd cfn-operators.pd build/splitter$(build_exeext)
 	$(RUN_GEN) build/genmatch$(build_exeext) --gimple $(srcdir)/match.pd \
 	    > tmp-gimple-match.c
 	$(RUN_GEN) build/genmatch$(build_exeext) --generic $(srcdir)/match.pd \
@@ -2519,6 +2545,8 @@ s-match: build/genmatch$(build_exeext) $(srcdir)/match.pd cfn-operators.pd
 	    					gimple-match.c
 	$(SHELL) $(srcdir)/../move-if-change tmp-generic-match.c \
 	    					generic-match.c
+	build/splitter$(build_exeext) generic
+	build/splitter$(build_exeext) gimple
 	$(STAMP) s-match
 
 GTFILES = $(CPPLIB_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
@@ -2793,6 +2821,7 @@ build/genmatch.o : genmatch.c $(BCONFIG_H) $(SYSTEM_H) \
 build/gencfn-macros.o : gencfn-macros.c $(BCONFIG_H) $(SYSTEM_H)	\
   $(CORETYPES_H) errors.h $(HASH_TABLE_H) hash-set.h builtins.def	\
   internal-fn.def
+build/splitter.o: splitter.cc
 
 # Compile the programs that generate insn-* from the machine description.
 # They are compiled with $(COMPILER_FOR_BUILD), and associated libraries,
@@ -2836,6 +2865,10 @@ endif
 build/genmatch$(build_exeext) : $(BUILD_CPPLIB) \
   $(BUILD_ERRORS) build/vec.o build/hash-table.o build/sort.o
 
+build/splitter$(build_exeext) : $(BUILD_CPPLIB) \
+	$(BUILD_ERRORS) splitter.o
+	g++ -o $@ $^
+
 # These programs are not linked with the MD reader.
 build/gengtype$(build_exeext) : build/gengtype-lex.o build/gengtype-parse.o \
               build/gengtype-state.o build/version.o build/errors.o
diff --git a/gcc/genmatch.c b/gcc/genmatch.c
index 5f1691ae206..3a06210d0c2 100644
--- a/gcc/genmatch.c
+++ b/gcc/genmatch.c
@@ -3551,6 +3551,7 @@ dt_simplify::gen (FILE *f, int indent, bool gimple)
   /* If we have a split-out function for the actual transform, call it.  */
   if (info && info->fname)
     {
+      fprintf (f, "// call-fn:%s\n", info->fname);
       if (gimple)
 	{
 	  fprintf_indent (f, indent, "if (%s (res_op, seq, "
@@ -3682,6 +3683,27 @@ sinfo_hashmap_traits::equal_keys (const key_type &v,
   return compare_op (v->s->result, v->s, candidate->s->result, candidate->s);
 }
 
+static void
+print_simplify_fnheader (FILE *f, bool gimple, const char *op, unsigned n, bool declaration)
+{
+  if (gimple)
+    fprintf (f, "%sbool\n"
+	     "gimple_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)", declaration ? "extern " : "",
+	     op);
+  else
+    fprintf (f, "extern tree\n"
+	     "generic_simplify_%s (location_t ARG_UNUSED (loc), enum "
+	     "tree_code ARG_UNUSED (code), const tree ARG_UNUSED (type)",
+	     op);
+  for (unsigned i = 0; i < n; ++i)
+    fprintf (f, ", tree op%d", i);
+  fprintf (f, ")%s\n", declaration ? ";" : "");
+}
 
 /* Main entry to generate code for matching GIMPLE IL off the decision
    tree.  */
@@ -3719,8 +3741,10 @@ decision_tree::gen (FILE *f, bool gimple)
       /* Generate a split out function with the leaf transform code.  */
       s->fname = xasprintf ("%s_simplify_%u", gimple ? "gimple" : "generic",
 			    fcnt++);
+
+      fprintf (f, "\n// split-fn-begin:%s\n", s->fname);
       if (gimple)
-	fprintf (f, "\nstatic bool\n"
+	fprintf (f, "static bool\n"
 		 "%s (gimple_match_op *res_op, gimple_seq *seq,\n"
 		 "                 tree (*valueize)(tree) ATTRIBUTE_UNUSED,\n"
 		 "                 const tree ARG_UNUSED (type), tree *ARG_UNUSED "
@@ -3755,6 +3779,7 @@ decision_tree::gen (FILE *f, bool gimple)
       else
 	fprintf (f, "  return NULL_TREE;\n");
       fprintf (f, "}\n");
+      fprintf (f, "// split-fn-end\n");
     }
   fprintf (stderr, "removed %u duplicate tails\n", rcnt);
 
@@ -3774,23 +3799,10 @@ decision_tree::gen (FILE *f, bool gimple)
 		  && e->operation->kind != id_base::CODE))
 	    continue;
 
-	  if (gimple)
-	    fprintf (f, "\nstatic bool\n"
-		     "gimple_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)\n",
-		     e->operation->id);
-	  else
-	    fprintf (f, "\nstatic tree\n"
-		     "generic_simplify_%s (location_t ARG_UNUSED (loc), enum "
-		     "tree_code ARG_UNUSED (code), const tree ARG_UNUSED (type)",
-		     e->operation->id);
-	  for (unsigned i = 0; i < n; ++i)
-	    fprintf (f, ", tree op%d", i);
-	  fprintf (f, ")\n");
+	  print_simplify_fnheader (f, gimple, e->operation->id, n, true);
+	  fprintf (f, "\n// split-fn-begin:%s_%s\n", gimple ? "gimple" : "generic",
+		   e->operation->id);
+	  print_simplify_fnheader (f, gimple, e->operation->id, n, false);
 	  fprintf (f, "{\n");
 	  dop->gen_kids (f, 2, gimple);
 	  if (gimple)
@@ -3798,13 +3810,14 @@ decision_tree::gen (FILE *f, bool gimple)
 	  else
 	    fprintf (f, "  return NULL_TREE;\n");
 	  fprintf (f, "}\n");
+	  fprintf (f, "// split-fn-end\n");
 	}
 
       /* Then generate the main entry with the outermost switch and
          tail-calls to the split-out functions.  */
       if (gimple)
-	fprintf (f, "\nstatic bool\n"
-		 "gimple_simplify (gimple_match_op *res_op, gimple_seq *seq,\n"
+	fprintf (f, "\nbool\n"
+		 "gimple_simplify_generated (gimple_match_op *res_op, gimple_seq *seq,\n"
 		 "                 tree (*valueize)(tree) ATTRIBUTE_UNUSED,\n"
 		 "                 code_helper code, const tree type");
       else
@@ -3868,7 +3881,7 @@ decision_tree::gen (FILE *f, bool gimple)
 void
 write_predicate (FILE *f, predicate_id *p, decision_tree &dt, bool gimple)
 {
-  fprintf (f, "\nbool\n"
+  fprintf (f, "\nstatic bool\n"
 	   "%s%s (tree t%s%s)\n"
 	   "{\n", gimple ? "gimple_" : "tree_", p->id,
 	   p->nargs > 0 ? ", tree *res_ops" : "",
@@ -5117,7 +5130,7 @@ add_operator (VIEW_CONVERT2, "view_convert2", "tcc_unary", 1);
   parser p (r);
 
   if (gimple)
-    write_header (stdout, "gimple-match-head.c");
+    write_header (stdout, "gimple-match-head-common.h");
   else
     write_header (stdout, "generic-match-head.c");
 
diff --git a/gcc/gimple-match-head-common.h b/gcc/gimple-match-head-common.h
new file mode 100644
index 00000000000..a854db32e7d
--- /dev/null
+++ b/gcc/gimple-match-head-common.h
@@ -0,0 +1,191 @@
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "backend.h"
+#include "target.h"
+#include "rtl.h"
+#include "tree.h"
+#include "gimple.h"
+#include "ssa.h"
+#include "cgraph.h"
+#include "fold-const.h"
+#include "fold-const-call.h"
+#include "stor-layout.h"
+#include "gimple-fold.h"
+#include "calls.h"
+#include "tree-dfa.h"
+#include "builtins.h"
+#include "gimple-match.h"
+#include "tree-pass.h"
+#include "internal-fn.h"
+#include "case-cfn-macros.h"
+#include "gimplify.h"
+#include "optabs-tree.h"
+#include "tree-eh.h"
+
+/* Return whether T is a constant that we'll dispatch to fold to
+   evaluate fully constant expressions.  */
+
+static inline bool
+constant_for_folding (tree t)
+{
+  return (CONSTANT_CLASS_P (t)
+	  /* The following is only interesting to string builtins.  */
+	  || (TREE_CODE (t) == ADDR_EXPR
+	      && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST));
+}
+
+/* Helper for gimple_simplify_generated valueizing OP using VALUEIZE and setting
+   VALUEIZED to true if valueization changed OP.  */
+
+static inline tree
+do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
+{
+  if (valueize && TREE_CODE (op) == SSA_NAME)
+    {
+      tree tem = valueize (op);
+      if (tem && tem != op)
+	{
+	  op = tem;
+	  valueized = true;
+	}
+    }
+  return op;
+}
+
+/* Routine to determine if the types T1 and T2 are effectively
+   the same for GIMPLE.  If T1 or T2 is not a type, the test
+   applies to their TREE_TYPE.  */
+
+static inline bool
+types_match (tree t1, tree t2)
+{
+  if (!TYPE_P (t1))
+    t1 = TREE_TYPE (t1);
+  if (!TYPE_P (t2))
+    t2 = TREE_TYPE (t2);
+
+  return types_compatible_p (t1, t2);
+}
+
+/* Return if T has a single use.  For GIMPLE, we also allow any
+   non-SSA_NAME (ie constants) and zero uses to cope with uses
+   that aren't linked up yet.  */
+
+static inline bool
+single_use (tree t)
+{
+  return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t);
+}
+
+/* Return true if math operations should be canonicalized,
+   e.g. sqrt(sqrt(x)) -> pow(x, 0.25).  */
+
+static inline bool
+canonicalize_math_p ()
+{
+  return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
+}
+
+/* Return true if math operations that are beneficial only after
+   vectorization should be canonicalized.  */
+
+static inline bool
+canonicalize_math_after_vectorization_p ()
+{
+  return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0;
+}
+
+/* Helper for the autogenerated code, get at the definition of NAME when
+   VALUEIZE allows that.  */
+
+static inline gimple *
+get_def (tree (*valueize)(tree), tree name)
+{
+  if (valueize && ! valueize (name))
+    return NULL;
+  return SSA_NAME_DEF_STMT (name);
+}
+
+/* Helper for the autogenerated code, valueize OP.  */
+
+static inline tree
+do_valueize (tree (*valueize)(tree), tree op)
+{
+  if (valueize && TREE_CODE (op) == SSA_NAME)
+    {
+      tree tem = valueize (op);
+      if (tem)
+	return tem;
+    }
+  return op;
+}
+
+
+/* Return true if pow(cst, x) should be optimized into exp(log(cst) * x).
+   As a workaround for SPEC CPU2017 628.pop2_s, don't do it if arg0
+   is an exact integer, arg1 = phi_res +/- cst1 and phi_res = PHI <cst2, ...>
+   where cst2 +/- cst1 is an exact integer, because then pow (arg0, arg1)
+   will likely be exact, while exp (log (arg0) * arg1) might be not.
+   Also don't do it if arg1 is phi_res above and cst2 is an exact integer.  */
+
+static bool
+optimize_pow_to_exp (tree arg0, tree arg1)
+{
+  gcc_assert (TREE_CODE (arg0) == REAL_CST);
+  if (!real_isinteger (TREE_REAL_CST_PTR (arg0), TYPE_MODE (TREE_TYPE (arg0))))
+    return true;
+
+  if (TREE_CODE (arg1) != SSA_NAME)
+    return true;
+
+  gimple *def = SSA_NAME_DEF_STMT (arg1);
+  gphi *phi = dyn_cast <gphi *> (def);
+  tree cst1 = NULL_TREE;
+  enum tree_code code = ERROR_MARK;
+  if (!phi)
+    {
+      if (!is_gimple_assign (def))
+	return true;
+      code = gimple_assign_rhs_code (def);
+      switch (code)
+	{
+	case PLUS_EXPR:
+	case MINUS_EXPR:
+	  break;
+	default:
+	  return true;
+	}
+      if (TREE_CODE (gimple_assign_rhs1 (def)) != SSA_NAME
+	  || TREE_CODE (gimple_assign_rhs2 (def)) != REAL_CST)
+	return true;
+
+      cst1 = gimple_assign_rhs2 (def);
+
+      phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def)));
+      if (!phi)
+	return true;
+    }
+
+  tree cst2 = NULL_TREE;
+  int n = gimple_phi_num_args (phi);
+  for (int i = 0; i < n; i++)
+    {
+      tree arg = PHI_ARG_DEF (phi, i);
+      if (TREE_CODE (arg) != REAL_CST)
+	continue;
+      else if (cst2 == NULL_TREE)
+	cst2 = arg;
+      else if (!operand_equal_p (cst2, arg, 0))
+	return true;
+    }
+
+  if (cst1 && cst2)
+    cst2 = const_binop (code, TREE_TYPE (cst2), cst2, cst1);
+  if (cst2
+      && TREE_CODE (cst2) == REAL_CST
+      && real_isinteger (TREE_REAL_CST_PTR (cst2),
+			 TYPE_MODE (TREE_TYPE (cst2))))
+    return false;
+  return true;
+}
diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c
index 414007ec1f9..f6cffedbc2f 100644
--- a/gcc/gimple-match-head.c
+++ b/gcc/gimple-match-head.c
@@ -41,35 +41,25 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimplify.h"
 #include "optabs-tree.h"
 #include "tree-eh.h"
+#include "gimple-match-head-common.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 (gimple_match_op *, gimple_seq *, tree (*)(tree),
+extern bool gimple_simplify_generated (gimple_match_op *, gimple_seq *, tree (*)(tree),
 			     code_helper, tree, tree);
-static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
+extern bool gimple_simplify_generated (gimple_match_op *, gimple_seq *, tree (*)(tree),
 			     code_helper, tree, tree, tree);
-static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
+extern bool gimple_simplify_generated (gimple_match_op *, gimple_seq *, tree (*)(tree),
 			     code_helper, tree, tree, tree, tree);
-static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
+extern bool gimple_simplify_generated (gimple_match_op *, gimple_seq *, tree (*)(tree),
 			     code_helper, tree, tree, tree, tree, tree);
-static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
+extern bool gimple_simplify_generated (gimple_match_op *, gimple_seq *, tree (*)(tree),
 			     code_helper, tree, tree, tree, tree, tree, tree);
 
-const unsigned int gimple_match_op::MAX_NUM_OPS;
-
-/* Return whether T is a constant that we'll dispatch to fold to
-   evaluate fully constant expressions.  */
 
-static inline bool
-constant_for_folding (tree t)
-{
-  return (CONSTANT_CLASS_P (t)
-	  /* The following is only interesting to string builtins.  */
-	  || (TREE_CODE (t) == ADDR_EXPR
-	      && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST));
-}
+const unsigned int gimple_match_op::MAX_NUM_OPS;
 
 /* Try to convert conditional operation ORIG_OP into an IFN_COND_*
    operation.  Return true on success, storing the new operation in NEW_OP.  */
@@ -167,7 +157,7 @@ maybe_resimplify_conditional_op (gimple_seq *seq, gimple_match_op *res_op,
 }
 
 /* Helper that matches and simplifies the toplevel result from
-   a gimple_simplify run (where we don't want to build
+   a gimple_simplify_generated run (where we don't want to build
    a stmt in case it's used in in-place folding).  Replaces
    RES_OP with a simplified and/or canonicalized result and
    returns whether any change was made.  */
@@ -211,7 +201,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,
+  if (gimple_simplify_generated (&res_op2, seq, valueize,
 		       res_op->code, res_op->type, res_op->ops[0]))
     {
       --depth;
@@ -227,7 +217,7 @@ gimple_resimplify1 (gimple_seq *seq, gimple_match_op *res_op,
 }
 
 /* Helper that matches and simplifies the toplevel result from
-   a gimple_simplify run (where we don't want to build
+   a gimple_simplify_generated run (where we don't want to build
    a stmt in case it's used in in-place folding).  Replaces
    RES_OP with a simplified and/or canonicalized result and
    returns whether any change was made.  */
@@ -282,7 +272,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,
+  if (gimple_simplify_generated (&res_op2, seq, valueize,
 		       res_op->code, res_op->type,
 		       res_op->ops[0], res_op->ops[1]))
     {
@@ -299,7 +289,7 @@ gimple_resimplify2 (gimple_seq *seq, gimple_match_op *res_op,
 }
 
 /* Helper that matches and simplifies the toplevel result from
-   a gimple_simplify run (where we don't want to build
+   a gimple_simplify_generated run (where we don't want to build
    a stmt in case it's used in in-place folding).  Replaces
    RES_OP with a simplified and/or canonicalized result and
    returns whether any change was made.  */
@@ -353,7 +343,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,
+  if (gimple_simplify_generated (&res_op2, seq, valueize,
 		       res_op->code, res_op->type,
 		       res_op->ops[0], res_op->ops[1], res_op->ops[2]))
     {
@@ -370,7 +360,7 @@ gimple_resimplify3 (gimple_seq *seq, gimple_match_op *res_op,
 }
 
 /* Helper that matches and simplifies the toplevel result from
-   a gimple_simplify run (where we don't want to build
+   a gimple_simplify_generated run (where we don't want to build
    a stmt in case it's used in in-place folding).  Replaces
    RES_OP with a simplified and/or canonicalized result and
    returns whether any change was made.  */
@@ -393,7 +383,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,
+  if (gimple_simplify_generated (&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]))
@@ -411,7 +401,7 @@ gimple_resimplify4 (gimple_seq *seq, gimple_match_op *res_op,
 }
 
 /* Helper that matches and simplifies the toplevel result from
-   a gimple_simplify run (where we don't want to build
+   a gimple_simplify_generated run (where we don't want to build
    a stmt in case it's used in in-place folding).  Replaces
    RES_OP with a simplified and/or canonicalized result and
    returns whether any change was made.  */
@@ -423,7 +413,7 @@ gimple_resimplify5 (gimple_seq *seq, gimple_match_op *res_op,
   /* No constant folding is defined for five-operand functions.  */
 
   gimple_match_op res_op2 (*res_op);
-  if (gimple_simplify (&res_op2, seq, valueize,
+  if (gimple_simplify_generated (&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]))
@@ -616,7 +606,7 @@ gimple_simplify (enum tree_code code, tree type,
     }
 
   gimple_match_op res_op;
-  if (!gimple_simplify (&res_op, seq, valueize, code, type, op0))
+  if (!gimple_simplify_generated (&res_op, seq, valueize, code, type, op0))
     return NULL_TREE;
   return maybe_push_res_to_seq (&res_op, seq);
 }
@@ -648,7 +638,7 @@ gimple_simplify (enum tree_code code, tree type,
     }
 
   gimple_match_op res_op;
-  if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1))
+  if (!gimple_simplify_generated (&res_op, seq, valueize, code, type, op0, op1))
     return NULL_TREE;
   return maybe_push_res_to_seq (&res_op, seq);
 }
@@ -676,7 +666,7 @@ gimple_simplify (enum tree_code code, tree type,
     std::swap (op0, op1);
 
   gimple_match_op res_op;
-  if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1, op2))
+  if (!gimple_simplify_generated (&res_op, seq, valueize, code, type, op0, op1, op2))
     return NULL_TREE;
   return maybe_push_res_to_seq (&res_op, seq);
 }
@@ -696,7 +686,7 @@ gimple_simplify (combined_fn fn, tree type,
     }
 
   gimple_match_op res_op;
-  if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0))
+  if (!gimple_simplify_generated (&res_op, seq, valueize, fn, type, arg0))
     return NULL_TREE;
   return maybe_push_res_to_seq (&res_op, seq);
 }
@@ -717,7 +707,7 @@ gimple_simplify (combined_fn fn, tree type,
     }
 
   gimple_match_op res_op;
-  if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1))
+  if (!gimple_simplify_generated (&res_op, seq, valueize, fn, type, arg0, arg1))
     return NULL_TREE;
   return maybe_push_res_to_seq (&res_op, seq);
 }
@@ -739,29 +729,11 @@ gimple_simplify (combined_fn fn, tree type,
     }
 
   gimple_match_op res_op;
-  if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1, arg2))
+  if (!gimple_simplify_generated (&res_op, seq, valueize, fn, type, arg0, arg1, arg2))
     return NULL_TREE;
   return maybe_push_res_to_seq (&res_op, seq);
 }
 
-/* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
-   VALUEIZED to true if valueization changed OP.  */
-
-static inline tree
-do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
-{
-  if (valueize && TREE_CODE (op) == SSA_NAME)
-    {
-      tree tem = valueize (op);
-      if (tem && tem != op)
-	{
-	  op = tem;
-	  valueized = true;
-	}
-    }
-  return op;
-}
-
 /* If RES_OP is a call to a conditional internal function, try simplifying
    the associated unconditional operation and using the result to build
    a new conditional operation.  For example, if RES_OP is:
@@ -1019,140 +991,3 @@ gimple_simplify (gimple *stmt, gimple_match_op *res_op, gimple_seq *seq,
 
   return false;
 }
-
-
-/* Helper for the autogenerated code, valueize OP.  */
-
-inline tree
-do_valueize (tree (*valueize)(tree), tree op)
-{
-  if (valueize && TREE_CODE (op) == SSA_NAME)
-    {
-      tree tem = valueize (op);
-      if (tem)
-	return tem;
-    }
-  return op;
-}
-
-/* Helper for the autogenerated code, get at the definition of NAME when
-   VALUEIZE allows that.  */
-
-inline gimple *
-get_def (tree (*valueize)(tree), tree name)
-{
-  if (valueize && ! valueize (name))
-    return NULL;
-  return SSA_NAME_DEF_STMT (name);
-}
-
-/* Routine to determine if the types T1 and T2 are effectively
-   the same for GIMPLE.  If T1 or T2 is not a type, the test
-   applies to their TREE_TYPE.  */
-
-static inline bool
-types_match (tree t1, tree t2)
-{
-  if (!TYPE_P (t1))
-    t1 = TREE_TYPE (t1);
-  if (!TYPE_P (t2))
-    t2 = TREE_TYPE (t2);
-
-  return types_compatible_p (t1, t2);
-}
-
-/* Return if T has a single use.  For GIMPLE, we also allow any
-   non-SSA_NAME (ie constants) and zero uses to cope with uses
-   that aren't linked up yet.  */
-
-static inline bool
-single_use (tree t)
-{
-  return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t);
-}
-
-/* Return true if math operations should be canonicalized,
-   e.g. sqrt(sqrt(x)) -> pow(x, 0.25).  */
-
-static inline bool
-canonicalize_math_p ()
-{
-  return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
-}
-
-/* Return true if math operations that are beneficial only after
-   vectorization should be canonicalized.  */
-
-static inline bool
-canonicalize_math_after_vectorization_p ()
-{
-  return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0;
-}
-
-/* Return true if pow(cst, x) should be optimized into exp(log(cst) * x).
-   As a workaround for SPEC CPU2017 628.pop2_s, don't do it if arg0
-   is an exact integer, arg1 = phi_res +/- cst1 and phi_res = PHI <cst2, ...>
-   where cst2 +/- cst1 is an exact integer, because then pow (arg0, arg1)
-   will likely be exact, while exp (log (arg0) * arg1) might be not.
-   Also don't do it if arg1 is phi_res above and cst2 is an exact integer.  */
-
-static bool
-optimize_pow_to_exp (tree arg0, tree arg1)
-{
-  gcc_assert (TREE_CODE (arg0) == REAL_CST);
-  if (!real_isinteger (TREE_REAL_CST_PTR (arg0), TYPE_MODE (TREE_TYPE (arg0))))
-    return true;
-
-  if (TREE_CODE (arg1) != SSA_NAME)
-    return true;
-
-  gimple *def = SSA_NAME_DEF_STMT (arg1);
-  gphi *phi = dyn_cast <gphi *> (def);
-  tree cst1 = NULL_TREE;
-  enum tree_code code = ERROR_MARK;
-  if (!phi)
-    {
-      if (!is_gimple_assign (def))
-	return true;
-      code = gimple_assign_rhs_code (def);
-      switch (code)
-	{
-	case PLUS_EXPR:
-	case MINUS_EXPR:
-	  break;
-	default:
-	  return true;
-	}
-      if (TREE_CODE (gimple_assign_rhs1 (def)) != SSA_NAME
-	  || TREE_CODE (gimple_assign_rhs2 (def)) != REAL_CST)
-	return true;
-
-      cst1 = gimple_assign_rhs2 (def);
-
-      phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def)));
-      if (!phi)
-	return true;
-    }
-
-  tree cst2 = NULL_TREE;
-  int n = gimple_phi_num_args (phi);
-  for (int i = 0; i < n; i++)
-    {
-      tree arg = PHI_ARG_DEF (phi, i);
-      if (TREE_CODE (arg) != REAL_CST)
-	continue;
-      else if (cst2 == NULL_TREE)
-	cst2 = arg;
-      else if (!operand_equal_p (cst2, arg, 0))
-	return true;
-    }
-
-  if (cst1 && cst2)
-    cst2 = const_binop (code, TREE_TYPE (cst2), cst2, cst1);
-  if (cst2
-      && TREE_CODE (cst2) == REAL_CST
-      && real_isinteger (TREE_REAL_CST_PTR (cst2),
-			 TYPE_MODE (TREE_TYPE (cst2))))
-    return false;
-  return true;
-}
diff --git a/gcc/splitter.cc b/gcc/splitter.cc
new file mode 100644
index 00000000000..528d814b9a9
--- /dev/null
+++ b/gcc/splitter.cc
@@ -0,0 +1,357 @@
+#include <sstream>
+#include <string>
+#include <fstream>
+#include <vector>
+#include <map>
+#include <algorithm>
+
+#include <iostream>
+#include <list>
+#include <stack>
+
+#define NIL -1
+
+using namespace std;
+
+// A class that represents an directed graph
+class Graph
+{
+    int V;    // No. of vertices
+    list<int> *adj;    // A dynamic array of adjacency lists
+ 
+    // A Recursive DFS based function used by SCC()
+    void SCCUtil(int u, int disc[], int low[],
+                 stack<int> *st, bool stackMember[]);
+public:
+    Graph(int V);   // Constructor
+    void addEdge(int v, int w);   // function to add an edge to graph
+    void SCC();    // prints strongly connected components
+
+    vector<vector<int>> components;
+};
+ 
+Graph::Graph(int V)
+{
+    this->V = V;
+    adj = new list<int>[V];
+}
+ 
+void Graph::addEdge(int v, int w)
+{
+    adj[v].push_back(w);
+}
+ 
+// A recursive function that finds and prints strongly connected
+// components using DFS traversal
+// u --> The vertex to be visited next
+// disc[] --> Stores discovery times of visited vertices
+// low[] -- >> earliest visited vertex (the vertex with minimum
+//             discovery time) that can be reached from subtree
+//             rooted with current vertex
+// *st -- >> To store all the connected ancestors (could be part
+//           of SCC)
+// stackMember[] --> bit/index array for faster check whether
+//                  a node is in stack
+void Graph::SCCUtil(int u, int disc[], int low[], stack<int> *st,
+                    bool stackMember[])
+{
+    // A static variable is used for simplicity, we can avoid use
+    // of static variable by passing a pointer.
+    static int time = 0;
+ 
+    // Initialize discovery time and low value
+    disc[u] = low[u] = ++time;
+    st->push(u);
+    stackMember[u] = true;
+ 
+    // Go through all vertices adjacent to this
+    list<int>::iterator i;
+    for (i = adj[u].begin(); i != adj[u].end(); ++i)
+    {
+        int v = *i;  // v is current adjacent of 'u'
+ 
+        // If v is not visited yet, then recur for it
+        if (disc[v] == -1)
+        {
+            SCCUtil(v, disc, low, st, stackMember);
+ 
+            // Check if the subtree rooted with 'v' has a
+            // connection to one of the ancestors of 'u'
+            // Case 1 (per above discussion on Disc and Low value)
+            low[u]  = min(low[u], low[v]);
+        }
+ 
+        // Update low value of 'u' only of 'v' is still in stack
+        // (i.e. it's a back edge, not cross edge).
+        // Case 2 (per above discussion on Disc and Low value)
+        else if (stackMember[v] == true)
+            low[u]  = min(low[u], disc[v]);
+    }
+ 
+    // head node found, pop the stack and print an SCC
+    int w = 0;  // To store stack extracted vertices
+    if (low[u] == disc[u])
+    {
+	vector<int> component;
+        while (st->top() != u)
+        {
+            w = (int) st->top();
+	    component.push_back (w);
+            stackMember[w] = false;
+            st->pop();
+        }
+        w = (int) st->top();
+	component.push_back (w);
+	components.push_back (component);
+        stackMember[w] = false;
+        st->pop();
+    }
+}
+ 
+// The function to do DFS traversal. It uses SCCUtil()
+void Graph::SCC()
+{
+    int *disc = new int[V];
+    int *low = new int[V];
+    bool *stackMember = new bool[V];
+    stack<int> *st = new stack<int>();
+ 
+    // Initialize disc and low, and stackMember arrays
+    for (int i = 0; i < V; i++)
+    {
+        disc[i] = NIL;
+        low[i] = NIL;
+        stackMember[i] = false;
+    }
+ 
+    // Call the recursive helper function to find strongly
+    // connected components in DFS tree with vertex 'i'
+    for (int i = 0; i < V; i++)
+        if (disc[i] == NIL)
+            SCCUtil(i, disc, low, st, stackMember);
+}
+
+using namespace std;
+
+struct function_entry
+{
+  function_entry (string name, unsigned lineno_start, unsigned id):
+    m_name (name), m_lineno_start (lineno_start), m_id (id),
+    m_callees ()
+  {}
+
+  unsigned get_loc ()
+  {
+    return m_lineno_end - m_lineno_start;
+  }
+
+  string m_name;
+  unsigned m_lineno_start;
+  unsigned m_lineno_end;
+  unsigned m_id;
+  vector<unsigned> m_callees;
+};
+
+map<string, unsigned> fn_to_index_map; 
+vector<function_entry *> functions;
+vector<string> lines;
+
+static unsigned
+get_id_for_fname (string fname)
+{  
+  map<string, unsigned>::iterator it = fn_to_index_map.find (fname);
+  if (it != fn_to_index_map.end ())
+    return it->second;
+  else
+    {
+      unsigned id = fn_to_index_map.size ();
+      fn_to_index_map[fname] = id;
+      return id;
+    }
+}
+
+struct function_component
+{
+  function_component (vector<int> function_ids):
+    m_function_ids (function_ids)
+  {}
+
+  void print()
+  {
+    for (unsigned i = 0; i < m_function_ids.size (); i++)
+      printf ("%s ", functions[m_function_ids[i]]->m_name.c_str ());
+    printf ("\n");
+  }
+
+  unsigned get_total_loc ()
+    {
+      unsigned loc = 0;
+      for (unsigned i = 0; i < m_function_ids.size (); i++)
+	loc += functions[m_function_ids[i]]->get_loc ();
+      return loc;
+    }
+
+  void write (ofstream &s)
+    {
+      sort (m_function_ids.begin (), m_function_ids.end ());
+      for (unsigned i = 0; i < m_function_ids.size (); i++)
+	{
+	  function_entry *f = functions[m_function_ids[i]];
+	  for (unsigned j = f->m_lineno_start; j <= f->m_lineno_end; j++)
+	    s << lines[j] << endl;
+	  s << endl;
+	}
+    }
+
+  vector<int> m_function_ids;
+};
+
+bool component_size_cmp (function_component *a, function_component *b)
+{
+  return a->get_total_loc () < b->get_total_loc ();
+}
+
+vector<function_component *> components;
+
+int
+main (int argc, char **argv)
+{
+  if (argc != 2)
+    return -1;
+
+  string type (argv[1]);
+
+  ifstream infile(type + "-match.c");
+  ofstream header(type + "-match-header.c");
+  ofstream footer(type + "-match-part-footer.c");
+  footer << "#include \"" << type << "-match-header.c\"" << endl;
+
+  string line;
+  unsigned lineno = 0;
+  bool in_split = false;
+  bool header_done = false;
+
+  while (getline(infile, line))
+    {
+      string fnbegin ("// split-fn-begin:");
+      string fnend ("// split-fn-end");
+      string call ("// call-fn:");
+      lines.push_back (line);
+
+      if (line.find(fnbegin) != string::npos)
+	{
+	  in_split = true;
+	  header_done = true;
+	  string fname = line.substr (fnbegin.length ());
+	  functions.push_back (new function_entry (fname, lineno,
+					     get_id_for_fname (fname)));
+	}
+      else if (line.find (fnend) != string::npos)
+	{
+	  functions.back ()->m_lineno_end = lineno;
+	  in_split = false;
+	}
+      else if (line.find (call) != string::npos)
+	{
+	  string fname = line.substr (call.length ());
+	  functions.back ()->m_callees.push_back (get_id_for_fname (fname));
+	}
+      else if (!in_split && !line.empty ())
+	{
+	  if (header_done)
+	    footer << line << endl;
+	  else
+	    header << line << endl;
+	}
+
+      lineno++;
+    }
+
+  /*
+  for (unsigned i = 0; i < functions.size (); i++)
+    {
+      function_entry *f = functions[i];
+      fprintf (stderr, "%d %s: %d\n",
+	       f->m_lineno_end - f->m_lineno_start,
+	       f->m_name.c_str (), f->m_callees.size ());
+    }
+    */
+
+  /* Create graph and compute SCC.  */
+  Graph g (functions.size ());
+  for (unsigned i = 0; i < functions.size (); i++)
+    {
+      function_entry *f = functions[i];
+      for (unsigned j = 0; j < f->m_callees.size (); j++)
+	{
+	  g.addEdge (f->m_id, f->m_callees[j]);
+	  g.addEdge (f->m_callees[j], f->m_id);
+	}
+    }
+  g.SCC ();
+
+  for (unsigned i = 0; i < g.components.size (); i++)
+    components.push_back (new function_component(g.components[i]));
+
+  sort (components.begin (), components.end (), component_size_cmp);
+
+  unsigned total_loc = 0;
+  for (unsigned i = 0; i < components.size (); i++)
+    {
+//      components[i]->print();
+      total_loc += components[i]->get_total_loc ();
+    }
+
+  printf ("Total # of functions: %ld, total LOC: %u\n", functions.size (),
+	  total_loc);
+
+  vector<vector<function_component *>> groups;
+
+  unsigned parts = 4;
+  unsigned component_size = total_loc / parts;
+  if (components.back ()->get_total_loc () > component_size)
+    component_size = components.back ()->get_total_loc ();
+
+  for (unsigned i = 0; i < parts; i++)
+    {
+      unsigned space = component_size;
+      vector<function_component *> group;
+      for (int j = components.size () - 1; j >= 0; j--)
+	{
+	  function_component *c = components[j];
+	  unsigned loc = c->get_total_loc ();
+	  if (space >= loc || (i == parts - 1))
+	    {
+//	      fprintf (stderr, "adding %d to group %d\n", loc, i);
+	      components.erase (components.begin () + j);
+	      space -= loc;
+	      group.push_back (c);
+	    }
+	}
+
+      groups.push_back (group);
+    }
+
+  for (unsigned i = 0; i < groups.size (); i++)
+    {
+      string name = type + "-match-part-" + std::to_string (i) + ".c";
+      ofstream s (name);
+      s << "#include \"" << type << "-match-header.c\"" << endl;
+
+      unsigned loc = 0;
+      for (unsigned j = 0; j < groups[i].size (); j++)
+	{
+	  function_component *c = groups[i][j];
+	  loc += c->get_total_loc ();
+	  c->write (s);
+	}
+      s.close ();
+
+      fprintf (stderr, "written %d LOC functions to %s\n", loc, name.c_str ());
+    }
+
+  header.close ();
+  footer.close ();
+
+  return 0;
+}
-- 
2.18.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2018-09-04 15:07               ` Martin Liška
@ 2018-09-10 11:43                 ` Martin Liška
  2019-04-29 15:21                   ` Martin Liška
  2019-04-29 14:41                 ` Martin Liška
  1 sibling, 1 reply; 27+ messages in thread
From: Martin Liška @ 2018-09-10 11:43 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

On 09/04/2018 05:07 PM, Martin Liška wrote:
> - in order to achieve real speed up we need to split also other generated (and also dwarf2out.c, i386.c, ..) files:
> here I'm most concerned about insn-recog.c, which can't be split the same way without ending up with a single huge SCC component.

About the insn-recog.c file: all functions are static and using SCC one ends
up with all functions in one component. In order to split the callgraph one
needs to promote some functions to be extern and then split would be possible.
In order to do that we'll probably need to teach splitter how to do partitioning
based on minimal number of edges to be removed.

I need to inspire in lto_balanced_map, or is there some simple algorithm I can start with?

Martin

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2018-09-04 15:07               ` Martin Liška
  2018-09-10 11:43                 ` Martin Liška
@ 2019-04-29 14:41                 ` Martin Liška
  1 sibling, 0 replies; 27+ messages in thread
From: Martin Liška @ 2019-04-29 14:41 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

On 9/4/18 5:07 PM, Martin Liška wrote:
> On 09/03/2018 04:43 PM, Richard Biener wrote:
>> On Mon, 3 Sep 2018, Martin Liška wrote:
>>
>>> On 09/03/2018 04:00 PM, Richard Biener wrote:
>>>> 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.
>> ...
>>>>>>>> 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.
>>>
>>> I see! Note that shrinking gimple-match.o 4 times will be probably sufficient for general
>>> speed up:
>>> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43440
>>>
>>>>
>>>> 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
>>>
>>> That would be my plan, genmatch can mark in C comments function that can be partitioned
>>> and callgraph of these functions.
>>>
>>>> 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 ;))
>>>
>>> ... and a C++ splitter can do the rest: read content, do SCC, split to N parts
>>> and stream out.
>>>
>>> I can work on that. Questionable is still Makefile integration of such 
>>> parallelism?
>>
>> Well, just hard-code the number of pieces and thus the pices to
>> compile in the end...
>>
>> Of course we shouldn't add any additional build dependencies
>> (a "C++ splitter").  Adding additional annotation to the genmatch
>> generated sources may be OK but then eventually doing everything in
>> genmatch isn't too complicated (putting aside that # of lines metric...).
>>
>> Richard.
>>
> 
> Hi.
> 
> There's working solution for {gimple,generic}-match.c. It introduces splitter.cc which
> parses annotated generated files and split it according to call graph provided by annotations.
> Currently I copied a SCC implementation as graphds.c has quite some dependencies (xrealloc, bitmap,..).
> Questionable how to reduce the dependencies?
> 
> For gimple-match.c the biggest SCC component contains about 1/4 LOC, which means maximal reasonable number
> of parts is equal to 4. Doing that the biggest component is compiled with -O2 14.5s, which the original gimple-match.c
> 50.0s. That sounds promising:
> 
>  l gimple-match-part*.c
> -rw-r--r-- 1 marxin users 791442 Sep  4 17:02 gimple-match-part-0.c
> -rw-r--r-- 1 marxin users 748610 Sep  4 17:02 gimple-match-part-1.c
> -rw-r--r-- 1 marxin users 783749 Sep  4 17:02 gimple-match-part-2.c
> -rw-r--r-- 1 marxin users 828990 Sep  4 17:02 gimple-match-part-3.c
> -rw-r--r-- 1 marxin users 103130 Sep  4 17:02 gimple-match-part-footer.c
> 
> for generic-match.c:
> 
> l generic-match-part*.c
> -rw-r--r-- 1 marxin users 528712 Sep  4 17:02 generic-match-part-0.c
> -rw-r--r-- 1 marxin users 517120 Sep  4 17:02 generic-match-part-1.c
> -rw-r--r-- 1 marxin users 519777 Sep  4 17:02 generic-match-part-2.c
> -rw-r--r-- 1 marxin users 221971 Sep  4 17:02 generic-match-part-3.c
> -rw-r--r-- 1 marxin users  14596 Sep  4 17:02 generic-match-part-footer.c
> 
> There are some issues with functions that live in gimple-match-head.c, these
> should live in a header file the parts can include. I also renamed
> gimple_simplify function that live in gimple-match.c to gimple_simplify_generated
> as they clash with these that are in gimple-match-head.c.
> 
> There are still various questions:
> - how to make the split process optional, how to modify then Makefile?
> - SCC implementation should be shared with graphds.c
> - splitter.cc should be cleaned up
> - in order to achieve real speed up we need to split also other generated (and also dwarf2out.c, i386.c, ..) files:
> here I'm most concerned about insn-recog.c, which can't be split the same way without ending up with a single huge SCC component.
> Ideas what to do with that file?
> 
> Thoughts?
> 
> Martin
> 

Long time, no see. Richi, can we please return to this in next stage1?

Martin

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2018-09-10 11:43                 ` Martin Liška
@ 2019-04-29 15:21                   ` Martin Liška
  2019-05-02 13:18                     ` Richard Biener
  0 siblings, 1 reply; 27+ messages in thread
From: Martin Liška @ 2019-04-29 15:21 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches, Richard Sandiford

On 9/10/18 1:43 PM, Martin Liška wrote:
> On 09/04/2018 05:07 PM, Martin Liška wrote:
>> - in order to achieve real speed up we need to split also other generated (and also dwarf2out.c, i386.c, ..) files:
>> here I'm most concerned about insn-recog.c, which can't be split the same way without ending up with a single huge SCC component.
> 
> About the insn-recog.c file: all functions are static and using SCC one ends
> up with all functions in one component. In order to split the callgraph one
> needs to promote some functions to be extern and then split would be possible.
> In order to do that we'll probably need to teach splitter how to do partitioning
> based on minimal number of edges to be removed.
> 
> I need to inspire in lto_balanced_map, or is there some simple algorithm I can start with?
> 
> Martin
> 

I'm adding here Richard Sandiford as he wrote majority of gcc/genrecog.c file.
As mentioned, I'm seeking for a way how to split the generated file. Or how
to learn the generator to process a reasonable splitting.

Thanks,
Martin

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2019-04-29 15:21                   ` Martin Liška
@ 2019-05-02 13:18                     ` Richard Biener
  2019-05-02 17:00                       ` Segher Boessenkool
  2019-05-06 12:56                       ` Martin Liška
  0 siblings, 2 replies; 27+ messages in thread
From: Richard Biener @ 2019-05-02 13:18 UTC (permalink / raw)
  To: Martin Liška; +Cc: gcc-patches, Richard Sandiford

[-- Attachment #1: Type: text/plain, Size: 1829 bytes --]

On Mon, 29 Apr 2019, Martin Liška wrote:

> On 9/10/18 1:43 PM, Martin Liška wrote:
> > On 09/04/2018 05:07 PM, Martin Liška wrote:
> >> - in order to achieve real speed up we need to split also other generated (and also dwarf2out.c, i386.c, ..) files:
> >> here I'm most concerned about insn-recog.c, which can't be split the same way without ending up with a single huge SCC component.
> > 
> > About the insn-recog.c file: all functions are static and using SCC one ends
> > up with all functions in one component. In order to split the callgraph one
> > needs to promote some functions to be extern and then split would be possible.
> > In order to do that we'll probably need to teach splitter how to do partitioning
> > based on minimal number of edges to be removed.
> > 
> > I need to inspire in lto_balanced_map, or is there some simple algorithm I can start with?
> > 
> > Martin
> > 
> 
> I'm adding here Richard Sandiford as he wrote majority of gcc/genrecog.c file.
> As mentioned, I'm seeking for a way how to split the generated file. Or how
> to learn the generator to process a reasonable splitting.

Somewhen earlier this year I've done the experiment with using
a compile with -flto -fno-fat-lto-objects and a link
via -flto -r -flinker-output=rel into the object file.  This cut
compile-time more than in half with less maintainance overhead.

Adding other files to this handling looks trivial as well, as well
as conditionalizing it (I'd probably not want this for devel builds).

It might be interesting to optimize this a bit as well by somehow
merging the compile and WPA stages, thus special-casing single TU
WPA input in a similar way as we (still) have -flto-partition=none.

That said, re-doing the measurement is probably interesting (as
applying to other cases like insn-recog.c).

Richard.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2019-05-02 13:18                     ` Richard Biener
@ 2019-05-02 17:00                       ` Segher Boessenkool
  2019-05-02 17:41                         ` Richard Biener
  2019-05-06 12:56                       ` Martin Liška
  1 sibling, 1 reply; 27+ messages in thread
From: Segher Boessenkool @ 2019-05-02 17:00 UTC (permalink / raw)
  To: Richard Biener; +Cc: Martin Liška, gcc-patches, Richard Sandiford

On Thu, May 02, 2019 at 03:18:00PM +0200, Richard Biener wrote:
> Somewhen earlier this year I've done the experiment with using
> a compile with -flto -fno-fat-lto-objects and a link
> via -flto -r -flinker-output=rel into the object file.  This cut
> compile-time more than in half with less maintainance overhead.
> 
> Adding other files to this handling looks trivial as well, as well
> as conditionalizing it (I'd probably not want this for devel builds).

But we want devel builds to be a lot faster than they are now :-/


Segher

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2019-05-02 17:00                       ` Segher Boessenkool
@ 2019-05-02 17:41                         ` Richard Biener
  2019-05-02 18:14                           ` Segher Boessenkool
  0 siblings, 1 reply; 27+ messages in thread
From: Richard Biener @ 2019-05-02 17:41 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Martin Liška, gcc-patches, Richard Sandiford

On May 2, 2019 7:00:16 PM GMT+02:00, Segher Boessenkool <segher@kernel.crashing.org> wrote:
>On Thu, May 02, 2019 at 03:18:00PM +0200, Richard Biener wrote:
>> Somewhen earlier this year I've done the experiment with using
>> a compile with -flto -fno-fat-lto-objects and a link
>> via -flto -r -flinker-output=rel into the object file.  This cut
>> compile-time more than in half with less maintainance overhead.
>> 
>> Adding other files to this handling looks trivial as well, as well
>> as conditionalizing it (I'd probably not want this for devel builds).
>
>But we want devel builds to be a lot faster than they are now :-/

My devel build is -O0 non-bootstrapped and building the files after dependency changes is fast enough. It's the bootstraps that matter, no? 

Richard. 

>
>Segher

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2019-05-02 17:41                         ` Richard Biener
@ 2019-05-02 18:14                           ` Segher Boessenkool
  2019-05-02 19:04                             ` Richard Biener
  0 siblings, 1 reply; 27+ messages in thread
From: Segher Boessenkool @ 2019-05-02 18:14 UTC (permalink / raw)
  To: Richard Biener; +Cc: Martin Liška, gcc-patches, Richard Sandiford

On Thu, May 02, 2019 at 07:41:18PM +0200, Richard Biener wrote:
> On May 2, 2019 7:00:16 PM GMT+02:00, Segher Boessenkool <segher@kernel.crashing.org> wrote:
> >On Thu, May 02, 2019 at 03:18:00PM +0200, Richard Biener wrote:
> >> Somewhen earlier this year I've done the experiment with using
> >> a compile with -flto -fno-fat-lto-objects and a link
> >> via -flto -r -flinker-output=rel into the object file.  This cut
> >> compile-time more than in half with less maintainance overhead.
> >> 
> >> Adding other files to this handling looks trivial as well, as well
> >> as conditionalizing it (I'd probably not want this for devel builds).
> >
> >But we want devel builds to be a lot faster than they are now :-/
> 
> My devel build is -O0 non-bootstrapped and building the files after dependency changes is fast enough. It's the bootstraps that matter, no? 

Yes, I bootstrap most of the time.  For development.  It catches a *lot*
of problems progressive builds do not.  (Those are plenty fast already of
course, -O0 or not).


Segher

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2019-05-02 18:14                           ` Segher Boessenkool
@ 2019-05-02 19:04                             ` Richard Biener
  2019-05-06 12:59                               ` Martin Liška
  0 siblings, 1 reply; 27+ messages in thread
From: Richard Biener @ 2019-05-02 19:04 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: Martin Liška, gcc-patches, Richard Sandiford

On May 2, 2019 8:14:46 PM GMT+02:00, Segher Boessenkool <segher@kernel.crashing.org> wrote:
>On Thu, May 02, 2019 at 07:41:18PM +0200, Richard Biener wrote:
>> On May 2, 2019 7:00:16 PM GMT+02:00, Segher Boessenkool
><segher@kernel.crashing.org> wrote:
>> >On Thu, May 02, 2019 at 03:18:00PM +0200, Richard Biener wrote:
>> >> Somewhen earlier this year I've done the experiment with using
>> >> a compile with -flto -fno-fat-lto-objects and a link
>> >> via -flto -r -flinker-output=rel into the object file.  This cut
>> >> compile-time more than in half with less maintainance overhead.
>> >> 
>> >> Adding other files to this handling looks trivial as well, as well
>> >> as conditionalizing it (I'd probably not want this for devel
>builds).
>> >
>> >But we want devel builds to be a lot faster than they are now :-/
>> 
>> My devel build is -O0 non-bootstrapped and building the files after
>dependency changes is fast enough. It's the bootstraps that matter, no?
>
>
>Yes, I bootstrap most of the time.  For development.  It catches a
>*lot*
>of problems progressive builds do not.  (Those are plenty fast already
>of
>course, -O0 or not).

So we'd catch it there but disable by default for stage 1 since we probably do not want to rely on the host compiler. 

Richard. 

>
>Segher

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2019-05-02 13:18                     ` Richard Biener
  2019-05-02 17:00                       ` Segher Boessenkool
@ 2019-05-06 12:56                       ` Martin Liška
  2019-05-06 13:32                         ` Richard Biener
  1 sibling, 1 reply; 27+ messages in thread
From: Martin Liška @ 2019-05-06 12:56 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches, Richard Sandiford

On 5/2/19 3:18 PM, Richard Biener wrote:
> On Mon, 29 Apr 2019, Martin Liška wrote:
> 
>> On 9/10/18 1:43 PM, Martin Liška wrote:
>>> On 09/04/2018 05:07 PM, Martin Liška wrote:
>>>> - in order to achieve real speed up we need to split also other generated (and also dwarf2out.c, i386.c, ..) files:
>>>> here I'm most concerned about insn-recog.c, which can't be split the same way without ending up with a single huge SCC component.
>>>
>>> About the insn-recog.c file: all functions are static and using SCC one ends
>>> up with all functions in one component. In order to split the callgraph one
>>> needs to promote some functions to be extern and then split would be possible.
>>> In order to do that we'll probably need to teach splitter how to do partitioning
>>> based on minimal number of edges to be removed.
>>>
>>> I need to inspire in lto_balanced_map, or is there some simple algorithm I can start with?
>>>
>>> Martin
>>>
>>
>> I'm adding here Richard Sandiford as he wrote majority of gcc/genrecog.c file.
>> As mentioned, I'm seeking for a way how to split the generated file. Or how
>> to learn the generator to process a reasonable splitting.
> 
> Somewhen earlier this year I've done the experiment with using
> a compile with -flto -fno-fat-lto-objects

-fno-fat-lto-objects is default, isn't it?

> and a link
> via -flto -r -flinker-output=rel into the object file.  This cut
> compile-time more than in half with less maintainance overhead.

Can you please provide exact command line how to do that?

> 
> Adding other files to this handling looks trivial as well, as well
> as conditionalizing it (I'd probably not want this for devel builds).
> 
> It might be interesting to optimize this a bit as well by somehow
> merging the compile and WPA stages, thus special-casing single TU
> WPA input in a similar way as we (still) have -flto-partition=none.
> 
> That said, re-doing the measurement is probably interesting (as
> applying to other cases like insn-recog.c).
> 
> Richard.
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2019-05-02 19:04                             ` Richard Biener
@ 2019-05-06 12:59                               ` Martin Liška
  2019-05-06 13:36                                 ` Richard Biener
  0 siblings, 1 reply; 27+ messages in thread
From: Martin Liška @ 2019-05-06 12:59 UTC (permalink / raw)
  To: Richard Biener, Segher Boessenkool; +Cc: gcc-patches, Richard Sandiford

On 5/2/19 9:04 PM, Richard Biener wrote:
> On May 2, 2019 8:14:46 PM GMT+02:00, Segher Boessenkool <segher@kernel.crashing.org> wrote:
>> On Thu, May 02, 2019 at 07:41:18PM +0200, Richard Biener wrote:
>>> On May 2, 2019 7:00:16 PM GMT+02:00, Segher Boessenkool
>> <segher@kernel.crashing.org> wrote:
>>>> On Thu, May 02, 2019 at 03:18:00PM +0200, Richard Biener wrote:
>>>>> Somewhen earlier this year I've done the experiment with using
>>>>> a compile with -flto -fno-fat-lto-objects and a link
>>>>> via -flto -r -flinker-output=rel into the object file.  This cut
>>>>> compile-time more than in half with less maintainance overhead.
>>>>>
>>>>> Adding other files to this handling looks trivial as well, as well
>>>>> as conditionalizing it (I'd probably not want this for devel
>> builds).
>>>>
>>>> But we want devel builds to be a lot faster than they are now :-/
>>>
>>> My devel build is -O0 non-bootstrapped and building the files after
>> dependency changes is fast enough. It's the bootstraps that matter, no?
>>
>>
>> Yes, I bootstrap most of the time.  For development.  It catches a
>> *lot*
>> of problems progressive builds do not.  (Those are plenty fast already
>> of
>> course, -O0 or not).
> 
> So we'd catch it there but disable by default for stage 1 since we probably do not want to rely on the host compiler. 
> 
> Richard. 
> 
>>
>> Segher
> 

I'm interested in 2 scenarios:

1) fast non-bootstrap development build with -O2; typically I want to run a fraction of test-suite or
I want to install the compiler and run-time binaries; building the compiler with -O0 will result in terribly
slow build of run-time libraries

2) faster bootstrap on a massively parallel machine (64+ cores)

Martin

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2019-05-06 12:56                       ` Martin Liška
@ 2019-05-06 13:32                         ` Richard Biener
  2019-05-06 13:50                           ` Martin Liška
  0 siblings, 1 reply; 27+ messages in thread
From: Richard Biener @ 2019-05-06 13:32 UTC (permalink / raw)
  To: Martin Liška; +Cc: gcc-patches, Richard Sandiford

[-- Attachment #1: Type: text/plain, Size: 4721 bytes --]

On Mon, 6 May 2019, Martin Liška wrote:

> On 5/2/19 3:18 PM, Richard Biener wrote:
> > On Mon, 29 Apr 2019, Martin Liška wrote:
> > 
> >> On 9/10/18 1:43 PM, Martin Liška wrote:
> >>> On 09/04/2018 05:07 PM, Martin Liška wrote:
> >>>> - in order to achieve real speed up we need to split also other generated (and also dwarf2out.c, i386.c, ..) files:
> >>>> here I'm most concerned about insn-recog.c, which can't be split the same way without ending up with a single huge SCC component.
> >>>
> >>> About the insn-recog.c file: all functions are static and using SCC one ends
> >>> up with all functions in one component. In order to split the callgraph one
> >>> needs to promote some functions to be extern and then split would be possible.
> >>> In order to do that we'll probably need to teach splitter how to do partitioning
> >>> based on minimal number of edges to be removed.
> >>>
> >>> I need to inspire in lto_balanced_map, or is there some simple algorithm I can start with?
> >>>
> >>> Martin
> >>>
> >>
> >> I'm adding here Richard Sandiford as he wrote majority of gcc/genrecog.c file.
> >> As mentioned, I'm seeking for a way how to split the generated file. Or how
> >> to learn the generator to process a reasonable splitting.
> > 
> > Somewhen earlier this year I've done the experiment with using
> > a compile with -flto -fno-fat-lto-objects
> 
> -fno-fat-lto-objects is default, isn't it?

Where linker plugin support is detected, yes.

> > and a link
> > via -flto -r -flinker-output=rel into the object file.  This cut
> > compile-time more than in half with less maintainance overhead.
> 
> Can you please provide exact command line how to do that?

gcc t.c -o t.o -flto=8 -r -flinker-output=nolto-rel

there's an annoying warning:

cc1plus: warning: command line option ‘-flinker-output=nolto-rel’ is valid 
for LTO but not for C++

which can be avoided by splitting the above into a compile and
a separate LTO "link" step.  Using -Wl,-flinker-.... doesn't
work unfortunately (ld doesn't understand it).

Using installed GCC 9.1 compiling trunk gimple-match.c with -O2 -g
takes 58.7s while with the LTO trick it takes 23.3s (combined
CPU time is up to 96s).  That was with -flto=8 on a CPU with
4 physical and 8 logical cores.  As it includes -g it includes
the debug copy dance as well.

> bloaty gimple-match.o -- gimple-match.o.nolto
     VM SIZE                                                     FILE SIZE
 ++++++++++++++ GROWING                                       
++++++++++++++
  [ = ]       0 .rela.debug_info                              +3.62Mi   
+45%
  [ = ]       0 .rela.debug_ranges                             +161Ki  
+1.8%
  [ = ]       0 .debug_str                                    +95.8Ki   
+19%
  [ = ]       0 .rela.text                                    +77.6Ki   
+10%
  [ = ]       0 .debug_ranges                                 +58.9Ki  
+1.7%
  [ = ]       0 .symtab                                       +22.9Ki   
+68%
  [ = ]       0 .debug_abbrev                                 +21.1Ki  
+394%
  [ = ]       0 .strtab                                       +11.4Ki  
+9.5%
  +8.1% +5.34Ki .eh_frame                                     +5.34Ki  
+8.1%
   +84% +4.09Ki .rodata.str1.8                                +4.09Ki   
+84%
  [ = ]       0 .rela.text.unlikely                           +3.87Ki  
+1.0%
  [ = ]       0 .rela.debug_aranges                           +3.68Ki  
+872%
  [ = ]       0 .debug_aranges                                +3.02Ki 
+10e2%
   +42% +2.59Ki .rodata.str1.1                                +2.59Ki   
+42%
  +0.2% +2.41Ki [Other]                                       +2.45Ki  
+0.2%
  [ = ]       0 .rela.debug_line                              +2.09Ki   
+16%
  [ = ]       0 .rela.eh_frame                                +1.17Ki  
+4.3%
  [NEW] +1.09Ki .rodata._Z7get_defPFP9tree_nodeS0_ES0_.str1.8 +1.09Ki  
[NEW]
  [ = ]       0 .shstrtab                                        +784   
+44%
  [ = ]       0 [ELF Headers]                                    +768   
+16%
  [ = ]       0 .comment                                         +666 
+37e2%

 -------------- SHRINKING                                     
--------------
  [ = ]       0 .debug_line                                    -256Ki 
-17.3%
  [ = ]       0 .rela.debug_loc                               -73.6Ki  
-0.6%
  [ = ]       0 .debug_info                                   -63.4Ki  
-1.6%
  [ = ]       0 .debug_loc                                    -39.3Ki  
-0.6%

  +1.1% +15.5Ki TOTAL                                         +3.67Mi  
+7.8%

.debug_line probably shrinks because we drop columns with LTO.

Richard.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2019-05-06 12:59                               ` Martin Liška
@ 2019-05-06 13:36                                 ` Richard Biener
  2019-05-06 13:51                                   ` Martin Liška
  2019-05-06 15:10                                   ` Segher Boessenkool
  0 siblings, 2 replies; 27+ messages in thread
From: Richard Biener @ 2019-05-06 13:36 UTC (permalink / raw)
  To: Martin Liška; +Cc: Segher Boessenkool, gcc-patches, Richard Sandiford

[-- Attachment #1: Type: text/plain, Size: 2263 bytes --]

On Mon, 6 May 2019, Martin Liška wrote:

> On 5/2/19 9:04 PM, Richard Biener wrote:
> > On May 2, 2019 8:14:46 PM GMT+02:00, Segher Boessenkool <segher@kernel.crashing.org> wrote:
> >> On Thu, May 02, 2019 at 07:41:18PM +0200, Richard Biener wrote:
> >>> On May 2, 2019 7:00:16 PM GMT+02:00, Segher Boessenkool
> >> <segher@kernel.crashing.org> wrote:
> >>>> On Thu, May 02, 2019 at 03:18:00PM +0200, Richard Biener wrote:
> >>>>> Somewhen earlier this year I've done the experiment with using
> >>>>> a compile with -flto -fno-fat-lto-objects and a link
> >>>>> via -flto -r -flinker-output=rel into the object file.  This cut
> >>>>> compile-time more than in half with less maintainance overhead.
> >>>>>
> >>>>> Adding other files to this handling looks trivial as well, as well
> >>>>> as conditionalizing it (I'd probably not want this for devel
> >> builds).
> >>>>
> >>>> But we want devel builds to be a lot faster than they are now :-/
> >>>
> >>> My devel build is -O0 non-bootstrapped and building the files after
> >> dependency changes is fast enough. It's the bootstraps that matter, no?
> >>
> >>
> >> Yes, I bootstrap most of the time.  For development.  It catches a
> >> *lot*
> >> of problems progressive builds do not.  (Those are plenty fast already
> >> of
> >> course, -O0 or not).
> > 
> > So we'd catch it there but disable by default for stage 1 since we probably do not want to rely on the host compiler. 
> > 
> > Richard. 
> > 
> >>
> >> Segher
> > 
> 
> I'm interested in 2 scenarios:
> 
> 1) fast non-bootstrap development build with -O2; typically I want to run a fraction of test-suite or
> I want to install the compiler and run-time binaries; building the compiler with -O0 will result in terribly
> slow build of run-time libraries

That's already overall "fast", mostly dominated by runtime library build.

> 2) faster bootstrap on a massively parallel machine (64+ cores)

I guess for this we can also try to do LTO bootstap and
LTO-link libbackend itself.  LTO bootstrap is only slow because
we build everything 12 times.

I'm most interested in faster bootstrap on low-core machines
(4 to 6 physical cores), since that's what I am doing most of the time.
This is dominated by testing time, not bootstrap time.

Richard.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2019-05-06 13:32                         ` Richard Biener
@ 2019-05-06 13:50                           ` Martin Liška
  0 siblings, 0 replies; 27+ messages in thread
From: Martin Liška @ 2019-05-06 13:50 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches, Richard Sandiford

On 5/6/19 3:31 PM, Richard Biener wrote:
> On Mon, 6 May 2019, Martin Liška wrote:
> 
>> On 5/2/19 3:18 PM, Richard Biener wrote:
>>> On Mon, 29 Apr 2019, Martin Liška wrote:
>>>
>>>> On 9/10/18 1:43 PM, Martin Liška wrote:
>>>>> On 09/04/2018 05:07 PM, Martin Liška wrote:
>>>>>> - in order to achieve real speed up we need to split also other generated (and also dwarf2out.c, i386.c, ..) files:
>>>>>> here I'm most concerned about insn-recog.c, which can't be split the same way without ending up with a single huge SCC component.
>>>>>
>>>>> About the insn-recog.c file: all functions are static and using SCC one ends
>>>>> up with all functions in one component. In order to split the callgraph one
>>>>> needs to promote some functions to be extern and then split would be possible.
>>>>> In order to do that we'll probably need to teach splitter how to do partitioning
>>>>> based on minimal number of edges to be removed.
>>>>>
>>>>> I need to inspire in lto_balanced_map, or is there some simple algorithm I can start with?
>>>>>
>>>>> Martin
>>>>>
>>>>
>>>> I'm adding here Richard Sandiford as he wrote majority of gcc/genrecog.c file.
>>>> As mentioned, I'm seeking for a way how to split the generated file. Or how
>>>> to learn the generator to process a reasonable splitting.
>>>
>>> Somewhen earlier this year I've done the experiment with using
>>> a compile with -flto -fno-fat-lto-objects
>>
>> -fno-fat-lto-objects is default, isn't it?
> 
> Where linker plugin support is detected, yes.
> 
>>> and a link
>>> via -flto -r -flinker-output=rel into the object file.  This cut
>>> compile-time more than in half with less maintainance overhead.

Ah, -flinker-output=nolto-rel is new in GCC 9 release. That's why I was confused.

>>
>> Can you please provide exact command line how to do that?
> 
> gcc t.c -o t.o -flto=8 -r -flinker-output=nolto-rel
> 
> there's an annoying warning:
> 
> cc1plus: warning: command line option ‘-flinker-output=nolto-rel’ is valid 
> for LTO but not for C++
> 
> which can be avoided by splitting the above into a compile and
> a separate LTO "link" step.  Using -Wl,-flinker-.... doesn't
> work unfortunately (ld doesn't understand it).
> 
> Using installed GCC 9.1 compiling trunk gimple-match.c with -O2 -g
> takes 58.7s while with the LTO trick it takes 23.3s (combined
> CPU time is up to 96s).  That was with -flto=8 on a CPU with
> 4 physical and 8 logical cores.  As it includes -g it includes
> the debug copy dance as well.

That would be usable for the bootstrap on a massively parallel machine
where combined CPU time overhead won't be issue. I'll play with that a bit.

Martin

> 
>> bloaty gimple-match.o -- gimple-match.o.nolto
>      VM SIZE                                                     FILE SIZE
>  ++++++++++++++ GROWING                                       
> ++++++++++++++
>   [ = ]       0 .rela.debug_info                              +3.62Mi   
> +45%
>   [ = ]       0 .rela.debug_ranges                             +161Ki  
> +1.8%
>   [ = ]       0 .debug_str                                    +95.8Ki   
> +19%
>   [ = ]       0 .rela.text                                    +77.6Ki   
> +10%
>   [ = ]       0 .debug_ranges                                 +58.9Ki  
> +1.7%
>   [ = ]       0 .symtab                                       +22.9Ki   
> +68%
>   [ = ]       0 .debug_abbrev                                 +21.1Ki  
> +394%
>   [ = ]       0 .strtab                                       +11.4Ki  
> +9.5%
>   +8.1% +5.34Ki .eh_frame                                     +5.34Ki  
> +8.1%
>    +84% +4.09Ki .rodata.str1.8                                +4.09Ki   
> +84%
>   [ = ]       0 .rela.text.unlikely                           +3.87Ki  
> +1.0%
>   [ = ]       0 .rela.debug_aranges                           +3.68Ki  
> +872%
>   [ = ]       0 .debug_aranges                                +3.02Ki 
> +10e2%
>    +42% +2.59Ki .rodata.str1.1                                +2.59Ki   
> +42%
>   +0.2% +2.41Ki [Other]                                       +2.45Ki  
> +0.2%
>   [ = ]       0 .rela.debug_line                              +2.09Ki   
> +16%
>   [ = ]       0 .rela.eh_frame                                +1.17Ki  
> +4.3%
>   [NEW] +1.09Ki .rodata._Z7get_defPFP9tree_nodeS0_ES0_.str1.8 +1.09Ki  
> [NEW]
>   [ = ]       0 .shstrtab                                        +784   
> +44%
>   [ = ]       0 [ELF Headers]                                    +768   
> +16%
>   [ = ]       0 .comment                                         +666 
> +37e2%
> 
>  -------------- SHRINKING                                     
> --------------
>   [ = ]       0 .debug_line                                    -256Ki 
> -17.3%
>   [ = ]       0 .rela.debug_loc                               -73.6Ki  
> -0.6%
>   [ = ]       0 .debug_info                                   -63.4Ki  
> -1.6%
>   [ = ]       0 .debug_loc                                    -39.3Ki  
> -0.6%
> 
>   +1.1% +15.5Ki TOTAL                                         +3.67Mi  
> +7.8%
> 
> .debug_line probably shrinks because we drop columns with LTO.
> 
> Richard.
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2019-05-06 13:36                                 ` Richard Biener
@ 2019-05-06 13:51                                   ` Martin Liška
  2019-05-06 15:10                                   ` Segher Boessenkool
  1 sibling, 0 replies; 27+ messages in thread
From: Martin Liška @ 2019-05-06 13:51 UTC (permalink / raw)
  To: Richard Biener; +Cc: Segher Boessenkool, gcc-patches, Richard Sandiford

On 5/6/19 3:36 PM, Richard Biener wrote:
> On Mon, 6 May 2019, Martin Liška wrote:
> 
>> On 5/2/19 9:04 PM, Richard Biener wrote:
>>> On May 2, 2019 8:14:46 PM GMT+02:00, Segher Boessenkool <segher@kernel.crashing.org> wrote:
>>>> On Thu, May 02, 2019 at 07:41:18PM +0200, Richard Biener wrote:
>>>>> On May 2, 2019 7:00:16 PM GMT+02:00, Segher Boessenkool
>>>> <segher@kernel.crashing.org> wrote:
>>>>>> On Thu, May 02, 2019 at 03:18:00PM +0200, Richard Biener wrote:
>>>>>>> Somewhen earlier this year I've done the experiment with using
>>>>>>> a compile with -flto -fno-fat-lto-objects and a link
>>>>>>> via -flto -r -flinker-output=rel into the object file.  This cut
>>>>>>> compile-time more than in half with less maintainance overhead.
>>>>>>>
>>>>>>> Adding other files to this handling looks trivial as well, as well
>>>>>>> as conditionalizing it (I'd probably not want this for devel
>>>> builds).
>>>>>>
>>>>>> But we want devel builds to be a lot faster than they are now :-/
>>>>>
>>>>> My devel build is -O0 non-bootstrapped and building the files after
>>>> dependency changes is fast enough. It's the bootstraps that matter, no?
>>>>
>>>>
>>>> Yes, I bootstrap most of the time.  For development.  It catches a
>>>> *lot*
>>>> of problems progressive builds do not.  (Those are plenty fast already
>>>> of
>>>> course, -O0 or not).
>>>
>>> So we'd catch it there but disable by default for stage 1 since we probably do not want to rely on the host compiler. 
>>>
>>> Richard. 
>>>
>>>>
>>>> Segher
>>>
>>
>> I'm interested in 2 scenarios:
>>
>> 1) fast non-bootstrap development build with -O2; typically I want to run a fraction of test-suite or
>> I want to install the compiler and run-time binaries; building the compiler with -O0 will result in terribly
>> slow build of run-time libraries
> 
> That's already overall "fast", mostly dominated by runtime library build.

Yes, mainly libsanitizer run-time libraries build is a pain.

> 
>> 2) faster bootstrap on a massively parallel machine (64+ cores)
> 
> I guess for this we can also try to do LTO bootstap and
> LTO-link libbackend itself.  LTO bootstrap is only slow because
> we build everything 12 times.
> 
> I'm most interested in faster bootstrap on low-core machines
> (4 to 6 physical cores), since that's what I am doing most of the time.
> This is dominated by testing time, not bootstrap time.

I can provide access to multiple high-core machines we have at SUSE ;)

Martin

> 
> Richard.
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [RFH] split {generic,gimple}-match.c files
  2019-05-06 13:36                                 ` Richard Biener
  2019-05-06 13:51                                   ` Martin Liška
@ 2019-05-06 15:10                                   ` Segher Boessenkool
  1 sibling, 0 replies; 27+ messages in thread
From: Segher Boessenkool @ 2019-05-06 15:10 UTC (permalink / raw)
  To: Richard Biener; +Cc: Martin Liška, gcc-patches, Richard Sandiford

On Mon, May 06, 2019 at 03:36:06PM +0200, Richard Biener wrote:
> On Mon, 6 May 2019, Martin Liška wrote:
> > 2) faster bootstrap on a massively parallel machine (64+ cores)
> 
> I guess for this we can also try to do LTO bootstap and
> LTO-link libbackend itself.  LTO bootstrap is only slow because
> we build everything 12 times.

Currently it is dominated by the serial things, like the handful of huge
files it compiles.  The hundreds of smaller files take only a few seconds
*combined*.

> I'm most interested in faster bootstrap on low-core machines
> (4 to 6 physical cores), since that's what I am doing most of the time.
> This is dominated by testing time, not bootstrap time.

Yeah.

On a bigger machine, regstrap is 61m for me, while regstrap with
--disable-libgomp is 41m.  I also have guality and prettyprinters
disabled, those take disproportionally much testing time as well.


Segher

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2019-05-06 15:10 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-25 11:44 [RFH] split {generic,gimple}-match.c files Richard Biener
2018-04-25 12:26 ` Richard Biener
2018-04-25 12:46   ` Richard Biener
2018-04-25 13:16 ` Martin Liška
2018-09-03 12:27 ` Martin Liška
2018-09-03 12:41   ` Richard Biener
2018-09-03 12:54     ` Martin Liška
2018-09-03 13:50       ` Martin Liška
2018-09-03 14:01         ` Richard Biener
2018-09-03 14:27           ` Martin Liška
2018-09-03 14:43             ` Richard Biener
2018-09-04 15:07               ` Martin Liška
2018-09-10 11:43                 ` Martin Liška
2019-04-29 15:21                   ` Martin Liška
2019-05-02 13:18                     ` Richard Biener
2019-05-02 17:00                       ` Segher Boessenkool
2019-05-02 17:41                         ` Richard Biener
2019-05-02 18:14                           ` Segher Boessenkool
2019-05-02 19:04                             ` Richard Biener
2019-05-06 12:59                               ` Martin Liška
2019-05-06 13:36                                 ` Richard Biener
2019-05-06 13:51                                   ` Martin Liška
2019-05-06 15:10                                   ` Segher Boessenkool
2019-05-06 12:56                       ` Martin Liška
2019-05-06 13:32                         ` Richard Biener
2019-05-06 13:50                           ` Martin Liška
2019-04-29 14:41                 ` Martin Liška

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).