* Check in merge from gcc2. See ChangeLog.11 and ChangeLog.12
[gcc.git] / gcc / toplev.c
index 8635e81e0297c1dc77c60d2f79d525e89e033bc9..d226950dfecc9836cf9d2adcdc56e6aa4fd58dad 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.
 
@@ -29,28 +29,19 @@ Boston, MA 02111-1307, USA.  */
 #else
 #include <varargs.h>
 #endif
-#include <stdio.h>
+#undef FLOAT /* This is for hpux. They should change hpux.  */
+#undef FFS  /* Some systems define this in param.h.  */
+#include "system.h"
 #include <signal.h>
 #include <setjmp.h>
-#include <sys/types.h>
-#include <ctype.h>
 #include <sys/stat.h>
 
-#ifndef _WIN32
-#ifdef USG
-#undef FLOAT
-#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?  */
-#undef FFS  /* Some systems define this in param.h.  */
-#else
-#ifndef VMS
-#include <sys/time.h>
-#include <sys/resource.h>
-#endif
+#ifdef HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
 #endif
+
+#ifdef HAVE_SYS_TIMES_H
+# include <sys/times.h>
 #endif
 
 #include "input.h"
@@ -58,10 +49,11 @@ Boston, MA 02111-1307, USA.  */
 #include "rtl.h"
 #include "flags.h"
 #include "insn-attr.h"
+#include "insn-codes.h"
+#include "insn-config.h"
+#include "recog.h"
 #include "defaults.h"
 #include "output.h"
-#include "bytecode.h"
-#include "bc-emit.h"
 #include "except.h"
 
 #ifdef XCOFF_DEBUGGING_INFO
@@ -153,6 +145,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, ...));
@@ -169,9 +164,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 ();
 
@@ -181,7 +173,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
 
@@ -204,9 +200,10 @@ char *input_filename;
 
 char *main_input_filename;
 
+#if !USE_CPPLIB
 /* Stream for reading from the input file.  */
-
 FILE *finput;
+#endif
 
 /* Current line number in real source file.  */
 
@@ -238,20 +235,29 @@ extern int target_flags;
 int rtl_dump = 0;
 int rtl_dump_and_exit = 0;
 int jump_opt_dump = 0;
+int addressof_dump = 0;
 int cse_dump = 0;
 int loop_dump = 0;
 int cse2_dump = 0;
 int branch_prob_dump = 0;
 int flow_dump = 0;
 int combine_dump = 0;
+int regmove_dump = 0;
 int sched_dump = 0;
 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.  */
 
@@ -285,15 +291,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:
@@ -444,6 +454,16 @@ int flag_unroll_loops;
 
 int flag_unroll_all_loops;
 
+/* Nonzero forces all invariant computations in loops to be moved
+   outside the loop. */
+
+int flag_move_all_movables = 0;
+
+/* Nonzero forces all general induction variables in loops to be
+   strength reduced. */
+
+int flag_reduce_all_givs = 0;
+
 /* Nonzero for -fwritable-strings:
    store string constants in data segment and don't uniquize them.  */
 
@@ -493,6 +513,10 @@ int flag_syntax_only = 0;
 
 static int flag_rerun_cse_after_loop;
 
+/* Nonzero means to run loop optimizations twice.  */
+
+int flag_rerun_loop_opt;
+
 /* Nonzero for -finline-functions: ok to inline functions that look like
    good inline candidates.  */
 
@@ -539,7 +563,7 @@ int flag_pic;
 /* Nonzero means generate extra code for exception handling and enable
    exception handling.  */
 
-int flag_exceptions = 1;
+int flag_exceptions = 2;
 
 /* Nonzero means don't place uninitialized global data in common storage
    by default.  */
@@ -565,6 +589,28 @@ int flag_pedantic_errors = 0;
 int flag_schedule_insns = 0;
 int flag_schedule_insns_after_reload = 0;
 
+#ifdef HAIFA
+/* The following flags have effect only for scheduling before register
+   allocation:
+
+   flag_schedule_interblock means schedule insns accross basic blocks.
+   flag_schedule_speculative means allow speculative motion of non-load insns.
+   flag_schedule_speculative_load means allow speculative motion of some
+   load insns.
+   flag_schedule_speculative_load_dangerous allows speculative motion of more
+   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;
+
+/* flag_on_branch_count_reg means try to replace add-1,compare,branch tupple
+   by a cheaper branch, on a count register. */
+int flag_branch_on_count_reg;
+#endif  /* HAIFA */
+
+
 /* -finhibit-size-directive inhibits output of .size for ELF.
    This is used only for compiling crtstuff.c, 
    and it may be extended to other effects
@@ -575,10 +621,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
@@ -605,6 +651,26 @@ int flag_pack_struct = 0;
    to be allocated dynamically.  */
 int flag_stack_check;
 
+/* -fcheck-memory-usage causes extra code to be generated in order to check
+   memory accesses.  This is used by a detector of bad memory accesses such
+   as Checker.  */
+int flag_check_memory_usage = 0;
+
+/* -fprefix-function-name causes function name to be prefixed.  This
+   can be used with -fcheck-memory-usage to isolate code compiled with
+   -fcheck-memory-usage.  */
+int flag_prefix_function_name = 0;
+
+int flag_regmove = 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.
+   2 if pointer arguments may not alias each other and may not
+   alias global variables.  True in Fortran.
+   This defaults to 0 for C.  */
+int flag_argument_noalias = 0;
+
 /* Table of language-independent -f options.
    STRING is the option name.  VARIABLE is the address of the variable.
    ON_VALUE is the value to store in VARIABLE
@@ -625,6 +691,8 @@ struct { char *string; int *variable; int on_value;} f_options[] =
   {"strength-reduce", &flag_strength_reduce, 1},
   {"unroll-loops", &flag_unroll_loops, 1},
   {"unroll-all-loops", &flag_unroll_all_loops, 1},
+  {"move-all-movables", &flag_move_all_movables, 1},
+  {"reduce-all-givs", &flag_reduce_all_givs, 1},
   {"writable-strings", &flag_writable_strings, 1},
   {"peephole", &flag_no_peephole, 0},
   {"force-mem", &flag_force_mem, 1},
@@ -641,9 +709,17 @@ struct { char *string; int *variable; int on_value;} f_options[] =
   {"reg-struct-return", &flag_pcc_struct_return, 0},
   {"delayed-branch", &flag_delayed_branch, 1},
   {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1},
+  {"rerun-loop-opt", &flag_rerun_loop_opt, 1},
   {"pretend-float", &flag_pretend_float, 1},
   {"schedule-insns", &flag_schedule_insns, 1},
   {"schedule-insns2", &flag_schedule_insns_after_reload, 1},
+#ifdef HAIFA
+  {"sched-interblock",&flag_schedule_interblock, 1},
+  {"sched-spec",&flag_schedule_speculative, 1},
+  {"sched-spec-load",&flag_schedule_speculative_load, 1},
+  {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1},
+  {"branch-count-reg",&flag_branch_on_count_reg, 1},
+#endif  /* HAIFA */
   {"pic", &flag_pic, 1},
   {"PIC", &flag_pic, 2},
   {"exceptions", &flag_exceptions, 1},
@@ -658,9 +734,14 @@ struct { char *string; int *variable; int on_value;} f_options[] =
   {"function-sections", &flag_function_sections, 1},
   {"verbose-asm", &flag_verbose_asm, 1},
   {"gnu-linker", &flag_gnu_linker, 1},
+  {"regmove", &flag_regmove, 1},
   {"pack-struct", &flag_pack_struct, 1},
   {"stack-check", &flag_stack_check, 1},
-  {"bytecode", &output_bytecode, 1}
+  {"argument-alias", &flag_argument_noalias, 0},
+  {"argument-noalias", &flag_argument_noalias, 1},
+  {"argument-noalias-global", &flag_argument_noalias, 2},
+  {"check-memory-usage", &flag_check_memory_usage, 1},
+  {"prefix-function-name", &flag_prefix_function_name, 1}
 };
 
 /* Table of language-specific options.  */
@@ -720,6 +801,11 @@ char *lang_options[] =
   "-Wno-format",
   "-Wimport",
   "-Wno-import",
+  "-Wimplicit-function-declaration",
+  "-Wno-implicit-function-declaration",
+  "-Werror-implicit-function-declaration",
+  "-Wimplicit-int",
+  "-Wno-implicit-int",
   "-Wimplicit",
   "-Wno-implicit",
   "-Wmain",
@@ -740,6 +826,8 @@ char *lang_options[] =
   "-Wno-redundant-decls",
   "-Wsign-compare",
   "-Wno-sign-compare",
+  "-Wunknown-pragmas",
+  "-Wno-unknown-pragmas",
   "-Wstrict-prototypes",
   "-Wno-strict-prototypes",
   "-Wtraditional",
@@ -762,6 +850,7 @@ char *lang_options[] =
   "-Wno-selector",
   "-Wprotocol",
   "-Wno-protocol",
+  "-print-objc-runtime-info",
 
 #include "options.h"
   0
@@ -849,21 +938,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 *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 *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.  */
 
@@ -877,11 +952,14 @@ int cse2_time;
 int branch_prob_time;
 int flow_time;
 int combine_time;
+int regmove_time;
 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;
@@ -893,46 +971,68 @@ int dump_time;
 int
 get_run_time ()
 {
-#ifndef _WIN32
-#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 _WIN32
+
+#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;
+#   if HAVE_SYSCONF && defined _SC_CLK_TCK
+#    define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */
+#   else
+#    ifdef CLK_TCK
+#     define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */
+#    else
+#     define TICKS_PER_SECOND HZ /* traditional UNIX */
+#    endif
+#   endif
+    times (&tms);
+    return (tms.tms_utime + tms.tms_stime) * (1000000 / TICKS_PER_SECOND);
+  }
 #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)    \
@@ -1002,43 +1102,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 (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 (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 ();
@@ -1216,7 +1287,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));
@@ -1822,6 +1893,7 @@ do_abort ()
 
 void
 botch (s)
+  char * s;
 {
   abort ();
 }
@@ -1838,14 +1910,17 @@ xmalloc (size)
   return value;
 }
 
-/* Same as `realloc' but report error if no memory available.  */
+/* Same as `realloc' but report error if no memory available.  
+   Also handle null PTR even if the vendor realloc gets it wrong.  */
 
 char *
 xrealloc (ptr, size)
      char *ptr;
      int size;
 {
-  char *result = (char *) realloc (ptr, size);
+  char *result = (ptr
+                 ? (char *) realloc (ptr, size)
+                 : (char *) malloc (size));
   if (!result)
     fatal ("virtual memory exhausted");
   return result;
@@ -1982,20 +2057,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.  */
@@ -2005,6 +2083,9 @@ output_quoted_string (asm_file, string)
      FILE *asm_file;
      char *string;
 {
+#ifdef OUTPUT_QUOTED_STRING
+  OUTPUT_QUOTED_STRING (asm_file, string);
+#else
   char c;
 
   putc ('\"', asm_file);
@@ -2015,6 +2096,7 @@ output_quoted_string (asm_file, string)
       putc (c, asm_file);
     }
   putc ('\"', asm_file);
+#endif
 }
 
 /* Output a file name in the form wanted by System V.  */
@@ -2061,23 +2143,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;
+
+  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;
+}
 
-static FILE *
-open_dump_file (base_name, suffix)
-     char *base_name;
+/* 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;
+{
+  open_dump_file (suffix, decl_printable_name (decl, 2));
+  close_dump_file (func, insns);
+}
+
+/* Routine to empty a dump file.  */
+static void
+clean_dump_file (suffix)
+     char * suffix;
 {
-  FILE *f;
-  char *dumpname = (char *) alloca (strlen (base_name) + strlen (suffix) + 1);
+  char * dumpname;
+
+  dumpname = (char *) xmalloc (strlen (dump_base_name) + strlen (suffix) + 1);
 
-  strcpy (dumpname, base_name);
+  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.  */
 
@@ -2103,17 +2259,21 @@ compile_file (name)
   branch_prob_time = 0;
   flow_time = 0;
   combine_time = 0;
+  regmove_time = 0;
   sched_time = 0;
   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;
   symout_time = 0;
   dump_time = 0;
 
+#if !USE_CPPLIB
   /* Open input file.  */
 
   if (name == 0 || !strcmp (name, "-"))
@@ -2129,14 +2289,17 @@ compile_file (name)
 #ifdef IO_BUFFER_SIZE
   setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE);
 #endif
+#endif /* !USE_CPPLIB */
 
   /* Initialize data in various passes.  */
 
   init_obstacks ();
   init_tree_codes ();
+#if USE_CPPLIB
+  init_parse (name);
+#else
   init_lex ();
-  /* 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 */
+#endif
   init_rtl ();
   init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
                  || debug_info_level == DINFO_LEVEL_VERBOSE
@@ -2149,6 +2312,7 @@ compile_file (name)
   init_expr_once ();
   init_loop ();
   init_reload ();
+  init_alias_once ();
 
   if (flag_caller_saves)
     init_caller_save ();
@@ -2163,68 +2327,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 cse dump desired, open the output file.  */
+    clean_dump_file (".jump");
+  if (addressof_dump)
+    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 scheduling dump desired, open the output file.  */
+    clean_dump_file (".combine");
+  if (regmove_dump)
+    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.  */
@@ -2264,45 +2408,58 @@ compile_file (name)
   input_file_stack->next = 0;
   input_file_stack->name = input_filename;
 
+  /* Gross. Gross.  lang_init is (I think) the first callback into
+     the language front end, and is thus the first opportunity to
+     have the selected language override the default value for any
+     -f option.
+
+     So the default value for flag_exceptions is 2 (uninitialized).
+     If we encounter -fno-exceptions or -fexceptions, then flag_exceptions
+     will be set to zero or one respectively.
+
+     flag_exceptions can also be set by lang_init to something other
+     than the default "uninitialized" value of 2.
+
+     After lang_init, if the value is still 2, then we default to
+     -fno-exceptions (value will be reset to zero).
+
+     When our EH mechanism is low enough overhead that we can enable
+     it by default for languages other than C++, then all this braindamage
+     will go away.  */
+  
   /* Perform language-specific initialization.
      This may set main_input_filename.  */
   lang_init ();
 
+  if (flag_exceptions == 2)
+    flag_exceptions = 0;
+     
   /* If the input doesn't start with a #line, use the input name
      as the official input 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
@@ -2327,26 +2484,25 @@ 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)
+  /* Don't let the first function fall at the same address
+     as gcc_compiled., if profiling.  */
+  if (profile_flag || profile_block_flag)
+    {
+      /* It's best if we can write a nop here since some
+        assemblers don't tolerate zeros in the text section.  */
+      if (insn_template[CODE_FOR_nop] != 0)
+       output_asm_insn (insn_template[CODE_FOR_nop], NULL_PTR);
+      else
        assemble_zeros (UNITS_PER_WORD);
     }
 
@@ -2366,6 +2522,10 @@ compile_file (name)
   if (write_symbols == DWARF_DEBUG)
     TIMEVAR (symout_time, dwarfout_init (asm_out_file, main_input_filename));
 #endif
+#ifdef DWARF2_UNWIND_INFO
+  if (dwarf2out_do_frame ())
+    dwarf2out_frame_init ();
+#endif
 #ifdef DWARF2_DEBUGGING_INFO
   if (write_symbols == DWARF2_DEBUG)
     TIMEVAR (symout_time, dwarf2out_init (asm_out_file, main_input_filename));
@@ -2373,8 +2533,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 ();
@@ -2486,6 +2645,7 @@ compile_file (name)
                && DECL_INITIAL (decl) != 0
                && DECL_SAVED_INSNS (decl) != 0
                && (flag_keep_inline_functions
+                   || TREE_PUBLIC (decl)
                    || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
              {
                reconsider = 1;
@@ -2499,8 +2659,7 @@ compile_file (name)
     /* Now that all possible functions have been output, we can dump
        the exception table.  */
 
-    if (exception_table_p ())
-      output_exception_table ();
+    output_exception_table ();
 
     for (i = 0; i < len; i++)
       {
@@ -2615,6 +2774,11 @@ compile_file (name)
             });
 #endif
 
+#ifdef DWARF2_UNWIND_INFO
+  if (dwarf2out_do_frame ())
+    dwarf2out_frame_finish ();
+#endif
+
 #ifdef DWARF2_DEBUGGING_INFO
   if (write_symbols == DWARF2_DEBUG)
     TIMEVAR (symout_time,
@@ -2625,23 +2789,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)
@@ -2651,61 +2816,22 @@ 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 (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 (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.  */
 
+#if USE_CPPLIB
+  finish_parse ();
+#else
   fclose (finput);
+#endif
   if (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0)
     fatal_io_error (asm_file_name);
 
@@ -2716,28 +2842,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 ("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
@@ -2788,8 +2914,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);
@@ -2855,15 +2980,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.  */
@@ -2890,7 +3012,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 ();
@@ -2898,15 +3020,19 @@ 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",
-                           IDENTIFIER_POINTER (DECL_NAME (decl)));
-                  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 (inlinable && ! decl_function_context (decl))
+       DECL_DEFER_OUTPUT (decl) = 1;
 
       /* If function is inline, and we don't yet know whether to
         compile it by itself, defer decision till end of compilation.
@@ -2916,6 +3042,18 @@ rest_of_compilation (decl)
         functions containing nested functions since the nested function
         data is in our non-saved obstack.  */
 
+      /* If this is a nested inline, remove ADDRESSOF now so we can
+        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 (inlinable)
+       {
+         if (decl_function_context (decl))
+           purge_addressof (insns);
+         else
+           DECL_DEFER_OUTPUT (decl) = 1;
+       }
+
       if (! current_function_contains_functions
          && (DECL_DEFER_OUTPUT (decl)
              || (DECL_INLINE (decl)
@@ -2925,40 +3063,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
@@ -2987,7 +3138,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
@@ -3010,9 +3161,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
@@ -3038,6 +3188,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 ());
@@ -3062,29 +3218,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",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
-              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",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
-            });
-
   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)
@@ -3092,107 +3238,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);
+    }
 
-  if (loop_dump)
-    TIMEVAR (dump_time,
-            {
-              fprintf (loop_dump_file, "\n;; Function %s\n\n",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
-            });
+  purge_addressof (insns);
+  reg_scan (insns, max_reg_num (), 1);
 
+  if (addressof_dump)
+    dump_rtl (".addressof", decl, print_rtl, insns);
+  
   /* Move constant computations out of loops.  */
 
   if (optimize > 0)
     {
-      TIMEVAR (loop_time,
-              {
-                loop_optimize (insns, loop_dump_file);
-              });
-    }
-
-  /* Dump rtl code after loop opt, if we are doing that.  */
-
-  if (loop_dump)
-    TIMEVAR (dump_time,
-            {
-              print_rtl (loop_dump_file, insns);
-              fflush (loop_dump_file);
-            });
-
-  if (cse2_dump)
-    TIMEVAR (dump_time,
+      if (loop_dump)
+       open_dump_file (".loop", decl_printable_name (decl, 2));
+       
+      TIMEVAR
+       (loop_time,
+        {
+          if (flag_rerun_loop_opt)
             {
-              fprintf (cse2_dump_file, "\n;; Function %s\n\n",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
-            });
-
-  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",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
-            });
+      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;
@@ -3210,19 +3353,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",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
-            });
-
+    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
@@ -3230,8 +3369,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));
@@ -3242,56 +3386,53 @@ rest_of_compilation (decl)
   /* Dump rtl after flow analysis.  */
 
   if (flow_dump)
-    TIMEVAR (dump_time,
-            {
-              print_rtl (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.  */
+    {
+      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);
+    }
 
-  if (combine_dump)
-    TIMEVAR (dump_time,
-            {
-              fprintf (combine_dump_file, "\n;; Function %s\n\n",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
-              dump_combine_stats (combine_dump_file);
-              print_rtl (combine_dump_file, insns);
-              fflush (combine_dump_file);
-            });
+  /* Register allocation pre-pass, to reduce number of moves
+     necessary for two-address machines.  */
+  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",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
-            });
-
   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 (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.  */
 
@@ -3305,20 +3446,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",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
-              dump_flow_info (local_reg_dump_file);
-              dump_local_alloc (local_reg_dump_file);
-              print_rtl (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",
-                     IDENTIFIER_POINTER (DECL_NAME (decl))));
+    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.  */
@@ -3331,18 +3469,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 (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;
@@ -3363,25 +3499,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",
-                           IDENTIFIER_POINTER (DECL_NAME (decl)));
-                });
+       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 (sched2_dump_file, insns);
-                  fflush (sched2_dump_file);
-                });
+       close_dump_file (print_rtl_with_bb, insns);
     }
 
 #ifdef LEAF_REGISTERS
@@ -3398,22 +3526,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",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
-              print_rtl (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,
@@ -3422,17 +3547,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",
-                           IDENTIFIER_POINTER (DECL_NAME (decl)));
-                  print_rtl (dbr_sched_dump_file, insns);
-                  fflush (dbr_sched_dump_file);
-                });
-       }
+       dump_rtl (".dbr", decl, print_rtl_with_bb, insns);
     }
 #endif
 
@@ -3443,17 +3561,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",
-                         IDENTIFIER_POINTER (DECL_NAME (decl)));
-                print_rtl (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.  */
@@ -3480,7 +3591,8 @@ rest_of_compilation (decl)
             final (insns, asm_out_file, optimize, 0);
             final_end_function (insns, asm_out_file, optimize);
             assemble_end_function (decl, fnname);
-            fflush (asm_out_file);
+            if (! quiet_flag)
+              fflush (asm_out_file);
 
             /* Release all memory held by regsets now */
             regset_release_memory ();
@@ -3551,6 +3663,17 @@ rest_of_compilation (decl)
 
   init_temp_slots ();
 
+  /* Make sure volatile mem refs aren't considered valid operands for
+     arithmetic insns.  We must call this here if this is a nested inline
+     function, since the above code leaves us in the init_recog state
+     (from final.c), and the function context push/pop code does not
+     save/restore volatile_ok.
+
+     ??? Maybe it isn't necessary for expand_start_function to call this
+     anymore if we do it here?  */
+
+  init_recog_no_volatile ();
+
   /* The parsing time is all the time spent in yyparse
      *except* what is spent in this function.  */
 
@@ -3586,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;
@@ -3596,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);
 
@@ -3624,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)
@@ -3657,12 +3789,14 @@ main (argc, argv, envp)
       flag_expensive_optimizations = 1;
       flag_strength_reduce = 1;
       flag_rerun_cse_after_loop = 1;
+      flag_rerun_loop_opt = 1;
       flag_caller_saves = 1;
       flag_force_mem = 1;
 #ifdef INSN_SCHEDULING
       flag_schedule_insns = 1;
       flag_schedule_insns_after_reload = 1;
 #endif
+      flag_regmove = 1;
     }
 
   if (optimize >= 3)
@@ -3677,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.  */
@@ -3685,7 +3819,7 @@ main (argc, argv, envp)
 
   for (i = 1; i < argc; i++)
     {
-      int j;
+      size_t j;
       /* If this is a language-specific option,
         decode it in a language-specific way.  */
       for (j = 0; lang_options[j] != 0; j++)
@@ -3717,31 +3851,44 @@ 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;
+                   addressof_dump = 1;
                    jump2_opt_dump = 1;
                    local_reg_dump = 1;
                    loop_dump = 1;
+                   regmove_dump = 1;
                    rtl_dump = 1;
                    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;
@@ -3751,6 +3898,9 @@ main (argc, argv, envp)
                  case 'j':
                    jump_opt_dump = 1;
                    break;
+                 case 'D':
+                   addressof_dump = 1;
+                   break;
                  case 'J':
                    jump2_opt_dump = 1;
                    break;
@@ -3763,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;
@@ -3775,6 +3930,9 @@ main (argc, argv, envp)
                  case 't':
                    cse2_dump = 1;
                    break;
+                 case 'N':
+                   regmove_dump = 1;
+                   break;
                  case 'S':
                    sched_dump = 1;
                    break;
@@ -3790,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')
@@ -3822,6 +3983,18 @@ main (argc, argv, envp)
 
              if (found)
                ;
+#ifdef HAIFA
+#ifdef INSN_SCHEDULING
+             else if (!strncmp (p, "sched-verbose-",14))
+               fix_sched_param("verbose",&p[14]);
+             else if (!strncmp (p, "sched-max-",10))
+               fix_sched_param("max",&p[10]);
+             else if (!strncmp (p, "sched-inter-max-b-",18))
+               fix_sched_param("interblock-max-blocks",&p[18]);
+             else if (!strncmp (p, "sched-inter-max-i-",18))
+               fix_sched_param("interblock-max-insns",&p[18]);
+#endif
+#endif  /* HAIFA */
              else if (!strncmp (p, "fixed-", 6))
                fix_register (&p[6], 1, 1);
              else if (!strncmp (p, "call-used-", 10))
@@ -3834,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
@@ -4010,11 +4186,21 @@ main (argc, argv, envp)
                      p = str + strlen (da->arg);
                      if (*p && (*p < '0' || *p > '9'))
                        continue;
+                     len = p - str;
                      q = p;
                      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)
@@ -4032,10 +4218,12 @@ 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;
-#elif defined DBX_DEBUGGING_INFO
+#else
+#ifdef DBX_DEBUGGING_INFO
                              type = DBX_DEBUG;
+#endif
 #endif
                            }
                        }
@@ -4099,17 +4287,9 @@ main (argc, argv, envp)
        filename = argv[i];
     }
 
-  /* 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
-    }
+  /* Checker uses the frame pointer.  */
+  if (flag_check_memory_usage)
+    flag_omit_frame_pointer = 0;
 
   if (optimize == 0)
     {
@@ -4130,6 +4310,15 @@ main (argc, argv, envp)
   OVERRIDE_OPTIONS;
 #endif
 
+  if (exceptions_via_longjmp == 2)
+    {
+#ifdef DWARF2_UNWIND_INFO
+      exceptions_via_longjmp = ! DWARF2_UNWIND_INFO;
+#else
+      exceptions_via_longjmp = 1;
+#endif
+    }
+
   if (profile_block_flag == 3)
     {
       warning ("`-ax' and `-a' are conflicting options. `-a' ignored.");
@@ -4180,11 +4369,13 @@ main (argc, argv, envp)
               lim - (char *) &environ);
       fflush (stderr);
 
+#ifndef __MSDOS__
 #ifdef USG
       system ("ps -l 1>&2");
 #else /* not USG */
       system ("ps v");
 #endif /* not USG */
+#endif
     }
 #endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN32) */
 
@@ -4220,7 +4411,7 @@ void
 set_target_switch (name)
      char *name;
 {
-  register int j;
+  register size_t j;
   int valid = 0;
 
   for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
@@ -4313,7 +4504,7 @@ print_switch_values (file, pos, max, indent, sep, term)
      int pos, max;
      char *indent, *sep, *term;
 {
-  int j, flags;
+  size_t j;
   char **p;
 
   /* Print the options as passed.  */
@@ -4357,7 +4548,6 @@ print_switch_values (file, pos, max, indent, sep, term)
 
   /* Print target specific options.  */
 
-  flags = target_flags;
   for (j = 0; j < sizeof target_switches / sizeof target_switches[0]; j++)
     if (target_switches[j].name[0] != '\0'
        && target_switches[j].value > 0
@@ -4366,7 +4556,6 @@ print_switch_values (file, pos, max, indent, sep, term)
       {
        pos = print_single_switch (file, pos, max, indent, sep, term,
                                   "-m", target_switches[j].name);
-       flags &= ~ target_switches[j].value;
       }
 
 #ifdef TARGET_OPTIONS