	PR other/29442
	* genattrtab.c (attr_file_name, dfa_file_name, latency_file_name):
	New static chars, file names for output files.  These must match
	with the file names in Makefile.in.
	(switch_stdout): New function.
	(make_automaton_attrs): Write prototypes as extern to the output
	files.
	(write_header): New function.
	(main): Write headers to the output files.  Switch output files
	to write out internal functions for DFA attributes to dfa_file_name,
	and insn latency attributes to latency_file_name.
	* Makefile.in (OBJS): Add insn-dfatab.o and insn-latencytab.o.
	(BACKEND): Build libbackend first.
	(MOSTLYCLEANFILES): Add insn-dfatab.c and insn-latencytab.c.
	(.PRECIOUS): Likewise.
	(insn-dfatab.o): New rule.
	(insn-latencytab.o): New rule.
	(simple_rtl_generated_c): Do not include insn-attrtab.c.
	(s-attrtab): New rule.

Index: genattrtab.c
===================================================================
--- genattrtab.c	(revision 187092)
+++ genattrtab.c	(working copy)
@@ -294,6 +294,33 @@ static rtx min_fn		   (rtx);
 #define oballoc(T) XOBNEW (hash_obstack, T)
 #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
 
+/* This gen* file is unique, in that it writes out multiple files.
+
+   Before GCC 4.8, insn-attrtab.c was written out containing many large
+   functions and tables.  This made insn-attrtab.c _the_ bottle-neck in
+   a parallel build, and even made it impossible to build GCC on machines
+   with relatively small RAM space (PR other/29442).  Therefore, the
+   atrribute functions/tables are now written out to three separate
+   files: "*insn_default_latency" and "*internal_dfa_insn_code"
+   can be output to separate files, stdout and DFA_FILE_NAME respectively.
+   The remaining attributes can be output to ATTR_FILE_NAME.
+
+   Because the gen* support functions write their output to stdout, we have
+   to play tricks with freopen to redirect the output to the right files.  */
+
+static const char *attr_file_name = "tmp-attrtab.c";
+static const char *dfa_file_name = "tmp-dfatab.c";
+static const char *latency_file_name = "tmp-latencytab.c";
+
+static void
+switch_stdout (const char *file_name)
+{
+  if (fflush (stdout) || ferror (stdout))
+    exit (FATAL_EXIT_CODE);
+  if (!freopen (file_name, "a", stdout))
+    fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
+}
+
 /* Hash table for sharing RTL and strings.  */
 
 /* Each hash table slot is a bucket containing a chain of these structures.
@@ -4697,7 +4724,10 @@ find_tune_attr (rtx exp)
     }
 }
 
-/* Create all of the attributes that describe automaton properties.  */
+/* Create all of the attributes that describe automaton properties.
+   Write the DFA and latency function prototypes to  the files that
+   need to have them, and write the init_sched_attrs().  */
+
 static void
 make_automaton_attrs (void)
 {
@@ -4719,16 +4749,42 @@ make_automaton_attrs (void)
       gcc_assert (tune_attr->is_const
 		  && !tune_attr->is_special
 		  && !tune_attr->is_numeric);
+
+      /* Write the prototypes for all DFA functions.  */
+      switch_stdout (dfa_file_name);
       for (val = tune_attr->first_value; val; val = val->next)
 	{
 	  if (val == tune_attr->default_val)
 	    continue;
 	  gcc_assert (GET_CODE (val->value) == CONST_STRING);
-	  printf ("static int internal_dfa_insn_code_%s (rtx);\n"
-		  "static int insn_default_latency_%s (rtx);\n",
-		  XSTR (val->value, 0), XSTR (val->value, 0));
+	  printf ("extern int internal_dfa_insn_code_%s (rtx);\n",
+		  XSTR (val->value, 0));
+	}
+      printf ("\n");
+
+      /* Write the prototypes for all latency functions.  */
+      switch_stdout (latency_file_name);
+      for (val = tune_attr->first_value; val; val = val->next)
+	{
+	  if (val == tune_attr->default_val)
+	    continue;
+	  gcc_assert (GET_CODE (val->value) == CONST_STRING);
+	  printf ("extern int insn_default_latency_%s (rtx);\n",
+		  XSTR (val->value, 0));
 	}
+      printf ("\n");
 
+      /* Write the prototypes for all automaton functions.  */
+      switch_stdout (attr_file_name);
+      for (val = tune_attr->first_value; val; val = val->next)
+	{
+	  if (val == tune_attr->default_val)
+	    continue;
+	  gcc_assert (GET_CODE (val->value) == CONST_STRING);
+	  printf ("extern int internal_dfa_insn_code_%s (rtx);\n"
+		  "extern int insn_default_latency_%s (rtx);\n",
+		  XSTR (val->value, 0), XSTR (val->value, 0));
+	}
       printf ("\n");
       printf ("int (*internal_dfa_insn_code) (rtx);\n");
       printf ("int (*insn_default_latency) (rtx);\n");
@@ -4874,7 +4930,32 @@ make_automaton_attrs (void)
 	  }
     }
 
-  make_internal_attr ("*bypass_p",               byps_exp, ATTR_NONE);
+  make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE);
+}
+
+static void
+write_header (void)
+{
+  printf ("/* Generated automatically by the program `genattrtab'\n\
+from the machine description file `md'.  */\n\n");
+
+  printf ("#include \"config.h\"\n");
+  printf ("#include \"system.h\"\n");
+  printf ("#include \"coretypes.h\"\n");
+  printf ("#include \"tm.h\"\n");
+  printf ("#include \"rtl.h\"\n");
+  printf ("#include \"insn-attr.h\"\n");
+  printf ("#include \"tm_p.h\"\n");
+  printf ("#include \"insn-config.h\"\n");
+  printf ("#include \"recog.h\"\n");
+  printf ("#include \"regs.h\"\n");
+  printf ("#include \"real.h\"\n");
+  printf ("#include \"output.h\"\n");
+  printf ("#include \"toplev.h\"\n");
+  printf ("#include \"flags.h\"\n");
+  printf ("#include \"function.h\"\n");
+  printf ("\n");
+  printf ("#define operands recog_data.operand\n\n");
 }
 
 int
@@ -4891,6 +4972,13 @@ main (int argc, char **argv)
   if (!init_rtx_reader_args (argc, argv))
     return (FATAL_EXIT_CODE);
 
+  switch_stdout (attr_file_name);
+  write_header ();
+  switch_stdout (dfa_file_name);
+  write_header ();
+  switch_stdout (latency_file_name);
+  write_header ();
+
   obstack_init (hash_obstack);
   obstack_init (temp_obstack);
 
@@ -4908,9 +4996,6 @@ main (int argc, char **argv)
   delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
   num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
 
-  printf ("/* Generated automatically by the program `genattrtab'\n\
-from the machine description file `md'.  */\n\n");
-
   /* Read the machine description.  */
 
   while (1)
@@ -4970,23 +5055,6 @@ from the machine description file `md'. 
   if (num_delays)
     expand_delays ();
 
-  printf ("#include \"config.h\"\n");
-  printf ("#include \"system.h\"\n");
-  printf ("#include \"coretypes.h\"\n");
-  printf ("#include \"tm.h\"\n");
-  printf ("#include \"rtl.h\"\n");
-  printf ("#include \"insn-attr.h\"\n");
-  printf ("#include \"tm_p.h\"\n");
-  printf ("#include \"insn-config.h\"\n");
-  printf ("#include \"recog.h\"\n");
-  printf ("#include \"regs.h\"\n");
-  printf ("#include \"output.h\"\n");
-  printf ("#include \"diagnostic-core.h\"\n");
-  printf ("#include \"flags.h\"\n");
-  printf ("#include \"function.h\"\n");
-  printf ("\n");
-  printf ("#define operands recog_data.operand\n\n");
-
   /* Make `insn_alternatives'.  */
   insn_alternatives = oballocvec (int, insn_code_number);
   for (id = defs; id; id = id->next)
@@ -5031,6 +5099,15 @@ from the machine description file `md'. 
   for (i = 0; i < MAX_ATTRS_INDEX; i++)
     for (attr = attrs[i]; attr; attr = attr->next)
       {
+#define IS_ATTR_GROUP(X) (!strncmp(attr->name,X,strlen(X)))
+	if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
+	  switch_stdout (dfa_file_name);
+	else if (IS_ATTR_GROUP ("*insn_default_latency"))
+	  switch_stdout (latency_file_name);
+	else
+	  switch_stdout (attr_file_name);
+#undef IS_ATTR_GROUP
+
 	if (! attr->is_special && ! attr->is_const)
 	  write_attr_get (attr);
       }
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 187092)
+++ Makefile.in	(working copy)
@@ -1143,8 +1143,10 @@ C_OBJS = c-lang.o c-family/stub-objc.o $
 OBJS = \
 	insn-attrtab.o \
 	insn-automata.o \
+	insn-dfatab.o \
 	insn-emit.o \
 	insn-extract.o \
+	insn-latencytab.o \
 	insn-modes.o \
 	insn-opinit.o \
 	insn-output.o \
@@ -1469,13 +1471,13 @@ ALL_HOST_BACKEND_OBJS = $(GCC_OBJS) $(OB
 # compilation or not.
 ALL_HOST_OBJS = $(ALL_HOST_FRONTEND_OBJS) $(ALL_HOST_BACKEND_OBJS)
 
-BACKEND = main.o @TREEBROWSER@ libbackend.a libcommon-target.a libcommon.a \
+BACKEND = libbackend.a main.o @TREEBROWSER@ libcommon-target.a libcommon.a \
 	$(CPPLIB) $(LIBDECNUMBER)
 
 MOSTLYCLEANFILES = insn-flags.h insn-config.h insn-codes.h \
  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-opinit.c \
- insn-preds.c insn-constants.h \
+ insn-attr.h insn-attr-common.h insn-attrtab.c insn-dfatab.c \
+ insn-latencytab.c insn-opinit.c insn-preds.c insn-constants.h \
  tm-preds.h tm-constrs.h checksum-options \
  tree-check.h min-insn-modes.c insn-modes.c insn-modes.h \
  genrtl.h gt-*.h gtype-*.h gtype-desc.c gtyp-input.list \
@@ -3460,7 +3462,8 @@ $(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-preds.c
+  insn-attr.h insn-attr-common.h insn-attrtab.c insn-dfatab.c \
+  insn-latencytab.c insn-preds.c
 
 # 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
@@ -3479,7 +3482,11 @@ insn-attrtab.o : insn-attrtab.c $(CONFIG
   insn-config.h $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(TM_P_H) $(FLAGS_H)
 insn-automata.o : insn-automata.c $(CONFIG_H) $(SYSTEM_H) coretypes.h	\
   $(TM_H) $(RTL_H) $(REGS_H) output.h $(INSN_ATTR_H)			\
-  insn-config.h toplev.h $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(TM_P_H) $(FLAGS_H) $(EMIT_RTL_H)
+  insn-config.h toplev.h $(DIAGNOSTIC_CORE_H) $(RECOG_H)		\
+  $(TM_P_H) $(FLAGS_H) $(EMIT_RTL_H)
+insn-dfatab.o : insn-dfatab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h	\
+  $(TM_H) $(RTL_H) $(REGS_H) output.h $(INSN_ATTR_H)			\
+  insn-config.h $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(TM_P_H) $(FLAGS_H)
 insn-emit.o : insn-emit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)	\
   $(RTL_H) $(TM_P_H) $(FUNCTION_H) $(EXPR_H) $(OPTABS_H) 		\
   dfp.h $(FLAGS_H) output.h insn-config.h hard-reg-set.h $(RECOG_H)	\
@@ -3488,6 +3495,9 @@ insn-emit.o : insn-emit.c $(CONFIG_H) $(
 insn-enums.o : insn-enums.c $(CONFIG_H) $(SYSTEM_H) insn-constants.h
 insn-extract.o : insn-extract.c $(CONFIG_H) $(SYSTEM_H) coretypes.h	\
   $(TM_H) $(RTL_H) $(DIAGNOSTIC_CORE_H) insn-config.h $(RECOG_H)
+insn-latencytab.o : insn-latencytab.c $(CONFIG_H) $(SYSTEM_H) 		\
+  coretypes.h $(TM_H) $(RTL_H) $(REGS_H) output.h $(INSN_ATTR_H)	\
+  insn-config.h $(DIAGNOSTIC_CORE_H) $(RECOG_H) $(TM_P_H) $(FLAGS_H)
 insn-modes.o : insn-modes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h	$(TM_H) \
   $(MACHMODE_H)
 insn-opinit.o : insn-opinit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h	\
@@ -3520,7 +3530,7 @@ insn-recog.o : insn-recog.c $(CONFIG_H) 
 simple_rtl_generated_h	= insn-attr.h insn-attr-common.h insn-codes.h \
 			  insn-config.h insn-flags.h
 
-simple_rtl_generated_c	= insn-attrtab.c insn-automata.c insn-emit.c \
+simple_rtl_generated_c	= insn-automata.c insn-emit.c \
 			  insn-extract.c insn-opinit.c insn-output.c \
 			  insn-peep.c insn-recog.c
 
@@ -3557,6 +3567,16 @@ s-check : build/gencheck$(build_exeext)
 	$(SHELL) $(srcdir)/../move-if-change tmp-check.h tree-check.h
 	$(STAMP) s-check
 
+# genattrtab produces three files: tmp-{attrtab.c,dfatab.c,latencytab.c}
+insn-attrtab.c insn-dfatab.c insn-latencytab.c: s-attrtab ; @true
+s-attrtab : $(MD_DEPS) build/genattrtab$(build_exeext) \
+  insn-conditions.md
+	$(RUN_GEN) build/genattrtab$(build_exeext) $(md_file) insn-conditions.md
+	$(SHELL) $(srcdir)/../move-if-change tmp-attrtab.c    insn-attrtab.c
+	$(SHELL) $(srcdir)/../move-if-change tmp-dfatab.c     insn-dfatab.c
+	$(SHELL) $(srcdir)/../move-if-change tmp-latencytab.c insn-latencytab.c
+	$(STAMP) s-attrtab
+
 # gencondmd doesn't use the standard naming convention.
 build/gencondmd.c: s-conditions; @true
 s-conditions: $(MD_DEPS) build/genconditions$(build_exeext)
