* Check in merge from gcc2. See ChangeLog.11 and ChangeLog.12
[gcc.git] / gcc / toplev.c
index 8b084d3cd1ef166fc7cd83a7f3043de95b6d251d..d226950dfecc9836cf9d2adcdc56e6aa4fd58dad 100644 (file)
@@ -1,5 +1,5 @@
 /* Top level of GNU C compiler
-   Copyright (C) 1987, 88, 89, 92-5, 1996 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,12 @@ 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
 #include "xcoffout.h"
@@ -92,6 +85,39 @@ vms_fopen (fname, type)
 #define DEFAULT_GDB_EXTENSIONS 1
 #endif
 
+/* If more than one debugging type is supported, you must define
+   PREFERRED_DEBUGGING_TYPE to choose a format in a system-dependent way. 
+
+   This is one long line cause VAXC can't handle a \-newline.  */
+#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (DWARF2_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO))
+#ifndef PREFERRED_DEBUGGING_TYPE
+You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
+#endif /* no PREFERRED_DEBUGGING_TYPE */
+#else /* Only one debugging format supported.  Define PREFERRED_DEBUGGING_TYPE
+        so the following code needn't care.  */
+#ifdef DBX_DEBUGGING_INFO
+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
+#endif
+#ifdef SDB_DEBUGGING_INFO
+#define PREFERRED_DEBUGGING_TYPE SDB_DEBUG
+#endif
+#ifdef DWARF_DEBUGGING_INFO
+#define PREFERRED_DEBUGGING_TYPE DWARF_DEBUG
+#endif
+#ifdef DWARF2_DEBUGGING_INFO
+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
+#endif
+#ifdef XCOFF_DEBUGGING_INFO
+#define PREFERRED_DEBUGGING_TYPE XCOFF_DEBUG
+#endif
+#endif /* More than one debugger format enabled.  */
+
+/* If still not defined, must have been because no debugging formats
+   are supported.  */
+#ifndef PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE NO_DEBUG
+#endif
+
 extern int rtx_equal_function_value_matters;
 
 #if ! (defined (VMS) || defined (OS2))
@@ -117,6 +143,10 @@ extern void init_reg_sets ();
 extern void dump_flow_info ();
 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, ...));
@@ -134,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 ();
 
@@ -146,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
 
@@ -169,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.  */
 
@@ -203,19 +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.  */
 
@@ -249,18 +291,28 @@ 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.  */
+/* 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:
+     0: DECL_NAME, demangled as necessary.
+     1: and scope information.
+     2: and any other information that might be interesting, such as function
+        parameter types in C++.  */
 
-char *(*decl_printable_name) ();
+char *(*decl_printable_name) (/* tree decl, int verbosity */);
 
 /* Pointer to function to compute rtl for a language-specific tree code.  */
 
@@ -271,12 +323,6 @@ struct rtx_def *(*lang_expand_expr) ();
 
 void (*incomplete_decl_finalize_hook) () = 0;
 
-/* Pointer to function for interim exception handling implementation.
-   This interface will change, and it is only here until a better interface
-   replaces it.  */
-
-void (*interim_eh_hook)        PROTO((tree));
-
 /* Highest label number used at the end of reload.  */
 
 int max_label_num_after_reload;
@@ -289,6 +335,18 @@ int profile_flag = 0;
 
 int profile_block_flag;
 
+/* Nonzero if generating code to profile program flow graph arcs.  */
+
+int profile_arc_flag = 0;
+
+/* Nonzero if generating info for gcov to calculate line test coverage.  */
+
+int flag_test_coverage = 0;
+
+/* Nonzero indicates that branch taken probabilities should be calculated.  */
+
+int flag_branch_probabilities = 0;
+
 /* Nonzero for -pedantic switch: warn about anything
    that standard spec forbids.  */
 
@@ -396,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.  */
 
@@ -424,7 +492,7 @@ int flag_no_peephole = 0;
 /* Nonzero allows GCC to violate some IEEE or ANSI rules regarding math
    operations in the interest of optimization.  For example it allows
    GCC to assume arguments to sqrt are nonnegative numbers, allowing
-   faster code for sqrt to be generated. */
+   faster code for sqrt to be generated.  */
 
 int flag_fast_math = 0;
 
@@ -445,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.  */
 
@@ -460,6 +532,11 @@ int flag_keep_inline_functions;
 
 int flag_no_inline;
 
+/* Nonzero means that we should emit static const variables
+   regardless of whether or not optimization is turned on.  */
+
+int flag_keep_static_consts = 1;
+
 /* Nonzero means we should be saving declaration info into a .X file.  */
 
 int flag_gen_aux_info = 0;
@@ -476,10 +553,6 @@ int flag_shared_data;
 
 int flag_delayed_branch;
 
-/* Nonzero means to run cleanups after CALL_EXPRs.  */
-
-int flag_short_temps;
-
 /* Nonzero if we are compiling pure (sharable) code.
    Value is 1 if we are doing reasonable (i.e. simple
    offset into offset table) pic.  Value is 2 if we can
@@ -487,8 +560,13 @@ int flag_short_temps;
 
 int flag_pic;
 
+/* Nonzero means generate extra code for exception handling and enable
+   exception handling.  */
+
+int flag_exceptions = 2;
+
 /* Nonzero means don't place uninitialized global data in common storage
-   by default. */
+   by default.  */
 
 int flag_no_common;
 
@@ -511,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
@@ -521,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
@@ -547,6 +647,30 @@ int flag_gnu_linker = 1;
 /* Tag all structures with __attribute__(packed) */
 int flag_pack_struct = 0;
 
+/* Emit code to check for stack overflow; also may cause large objects
+   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
@@ -567,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},
@@ -575,6 +701,7 @@ struct { char *string; int *variable; int on_value;} f_options[] =
   {"inline-functions", &flag_inline_functions, 1},
   {"keep-inline-functions", &flag_keep_inline_functions, 1},
   {"inline", &flag_no_inline, 0},
+  {"keep-static-consts", &flag_keep_static_consts, 1},
   {"syntax-only", &flag_syntax_only, 1},
   {"shared-data", &flag_shared_data, 1},
   {"caller-saves", &flag_caller_saves, 1},
@@ -582,19 +709,39 @@ 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},
+  {"sjlj-exceptions", &exceptions_via_longjmp, 1},
+  {"asynchronous-exceptions", &asynchronous_exceptions, 1},
+  {"profile-arcs", &profile_arc_flag, 1},
+  {"test-coverage", &flag_test_coverage, 1},
+  {"branch-probabilities", &flag_branch_probabilities, 1},
   {"fast-math", &flag_fast_math, 1},
   {"common", &flag_no_common, 0},
   {"inhibit-size-directive", &flag_inhibit_size_directive, 1},
   {"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},
-  {"bytecode", &output_bytecode, 1}
+  {"stack-check", &flag_stack_check, 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.  */
@@ -622,6 +769,10 @@ char *lang_options[] =
   "-fno-asm",
   "-fbuiltin",
   "-fno-builtin",
+  "-fhosted",
+  "-fno-hosted",
+  "-ffreestanding",
+  "-fno-freestanding",
   "-fcond-mismatch",
   "-fno-cond-mismatch",
   "-fdollars-in-identifiers",
@@ -650,8 +801,15 @@ 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",
+  "-Wno-main",
   "-Wmissing-braces",
   "-Wno-missing-braces",
   "-Wmissing-declarations",
@@ -668,12 +826,16 @@ char *lang_options[] =
   "-Wno-redundant-decls",
   "-Wsign-compare",
   "-Wno-sign-compare",
+  "-Wunknown-pragmas",
+  "-Wno-unknown-pragmas",
   "-Wstrict-prototypes",
   "-Wno-strict-prototypes",
   "-Wtraditional",
   "-Wno-traditional",
   "-Wtrigraphs",
   "-Wno-trigraphs",
+  "-Wundef",
+  "-Wno-undef",
   "-Wwrite-strings",
   "-Wno-write-strings",
 
@@ -688,6 +850,7 @@ char *lang_options[] =
   "-Wno-selector",
   "-Wprotocol",
   "-Wno-protocol",
+  "-print-objc-runtime-info",
 
 #include "options.h"
   0
@@ -775,20 +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 *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.  */
 
@@ -799,13 +949,17 @@ int jump_time;
 int cse_time;
 int loop_time;
 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;
@@ -817,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)    \
@@ -926,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 ();
@@ -985,21 +1132,12 @@ fatal_insn_not_found (insn)
 /* This is the default decl_printable_name function.  */
 
 static char *
-decl_name (decl, kind)
+decl_name (decl, verbosity)
      tree decl;
-     char **kind;
+     int verbosity;
 {
   return IDENTIFIER_POINTER (DECL_NAME (decl));
 }
-
-/* This is the default interim_eh_hook function.  */
-
-void
-interim_eh (finalization)
-     tree finalization;
-{
-  /* Don't do anything by default.  */
-}
 \f
 static int need_error_newline;
 
@@ -1020,11 +1158,10 @@ announce_function (decl)
 {
   if (! quiet_flag)
     {
-      char *junk;
       if (rtl_dump_and_exit)
        fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
       else
-       fprintf (stderr, " %s", (*decl_printable_name) (decl, &junk));
+       fprintf (stderr, " %s", (*decl_printable_name) (decl, 2));
       fflush (stderr);
       need_error_newline = 1;
       last_error_function = current_function_decl;
@@ -1052,7 +1189,7 @@ default_print_error_function (file)
        fprintf (stderr, "At top level:\n");
       else
        {
-         char *name = (*decl_printable_name) (current_function_decl, &kind);
+         char *name = (*decl_printable_name) (current_function_decl, 2);
          fprintf (stderr, "In %s `%s':\n", kind, name);
        }
 
@@ -1061,9 +1198,9 @@ default_print_error_function (file)
 }
 
 /* Called by report_error_function to print out function name.
- * Default may be overridden by language front-ends. */
+ * Default may be overridden by language front-ends.  */
 
-void (*print_error_function) PROTO((char*)) = default_print_error_function;
+void (*print_error_function) PROTO((char *)) = default_print_error_function;
 
 /* Prints out, if necessary, the name of the current function
   that caused an error.  Called from all error and warning functions.  */
@@ -1150,7 +1287,7 @@ v_message_with_decl (decl, prefix, s, ap)
      char *s;
      va_list ap;
 {
-  char *n, *p, *junk;
+  char *p;
 
   fprintf (stderr, "%s:%d: ",
           DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl));
@@ -1186,7 +1323,7 @@ v_message_with_decl (decl, prefix, s, ap)
   if (*p == '%')               /* Print the name.  */
     {
       char *n = (DECL_NAME (decl)
-                ? (*decl_printable_name) (decl, &junk)
+                ? (*decl_printable_name) (decl, 2)
                 : "((anonymous))");
       fputs (n, stderr);
       while (*p)
@@ -1756,6 +1893,7 @@ do_abort ()
 
 void
 botch (s)
+  char * s;
 {
   abort ();
 }
@@ -1767,19 +1905,22 @@ xmalloc (size)
      unsigned size;
 {
   register char *value = (char *) malloc (size);
-  if (value == 0)
+  if (value == 0 && size != 0)
     fatal ("virtual memory exhausted");
   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;
@@ -1833,9 +1974,27 @@ floor_log2_wide (x)
   return log;
 }
 
+static int float_handler_set;
 int float_handled;
 jmp_buf float_handler;
 
+/* Signals actually come here.  */
+
+static void
+float_signal (signo)
+     /* If this is missing, some compilers complain.  */
+     int signo;
+{
+  if (float_handled == 0)
+    abort ();
+#if defined (USG) || defined (hpux)
+  signal (SIGFPE, float_signal);  /* re-enable the signal catcher */
+#endif
+  float_handled = 0;
+  signal (SIGFPE, float_signal);
+  longjmp (float_handler, 1);
+}
+
 /* Specify where to longjmp to when a floating arithmetic error happens.
    If HANDLER is 0, it means don't handle the errors any more.  */
 
@@ -1846,6 +2005,12 @@ set_float_handler (handler)
   float_handled = (handler != 0);
   if (handler)
     bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
+
+  if (float_handled && ! float_handler_set)
+    {
+      signal (SIGFPE, float_signal);
+      float_handler_set = 1;
+    }
 }
 
 /* Specify, in HANDLER, where to longjmp to when a floating arithmetic
@@ -1880,23 +2045,6 @@ pop_float_handler (handled, handler)
     bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
 }
 
-/* Signals actually come here.  */
-
-static void
-float_signal (signo)
-     /* If this is missing, some compilers complain.  */
-     int signo;
-{
-  if (float_handled == 0)
-    abort ();
-#if defined (USG) || defined (hpux)
-  signal (SIGFPE, float_signal);  /* re-enable the signal catcher */
-#endif
-  float_handled = 0;
-  signal (SIGFPE, float_signal);
-  longjmp (float_handler, 1);
-}
-
 /* Handler for SIGPIPE.  */
 
 static void
@@ -1909,28 +2057,35 @@ 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.  */
+
 void
 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);
@@ -1941,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.  */
@@ -1974,7 +2130,8 @@ output_file_directive (asm_file, input_name)
 #endif
 }
 \f
-/* Routine to build language identifier for object file. */
+/* Routine to build language identifier for object file.  */
+
 static void
 output_lang_identify (asm_out_file)
      FILE *asm_out_file;
@@ -1986,22 +2143,97 @@ output_lang_identify (asm_out_file)
 }
 
 /* Routine to open a dump file.  */
-static FILE *
-open_dump_file (base_name, suffix)
-     char *base_name;
+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;
+}
+
+/* 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;
 
-  strcpy (dumpname, base_name);
+  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.  */
 
@@ -2024,19 +2256,24 @@ compile_file (name)
   cse_time = 0;
   loop_time = 0;
   cse2_time = 0;
+  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, "-"))
@@ -2052,17 +2289,21 @@ 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);
+                 || debug_info_level == DINFO_LEVEL_VERBOSE
+                 || flag_test_coverage);
   init_regs ();
   init_decl_processing ();
   init_optabs ();
@@ -2071,6 +2312,7 @@ compile_file (name)
   init_expr_once ();
   init_loop ();
   init_reload ();
+  init_alias_once ();
 
   if (flag_caller_saves)
     init_caller_save ();
@@ -2085,64 +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 flow dump desired, open the output file.  */
+    clean_dump_file (".cse2");
+  if (branch_prob_dump)
+    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.  */
@@ -2182,47 +2408,60 @@ 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. */
+  /* Output something to identify which front-end produced this file.  */
 #ifdef ASM_IDENTIFY_LANGUAGE
   ASM_IDENTIFY_LANGUAGE (asm_out_file);
 #endif
@@ -2245,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);
     }
 
@@ -2284,11 +2522,19 @@ 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));
+#endif
 
   /* 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 ();
 
@@ -2306,6 +2552,8 @@ compile_file (name)
        poplevel (0, 0, 0);
     }
 
+  output_func_start_profiler ();
+
   /* Compilation is now finished except for writing
      what's left of the symbol table output.  */
 
@@ -2360,7 +2608,8 @@ compile_file (name)
 
            /* Don't write out static consts, unless we still need them.
 
-              We also keep static consts if not optimizing (for debugging).
+              We also keep static consts if not optimizing (for debugging),
+              unless the user specified -fno-keep-static-consts.
               ??? They might be better written into the debug information.
               This is possible when using DWARF.
 
@@ -2380,12 +2629,12 @@ compile_file (name)
 
               ??? A tempting alternative (for both C and C++) would be
               to force a constant to be written if and only if it is
-              defined in a main file, as opposed to an include file. */
+              defined in a main file, as opposed to an include file.  */
 
            if (TREE_CODE (decl) == VAR_DECL && TREE_STATIC (decl)
                && (! TREE_READONLY (decl)
                    || TREE_PUBLIC (decl)
-                   || !optimize
+                   || (!optimize && flag_keep_static_consts)
                    || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
              {
                reconsider = 1;
@@ -2396,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;
@@ -2406,6 +2656,11 @@ compile_file (name)
          }
       }
 
+    /* Now that all possible functions have been output, we can dump
+       the exception table.  */
+
+    output_exception_table ();
+
     for (i = 0; i < len; i++)
       {
        decl = vec[i];
@@ -2466,7 +2721,7 @@ compile_file (name)
          TIMEVAR (symout_time, sdbout_symbol (decl, 0));
 
        /* Output COFF information for non-global
-          file-scope initialized variables. */
+          file-scope initialized variables.  */
        if (write_symbols == SDB_DEBUG
            && TREE_CODE (decl) == VAR_DECL
            && DECL_INITIAL (decl)
@@ -2484,6 +2739,16 @@ compile_file (name)
        if (write_symbols == DWARF_DEBUG
            && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
          TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1));
+#endif
+#ifdef DWARF2_DEBUGGING_INFO
+       /* Output DWARF2 information for file-scope tentative data object
+          declarations, file-scope (extern) function declarations (which
+          had no corresponding body) and file-scope tagged type declarations
+          and definitions which have not yet been forced out.  */
+
+       if (write_symbols == DWARF2_DEBUG
+           && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
+         TIMEVAR (symout_time, dwarf2out_decl (decl));
 #endif
       }
   }
@@ -2509,24 +2774,39 @@ compile_file (name)
             });
 #endif
 
-  /* Output some stuff at end of file if nec.  */
+#ifdef DWARF2_UNWIND_INFO
+  if (dwarf2out_do_frame ())
+    dwarf2out_frame_finish ();
+#endif
 
-  if (!output_bytecode)
-    {
-      end_final (main_input_filename);
+#ifdef DWARF2_DEBUGGING_INFO
+  if (write_symbols == DWARF2_DEBUG)
+    TIMEVAR (symout_time,
+            {
+              dwarf2out_finish ();
+            });
+#endif
+
+  /* Output some stuff at end of file if nec.  */
 
+  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)
@@ -2536,58 +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 (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.  */
+  /* 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);
 
@@ -2598,27 +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 ("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
@@ -2669,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);
@@ -2736,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.  */
@@ -2771,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 ();
@@ -2779,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.
@@ -2797,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)
@@ -2806,29 +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
-             TIMEVAR (integration_time, save_for_inline_nocopy (decl));
-             RTX_INTEGRATED_P (DECL_SAVED_INSNS (decl)) = inlineable;
-             goto exit_rest_of_compilation;
+#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)) = 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
@@ -2841,11 +3122,23 @@ rest_of_compilation (decl)
              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 will generate an out-of-line instance
+            of almost immediately (and which we may also later generate
+            various inlined 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
          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
@@ -2868,12 +3161,8 @@ rest_of_compilation (decl)
       goto exit_rest_of_compilation;
     }
 
-  /* From now on, allocate rtl in current_obstack, not in saveable_obstack.
-     Note that that may have been done above, in save_for_inline_copying.
-     The call to resume_temporary_allocation near the end of this function
-     goes back to the usual state of affairs.  */
-
-  rtl_in_current_obstack ();
+  /* Emit code to get eh context, if needed. */
+  emit_eh_context ();
 
 #ifdef FINALIZE_PIC
   /* If we are doing position-independent code generation, now
@@ -2884,12 +3173,27 @@ rest_of_compilation (decl)
     FINALIZE_PIC;
 #endif
 
+  /* From now on, allocate rtl in current_obstack, not in saveable_obstack.
+     Note that that may have been done above, in save_for_inline_copying.
+     The call to resume_temporary_allocation near the end of this function
+     goes back to the usual state of affairs.  This must be done after
+     we've built up any unwinders for exception handling, and done
+     the FINALIZE_PIC work, if necessary.  */
+
+  rtl_in_current_obstack ();
+
   insns = get_insns ();
 
   /* Copy any shared structure that should not be shared.  */
 
   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 ());
@@ -2899,6 +3203,9 @@ rest_of_compilation (decl)
      for all references to such slots.  */
 /*   fixup_stack_slots (); */
 
+  /* Find all the EH handlers.  */
+  find_exception_handler_labels ();
+
   /* Always do one jump optimization pass to ensure that JUMP_LABEL fields
      are initialized and to compute whether control can drop off the end
      of the function.  */
@@ -2911,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)
@@ -2941,86 +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,
+      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);
-            });
+              /* 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 (cse2_dump)
-    TIMEVAR (dump_time,
-            {
-              fprintf (cse2_dump_file, "\n;; Function %s\n\n",
-                       IDENTIFIER_POINTER (DECL_NAME (decl)));
-            });
+  if (optimize > 0)
+    {
+      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 (optimize > 0 && flag_rerun_cse_after_loop)
+      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)
     {
-      /* 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));
+      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);
     }
-
-  if (optimize > 0 && flag_thread_jumps)
-    /* This pass of jump threading straightens out code
-       that was kinked by loop optimization.  */
-    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);
-            });
-
+  
   /* We are no longer anticipating cse in this function, at least.  */
 
   cse_not_expected = 1;
@@ -3038,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
@@ -3058,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));
@@ -3070,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.  */
 
@@ -3133,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.  */
@@ -3159,24 +3469,26 @@ 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;
 
   reload_completed = 1;
 
+  /* Do a very simple CSE pass over just the hard registers.  */
+  if (optimize > 0)
+    reload_cse_regs (insns);
+
   /* On some machines, the prologue and epilogue code, or parts thereof,
      can be represented as RTL.  Doing so lets us schedule insns between
      it and the rest of the code and also allows delayed branch
@@ -3187,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
@@ -3222,41 +3526,31 @@ 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,
-     call the scheduling code. */
+     call the scheduling code.  */
 
 #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
 
@@ -3267,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.  */
@@ -3304,7 +3591,11 @@ 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 ();
           });
 
   /* Write DBX symbols if requested */
@@ -3327,6 +3618,11 @@ rest_of_compilation (decl)
     TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
 #endif
 
+#ifdef DWARF2_DEBUGGING_INFO
+  if (write_symbols == DWARF2_DEBUG)
+    TIMEVAR (symout_time, dwarf2out_decl (decl));
+#endif
+
  exit_rest_of_compilation:
 
   /* In case the function was not output,
@@ -3343,9 +3639,11 @@ rest_of_compilation (decl)
      the copy, but the original is unchanged.  */
 
   if (saved_block_tree != 0)
-    DECL_INITIAL (decl) = saved_block_tree;
-  if (saved_arguments != 0)
-    DECL_ARGUMENTS (decl) = saved_arguments;
+    {
+      DECL_INITIAL (decl) = saved_block_tree;
+      DECL_ARGUMENTS (decl) = saved_arguments;
+      DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE;
+    }
 
   reload_completed = 0;
 
@@ -3365,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.  */
 
@@ -3400,17 +3709,17 @@ 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;
 
-    /* Set the stack limit huge so that alloca does not fail. */
+    /* Set the stack limit huge so that alloca does not fail.  */
     getrlimit (RLIMIT_STACK, &rlim);
     rlim.rlim_cur = rlim.rlim_max;
     setrlimit (RLIMIT_STACK, &rlim);
   }
-#endif /* RLIMIT_STACK */
+#endif
 
   signal (SIGFPE, float_signal);
 
@@ -3420,7 +3729,6 @@ main (argc, argv, envp)
 
   decl_printable_name = decl_name;
   lang_expand_expr = (struct rtx_def *(*)()) do_abort;
-  interim_eh_hook = interim_eh;
 
   /* Initialize whether `char' is signed.  */
   flag_signed_char = DEFAULT_SIGNED_CHAR;
@@ -3439,24 +3747,28 @@ 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 == 0)
-    {
-      flag_no_inline = 1;
-      warn_inline = 0;
-    }
 
   if (optimize >= 1)
     {
@@ -3477,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)
@@ -3497,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.  */
@@ -3505,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++)
@@ -3535,29 +3849,46 @@ main (argc, argv, envp)
                switch (*p++)
                  {
                  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;
@@ -3567,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;
@@ -3579,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;
@@ -3591,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;
@@ -3606,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')
@@ -3638,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))
@@ -3650,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
@@ -3768,131 +4128,141 @@ main (argc, argv, envp)
            }
          else if (str[0] == 'g')
            {
-             char *p = str + 1;
-             char *q;
              unsigned len;
              unsigned level;
-
-             while (*p && (*p < '0' || *p > '9'))
-               p++;
-             len = p - str;
-             q = p;
-             while (*q && (*q >= '0' && *q <= '9'))
-               q++;
-             if (*p)
-               level = atoi (p);
-             else
-               level = 2;      /* default debugging info level */
-             if (*q || level > 3)
-               {
-                 warning ("invalid debug level specification in option: `-%s'",
-                          str);
-                 warning ("no debugging information will be generated");
-                 level = 0;
-               }
-
-             /* If more than one debugging type is supported,
-                you must define PREFERRED_DEBUGGING_TYPE
-                to choose a format in a system-dependent way.  */
-             /* This is one long line cause VAXC can't handle a \-newline.  */
-#if 1 < (defined (DBX_DEBUGGING_INFO) + defined (SDB_DEBUGGING_INFO) + defined (DWARF_DEBUGGING_INFO) + defined (XCOFF_DEBUGGING_INFO))
-#ifdef PREFERRED_DEBUGGING_TYPE
-             if (!strncmp (str, "ggdb", len))
-               write_symbols = PREFERRED_DEBUGGING_TYPE;
-#else /* no PREFERRED_DEBUGGING_TYPE */
-You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
-#endif /* no PREFERRED_DEBUGGING_TYPE */
-#endif /* More than one debugger format enabled.  */
+             /* A lot of code assumes write_symbols == NO_DEBUG if the
+                debugging level is 0 (thus -gstabs1 -gstabs0 would lose track
+                of what debugging type has been selected).  This records the
+                selected type.  It is an error to specify more than one
+                debugging type.  */
+             static enum debug_info_type selected_debug_type = NO_DEBUG;
+             /* Non-zero if debugging format has been explicitly set.
+                -g and -ggdb don't explicitly set the debugging format so
+                -gdwarf -g3 is equivalent to -gdwarf3.  */
+             static int type_explicitly_set_p = 0;
+             /* Table of supported debugging formats.  */
+             static struct {
+               char *arg;
+               /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a
+                  constant expression, we use NO_DEBUG in its place.  */
+               enum debug_info_type debug_type;
+               int use_extensions_p;
+             } *da, debug_args[] = {
+               { "g", NO_DEBUG, DEFAULT_GDB_EXTENSIONS },
+               { "ggdb", NO_DEBUG, 1 },
 #ifdef DBX_DEBUGGING_INFO
-             if (write_symbols != NO_DEBUG)
-               ;
-             else if (!strncmp (str, "ggdb", len))
-               write_symbols = DBX_DEBUG;
-             else if (!strncmp (str, "gstabs", len))
-               write_symbols = DBX_DEBUG;
-             else if (!strncmp (str, "gstabs+", len))
-               write_symbols = DBX_DEBUG;
-
-             /* Always enable extensions for -ggdb or -gstabs+, 
-                always disable for -gstabs.
-                For plain -g, use system-specific default.  */
-             if (write_symbols == DBX_DEBUG && !strncmp (str, "ggdb", len)
-                 && len >= 2)
-               use_gnu_debug_info_extensions = 1;
-             else if (write_symbols == DBX_DEBUG && !strncmp (str, "gstabs+", len)
-                      && len >= 7)
-               use_gnu_debug_info_extensions = 1;
-             else if (write_symbols == DBX_DEBUG
-                      && !strncmp (str, "gstabs", len) && len >= 2)
-               use_gnu_debug_info_extensions = 0;
-             else
-               use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
-#endif /* DBX_DEBUGGING_INFO */
+               { "gstabs", DBX_DEBUG, 0 },
+               { "gstabs+", DBX_DEBUG, 1 },
+#endif
 #ifdef DWARF_DEBUGGING_INFO
-             if (write_symbols != NO_DEBUG)
-               ;
-             else if (!strncmp (str, "g", len))
-               write_symbols = DWARF_DEBUG;
-             else if (!strncmp (str, "ggdb", len))
-               write_symbols = DWARF_DEBUG;
-             else if (!strncmp (str, "gdwarf", len))
-               write_symbols = DWARF_DEBUG;
-
-             /* Always enable extensions for -ggdb or -gdwarf+, 
-                always disable for -gdwarf.
-                For plain -g, use system-specific default.  */
-             if (write_symbols == DWARF_DEBUG && !strncmp (str, "ggdb", len)
-                 && len >= 2)
-               use_gnu_debug_info_extensions = 1;
-             else if (write_symbols == DWARF_DEBUG && !strcmp (str, "gdwarf+"))
-               use_gnu_debug_info_extensions = 1;
-             else if (write_symbols == DWARF_DEBUG
-                      && !strncmp (str, "gdwarf", len) && len >= 2)
-               use_gnu_debug_info_extensions = 0;
-             else
-               use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
+               { "gdwarf", DWARF_DEBUG, 0 },
+               { "gdwarf+", DWARF_DEBUG, 1 },
+#endif
+#ifdef DWARF2_DEBUGGING_INFO
+               { "gdwarf-2", DWARF2_DEBUG, 0 },
 #endif
-#ifdef SDB_DEBUGGING_INFO
-             if (write_symbols != NO_DEBUG)
-               ;
-             else if (!strncmp (str, "g", len))
-               write_symbols = SDB_DEBUG;
-             else if (!strncmp (str, "gdb", len))
-               write_symbols = SDB_DEBUG;
-             else if (!strncmp (str, "gcoff", len))
-               write_symbols = SDB_DEBUG;
-#endif /* SDB_DEBUGGING_INFO */
 #ifdef XCOFF_DEBUGGING_INFO
-             if (write_symbols != NO_DEBUG)
-               ;
-             else if (!strncmp (str, "g", len))
-               write_symbols = XCOFF_DEBUG;
-             else if (!strncmp (str, "ggdb", len))
-               write_symbols = XCOFF_DEBUG;
-             else if (!strncmp (str, "gxcoff", len))
-               write_symbols = XCOFF_DEBUG;
-
-             /* Always enable extensions for -ggdb or -gxcoff+,
-                always disable for -gxcoff.
-                For plain -g, use system-specific default.  */
-             if (write_symbols == XCOFF_DEBUG && !strncmp (str, "ggdb", len)
-                 && len >= 2)
-               use_gnu_debug_info_extensions = 1;
-             else if (write_symbols == XCOFF_DEBUG && !strcmp (str, "gxcoff+"))
-               use_gnu_debug_info_extensions = 1;
-             else if (write_symbols == XCOFF_DEBUG
-                      && !strncmp (str, "gxcoff", len) && len >= 2)
-               use_gnu_debug_info_extensions = 0;
-             else
-               use_gnu_debug_info_extensions = DEFAULT_GDB_EXTENSIONS;
-#endif       
-             if (write_symbols == NO_DEBUG)
+               { "gxcoff", XCOFF_DEBUG, 0 },
+               { "gxcoff+", XCOFF_DEBUG, 1 },
+#endif
+#ifdef SDB_DEBUGGING_INFO
+               { "gcoff", SDB_DEBUG, 0 },
+#endif
+               { 0, 0, 0 }
+             };
+             /* Indexed by enum debug_info_type.  */
+             static char *debug_type_names[] = {
+               "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff"
+             };
+
+             /* Look up STR in the table.  */
+             for (da = debug_args; da->arg; da++)
+               {
+                 if (! strncmp (str, da->arg, strlen (da->arg)))
+                   {
+                     enum debug_info_type type = da->debug_type;
+                     char *p, *q;
+
+                     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);
+                         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)
+                       {
+                         warning ("invalid debug level specification in option: `-%s'",
+                                  str);
+                         /* ??? This error message is incorrect in the case of
+                            -g4 -g.  */
+                         warning ("no debugging information will be generated");
+                         level = 0;
+                       }
+
+                     if (type == NO_DEBUG)
+                       {
+                         type = PREFERRED_DEBUGGING_TYPE;
+                         if (len > 1 && strncmp (str, "ggdb", len) == 0)
+                           {
+#if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2)
+                             type = DWARF2_DEBUG;
+#else
+#ifdef DBX_DEBUGGING_INFO
+                             type = DBX_DEBUG;
+#endif
+#endif
+                           }
+                       }
+
+                     if (type == NO_DEBUG)
+                       warning ("`-%s' not supported by this configuration of GCC",
+                                str);
+
+                     /* Does it conflict with an already selected type?  */
+                     if (type_explicitly_set_p
+                         /* -g/-ggdb don't conflict with anything */
+                         && da->debug_type != NO_DEBUG
+                         && type != selected_debug_type)
+                       warning ("`-%s' ignored, conflicts with `-g%s'",
+                                str, debug_type_names[(int) selected_debug_type]);
+                     else
+                       {
+                         /* If the format has already been set, -g/-ggdb
+                            only change the debug level.  */
+                         if (type_explicitly_set_p
+                             && da->debug_type == NO_DEBUG)
+                           ; /* don't change debugging type */
+                         else
+                           {
+                             selected_debug_type = type;
+                             type_explicitly_set_p = da->debug_type != NO_DEBUG;
+                           }
+                         write_symbols = (level == 0
+                                          ? NO_DEBUG
+                                          : selected_debug_type);
+                         use_gnu_debug_info_extensions = da->use_extensions_p;
+                         debug_info_level = (enum debug_info_level) level;
+                       }
+                     break;
+                   }
+               }
+             if (! da->arg)
                warning ("`-%s' not supported by this configuration of GCC",
                         str);
-             else if (level == 0)
-               write_symbols = NO_DEBUG;
-             else
-               debug_info_level = (enum debug_info_level) level;
            }
          else if (!strcmp (str, "o"))
            {
@@ -3917,17 +4287,9 @@ You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
        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 supporter 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)
     {
@@ -3943,20 +4305,20 @@ You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
        warning ("-Wuninitialized is not supported without -O");
     }
 
-#if defined(DWARF_DEBUGGING_INFO)
-  if (write_symbols == DWARF_DEBUG
-      && strcmp (language_string, "GNU C++") == 0)
-    {
-      warning ("-g option not supported for C++ on systems using the DWARF debugging format");
-      write_symbols = NO_DEBUG;
-    }
-#endif /* defined(DWARF_DEBUGGING_INFO) */
-
 #ifdef OVERRIDE_OPTIONS
   /* Some machines may reject certain combinations of options.  */
   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.");
@@ -3998,7 +4360,7 @@ You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
 
   compile_file (filename);
 
-#if !defined(OS2) && !defined(VMS) && !defined(_WIN32)
+#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN32__))
   if (flag_print_mem)
     {
       char *lim = (char *) sbrk (0);
@@ -4007,13 +4369,15 @@ You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
               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 /* not OS2 and not VMS and not _WIN32 */
+#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN32) */
 
   if (errorcount)
     exit (FATAL_EXIT_CODE);
@@ -4047,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++)
@@ -4100,7 +4464,8 @@ print_version (file, indent)
 }
 
 /* Print an option value and return the adjusted position in the line.
-   ??? We don't handle error returns from fprintf (disk full).  */
+   ??? We don't handle error returns from fprintf (disk full); presumably
+   other code will catch a disk full though.  */
 
 int
 print_single_switch (file, pos, max, indent, sep, term, type, name)
@@ -4108,17 +4473,23 @@ print_single_switch (file, pos, max, indent, sep, term, type, name)
      int pos, max;
      char *indent, *sep, *term, *type, *name;
 {
+  /* The ultrix fprintf returns 0 on success, so compute the result we want
+     here since we need it for the following test.  */
+  int len = strlen (sep) + strlen (type) + strlen (name);
+
   if (pos != 0
-      && pos + strlen (sep) + strlen (type) + strlen (name) > max)
+      && pos + len > max)
     {
       fprintf (file, "%s", term);
       pos = 0;
     }
   if (pos == 0)
     {
-      pos = fprintf (file, "%s", indent);
+      fprintf (file, "%s", indent);
+      pos = strlen (indent);
     }
-  pos += fprintf (file, "%s%s%s", sep, type, name);
+  fprintf (file, "%s%s%s", sep, type, name);
+  pos += len;
   return pos;
 }
      
@@ -4133,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.  */
@@ -4141,10 +4512,16 @@ print_switch_values (file, pos, max, indent, sep, term)
   pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term,
                             "options passed: ", "");
 
-  for (p = &save_argv[1]; *p != (char *)0; p++)
+  for (p = &save_argv[1]; *p != NULL; p++)
     if (**p == '-')
       {
        /* Ignore these.  */
+       if (strcmp (*p, "-o") == 0)
+         {
+           if (p[1] != NULL)
+             p++;
+           continue;
+         }
        if (strcmp (*p, "-quiet") == 0)
          continue;
        if (strcmp (*p, "-version") == 0)
@@ -4171,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
@@ -4180,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
@@ -4196,3 +4571,98 @@ print_switch_values (file, pos, max, indent, sep, term)
 
   fprintf (file, "%s", term);
 }
+
+/* Record the beginning of a new source file, named FILENAME.  */
+
+void
+debug_start_source_file (filename)
+     register char *filename;
+{
+#ifdef DBX_DEBUGGING_INFO
+  if (write_symbols == DBX_DEBUG)
+    dbxout_start_new_source_file (filename);
+#endif
+#ifdef DWARF_DEBUGGING_INFO
+  if (debug_info_level == DINFO_LEVEL_VERBOSE
+      && write_symbols == DWARF_DEBUG)
+    dwarfout_start_new_source_file (filename);
+#endif /* DWARF_DEBUGGING_INFO */
+#ifdef DWARF2_DEBUGGING_INFO
+  if (debug_info_level == DINFO_LEVEL_VERBOSE
+      && write_symbols == DWARF2_DEBUG)
+    dwarf2out_start_source_file (filename);
+#endif /* DWARF2_DEBUGGING_INFO */  
+#ifdef SDB_DEBUGGING_INFO
+  if (write_symbols == SDB_DEBUG)
+    sdbout_start_new_source_file (filename);
+#endif
+}
+
+/* Record the resumption of a source file.  LINENO is the line number in
+   the source file we are returning to.  */
+
+void
+debug_end_source_file (lineno)
+     register unsigned lineno;
+{
+#ifdef DBX_DEBUGGING_INFO
+  if (write_symbols == DBX_DEBUG)
+    dbxout_resume_previous_source_file ();
+#endif
+#ifdef DWARF_DEBUGGING_INFO
+  if (debug_info_level == DINFO_LEVEL_VERBOSE
+      && write_symbols == DWARF_DEBUG)
+    dwarfout_resume_previous_source_file (lineno);
+#endif /* DWARF_DEBUGGING_INFO */
+#ifdef DWARF2_DEBUGGING_INFO
+  if (debug_info_level == DINFO_LEVEL_VERBOSE
+      && write_symbols == DWARF2_DEBUG)
+    dwarf2out_end_source_file ();
+#endif /* DWARF2_DEBUGGING_INFO */
+#ifdef SDB_DEBUGGING_INFO
+  if (write_symbols == SDB_DEBUG)
+    sdbout_resume_previous_source_file ();
+#endif
+}
+
+/* Called from check_newline in c-parse.y.  The `buffer' parameter contains
+   the tail part of the directive line, i.e. the part which is past the
+   initial whitespace, #, whitespace, directive-name, whitespace part.  */
+
+void
+debug_define (lineno, buffer)
+     register unsigned lineno;
+     register char *buffer;
+{
+#ifdef DWARF_DEBUGGING_INFO
+  if (debug_info_level == DINFO_LEVEL_VERBOSE
+      && write_symbols == DWARF_DEBUG)
+    dwarfout_define (lineno, buffer);
+#endif /* DWARF_DEBUGGING_INFO */
+#ifdef DWARF2_DEBUGGING_INFO
+  if (debug_info_level == DINFO_LEVEL_VERBOSE
+      && write_symbols == DWARF2_DEBUG)
+    dwarf2out_define (lineno, buffer);
+#endif /* DWARF2_DEBUGGING_INFO */
+}
+
+/* Called from check_newline in c-parse.y.  The `buffer' parameter contains
+   the tail part of the directive line, i.e. the part which is past the
+   initial whitespace, #, whitespace, directive-name, whitespace part.  */
+
+void
+debug_undef (lineno, buffer)
+     register unsigned lineno;
+     register char *buffer;
+{
+#ifdef DWARF_DEBUGGING_INFO
+  if (debug_info_level == DINFO_LEVEL_VERBOSE
+      && write_symbols == DWARF_DEBUG)
+    dwarfout_undef (lineno, buffer);
+#endif /* DWARF_DEBUGGING_INFO */
+#ifdef DWARF2_DEBUGGING_INFO
+  if (debug_info_level == DINFO_LEVEL_VERBOSE
+      && write_symbols == DWARF2_DEBUG)
+    dwarf2out_undef (lineno, buffer);
+#endif /* DWARF2_DEBUGGING_INFO */
+}