haifa-sched.c (build_jmp_edges): Delete dead function.
[gcc.git] / gcc / toplev.c
index 43b7d8a6264fc14f0f567e3eac1fd4117a144f3f..1922384881eb40c5d84fee0e1789fbf69ce62c26 100644 (file)
@@ -1,5 +1,5 @@
 /* Top level of GNU C compiler
-   Copyright (C) 1987, 88, 89, 92-6, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1987, 88, 89, 92-7, 1998 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -35,21 +35,44 @@ Boston, MA 02111-1307, USA.  */
 #include <sys/types.h>
 #include <ctype.h>
 #include <sys/stat.h>
-#if !defined (_WIN32) || defined (__CYGWIN32__)
-#ifdef USG
 #undef FLOAT
+#ifdef HAVE_SYS_PARAM_H
 #include <sys/param.h>
-/* This is for hpux.  It is a real screw.  They should change hpux.  */
-#undef FLOAT
-#include <sys/times.h>
-#include <time.h>   /* Correct for hpux at least.  Is it good on other USG?  */
+#endif
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#undef FLOAT /* This is for hpux. They should change hpux.  */
 #undef FFS  /* Some systems define this in param.h.  */
+
+#ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
 #else
-#ifndef VMS
-#include <sys/time.h>
-#include <sys/resource.h>
+# if HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+#  include <time.h>
+#endif
 #endif
+
+#ifdef HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
 #endif
+
+#ifdef HAVE_SYS_TIMES_H
+# include <sys/times.h>
 #endif
 
 #include "input.h"
@@ -59,8 +82,6 @@ Boston, MA 02111-1307, USA.  */
 #include "insn-attr.h"
 #include "defaults.h"
 #include "output.h"
-#include "bytecode.h"
-#include "bc-emit.h"
 #include "except.h"
 
 #ifdef XCOFF_DEBUGGING_INFO
@@ -152,6 +173,9 @@ extern void dump_sched_info ();
 extern void dump_local_alloc ();
 extern void regset_release_memory ();
 
+extern void print_rtl ();
+extern void print_rtl_with_bb ();
+
 void rest_of_decl_compilation ();
 void error_with_file_and_line PVPROTO((char *file, int line, char *s, ...));
 void error_with_decl PVPROTO((tree decl, char *s, ...));
@@ -168,9 +192,6 @@ void pedwarn_with_file_and_line PVPROTO((char *file, int line, char *s, ...));
 void sorry PVPROTO((char *s, ...));
 void really_sorry PVPROTO((char *s, ...));
 void fancy_abort ();
-#ifndef abort
-void abort ();
-#endif
 void set_target_switch ();
 static char *decl_name ();
 
@@ -180,7 +201,11 @@ void print_switch_values ();
 /* Length of line when printing switch values.  */
 #define MAX_LINE 75
 
-#ifdef __alpha
+#ifdef NEED_DECLARATION_ABORT
+void abort ();
+#endif
+
+#ifdef NEED_DECLARATION_SBRK
 extern char *sbrk ();
 #endif
 
@@ -251,9 +276,16 @@ int local_reg_dump = 0;
 int global_reg_dump = 0;
 int sched2_dump = 0;
 int jump2_opt_dump = 0;
+#ifdef DELAY_SLOTS
 int dbr_sched_dump = 0;
+#endif
 int flag_print_asm_name = 0;
+#ifdef STACK_REGS
 int stack_reg_dump = 0;
+#endif
+#ifdef MACHINE_DEPENDENT_REORG
+int mach_dep_reorg_dump = 0;
+#endif
 
 /* Name for output file of assembly code, specified with -o.  */
 
@@ -287,15 +319,19 @@ int use_gnu_debug_info_extensions = 0;
 
 int optimize = 0;
 
+/* Nonzero means optimize for size.  -Os.
+   The only valid values are zero and non-zero. When optimize_size is
+   non-zero, optimize defaults to 2, but certain individual code
+   bloating optimizations are disabled.  */
+
+int optimize_size = 0;
+
 /* Number of error messages and warning messages so far.  */
 
 int errorcount = 0;
 int warningcount = 0;
 int sorrycount = 0;
 
-/* Flag to output bytecode instead of native assembler */
-int output_bytecode = 0;
-
 /* Pointer to function to compute the name to use to print a declaration.
    DECL is the declaration in question.
    VERBOSITY determines what information will be printed:
@@ -590,19 +626,12 @@ int flag_schedule_insns_after_reload = 0;
    flag_schedule_speculative_load means allow speculative motion of some
    load insns.
    flag_schedule_speculative_load_dangerous allows speculative motion of more
-   load insns.
-   flag_schedule_reverse_before_reload means try to reverse original order
-   of insns (S).
-   flag_schedule_reverse_after_reload means try to reverse original order
-   of insns (R).  */
+   load insns.  */
 
 int flag_schedule_interblock = 1;
 int flag_schedule_speculative = 1;
 int flag_schedule_speculative_load = 0;
 int flag_schedule_speculative_load_dangerous = 0;
-int flag_schedule_reverse_before_reload = 0;
-int flag_schedule_reverse_after_reload = 0;
-
 
 /* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple
    by a cheaper branch, on a count register. */
@@ -620,10 +649,10 @@ int flag_inhibit_size_directive = 0;
    the generated assembly code (to make it more readable).  This option
    is generally only of use to those who actually need to read the
    generated assembly code (perhaps while debugging the compiler itself).
-   -fverbose-asm is the default.  -fno-verbose-asm causes the extra information
+   -fno-verbose-asm, the default, causes the extra information
    to be omitted and is useful when comparing two assembler files.  */
 
-int flag_verbose_asm = 1;
+int flag_verbose_asm = 0;
 
 /* -dA causes debug commentary information to be produced in
    the generated assembly code (to make it more readable).  This option
@@ -662,9 +691,6 @@ int flag_prefix_function_name = 0;
 
 int flag_regmove = 0;
 
-/* 1 if alias checking is on (by default, when -O).  */
-int flag_alias_check = 0;
-
 /* 0 if pointer arguments may alias each other.  True in C.
    1 if pointer arguments may not alias each other but may alias
    global variables.
@@ -720,8 +746,6 @@ struct { char *string; int *variable; int on_value;} f_options[] =
   {"sched-spec",&flag_schedule_speculative, 1},
   {"sched-spec-load",&flag_schedule_speculative_load, 1},
   {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1},
-  {"sched-reverse-S",&flag_schedule_reverse_before_reload, 1},
-  {"sched-reverse-R",&flag_schedule_reverse_after_reload, 1},
   {"branch-count-reg",&flag_branch_on_count_reg, 1},
 #endif  /* HAIFA */
   {"pic", &flag_pic, 1},
@@ -741,8 +765,6 @@ struct { char *string; int *variable; int on_value;} f_options[] =
   {"regmove", &flag_regmove, 1},
   {"pack-struct", &flag_pack_struct, 1},
   {"stack-check", &flag_stack_check, 1},
-  {"bytecode", &output_bytecode, 1},
-  {"alias-check", &flag_alias_check, 1},
   {"argument-alias", &flag_argument_noalias, 0},
   {"argument-noalias", &flag_argument_noalias, 1},
   {"argument-noalias-global", &flag_argument_noalias, 2},
@@ -832,6 +854,8 @@ char *lang_options[] =
   "-Wno-redundant-decls",
   "-Wsign-compare",
   "-Wno-sign-compare",
+  "-Wunknown-pragmas",
+  "-Wno-unknown-pragmas",
   "-Wstrict-prototypes",
   "-Wno-strict-prototypes",
   "-Wtraditional",
@@ -854,6 +878,7 @@ char *lang_options[] =
   "-Wno-selector",
   "-Wprotocol",
   "-Wno-protocol",
+  "-print-objc-runtime-info",
 
 #include "options.h"
   0
@@ -941,23 +966,7 @@ struct { char *string; int *variable; int on_value;} W_options[] =
 
 FILE *asm_out_file;
 FILE *aux_info_file;
-FILE *rtl_dump_file;
-FILE *jump_opt_dump_file;
-FILE *addressof_dump_file;
-FILE *cse_dump_file;
-FILE *loop_dump_file;
-FILE *cse2_dump_file;
-FILE *branch_prob_dump_file;
-FILE *flow_dump_file;
-FILE *combine_dump_file;
-FILE *regmove_dump_file;
-FILE *sched_dump_file;
-FILE *local_reg_dump_file;
-FILE *global_reg_dump_file;
-FILE *sched2_dump_file;
-FILE *jump2_opt_dump_file;
-FILE *dbr_sched_dump_file;
-FILE *stack_reg_dump_file;
+FILE *rtl_dump_file = NULL;
 
 /* Time accumulators, to count the total time spent in various passes.  */
 
@@ -976,7 +985,9 @@ int sched_time;
 int local_alloc_time;
 int global_alloc_time;
 int sched2_time;
+#ifdef DELAY_SLOTS
 int dbr_sched_time;
+#endif
 int shorten_branch_time;
 int stack_reg_time;
 int final_time;
@@ -988,46 +999,59 @@ int dump_time;
 int
 get_run_time ()
 {
-#if !defined (_WIN32) || defined (__CYGWIN32__)
-#ifdef USG
-  struct tms tms;
-#else
-#ifndef VMS
-  struct rusage rusage;
-#else
-  struct
-    {
-      int proc_user_time;
-      int proc_system_time;
-      int child_user_time;
-      int child_system_time;
-    } vms_times;
-#endif
-#endif
-#endif
-
   if (quiet_flag)
     return 0;
+
+#ifdef __BEOS__
+  return 0;
+#else /* not BeOS */
 #if defined (_WIN32) && !defined (__CYGWIN32__)
   if (clock() < 0)
     return 0;
   else
     return (clock() * 1000);
 #else /* not _WIN32 */
+#ifdef _SC_CLK_TCK
+  {
+    static int tick;
+    struct tms tms;
+    if (tick == 0)
+      tick = 1000000 / sysconf(_SC_CLK_TCK);
+    times (&tms);
+    return (tms.tms_utime + tms.tms_stime) * tick;
+  }
+#else
 #ifdef USG
-  times (&tms);
-  return (tms.tms_utime + tms.tms_stime) * (1000000 / HZ);
+  {
+    struct tms tms;
+    times (&tms);
+    return (tms.tms_utime + tms.tms_stime) * (1000000 / HZ);
+  }
 #else
 #ifndef VMS
-  getrusage (0, &rusage);
-  return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
-         + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
+  {
+    struct rusage rusage;
+    getrusage (0, &rusage);
+    return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
+           + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
+  }
 #else /* VMS */
-  times (&vms_times);
-  return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000;
-#endif
-#endif
-#endif
+  {
+    struct
+      {
+        int proc_user_time;
+        int proc_system_time;
+        int child_user_time;
+        int child_system_time;
+      } vms_times;
+    times ((void *) &vms_times);
+    return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000;
+  }
+#endif /* VMS */
+#endif /* USG */
+#endif  /* _SC_CLK_TCK */
+#endif /* _WIN32 */
+#endif /* __BEOS__ */
 }
 
 #define TIMEVAR(VAR, BODY)    \
@@ -1097,47 +1121,14 @@ fatal_insn (message, insn)
      char *message;
      rtx insn;
 {
-  if (!output_bytecode)
-    {
-      error (message);
-      debug_rtx (insn);
-    }
+  error (message);
+  debug_rtx (insn);
   if (asm_out_file)
     fflush (asm_out_file);
   if (aux_info_file)
     fflush (aux_info_file);
-  if (rtl_dump_file)
+  if (rtl_dump_file != NULL)
     fflush (rtl_dump_file);
-  if (jump_opt_dump_file)
-    fflush (jump_opt_dump_file);
-  if (addressof_dump_file)
-    fflush (addressof_dump_file);
-  if (cse_dump_file)
-    fflush (cse_dump_file);
-  if (loop_dump_file)
-    fflush (loop_dump_file);
-  if (cse2_dump_file)
-    fflush (cse2_dump_file);
-  if (flow_dump_file)
-    fflush (flow_dump_file);
-  if (combine_dump_file)
-    fflush (combine_dump_file);
-  if (regmove_dump_file)
-    fflush (regmove_dump_file);
-  if (sched_dump_file)
-    fflush (sched_dump_file);
-  if (local_reg_dump_file)
-    fflush (local_reg_dump_file);
-  if (global_reg_dump_file)
-    fflush (global_reg_dump_file);
-  if (sched2_dump_file)
-    fflush (sched2_dump_file);
-  if (jump2_opt_dump_file)
-    fflush (jump2_opt_dump_file);
-  if (dbr_sched_dump_file)
-    fflush (dbr_sched_dump_file);
-  if (stack_reg_dump_file)
-    fflush (stack_reg_dump_file);
   fflush (stdout);
   fflush (stderr);
   abort ();
@@ -1315,7 +1306,7 @@ v_message_with_decl (decl, prefix, s, ap)
      char *s;
      va_list ap;
 {
-  char *n, *p;
+  char *p;
 
   fprintf (stderr, "%s:%d: ",
           DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
@@ -1921,6 +1912,7 @@ do_abort ()
 
 void
 botch (s)
+  char * s;
 {
   abort ();
 }
@@ -2084,20 +2076,23 @@ pipe_closed (signo)
 
 /* Strip off a legitimate source ending from the input string NAME of
    length LEN.  Rather than having to know the names used by all of
-   our front ends, we strip off an ending of a period followed by one,
-   two, or three characters.  */
+   our front ends, we strip off an ending of a period followed by
+   up to five characters.  (Java uses ".class".) */
 
 void
 strip_off_ending (name, len)
      char *name;
      int len;
 {
-  if (len > 2 && name[len - 2] == '.')
-    name[len - 2] = '\0';
-  else if (len > 3 && name[len - 3] == '.')
-    name[len - 3] = '\0';
-  else if (len > 4 && name[len - 4] == '.')
-    name[len - 4] = '\0';
+  int i;
+  for (i = 2;  i < 6 && len > i;  i++)
+    {
+      if (name[len - i] == '.')
+       {
+         name[len - i] = '\0';
+         break;
+       }
+    }
 }
 
 /* Output a quoted string.  */
@@ -2167,23 +2162,97 @@ output_lang_identify (asm_out_file)
 }
 
 /* Routine to open a dump file.  */
+static void
+open_dump_file (suffix, function_name)
+     char *suffix;
+     char *function_name;
+{
+  char *dumpname;
 
-static FILE *
-open_dump_file (base_name, suffix)
-     char *base_name;
+  TIMEVAR
+    (dump_time,
+     {
+       dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1);
+
+       if (rtl_dump_file != NULL)
+        fclose (rtl_dump_file);
+  
+       strcpy (dumpname, dump_base_name);
+       strcat (dumpname, suffix);
+       
+       rtl_dump_file = fopen (dumpname, "a");
+       
+       if (rtl_dump_file == NULL)
+        pfatal_with_name (dumpname);
+       
+       free (dumpname);
+
+       if (function_name)
+        fprintf (rtl_dump_file, "\n;; Function %s\n\n", function_name);
+     });
+  
+  return;
+}
+
+/* Routine to close a dump file.  */
+static void
+close_dump_file (func, insns)
+     void (*func) PROTO ((FILE *, rtx));
+     rtx    insns;
+{
+  TIMEVAR
+    (dump_time,
+     {
+       if (func)
+        func (rtl_dump_file, insns);
+       
+       fflush (rtl_dump_file);
+       fclose (rtl_dump_file);
+       
+       rtl_dump_file = NULL;
+     });
+
+  return;
+}
+
+/* Routine to dump rtl into a file.  */
+static void
+dump_rtl (suffix, decl, func, insns)
      char *suffix;
+     tree   decl;
+     void (*func) PROTO ((FILE *, rtx));
+     rtx    insns;
 {
-  FILE *f;
-  char *dumpname = (char *) alloca (strlen (base_name) + strlen (suffix) + 1);
+  open_dump_file (suffix, decl_printable_name (decl, 2));
+  close_dump_file (func, insns);
+}
 
-  strcpy (dumpname, base_name);
+/* Routine to empty a dump file.  */
+static void
+clean_dump_file (suffix)
+     char * suffix;
+{
+  char * dumpname;
+
+  dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1);
+
+  strcpy (dumpname, dump_base_name);
   strcat (dumpname, suffix);
-  f = fopen (dumpname, "w");
-  if (f == 0)
-    pfatal_with_name (dumpname);
-  return f;
+       
+  rtl_dump_file = fopen (dumpname, "w");
+
+  if (rtl_dump_file == NULL)
+    pfatal_with_name (dumpname);       
+
+  free (dumpname);
+
+  fclose (rtl_dump_file);
+  rtl_dump_file = NULL;
+  
+  return;
 }
 
+
 /* Compile an entire file of output from cpp, named NAME.
    Write a file of assembly output and various debugging dumps.  */
 
@@ -2214,7 +2283,9 @@ compile_file (name)
   local_alloc_time = 0;
   global_alloc_time = 0;
   sched2_time = 0;
+#ifdef DELAY_SLOTS
   dbr_sched_time = 0;
+#endif
   shorten_branch_time = 0;
   stack_reg_time = 0;
   final_time = 0;
@@ -2248,8 +2319,6 @@ compile_file (name)
 #else
   init_lex ();
 #endif
-  /* Some of these really don't need to be called when generating bytecode,
-     but the options would have to be parsed first to know that. -bson */
   init_rtl ();
   init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
                  || debug_info_level == DINFO_LEVEL_VERBOSE
@@ -2262,6 +2331,7 @@ compile_file (name)
   init_expr_once ();
   init_loop ();
   init_reload ();
+  init_alias_once ();
 
   if (flag_caller_saves)
     init_caller_save ();
@@ -2276,76 +2346,48 @@ compile_file (name)
        pfatal_with_name (aux_info_file_name);
     }
 
-  /* If rtl dump desired, open the output file.  */
+  /* Clear the dump files file.  */
   if (rtl_dump)
-    rtl_dump_file = open_dump_file (dump_base_name, ".rtl");
-
-  /* If jump_opt dump desired, open the output file.  */
+    clean_dump_file (".rtl");
   if (jump_opt_dump)
-    jump_opt_dump_file = open_dump_file (dump_base_name, ".jump");
-
-  /* If addressof dump desired, open the output file.  */
+    clean_dump_file (".jump");
   if (addressof_dump)
-    addressof_dump_file = open_dump_file (dump_base_name, ".addressof");
-
-  /* If cse dump desired, open the output file.  */
+    clean_dump_file (".addressof");
   if (cse_dump)
-    cse_dump_file = open_dump_file (dump_base_name, ".cse");
-
-  /* If loop dump desired, open the output file.  */
+    clean_dump_file (".cse");
   if (loop_dump)
-    loop_dump_file = open_dump_file (dump_base_name, ".loop");
-
-  /* If cse2 dump desired, open the output file.  */
+    clean_dump_file (".loop");
   if (cse2_dump)
-    cse2_dump_file = open_dump_file (dump_base_name, ".cse2");
-
-  /* If branch_prob dump desired, open the output file.  */
+    clean_dump_file (".cse2");
   if (branch_prob_dump)
-    branch_prob_dump_file = open_dump_file (dump_base_name, ".bp");
-
-  /* If flow dump desired, open the output file.  */
+    clean_dump_file (".bp");
   if (flow_dump)
-    flow_dump_file = open_dump_file (dump_base_name, ".flow");
-
-  /* If combine dump desired, open the output file.  */
+    clean_dump_file (".flow");
   if (combine_dump)
-    combine_dump_file = open_dump_file (dump_base_name, ".combine");
-
-  /* If regmove dump desired, open the output file.  */
+    clean_dump_file (".combine");
   if (regmove_dump)
-    regmove_dump_file = open_dump_file (dump_base_name, ".regmove");
-
-  /* If scheduling dump desired, open the output file.  */
+    clean_dump_file (".regmove");
   if (sched_dump)
-    sched_dump_file = open_dump_file (dump_base_name, ".sched");
-
-  /* If local_reg dump desired, open the output file.  */
+    clean_dump_file (".sched");
   if (local_reg_dump)
-    local_reg_dump_file = open_dump_file (dump_base_name, ".lreg");
-
-  /* If global_reg dump desired, open the output file.  */
+    clean_dump_file (".lreg");
   if (global_reg_dump)
-    global_reg_dump_file = open_dump_file (dump_base_name, ".greg");
-
-  /* If 2nd scheduling dump desired, open the output file.  */
+    clean_dump_file (".greg");
   if (sched2_dump)
-    sched2_dump_file = open_dump_file (dump_base_name, ".sched2");
-
-  /* If jump2_opt dump desired, open the output file.  */
+    clean_dump_file (".sched2");
   if (jump2_opt_dump)
-    jump2_opt_dump_file = open_dump_file (dump_base_name, ".jump2");
-
-  /* If dbr_sched dump desired, open the output file.  */
+    clean_dump_file (".jump2");
+#ifdef DELAY_SLOTS
   if (dbr_sched_dump)
-    dbr_sched_dump_file = open_dump_file (dump_base_name, ".dbr");
-
+    clean_dump_file (".dbr");
+#endif
 #ifdef STACK_REGS
-
-  /* If stack_reg dump desired, open the output file.  */
   if (stack_reg_dump)
-    stack_reg_dump_file = open_dump_file (dump_base_name, ".stack");
-
+    clean_dump_file (".stack");
+#endif
+#ifdef MACHINE_DEPENDENT_REORG
+  if (mach_dep_reorg_dump)
+    clean_dump_file (".mach");
 #endif
 
   /* Open assembler code output file.  */
@@ -2416,36 +2458,27 @@ compile_file (name)
   if (main_input_filename == 0)
     main_input_filename = name;
 
-  if (!output_bytecode)
-    {
-      ASM_FILE_START (asm_out_file);
+  ASM_FILE_START (asm_out_file);
 
 #ifdef ASM_COMMENT_START
-      if (flag_verbose_asm)
-       {
-         /* Print the list of options in effect.  */
-         print_version (asm_out_file, ASM_COMMENT_START);
-         print_switch_values (asm_out_file, 0, MAX_LINE,
+  if (flag_verbose_asm)
+    {
+      /* Print the list of options in effect.  */
+      print_version (asm_out_file, ASM_COMMENT_START);
+      print_switch_values (asm_out_file, 0, MAX_LINE,
                               ASM_COMMENT_START, " ", "\n");
-         /* Add a blank line here so it appears in assembler output but not
-            screen output.  */
-         fprintf (asm_out_file, "\n");
-       }
-#endif
+      /* Add a blank line here so it appears in assembler output but not
+        screen output.  */
+      fprintf (asm_out_file, "\n");
     }
+#endif
 
-  /* Output something to inform GDB that this compilation was by GCC.  Also
-     serves to tell GDB file consists of bytecodes.  */
-  if (output_bytecode)
-    fprintf (asm_out_file, "bc_gcc2_compiled.:\n");
-  else
-    {
+  /* Output something to inform GDB that this compilation was by GCC.  */
 #ifndef ASM_IDENTIFY_GCC
-      fprintf (asm_out_file, "gcc2_compiled.:\n");
+  fprintf (asm_out_file, "gcc2_compiled.:\n");
 #else
-      ASM_IDENTIFY_GCC (asm_out_file);
+  ASM_IDENTIFY_GCC (asm_out_file);
 #endif
-    }
 
   /* Output something to identify which front-end produced this file.  */
 #ifdef ASM_IDENTIFY_LANGUAGE
@@ -2470,28 +2503,20 @@ compile_file (name)
   if (flag_function_sections && write_symbols != NO_DEBUG)
     warning ("-ffunction-sections may affect debugging on some targets.");
 
-  if (output_bytecode)
-    {
-      if (profile_flag || profile_block_flag)
-       error ("profiling not supported in bytecode compilation");
-    }
-  else
-    {
-      /* ??? Note: There used to be a conditional here
-        to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined.
-        This was to guarantee separation between gcc_compiled. and
-        the first function, for the sake of dbx on Suns.
-        However, having the extra zero here confused the Emacs
-        code for unexec, and might confuse other programs too.
-        Therefore, I took out that change.
-        In future versions we should find another way to solve
-        that dbx problem.  -- rms, 23 May 93.  */
+  /* ??? Note: There used to be a conditional here
+      to call assemble_zeros without fail if DBX_DEBUGGING_INFO is defined.
+      This was to guarantee separation between gcc_compiled. and
+      the first function, for the sake of dbx on Suns.
+      However, having the extra zero here confused the Emacs
+      code for unexec, and might confuse other programs too.
+      Therefore, I took out that change.
+      In future versions we should find another way to solve
+      that dbx problem.  -- rms, 23 May 93.  */
       
-      /* Don't let the first function fall at the same address
-        as gcc_compiled., if profiling.  */
-      if (profile_flag || profile_block_flag)
-       assemble_zeros (UNITS_PER_WORD);
-    }
+  /* Don't let the first function fall at the same address
+     as gcc_compiled., if profiling.  */
+  if (profile_flag || profile_block_flag)
+    assemble_zeros (UNITS_PER_WORD);
 
   /* If dbx symbol table desired, initialize writing it
      and output the predefined types.  */
@@ -2520,8 +2545,7 @@ compile_file (name)
 
   /* Initialize yet another pass.  */
 
-  if (!output_bytecode)
-    init_final (main_input_filename);
+  init_final (main_input_filename);
   init_branch_prob (dump_base_name);
 
   start_time = get_run_time ();
@@ -2777,23 +2801,24 @@ compile_file (name)
 
   /* Output some stuff at end of file if nec.  */
 
-  if (!output_bytecode)
-    {
-      end_final (dump_base_name);
-      end_branch_prob (branch_prob_dump_file);
-
+  end_final (dump_base_name);
+   
+  if (branch_prob_dump)
+    open_dump_file (".bp", NULL);
+   
+  TIMEVAR (dump_time, end_branch_prob (rtl_dump_file));
+   
+  if (branch_prob_dump)
+    close_dump_file (NULL, NULL_RTX);
+   
 #ifdef ASM_FILE_END
-      ASM_FILE_END (asm_out_file);
+  ASM_FILE_END (asm_out_file);
 #endif
-    }
 
   /* Language-specific end of compilation actions.  */
 
   lang_finish ();
 
-  if (output_bytecode)
-    bc_write_file (asm_out_file);
-
   /* Close the dump files.  */
 
   if (flag_gen_aux_info)
@@ -2803,62 +2828,13 @@ compile_file (name)
        unlink (aux_info_file_name);
     }
 
-  if (rtl_dump)
-    fclose (rtl_dump_file);
-
-  if (jump_opt_dump)
-    fclose (jump_opt_dump_file);
-
-  if (addressof_dump)
-    fclose (addressof_dump_file);
-
-  if (cse_dump)
-    fclose (cse_dump_file);
-
-  if (loop_dump)
-    fclose (loop_dump_file);
-
-  if (cse2_dump)
-    fclose (cse2_dump_file);
-
-  if (branch_prob_dump)
-    fclose (branch_prob_dump_file);
-
-  if (flow_dump)
-    fclose (flow_dump_file);
-
   if (combine_dump)
     {
-      dump_combine_total_stats (combine_dump_file);
-      fclose (combine_dump_file);
+      open_dump_file (".combine", NULL);
+      TIMEVAR (dump_time, dump_combine_total_stats (rtl_dump_file));
+      close_dump_file (NULL, NULL_RTX);
     }
 
-  if (regmove_dump)
-    fclose (regmove_dump_file);
-
-  if (sched_dump)
-    fclose (sched_dump_file);
-
-  if (local_reg_dump)
-    fclose (local_reg_dump_file);
-
-  if (global_reg_dump)
-    fclose (global_reg_dump_file);
-
-  if (sched2_dump)
-    fclose (sched2_dump_file);
-
-  if (jump2_opt_dump)
-    fclose (jump2_opt_dump_file);
-
-  if (dbr_sched_dump)
-    fclose (dbr_sched_dump_file);
-
-#ifdef STACK_REGS
-  if (stack_reg_dump)
-    fclose (stack_reg_dump_file);
-#endif
-
   /* Close non-debugging input and output files.  Take special care to note
      whether fclose returns an error, since the pages might still be on the
      buffer chain while the file is open.  */
@@ -2878,29 +2854,28 @@ compile_file (name)
       fprintf (stderr,"\n");
       print_time ("parse", parse_time);
 
-      if (!output_bytecode)
-       {
-         print_time ("integration", integration_time);
-         print_time ("jump", jump_time);
-         print_time ("cse", cse_time);
-         print_time ("loop", loop_time);
-         print_time ("cse2", cse2_time);
-         print_time ("branch-prob", branch_prob_time);
-         print_time ("flow", flow_time);
-         print_time ("combine", combine_time);
-         print_time ("regmove", regmove_time);
-         print_time ("sched", sched_time);
-         print_time ("local-alloc", local_alloc_time);
-         print_time ("global-alloc", global_alloc_time);
-         print_time ("sched2", sched2_time);
-         print_time ("dbranch", dbr_sched_time);
-         print_time ("shorten-branch", shorten_branch_time);
-         print_time ("stack-reg", stack_reg_time);
-         print_time ("final", final_time);
-         print_time ("varconst", varconst_time);
-         print_time ("symout", symout_time);
-         print_time ("dump", dump_time);
-       }
+      print_time ("integration", integration_time);
+      print_time ("jump", jump_time);
+      print_time ("cse", cse_time);
+      print_time ("loop", loop_time);
+      print_time ("cse2", cse2_time);
+      print_time ("branch-prob", branch_prob_time);
+      print_time ("flow", flow_time);
+      print_time ("combine", combine_time);
+      print_time ("regmove", regmove_time);
+      print_time ("sched", sched_time);
+      print_time ("local-alloc", local_alloc_time);
+      print_time ("global-alloc", global_alloc_time);
+      print_time ("sched2", sched2_time);
+#ifdef DELAY_SLOTS
+      print_time ("dbranch", dbr_sched_time);
+#endif
+      print_time ("shorten-branch", shorten_branch_time);
+      print_time ("stack-reg", stack_reg_time);
+      print_time ("final", final_time);
+      print_time ("varconst", varconst_time);
+      print_time ("symout", symout_time);
+      print_time ("dump", dump_time);
     }
 }
 \f
@@ -2951,8 +2926,7 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
                        && (DECL_INITIAL (decl) == 0
                            || DECL_INITIAL (decl) == error_mark_node)))
                   assemble_variable (decl, top_level, at_end, 0);
-              if (!output_bytecode
-                  && decl == last_assemble_variable_decl)
+              if (decl == last_assemble_variable_decl)
                 {
                   ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
                                              top_level, at_end);
@@ -3018,15 +2992,12 @@ rest_of_compilation (decl)
   tree saved_arguments = 0;
   int failure = 0;
 
-  if (output_bytecode)
-    return;
-
   /* If we are reconsidering an inline function
      at the end of compilation, skip the stuff for making it inline.  */
 
   if (DECL_SAVED_INSNS (decl) == 0)
     {
-      int inlineable = 0;
+      int inlinable = 0;
       char *lose;
 
       /* If requested, consider whether to make this function inline.  */
@@ -3053,7 +3024,7 @@ rest_of_compilation (decl)
                        like "inline" was specified for a function if we choose
                        to inline it.  This isn't quite right, but it's
                        probably not worth the trouble to fix.  */
-                    inlineable = DECL_INLINE (decl) = 1;
+                    inlinable = DECL_INLINE (decl) = 1;
                 });
 
       insns = get_insns ();
@@ -3061,19 +3032,18 @@ rest_of_compilation (decl)
       /* Dump the rtl code if we are dumping rtl.  */
 
       if (rtl_dump)
-       TIMEVAR (dump_time,
-                {
-                  fprintf (rtl_dump_file, "\n;; Function %s\n\n",
-                           (*decl_printable_name) (decl, 2));
-                  if (DECL_SAVED_INSNS (decl))
-                    fprintf (rtl_dump_file, ";; (integrable)\n\n");
-                  print_rtl (rtl_dump_file, insns);
-                  fflush (rtl_dump_file);
-                });
+       {
+         open_dump_file (".rtl", decl_printable_name (decl, 2));
+         
+         if (DECL_SAVED_INSNS (decl))
+           fprintf (rtl_dump_file, ";; (integrable)\n\n");
+         
+         close_dump_file (print_rtl, insns);
+       }
 
       /* If we can, defer compiling inlines until EOF.
         save_for_inline_copying can be extremely expensive.  */
-      if (inlineable && ! decl_function_context (decl))
+      if (inlinable && ! decl_function_context (decl))
        DECL_DEFER_OUTPUT (decl) = 1;
 
       /* If function is inline, and we don't yet know whether to
@@ -3088,7 +3058,7 @@ rest_of_compilation (decl)
         finish compiling ourselves.  Otherwise, wait until EOF.
         We have to do this because the purge_addressof transformation
         changes the DECL_RTL for many variables, which confuses integrate.  */
-      if (inlineable)
+      if (inlinable)
        {
          if (decl_function_context (decl))
            purge_addressof (insns);
@@ -3105,40 +3075,53 @@ rest_of_compilation (decl)
        {
          DECL_DEFER_OUTPUT (decl) = 1;
 
-         /* If -Wreturn-type, we have to do a bit of compilation.  */
-         if (! warn_return_type)
+         /* If -Wreturn-type, we have to do a bit of compilation.
+            However, if we just fall through we will call
+            save_for_inline_copying() which results in excessive
+            memory use.  Instead, we just want to call
+            jump_optimize() to figure out whether or not we can fall
+            off the end of the function; we do the minimum amount of
+            work necessary to make that safe.  And, we set optimize
+            to zero to keep jump_optimize from working too hard.  */
+         if (warn_return_type)
            {
+             int saved_optimize = optimize;
+             optimize = 0;
+             find_exception_handler_labels ();
+             jump_optimize (get_insns(), 0, 0, 0);
+             optimize = saved_optimize;
+           }
+
 #ifdef DWARF_DEBUGGING_INFO
-             /* Generate the DWARF info for the "abstract" instance
-                of a function which we may later generate inlined and/or
-                out-of-line instances of.  */
-             if (write_symbols == DWARF_DEBUG)
-               {
-                 set_decl_abstract_flags (decl, 1);
-                 TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
-                 set_decl_abstract_flags (decl, 0);
-               }
+         /* Generate the DWARF info for the "abstract" instance
+            of a function which we may later generate inlined and/or
+            out-of-line instances of.  */
+         if (write_symbols == DWARF_DEBUG)
+           {
+             set_decl_abstract_flags (decl, 1);
+             TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
+             set_decl_abstract_flags (decl, 0);
+           }
 #endif
 #ifdef DWARF2_DEBUGGING_INFO
-             /* Generate the DWARF2 info for the "abstract" instance
-                of a function which we may later generate inlined and/or
-                out-of-line instances of.  */
-             if (write_symbols == DWARF2_DEBUG)
-               {
-                 set_decl_abstract_flags (decl, 1);
-                 TIMEVAR (symout_time, dwarf2out_decl (decl));
-                 set_decl_abstract_flags (decl, 0);
-               }
-#endif
-             TIMEVAR (integration_time, save_for_inline_nocopy (decl));
-             RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlineable;
-             goto exit_rest_of_compilation;
+         /* Generate the DWARF2 info for the "abstract" instance
+            of a function which we may later generate inlined and/or
+            out-of-line instances of.  */
+         if (write_symbols == DWARF2_DEBUG)
+           {
+             set_decl_abstract_flags (decl, 1);
+             TIMEVAR (symout_time, dwarf2out_decl (decl));
+             set_decl_abstract_flags (decl, 0);
            }
+#endif
+         TIMEVAR (integration_time, save_for_inline_nocopy (decl));
+         RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable;
+         goto exit_rest_of_compilation;
        }
 
       /* If we have to compile the function now, save its rtl and subdecls
         so that its compilation will not affect what others get.  */
-      if (inlineable || DECL_DEFER_OUTPUT (decl))
+      if (inlinable || DECL_DEFER_OUTPUT (decl))
        {
 #ifdef DWARF_DEBUGGING_INFO
          /* Generate the DWARF info for the "abstract" instance of
@@ -3167,7 +3150,7 @@ rest_of_compilation (decl)
          saved_block_tree = DECL_INITIAL (decl);
          saved_arguments = DECL_ARGUMENTS (decl);
          TIMEVAR (integration_time, save_for_inline_copying (decl));
-         RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlineable;
+         RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlinable;
        }
 
       /* If specified extern inline but we aren't inlining it, we are
@@ -3190,9 +3173,8 @@ rest_of_compilation (decl)
       goto exit_rest_of_compilation;
     }
 
-  /* Add an unwinder for exception handling, if needed.
-     This must be done before we finalize PIC code.  */
-  emit_unwinder ();
+  /* Emit code to get eh context, if needed. */
+  emit_eh_context ();
 
 #ifdef FINALIZE_PIC
   /* If we are doing position-independent code generation, now
@@ -3218,6 +3200,12 @@ rest_of_compilation (decl)
 
   unshare_all_rtl (insns);
 
+#ifdef SETJMP_VIA_SAVE_AREA
+  /* This must be performed before virutal register instantiation.  */
+  if (current_function_calls_alloca)
+    optimize_save_area_alloca (insns);
+#endif
+
   /* Instantiate all virtual registers.  */
 
   instantiate_virtual_regs (current_function_decl, get_insns ());
@@ -3242,29 +3230,19 @@ rest_of_compilation (decl)
 
   /* Dump rtl code after jump, if we are doing that.  */
 
-  if (jump_opt_dump)
-    TIMEVAR (dump_time,
-            {
-              fprintf (jump_opt_dump_file, "\n;; Function %s\n\n",
-                       (*decl_printable_name) (decl, 2));
-              print_rtl (jump_opt_dump_file, insns);
-              fflush (jump_opt_dump_file);
-            });
+    if (jump_opt_dump)
+      dump_rtl (".jump", decl, print_rtl, insns);
 
   /* Perform common subexpression elimination.
      Nonzero value from `cse_main' means that jumps were simplified
      and some code may now be unreachable, so do
      jump optimization again.  */
 
-  if (cse_dump)
-    TIMEVAR (dump_time,
-            {
-              fprintf (cse_dump_file, "\n;; Function %s\n\n",
-                       (*decl_printable_name) (decl, 2));
-            });
-
   if (optimize > 0)
     {
+      if (cse_dump)
+       open_dump_file (".cse", decl_printable_name (decl, 2));
+
       TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 1));
 
       if (flag_thread_jumps)
@@ -3272,140 +3250,104 @@ rest_of_compilation (decl)
        TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 1));
 
       TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (),
-                                        0, cse_dump_file));
+                                        0, rtl_dump_file));
       TIMEVAR (cse_time, delete_dead_from_cse (insns, max_reg_num ()));
 
       if (tem || optimize > 1)
        TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 0));
-    }
-
-  /* Dump rtl code after cse, if we are doing that.  */
 
-  if (cse_dump)
-    TIMEVAR (dump_time,
-            {
-              print_rtl (cse_dump_file, insns);
-              fflush (cse_dump_file);
-            });
+      /* Dump rtl code after cse, if we are doing that.  */
+      
+      if (cse_dump)
+       close_dump_file (print_rtl, insns);
+    }
 
   purge_addressof (insns);
   reg_scan (insns, max_reg_num (), 1);
 
   if (addressof_dump)
-    TIMEVAR (dump_time,
-            {
-              fprintf (addressof_dump_file, "\n;; Function %s\n\n",
-                       (*decl_printable_name) (decl, 2));
-              print_rtl (addressof_dump_file, insns);
-              fflush (addressof_dump_file);
-            });
-
-  if (loop_dump)
-    TIMEVAR (dump_time,
-            {
-              fprintf (loop_dump_file, "\n;; Function %s\n\n",
-                       (*decl_printable_name) (decl, 2));
-            });
-
+    dump_rtl (".addressof", decl, print_rtl, insns);
+  
   /* Move constant computations out of loops.  */
 
   if (optimize > 0)
     {
-      TIMEVAR (loop_time,
-              {
-                int save_flag_unroll_loops;
-                int save_flag_unroll_all_loops;
-
-                if (flag_rerun_loop_opt)
-                  {
-                     /* We only want to perform unrolling once.  */
-                     save_flag_unroll_loops = flag_unroll_loops;
-                     save_flag_unroll_all_loops = flag_unroll_all_loops;
-                     flag_unroll_loops = 0;
-                     flag_unroll_all_loops = 0;
-
-                     loop_optimize (insns, loop_dump_file);
-
-                     /* The regscan pass may not be necessary, but let's
-                        be safe until we can prove otherwise.  */
-                     reg_scan (insns, max_reg_num (), 1);
-
-                     /* Restore loop unrolling flags.  */
-                     flag_unroll_loops = save_flag_unroll_loops;
-                     flag_unroll_all_loops = save_flag_unroll_all_loops;
-                  }
-                loop_optimize (insns, loop_dump_file);
-              });
-    }
-
-  /* Dump rtl code after loop opt, if we are doing that.  */
-
-  if (loop_dump)
-    TIMEVAR (dump_time,
+      if (loop_dump)
+       open_dump_file (".loop", decl_printable_name (decl, 2));
+       
+      TIMEVAR
+       (loop_time,
+        {
+          if (flag_rerun_loop_opt)
             {
-              print_rtl (loop_dump_file, insns);
-              fflush (loop_dump_file);
-            });
-
-  if (cse2_dump)
-    TIMEVAR (dump_time,
-            {
-              fprintf (cse2_dump_file, "\n;; Function %s\n\n",
-                       (*decl_printable_name) (decl, 2));
-            });
-
-  if (optimize > 0 && flag_rerun_cse_after_loop)
-    {
-      /* Running another jump optimization pass before the second
-        cse pass sometimes simplifies the RTL enough to allow
-        the second CSE pass to do a better job.  Jump_optimize can change
-        max_reg_num so we must rerun reg_scan afterwards.
-        ??? Rework to not call reg_scan so often.  */
-      TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
-      TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 1));
-
-      TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0));
-      TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (),
-                                         1, cse2_dump_file));
-      if (tem)
-       TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 0));
+              /* We only want to perform unrolling once.  */
+              
+              loop_optimize (insns, rtl_dump_file, 0);
+              
+              /* The regscan pass may not be necessary, but let's
+                 be safe until we can prove otherwise.  */
+              reg_scan (insns, max_reg_num (), 1);
+            }
+          loop_optimize (insns, rtl_dump_file, flag_unroll_loops);
+        });
+      
+      /* Dump rtl code after loop opt, if we are doing that.  */
+      
+      if (loop_dump)
+       close_dump_file (print_rtl, insns);
     }
 
-  if (optimize > 0 && flag_thread_jumps)
+  if (optimize > 0)
     {
-      /* This pass of jump threading straightens out code
-         that was kinked by loop optimization.  */
-      TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
-      TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0));
-    }
-  /* Dump rtl code after cse, if we are doing that.  */
-
-  if (cse2_dump)
-    TIMEVAR (dump_time,
-            {
-              print_rtl (cse2_dump_file, insns);
-              fflush (cse2_dump_file);
-            });
-
-  if (branch_prob_dump)
-    TIMEVAR (dump_time,
-            {
-              fprintf (branch_prob_dump_file, "\n;; Function %s\n\n",
-                       (*decl_printable_name) (decl, 2));
-            });
+      if (cse2_dump)
+       open_dump_file (".cse2", decl_printable_name (decl, 2));
+      
+      if (flag_rerun_cse_after_loop)
+       {
+         /* Running another jump optimization pass before the second
+            cse pass sometimes simplifies the RTL enough to allow
+            the second CSE pass to do a better job.  Jump_optimize can change
+            max_reg_num so we must rerun reg_scan afterwards.
+            ??? Rework to not call reg_scan so often.  */
+         TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
+         TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 1));
+         
+         TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0));
+         TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (),
+                                             1, rtl_dump_file));
+         if (tem)
+           TIMEVAR (jump_time, jump_optimize (insns, 0, 0, 0));
+       }
 
+      if (flag_thread_jumps)
+       {
+         /* This pass of jump threading straightens out code
+            that was kinked by loop optimization.  */
+         TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
+         TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0));
+       }
+      
+      /* Dump rtl code after cse, if we are doing that.  */
+      
+      if (cse2_dump)
+       close_dump_file (print_rtl, insns);
+    }
+  
   if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
-    TIMEVAR (branch_prob_time,
-            {
-              branch_prob (insns, branch_prob_dump_file);
-            });
-
-  if (branch_prob_dump)
-    TIMEVAR (dump_time,
-            {
-              print_rtl (branch_prob_dump_file, insns);
-              fflush (branch_prob_dump_file);
-            });
+    {
+      if (branch_prob_dump)
+       open_dump_file (".bp", decl_printable_name (decl, 2));
+    
+      TIMEVAR
+       (branch_prob_time,
+        {
+          branch_prob (insns, rtl_dump_file);
+        });
+      
+      if (branch_prob_dump)
+       close_dump_file (print_rtl, insns);
+    }
+  
   /* We are no longer anticipating cse in this function, at least.  */
 
   cse_not_expected = 1;
@@ -3423,19 +3365,15 @@ rest_of_compilation (decl)
      because doing the flow analysis makes some of the dump.  */
 
   if (flow_dump)
-    TIMEVAR (dump_time,
-            {
-              fprintf (flow_dump_file, "\n;; Function %s\n\n",
-                       (*decl_printable_name) (decl, 2));
-            });
-
+    open_dump_file (".flow", decl_printable_name (decl, 2));
+  
   if (obey_regdecls)
     {
       TIMEVAR (flow_time,
               {
                 regclass (insns, max_reg_num ());
                 stupid_life_analysis (insns, max_reg_num (),
-                                      flow_dump_file);
+                                      rtl_dump_file);
               });
     }
   else
@@ -3443,8 +3381,13 @@ rest_of_compilation (decl)
       /* Do control and data flow analysis,
         and write some of the results to dump file.  */
 
-      TIMEVAR (flow_time, flow_analysis (insns, max_reg_num (),
-                                        flow_dump_file));
+      TIMEVAR
+       (flow_time,
+        {
+          find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
+          life_analysis (insns, max_reg_num (), rtl_dump_file);
+        });
+
       if (warn_uninitialized)
        {
          uninitialized_vars_warning (DECL_INITIAL (decl));
@@ -3455,76 +3398,53 @@ rest_of_compilation (decl)
   /* Dump rtl after flow analysis.  */
 
   if (flow_dump)
-    TIMEVAR (dump_time,
-            {
-              print_rtl_with_bb (flow_dump_file, insns);
-              fflush (flow_dump_file);
-            });
-
+    close_dump_file (print_rtl_with_bb, insns);
+  
   /* If -opt, try combining insns through substitution.  */
 
   if (optimize > 0)
-    TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
-
-  /* Dump rtl code after insn combination.  */
-
-  if (combine_dump)
-    TIMEVAR (dump_time,
-            {
-              fprintf (combine_dump_file, "\n;; Function %s\n\n",
-                       (*decl_printable_name) (decl, 2));
-              dump_combine_stats (combine_dump_file);
-              print_rtl_with_bb (combine_dump_file, insns);
-              fflush (combine_dump_file);
-            });
-
-  if (regmove_dump)
-    TIMEVAR (dump_time,
-            {
-              fprintf (regmove_dump_file, "\n;; Function %s\n\n",
-                       (*decl_printable_name) (decl, 2));
-            });
+    {
+      TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
+      
+      /* Dump rtl code after insn combination.  */
+      
+      if (combine_dump)
+       dump_rtl (".combine", decl, print_rtl_with_bb, insns);
+    }
 
   /* Register allocation pre-pass, to reduce number of moves
      necessary for two-address machines.  */
-  if (optimize > 0 && flag_regmove)
-    TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (),
-                                            regmove_dump_file));
-
-  if (regmove_dump)
-    TIMEVAR (dump_time,
-            {
-              print_rtl_with_bb (regmove_dump_file, insns);
-              fflush (regmove_dump_file);
-            });
+  if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
+    {
+      if (regmove_dump)
+       open_dump_file (".regmove", decl_printable_name (decl, 2));
+      
+      TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (),
+                                              rtl_dump_file));
+      
+      if (regmove_dump)
+       close_dump_file (print_rtl_with_bb, insns);
+    }
 
   /* Print function header into sched dump now
      because doing the sched analysis makes some of the dump.  */
 
-  if (sched_dump)
-    TIMEVAR (dump_time,
-            {
-              fprintf (sched_dump_file, "\n;; Function %s\n\n",
-                       (*decl_printable_name) (decl, 2));
-            });
-
   if (optimize > 0 && flag_schedule_insns)
     {
+      if (sched_dump)
+       open_dump_file (".sched", decl_printable_name (decl, 2));
+      
       /* Do control and data sched analysis,
         and write some of the results to dump file.  */
 
-      TIMEVAR (sched_time, schedule_insns (sched_dump_file));
+      TIMEVAR (sched_time, schedule_insns (rtl_dump_file));
+      
+      /* Dump rtl after instruction scheduling.  */
+      
+      if (sched_dump)
+       close_dump_file (print_rtl_with_bb, insns);
     }
 
-  /* Dump rtl after instruction scheduling.  */
-
-  if (sched_dump)
-    TIMEVAR (dump_time,
-            {
-              print_rtl_with_bb (sched_dump_file, insns);
-              fflush (sched_dump_file);
-            });
-
   /* Unless we did stupid register allocation,
      allocate pseudo-regs that are used only within 1 basic block.  */
 
@@ -3538,20 +3458,17 @@ rest_of_compilation (decl)
   /* Dump rtl code after allocating regs within basic blocks.  */
 
   if (local_reg_dump)
-    TIMEVAR (dump_time,
-            {
-              fprintf (local_reg_dump_file, "\n;; Function %s\n\n",
-                       (*decl_printable_name) (decl, 2));
-              dump_flow_info (local_reg_dump_file);
-              dump_local_alloc (local_reg_dump_file);
-              print_rtl_with_bb (local_reg_dump_file, insns);
-              fflush (local_reg_dump_file);
-            });
+    {
+      open_dump_file (".lreg", decl_printable_name (decl, 2));
+      
+      TIMEVAR (dump_time, dump_flow_info (rtl_dump_file));
+      TIMEVAR (dump_time, dump_local_alloc (rtl_dump_file));
+      
+      close_dump_file (print_rtl_with_bb, insns);
+    }
 
   if (global_reg_dump)
-    TIMEVAR (dump_time,
-            fprintf (global_reg_dump_file, "\n;; Function %s\n\n",
-                     (*decl_printable_name) (decl, 2)));
+    open_dump_file (".greg", decl_printable_name (decl, 2));
 
   /* Save the last label number used so far, so reorg can tell
      when it's safe to kill spill regs.  */
@@ -3564,18 +3481,16 @@ rest_of_compilation (decl)
   TIMEVAR (global_alloc_time,
           {
             if (!obey_regdecls)
-              failure = global_alloc (global_reg_dump_file);
+              failure = global_alloc (rtl_dump_file);
             else
-              failure = reload (insns, 0, global_reg_dump_file);
+              failure = reload (insns, 0, rtl_dump_file);
           });
 
   if (global_reg_dump)
-    TIMEVAR (dump_time,
-            {
-              dump_global_regs (global_reg_dump_file);
-              print_rtl_with_bb (global_reg_dump_file, insns);
-              fflush (global_reg_dump_file);
-            });
+    {
+      TIMEVAR (dump_time, dump_global_regs (rtl_dump_file));
+      close_dump_file (print_rtl_with_bb, insns);
+    }
 
   if (failure)
     goto exit_rest_of_compilation;
@@ -3596,25 +3511,17 @@ rest_of_compilation (decl)
   if (optimize > 0 && flag_schedule_insns_after_reload)
     {
       if (sched2_dump)
-       TIMEVAR (dump_time,
-                {
-                  fprintf (sched2_dump_file, "\n;; Function %s\n\n",
-                           (*decl_printable_name) (decl, 2));
-                });
+       open_dump_file (".sched2", decl_printable_name (decl, 2));
 
       /* Do control and data sched analysis again,
         and write some more of the results to dump file.  */
 
-      TIMEVAR (sched2_time, schedule_insns (sched2_dump_file));
+      TIMEVAR (sched2_time, schedule_insns (rtl_dump_file));
 
       /* Dump rtl after post-reorder instruction scheduling.  */
 
       if (sched2_dump)
-       TIMEVAR (dump_time,
-                {
-                  print_rtl_with_bb (sched2_dump_file, insns);
-                  fflush (sched2_dump_file);
-                });
+       close_dump_file (print_rtl_with_bb, insns);
     }
 
 #ifdef LEAF_REGISTERS
@@ -3631,22 +3538,19 @@ rest_of_compilation (decl)
   if (optimize > 0)
     {
       TIMEVAR (jump_time, jump_optimize (insns, 1, 1, 0));
-    }
-
-  /* Dump rtl code after jump, if we are doing that.  */
+      
+      /* Dump rtl code after jump, if we are doing that.  */
 
-  if (jump2_opt_dump)
-    TIMEVAR (dump_time,
-            {
-              fprintf (jump2_opt_dump_file, "\n;; Function %s\n\n",
-                       (*decl_printable_name) (decl, 2));
-              print_rtl_with_bb (jump2_opt_dump_file, insns);
-              fflush (jump2_opt_dump_file);
-            });
+      if (jump2_opt_dump)
+       dump_rtl (".jump2", decl, print_rtl_with_bb, insns);
+    }
 
   /* If a machine dependent reorganization is needed, call it.  */
 #ifdef MACHINE_DEPENDENT_REORG
    MACHINE_DEPENDENT_REORG (insns);
+
+   if (mach_dep_reorg_dump)
+     dump_rtl (".mach", decl, print_rtl_with_bb, insns);
 #endif
 
   /* If a scheduling pass for delayed branches is to be done,
@@ -3655,17 +3559,10 @@ rest_of_compilation (decl)
 #ifdef DELAY_SLOTS
   if (optimize > 0 && flag_delayed_branch)
     {
-      TIMEVAR (dbr_sched_time, dbr_schedule (insns, dbr_sched_dump_file));
+      TIMEVAR (dbr_sched_time, dbr_schedule (insns, rtl_dump_file));
+      
       if (dbr_sched_dump)
-       {
-         TIMEVAR (dump_time,
-                {
-                  fprintf (dbr_sched_dump_file, "\n;; Function %s\n\n",
-                           (*decl_printable_name) (decl, 2));
-                  print_rtl_with_bb (dbr_sched_dump_file, insns);
-                  fflush (dbr_sched_dump_file);
-                });
-       }
+       dump_rtl (".dbr", decl, print_rtl_with_bb, insns);
     }
 #endif
 
@@ -3676,17 +3573,10 @@ rest_of_compilation (decl)
           });
 
 #ifdef STACK_REGS
-  TIMEVAR (stack_reg_time, reg_to_stack (insns, stack_reg_dump_file));
+  TIMEVAR (stack_reg_time, reg_to_stack (insns, rtl_dump_file));
+
   if (stack_reg_dump)
-    {
-      TIMEVAR (dump_time,
-              {
-                fprintf (stack_reg_dump_file, "\n;; Function %s\n\n",
-                         (*decl_printable_name) (decl, 2));
-                print_rtl_with_bb (stack_reg_dump_file, insns);
-                fflush (stack_reg_dump_file);
-              });
-    }
+    dump_rtl (".stack", decl, print_rtl_with_bb, insns);
 #endif
 
   /* Now turn the rtl into assembler code.  */
@@ -3819,7 +3709,7 @@ main (argc, argv, envp)
     --p;
   progname = p;
 
-#ifdef RLIMIT_STACK
+#if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
   /* Get rid of any avoidable limit on stack size.  */
   {
     struct rlimit rlim;
@@ -3829,7 +3719,7 @@ main (argc, argv, envp)
     rlim.rlim_cur = rlim.rlim_max;
     setrlimit (RLIMIT_STACK, &rlim);
   }
-#endif /* RLIMIT_STACK */
+#endif
 
   signal (SIGFPE, float_signal);
 
@@ -3857,18 +3747,27 @@ main (argc, argv, envp)
        }
       else if (argv[i][0] == '-' && argv[i][1] == 'O')
        {
-         /* Handle -O2, -O3, -O69, ...  */
+         /* Handle -Os, -O2, -O3, -O69, ...  */
          char *p = &argv[i][2];
          int c;
-
-         while (c = *p++)
-           if (! (c >= '0' && c <= '9'))
-             break;
-         if (c == 0)
-           optimize = atoi (&argv[i][2]);
+         
+         if ((p[0] == 's') && (p[1] == 0))
+           optimize_size = 1;
+         else
+           {       
+             while ((c = *p++))
+               if (! (c >= '0' && c <= '9'))
+                 break;
+             if (c == 0)
+               optimize = atoi (&argv[i][2]);
+           }
        }
     }
 
+  /* Optimizing for size forces optimize to be no less than 2. */
+  if (optimize_size && (optimize < 2))
+    optimize = 2;
+    
   obey_regdecls = (optimize == 0);
 
   if (optimize >= 1)
@@ -3881,7 +3780,6 @@ main (argc, argv, envp)
 #ifdef CAN_DEBUG_WITHOUT_FP
       flag_omit_frame_pointer = 1;
 #endif
-      flag_alias_check = 1;
     }
 
   if (optimize >= 2)
@@ -3913,7 +3811,7 @@ main (argc, argv, envp)
 
 #ifdef OPTIMIZATION_OPTIONS
   /* Allow default optimizations to be specified on a per-machine basis.  */
-  OPTIMIZATION_OPTIONS (optimize);
+  OPTIMIZATION_OPTIONS (optimize, optimize_size);
 #endif
 
   /* Initialize register usage now so switches may override.  */
@@ -3953,7 +3851,9 @@ main (argc, argv, envp)
                  case 'a':
                    branch_prob_dump = 1;
                    combine_dump = 1;
+#ifdef DELAY_SLOTS
                    dbr_sched_dump = 1;
+#endif
                    flow_dump = 1;
                    global_reg_dump = 1;
                    jump_opt_dump = 1;
@@ -3966,20 +3866,29 @@ main (argc, argv, envp)
                    cse_dump = 1, cse2_dump = 1;
                    sched_dump = 1;
                    sched2_dump = 1;
+#ifdef STACK_REGS
                    stack_reg_dump = 1;
+#endif
+#ifdef MACHINE_DEPENDENT_REORG
+                   mach_dep_reorg_dump = 1;
+#endif
                    break;
                  case 'b':
                    branch_prob_dump = 1;
                    break;
+#ifdef STACK_REGS                  
                  case 'k':
                    stack_reg_dump = 1;
                    break;
+#endif
                  case 'c':
                    combine_dump = 1;
                    break;
+#ifdef DELAY_SLOTS
                  case 'd':
                    dbr_sched_dump = 1;
                    break;
+#endif
                  case 'f':
                    flow_dump = 1;
                    break;
@@ -4004,6 +3913,11 @@ main (argc, argv, envp)
                  case 'm':
                    flag_print_mem = 1;
                    break;
+#ifdef MACHINE_DEPENDENT_REORG
+                 case 'M':
+                   mach_dep_reorg_dump = 1;
+                   break;
+#endif
                  case 'p':
                    flag_print_asm_name = 1;
                    break;
@@ -4034,6 +3948,9 @@ main (argc, argv, envp)
                  case 'A':
                    flag_debug_asm = 1;
                    break;
+                 default:
+                   warning ("unrecognised gcc debugging option: %c", p[-1]);
+                   break;
                  }
            }
          else if (str[0] == 'f')
@@ -4090,8 +4007,11 @@ main (argc, argv, envp)
          else if (str[0] == 'O')
            {
              register char *p = str+1;
-             while (*p && *p >= '0' && *p <= '9')
+             if (*p == 's')
                p++;
+             else
+               while (*p && *p >= '0' && *p <= '9')
+                 p++;
              if (*p == '\0')
                ;
              else
@@ -4271,7 +4191,16 @@ main (argc, argv, envp)
                      while (*q && (*q >= '0' && *q <= '9'))
                        q++;
                      if (*p)
-                       level = atoi (p);
+                       {
+                         level = atoi (p);
+                         if (len > 1 && !strncmp (str, "gdwarf", len))
+                           {
+                             error ("use -gdwarf -g%d for DWARF v1, level %d",
+                                      level, level);
+                             if (level == 2)
+                               error ("use -gdwarf-2   for DWARF v2");
+                           }
+                       }
                      else
                        level = 2;      /* default debugging info level */
                      if (*q || level > 3)
@@ -4289,7 +4218,7 @@ main (argc, argv, envp)
                          type = PREFERRED_DEBUGGING_TYPE;
                          if (len > 1 && strncmp (str, "ggdb", len) == 0)
                            {
-#ifdef DWARF2_DEBUGGING_INFO
+#if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2)
                              type = DWARF2_DEBUG;
 #else
 #ifdef DBX_DEBUGGING_INFO
@@ -4362,18 +4291,6 @@ main (argc, argv, envp)
   if (flag_check_memory_usage)
     flag_omit_frame_pointer = 0;
 
-  /* Initialize for bytecode output.  A good idea to do this as soon as
-     possible after the "-f" options have been parsed.  */
-  if (output_bytecode)
-    {
-#ifndef TARGET_SUPPORTS_BYTECODE
-      /* Just die with a fatal error if not supported */
-      fatal ("-fbytecode not supported for this target");
-#else
-      bc_initialize ();
-#endif
-    }
-
   if (optimize == 0)
     {
       /* Inlining does not work if not optimizing,