Re: [PATCH v2] genemit.c (main): split insn-emit.c for compiling parallelly
在 2020年7月21日 +0800 PM2:55,Bin.Cheng ,写道: > On Tue, Jul 21, 2020 at 11:14 AM Jojo wrote: > > > > gcc/ChangeLog: > > > > * genemit.c (main): Print 'split line'. > > * Makefile.in (insn-emit.c): Define split count and file > > > > Thanks for working one this, following comments are based on the > assumption that the approach is feasible after your investigation. > > It's great to accelerate compilation time, do you have any number > showing how much this can achieve, on a typical machine with > reasonable parallelism? > Here are time collections from machine: 20 Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz, Size of insn-emit.c (du -sh insn-emit.c) : 121M Not split (same like j1) : 195 second Split 20, -j1 : 213 second Split 20, -j4: 76 second Split 20, -j8: 44 second Split 20, -j12: 44 second Split 20, -j16: 44 second Split 20, -j20: 44 second Also, litter RAM will be consumed by litter code :) > > --- > > gcc/Makefile.in | 10 ++ > > gcc/genemit.c | 86 +++-- > > 2 files changed, 58 insertions(+), 38 deletions(-) > > > > diff --git a/gcc/Makefile.in b/gcc/Makefile.in > > index 2ba76656dbf..f805050a119 100644 > > --- a/gcc/Makefile.in > > +++ b/gcc/Makefile.in > > @@ -1253,6 +1253,13 @@ ANALYZER_OBJS = \ > > # We put the *-match.o and insn-*.o files first so that a parallel make > > # will build them sooner, because they are large and otherwise tend to be > > # the last objects to finish building. > > + > > +insn-generated-split-num = 15 > Hardcode number 15 looks strange here, how shall we know it's enough? > Or one step further, can we use some kind of general match "*" for > writing make rules here? I have researched the detail of Makefile rules, As far as I know, ‘Make’ analyze the dependent objects before some object running it’s shell command, so we need to static define the ‘insn-emit.c’ counts for creating ‘insn-emit.o’. We can define split counts from processor numbers from machine, it should be nice ? It’s fixed in v3 patch. > > + > > +insn-emit-split-c = $(foreach o, $(shell for i in > > {1..$(insn-generated-split-num)}; do echo $$i; done), insn-emit$(o).c) > > +insn-emit-split-obj = $(patsubst %.c,%.o, $(insn-emit-split-c)) > > +$(insn-emit-split-c): insn-emit.c > > + > > OBJS = \ > > gimple-match.o \ > > generic-match.o \ > > @@ -1260,6 +1267,7 @@ OBJS = \ > > insn-automata.o \ > > insn-dfatab.o \ > > insn-emit.o \ > > + $(insn-emit-split-obj) \ > > insn-extract.o \ > > insn-latencytab.o \ > > insn-modes.o \ > > @@ -2367,6 +2375,8 @@ $(simple_generated_c:insn-%.c=s-%): s-%: > > build/gen%$(build_exeext) > > $(RUN_GEN) build/gen$*$(build_exeext) $(md_file) \ > > $(filter insn-conditions.md,$^) > tmp-$*.c > > $(SHELL) $(srcdir)/../move-if-change tmp-$*.c insn-$*.c > > + -csplit insn-$*.c /i\ am\ split\ line/ -k -s > > {$(insn-generated-split-num)} -f insn-$* -b "%d.c" > > + -( [ ! -s insn-$*0.c ] && for i in {1..$(insn-generated-split-num)}; do > > touch insn-$*$$i.c; done && echo "" > insn-$*.c) > Not sure if this is the first time that csplit/coreutils is used, > shall we mention it here > https://gcc.gnu.org/install/prerequisites.html, even check it in > configure? I grep coreutils from gcc source code and much more modules have checked the coreutils like libcc1, libssp and so on. > > $(STAMP) s-$* > > > > # gencheck doesn't read the machine description, and the file produced > > diff --git a/gcc/genemit.c b/gcc/genemit.c > > index 84d07d388ee..fd60cdeeb96 100644 > > --- a/gcc/genemit.c > > +++ b/gcc/genemit.c > > @@ -847,6 +847,45 @@ handle_overloaded_gen (overloaded_name *oname) > > } > > } > > > > +#define printf_include() \ > > + printf ("/* Generated automatically by the program `genemit'\n\ > > +from the machine description file `md'. */\n\n"); \ > > + printf ("#define IN_TARGET_CODE 1\n"); \ > > + printf ("#include \"config.h\"\n"); \ > > + printf ("#include \"system.h\"\n"); \ > > + printf ("#include \"coretypes.h\"\n"); \ > > + printf ("#include \"backend.h\"\n"); \ > > + printf ("#include \"predict.h\"\n"); \ > > + printf ("#include \"tree.h\"\n"); \ > > + printf ("#include \"rtl.h\"\n"); \ > > + printf ("#include \"alias.h\"\n"); \ > > + printf ("#include \"varasm.h\"\n"); \ > > + printf ("#include \"stor-layout.h\"\n"); \ > > + printf ("#include \"calls.h\"\n"); \ > > + printf ("#include \"memmodel.h\"\n"); \ > > + printf ("#include \"tm_p.h\"\n"); \ > > + printf ("#include \"flags.h\"\n"); \ > > + printf ("#include \"insn-config.h\"\n"); \ > > + printf ("#include \"expmed.h\"\n"); \ > > + printf ("#include \"dojump.h\"\n"); \ > > + printf ("#include \"explow.h\"\n"); \ > > + printf ("#include \"emit-rtl.h\"\n"); \ > > + printf ("#include \"stmt.h\"\n"); \ > > + printf ("#include \"expr.h\"\n"); \ > > + printf ("#include \"insn-codes.h\"\n"); \ > > + printf ("#include \"optabs.h\"\n"); \ > > + printf ("#include \"dfp.h\"\n"); \ > > + printf ("#include \"output.h\"\n"); \ > > + printf ("#include \"recog.h\"\n"); \ > > +
Re: [PATCH v2] genemit.c (main): split insn-emit.c for compiling parallelly
On Tue, Jul 21, 2020 at 11:14 AM Jojo wrote: > > gcc/ChangeLog: > > * genemit.c (main): Print 'split line'. > * Makefile.in (insn-emit.c): Define split count and file > Thanks for working one this, following comments are based on the assumption that the approach is feasible after your investigation. It's great to accelerate compilation time, do you have any number showing how much this can achieve, on a typical machine with reasonable parallelism? > --- > gcc/Makefile.in | 10 ++ > gcc/genemit.c | 86 +++-- > 2 files changed, 58 insertions(+), 38 deletions(-) > > diff --git a/gcc/Makefile.in b/gcc/Makefile.in > index 2ba76656dbf..f805050a119 100644 > --- a/gcc/Makefile.in > +++ b/gcc/Makefile.in > @@ -1253,6 +1253,13 @@ ANALYZER_OBJS = \ > # We put the *-match.o and insn-*.o files first so that a parallel make > # will build them sooner, because they are large and otherwise tend to be > # the last objects to finish building. > + > +insn-generated-split-num = 15 Hardcode number 15 looks strange here, how shall we know it's enough? Or one step further, can we use some kind of general match "*" for writing make rules here? > + > +insn-emit-split-c = $(foreach o, $(shell for i in > {1..$(insn-generated-split-num)}; do echo $$i; done), insn-emit$(o).c) > +insn-emit-split-obj = $(patsubst %.c,%.o, $(insn-emit-split-c)) > +$(insn-emit-split-c): insn-emit.c > + > OBJS = \ > gimple-match.o \ > generic-match.o \ > @@ -1260,6 +1267,7 @@ OBJS = \ > insn-automata.o \ > insn-dfatab.o \ > insn-emit.o \ > + $(insn-emit-split-obj) \ > insn-extract.o \ > insn-latencytab.o \ > insn-modes.o \ > @@ -2367,6 +2375,8 @@ $(simple_generated_c:insn-%.c=s-%): s-%: > build/gen%$(build_exeext) > $(RUN_GEN) build/gen$*$(build_exeext) $(md_file) \ > $(filter insn-conditions.md,$^) > tmp-$*.c > $(SHELL) $(srcdir)/../move-if-change tmp-$*.c insn-$*.c > + -csplit insn-$*.c /i\ am\ split\ line/ -k -s > {$(insn-generated-split-num)} -f insn-$* -b "%d.c" > + -( [ ! -s insn-$*0.c ] && for i in {1..$(insn-generated-split-num)}; > do touch insn-$*$$i.c; done && echo "" > insn-$*.c) Not sure if this is the first time that csplit/coreutils is used, shall we mention it here https://gcc.gnu.org/install/prerequisites.html, even check it in configure? > $(STAMP) s-$* > > # gencheck doesn't read the machine description, and the file produced > diff --git a/gcc/genemit.c b/gcc/genemit.c > index 84d07d388ee..fd60cdeeb96 100644 > --- a/gcc/genemit.c > +++ b/gcc/genemit.c > @@ -847,6 +847,45 @@ handle_overloaded_gen (overloaded_name *oname) > } > } > > +#define printf_include() \ > + printf ("/* Generated automatically by the program `genemit'\n\ > +from the machine description file `md'. */\n\n"); \ > + printf ("#define IN_TARGET_CODE 1\n"); \ > + printf ("#include \"config.h\"\n"); \ > + printf ("#include \"system.h\"\n"); \ > + printf ("#include \"coretypes.h\"\n"); \ > + printf ("#include \"backend.h\"\n"); \ > + printf ("#include \"predict.h\"\n"); \ > + printf ("#include \"tree.h\"\n"); \ > + printf ("#include \"rtl.h\"\n"); \ > + printf ("#include \"alias.h\"\n"); \ > + printf ("#include \"varasm.h\"\n"); \ > + printf ("#include \"stor-layout.h\"\n"); \ > + printf ("#include \"calls.h\"\n"); \ > + printf ("#include \"memmodel.h\"\n"); \ > + printf ("#include \"tm_p.h\"\n"); \ > + printf ("#include \"flags.h\"\n"); \ > + printf ("#include \"insn-config.h\"\n"); \ > + printf ("#include \"expmed.h\"\n"); \ > + printf ("#include \"dojump.h\"\n"); \ > + printf ("#include \"explow.h\"\n"); \ > + printf ("#include \"emit-rtl.h\"\n"); \ > + printf ("#include \"stmt.h\"\n"); \ > + printf ("#include \"expr.h\"\n"); \ > + printf ("#include \"insn-codes.h\"\n"); \ > + printf ("#include \"optabs.h\"\n"); \ > + printf ("#include \"dfp.h\"\n"); \ > + printf ("#include \"output.h\"\n"); \ > + printf ("#include \"recog.h\"\n"); \ > + printf ("#include \"df.h\"\n"); \ > + printf ("#include \"resource.h\"\n"); \ > + printf ("#include \"reload.h\"\n"); \ > + printf ("#include \"diagnostic-core.h\"\n"); \ > + printf ("#include \"regs.h\"\n"); \ > + printf ("#include \"tm-constrs.h\"\n"); \ > + printf ("#include \"ggc.h\"\n"); \ > + printf ("#include \"target.h\"\n\n"); \ Can you use do {} while(0) style for defining this code block macro? The trailing '\' is also strange here. > + > int > main (int argc, const char **argv) > { > @@ -862,49 +901,19 @@ main (int argc, const char **argv) >/* Assign sequential codes to all entries in the machine description > in parallel with the tables in insn-output.c. */ > > - printf ("/* Generated automatically by the program `genemit'\n\ > -from the machine description file `md'. */\n\n"); > - > - printf ("#define IN_TARGET_CODE 1\n"); > - printf ("#include \"config.h\"\n"); > - pri
[PATCH v2] genemit.c (main): split insn-emit.c for compiling parallelly
gcc/ChangeLog: * genemit.c (main): Print 'split line'. * Makefile.in (insn-emit.c): Define split count and file --- gcc/Makefile.in | 10 ++ gcc/genemit.c | 86 +++-- 2 files changed, 58 insertions(+), 38 deletions(-) diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 2ba76656dbf..f805050a119 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1253,6 +1253,13 @@ ANALYZER_OBJS = \ # We put the *-match.o and insn-*.o files first so that a parallel make # will build them sooner, because they are large and otherwise tend to be # the last objects to finish building. + +insn-generated-split-num = 15 + +insn-emit-split-c = $(foreach o, $(shell for i in {1..$(insn-generated-split-num)}; do echo $$i; done), insn-emit$(o).c) +insn-emit-split-obj = $(patsubst %.c,%.o, $(insn-emit-split-c)) +$(insn-emit-split-c): insn-emit.c + OBJS = \ gimple-match.o \ generic-match.o \ @@ -1260,6 +1267,7 @@ OBJS = \ insn-automata.o \ insn-dfatab.o \ insn-emit.o \ + $(insn-emit-split-obj) \ insn-extract.o \ insn-latencytab.o \ insn-modes.o \ @@ -2367,6 +2375,8 @@ $(simple_generated_c:insn-%.c=s-%): s-%: build/gen%$(build_exeext) $(RUN_GEN) build/gen$*$(build_exeext) $(md_file) \ $(filter insn-conditions.md,$^) > tmp-$*.c $(SHELL) $(srcdir)/../move-if-change tmp-$*.c insn-$*.c + -csplit insn-$*.c /i\ am\ split\ line/ -k -s {$(insn-generated-split-num)} -f insn-$* -b "%d.c" + -( [ ! -s insn-$*0.c ] && for i in {1..$(insn-generated-split-num)}; do touch insn-$*$$i.c; done && echo "" > insn-$*.c) $(STAMP) s-$* # gencheck doesn't read the machine description, and the file produced diff --git a/gcc/genemit.c b/gcc/genemit.c index 84d07d388ee..fd60cdeeb96 100644 --- a/gcc/genemit.c +++ b/gcc/genemit.c @@ -847,6 +847,45 @@ handle_overloaded_gen (overloaded_name *oname) } } +#define printf_include() \ + printf ("/* Generated automatically by the program `genemit'\n\ +from the machine description file `md'. */\n\n"); \ + printf ("#define IN_TARGET_CODE 1\n"); \ + printf ("#include \"config.h\"\n"); \ + printf ("#include \"system.h\"\n"); \ + printf ("#include \"coretypes.h\"\n"); \ + printf ("#include \"backend.h\"\n"); \ + printf ("#include \"predict.h\"\n"); \ + printf ("#include \"tree.h\"\n"); \ + printf ("#include \"rtl.h\"\n"); \ + printf ("#include \"alias.h\"\n"); \ + printf ("#include \"varasm.h\"\n"); \ + printf ("#include \"stor-layout.h\"\n"); \ + printf ("#include \"calls.h\"\n"); \ + printf ("#include \"memmodel.h\"\n"); \ + printf ("#include \"tm_p.h\"\n"); \ + printf ("#include \"flags.h\"\n"); \ + printf ("#include \"insn-config.h\"\n"); \ + printf ("#include \"expmed.h\"\n"); \ + printf ("#include \"dojump.h\"\n"); \ + printf ("#include \"explow.h\"\n"); \ + printf ("#include \"emit-rtl.h\"\n"); \ + printf ("#include \"stmt.h\"\n"); \ + printf ("#include \"expr.h\"\n"); \ + printf ("#include \"insn-codes.h\"\n"); \ + printf ("#include \"optabs.h\"\n"); \ + printf ("#include \"dfp.h\"\n"); \ + printf ("#include \"output.h\"\n"); \ + printf ("#include \"recog.h\"\n"); \ + printf ("#include \"df.h\"\n"); \ + printf ("#include \"resource.h\"\n"); \ + printf ("#include \"reload.h\"\n"); \ + printf ("#include \"diagnostic-core.h\"\n"); \ + printf ("#include \"regs.h\"\n"); \ + printf ("#include \"tm-constrs.h\"\n"); \ + printf ("#include \"ggc.h\"\n"); \ + printf ("#include \"target.h\"\n\n"); \ + int main (int argc, const char **argv) { @@ -862,49 +901,19 @@ main (int argc, const char **argv) /* Assign sequential codes to all entries in the machine description in parallel with the tables in insn-output.c. */ - printf ("/* Generated automatically by the program `genemit'\n\ -from the machine description file `md'. */\n\n"); - - printf ("#define IN_TARGET_CODE 1\n"); - printf ("#include \"config.h\"\n"); - printf ("#include \"system.h\"\n"); - printf ("#include \"coretypes.h\"\n"); - printf ("#include \"backend.h\"\n"); - printf ("#include \"predict.h\"\n"); - printf ("#include \"tree.h\"\n"); - printf ("#include \"rtl.h\"\n"); - printf ("#include \"alias.h\"\n"); - printf ("#include \"varasm.h\"\n"); - printf ("#include \"stor-layout.h\"\n"); - printf ("#include \"calls.h\"\n"); - printf ("#include \"memmodel.h\"\n"); - printf ("#include \"tm_p.h\"\n"); - printf ("#include \"flags.h\"\n"); - printf ("#include \"insn-config.h\"\n"); - printf ("#include \"expmed.h\"\n"); - printf ("#include \"dojump.h\"\n"); - printf ("#include \"explow.h\"\n"); - printf ("#include \"emit-rtl.h\"\n"); - printf ("#include \"stmt.h\"\n"); - printf ("#include \"expr.h\"\n"); - printf ("#include \"insn-codes.h\"\n"); - printf ("#include \"optabs.h\"\n"); - printf ("#include \"dfp.h\"\n"); - printf ("#include \"output.h\"\n"); - printf ("#include \"recog.h\"\n"); - prin