This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[RFC PATCH] Speed up bootstrap on SMP
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 29 Dec 2006 11:14:06 -0500
- Subject: [RFC PATCH] Speed up bootstrap on SMP
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
In my experience, compiling insn-attrtab.c takes longest time during
bootstrap and when bootstrap is done with make -jN for bigger N make
is always waiting till it completes while all other files are already
compiled.
The following patch allows insn-attrtab to be compiled in parts, so it
can be split accross multiple CPUs.
On quadcore x86_64-linux native bootstrap configured with
--enable-languages=c this resulted in 10% real time speedup.
without patch:
cd /usr/src/gcc; mkdir obj; cd obj; ../configure --enable-languages=c
time make -j16 bootstrap > LOG 2>&1
real 12m24.999s
user 34m46.462s
sys 2m50.103s
cd /usr/src/gcc; mkdir obj2; cd obj2; ../configure --enable-languages=c
time make -j16 bootstrap > LOG 2>&1
real 12m29.043s
user 34m48.859s
sys 2m50.343s
with patch:
cd /usr/src/gcc; mkdir obj3; cd obj3; ../configure --enable-languages=c
time make -j16 bootstrap > LOG 2>&1
real 11m13.584s
user 35m22.397s
sys 2m54.063s
cd /usr/src/gcc; mkdir obj4; cd obj4; ../configure --enable-languages=c
time make -j16 bootstrap > LOG 2>&1
real 11m7.970s
user 35m17.796s
sys 2m51.639s
Or perhaps we should adjust the Makefile depending on how big -j is used?
insn-attrtab.c could use two preprocessor macros instead of one,
#if !defined(INSN_ATTRTAB_PASS) || (INSN_ATTRTAB_PASS == (x % INSN_ATTRTAB_PASSES))
for -j1 just compile insn-attrtab.o (without -DINSN_ATTRTAB_PASS=x),
for -j2 compile insn-attrtab[01].o (-DINSN_ATTRTAB_PASS={0,1} -DINSN_ATTRTAB_PASSES=2)
etc. with 8 as a cap, not sure how hard would that be on the
Makefile side, especially when we need to be compatible with non-GNU
make. Checking whether -j1 resp. -j2 or higher is used can be
done e.g. through checking if $(MAKEFLAGS) contains --jobserver-fds=
substring.
2006-12-29 Jakub Jelinek <jakub@redhat.com>
* Makefile.in (OBJS-common): Replace insn-attrtab.o with
insn-attrtab[0-7].o.
(insn-attrtab%.c, insn-attrtab%.o): New rules.
* genattrtab.c (write_attr_get): Emit one less new-line at the end.
(main): Emit preprocessor guards around functions, so that it
can be compiled either all at once, or in 8 parts.
--- gcc/Makefile.in.jj 2006-12-28 10:46:25.000000000 +0100
+++ gcc/Makefile.in 2006-12-29 15:07:37.000000000 +0100
@@ -1000,10 +1000,12 @@ OBJS-common = \
dwarf2asm.o dwarf2out.o emit-rtl.o except.o explow.o loop-iv.o \
expmed.o expr.o final.o flow.o fold-const.o function.o fwprop.o gcse.o \
genrtl.o ggc-common.o global.o graph.o gtype-desc.o \
- haifa-sched.o hooks.o ifcvt.o insn-attrtab.o insn-emit.o insn-modes.o \
+ haifa-sched.o hooks.o ifcvt.o insn-attrtab0.o insn-attrtab1.o \
+ insn-attrtab2.o insn-attrtab3.o insn-attrtab4.o insn-attrtab5.o \
+ insn-attrtab6.o insn-attrtab7.o insn-emit.o insn-modes.o \
insn-extract.o insn-opinit.o insn-output.o insn-peep.o insn-recog.o \
integrate.o intl.o jump.o langhooks.o lcm.o lists.o local-alloc.o \
- mode-switching.o modulo-sched.o optabs.o options.o opts.o opts-common.o \
+ mode-switching.o modulo-sched.o optabs.o options.o opts.o opts-common.o \
params.o postreload.o postreload-gcse.o predict.o \
insn-preds.o insn-automata.o pointer-set.o \
print-rtl.o print-tree.o profile.o value-prof.o var-tracking.o \
@@ -2702,9 +2704,14 @@ s-mddeps: $(md_file) $(MD_INCLUDES) buil
# Header dependencies for generated source files.
genrtl.o : genrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H)\
$(GGC_H)
-insn-attrtab.o : insn-attrtab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) $(RTL_H) $(REGS_H) $(REAL_H) output.h $(INSN_ATTR_H) \
- insn-config.h toplev.h $(RECOG_H) $(TM_P_H) $(FLAGS_H)
+insn-attrtab%.c : insn-attrtab.c
+ $(LN_S) insn-attrtab.c $@
+insn-attrtab%.o : insn-attrtab%.c insn-attrtab.c $(CONFIG_H) \
+ $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) $(REAL_H) \
+ output.h $(INSN_ATTR_H) insn-config.h toplev.h $(RECOG_H) $(TM_P_H) \
+ $(FLAGS_H)
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $< $(OUTPUT_OPTION) \
+ -DINSN_ATTRTAB_PASS=`echo $@ | sed -e 's/^insn-attrtab//;s/\.o//'`
insn-automata.o : insn-automata.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(RTL_H) $(REGS_H) $(REAL_H) output.h $(INSN_ATTR_H) \
insn-config.h toplev.h $(RECOG_H) $(TM_P_H) $(FLAGS_H)
--- gcc/genattrtab.c.jj 2006-12-29 13:43:51.000000000 +0100
+++ gcc/genattrtab.c 2006-12-29 14:13:19.000000000 +0100
@@ -136,7 +136,7 @@ struct insn_def
struct insn_def *next; /* Next insn in chain. */
rtx def; /* The DEFINE_... */
int insn_code; /* Instruction number. */
- int insn_index; /* Expression numer in file, for errors. */
+ int insn_index; /* Expression number in file, for errors. */
int lineno; /* Line number. */
int num_alternatives; /* Number of alternatives. */
int vec_idx; /* Index of attribute vector in `def'. */
@@ -3696,7 +3696,7 @@ write_attr_get (struct attr_desc *attr)
write_attr_set (attr, 2, av->value, "return", ";",
true_rtx, -2, 0);
- printf ("}\n\n");
+ printf ("}\n");
return;
}
@@ -3709,7 +3709,7 @@ write_attr_get (struct attr_desc *attr)
write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
- printf (" }\n}\n\n");
+ printf (" }\n}\n");
}
/* Given an AND tree of known true terms (because we are inside an `if' with
@@ -4517,7 +4517,7 @@ main (int argc, char **argv)
struct attr_desc *attr;
struct insn_def *id;
rtx tem;
- int i;
+ int i, idx;
progname = "genattrtab";
@@ -4661,13 +4661,23 @@ from the machine description file `md'.
/* Now write out all the `gen_attr_...' routines. Do these before the
special routines so that they get defined before they are used. */
+ idx = 0;
for (i = 0; i < MAX_ATTRS_INDEX; i++)
for (attr = attrs[i]; attr; attr = attr->next)
{
if (! attr->is_special && ! attr->is_const)
- write_attr_get (attr);
+ {
+ printf ("#if !defined(INSN_ATTRTAB_PASS) || (INSN_ATTRTAB_PASS == %d)\n",
+ idx);
+ write_attr_get (attr);
+ puts ("#endif\n");
+ idx = (idx + 1) % 8;
+ }
}
+ printf ("#if !defined(INSN_ATTRTAB_PASS) || (INSN_ATTRTAB_PASS == %d)\n",
+ idx);
+
/* Write out delay eligibility information, if DEFINE_DELAY present.
(The function to compute the number of delay slots will be written
below.) */
@@ -4685,6 +4695,8 @@ from the machine description file `md'.
write_length_unit_log ();
+ puts ("#endif");
+
fflush (stdout);
return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
}
Jakub