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.