OSDN Git Service

* aclocal.m4: Fixed typo.
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index 64afd04..74b43de 100644 (file)
@@ -1,6 +1,6 @@
 /* Top level of GNU C compiler
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000 Free Software Foundation, Inc.
+   1999, 2000, 2001 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -45,11 +45,9 @@ Boston, MA 02111-1307, USA.  */
 #include "tm_p.h"
 #include "flags.h"
 #include "insn-attr.h"
-#include "insn-codes.h"
 #include "insn-config.h"
 #include "hard-reg-set.h"
 #include "recog.h"
-#include "defaults.h"
 #include "output.h"
 #include "except.h"
 #include "function.h"
@@ -64,10 +62,9 @@ Boston, MA 02111-1307, USA.  */
 #include "timevar.h"
 #include "diagnostic.h"
 #include "ssa.h"
-
-#ifndef ACCUMULATE_OUTGOING_ARGS
-#define ACCUMULATE_OUTGOING_ARGS 0
-#endif
+#include "params.h"
+#include "reload.h"
+#include "dwarf2asm.h"
 
 #ifdef DWARF_DEBUGGING_INFO
 #include "dwarfout.h"
@@ -164,13 +161,9 @@ static const char *decl_name PARAMS ((tree, int));
 
 static void float_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
 static void crash_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
-#ifdef ASM_IDENTIFY_LANGUAGE
-/* This might or might not be used in ASM_IDENTIFY_LANGUAGE. */
-static void output_lang_identify PARAMS ((FILE *)) ATTRIBUTE_UNUSED;
-#endif
 static void compile_file PARAMS ((const char *));
 static void display_help PARAMS ((void));
-static void mark_file_stack PARAMS ((void *));
+static void display_target_options PARAMS ((void));
 
 static void decode_d_option PARAMS ((const char *));
 static int decode_f_option PARAMS ((const char *));
@@ -192,7 +185,7 @@ static void print_switch_values PARAMS ((FILE *, int, int, const char *,
 
 const char *progname;
 
-/* Copy of arguments to main.  */
+/* Copy of arguments to toplev_main.  */
 int save_argc;
 char **save_argv;
 \f
@@ -257,6 +250,7 @@ enum dump_file_index
 {
   DFI_rtl,
   DFI_sibling,
+  DFI_eh,
   DFI_jump,
   DFI_cse,
   DFI_addressof,
@@ -275,10 +269,11 @@ enum dump_file_index
   DFI_sched,
   DFI_lreg,
   DFI_greg,
+  DFI_postreload,
   DFI_flow2,
-  DFI_ce2,
   DFI_peephole2,
   DFI_rnreg,
+  DFI_ce2,
   DFI_sched2,
   DFI_bbro,
   DFI_jump2,
@@ -293,7 +288,7 @@ enum dump_file_index
 
    Remaining -d letters:
 
-       "       h      o q   u     "
+       "              o q   u     "
        "       H  K   OPQ  TUVW YZ"
 */
 
@@ -301,6 +296,7 @@ struct dump_file_info dump_file[DFI_MAX] =
 {
   { "rtl",     'r', 0, 0, 0 },
   { "sibling",  'i', 0, 0, 0 },
+  { "eh",      'h', 0, 0, 0 },
   { "jump",    'j', 0, 0, 0 },
   { "cse",     's', 0, 0, 0 },
   { "addressof", 'F', 0, 0, 0 },
@@ -319,10 +315,11 @@ struct dump_file_info dump_file[DFI_MAX] =
   { "sched",   'S', 1, 0, 0 },
   { "lreg",    'l', 1, 0, 0 },
   { "greg",    'g', 1, 0, 0 },
+  { "postreload", 'o', 1, 0, 0 },
   { "flow2",   'w', 1, 0, 0 },
-  { "ce2",     'E', 1, 0, 0 },
   { "peephole2", 'z', 1, 0, 0 },
   { "rnreg",   'n', 1, 0, 0 },
+  { "ce2",     'E', 1, 0, 0 },
   { "sched2",  'R', 1, 0, 0 },
   { "bbro",    'B', 1, 0, 0 },
   { "jump2",   'J', 1, 0, 0 },
@@ -339,7 +336,6 @@ static void close_dump_file PARAMS ((enum dump_file_index,
 
 int rtl_dump_and_exit;
 int flag_print_asm_name;
-static int flag_print_mem;
 static int version_flag;
 static char *filename;
 enum graph_dump_types graph_dump_format;
@@ -389,6 +385,9 @@ int errorcount = 0;
 int warningcount = 0;
 int sorrycount = 0;
 
+/* Nonzero if we should exit after parsing options.  */
+static int exit_after_options = 0;
+
 /* The FUNCTION_DECL for the function currently being compiled,
    or 0 if between functions.  */
 tree current_function_decl;
@@ -422,6 +421,10 @@ tree (*lang_expand_constant) PARAMS ((tree)) = 0;
 
 void (*incomplete_decl_finalize_hook) PARAMS ((tree)) = 0;
 
+/* Nonzero if doing dwarf2 duplicate elimination.  */
+
+int flag_eliminate_dwarf2_dups = 0;
+
 /* Nonzero if generating code to do profiling.  */
 
 int profile_flag = 0;
@@ -460,10 +463,23 @@ int pedantic = 0;
 
 int in_system_header = 0;
 
-/* Don't print functions as they are compiled and don't print
-   times taken by the various passes.  -quiet.  */
+/* Don't print functions as they are compiled.  -quiet.  */
 
 int quiet_flag = 0;
+
+/* Print times taken by the various passes.  -ftime-report.  */
+
+int time_report = 0;
+
+/* Print memory still in use at end of compilation (which may have little
+   to do with peak memory consumption).  -fmem-report.  */
+
+int mem_report = 0;
+
+/* Non-zero means to collect statistics which might be expensive
+   and to print them when we are done.  */
+int flag_detailed_statistics = 0;
+
 \f
 /* -f flags.  */
 
@@ -596,25 +612,31 @@ int flag_data_sections = 0;
 
 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.  */
-
-int flag_fast_math = 0;
-
 /* Nonzero allows GCC to optimize sibling and tail recursive calls.  */
 
 int flag_optimize_sibling_calls = 0;
 
 /* Nonzero means the front end generally wants `errno' maintained by math
-   operations, like built-in SQRT, unless overridden by flag_fast_math.  */
+   operations, like built-in SQRT.  */
 
 int flag_errno_math = 1;
 
+/* Nonzero means that unsafe floating-point math optimizations are allowed
+   for the sake of speed.  IEEE compliance is not guaranteed, and operations
+   are allowed to assume that their arguments and results are "normal"
+   (e.g., nonnegative for SQRT).  */
+
+int flag_unsafe_math_optimizations = 0;
+
+/* Zero means that floating-point math operations cannot generate a
+   (user-visible) trap.  This is the case, for example, in nonstop
+   IEEE 754 arithmetic.  */
+
+int flag_trapping_math = 1;
+
 /* 0 means straightforward implementation of complex divide acceptable.
    1 means wide ranges of inputs must work for complex divide.
-   2 means C9X-like requirements for complex divide (not yet implemented).  */
+   2 means C99-like requirements for complex divide (not yet implemented).  */
 
 int flag_complex_divide_method = 0;
 
@@ -643,6 +665,18 @@ static int flag_gcse;
 
 static int flag_delete_null_pointer_checks;
 
+/* Nonzero means to do the enhanced load motion during gcse, which trys
+   to hoist loads by not killing them when a store to the same location
+   is seen.  */
+
+int flag_gcse_lm = 1;
+
+/* Nonzero means to perform store motion after gcse, which will try to
+   move stores closer to the exit block.  Its not very effective without
+   flag_gcse_lm.  */
+
+int flag_gcse_sm = 1;
+
 /* Nonzero means to rerun cse after loop optimization.  This increases
    compilation time about 20% and picks up a few more common expressions.  */
 
@@ -700,11 +734,6 @@ int flag_pic;
 
 int flag_exceptions;
 
-/* Nonzero means use the new model for exception handling. Replaces
-   -DNEW_EH_MODEL as a compile option.  */
-
-int flag_new_exceptions = 1;
-
 /* Nonzero means generate frame unwind info table when supported.  */
 
 int flag_unwind_tables = 0;
@@ -778,6 +807,10 @@ int flag_verbose_asm = 0;
 
 int flag_debug_asm = 0;
 
+/* -dP causes the rtl to be emitted as a comment in assembly.  */
+
+int flag_dump_rtl_in_asm = 0;
+
 /* -fgnu-linker specifies use of the GNU linker for initializations.
    (Or, more generally, a linker that handles initializations.)
    -fno-gnu-linker says that collect2 will be used.  */
@@ -845,6 +878,9 @@ int flag_no_ident = 0;
 /* This will perform a peephole pass before sched2.  */
 int flag_peephole2 = 0;
 
+/* This will try to guess branch probabilities.  */
+int flag_guess_branch_prob = 0;
+
 /* -fbounded-pointers causes gcc to compile pointers as composite
    objects occupying three words: the pointer value, the base address
    of the referent object, and the address immediately beyond the end
@@ -925,12 +961,22 @@ typedef struct
 }
 lang_independent_options;
 
+int flag_trapv = 0;
+
 /* Add or remove a leading underscore from user symbols.  */
 int flag_leading_underscore = -1;
 
 /* The user symbol prefix after having resolved same.  */
 const char *user_label_prefix;
 
+static const param_info lang_independent_params[] = {
+#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT) \
+  { OPTION, DEFAULT, HELP },
+#include "params.def"
+#undef DEFPARAM
+  { NULL, 0, NULL }
+};
+
 /* A default for same.  */
 #ifndef USER_LABEL_PREFIX
 #define USER_LABEL_PREFIX ""
@@ -944,6 +990,8 @@ const char *user_label_prefix;
 
 lang_independent_options f_options[] =
 {
+  {"eliminate-dwarf2-dups", &flag_eliminate_dwarf2_dups, 1,
+   "Perform DWARF2 duplicate elimination"},
   {"float-store", &flag_float_store, 1,
    "Do not store floats in registers" },
   {"volatile", &flag_volatile, 1,
@@ -1008,6 +1056,10 @@ lang_independent_options f_options[] =
    "Attempt to fill delay slots of branch instructions" },
   {"gcse", &flag_gcse, 1,
    "Perform the global common subexpression elimination" },
+  {"gcse-lm", &flag_gcse_lm, 1,
+   "Perform enhanced load motion during global subexpression elimination" },
+  {"gcse-sm", &flag_gcse_sm, 1,
+   "Perform store motion after global subexpression elimination" },
   {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1,
    "Run CSE pass after loop optimisations"},
   {"rerun-loop-opt", &flag_rerun_loop_opt, 1,
@@ -1017,9 +1069,9 @@ lang_independent_options f_options[] =
   {"pretend-float", &flag_pretend_float, 1,
    "Pretend that host and target use the same FP format"},
   {"schedule-insns", &flag_schedule_insns, 1,
-   "Reschedule instructions to avoid pipeline stalls"},
+   "Reschedule instructions before register allocation"},
   {"schedule-insns2", &flag_schedule_insns_after_reload, 1,
-  "Run two passes of the instruction scheduler"},
+   "Reschedule instructions after register allocation"},
   {"sched-interblock",&flag_schedule_interblock, 1,
    "Enable scheduling across basic blocks" },
   {"sched-spec",&flag_schedule_speculative, 1,
@@ -1035,14 +1087,10 @@ lang_independent_options f_options[] =
   {"PIC", &flag_pic, 2, ""},
   {"exceptions", &flag_exceptions, 1,
    "Enable exception handling" },
-  {"new-exceptions", &flag_new_exceptions, 1,
-   "Use the new model for exception handling" },
   {"unwind-tables", &flag_unwind_tables, 1,
     "Just generate unwind tables for exception handling" },
-  {"sjlj-exceptions", &exceptions_via_longjmp, 1,
-   "Use setjmp/longjmp to handle exceptions" },
-  {"asynchronous-exceptions", &asynchronous_exceptions, 1,
-   "Support asynchronous exceptions" },
+  {"non-call-exceptions", &flag_non_call_exceptions, 1,
+   "Support synchronous non-call exceptions" },
   {"profile-arcs", &profile_arc_flag, 1,
    "Insert arc based program profiling code" },
   {"test-coverage", &flag_test_coverage, 1,
@@ -1053,8 +1101,6 @@ lang_independent_options f_options[] =
    "Reorder basic blocks to improve code placement" },
   {"rename-registers", &flag_rename_registers, 1,
    "Do the register renaming optimization pass"},
-  {"fast-math", &flag_fast_math, 1,
-   "Improve FP speed by violating ANSI & IEEE rules" },
   {"common", &flag_no_common, 0,
    "Do not put unitialised globals in the common section" },
   {"inhibit-size-directive", &flag_inhibit_size_directive, 1,
@@ -1109,14 +1155,26 @@ lang_independent_options f_options[] =
    "Process #ident directives"},
   { "peephole2", &flag_peephole2, 1,
     "Enables an rtl peephole pass run before sched2" },
+  { "guess-branch-probability", &flag_guess_branch_prob, 1,
+    "Enables guessing of branch probabilities" },
   {"math-errno", &flag_errno_math, 1,
    "Set errno after built-in math functions"},
+  {"trapping-math", &flag_trapping_math, 1,
+   "Floating-point operations can trap"},
+  {"unsafe-math-optimizations", &flag_unsafe_math_optimizations, 1,
+   "Allow math optimizations that may violate IEEE or ANSI standards"},
   {"bounded-pointers", &flag_bounded_pointers, 1,
    "Compile pointers as triples: value, base & end" },
   {"bounds-check", &flag_bounds_check, 1,
    "Generate code to check bounds before dereferencing pointers and arrays" },
   {"single-precision-constant", &flag_single_precision_constant, 1,
-  "Convert floating point constant to single precision constant"}
+   "Convert floating point constant to single precision constant"},
+  {"time-report", &time_report, 1,
+   "Report time taken by each compiler pass at end of run"},
+  {"mem-report", &mem_report, 1,
+   "Report on permanent memory allocation at end of run"},
+  { "trapv", &flag_trapv, 1,
+    "Trap for signed overflow in addition / subtraction / multiplication." },
 };
 
 /* Table of language-specific options.  */
@@ -1177,9 +1235,10 @@ documented_lang_options[] =
   { "-Wbad-function-cast",
     "Warn about casting functions to incompatible types" },
   { "-Wno-bad-function-cast", "" },
-  { "-Wmissing-noreturn",
-    "Warn about functions which might be candidates for attribute noreturn" },
   { "-Wno-missing-noreturn", "" },
+  { "-Wmissing-format-attribute",
+    "Warn about functions which might be candidates for format attributes" },
+  { "-Wno-missing-format-attribute", "" },
   { "-Wcast-qual", "Warn about casts which discard qualifiers"},
   { "-Wno-cast-qual", "" },
   { "-Wchar-subscripts", "Warn about subscripts whose type is 'char'"},
@@ -1190,8 +1249,19 @@ documented_lang_options[] =
   { "-Wno-comments", "" },
   { "-Wconversion", "Warn about possibly confusing type conversions" },
   { "-Wno-conversion", "" },
-  { "-Wformat", "Warn about printf format anomalies" },
+  { "-Wformat", "Warn about printf/scanf/strftime/strfmon format anomalies" },
   { "-Wno-format", "" },
+  { "-Wformat-y2k", "" },
+  { "-Wno-format-y2k",
+    "Don't warn about strftime formats yielding 2 digit years" },
+  { "-Wformat-extra-args", "" },
+  { "-Wno-format-extra-args",
+    "Don't warn about too many arguments to format functions" },
+  { "-Wformat-nonliteral", "Warn about non-string-literal format strings" },
+  { "-Wno-format-nonliteral", "" },
+  { "-Wformat-security",
+    "Warn about possible security problems with format functions" },
+  { "-Wno-format-security", "" },
   { "-Wimplicit-function-declaration",
     "Warn about implicit function declarations" },
   { "-Wno-implicit-function-declaration", "" },
@@ -1220,6 +1290,9 @@ documented_lang_options[] =
   { "-Wno-nested-externs", "" },
   { "-Wparentheses", "Warn about possible missing parentheses" },
   { "-Wno-parentheses", "" },
+  { "-Wsequence-point",
+    "Warn about possible violations of sequence point rules" },
+  { "-Wno-sequence-point", "" },
   { "-Wpointer-arith", "Warn about function pointer arithmetic" },
   { "-Wno-pointer-arith", "" },
   { "-Wredundant-decls",
@@ -1280,6 +1353,10 @@ target_options [] = TARGET_OPTIONS;
 
 int inhibit_warnings = 0;
 
+/* Don't suppress warnings from system headers.  -Wsystem-headers.  */
+
+int warn_system_headers = 0;
+
 /* Print various extra warnings.  -W.  */
 
 int extra_warnings = 0;
@@ -1344,7 +1421,7 @@ int warn_cast_align;
    characters.  The value N is in `id_clash_len'.  */
 
 int warn_id_clash;
-int id_clash_len;
+unsigned int id_clash_len;
 
 /* Nonzero means warn about any objects definitions whose size is larger
    than N bytes.  Also want about function definitions whose returned
@@ -1370,6 +1447,14 @@ int warn_packed;
 
 int warn_padded;
 
+/* Warn when an optimization pass is disabled.  */
+
+int warn_disabled_optimization;
+
+/* Warn about functions which might be candidates for attribute noreturn.  */
+
+int warn_missing_noreturn;
+
 /* Likewise for -W.  */
 
 lang_independent_options W_options[] =
@@ -1379,6 +1464,7 @@ lang_independent_options W_options[] =
   {"unused-parameter", &warn_unused_parameter, 1, "Warn when a function parameter is unused" },
   {"unused-variable", &warn_unused_variable, 1, "Warn when a variable is unused" },
   {"unused-value", &warn_unused_value, 1, "Warn when an expression value is unused" },
+  {"system-headers", &warn_system_headers, 1, "Do not suppress warnings from system headers"},
   {"error", &warnings_are_errors, 1, ""},
   {"shadow", &warn_shadow, 1, "Warn when one local variable shadows another" },
   {"switch", &warn_switch, 1,
@@ -1396,8 +1482,32 @@ lang_independent_options W_options[] =
   {"packed", &warn_packed, 1,
    "Warn when the packed attribute has no effect on struct layout"},
   {"padded", &warn_padded, 1,
-   "Warn when padding is required to align struct members"}
+   "Warn when padding is required to align struct members"},
+  {"disabled-optimization", &warn_disabled_optimization, 1,
+   "Warn when an optimization pass is disabled"},
+  {"missing-noreturn", &warn_missing_noreturn, 1,
+   "Warn about functions which might be candidates for attribute noreturn"}
 };
+
+/* The following routines are useful in setting all the flags that
+   -ffast-math and -fno-fast-math imply.  */
+
+void
+set_fast_math_flags ()
+{
+  flag_trapping_math = 0;
+  flag_unsafe_math_optimizations = 1;
+  flag_errno_math = 0;
+}
+
+void
+set_no_fast_math_flags ()
+{
+  flag_trapping_math = 1;
+  flag_unsafe_math_optimizations = 0;
+  flag_errno_math = 1;
+}
+
 \f
 /* Output files for assembler code (real compiler output)
    and debugging dumps.  */
@@ -1448,26 +1558,6 @@ decl_name (decl, verbosity)
   return IDENTIFIER_POINTER (DECL_NAME (decl));
 }
 \f
-/* Mark P for GC.  Also mark main_input_filename and input_filename.  */
-
-static void
-mark_file_stack (p)
-     void *p;
-{
-  struct file_stack *stack = *(struct file_stack **)p;
-
-  /* We're only called for input_file_stack, so we can mark the current
-     input_filename here as well.  */
-  ggc_mark_string (main_input_filename);
-  ggc_mark_string (input_filename);
-
-  while (stack)
-    {
-      ggc_mark_string (stack->name);
-      stack = stack->next;
-    }
-}
-\f
 
 /* This calls abort and is used to avoid problems when abort if a macro.
    It is used when we need to pass the address of abort.  */
@@ -1535,11 +1625,10 @@ float_signal (signo)
 {
   if (float_handled == 0)
     crash_signal (signo);
-#if defined (USG) || defined (hpux)
-  /* Re-enable the signal catcher.  */
-  signal (SIGFPE, float_signal);
-#endif
   float_handled = 0;
+
+  /* On System-V derived systems, we must reinstall the signal handler.
+     This is harmless on BSD-derived systems.  */
   signal (SIGFPE, float_signal);
   longjmp (float_handler, 1);
 }
@@ -1553,7 +1642,7 @@ set_float_handler (handler)
 {
   float_handled = (handler != 0);
   if (handler)
-    bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
+    memcpy (float_handler, handler, sizeof (float_handler));
 
   if (float_handled && ! float_handler_set)
     {
@@ -1590,49 +1679,14 @@ do_float_handler (fn, data)
   return 1;
 }
 
-/* Specify, in HANDLER, where to longjmp to when a floating arithmetic
-   error happens, pushing the previous specification into OLD_HANDLER.
-   Return an indication of whether there was a previous handler in effect.  */
-
-int
-push_float_handler (handler, old_handler)
-     jmp_buf handler, old_handler;
-{
-  int was_handled = float_handled;
-
-  float_handled = 1;
-  if (was_handled)
-    memcpy ((char *) old_handler, (char *) float_handler,
-          sizeof (float_handler));
-
-  memcpy ((char *) float_handler, (char *) handler, sizeof (float_handler));
-  return was_handled;
-}
-
-/* Restore the previous specification of whether and where to longjmp to
-   when a floating arithmetic error happens.  */
-
-void
-pop_float_handler (handled, handler)
-     int handled;
-     jmp_buf handler;
-{
-  float_handled = handled;
-  if (handled)
-    bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
-}
-
 /* Handler for fatal signals, such as SIGSEGV.  These are transformed
    into ICE messages, which is much more user friendly.  */
 
 static void
 crash_signal (signo)
-     /* If this is missing, some compilers complain.  */
      int signo;
 {
-  fatal ("Internal error: %s.\n\
-Please submit a full bug report.\n\
-See %s for instructions.", strsignal (signo), GCCBUGURL);
+  internal_error ("Internal error: %s", strsignal (signo));
 }
 
 /* Strip off a legitimate source ending from the input string NAME of
@@ -1710,21 +1764,6 @@ output_file_directive (asm_file, input_name)
 #endif
 }
 \f
-#ifdef ASM_IDENTIFY_LANGUAGE
-/* Routine to build language identifier for object file.  */
-
-static void
-output_lang_identify (asm_out_file)
-     FILE *asm_out_file;
-{
-  int len = strlen (lang_identify ()) + sizeof ("__gnu_compiled_") + 1;
-  char *s = (char *) alloca (len);
-
-  sprintf (s, "__gnu_compiled_%s", lang_identify ());
-  ASM_OUTPUT_LABEL (asm_out_file, s);
-}
-#endif
-
 /* Routine to open a dump file.  Return true if the dump file is enabled.  */
 
 static int
@@ -1766,7 +1805,7 @@ open_dump_file (index, decl)
 
   rtl_dump_file = fopen (dump_name, open_arg);
   if (rtl_dump_file == NULL)
-    pfatal_with_name (dump_name);
+    fatal_io_error ("can't open %s", dump_name);
 
   free (dump_name);
 
@@ -1879,13 +1918,15 @@ wrapup_global_declarations (vec, len)
             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 && flag_keep_static_consts)
+             && (((! TREE_READONLY (decl) || TREE_PUBLIC (decl))
+                  && !DECL_COMDAT (decl))
+                 || (!optimize
+                     && flag_keep_static_consts
+                     && !DECL_ARTIFICIAL (decl))
                  || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
            {
              reconsider = 1;
-             rest_of_decl_compilation (decl, NULL_PTR, 1, 1);
+             rest_of_decl_compilation (decl, NULL, 1, 1);
            }
 
          if (TREE_CODE (decl) == FUNCTION_DECL
@@ -1896,9 +1937,7 @@ wrapup_global_declarations (vec, len)
                  || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
            {
              reconsider = 1;
-             temporary_allocation ();
              output_inline_function (decl);
-             permanent_allocation (1);
            }
        }
 
@@ -1930,7 +1969,7 @@ check_global_declarations (vec, len)
        /* Cancel the RTL for this decl so that, if debugging info
           output for global variables is still to come,
           this one will be omitted.  */
-       DECL_RTL (decl) = NULL;
+       SET_DECL_RTL (decl, NULL_RTX);
 
       /* Warn about any function
         declared static but not defined.
@@ -2059,7 +2098,7 @@ pop_srcloc ()
   input_file_stack = fs->next;
   free (fs);
   input_file_stack_tick++;
-  /* The initial souce file is never popped.  */
+  /* The initial source file is never popped.  */
   if (!input_file_stack)
     abort ();
   input_filename = input_file_stack->name;
@@ -2080,15 +2119,42 @@ compile_file (name)
   if (dump_base_name == 0)
     dump_base_name = name ? name : "gccdump";
 
+  if (! quiet_flag)
+    time_report = 1;
+
   /* Start timing total execution time.  */
 
   init_timevar ();
   timevar_start (TV_TOTAL);
 
+  /* Open assembler code output file.  Do this even if -fsyntax-only is on,
+     because then the driver will have provided the name of a temporary
+     file or bit bucket for us.  */
+
+  if (! name_specified && asm_file_name == 0)
+    asm_out_file = stdout;
+  else
+    {
+      if (asm_file_name == 0)
+        {
+          int len = strlen (dump_base_name);
+          char *dumpname = (char *) xmalloc (len + 6);
+          memcpy (dumpname, dump_base_name, len + 1);
+          strip_off_ending (dumpname, len);
+          strcat (dumpname, ".s");
+          asm_file_name = dumpname;
+        }
+      if (!strcmp (asm_file_name, "-"))
+        asm_out_file = stdout;
+      else
+        asm_out_file = fopen (asm_file_name, "w");
+      if (asm_out_file == 0)
+       fatal_io_error ("can't open %s for writing", asm_file_name);
+    }
+
   /* Initialize data in various passes.  */
 
   init_obstacks ();
-  init_tree_codes ();
   name = init_parse (name);
   init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
                  || debug_info_level == DINFO_LEVEL_VERBOSE
@@ -2097,14 +2163,15 @@ compile_file (name)
   init_regs ();
   init_alias_once ();
   init_decl_processing ();
+  init_eh ();
   init_optabs ();
   init_stmt ();
-  init_eh ();
   init_loop ();
   init_reload ();
   init_function_once ();
   init_stor_layout_once ();
   init_varasm_once ();
+  init_EXPR_INSN_LIST_cache ();
 
   /* The following initialization functions need to generate rtl, so
      provide a dummy function context for them.  */
@@ -2122,32 +2189,7 @@ compile_file (name)
     {
       aux_info_file = fopen (aux_info_file_name, "w");
       if (aux_info_file == 0)
-       pfatal_with_name (aux_info_file_name);
-    }
-
-  /* Open assembler code output file.  Do this even if -fsyntax-only is on,
-     because then the driver will have provided the name of a temporary
-     file or bit bucket for us.  */
-
-  if (! name_specified && asm_file_name == 0)
-    asm_out_file = stdout;
-  else
-    {
-      if (asm_file_name == 0)
-        {
-          int len = strlen (dump_base_name);
-          char *dumpname = (char *) xmalloc (len + 6);
-          memcpy (dumpname, dump_base_name, len + 1);
-          strip_off_ending (dumpname, len);
-          strcat (dumpname, ".s");
-          asm_file_name = dumpname;
-        }
-      if (!strcmp (asm_file_name, "-"))
-        asm_out_file = stdout;
-      else
-        asm_out_file = fopen (asm_file_name, "w");
-      if (asm_out_file == 0)
-        pfatal_with_name (asm_file_name);
+       fatal_io_error ("can't open %s", aux_info_file_name);
     }
 
 #ifdef IO_BUFFER_SIZE
@@ -2155,8 +2197,8 @@ compile_file (name)
            _IOFBF, IO_BUFFER_SIZE);
 #endif
 
-  if (ggc_p && name != 0)
-    name = ggc_alloc_string (name, strlen (name));
+  if (name != 0)
+    name = ggc_strdup (name);
 
   input_filename = name;
 
@@ -2165,7 +2207,8 @@ compile_file (name)
 
   /* Perform language-specific initialization.
      This may set main_input_filename.  */
-  lang_init ();
+  if (lang_hooks.init)
+    (*lang_hooks.init) ();
 
   /* If the input doesn't start with a #line, use the input name
      as the official input file name.  */
@@ -2194,18 +2237,6 @@ compile_file (name)
          fprintf (asm_out_file, "\n");
        }
 #endif
-
-      /* Output something to inform GDB that this compilation was by GCC.  */
-#ifndef ASM_IDENTIFY_GCC
-      fprintf (asm_out_file, "gcc2_compiled.:\n");
-#else
-      ASM_IDENTIFY_GCC (asm_out_file);
-#endif
-
-  /* Output something to identify which front-end produced this file.  */
-#ifdef ASM_IDENTIFY_LANGUAGE
-      ASM_IDENTIFY_LANGUAGE (asm_out_file);
-#endif
     } /* ! flag_syntax_only  */
 
 #ifndef ASM_OUTPUT_SECTION_NAME
@@ -2233,25 +2264,6 @@ compile_file (name)
     warning ("-ffunction-sections may affect debugging on some targets.");
 #endif
 
-  /* ??? 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)
-    {
-      /* It's best if we can write a nop here since some
-        assemblers don't tolerate zeros in the text section.  */
-      output_asm_insn (get_insn_template (CODE_FOR_nop, NULL), NULL_PTR);
-    }
-
   /* If dbx symbol table desired, initialize writing it
      and output the predefined types.  */
   timevar_push (TV_SYMOUT);
@@ -2335,14 +2347,6 @@ compile_file (name)
        loop above.  */
     output_func_start_profiler ();
 
-    /* Now that all possible functions have been output, we can dump
-       the exception table.  */
-
-#ifndef IA64_UNWIND_INFO
-    output_exception_table ();
-#endif
-    free_exception_table ();
-
     check_global_declarations (vec, len);
 
     /* Clean up.  */
@@ -2378,6 +2382,8 @@ compile_file (name)
 
   /* Output some stuff at end of file if nec.  */
 
+  dw2_output_indirect_constants ();
+
   end_final (dump_base_name);
 
   if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
@@ -2395,9 +2401,19 @@ compile_file (name)
   ASM_FILE_END (asm_out_file);
 #endif
 
+  /* Attach a special .ident directive to the end of the file to identify
+     the version of GCC which compiled this code.  The format of the .ident
+     string is patterned after the ones produced by native SVR4 compilers.  */
+#ifdef IDENT_ASM_OP
+  if (!flag_no_ident)
+    fprintf (asm_out_file, "%s\"GCC: (GNU) %s\"\n",
+            IDENT_ASM_OP, version_string);
+#endif
+
   /* Language-specific end of compilation actions.  */
  finish_syntax:
-  lang_finish ();
+  if (lang_hooks.finish)
+    (*lang_hooks.finish) ();
 
   /* Close the dump files.  */
 
@@ -2422,15 +2438,17 @@ compile_file (name)
 
   finish_parse ();
 
-  if (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0)
-    fatal_io_error (asm_file_name);
+  if (ferror (asm_out_file) != 0)
+    fatal_io_error ("error writing to %s", asm_file_name);
+  if (fclose (asm_out_file) != 0)
+    fatal_io_error ("error closing %s", asm_file_name);
 
   /* Do whatever is necessary to finish printing the graphs.  */
   if (graph_dump_format != no_graph)
     {
       int i;
 
-      for (i = 0; i < DFI_MAX; ++i)
+      for (i = 0; i < (int) DFI_MAX; ++i)
        if (dump_file[i].initialized && dump_file[i].graph_dump_p)
          {
            char seq[16];
@@ -2443,6 +2461,12 @@ compile_file (name)
          }
     }
 
+  if (mem_report)
+    {
+      ggc_print_statistics ();
+      stringpool_statistics ();
+    }
+
   /* Free up memory for the benefit of leak detectors.  */
   free_reg_info ();
 
@@ -2488,21 +2512,13 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
       || TREE_CODE (decl) == FUNCTION_DECL)
     {
       timevar_push (TV_VARCONST);
-      make_decl_rtl (decl, asmspec, top_level);
-      /* Initialized extern variable exists to be replaced
-        with its value, or represents something that will be
-        output in another file.  */
-      if (! (TREE_CODE (decl) == VAR_DECL
-            && DECL_EXTERNAL (decl) && TREE_READONLY (decl)
-            && DECL_INITIAL (decl) != 0
-            && DECL_INITIAL (decl) != error_mark_node))
-       /* Don't output anything
-            when a tentative file-scope definition is seen.
-            But at end of compilation, do output code for them.  */
-       if (! (! at_end && top_level
-              && (DECL_INITIAL (decl) == 0
-                  || DECL_INITIAL (decl) == error_mark_node)))
-         assemble_variable (decl, top_level, at_end, 0);
+      if (asmspec)
+       make_decl_rtl (decl, asmspec);
+      /* Don't output anything
+        when a tentative file-scope definition is seen.
+        But at end of compilation, do output code for them.  */
+      if (at_end || !DECL_DEFER_OUTPUT (decl))
+       assemble_variable (decl, top_level, at_end, 0);
       if (decl == last_assemble_variable_decl)
        {
          ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
@@ -2514,11 +2530,16 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
     {
       if (decode_reg_name (asmspec) >= 0)
        {
-         DECL_RTL (decl) = 0;
-         make_decl_rtl (decl, asmspec, top_level);
+         SET_DECL_RTL (decl, NULL_RTX);
+         make_decl_rtl (decl, asmspec);
        }
       else
-       error ("invalid register name `%s' for register variable", asmspec);
+       {
+         error ("invalid register name `%s' for register variable", asmspec);
+         DECL_REGISTER (decl) = 0;
+         if (!top_level)
+           expand_decl (decl);
+       }
     }
 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
   else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
@@ -2561,6 +2582,10 @@ rest_of_type_compilation (type, toplev)
   if (write_symbols == SDB_DEBUG)
     sdbout_symbol (TYPE_STUB_DECL (type), !toplev);
 #endif
+#ifdef DWARF2_DEBUGGING_INFO
+  if (write_symbols == DWARF2_DEBUG && toplev)
+    dwarf2out_decl (TYPE_STUB_DECL (type));
+#endif
   timevar_pop (TV_SYMOUT);
 }
 
@@ -2580,19 +2605,23 @@ note_deferral_of_defined_inline_function (decl)
   /* 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 && DECL_INLINE (decl))
+  if (write_symbols == DWARF_DEBUG
+      && (DECL_INLINE (decl) || DECL_ABSTRACT (decl))
+      && ! DECL_ABSTRACT_ORIGIN (decl))
     {
       /* The front-end may not have set CURRENT_FUNCTION_DECL, but the
         DWARF code expects it to be set in this case.  Intuitively,
         DECL is the function we just finished defining, so setting
         CURRENT_FUNCTION_DECL is sensible.  */
       tree saved_cfd = current_function_decl;
+      int was_abstract = DECL_ABSTRACT (decl);
       current_function_decl = decl;
 
       /* Let the DWARF code do its work.  */
       set_decl_abstract_flags (decl, 1);
       dwarfout_file_scope_decl (decl, 0);
-      set_decl_abstract_flags (decl, 0);
+      if (! was_abstract)
+       set_decl_abstract_flags (decl, 0);
 
       /* Reset CURRENT_FUNCTION_DECL.  */
       current_function_decl = saved_cfd;
@@ -2600,6 +2629,24 @@ note_deferral_of_defined_inline_function (decl)
 #endif
 }
 
+/* FNDECL is an inline function which is about to be emitted out of line.
+   Do any preparation, such as emitting abstract debug info for the inline
+   before it gets mangled by optimization.  */
+
+void
+note_outlining_of_inline_function (fndecl)
+     tree fndecl ATTRIBUTE_UNUSED;
+{
+#ifdef DWARF2_DEBUGGING_INFO
+  /* The DWARF 2 backend tries to reduce debugging bloat by not emitting
+     the abstract description of inline functions until something tries to
+     reference them.  Force it out now, before optimizations mangle the
+     block tree.  */
+  if (write_symbols == DWARF2_DEBUG)
+    dwarf2out_abstract_function (fndecl);
+#endif
+}
+
 /* This is called from finish_function (within yyparse)
    after each top-level definition is parsed.
    It is supposed to compile that function or variable
@@ -2618,6 +2665,10 @@ rest_of_compilation (decl)
 
   timevar_push (TV_REST_OF_COMPILATION);
 
+  /* Now that we're out of the frontend, we shouldn't have any more
+     CONCATs anywhere.  */
+  generating_concat_p = 0;
+
   /* When processing delayed functions, prepare_function_start() won't
      have been run to re-initialize it.  */
   cse_not_expected = ! optimize;
@@ -2637,6 +2688,8 @@ rest_of_compilation (decl)
   if (cfun->x_whole_function_mode_p)
     reorder_blocks ();
 
+  init_flow ();
+
   /* If we are reconsidering an inline function
      at the end of compilation, skip the stuff for making it inline.  */
 
@@ -2661,7 +2714,8 @@ rest_of_compilation (decl)
          }
 
       /* If requested, consider whether to make this function inline.  */
-      if (DECL_INLINE (decl) || flag_inline_functions)
+      if ((DECL_INLINE (decl) && !flag_no_inline)
+         || flag_inline_functions)
        {
          timevar_push (TV_INTEGRATION);
          lose = function_cannot_inline_p (decl);
@@ -2699,6 +2753,11 @@ rest_of_compilation (decl)
          close_dump_file (DFI_rtl, print_rtl, insns);
        }
 
+      /* Convert from NOTE_INSN_EH_REGION style notes, and do other
+        sorts of eh initialization.  Delay this until after the
+         initial rtl dump so that we can see the original nesting.  */
+      convert_from_eh_region_ranges ();
+
       /* If function is inline, and we don't yet know whether to
         compile it by itself, defer decision till end of compilation.
         finish_compilation will call rest_of_compilation again
@@ -2722,17 +2781,15 @@ rest_of_compilation (decl)
 
       if (DECL_DEFER_OUTPUT (decl))
        {
-         /* 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 -Wreturn-type, we have to do a bit of compilation.  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 (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
@@ -2747,7 +2804,7 @@ rest_of_compilation (decl)
            TREE_NOTHROW (current_function_decl) = 1;
 
          timevar_push (TV_INTEGRATION);
-         save_for_inline_nocopy (decl);
+         save_for_inline (decl);
          timevar_pop (TV_INTEGRATION);
          DECL_SAVED_INSNS (decl)->inlinable = inlinable;
          goto exit_rest_of_compilation;
@@ -2760,10 +2817,7 @@ rest_of_compilation (decl)
        goto exit_rest_of_compilation;
     }
 
-  init_EXPR_INSN_LIST_cache ();
-
-  if (ggc_p)
-    ggc_collect ();
+  ggc_collect ();
 
   /* Initialize some variables used by the optimizers.  */
   init_function_for_compilation ();
@@ -2771,18 +2825,18 @@ rest_of_compilation (decl)
   if (! DECL_DEFER_OUTPUT (decl))
     TREE_ASM_WRITTEN (decl) = 1;
 
-  /* Now that integrate will no longer see our rtl, we need not distinguish
-     between the return value of this function and the return value of called
-     functions.  */
+  /* Now that integrate will no longer see our rtl, we need not
+     distinguish between the return value of this function and the
+     return value of called functions.  Also, we can remove all SETs
+     of subregs of hard registers; they are only here because of
+     integrate.*/
   rtx_equal_function_value_matters = 0;
+  purge_hard_subreg_sets (get_insns ());
 
   /* Don't return yet if -Wreturn-type; we need to do jump_optimize.  */
   if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
     goto exit_rest_of_compilation;
 
-  /* Emit code to get eh context, if needed. */
-  emit_eh_context ();
-
   /* We may have potential sibling or tail recursion sites.  Select one
      (of possibly multiple) methods of performing the call.  */
   if (flag_optimize_sibling_calls)
@@ -2796,6 +2850,19 @@ rest_of_compilation (decl)
       timevar_pop (TV_JUMP);
     }
 
+  /* Complete generation of exception handling code.  */
+  find_exception_handler_labels ();
+  if (doing_eh (0))
+    {
+      timevar_push (TV_JUMP);
+      open_dump_file (DFI_eh, decl);
+
+      finish_eh_generation ();
+
+      close_dump_file (DFI_eh, print_rtl, get_insns ());
+      timevar_pop (TV_JUMP);
+    }
+
 #ifdef FINALIZE_PIC
   /* If we are doing position-independent code generation, now
      is the time to output special prologues and epilogues.
@@ -2805,15 +2872,6 @@ 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.  */
@@ -2828,9 +2886,6 @@ rest_of_compilation (decl)
   /* Instantiate all virtual registers.  */
   instantiate_virtual_regs (current_function_decl, insns);
 
-  /* Find all the EH handlers.  */
-  find_exception_handler_labels ();
-
   open_dump_file (DFI_jump, decl);
 
   /* Always do one jump optimization pass to ensure that JUMP_LABEL fields
@@ -2860,7 +2915,7 @@ rest_of_compilation (decl)
   if (optimize > 0)
     {
       find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-      cleanup_cfg (insns);
+      cleanup_cfg ();
 
       /* ??? Run if-conversion before delete_null_pointer_checks,
          since the later does not preserve the CFG.  This should
@@ -2885,8 +2940,7 @@ rest_of_compilation (decl)
 
   close_dump_file (DFI_jump, print_rtl, insns);
 
-  if (ggc_p)
-    ggc_collect ();
+  ggc_collect ();
 
   /* Perform common subexpression elimination.
      Nonzero value from `cse_main' means that jumps were simplified
@@ -2909,9 +2963,9 @@ rest_of_compilation (decl)
 
       tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
 
-      /* If we are not running the second CSE pass, then we are no longer
-        expecting CSE to be run.  */
-      cse_not_expected = !flag_rerun_cse_after_loop;
+      /* If we are not running more CSE passes, then we are no longer
+        expecting CSE to be run.  But always rerun it in a cheap mode.  */
+      cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse;
 
       if (tem || optimize > 1)
        {
@@ -2931,7 +2985,7 @@ rest_of_compilation (decl)
          timevar_push (TV_JUMP);
          find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
 
-         cleanup_cfg (insns);
+         cleanup_cfg ();
 
          delete_null_pointer_checks (insns);
          timevar_pop (TV_JUMP);
@@ -2952,8 +3006,7 @@ rest_of_compilation (decl)
 
   close_dump_file (DFI_addressof, print_rtl, insns);
 
-  if (ggc_p)
-    ggc_collect ();
+  ggc_collect ();
 
   if (optimize > 0 && flag_ssa)
     {
@@ -2963,7 +3016,7 @@ rest_of_compilation (decl)
       open_dump_file (DFI_ssa, decl);
 
       find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-      cleanup_cfg (insns);
+      cleanup_cfg ();
       convert_to_ssa ();
 
       close_dump_file (DFI_ssa, print_rtl_with_bb, insns);
@@ -2983,7 +3036,7 @@ rest_of_compilation (decl)
 
          insns = get_insns ();
          eliminate_dead_code();
-  
+
          close_dump_file (DFI_dce, print_rtl_with_bb, insns);
          timevar_pop (TV_DEAD_CODE_ELIM);
        }
@@ -3004,37 +3057,64 @@ rest_of_compilation (decl)
       close_dump_file (DFI_ussa, print_rtl_with_bb, insns);
       timevar_pop (TV_FROM_SSA);
 
-      if (ggc_p)
-       ggc_collect ();
+      ggc_collect ();
     }
 
   /* Perform global cse.  */
 
   if (optimize > 0 && flag_gcse)
     {
+      int save_csb, save_cfj;
+      int tem2 = 0;
+
       timevar_push (TV_GCSE);
       open_dump_file (DFI_gcse, decl);
 
       find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-      cleanup_cfg (insns);
+      cleanup_cfg ();
       tem = gcse_main (insns, rtl_dump_file);
 
-      /* If gcse altered any jumps, rerun jump optimizations to clean
-        things up.  */
-      if (tem)
+      save_csb = flag_cse_skip_blocks;
+      save_cfj = flag_cse_follow_jumps;
+      flag_cse_skip_blocks = flag_cse_follow_jumps = 0;
+
+      /* If -fexpensive-optimizations, re-run CSE to clean up things done
+        by gcse.  */
+      if (flag_expensive_optimizations)
        {
+         timevar_push (TV_CSE);
+         reg_scan (insns, max_reg_num (), 1);
+         tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
+         timevar_pop (TV_CSE);
+         cse_not_expected = !flag_rerun_cse_after_loop;
+       }
+
+      /* If gcse or cse altered any jumps, rerun jump optimizations to clean
+        things up.  Then possibly re-run CSE again.  */
+      while (tem || tem2)
+       {
+         tem = tem2 = 0;
          timevar_push (TV_JUMP);
          jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
                         !JUMP_AFTER_REGSCAN);
          timevar_pop (TV_JUMP);
+
+         if (flag_expensive_optimizations)
+           {
+             timevar_push (TV_CSE);
+             reg_scan (insns, max_reg_num (), 1);
+             tem2 = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
+             timevar_pop (TV_CSE);
+           }
        }
 
       close_dump_file (DFI_gcse, print_rtl, insns);
       timevar_pop (TV_GCSE);
 
-      if (ggc_p)
-       ggc_collect ();
-    }
+      ggc_collect ();
+      flag_cse_skip_blocks = save_csb;
+      flag_cse_follow_jumps = save_cfj;
+     }
 
   /* Move constant computations out of loops.  */
 
@@ -3065,8 +3145,7 @@ rest_of_compilation (decl)
       close_dump_file (DFI_loop, print_rtl, insns);
       timevar_pop (TV_LOOP);
 
-      if (ggc_p)
-       ggc_collect ();
+      ggc_collect ();
     }
 
   if (optimize > 0)
@@ -3083,6 +3162,12 @@ rest_of_compilation (decl)
             ??? Rework to not call reg_scan so often.  */
          timevar_push (TV_JUMP);
 
+         /* The previous call to loop_optimize makes some instructions
+            trivially dead.  We delete those instructions now in the
+            hope that doing so will make the heuristics in jump work
+            better and possibly speed up compilation.  */
+         delete_trivially_dead_insns (insns, max_reg_num ());
+
          reg_scan (insns, max_reg_num (), 0);
          jump_optimize (insns, !JUMP_CROSS_JUMP,
                         !JUMP_NOOP_MOVES, JUMP_AFTER_REGSCAN);
@@ -3090,7 +3175,7 @@ rest_of_compilation (decl)
          timevar_push (TV_IFCVT);
 
          find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-         cleanup_cfg (insns);
+         cleanup_cfg ();
          if_convert (0);
 
          timevar_pop(TV_IFCVT);
@@ -3122,8 +3207,7 @@ rest_of_compilation (decl)
       close_dump_file (DFI_cse2, print_rtl, insns);
       timevar_pop (TV_CSE2);
 
-      if (ggc_p)
-       ggc_collect ();
+      ggc_collect ();
     }
 
   cse_not_expected = 1;
@@ -3137,7 +3221,8 @@ rest_of_compilation (decl)
   open_dump_file (DFI_cfg, decl);
 
   find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-  cleanup_cfg (insns);
+  cleanup_cfg ();
+  check_function_return_warnings ();
 
   close_dump_file (DFI_cfg, print_rtl_with_bb, insns);
 
@@ -3159,13 +3244,14 @@ rest_of_compilation (decl)
 
       /* Discover and record the loop depth at the head of each basic
         block.  The loop infrastructure does the real job for us.  */
-      flow_loops_find (&loops);
+      flow_loops_find (&loops, LOOP_TREE);
 
       /* Estimate using heuristics if no profiling info is available.  */
-      estimate_probability (&loops);
+      if (flag_guess_branch_prob)
+       estimate_probability (&loops);
 
       if (rtl_dump_file)
-       flow_loops_dump (&loops, rtl_dump_file, 0);
+       flow_loops_dump (&loops, rtl_dump_file, NULL, 0);
 
       flow_loops_free (&loops);
     }
@@ -3185,8 +3271,7 @@ rest_of_compilation (decl)
 
   close_dump_file (DFI_life, print_rtl_with_bb, insns);
 
-  if (ggc_p)
-    ggc_collect ();
+  ggc_collect ();
 
   /* If -opt, try combining insns through substitution.  */
 
@@ -3211,7 +3296,7 @@ rest_of_compilation (decl)
 
          timevar_push (TV_FLOW);
          find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-         cleanup_cfg (insns);
+         cleanup_cfg ();
 
          /* Blimey.  We've got to have the CFG up to date for the call to
             if_convert below.  However, the random deletion of blocks
@@ -3228,8 +3313,7 @@ rest_of_compilation (decl)
       close_dump_file (DFI_combine, print_rtl_with_bb, insns);
       timevar_pop (TV_COMBINE);
 
-      if (ggc_p)
-       ggc_collect ();
+      ggc_collect ();
     }
 
   /* Rerun if-conversion, as combine may have simplified things enough to
@@ -3259,8 +3343,7 @@ rest_of_compilation (decl)
       close_dump_file (DFI_regmove, print_rtl_with_bb, insns);
       timevar_pop (TV_REGMOVE);
 
-      if (ggc_p)
-       ggc_collect ();
+      ggc_collect ();
     }
 
   /* Any of the several passes since flow1 will have munged register
@@ -3269,20 +3352,17 @@ rest_of_compilation (decl)
     register_life_up_to_date = 0;
 
 #ifdef OPTIMIZE_MODE_SWITCHING
-  if (optimize)
-    {
-      timevar_push (TV_GCSE);
+  timevar_push (TV_GCSE);
 
-      if (optimize_mode_switching (NULL_PTR))
-       {
-         /* We did work, and so had to regenerate global life information.
-            Take advantage of this and don't re-recompute register life
-            information below.  */
-         register_life_up_to_date = 1;
-       }
-
-      timevar_pop (TV_GCSE);
+  if (optimize_mode_switching (NULL))
+    {
+      /* We did work, and so had to regenerate global life information.
+        Take advantage of this and don't re-recompute register life
+        information below.  */
+      register_life_up_to_date = 1;
     }
+
+  timevar_pop (TV_GCSE);
 #endif
 
 #ifdef INSN_SCHEDULING
@@ -3302,8 +3382,7 @@ rest_of_compilation (decl)
       close_dump_file (DFI_sched, print_rtl_with_bb, insns);
       timevar_pop (TV_SCHED);
 
-      if (ggc_p)
-       ggc_collect ();
+      ggc_collect ();
 
       /* Register lifetime information was updated as part of verifying
         the schedule.  */
@@ -3342,8 +3421,7 @@ rest_of_compilation (decl)
       timevar_pop (TV_DUMP);
     }
 
-  if (ggc_p)
-    ggc_collect ();
+  ggc_collect ();
 
   timevar_push (TV_GLOBAL_ALLOC);
   open_dump_file (DFI_greg, decl);
@@ -3361,11 +3439,22 @@ rest_of_compilation (decl)
 
   timevar_pop (TV_GLOBAL_ALLOC);
 
+  if (dump_file[DFI_greg].enabled)
+    {
+      timevar_push (TV_DUMP);
+
+      dump_global_regs (rtl_dump_file);
+
+      close_dump_file (DFI_greg, print_rtl_with_bb, insns);
+      timevar_pop (TV_DUMP);
+    }
+
   if (failure)
     goto exit_rest_of_compilation;
 
-  if (ggc_p)
-    ggc_collect ();
+  ggc_collect ();
+
+  open_dump_file (DFI_postreload, decl);
 
   /* Do a very simple CSE pass over just the hard registers.  */
   if (optimize > 0)
@@ -3376,8 +3465,14 @@ rest_of_compilation (decl)
     }
 
   /* If optimizing, then go ahead and split insns now since we are about
-     to recompute flow information anyway.  */
+     to recompute flow information anyway.  Since we can't split insns after
+     reload, do the splitting unconditionally here to avoid gcc from losing
+     REG_DEAD notes.  */
+#ifdef STACK_REGS
+  if (1)
+#else
   if (optimize > 0)
+#endif
     {
       int old_labelnum = max_label_num ();
 
@@ -3397,22 +3492,14 @@ rest_of_compilation (decl)
       timevar_pop (TV_JUMP);
     }
 
-  if (dump_file[DFI_greg].enabled)
-    {
-      timevar_push (TV_DUMP);
-
-      dump_global_regs (rtl_dump_file);
-
-      close_dump_file (DFI_greg, print_rtl_with_bb, insns);
-      timevar_pop (TV_DUMP);
-    }
+  close_dump_file (DFI_postreload, print_rtl_with_bb, insns);
 
   /* Re-create the death notes which were deleted during reload.  */
   timevar_push (TV_FLOW2);
   open_dump_file (DFI_flow2, decl);
 
   jump_optimize (insns, !JUMP_CROSS_JUMP,
-                !JUMP_NOOP_MOVES, !JUMP_AFTER_REGSCAN);
+                JUMP_NOOP_MOVES, !JUMP_AFTER_REGSCAN);
   find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
 
   /* On some machines, the prologue and epilogue code, or parts thereof,
@@ -3423,7 +3510,7 @@ rest_of_compilation (decl)
 
   if (optimize)
     {
-      cleanup_cfg (insns);
+      cleanup_cfg ();
       life_analysis (insns, rtl_dump_file, PROP_FINAL);
 
       /* This is kind of a heuristic.  We need to run combine_stack_adjustments
@@ -3435,8 +3522,7 @@ rest_of_compilation (decl)
 #endif
        combine_stack_adjustments ();
 
-      if (ggc_p)
-       ggc_collect ();
+      ggc_collect ();
     }
 
   flow2_completed = 1;
@@ -3444,17 +3530,6 @@ rest_of_compilation (decl)
   close_dump_file (DFI_flow2, print_rtl_with_bb, insns);
   timevar_pop (TV_FLOW2);
 
-  if (optimize > 0)
-    {
-      timevar_push (TV_IFCVT2);
-      open_dump_file (DFI_ce2, decl);
-
-      if_convert (1);
-
-      close_dump_file (DFI_ce2, print_rtl_with_bb, insns);
-      timevar_pop (TV_IFCVT2);
-    }
-
 #ifdef HAVE_peephole2
   if (optimize > 0 && flag_peephole2)
     {
@@ -3479,6 +3554,17 @@ rest_of_compilation (decl)
       timevar_pop (TV_RENAME_REGISTERS);
     }
 
+  if (optimize > 0)
+    {
+      timevar_push (TV_IFCVT2);
+      open_dump_file (DFI_ce2, decl);
+
+      if_convert (1);
+
+      close_dump_file (DFI_ce2, print_rtl_with_bb, insns);
+      timevar_pop (TV_IFCVT2);
+    }
+
 #ifdef INSN_SCHEDULING
   if (optimize > 0 && flag_schedule_insns_after_reload)
     {
@@ -3493,8 +3579,7 @@ rest_of_compilation (decl)
       close_dump_file (DFI_sched2, print_rtl_with_bb, insns);
       timevar_pop (TV_SCHED2);
 
-      if (ggc_p)
-       ggc_collect ();
+      ggc_collect ();
     }
 #endif
 
@@ -3527,7 +3612,7 @@ rest_of_compilation (decl)
 
       /* CFG no longer kept up to date.  */
 
-      close_dump_file (DFI_jump2, print_rtl_with_bb, insns);
+      close_dump_file (DFI_jump2, print_rtl, insns);
       timevar_pop (TV_JUMP);
     }
 
@@ -3537,10 +3622,9 @@ rest_of_compilation (decl)
 
   MACHINE_DEPENDENT_REORG (insns);
 
-  close_dump_file (DFI_mach, print_rtl_with_bb, insns);
+  close_dump_file (DFI_mach, print_rtl, insns);
 
-  if (ggc_p)
-    ggc_collect ();
+  ggc_collect ();
 #endif
 
   /* If a scheduling pass for delayed branches is to be done,
@@ -3554,14 +3638,19 @@ rest_of_compilation (decl)
 
       dbr_schedule (insns, rtl_dump_file);
 
-      close_dump_file (DFI_dbr, print_rtl_with_bb, insns);
+      close_dump_file (DFI_dbr, print_rtl, insns);
       timevar_pop (TV_DBR_SCHED);
 
-      if (ggc_p)
-       ggc_collect ();
+      ggc_collect ();
     }
 #endif
 
+#ifndef STACK_REGS
+  /* ??? Do this before shorten branches so that we aren't creating
+     insns too late and fail sanity checks in final. */
+  convert_to_eh_region_ranges ();
+#endif
+
   /* Shorten branches.
 
      Note this must run before reg-stack because of death note (ab)use
@@ -3576,11 +3665,12 @@ rest_of_compilation (decl)
 
   reg_to_stack (insns, rtl_dump_file);
 
-  close_dump_file (DFI_stack, print_rtl_with_bb, insns);
+  close_dump_file (DFI_stack, print_rtl, insns);
   timevar_pop (TV_REG_STACK);
 
-  if (ggc_p)
-    ggc_collect ();
+  ggc_collect ();
+
+  convert_to_eh_region_ranges ();
 #endif
 
   current_function_nothrow = nothrow_function_p ();
@@ -3611,7 +3701,20 @@ rest_of_compilation (decl)
     final_start_function (insns, asm_out_file, optimize);
     final (insns, asm_out_file, optimize, 0);
     final_end_function (insns, asm_out_file, optimize);
+
+#ifdef IA64_UNWIND_INFO
+    /* ??? The IA-64 ".handlerdata" directive must be issued before
+       the ".endp" directive that closes the procedure descriptor.  */
+    output_function_exception_table ();
+#endif
+
     assemble_end_function (decl, fnname);
+
+#ifndef IA64_UNWIND_INFO
+    /* Otherwise, it feels unclean to switch sections in the middle.  */
+    output_function_exception_table ();
+#endif
+
     if (! quiet_flag)
       fflush (asm_out_file);
 
@@ -3623,8 +3726,7 @@ rest_of_compilation (decl)
   }
   timevar_pop (TV_FINAL);
 
-  if (ggc_p)
-    ggc_collect ();
+  ggc_collect ();
 
   /* Write DBX symbols if requested.  */
 
@@ -3677,9 +3779,6 @@ rest_of_compilation (decl)
      it runs through become garbage.  */
   clear_const_double_mem ();
 
-  /* Cancel the effect of rtl_in_current_obstack.  */
-  resume_temporary_allocation ();
-
   /* Show no temporary slots allocated.  */
   init_temp_slots ();
 
@@ -3704,8 +3803,7 @@ rest_of_compilation (decl)
     free_after_compilation (cfun);
   cfun = 0;
 
-  if (ggc_p)
-    ggc_collect ();
+  ggc_collect ();
 
   timevar_pop (TV_REST_OF_COMPILATION);
 }
@@ -3717,16 +3815,12 @@ display_help ()
   unsigned long i;
   const char *lang;
 
-#ifndef USE_CPPLIB
-  printf (_("Usage: %s input [switches]\n"), progname);
-  printf (_("Switches:\n"));
-#endif
   printf (_("  -ffixed-<register>      Mark <register> as being unavailable to the compiler\n"));
   printf (_("  -fcall-used-<register>  Mark <register> as being corrupted by function calls\n"));
   printf (_("  -fcall-saved-<register> Mark <register> as being preserved across functions\n"));
   printf (_("  -finline-limit=<number> Limits the size of inlined functions to <number>\n"));
   printf (_("  -fmessage-length=<number> Limits diagnostics messages lengths to <number> characters per line.  0 suppresses line-wrapping\n"));
-  printf (_("  -fdiagnostics-show-location=[once | never] Indicates how often source location information should be emitted, as prefix, at the beginning of diagnostics when line-wrapping\n"));
+  printf (_("  -fdiagnostics-show-location=[once | every-line] Indicates how often source location information should be emitted, as prefix, at the beginning of diagnostics when line-wrapping\n"));
 
   for (i = ARRAY_SIZE (f_options); i--;)
     {
@@ -3739,6 +3833,17 @@ display_help ()
 
   printf (_("  -O[number]              Set optimisation level to [number]\n"));
   printf (_("  -Os                     Optimise for space rather than speed\n"));
+  for (i = sizeof (compiler_params); i--;)
+    {
+      const char *description = compiler_params[i].help;
+      const int length = 21-strlen(compiler_params[i].option);
+
+      if (description != NULL && * description != 0)
+       printf ("  --param %s=<value>%.*s%s\n",
+               compiler_params[i].option,
+               length > 0 ? length : 1, "                     ",
+               description);
+    }
   printf (_("  -pedantic               Issue warnings needed by strict compliance to ISO C\n"));
   printf (_("  -pedantic-errors        Like -pedantic except that errors are produced\n"));
   printf (_("  -w                      Suppress warnings\n"));
@@ -3835,6 +3940,14 @@ display_help ()
     printf (_("\nThere are undocumented %s specific options as well.\n"),
            lang);
 
+  display_target_options ();
+}
+
+static void
+display_target_options ()
+{
+  int undoc,i;
+
   if (ARRAY_SIZE (target_switches) > 1
 #ifdef TARGET_OPTIONS
       || ARRAY_SIZE (target_options) > 1
@@ -3859,10 +3972,10 @@ display_help ()
              undoc = 1;
 
              if (extra_warnings)
-               printf (_("  -m%-21.21s [undocumented]\n"), option);
+               printf (_("  -m%-23.23s [undocumented]\n"), option);
            }
          else if (* description != 0)
-           doc += printf ("  -m%-21.21s %s\n", option, description);
+           doc += printf ("  -m%-23.23s %s\n", option, description);
        }
 
 #ifdef TARGET_OPTIONS
@@ -3878,10 +3991,10 @@ display_help ()
              undoc = 1;
 
              if (extra_warnings)
-               printf (_("  -m%-21.21s [undocumented]\n"), option);
+               printf (_("  -m%-23.23s [undocumented]\n"), option);
            }
          else if (* description != 0)
-           doc += printf ("  -m%-21.21s %s\n", option, description);
+           doc += printf ("  -m%-23.23s %s\n", option, description);
        }
 #endif
       if (undoc)
@@ -3906,18 +4019,19 @@ decode_d_option (arg)
     switch (c = *arg++)
       {
       case 'a':
-       for (i = 0; i < DFI_MAX; ++i)
+       for (i = 0; i < (int) DFI_MAX; ++i)
          dump_file[i].enabled = 1;
        break;
       case 'A':
        flag_debug_asm = 1;
        break;
-      case 'm':
-       flag_print_mem = 1;
-       break;
       case 'p':
        flag_print_asm_name = 1;
        break;
+      case 'P':
+        flag_dump_rtl_in_asm = 1;
+        flag_print_asm_name = 1;
+        break;
       case 'v':
        graph_dump_format = vcg;
        break;
@@ -3933,7 +4047,7 @@ decode_d_option (arg)
 
       default:
        matched = 0;
-       for (i = 0; i < DFI_MAX; ++i)
+       for (i = 0; i < (int) DFI_MAX; ++i)
          if (c == dump_file[i].debug_switch)
            {
              dump_file[i].enabled = 1;
@@ -3974,10 +4088,18 @@ decode_f_option (arg)
        }
     }
 
-  if ((option_value = skip_leading_substring (arg, "inline-limit-"))
-      || (option_value = skip_leading_substring (arg, "inline-limit=")))
-    inline_max_insns =
-      read_integral_parameter (option_value, arg - 2, inline_max_insns);
+  if (!strcmp (arg, "fast-math"))
+    set_fast_math_flags();
+  else if (!strcmp (arg, "no-fast-math"))
+    set_no_fast_math_flags();
+  else if ((option_value = skip_leading_substring (arg, "inline-limit-"))
+          || (option_value = skip_leading_substring (arg, "inline-limit=")))
+    {
+      int val =
+       read_integral_parameter (option_value, arg - 2,
+                                MAX_INLINE_INSNS);
+      set_param_value ("max-inline-insns", val);
+    }
 #ifdef INSN_SCHEDULING
   else if ((option_value = skip_leading_substring (arg, "sched-verbose=")))
     fix_sched_param ("verbose", option_value);
@@ -4010,11 +4132,8 @@ decode_f_option (arg)
   else if ((option_value
            = skip_leading_substring (arg, "stack-limit-symbol=")))
     {
-      char *nm;
-      if (ggc_p)
-       nm = ggc_alloc_string (option_value, strlen (option_value));
-      else
-       nm = xstrdup (option_value);
+      const char *nm;
+      nm = ggc_strdup (option_value);
       stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, nm);
     }
   else if ((option_value
@@ -4084,8 +4203,7 @@ decode_W_option (arg)
     {
       larger_than_size = read_integral_parameter (option_value, arg - 2, -1);
 
-      if (larger_than_size != -1)
-       warn_larger_than = 1;
+      warn_larger_than = larger_than_size != -1;
     }
   else if (!strcmp (arg, "unused"))
     {
@@ -4222,7 +4340,7 @@ ignoring option `%s' due to invalid debug level specification",
     }
 
   if (! da->arg)
-    warning ("`%s': unknown or unsupported -g option", arg - 2);
+    return 0;
 
   return 1;
 }
@@ -4252,7 +4370,53 @@ independent_decode_option (argc, argv)
   if (!strcmp (arg, "-help"))
     {
       display_help ();
-      exit (0);
+      exit_after_options = 1;
+    }
+
+  if (!strcmp (arg, "-target-help"))
+    {
+      display_target_options ();
+      exit_after_options = 1;
+    }
+
+  if (!strcmp (arg, "-version"))
+    {
+      print_version (stderr, "");
+      exit_after_options = 1;
+    }
+
+  /* Handle '--param <name>=<value>'.  */
+  if (strcmp (arg, "-param") == 0)
+    {
+      char *equal;
+
+      if (argc == 1)
+       {
+         error ("-param option missing argument");
+         return 1;
+       }
+
+      /* Get the '<name>=<value>' parameter.  */
+      arg = argv[1];
+      /* Look for the `='.  */
+      equal = strchr (arg, '=');
+      if (!equal)
+       error ("invalid --param option: %s", arg);
+      else
+       {
+         int val;
+
+         /* Zero out the `=' sign so that we get two separate strings.  */
+         *equal = '\0';
+         /* Figure out what value is specified.  */
+         val = read_integral_parameter (equal + 1, NULL, INVALID_PARAM_VAL);
+         if (val != INVALID_PARAM_VAL)
+           set_param_value (arg, val);
+         else
+           error ("invalid parameter value `%s'", equal + 1);
+       }
+
+      return 2;
     }
 
   if (*arg == 'Y')
@@ -4417,14 +4581,15 @@ independent_decode_option (argc, argv)
   return 1;
 }
 \f
-/* Entry point of cc1/c++.  Decode command args, then call compile_file.
-   Exit code is 35 if can't open files, 34 if fatal error,
-   33 if had nonfatal errors, else success.  */
+/* Entry point of cc1, cc1plus, jc1, f771, etc.
+   Decode command args, then call compile_file.
+   Exit code is FATAL_EXIT_CODE if can't open files or if there were
+   any errors, or SUCCESS_EXIT_CODE if compilation succeeded.
 
-extern int main PARAMS ((int, char **));
+   It is not safe to call this function more than once.  */
 
 int
-main (argc, argv)
+toplev_main (argc, argv)
      int argc;
      char **argv;
 {
@@ -4440,9 +4605,18 @@ main (argc, argv)
     --p;
   progname = p;
 
+  xmalloc_set_program_name (progname);
+
+/* LC_CTYPE determines the character set used by the terminal so it has be set
+   to output messages correctly.  */
+
 #ifdef HAVE_LC_MESSAGES
+  setlocale (LC_CTYPE, "");
   setlocale (LC_MESSAGES, "");
+#else
+  setlocale (LC_ALL, "");
 #endif
+
   (void) bindtextdomain (PACKAGE, localedir);
   (void) textdomain (PACKAGE);
 
@@ -4479,8 +4653,7 @@ main (argc, argv)
 
   /* Initialize the garbage-collector.  */
   init_ggc ();
-  ggc_add_root (&input_file_stack, 1, sizeof input_file_stack,
-               mark_file_stack);
+  init_stringpool ();
   ggc_add_rtx_root (&stack_limit_rtx, 1);
   ggc_add_tree_root (&current_function_decl, 1);
   ggc_add_tree_root (&current_function_func_begin_label, 1);
@@ -4488,8 +4661,12 @@ main (argc, argv)
   /* Initialize the diagnostics reporting machinery.  */
   initialize_diagnostics ();
 
+  /* Register the language-independent parameters.  */
+  add_params (lang_independent_params, LAST_PARAM);
+
   /* Perform language-specific options intialization.  */
-  lang_init_options ();
+  if (lang_hooks.init_options)
+    (*lang_hooks.init_options) ();
 
   /* Scan to see what optimization level has been specified.  That will
      determine the default value of many flags.  */
@@ -4534,6 +4711,7 @@ main (argc, argv)
 #ifdef CAN_DEBUG_WITHOUT_FP
       flag_omit_frame_pointer = 1;
 #endif
+      flag_guess_branch_prob = 1;
     }
 
   if (optimize >= 2)
@@ -4562,6 +4740,7 @@ main (argc, argv)
   if (optimize >= 3)
     {
       flag_inline_functions = 1;
+      flag_rename_registers = 1;
     }
 
   if (optimize < 2 || optimize_size)
@@ -4594,20 +4773,25 @@ main (argc, argv)
   /* Perform normal command line switch decoding.  */
   for (i = 1; i < argc;)
     {
-      unsigned int lang_processed;
-      unsigned int indep_processed;
+      int lang_processed;
+      int indep_processed;
 
       /* Give the language a chance to decode the option for itself.  */
-      lang_processed = lang_decode_option (argc - i, argv + i);
+      lang_processed = (*lang_hooks.decode_option) (argc - i, argv + i);
 
-      /* Now see if the option also has a language independent meaning.
-        Some options are both language specific and language independent,
-        eg --help.  */
-      indep_processed = independent_decode_option (argc - i, argv + i);
+      if (lang_processed >= 0)
+       /* Now see if the option also has a language independent meaning.
+          Some options are both language specific and language independent,
+          eg --help.  */
+       indep_processed = independent_decode_option (argc - i, argv + i);
+      else
+       {
+         lang_processed = -lang_processed;
+         indep_processed = 0;
+       }
 
       if (lang_processed || indep_processed)
-       i += (lang_processed > indep_processed
-             ? lang_processed : indep_processed);
+       i += MAX (lang_processed, indep_processed);
       else
        {
          const char *option = NULL;
@@ -4637,10 +4821,13 @@ main (argc, argv)
                {
                  warning ("Ignoring command line option '%s'", argv[i]);
                  if (lang)
-                   warning ("\
-(It is valid for %s but not the selected language)", lang);
+                   warning
+                     ("(It is valid for %s but not the selected language)",
+                      lang);
                }
            }
+         else if (argv[i][0] == '-' && argv[i][1] == 'g')
+           warning ("`%s': unknown or unsupported -g option", &argv[i][2]);
          else
            error ("Unrecognized option `%s'", argv[i]);
 
@@ -4648,6 +4835,13 @@ main (argc, argv)
        }
     }
 
+  /* All command line options have been processed.  */
+  if (lang_hooks.post_options)
+    (*lang_hooks.post_options) ();
+
+  if (exit_after_options)
+    exit (0);
+
   /* Reflect any language-specific diagnostic option setting.  */
   reshape_diagnostic_buffer ();
 
@@ -4662,7 +4856,7 @@ main (argc, argv)
       flag_no_inline = 1;
       warn_inline = 0;
 
-      /* The c_decode_option and lang_decode_option functions set
+      /* The c_decode_option function and decode_option hook set
         this to `2' if -Wall is used, so we can avoid giving out
         lots of errors for people who don't realize what -Wall does.  */
       if (warn_uninitialized == 1)
@@ -4674,27 +4868,6 @@ main (argc, argv)
   OVERRIDE_OPTIONS;
 #endif
 
-  if (exceptions_via_longjmp == 2)
-    {
-#ifdef DWARF2_UNWIND_INFO
-      exceptions_via_longjmp = ! DWARF2_UNWIND_INFO;
-#else
-#ifdef IA64_UNWIND_INFO
-      exceptions_via_longjmp = ! IA64_UNWIND_INFO;
-#else
-      exceptions_via_longjmp = 1;
-#endif
-#endif
-    }
-
-  /* Since each function gets its own handler data, we can't support the
-     new model currently, since it depend on a specific rethrow label
-     which is declared at the front of the table, and we can only
-     have one such symbol in a file.  */
-#ifdef IA64_UNWIND_INFO
-  flag_new_exceptions = 0;
-#endif
-
   /* Set up the align_*_log variables, defaulting them to 1 if they
      were still unset.  */
   if (align_loops <= 0) align_loops = 1;
@@ -4736,6 +4909,16 @@ main (argc, argv)
     warning ("this target machine does not have delayed branches");
 #endif
 
+  /* Some operating systems do not allow profiling without a frame
+     pointer.  */
+  if (!TARGET_ALLOWS_PROFILING_WITHOUT_FRAME_POINTER
+      && profile_flag
+      && flag_omit_frame_pointer)
+    {
+      error ("profiling does not work without a frame pointer");
+      flag_omit_frame_pointer = 0;
+    }
+    
   user_label_prefix = USER_LABEL_PREFIX;
   if (flag_leading_underscore != -1)
     {
@@ -4762,24 +4945,6 @@ main (argc, argv)
 
   compile_file (filename);
 
-#if !defined(OS2) && !defined(VMS) && (!defined(_WIN32) || defined (__CYGWIN__)) && !defined(__INTERIX)
-  if (flag_print_mem)
-    {
-      char *lim = (char *) sbrk (0);
-
-      fnotice (stderr, "Data size %ld.\n", (long) (lim - (char *) &environ));
-      fflush (stderr);
-
-#ifndef __MSDOS__
-#ifdef USG
-      system ("ps -l 1>&2");
-#else /* not USG  */
-      system ("ps v");
-#endif /* not USG  */
-#endif
-    }
-#endif /* ! OS2 && ! VMS && (! _WIN32 || CYGWIN) && ! __INTERIX  */
-
   if (errorcount)
     return (FATAL_EXIT_CODE);
   if (sorrycount)
@@ -4838,12 +5003,13 @@ print_version (file, indent)
 #endif
   fnotice (file,
 #ifdef __GNUC__
-          "%s%s%s version %s (%s) compiled by GNU C version %s.\n"
+          "%s%s%s version %s (%s)\n%s\tcompiled by GNU C version %s.\n"
 #else
           "%s%s%s version %s (%s) compiled by CC.\n"
 #endif
           , indent, *indent != 0 ? " " : "",
-          language_string, version_string, TARGET_NAME, __VERSION__);
+          language_string, version_string, TARGET_NAME,
+          indent, __VERSION__);
 }
 
 /* Print an option value and return the adjusted position in the line.
@@ -4971,8 +5137,7 @@ debug_start_source_file (filename)
     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)
+  if (write_symbols == DWARF2_DEBUG)
     dwarf2out_start_source_file (filename);
 #endif /* DWARF2_DEBUGGING_INFO  */
 #ifdef SDB_DEBUGGING_INFO
@@ -4998,8 +5163,7 @@ debug_end_source_file (lineno)
     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)
+  if (write_symbols == DWARF2_DEBUG)
     dwarf2out_end_source_file ();
 #endif /* DWARF2_DEBUGGING_INFO  */
 #ifdef SDB_DEBUGGING_INFO
@@ -5008,44 +5172,40 @@ debug_end_source_file (lineno)
 #endif
 }
 
-/* Called from check_newline in c-parse.y.  The `buffer' parameter contains
+/* Called from cb_define in c-lex.c.  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 ATTRIBUTE_UNUSED;
-     register char *buffer ATTRIBUTE_UNUSED;
+     register const char *buffer ATTRIBUTE_UNUSED;
 {
 #ifdef DWARF_DEBUGGING_INFO
-  if (debug_info_level == DINFO_LEVEL_VERBOSE
-      && write_symbols == DWARF_DEBUG)
+  if (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)
+  if (write_symbols == DWARF2_DEBUG)
     dwarf2out_define (lineno, buffer);
 #endif /* DWARF2_DEBUGGING_INFO  */
 }
 
-/* Called from check_newline in c-parse.y.  The `buffer' parameter contains
+/* Called from cb_undef in c-lex.c.  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 ATTRIBUTE_UNUSED;
-     register char *buffer ATTRIBUTE_UNUSED;
+     register const char *buffer ATTRIBUTE_UNUSED;
 {
 #ifdef DWARF_DEBUGGING_INFO
-  if (debug_info_level == DINFO_LEVEL_VERBOSE
-      && write_symbols == DWARF_DEBUG)
+  if (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)
+  if (write_symbols == DWARF2_DEBUG)
     dwarf2out_undef (lineno, buffer);
 #endif /* DWARF2_DEBUGGING_INFO  */
 }