This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RFH] split {generic,gimple}-match.c files
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 25 Apr 2018 13:42:56 +0200 (CEST)
- Subject: [RFH] split {generic,gimple}-match.c files
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 \