This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC PATCH] Speed up bootstrap on SMP


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]