OSDN Git Service

* a29k/unix.h (ASM_FILE_START): Const-ify.
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index b80e26b..a3bdba6 100644 (file)
@@ -2,22 +2,22 @@
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001 Free Software Foundation, Inc.
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
 
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
 
 /* This is the top level of cc1/c++.
    It parses command args, opens files, invokes the various passes
@@ -64,10 +64,11 @@ Boston, MA 02111-1307, USA.  */
 #include "ssa.h"
 #include "params.h"
 #include "reload.h"
-
-#ifdef DWARF_DEBUGGING_INFO
-#include "dwarfout.h"
-#endif
+#include "dwarf2asm.h"
+#include "integrate.h"
+#include "debug.h"
+#include "target.h"
+#include "langhooks.h"
 
 #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
 #include "dwarf2out.h"
@@ -82,7 +83,12 @@ Boston, MA 02111-1307, USA.  */
 #endif
 
 #ifdef XCOFF_DEBUGGING_INFO
-#include "xcoffout.h"
+#include "xcoffout.h"          /* Needed for external data
+                                  declarations for e.g. AIX 4.x.  */
+#endif
+
+#ifdef HALF_PIC_DEBUG
+#include "halfpic.h"
 #endif
 \f
 #ifdef VMS
@@ -155,12 +161,21 @@ extern char **environ;
 extern int size_directive_output;
 extern tree last_assemble_variable_decl;
 
+static void general_init PARAMS ((char *));
+static void parse_options_and_default_flags PARAMS ((int, char **));
+static void process_options PARAMS ((void));
+static void lang_independent_init PARAMS ((void));
+static int lang_dependent_init PARAMS ((const char *));
+static void init_asm_output PARAMS ((const char *));
+static void finalize PARAMS ((void));
+
 static void set_target_switch PARAMS ((const char *));
 static const char *decl_name PARAMS ((tree, int));
 
 static void float_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
 static void crash_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
-static void compile_file PARAMS ((const char *));
+static void set_float_handler PARAMS ((jmp_buf));
+static void compile_file PARAMS ((void));
 static void display_help PARAMS ((void));
 static void display_target_options PARAMS ((void));
 
@@ -223,6 +238,10 @@ const char *dump_base_name;
 
 extern int target_flags;
 
+/* Debug hooks - dependent upon command line options.  */
+
+struct gcc_debug_hooks *debug_hooks = &do_nothing_debug_hooks;
+
 /* Describes a dump file.  */
 
 struct dump_file_info
@@ -251,11 +270,12 @@ enum dump_file_index
   DFI_sibling,
   DFI_eh,
   DFI_jump,
-  DFI_cse,
-  DFI_addressof,
   DFI_ssa,
-  DFI_dce,
+  DFI_ssa_ccp,
+  DFI_ssa_dce,
   DFI_ussa,
+  DFI_cse,
+  DFI_addressof,
   DFI_gcse,
   DFI_loop,
   DFI_cse2,
@@ -274,11 +294,10 @@ enum dump_file_index
   DFI_rnreg,
   DFI_ce2,
   DFI_sched2,
+  DFI_stack,
   DFI_bbro,
-  DFI_jump2,
   DFI_mach,
   DFI_dbr,
-  DFI_stack,
   DFI_MAX
 };
 
@@ -288,7 +307,7 @@ enum dump_file_index
    Remaining -d letters:
 
        "              o q   u     "
-       "       H  K   OPQ  TUVW YZ"
+       "       H JK   OPQ  TUV  YZ"
 */
 
 struct dump_file_info dump_file[DFI_MAX] =
@@ -297,11 +316,12 @@ struct dump_file_info dump_file[DFI_MAX] =
   { "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 },
   { "ssa",     'e', 1, 0, 0 },
-  { "dce",     'X', 1, 0, 0 },
+  { "ssaccp",  'W', 1, 0, 0 },
+  { "ssadce",  'X', 1, 0, 0 },
   { "ussa",    'e', 1, 0, 0 }, /* Yes, duplicate enable switch.  */
+  { "cse",     's', 0, 0, 0 },
+  { "addressof", 'F', 0, 0, 0 },
   { "gcse",    'G', 1, 0, 0 },
   { "loop",    'L', 1, 0, 0 },
   { "cse2",    't', 1, 0, 0 },
@@ -320,11 +340,10 @@ struct dump_file_info dump_file[DFI_MAX] =
   { "rnreg",   'n', 1, 0, 0 },
   { "ce2",     'E', 1, 0, 0 },
   { "sched2",  'R', 1, 0, 0 },
+  { "stack",   'k', 1, 0, 0 },
   { "bbro",    'B', 1, 0, 0 },
-  { "jump2",   'J', 1, 0, 0 },
   { "mach",    'M', 1, 0, 0 },
   { "dbr",     'd', 0, 0, 0 },
-  { "stack",   'k', 1, 0, 0 },
 };
 
 static int open_dump_file PARAMS ((enum dump_file_index, tree));
@@ -378,12 +397,6 @@ int optimize = 0;
 
 int optimize_size = 0;
 
-/* Number of error messages and warning messages so far.  */
-
-int errorcount = 0;
-int warningcount = 0;
-int sorrycount = 0;
-
 /* Nonzero if we should exit after parsing options.  */
 static int exit_after_options = 0;
 
@@ -737,6 +750,10 @@ int flag_exceptions;
 
 int flag_unwind_tables = 0;
 
+/* Nonzero means generate frame unwind info table exact at each insn boundary */
+
+int flag_asynchronous_unwind_tables = 0;
+
 /* Nonzero means don't place uninitialized global data in common storage
    by default.  */
 
@@ -822,8 +839,11 @@ int flag_gnu_linker = 1;
 /* Enable SSA.  */
 int flag_ssa = 0;
 
-/* Enable dead code elimination. */
-int flag_dce = 0;
+/* Enable ssa conditional constant propagation.  */
+int flag_ssa_ccp = 0;
+
+/* Enable ssa aggressive dead code elimination.  */
+int flag_ssa_dce = 0;
 
 /* Tag all structures with __attribute__(packed).  */
 int flag_pack_struct = 0;
@@ -895,6 +915,11 @@ int flag_bounded_pointers = 0;
    For CHILL: defaults to off.  */
 int flag_bounds_check = 0;
 
+/* This will attempt to merge constant section constants, if 1 only
+   string constants and constants from constant pool, if 2 also constant
+   variables.  */
+int flag_merge_constants = 1;
+
 /* If one, renumber instruction UIDs to reduce the number of
    unused UIDs if there are a lot of instructions.  If greater than
    one, unconditionally renumber instruction UIDs.  */
@@ -907,46 +932,49 @@ int flag_renumber_insns = 1;
 
 int align_loops;
 int align_loops_log;
+int align_loops_max_skip;
 int align_jumps;
 int align_jumps_log;
+int align_jumps_max_skip;
 int align_labels;
 int align_labels_log;
+int align_labels_max_skip;
 int align_functions;
 int align_functions_log;
 
 /* Table of supported debugging formats.  */
-static struct
+static const struct
 {
-  const char *arg;
+  const char *const 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;
-  const char *description;
+  const enum debug_info_type debug_type;
+  const int use_extensions_p;
+  const char *const description;
 } *da,
 debug_args[] =
 {
   { "",       NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
-    "Generate default debug format output" },
-  { "gdb",    NO_DEBUG, 1, "Generate default extended debug format output" },
+    N_("Generate debugging info in default format") },
+  { "gdb",    NO_DEBUG, 1, N_("Generate debugging info in default extended format") },
 #ifdef DBX_DEBUGGING_INFO
-  { "stabs",  DBX_DEBUG, 0, "Generate STABS format debug output" },
-  { "stabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" },
+  { "stabs",  DBX_DEBUG, 0, N_("Generate STABS format debug info") },
+  { "stabs+", DBX_DEBUG, 1, N_("Generate extended STABS format debug info") },
 #endif
 #ifdef DWARF_DEBUGGING_INFO
-  { "dwarf",  DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"},
+  { "dwarf",  DWARF_DEBUG, 0, N_("Generate DWARF-1 format debug info") },
   { "dwarf+", DWARF_DEBUG, 1,
-    "Generated extended DWARF-1 format debug output" },
+    N_("Generate extended DWARF-1 format debug info") },
 #endif
 #ifdef DWARF2_DEBUGGING_INFO
-  { "dwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" },
+  { "dwarf-2", DWARF2_DEBUG, 0, N_("Generate DWARF-2 debug info") },
 #endif
 #ifdef XCOFF_DEBUGGING_INFO
-  { "xcoff",  XCOFF_DEBUG, 0, "Generate XCOFF format debug output" },
-  { "xcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" },
+  { "xcoff",  XCOFF_DEBUG, 0, N_("Generate XCOFF format debug info") },
+  { "xcoff+", XCOFF_DEBUG, 1, N_("Generate extended XCOFF format debug info") },
 #endif
 #ifdef SDB_DEBUGGING_INFO
-  { "coff", SDB_DEBUG, 0, "Generate COFF format debug output" },
+  { "coff", SDB_DEBUG, 0, N_("Generate COFF format debug info") },
 #endif
   { 0, 0, 0, 0 }
 };
@@ -990,198 +1018,206 @@ static const param_info lang_independent_params[] = {
 lang_independent_options f_options[] =
 {
   {"eliminate-dwarf2-dups", &flag_eliminate_dwarf2_dups, 1,
-   "Perform DWARF2 duplicate elimination"},
+   N_("Perform DWARF2 duplicate elimination") },
   {"float-store", &flag_float_store, 1,
-   "Do not store floats in registers" },
+   N_("Do not store floats in registers") },
   {"volatile", &flag_volatile, 1,
-   "Consider all mem refs through pointers as volatile"},
+   N_("Consider all mem refs through pointers as volatile") },
   {"volatile-global", &flag_volatile_global, 1,
-   "Consider all mem refs to global data to be volatile" },
+   N_("Consider all mem refs to global data to be volatile") },
   {"volatile-static", &flag_volatile_static, 1,
-   "Consider all mem refs to static data to be volatile" },
+   N_("Consider all mem refs to static data to be volatile") },
   {"defer-pop", &flag_defer_pop, 1,
-   "Defer popping functions args from stack until later" },
+   N_("Defer popping functions args from stack until later") },
   {"omit-frame-pointer", &flag_omit_frame_pointer, 1,
-   "When possible do not generate stack frames"},
+   N_("When possible do not generate stack frames") },
   {"optimize-sibling-calls", &flag_optimize_sibling_calls, 1,
-   "Optimize sibling and tail recursive calls" },
+   N_("Optimize sibling and tail recursive calls") },
   {"cse-follow-jumps", &flag_cse_follow_jumps, 1,
-   "When running CSE, follow jumps to their targets" },
+   N_("When running CSE, follow jumps to their targets") },
   {"cse-skip-blocks", &flag_cse_skip_blocks, 1,
-   "When running CSE, follow conditional jumps" },
+   N_("When running CSE, follow conditional jumps") },
   {"expensive-optimizations", &flag_expensive_optimizations, 1,
-   "Perform a number of minor, expensive optimisations" },
+   N_("Perform a number of minor, expensive optimisations") },
   {"thread-jumps", &flag_thread_jumps, 1,
-   "Perform jump threading optimisations"},
+   N_("Perform jump threading optimisations") },
   {"strength-reduce", &flag_strength_reduce, 1,
-   "Perform strength reduction optimisations" },
+   N_("Perform strength reduction optimisations") },
   {"unroll-loops", &flag_unroll_loops, 1,
-   "Perform loop unrolling when iteration count is known" },
+   N_("Perform loop unrolling when iteration count is known") },
   {"unroll-all-loops", &flag_unroll_all_loops, 1,
-   "Perform loop unrolling for all loops" },
+   N_("Perform loop unrolling for all loops") },
   {"move-all-movables", &flag_move_all_movables, 1,
-   "Force all loop invariant computations out of loops" },
+   N_("Force all loop invariant computations out of loops") },
   {"reduce-all-givs", &flag_reduce_all_givs, 1,
-   "Strength reduce all loop general induction variables" },
+   N_("Strength reduce all loop general induction variables") },
   {"writable-strings", &flag_writable_strings, 1,
-   "Store strings in writable data section" },
+   N_("Store strings in writable data section") },
   {"peephole", &flag_no_peephole, 0,
-   "Enable machine specific peephole optimisations" },
+   N_("Enable machine specific peephole optimisations") },
   {"force-mem", &flag_force_mem, 1,
-   "Copy memory operands into registers before using" },
+   N_("Copy memory operands into registers before using") },
   {"force-addr", &flag_force_addr, 1,
-   "Copy memory address constants into regs before using" },
+   N_("Copy memory address constants into regs before using") },
   {"function-cse", &flag_no_function_cse, 0,
-   "Allow function addresses to be held in registers" },
+   N_("Allow function addresses to be held in registers") },
   {"inline-functions", &flag_inline_functions, 1,
-   "Integrate simple functions into their callers" },
+   N_("Integrate simple functions into their callers") },
   {"keep-inline-functions", &flag_keep_inline_functions, 1,
-   "Generate code for funcs even if they are fully inlined" },
+   N_("Generate code for funcs even if they are fully inlined") },
   {"inline", &flag_no_inline, 0,
-   "Pay attention to the 'inline' keyword"},
+   N_("Pay attention to the 'inline' keyword") },
   {"keep-static-consts", &flag_keep_static_consts, 1,
-   "Emit static const variables even if they are not used" },
+   N_("Emit static const variables even if they are not used") },
   {"syntax-only", &flag_syntax_only, 1,
-   "Check for syntax errors, then stop" },
+   N_("Check for syntax errors, then stop") },
   {"shared-data", &flag_shared_data, 1,
-   "Mark data as shared rather than private" },
+   N_("Mark data as shared rather than private") },
   {"caller-saves", &flag_caller_saves, 1,
-   "Enable saving registers around function calls" },
+   N_("Enable saving registers around function calls") },
   {"pcc-struct-return", &flag_pcc_struct_return, 1,
-   "Return 'short' aggregates in memory, not registers" },
+   N_("Return 'short' aggregates in memory, not registers") },
   {"reg-struct-return", &flag_pcc_struct_return, 0,
-   "Return 'short' aggregates in registers" },
+   N_("Return 'short' aggregates in registers") },
   {"delayed-branch", &flag_delayed_branch, 1,
-   "Attempt to fill delay slots of branch instructions" },
+   N_("Attempt to fill delay slots of branch instructions") },
   {"gcse", &flag_gcse, 1,
-   "Perform the global common subexpression elimination" },
+   N_("Perform the global common subexpression elimination") },
   {"gcse-lm", &flag_gcse_lm, 1,
-   "Perform enhanced load motion during global subexpression elimination" },
+   N_("Perform enhanced load motion during global subexpression elimination") },
   {"gcse-sm", &flag_gcse_sm, 1,
-   "Perform store motion after global subexpression elimination" },
+   N_("Perform store motion after global subexpression elimination") },
   {"rerun-cse-after-loop", &flag_rerun_cse_after_loop, 1,
-   "Run CSE pass after loop optimisations"},
+   N_("Run CSE pass after loop optimisations") },
   {"rerun-loop-opt", &flag_rerun_loop_opt, 1,
-   "Run the loop optimiser twice"},
+   N_("Run the loop optimiser twice") },
   {"delete-null-pointer-checks", &flag_delete_null_pointer_checks, 1,
-   "Delete useless null pointer checks" },
+   N_("Delete useless null pointer checks") },
   {"pretend-float", &flag_pretend_float, 1,
-   "Pretend that host and target use the same FP format"},
+   N_("Pretend that host and target use the same FP format") },
   {"schedule-insns", &flag_schedule_insns, 1,
-   "Reschedule instructions before register allocation"},
+   N_("Reschedule instructions before register allocation") },
   {"schedule-insns2", &flag_schedule_insns_after_reload, 1,
-   "Reschedule instructions after register allocation"},
+   N_("Reschedule instructions after register allocation") },
   {"sched-interblock",&flag_schedule_interblock, 1,
-   "Enable scheduling across basic blocks" },
+   N_("Enable scheduling across basic blocks") },
   {"sched-spec",&flag_schedule_speculative, 1,
-   "Allow speculative motion of non-loads" },
+   N_("Allow speculative motion of non-loads") },
   {"sched-spec-load",&flag_schedule_speculative_load, 1,
-   "Allow speculative motion of some loads" },
+   N_("Allow speculative motion of some loads") },
   {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1,
-   "Allow speculative motion of more loads" },
+   N_("Allow speculative motion of more loads") },
   {"branch-count-reg",&flag_branch_on_count_reg, 1,
-   "Replace add,compare,branch with branch on count reg"},
+   N_("Replace add,compare,branch with branch on count reg") },
   {"pic", &flag_pic, 1,
-   "Generate position independent code, if possible"},
+   N_("Generate position independent code, if possible") },
   {"PIC", &flag_pic, 2, ""},
   {"exceptions", &flag_exceptions, 1,
-   "Enable exception handling" },
+   N_("Enable exception handling") },
   {"unwind-tables", &flag_unwind_tables, 1,
-    "Just generate unwind tables for exception handling" },
+   N_("Just generate unwind tables for exception handling") },
+  {"asynchronous-unwind-tables", &flag_asynchronous_unwind_tables, 1,
+   N_("Generate unwind tables exact at each instruction boundary") },
   {"non-call-exceptions", &flag_non_call_exceptions, 1,
-   "Support synchronous non-call exceptions" },
+   N_("Support synchronous non-call exceptions") },
   {"profile-arcs", &profile_arc_flag, 1,
-   "Insert arc based program profiling code" },
+   N_("Insert arc based program profiling code") },
   {"test-coverage", &flag_test_coverage, 1,
-   "Create data files needed by gcov" },
+   N_("Create data files needed by gcov") },
   {"branch-probabilities", &flag_branch_probabilities, 1,
-   "Use profiling information for branch probabilities" },
+   N_("Use profiling information for branch probabilities") },
   {"reorder-blocks", &flag_reorder_blocks, 1,
-   "Reorder basic blocks to improve code placement" },
+   N_("Reorder basic blocks to improve code placement") },
   {"rename-registers", &flag_rename_registers, 1,
-   "Do the register renaming optimization pass"},
+   N_("Do the register renaming optimization pass") },
   {"common", &flag_no_common, 0,
-   "Do not put unitialised globals in the common section" },
+   N_("Do not put uninitialized globals in the common section") },
   {"inhibit-size-directive", &flag_inhibit_size_directive, 1,
-   "Do not generate .size directives" },
+   N_("Do not generate .size directives") },
   {"function-sections", &flag_function_sections, 1,
-   "place each function into its own section" },
+   N_("place each function into its own section") },
   {"data-sections", &flag_data_sections, 1,
-   "place data items into their own section" },
+   N_("place data items into their own section") },
   {"verbose-asm", &flag_verbose_asm, 1,
-   "Add extra commentry to assembler output"},
+   N_("Add extra commentry to assembler output") },
   {"gnu-linker", &flag_gnu_linker, 1,
-   "Output GNU ld formatted global initialisers"},
+   N_("Output GNU ld formatted global initialisers") },
   {"regmove", &flag_regmove, 1,
-   "Enables a register move optimisation"},
+   N_("Enables a register move optimisation") },
   {"optimize-register-move", &flag_regmove, 1,
-   "Do the full regmove optimization pass"},
+   N_("Do the full regmove optimization pass") },
   {"pack-struct", &flag_pack_struct, 1,
-   "Pack structure members together without holes" },
+   N_("Pack structure members together without holes") },
   {"stack-check", &flag_stack_check, 1,
-   "Insert stack checking code into the program" },
+   N_("Insert stack checking code into the program") },
   {"argument-alias", &flag_argument_noalias, 0,
-   "Specify that arguments may alias each other & globals"},
+   N_("Specify that arguments may alias each other & globals") },
   {"argument-noalias", &flag_argument_noalias, 1,
-   "Assume arguments may alias globals but not each other"},
+   N_("Assume arguments may alias globals but not each other") },
   {"argument-noalias-global", &flag_argument_noalias, 2,
-   "Assume arguments do not alias each other or globals" },
+   N_("Assume arguments do not alias each other or globals") },
   {"strict-aliasing", &flag_strict_aliasing, 1,
-   "Assume strict aliasing rules apply" },
+   N_("Assume strict aliasing rules apply") },
   {"align-loops", &align_loops, 0,
-   "Align the start of loops" },
+   N_("Align the start of loops") },
   {"align-jumps", &align_jumps, 0,
-   "Align labels which are only reached by jumping" },
+   N_("Align labels which are only reached by jumping") },
   {"align-labels", &align_labels, 0,
-   "Align all labels" },
+   N_("Align all labels") },
   {"align-functions", &align_functions, 0,
-   "Align the start of functions" },
+   N_("Align the start of functions") },
+  {"merge-constants", &flag_merge_constants, 1,
+   N_("Attempt to merge identical constants accross compilation units") },
+  {"merge-all-constants", &flag_merge_constants, 2,
+   N_("Attempt to merge identical constants and constant variables") },
   {"check-memory-usage", &flag_check_memory_usage, 1,
-   "Generate code to check every memory access" },
+   N_("Generate code to check every memory access") },
   {"prefix-function-name", &flag_prefix_function_name, 1,
-   "Add a prefix to all function names" },
+   N_("Add a prefix to all function names") },
   {"dump-unnumbered", &flag_dump_unnumbered, 1,
-   "Suppress output of instruction numbers and line number notes in debugging dumps"},
+   N_("Suppress output of instruction numbers and line number notes in debugging dumps") },
   {"instrument-functions", &flag_instrument_function_entry_exit, 1,
-   "Instrument function entry/exit with profiling calls"},
+   N_("Instrument function entry/exit with profiling calls") },
   {"ssa", &flag_ssa, 1,
-   "Enable SSA optimizations" },
-  {"dce", &flag_dce, 1,
-   "Enable dead code elimination" },
+   N_("Enable SSA optimizations") },
+  {"ssa-ccp", &flag_ssa_ccp, 1,
+   N_("Enable SSA conditional constant propagation") },
+  {"ssa-dce", &flag_ssa_dce, 1,
+   N_("Enable aggressive SSA dead code elimination") },
   {"leading-underscore", &flag_leading_underscore, 1,
-   "External symbols have a leading underscore" },
+   N_("External symbols have a leading underscore") },
   {"ident", &flag_no_ident, 0,
-   "Process #ident directives"},
+   N_("Process #ident directives") },
   { "peephole2", &flag_peephole2, 1,
-    "Enables an rtl peephole pass run before sched2" },
+   N_("Enables an rtl peephole pass run before sched2") },
   { "guess-branch-probability", &flag_guess_branch_prob, 1,
-    "Enables guessing of branch probabilities" },
+   N_("Enables guessing of branch probabilities") },
   {"math-errno", &flag_errno_math, 1,
-   "Set errno after built-in math functions"},
+   N_("Set errno after built-in math functions") },
   {"trapping-math", &flag_trapping_math, 1,
-   "Floating-point operations can trap"},
+   N_("Floating-point operations can trap") },
   {"unsafe-math-optimizations", &flag_unsafe_math_optimizations, 1,
-   "Allow math optimizations that may violate IEEE or ANSI standards"},
+   N_("Allow math optimizations that may violate IEEE or ANSI standards") },
   {"bounded-pointers", &flag_bounded_pointers, 1,
-   "Compile pointers as triples: value, base & end" },
+   N_("Compile pointers as triples: value, base & end") },
   {"bounds-check", &flag_bounds_check, 1,
-   "Generate code to check bounds before dereferencing pointers and arrays" },
+   N_("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"},
+   N_("Convert floating point constant to single precision constant") },
   {"time-report", &time_report, 1,
-   "Report time taken by each compiler pass at end of run"},
+   N_("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"},
+   N_("Report on permanent memory allocation at end of run") },
   { "trapv", &flag_trapv, 1,
-    "Trap for signed overflow in addition / subtraction / multiplication." },
+   N_("Trap for signed overflow in addition / subtraction / multiplication.") },
 };
 
 /* Table of language-specific options.  */
 
-static struct lang_opt
+static const struct lang_opt
 {
-  const char *option;
-  const char *description;
+  const char *const option;
+  const char *const description;
 }
 documented_lang_options[] =
 {
@@ -1189,129 +1225,167 @@ documented_lang_options[] =
      used here is to only describe those options which are not
      enabled by default.  */
 
-  { "-ansi", "Compile just for ISO C89" },
+  { "-ansi", 
+    N_("Compile just for ISO C89") },
   { "-fallow-single-precision",
-    "Do not promote floats to double if using -traditional" },
-  { "-std= ", "Determine language standard"},
+    N_("Do not promote floats to double if using -traditional") },
+  { "-std= ", 
+    N_("Determine language standard") },
 
   { "-fsigned-bitfields", "" },
-  { "-funsigned-bitfields","Make bitfields by unsigned by default" },
+  { "-funsigned-bitfields",
+    N_("Make bitfields by unsigned by default") },
   { "-fno-signed-bitfields", "" },
   { "-fno-unsigned-bitfields","" },
-  { "-fsigned-char", "Make 'char' be signed by default"},
-  { "-funsigned-char", "Make 'char' be unsigned by default"},
+  { "-fsigned-char", 
+    N_("Make 'char' be signed by default") },
+  { "-funsigned-char", 
+    N_("Make 'char' be unsigned by default") },
   { "-fno-signed-char", "" },
   { "-fno-unsigned-char", "" },
 
   { "-ftraditional", "" },
-  { "-traditional", "Attempt to support traditional K&R style C"},
+  { "-traditional", 
+    N_("Attempt to support traditional K&R style C") },
   { "-fnotraditional", "" },
   { "-fno-traditional", "" },
 
   { "-fasm", "" },
-  { "-fno-asm", "Do not recognise the 'asm' keyword" },
+  { "-fno-asm", 
+    N_("Do not recognise the 'asm' keyword") },
   { "-fbuiltin", "" },
-  { "-fno-builtin", "Do not recognise any built in functions" },
-  { "-fhosted", "Assume normal C execution environment" },
+  { "-fno-builtin", 
+    N_("Do not recognise any built in functions") },
+  { "-fhosted", 
+    N_("Assume normal C execution environment") },
   { "-fno-hosted", "" },
   { "-ffreestanding",
-    "Assume that standard libraries & main might not exist" },
+    N_("Assume that standard libraries & main might not exist") },
   { "-fno-freestanding", "" },
-  { "-fcond-mismatch", "Allow different types as args of ? operator"},
+  { "-fcond-mismatch", 
+    N_("Allow different types as args of ? operator") },
   { "-fno-cond-mismatch", "" },
-  { "-fdollars-in-identifiers", "Allow the use of $ inside identifiers" },
+  { "-fdollars-in-identifiers", 
+    N_("Allow the use of $ inside identifiers") },
   { "-fno-dollars-in-identifiers", "" },
   { "-fpreprocessed", "" },
   { "-fno-preprocessed", "" },
-  { "-fshort-double", "Use the same size for double as for float" },
+  { "-fshort-double", 
+    N_("Use the same size for double as for float") },
   { "-fno-short-double", "" },
-  { "-fshort-enums", "Use the smallest fitting integer to hold enums"},
+  { "-fshort-enums", 
+    N_("Use the smallest fitting integer to hold enums") },
   { "-fno-short-enums", "" },
-  { "-fshort-wchar", "Override the underlying type for wchar_t to `unsigned short'" },
+  { "-fshort-wchar", 
+    N_("Override the underlying type for wchar_t to `unsigned short'") },
   { "-fno-short-wchar", "" },
 
-  { "-Wall", "Enable most warning messages" },
+  { "-Wall", 
+    N_("Enable most warning messages") },
   { "-Wbad-function-cast",
-    "Warn about casting functions to incompatible types" },
+    N_("Warn about casting functions to incompatible types") },
   { "-Wno-bad-function-cast", "" },
   { "-Wno-missing-noreturn", "" },
   { "-Wmissing-format-attribute",
-    "Warn about functions which might be candidates for format attributes" },
+    N_("Warn about functions which might be candidates for format attributes") },
   { "-Wno-missing-format-attribute", "" },
-  { "-Wcast-qual", "Warn about casts which discard qualifiers"},
+  { "-Wcast-qual", 
+    N_("Warn about casts which discard qualifiers") },
   { "-Wno-cast-qual", "" },
-  { "-Wchar-subscripts", "Warn about subscripts whose type is 'char'"},
+  { "-Wchar-subscripts", 
+    N_("Warn about subscripts whose type is 'char'") },
   { "-Wno-char-subscripts", "" },
-  { "-Wcomment", "Warn if nested comments are detected" },
+  { "-Wcomment", 
+    N_("Warn if nested comments are detected") },
   { "-Wno-comment", "" },
-  { "-Wcomments", "Warn if nested comments are detected" },
+  { "-Wcomments", 
+    N_("Warn if nested comments are detected") },
   { "-Wno-comments", "" },
-  { "-Wconversion", "Warn about possibly confusing type conversions" },
+  { "-Wconversion", 
+    N_("Warn about possibly confusing type conversions") },
   { "-Wno-conversion", "" },
-  { "-Wformat", "Warn about printf/scanf/strftime/strfmon format anomalies" },
+  { "-Wformat", 
+    N_("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" },
+    N_("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" },
+    N_("Don't warn about too many arguments to format functions") },
+  { "-Wformat-nonliteral", 
+    N_("Warn about non-string-literal format strings") },
   { "-Wno-format-nonliteral", "" },
   { "-Wformat-security",
-    "Warn about possible security problems with format functions" },
+    N_("Warn about possible security problems with format functions") },
   { "-Wno-format-security", "" },
   { "-Wimplicit-function-declaration",
-    "Warn about implicit function declarations" },
+    N_("Warn about implicit function declarations") },
   { "-Wno-implicit-function-declaration", "" },
   { "-Werror-implicit-function-declaration", "" },
-  { "-Wimplicit-int", "Warn when a declaration does not specify a type" },
+  { "-Wimplicit-int", 
+    N_("Warn when a declaration does not specify a type") },
   { "-Wno-implicit-int", "" },
   { "-Wimplicit", "" },
   { "-Wno-implicit", "" },
-  { "-Wimport", "Warn about the use of the #import directive" },
+  { "-Wimport", 
+    N_("Warn about the use of the #import directive") },
   { "-Wno-import", "" },
   { "-Wlong-long","" },
-  { "-Wno-long-long", "Do not warn about using 'long long' when -pedantic" },
-  { "-Wmain", "Warn about suspicious declarations of main" },
+  { "-Wno-long-long", 
+    N_("Do not warn about using 'long long' when -pedantic") },
+  { "-Wmain", 
+    N_("Warn about suspicious declarations of main") },
   { "-Wno-main", "" },
   { "-Wmissing-braces",
-    "Warn about possibly missing braces around initialisers" },
+    N_("Warn about possibly missing braces around initialisers") },
   { "-Wno-missing-braces", "" },
   { "-Wmissing-declarations",
-    "Warn about global funcs without previous declarations"},
+    N_("Warn about global funcs without previous declarations") },
   { "-Wno-missing-declarations", "" },
-  { "-Wmissing-prototypes", "Warn about global funcs without prototypes" },
+  { "-Wmissing-prototypes", 
+    N_("Warn about global funcs without prototypes") },
   { "-Wno-missing-prototypes", "" },
-  { "-Wmultichar", "Warn about use of multicharacter literals"},
+  { "-Wmultichar", 
+    N_("Warn about use of multicharacter literals") },
   { "-Wno-multichar", "" },
-  { "-Wnested-externs", "Warn about externs not at file scope level" },
+  { "-Wnested-externs", 
+    N_("Warn about externs not at file scope level") },
   { "-Wno-nested-externs", "" },
-  { "-Wparentheses", "Warn about possible missing parentheses" },
+  { "-Wparentheses", 
+    N_("Warn about possible missing parentheses") },
   { "-Wno-parentheses", "" },
   { "-Wsequence-point",
-    "Warn about possible violations of sequence point rules" },
+    N_("Warn about possible violations of sequence point rules") },
   { "-Wno-sequence-point", "" },
-  { "-Wpointer-arith", "Warn about function pointer arithmetic" },
+  { "-Wpointer-arith", 
+    N_("Warn about function pointer arithmetic") },
   { "-Wno-pointer-arith", "" },
   { "-Wredundant-decls",
-    "Warn about multiple declarations of the same object" },
+    N_("Warn about multiple declarations of the same object") },
   { "-Wno-redundant-decls", "" },
-  { "-Wsign-compare", "Warn about signed/unsigned comparisons" },
+  { "-Wsign-compare", 
+    N_("Warn about signed/unsigned comparisons") },
   { "-Wno-sign-compare", "" },
-  { "-Wfloat-equal", "Warn about testing equality of floating point numbers" },
+  { "-Wfloat-equal", 
+    N_("Warn about testing equality of floating point numbers") },
   { "-Wno-float-equal", "" },
-  { "-Wunknown-pragmas", "Warn about unrecognized pragmas" },
+  { "-Wunknown-pragmas", 
+    N_("Warn about unrecognized pragmas") },
   { "-Wno-unknown-pragmas", "" },
-  { "-Wstrict-prototypes", "Warn about non-prototyped function decls" },
+  { "-Wstrict-prototypes", 
+    N_("Warn about non-prototyped function decls") },
   { "-Wno-strict-prototypes", "" },
-  { "-Wtraditional", "Warn about constructs whose meaning change in ISO C"},
+  { "-Wtraditional", 
+    N_("Warn about constructs whose meaning change in ISO C") },
   { "-Wno-traditional", "" },
-  { "-Wtrigraphs", "Warn when trigraphs are encountered" },
+  { "-Wtrigraphs", 
+    N_("Warn when trigraphs are encountered") },
   { "-Wno-trigraphs", "" },
   { "-Wundef", "" },
   { "-Wno-undef", "" },
-  { "-Wwrite-strings", "Mark strings as 'const char *'"},
+  { "-Wwrite-strings", 
+    N_("Mark strings as 'const char *'") },
   { "-Wno-write-strings", "" },
 
 #define DEFINE_LANG_NAME(NAME) { NULL, NAME },
@@ -1326,22 +1400,22 @@ documented_lang_options[] =
    If VALUE is negative, -VALUE is bits to clear.
    (The sign bit is not used so there is no confusion.)  */
 
-struct
+static const struct
 {
-  const char *name;
-  int value;
-  const char *description;
+  const char *const name;
+  const int value;
+  const char *const description;
 }
 target_switches [] = TARGET_SWITCHES;
 
 /* This table is similar, but allows the switch to have a value.  */
 
 #ifdef TARGET_OPTIONS
-struct
+static const struct
 {
-  const char *prefix;
-  const char **variable;
-  const char *description;
+  const char *const prefix;
+  const char **const variable;
+  const char *const description;
 }
 target_options [] = TARGET_OPTIONS;
 #endif
@@ -1372,23 +1446,6 @@ int warn_unused_parameter;
 int warn_unused_variable;
 int warn_unused_value;
 
-void
-set_Wunused (setting)
-     int setting;
-{
-  warn_unused_function = setting;
-  warn_unused_label = setting;
-  /* Unused function parameter warnings are reported when either ``-W
-     -Wunused'' or ``-Wunused-parameter'' is specified.  Differentiate
-     -Wunused by setting WARN_UNUSED_PARAMETER to -1.  */
-  if (!setting)
-    warn_unused_parameter = 0;
-  else if (!warn_unused_parameter)
-    warn_unused_parameter = -1;
-  warn_unused_variable = setting;
-  warn_unused_value = setting;
-}
-
 /* Nonzero to warn about code which is never reached.  */
 
 int warn_notreached;
@@ -1397,7 +1454,7 @@ int warn_notreached;
 
 int warn_uninitialized;
 
-/* Nonzero means warn about all declarations which shadow others.   */
+/* Nonzero means warn about all declarations which shadow others.  */
 
 int warn_shadow;
 
@@ -1416,12 +1473,6 @@ int warn_return_type;
 
 int warn_cast_align;
 
-/* Nonzero means warn about any identifiers that match in the first N
-   characters.  The value N is in `id_clash_len'.  */
-
-int warn_id_clash;
-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
    values are larger than N bytes. The value N is in `larger_than_size'.  */
@@ -1458,36 +1509,61 @@ int warn_missing_noreturn;
 
 lang_independent_options W_options[] =
 {
-  {"unused-function", &warn_unused_function, 1, "Warn when a function is unused" },
-  {"unused-label", &warn_unused_label, 1, "Warn when a label is unused" },
-  {"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" },
+  {"unused-function", &warn_unused_function, 1,
+   N_("Warn when a function is unused") },
+  {"unused-label", &warn_unused_label, 1,
+   N_("Warn when a label is unused") },
+  {"unused-parameter", &warn_unused_parameter, 1,
+   N_("Warn when a function parameter is unused") },
+  {"unused-variable", &warn_unused_variable, 1,
+   N_("Warn when a variable is unused") },
+  {"unused-value", &warn_unused_value, 1,
+   N_("Warn when an expression value is unused") },
+  {"system-headers", &warn_system_headers, 1,
+   N_("Do not suppress warnings from system headers") },
+  {"error", &warnings_are_errors, 1,
+   N_("Treat all warnings as errors") },
+  {"shadow", &warn_shadow, 1,
+   N_("Warn when one local variable shadows another") },
   {"switch", &warn_switch, 1,
-   "Warn about enumerated switches missing a specific case" },
+   N_("Warn about enumerated switches missing a specific case") },
   {"aggregate-return", &warn_aggregate_return, 1,
-   "Warn about returning structures, unions or arrays" },
+   N_("Warn about returning structures, unions or arrays") },
   {"cast-align", &warn_cast_align, 1,
-   "Warn about pointer casts which increase alignment" },
+   N_("Warn about pointer casts which increase alignment") },
   {"unreachable-code", &warn_notreached, 1,
-   "Warn about code that will never be executed" },
+   N_("Warn about code that will never be executed") },
   {"uninitialized", &warn_uninitialized, 1,
-   "Warn about unitialized automatic variables"},
+   N_("Warn about uninitialized automatic variables") },
   {"inline", &warn_inline, 1,
-   "Warn when an inlined function cannot be inlined"},
+   N_("Warn when an inlined function cannot be inlined") },
   {"packed", &warn_packed, 1,
-   "Warn when the packed attribute has no effect on struct layout"},
+   N_("Warn when the packed attribute has no effect on struct layout") },
   {"padded", &warn_padded, 1,
-   "Warn when padding is required to align struct members"},
+   N_("Warn when padding is required to align struct members") },
   {"disabled-optimization", &warn_disabled_optimization, 1,
-   "Warn when an optimization pass is disabled"},
+   N_("Warn when an optimization pass is disabled") },
   {"missing-noreturn", &warn_missing_noreturn, 1,
-   "Warn about functions which might be candidates for attribute noreturn"}
+   N_("Warn about functions which might be candidates for attribute noreturn") }
 };
 
+void
+set_Wunused (setting)
+     int setting;
+{
+  warn_unused_function = setting;
+  warn_unused_label = setting;
+  /* Unused function parameter warnings are reported when either ``-W
+     -Wunused'' or ``-Wunused-parameter'' is specified.  Differentiate
+     -Wunused by setting WARN_UNUSED_PARAMETER to -1.  */
+  if (!setting)
+    warn_unused_parameter = 0;
+  else if (!warn_unused_parameter)
+    warn_unused_parameter = -1;
+  warn_unused_variable = setting;
+  warn_unused_value = setting;
+}
+
 /* The following routines are useful in setting all the flags that
    -ffast-math and -fno-fast-math imply.  */
 
@@ -1530,7 +1606,7 @@ read_integral_parameter (p, pname, defval)
 
   while (*endp)
     {
-      if (*endp >= '0' && *endp <= '9')
+      if (ISDIGIT (*endp))
        endp++;
       else
        break;
@@ -1584,9 +1660,9 @@ botch (s)
 
 int
 exact_log2_wide (x)
-     register unsigned HOST_WIDE_INT x;
+     unsigned HOST_WIDE_INT x;
 {
-  register int log = 0;
+  int log = 0;
   /* Test for 0 or a power of 2.  */
   if (x == 0 || x != (x & -x))
     return -1;
@@ -1602,38 +1678,15 @@ exact_log2_wide (x)
 
 int
 floor_log2_wide (x)
-     register unsigned HOST_WIDE_INT x;
+     unsigned HOST_WIDE_INT x;
 {
-  register int log = -1;
+  int log = -1;
   while (x != 0)
     log++,
     x >>= 1;
   return log;
 }
 
-/* Return the approximate positive square root of a number N.  This is for
-   statistical reports, not code generation.  */
-double
-approx_sqrt (x)
-     double x;
-{
-  double s, d;
-
-  if (x < 0)
-    abort ();
-  if (x == 0)
-    return 0;
-
-  s = x;
-  do
-    {
-      d = (s * s - x) / (2 * s);
-      s -= d;
-    }
-  while (d > .0001);
-  return s;
-}
-
 static int float_handler_set;
 int float_handled;
 jmp_buf float_handler;
@@ -1658,7 +1711,7 @@ float_signal (signo)
 /* Specify where to longjmp to when a floating arithmetic error happens.
    If HANDLER is 0, it means don't handle the errors any more.  */
 
-void
+static void
 set_float_handler (handler)
      jmp_buf handler;
 {
@@ -1678,7 +1731,7 @@ set_float_handler (handler)
    pointer FN, and one argument DATA.  DATA is usually a struct which
    contains the real input and output for function FN.  This function
    returns 0 (failure) if longjmp was called (i.e. an exception
-   occured.)  It returns 1 (success) otherwise.  */
+   occurred.)  It returns 1 (success) otherwise.  */
 
 int
 do_float_handler (fn, data)
@@ -2036,47 +2089,7 @@ check_global_declarations (vec, len)
        warning_with_decl (decl, "`%s' defined but not used");
 
       timevar_push (TV_SYMOUT);
-#ifdef SDB_DEBUGGING_INFO
-      /* The COFF linker can move initialized global vars to the end.
-        And that can screw up the symbol ordering.
-        By putting the symbols in that order to begin with,
-        we avoid a problem.  mcsun!unido!fauern!tumuc!pes@uunet.uu.net.  */
-      if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL
-         && TREE_PUBLIC (decl) && DECL_INITIAL (decl)
-         && ! DECL_EXTERNAL (decl)
-         && DECL_RTL (decl) != 0)
-       sdbout_symbol (decl, 0);
-
-      /* Output COFF information for non-global
-        file-scope initialized variables.  */
-      if (write_symbols == SDB_DEBUG
-         && TREE_CODE (decl) == VAR_DECL
-         && DECL_INITIAL (decl)
-         && ! DECL_EXTERNAL (decl)
-         && DECL_RTL (decl) != 0
-         && GET_CODE (DECL_RTL (decl)) == MEM)
-       sdbout_toplevel_data (decl);
-#endif /* SDB_DEBUGGING_INFO  */
-#ifdef DWARF_DEBUGGING_INFO
-      /* Output DWARF 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 == DWARF_DEBUG
-         && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
-       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)))
-       dwarf2out_decl (decl);
-#endif
+      (*debug_hooks->global_decl) (decl);
       timevar_pop (TV_SYMOUT);
     }
 }
@@ -2127,190 +2140,14 @@ pop_srcloc ()
   lineno = input_file_stack->line;
 }
 
-/* Compile an entire file of output from cpp, named NAME.
-   Write a file of assembly output and various debugging dumps.  */
+/* Compile an entire translation unit.  Write a file of assembly
+   output and various debugging dumps.  */
 
 static void
-compile_file (name)
-     const char *name;
+compile_file ()
 {
   tree globals;
 
-  int name_specified = name != 0;
-
-  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 ();
-  name = init_parse (name);
-  init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
-                 || debug_info_level == DINFO_LEVEL_VERBOSE
-                 || flag_test_coverage
-                 || warn_notreached);
-  init_regs ();
-  init_alias_once ();
-  init_decl_processing ();
-  init_eh ();
-  init_optabs ();
-  init_stmt ();
-  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.  */
-  init_dummy_function_start ();
-  init_expmed ();
-  init_expr_once ();
-  if (flag_caller_saves)
-    init_caller_save ();
-  expand_dummy_function_end ();
-
-  /* If auxiliary info generation is desired, open the output file.
-     This goes in the same directory as the source file--unlike
-     all the other output files.  */
-  if (flag_gen_aux_info)
-    {
-      aux_info_file = fopen (aux_info_file_name, "w");
-      if (aux_info_file == 0)
-       fatal_io_error ("can't open %s", aux_info_file_name);
-    }
-
-#ifdef IO_BUFFER_SIZE
-  setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
-           _IOFBF, IO_BUFFER_SIZE);
-#endif
-
-  if (name != 0)
-    name = ggc_strdup (name);
-
-  input_filename = name;
-
-  /* Put an entry on the input file stack for the main input file.  */
-  push_srcloc (input_filename, 0);
-
-  /* Perform language-specific initialization.
-     This may set main_input_filename.  */
-  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.  */
-  if (main_input_filename == 0)
-    main_input_filename = name;
-
-  if (flag_syntax_only)
-    {
-      write_symbols = NO_DEBUG;
-      profile_flag = 0;
-      profile_block_flag = 0;
-    }
-  else
-    {
-      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,
-                              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
-    } /* ! flag_syntax_only  */
-
-#ifndef ASM_OUTPUT_SECTION_NAME
-  if (flag_function_sections)
-    {
-      warning ("-ffunction-sections not supported for this target.");
-      flag_function_sections = 0;
-    }
-  if (flag_data_sections)
-    {
-      warning ("-fdata-sections not supported for this target.");
-      flag_data_sections = 0;
-    }
-#endif
-
-  if (flag_function_sections
-      && (profile_flag || profile_block_flag))
-    {
-      warning ("-ffunction-sections disabled; it makes profiling impossible.");
-      flag_function_sections = 0;
-    }
-
-#ifndef OBJECT_FORMAT_ELF
-  if (flag_function_sections && write_symbols != NO_DEBUG)
-    warning ("-ffunction-sections may affect debugging on some targets.");
-#endif
-
-  /* If dbx symbol table desired, initialize writing it
-     and output the predefined types.  */
-  timevar_push (TV_SYMOUT);
-#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
-  if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
-    dbxout_init (asm_out_file, main_input_filename, getdecls ());
-#endif
-#ifdef SDB_DEBUGGING_INFO
-  if (write_symbols == SDB_DEBUG)
-    sdbout_init (asm_out_file, main_input_filename, getdecls ());
-#endif
-#ifdef DWARF_DEBUGGING_INFO
-  if (write_symbols == DWARF_DEBUG)
-    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)
-    dwarf2out_init (asm_out_file, main_input_filename);
-#endif
-  timevar_pop (TV_SYMOUT);
-
   /* Initialize yet another pass.  */
 
   init_final (main_input_filename);
@@ -2320,17 +2157,11 @@ compile_file (name)
 
   /* Call the parser, which parses the entire file
      (calling rest_of_compilation for each function).  */
+  yyparse ();
 
-  if (yyparse () != 0)
-    {
-      if (errorcount == 0)
-       fnotice (stderr, "Errors detected in input file (your bison.simple is out of date)\n");
-
-      /* In case there were missing closebraces,
-        get us back to the global binding level.  */
-      while (! global_bindings_p ())
-       poplevel (0, 0, 0);
-    }
+  /* In case there were missing block closers,
+     get us back to the global binding level.  */
+  (*lang_hooks.clear_binding_stack) ();
 
   /* Compilation is now finished except for writing
      what's left of the symbol table output.  */
@@ -2338,7 +2169,7 @@ compile_file (name)
   timevar_pop (TV_PARSE);
 
   if (flag_syntax_only)
-    goto finish_syntax;
+    return;
 
   globals = getdecls ();
 
@@ -2381,25 +2212,13 @@ compile_file (name)
 
   /* Do dbx symbols.  */
   timevar_push (TV_SYMOUT);
-#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
-  if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
-    dbxout_finish (asm_out_file, main_input_filename);
-#endif
-
-#ifdef DWARF_DEBUGGING_INFO
-  if (write_symbols == DWARF_DEBUG)
-    dwarfout_finish ();
-#endif
 
 #ifdef DWARF2_UNWIND_INFO
   if (dwarf2out_do_frame ())
     dwarf2out_frame_finish ();
 #endif
 
-#ifdef DWARF2_DEBUGGING_INFO
-  if (write_symbols == DWARF2_DEBUG)
-    dwarf2out_finish ();
-#endif
+  (*debug_hooks->finish) (main_input_filename);
   timevar_pop (TV_SYMOUT);
 
   /* Output some stuff at end of file if nec.  */
@@ -2432,20 +2251,6 @@ compile_file (name)
             IDENT_ASM_OP, version_string);
 #endif
 
-  /* Language-specific end of compilation actions.  */
- finish_syntax:
-  if (lang_hooks.finish)
-    (*lang_hooks.finish) ();
-
-  /* Close the dump files.  */
-
-  if (flag_gen_aux_info)
-    {
-      fclose (aux_info_file);
-      if (errorcount)
-       unlink (aux_info_file_name);
-    }
-
   if (optimize > 0 && open_dump_file (DFI_combine, NULL))
     {
       timevar_push (TV_DUMP);
@@ -2453,51 +2258,6 @@ compile_file (name)
       close_dump_file (DFI_combine, NULL, NULL_RTX);
       timevar_pop (TV_DUMP);
     }
-
-  /* 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.  */
-
-  finish_parse ();
-
-  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 < (int) DFI_MAX; ++i)
-       if (dump_file[i].initialized && dump_file[i].graph_dump_p)
-         {
-           char seq[16];
-           char *suffix;
-
-           sprintf (seq, ".%02d.", i);
-           suffix = concat (seq, dump_file[i].extension, NULL);
-           finish_graph_dump_file (dump_base_name, suffix);
-           free (suffix);
-         }
-    }
-
-  if (mem_report)
-    {
-      ggc_print_statistics ();
-      stringpool_statistics ();
-    }
-
-  /* Free up memory for the benefit of leak detectors.  */
-  free_reg_info ();
-
-  /* Stop timing total execution time.  */
-  timevar_stop (TV_TOTAL);
-
-  /* Print the times.  */
-
-  timevar_print (stderr);
 }
 \f
 /* This is called from various places for FUNCTION_DECL, VAR_DECL,
@@ -2505,7 +2265,7 @@ compile_file (name)
 
    This does nothing for local (non-static) variables, unless the
    variable is a register variable with an ASMSPEC.  In that case, or
-   if the variable is not an automatice, it sets up the RTL and
+   if the variable is not an automatic, it sets up the RTL and
    outputs any assembler code (label definition, storage allocation
    and initialization).
 
@@ -2611,64 +2371,6 @@ rest_of_type_compilation (type, toplev)
   timevar_pop (TV_SYMOUT);
 }
 
-/* DECL is an inline function, whose body is present, but which is not
-   being output at this point.  (We're putting that off until we need
-   to do it.)  If there are any actions that need to take place,
-   including the emission of debugging information for the function,
-   this is where they should go.  This function may be called by
-   language-dependent code for front-ends that do not even generate
-   RTL for functions that don't need to be put out.  */
-
-void
-note_deferral_of_defined_inline_function (decl)
-     tree decl ATTRIBUTE_UNUSED;
-{
-#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
-      && (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);
-      if (! was_abstract)
-       set_decl_abstract_flags (decl, 0);
-
-      /* Reset CURRENT_FUNCTION_DECL.  */
-      current_function_decl = saved_cfd;
-    }
-#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
@@ -2679,7 +2381,7 @@ void
 rest_of_compilation (decl)
      tree decl;
 {
-  register rtx insns;
+  rtx insns;
   int tem;
   int failure = 0;
   int rebuild_label_notes_after_reload;
@@ -2736,7 +2438,7 @@ rest_of_compilation (decl)
          }
 
       /* If requested, consider whether to make this function inline.  */
-      if ((DECL_INLINE (decl) && !flag_no_inline) 
+      if ((DECL_INLINE (decl) && !flag_no_inline)
          || flag_inline_functions)
        {
          timevar_push (TV_INTEGRATION);
@@ -2794,29 +2496,32 @@ rest_of_compilation (decl)
        DECL_DEFER_OUTPUT (decl) = 1;
 
       if (DECL_INLINE (decl))
-       /* DWARF wants seperate debugging info for abstract and
+       /* DWARF wants separate debugging info for abstract and
           concrete instances of all inline functions, including those
           declared inline but not inlined, and those inlined even
           though they weren't declared inline.  Conveniently, that's
           what DECL_INLINE means at this point.  */
-       note_deferral_of_defined_inline_function (decl);
+       (*debug_hooks->deferred_inline_function) (decl);
 
       if (DECL_DEFER_OUTPUT (decl))
        {
          /* 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
+            want to call cleanup the cfg 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.  */
+            work necessary to make that safe.  */
          if (warn_return_type)
            {
              int saved_optimize = optimize;
 
              optimize = 0;
+             rebuild_jump_labels (insns);
              find_exception_handler_labels ();
-             jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
-                            !JUMP_AFTER_REGSCAN);
+             find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+             cleanup_cfg (CLEANUP_PRE_SIBCALL | CLEANUP_PRE_LOOP);
              optimize = saved_optimize;
+
+             /* CFG is no longer maintained up-to-date.  */
+             free_bb_for_insn ();
            }
 
          current_function_nothrow = nothrow_function_p ();
@@ -2851,11 +2556,13 @@ rest_of_compilation (decl)
      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.*/
+     integrate.  Also, we can now initialize pseudos intended to 
+     carry magic hard reg data throughout the function.  */
   rtx_equal_function_value_matters = 0;
   purge_hard_subreg_sets (get_insns ());
+  emit_initial_value_sets ();
 
-  /* Don't return yet if -Wreturn-type; we need to do jump_optimize.  */
+  /* Don't return yet if -Wreturn-type; we need to do cleanup_cfg.  */
   if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
     goto exit_rest_of_compilation;
 
@@ -2900,7 +2607,7 @@ rest_of_compilation (decl)
   unshare_all_rtl (current_function_decl, insns);
 
 #ifdef SETJMP_VIA_SAVE_AREA
-  /* This must be performed before virutal register instantiation.  */
+  /* This must be performed before virtual register instantiation.  */
   if (current_function_calls_alloca)
     optimize_save_area_alloca (insns);
 #endif
@@ -2920,8 +2627,14 @@ rest_of_compilation (decl)
   expected_value_to_br_prob ();
 
   reg_scan (insns, max_reg_num (), 0);
-  jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
-                JUMP_AFTER_REGSCAN);
+  rebuild_jump_labels (insns);
+  find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+  cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP);
+
+  /* CFG is no longer maintained up-to-date.  */
+  free_bb_for_insn ();
+  copy_loop_headers (insns);
+  purge_line_number_notes (insns);
 
   timevar_pop (TV_JUMP);
 
@@ -2932,12 +2645,81 @@ rest_of_compilation (decl)
       goto exit_rest_of_compilation;
     }
 
+  /* Long term, this should probably move before the jump optimizer too,
+     but I didn't want to disturb the rtl_dump_and_exit and related
+     stuff at this time.  */
+  if (optimize > 0 && flag_ssa)
+    {
+      /* Convert to SSA form.  */
+
+      timevar_push (TV_TO_SSA);
+      open_dump_file (DFI_ssa, decl);
+
+      find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
+      convert_to_ssa ();
+
+      close_dump_file (DFI_ssa, print_rtl_with_bb, insns);
+      timevar_pop (TV_TO_SSA);
+
+      /* Perform sparse conditional constant propagation, if requested.  */
+      if (flag_ssa_ccp)
+       {
+         timevar_push (TV_SSA_CCP);
+         open_dump_file (DFI_ssa_ccp, decl);
+
+         ssa_const_prop ();
+
+         close_dump_file (DFI_ssa_ccp, print_rtl_with_bb, get_insns ());
+         timevar_pop (TV_SSA_CCP);
+       }
+
+      /* It would be useful to cleanup the CFG at this point, but block
+        merging and possibly other transformations might leave a PHI
+        node in the middle of a basic block, which is a strict no-no.  */
+
+      /* The SSA implementation uses basic block numbers in its phi
+        nodes.  Thus, changing the control-flow graph or the basic
+        blocks, e.g., calling find_basic_blocks () or cleanup_cfg (),
+        may cause problems.  */
+
+      if (flag_ssa_dce)
+       {
+         /* Remove dead code.  */
+
+         timevar_push (TV_SSA_DCE);
+         open_dump_file (DFI_ssa_dce, decl);
+
+         insns = get_insns ();
+         ssa_eliminate_dead_code();
+
+         close_dump_file (DFI_ssa_dce, print_rtl_with_bb, insns);
+         timevar_pop (TV_SSA_DCE);
+       }
+
+      /* Convert from SSA form.  */
+
+      timevar_push (TV_FROM_SSA);
+      open_dump_file (DFI_ussa, decl);
+
+      convert_from_ssa ();
+      /* New registers have been created.  Rescan their usage.  */
+      reg_scan (insns, max_reg_num (), 1);
+
+      close_dump_file (DFI_ussa, print_rtl_with_bb, insns);
+      timevar_pop (TV_FROM_SSA);
+
+      ggc_collect ();
+      /* CFG is no longer maintained up-to-date.  */
+      free_bb_for_insn ();
+    }
+
   timevar_push (TV_JUMP);
 
   if (optimize > 0)
     {
       find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-      cleanup_cfg ();
+      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
 
       /* ??? Run if-conversion before delete_null_pointer_checks,
          since the later does not preserve the CFG.  This should
@@ -2947,6 +2729,8 @@ rest_of_compilation (decl)
       if_convert (0);
       timevar_pop (TV_IFCVT);
 
+      /* CFG is no longer maintained up-to-date.  */
+      free_bb_for_insn ();
       /* Try to identify useless null pointer tests and delete them.  */
       if (flag_delete_null_pointer_checks)
        delete_null_pointer_checks (insns);
@@ -2992,14 +2776,17 @@ rest_of_compilation (decl)
       if (tem || optimize > 1)
        {
          timevar_push (TV_JUMP);
-         jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
-                        !JUMP_AFTER_REGSCAN);
+         rebuild_jump_labels (insns);
+         find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+         cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
          timevar_pop (TV_JUMP);
+         /* CFG is no longer maintained up-to-date.  */
+         free_bb_for_insn ();
        }
 
       /* Run this after jump optmizations remove all the unreachable code
         so that unreachable code will not keep values live.  */
-      delete_trivially_dead_insns (insns, max_reg_num ());
+      delete_trivially_dead_insns (insns, max_reg_num (), 0);
 
       /* Try to identify useless null pointer tests and delete them.  */
       if (flag_delete_null_pointer_checks)
@@ -3007,9 +2794,11 @@ rest_of_compilation (decl)
          timevar_push (TV_JUMP);
          find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
 
-         cleanup_cfg ();
+         cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
 
          delete_null_pointer_checks (insns);
+         /* CFG is no longer maintained up-to-date.  */
+         free_bb_for_insn ();
          timevar_pop (TV_JUMP);
        }
 
@@ -3030,58 +2819,6 @@ rest_of_compilation (decl)
 
   ggc_collect ();
 
-  if (optimize > 0 && flag_ssa)
-    {
-      /* Convert to SSA form.  */
-
-      timevar_push (TV_TO_SSA);
-      open_dump_file (DFI_ssa, decl);
-
-      find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-      cleanup_cfg ();
-      convert_to_ssa ();
-
-      close_dump_file (DFI_ssa, print_rtl_with_bb, insns);
-      timevar_pop (TV_TO_SSA);
-
-      /* The SSA implementation uses basic block numbers in its phi
-        nodes.  Thus, changing the control-flow graph or the basic
-        blocks, e.g., calling find_basic_blocks () or cleanup_cfg (),
-        may cause problems.  */
-
-      if (flag_dce)
-       {
-         /* Remove dead code. */
-
-         timevar_push (TV_DEAD_CODE_ELIM);
-         open_dump_file (DFI_dce, decl);
-
-         insns = get_insns ();
-         eliminate_dead_code();
-
-         close_dump_file (DFI_dce, print_rtl_with_bb, insns);
-         timevar_pop (TV_DEAD_CODE_ELIM);
-       }
-
-      /* Convert from SSA form.  */
-
-      timevar_push (TV_FROM_SSA);
-      open_dump_file (DFI_ussa, decl);
-
-      convert_from_ssa ();
-      /* New registers have been created.  Rescan their usage.  */
-      reg_scan (insns, max_reg_num (), 1);
-      /* Life analysis used in SSA adds log_links but these
-        shouldn't be there until the flow stage, so clear
-        them away.  */
-      clear_log_links (insns);
-
-      close_dump_file (DFI_ussa, print_rtl_with_bb, insns);
-      timevar_pop (TV_FROM_SSA);
-
-      ggc_collect ();
-    }
-
   /* Perform global cse.  */
 
   if (optimize > 0 && flag_gcse)
@@ -3093,13 +2830,15 @@ rest_of_compilation (decl)
       open_dump_file (DFI_gcse, decl);
 
       find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-      cleanup_cfg ();
+      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
       tem = gcse_main (insns, rtl_dump_file);
 
       save_csb = flag_cse_skip_blocks;
       save_cfj = flag_cse_follow_jumps;
       flag_cse_skip_blocks = flag_cse_follow_jumps = 0;
 
+      /* CFG is no longer maintained up-to-date.  */
+      free_bb_for_insn ();
       /* If -fexpensive-optimizations, re-run CSE to clean up things done
         by gcse.  */
       if (flag_expensive_optimizations)
@@ -3110,15 +2849,19 @@ rest_of_compilation (decl)
          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);
+         rebuild_jump_labels (insns);
+         delete_trivially_dead_insns (insns, max_reg_num (), 0);
+         find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+         cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
+         /* CFG is no longer maintained up-to-date.  */
+         free_bb_for_insn ();
          timevar_pop (TV_JUMP);
 
          if (flag_expensive_optimizations)
@@ -3144,9 +2887,12 @@ rest_of_compilation (decl)
     {
       timevar_push (TV_LOOP);
       open_dump_file (DFI_loop, decl);
+      free_bb_for_insn ();
 
       if (flag_rerun_loop_opt)
        {
+         cleanup_barriers ();
+
          /* We only want to perform unrolling once.  */
 
          loop_optimize (insns, rtl_dump_file, 0);
@@ -3155,12 +2901,13 @@ rest_of_compilation (decl)
             trivially dead.  We delete those instructions now in the
             hope that doing so will make the heuristics in loop work
             better and possibly speed up compilation.  */
-         delete_trivially_dead_insns (insns, max_reg_num ());
+         delete_trivially_dead_insns (insns, max_reg_num (), 0);
 
          /* The regscan pass is currently necessary as the alias
                  analysis code depends on this information.  */
          reg_scan (insns, max_reg_num (), 1);
        }
+      cleanup_barriers ();
       loop_optimize (insns, rtl_dump_file,
                     (flag_unroll_loops ? LOOP_UNROLL : 0) | LOOP_BCT);
 
@@ -3188,30 +2935,33 @@ rest_of_compilation (decl)
             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 ());
+         delete_trivially_dead_insns (insns, max_reg_num (), 0);
 
          reg_scan (insns, max_reg_num (), 0);
-         jump_optimize (insns, !JUMP_CROSS_JUMP,
-                        !JUMP_NOOP_MOVES, JUMP_AFTER_REGSCAN);
 
          timevar_push (TV_IFCVT);
 
          find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-         cleanup_cfg ();
+         cleanup_cfg (CLEANUP_EXPENSIVE);
          if_convert (0);
 
          timevar_pop(TV_IFCVT);
 
          timevar_pop (TV_JUMP);
 
+         /* CFG is no longer maintained up-to-date.  */
+         free_bb_for_insn ();
          reg_scan (insns, max_reg_num (), 0);
          tem = cse_main (insns, max_reg_num (), 1, rtl_dump_file);
 
          if (tem)
            {
              timevar_push (TV_JUMP);
-             jump_optimize (insns, !JUMP_CROSS_JUMP,
-                            !JUMP_NOOP_MOVES, !JUMP_AFTER_REGSCAN);
+             rebuild_jump_labels (insns);
+             find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+             cleanup_cfg (CLEANUP_EXPENSIVE);
+             /* CFG is no longer maintained up-to-date.  */
+             free_bb_for_insn ();
              timevar_pop (TV_JUMP);
            }
        }
@@ -3243,9 +2993,18 @@ rest_of_compilation (decl)
   open_dump_file (DFI_cfg, decl);
 
   find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-  cleanup_cfg ();
+  cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0);
   check_function_return_warnings ();
 
+  /* It may make more sense to mark constant functions after dead code is
+     eliminated by life_analyzis, but we need to do it early, as -fprofile-arcs
+     may insert code making function non-constant, but we still must consider
+     it as constant, otherwise -fbranch-probabilities will not read data back.
+
+     life_analyzis rarely eliminates modification of external memory.
+   */
+  mark_constant_function ();
+
   close_dump_file (DFI_cfg, print_rtl_with_bb, insns);
 
   if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
@@ -3278,10 +3037,8 @@ rest_of_compilation (decl)
       flow_loops_free (&loops);
     }
   life_analysis (insns, rtl_dump_file, PROP_FINAL);
-  mark_constant_function ();
   timevar_pop (TV_FLOW);
 
-  register_life_up_to_date = 1;
   no_new_pseudos = 1;
 
   if (warn_uninitialized || extra_warnings)
@@ -3307,6 +3064,10 @@ rest_of_compilation (decl)
       rebuild_jump_labels_after_combine
        = combine_instructions (insns, max_reg_num ());
 
+      /* Always purge dead edges, as we may eliminate an insn throwing
+         exception.  */
+      rebuild_jump_labels_after_combine |= purge_all_dead_edges (true);
+
       /* Combining insns may have turned an indirect jump into a
         direct jump.  Rebuid the JUMP_LABEL fields of jumping
         instructions.  */
@@ -3316,20 +3077,7 @@ rest_of_compilation (decl)
          rebuild_jump_labels (insns);
          timevar_pop (TV_JUMP);
 
-         timevar_push (TV_FLOW);
-         find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-         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
-            without updating life info can wind up with Wierd Stuff in
-            global_live_at_end.  We then run sched1, which updates things
-            properly, discovers the wierdness and aborts.  */
-         update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
-                           PROP_DEATH_NOTES | PROP_KILL_DEAD_CODE
-                           | PROP_SCAN_DEAD_CODE);
-
-         timevar_pop (TV_FLOW);
+         cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
        }
 
       close_dump_file (DFI_combine, print_rtl_with_bb, insns);
@@ -3368,14 +3116,18 @@ rest_of_compilation (decl)
       ggc_collect ();
     }
 
+  /* Do unconditional splitting before register allocation to allow machine
+     description to add extra information not needed previously.  */
+  split_all_insns (1);
+
   /* Any of the several passes since flow1 will have munged register
      lifetime data a bit.  */
-  if (optimize > 0)
-    register_life_up_to_date = 0;
+  register_life_up_to_date = 0;
 
 #ifdef OPTIMIZE_MODE_SWITCHING
-  timevar_push (TV_GCSE);
+  timevar_push (TV_MODE_SWITCH);
 
+  no_new_pseudos = 0;
   if (optimize_mode_switching (NULL))
     {
       /* We did work, and so had to regenerate global life information.
@@ -3383,17 +3135,19 @@ rest_of_compilation (decl)
         information below.  */
       register_life_up_to_date = 1;
     }
+  no_new_pseudos = 1;
 
-  timevar_pop (TV_GCSE);
+  timevar_pop (TV_MODE_SWITCH);
 #endif
 
+  timevar_push (TV_SCHED);
+
 #ifdef INSN_SCHEDULING
 
   /* Print function header into sched dump now
      because doing the sched analysis makes some of the dump.  */
   if (optimize > 0 && flag_schedule_insns)
     {
-      timevar_push (TV_SCHED);
       open_dump_file (DFI_sched, decl);
 
       /* Do control and data sched analysis,
@@ -3402,15 +3156,15 @@ rest_of_compilation (decl)
       schedule_insns (rtl_dump_file);
 
       close_dump_file (DFI_sched, print_rtl_with_bb, insns);
-      timevar_pop (TV_SCHED);
-
-      ggc_collect ();
 
       /* Register lifetime information was updated as part of verifying
         the schedule.  */
       register_life_up_to_date = 1;
     }
 #endif
+  timevar_pop (TV_SCHED);
+
+  ggc_collect ();
 
   /* Determine if the current function is a leaf before running reload
      since this can impact optimizations done by the prologue and
@@ -3427,6 +3181,15 @@ rest_of_compilation (decl)
 
   if (! register_life_up_to_date)
     recompute_reg_usage (insns, ! optimize_size);
+
+  /* Allocate the reg_renumber array.  */
+  allocate_reg_info (max_regno, FALSE, TRUE);
+
+  /* And the reg_equiv_memory_loc array.  */
+  reg_equiv_memory_loc = (rtx *) xcalloc (max_regno, sizeof (rtx));
+
+  allocate_initial_values (reg_equiv_memory_loc);
+
   regclass (insns, max_reg_num (), rtl_dump_file);
   rebuild_label_notes_after_reload = local_alloc ();
 
@@ -3486,22 +3249,6 @@ rest_of_compilation (decl)
       timevar_pop (TV_RELOAD_CSE_REGS);
     }
 
-  /* If optimizing, then go ahead and split insns now since we are about
-     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 ();
-
-      split_all_insns (0);
-      rebuild_label_notes_after_reload |= old_labelnum != max_label_num ();
-    }
-
   /* Register allocation and reloading may have turned an indirect jump into
      a direct jump.  If so, we must rebuild the JUMP_LABEL fields of
      jumping instructions.  */
@@ -3520,9 +3267,15 @@ rest_of_compilation (decl)
   timevar_push (TV_FLOW2);
   open_dump_file (DFI_flow2, decl);
 
-  jump_optimize (insns, !JUMP_CROSS_JUMP,
-                JUMP_NOOP_MOVES, !JUMP_AFTER_REGSCAN);
-  find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+#ifdef ENABLE_CHECKING
+  verify_flow_info ();
+#endif
+
+  /* If optimizing, then go ahead and split insns now.  */
+  if (optimize > 0)
+    split_all_insns (0);
+
+  cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0);
 
   /* On some machines, the prologue and epilogue code, or parts thereof,
      can be represented as RTL.  Doing so lets us schedule insns between
@@ -3532,7 +3285,7 @@ rest_of_compilation (decl)
 
   if (optimize)
     {
-      cleanup_cfg ();
+      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_CROSSJUMP);
       life_analysis (insns, rtl_dump_file, PROP_FINAL);
 
       /* This is kind of a heuristic.  We need to run combine_stack_adjustments
@@ -3586,6 +3339,10 @@ rest_of_compilation (decl)
       close_dump_file (DFI_ce2, print_rtl_with_bb, insns);
       timevar_pop (TV_IFCVT2);
     }
+#ifdef STACK_REGS
+  if (optimize)
+    split_all_insns (1);
+#endif
 
 #ifdef INSN_SCHEDULING
   if (optimize > 0 && flag_schedule_insns_after_reload)
@@ -3596,6 +3353,8 @@ rest_of_compilation (decl)
       /* Do control and data sched analysis again,
         and write some more of the results to dump file.  */
 
+      split_all_insns (1);
+
       schedule_insns (rtl_dump_file);
 
       close_dump_file (DFI_sched2, print_rtl_with_bb, insns);
@@ -3610,45 +3369,56 @@ rest_of_compilation (decl)
     = optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
 #endif
 
-  if (optimize > 0 && flag_reorder_blocks)
+#ifdef STACK_REGS
+  timevar_push (TV_REG_STACK);
+  open_dump_file (DFI_stack, decl);
+
+  reg_to_stack (insns, rtl_dump_file);
+
+  close_dump_file (DFI_stack, print_rtl_with_bb, insns);
+  timevar_pop (TV_REG_STACK);
+
+  ggc_collect ();
+#endif
+  if (optimize > 0)
     {
       timevar_push (TV_REORDER_BLOCKS);
       open_dump_file (DFI_bbro, decl);
 
-      reorder_basic_blocks ();
+      /* Last attempt to optimize CFG, as life analyzis possibly removed
+        some instructions.  */
+      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
+                  | CLEANUP_CROSSJUMP);
+      if (flag_reorder_blocks)
+       {
+         reorder_basic_blocks ();
+         cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
+       }
 
       close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
       timevar_pop (TV_REORDER_BLOCKS);
     }
+  compute_alignments ();
 
-  /* One more attempt to remove jumps to .+1 left by dead-store elimination.
-     Also do cross-jumping this time and delete no-op move insns.  */
-
-  if (optimize > 0)
-    {
-      timevar_push (TV_JUMP);
-      open_dump_file (DFI_jump2, decl);
-
-      jump_optimize (insns, JUMP_CROSS_JUMP, JUMP_NOOP_MOVES,
-                    !JUMP_AFTER_REGSCAN);
-
-      /* CFG no longer kept up to date.  */
-
-      close_dump_file (DFI_jump2, print_rtl, insns);
-      timevar_pop (TV_JUMP);
-    }
+  /* CFG is no longer maintained up-to-date.  */
+  free_bb_for_insn ();
 
   /* If a machine dependent reorganization is needed, call it.  */
 #ifdef MACHINE_DEPENDENT_REORG
+  timevar_push (TV_MACH_DEP);
   open_dump_file (DFI_mach, decl);
 
   MACHINE_DEPENDENT_REORG (insns);
 
   close_dump_file (DFI_mach, print_rtl, insns);
+  timevar_pop (TV_MACH_DEP);
 
   ggc_collect ();
 #endif
 
+  purge_line_number_notes (insns);
+  cleanup_barriers ();
+
   /* If a scheduling pass for delayed branches is to be done,
      call the scheduling code.  */
 
@@ -3667,34 +3437,19 @@ rest_of_compilation (decl)
     }
 #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 ();
+#if defined (HAVE_ATTR_length) && !defined (STACK_REGS)
+  timevar_push (TV_SHORTEN_BRANCH);
+  split_all_insns_noflow ();
+  timevar_pop (TV_SHORTEN_BRANCH);
 #endif
 
-  /* Shorten branches.
+  convert_to_eh_region_ranges ();
 
-     Note this must run before reg-stack because of death note (ab)use
-     in the ia32 backend.  */
+  /* Shorten branches.  */
   timevar_push (TV_SHORTEN_BRANCH);
   shorten_branches (get_insns ());
   timevar_pop (TV_SHORTEN_BRANCH);
 
-#ifdef STACK_REGS
-  timevar_push (TV_REG_STACK);
-  open_dump_file (DFI_stack, decl);
-
-  reg_to_stack (insns, rtl_dump_file);
-
-  close_dump_file (DFI_stack, print_rtl, insns);
-  timevar_pop (TV_REG_STACK);
-
-  ggc_collect ();
-
-  convert_to_eh_region_ranges ();
-#endif
-
   current_function_nothrow = nothrow_function_p ();
   if (current_function_nothrow)
     /* Now we know that this can't throw; set the flag for the benefit
@@ -3722,7 +3477,7 @@ rest_of_compilation (decl)
     assemble_start_function (decl, fnname);
     final_start_function (insns, asm_out_file, optimize);
     final (insns, asm_out_file, optimize, 0);
-    final_end_function (insns, asm_out_file, optimize);
+    final_end_function ();
 
 #ifdef IA64_UNWIND_INFO
     /* ??? The IA-64 ".handlerdata" directive must be issued before
@@ -3761,20 +3516,7 @@ rest_of_compilation (decl)
      generated.  During that call, we *will* be routed past here.  */
 
   timevar_push (TV_SYMOUT);
-#ifdef DBX_DEBUGGING_INFO
-  if (write_symbols == DBX_DEBUG)
-    dbxout_function (decl);
-#endif
-
-#ifdef DWARF_DEBUGGING_INFO
-  if (write_symbols == DWARF_DEBUG)
-    dwarfout_file_scope_decl (decl, 0);
-#endif
-
-#ifdef DWARF2_DEBUGGING_INFO
-  if (write_symbols == DWARF2_DEBUG)
-    dwarf2out_decl (decl);
-#endif
+  (*debug_hooks->function_decl) (decl);
   timevar_pop (TV_SYMOUT);
 
  exit_rest_of_compilation:
@@ -3822,7 +3564,13 @@ rest_of_compilation (decl)
   /* We're done with this function.  Free up memory if we can.  */
   free_after_parsing (cfun);
   if (! DECL_DEFER_OUTPUT (decl))
-    free_after_compilation (cfun);
+    {
+      free_after_compilation (cfun);
+
+      /* Clear integrate.c's pointer to the cfun structure we just
+        destroyed.  */
+      DECL_SAVED_INSNS (decl) = 0;
+    }
   cfun = 0;
 
   ggc_collect ();
@@ -3850,12 +3598,12 @@ display_help ()
 
       if (description != NULL && * description != 0)
        printf ("  -f%-21s %s\n",
-               f_options[i].string, description);
+               f_options[i].string, _(description));
     }
 
   printf (_("  -O[number]              Set optimisation level to [number]\n"));
   printf (_("  -Os                     Optimise for space rather than speed\n"));
-  for (i = sizeof (compiler_params); i--;)
+  for (i = LAST_PARAM; i--;)
     {
       const char *description = compiler_params[i].help;
       const int length = 21-strlen(compiler_params[i].option);
@@ -3864,7 +3612,7 @@ display_help ()
        printf ("  --param %s=<value>%.*s%s\n",
                compiler_params[i].option,
                length > 0 ? length : 1, "                     ",
-               description);
+               _(description));
     }
   printf (_("  -pedantic               Issue warnings needed by strict compliance to ISO C\n"));
   printf (_("  -pedantic-errors        Like -pedantic except that errors are produced\n"));
@@ -3877,11 +3625,10 @@ display_help ()
 
       if (description != NULL && * description != 0)
        printf ("  -W%-21s %s\n",
-               W_options[i].string, description);
+               W_options[i].string, _(description));
     }
 
   printf (_("  -Wunused                Enable unused warnings\n"));
-  printf (_("  -Wid-clash-<num>        Warn if 2 identifiers have the same first <num> chars\n"));
   printf (_("  -Wlarger-than-<number>  Warn if an object is larger than <number> bytes\n"));
   printf (_("  -p                      Enable function profiling\n"));
 #if defined (BLOCK_PROFILER) || defined (FUNCTION_BLOCK_PROFILER)
@@ -3899,10 +3646,10 @@ display_help ()
     {
       if (debug_args[i].description != NULL)
        printf ("  -g%-21s %s\n",
-               debug_args[i].arg, debug_args[i].description);
+               debug_args[i].arg, _(debug_args[i].description));
     }
 
-  printf (_("  -aux-info <file>        Emit declaration info into <file>.X\n"));
+  printf (_("  -aux-info <file>        Emit declaration info into <file>\n"));
   printf (_("  -quiet                  Do not display functions compiled or elapsed time\n"));
   printf (_("  -version                Display the compiler's version\n"));
   printf (_("  -d[letters]             Enable dumps from specific passes of the compiler\n"));
@@ -3954,7 +3701,7 @@ display_help ()
              lang = description;
            }
          else
-           printf ("  %-23.23s %s\n", option, description);
+           printf ("  %-23.23s %s\n", option, _(description));
        }
     }
 
@@ -3997,7 +3744,7 @@ display_target_options ()
                printf (_("  -m%-23.23s [undocumented]\n"), option);
            }
          else if (* description != 0)
-           doc += printf ("  -m%-23.23s %s\n", option, description);
+           doc += printf ("  -m%-23.23s %s\n", option, _(description));
        }
 
 #ifdef TARGET_OPTIONS
@@ -4016,7 +3763,7 @@ display_target_options ()
                printf (_("  -m%-23.23s [undocumented]\n"), option);
            }
          else if (* description != 0)
-           doc += printf ("  -m%-23.23s %s\n", option, description);
+           doc += printf ("  -m%-23.23s %s\n", option, _(description));
        }
 #endif
       if (undoc)
@@ -4029,7 +3776,7 @@ display_target_options ()
     }
 }
 \f
-/* Parse a -d... comand line switch.  */
+/* Parse a -d... command line switch.  */
 
 static void
 decode_d_option (arg)
@@ -4061,7 +3808,7 @@ decode_d_option (arg)
        rtl_dump_and_exit = 1;
        break;
       case 'y':
-       set_yydebug (1);
+       (*lang_hooks.set_yydebug) (1);
        break;
       case 'D':        /* These are handled by the preprocessor.  */
       case 'I':
@@ -4082,7 +3829,7 @@ decode_d_option (arg)
       }
 }
 
-/* Parse a -f... comand line switch.  ARG is the value after the -f.
+/* Parse a -f... command line switch.  ARG is the value after the -f.
    It is safe to access 'ARG - 2' to generate the full switch name.
    Return the number of strings consumed.  */
 
@@ -4117,7 +3864,7 @@ decode_f_option (arg)
   else if ((option_value = skip_leading_substring (arg, "inline-limit-"))
           || (option_value = skip_leading_substring (arg, "inline-limit=")))
     {
-      int val = 
+      int val =
        read_integral_parameter (option_value, arg - 2,
                                 MAX_INLINE_INSNS);
       set_param_value ("max-inline-insns", val);
@@ -4160,16 +3907,17 @@ decode_f_option (arg)
     }
   else if ((option_value
             = skip_leading_substring (arg, "message-length=")))
-    diagnostic_message_length_per_line =
-      read_integral_parameter (option_value, arg - 2,
-                              diagnostic_message_length_per_line);
+    output_set_maximum_length
+      (&global_dc->buffer, read_integral_parameter
+       (option_value, arg - 2, diagnostic_line_cutoff (global_dc)));
   else if ((option_value
            = skip_leading_substring (arg, "diagnostics-show-location=")))
     {
       if (!strcmp (option_value, "once"))
-       set_message_prefixing_rule (DIAGNOSTICS_SHOW_PREFIX_ONCE);
+        diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
       else if (!strcmp (option_value, "every-line"))
-       set_message_prefixing_rule (DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE);
+        diagnostic_prefixing_rule (global_dc)
+          = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
       else
        error ("Unrecognized option `%s'", arg - 2);
     }
@@ -4185,7 +3933,7 @@ decode_f_option (arg)
   return 1;
 }
 
-/* Parse a -W... comand line switch.  ARG is the value after the -W.
+/* Parse a -W... command line switch.  ARG is the value after the -W.
    It is safe to access 'ARG - 2' to generate the full switch name.
    Return the number of strings consumed.  */
 
@@ -4215,12 +3963,7 @@ decode_W_option (arg)
     }
 
   if ((option_value = skip_leading_substring (arg, "id-clash-")))
-    {
-      id_clash_len = read_integral_parameter (option_value, arg - 2, -1);
-
-      if (id_clash_len != -1)
-       warn_id_clash = 1;
-    }
+    warning ("-Wid-clash-LEN is no longer supported");
   else if ((option_value = skip_leading_substring (arg, "larger-than-")))
     {
       larger_than_size = read_integral_parameter (option_value, arg - 2, -1);
@@ -4241,7 +3984,7 @@ decode_W_option (arg)
   return 1;
 }
 
-/* Parse a -g... comand line switch.  ARG is the value after the -g.
+/* Parse a -g... command line switch.  ARG is the value after the -g.
    It is safe to access 'ARG - 2' to generate the full switch name.
    Return the number of strings consumed.  */
 
@@ -4249,7 +3992,7 @@ static int
 decode_g_option (arg)
      const char *arg;
 {
-  unsigned level;
+  static unsigned level=0;
   /* 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
@@ -4261,7 +4004,7 @@ decode_g_option (arg)
      -gdwarf -g3 is equivalent to -gdwarf3.  */
   static int type_explicitly_set_p = 0;
   /* Indexed by enum debug_info_type.  */
-  static const char *debug_type_names[] =
+  static const char *const debug_type_names[] =
   {
     "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff"
   };
@@ -4279,7 +4022,7 @@ decode_g_option (arg)
          enum debug_info_type type = da->debug_type;
          const char *p = arg + da_len;
 
-         if (*p && (*p < '0' || *p > '9'))
+         if (*p && ! ISDIGIT (*p))
            continue;
 
          /* A debug flag without a level defaults to level 2.
@@ -4293,7 +4036,7 @@ decode_g_option (arg)
          if (*p)
            level = read_integral_parameter (p, 0, max_debug_level + 1);
          else
-           level = 2;
+           level = (level == 0) ? 2 : level;
 
          if (da_len > 1 && *p && !strncmp (arg, "dwarf", da_len))
            {
@@ -4422,9 +4165,9 @@ independent_decode_option (argc, argv)
       arg = argv[1];
       /* Look for the `='.  */
       equal = strchr (arg, '=');
-      if (!equal) 
+      if (!equal)
        error ("invalid --param option: %s", arg);
-      else 
+      else
        {
          int val;
 
@@ -4440,7 +4183,7 @@ independent_decode_option (argc, argv)
 
       return 2;
     }
-      
+
   if (*arg == 'Y')
     arg++;
 
@@ -4542,17 +4285,22 @@ independent_decode_option (argc, argv)
        }
       else if (!strncmp (arg, "aux-info", 8))
        {
-         flag_gen_aux_info = 1;
          if (arg[8] == '\0')
            {
              if (argc == 1)
                return 0;
 
              aux_info_file_name = argv[1];
+             flag_gen_aux_info = 1;
              return 2;
            }
+         else if (arg[8] == '=')
+           {
+             aux_info_file_name = arg + 9;
+             flag_gen_aux_info = 1;
+           }
          else
-           aux_info_file_name = arg + 8;
+           return 0;
        }
       else
        return 0;
@@ -4603,44 +4351,247 @@ independent_decode_option (argc, argv)
   return 1;
 }
 \f
-/* 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.
-   
-   It is not safe to call this function more than once.  */
+/* Decode -m switches.  */
+/* Decode the switch -mNAME.  */
 
-int
-toplev_main (argc, argv)
-     int argc;
-     char **argv;
+static void
+set_target_switch (name)
+     const char *name;
 {
-  register int i;
-  char *p;
-
-  /* save in case md file wants to emit args as a comment.  */
-  save_argc = argc;
-  save_argv = argv;
+  size_t j;
+  int valid_target_option = 0;
 
-  p = argv[0] + strlen (argv[0]);
-  while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
-    --p;
-  progname = p;
+  for (j = 0; j < ARRAY_SIZE (target_switches); j++)
+    if (!strcmp (target_switches[j].name, name))
+      {
+       if (target_switches[j].value < 0)
+         target_flags &= ~-target_switches[j].value;
+       else
+         target_flags |= target_switches[j].value;
+       valid_target_option = 1;
+      }
 
-  xmalloc_set_program_name (progname);
+#ifdef TARGET_OPTIONS
+  if (!valid_target_option)
+    for (j = 0; j < ARRAY_SIZE (target_options); j++)
+      {
+       int len = strlen (target_options[j].prefix);
+       if (!strncmp (target_options[j].prefix, name, len))
+         {
+           *target_options[j].variable = name + len;
+           valid_target_option = 1;
+         }
+      }
+#endif
 
-/* LC_CTYPE determines the character set used by the terminal so it has be set
-   to output messages correctly.  */
+  if (!valid_target_option)
+    error ("Invalid option `%s'", name);
+}
+\f
+/* Print version information to FILE.
+   Each line begins with INDENT (for the case where FILE is the
+   assembler output file).  */
 
-#ifdef HAVE_LC_MESSAGES
-  setlocale (LC_CTYPE, "");
-  setlocale (LC_MESSAGES, "");
+static void
+print_version (file, indent)
+     FILE *file;
+     const char *indent;
+{
+#ifndef __VERSION__
+#define __VERSION__ "[?]"
+#endif
+  fnotice (file,
+#ifdef __GNUC__
+          "%s%s%s version %s (%s)\n%s\tcompiled by GNU C version %s.\n"
 #else
-  setlocale (LC_ALL, "");
+          "%s%s%s version %s (%s) compiled by CC.\n"
+#endif
+          , indent, *indent != 0 ? " " : "",
+          lang_hooks.name, version_string, TARGET_NAME,
+          indent, __VERSION__);
+}
+
+/* Print an option value and return the adjusted position in the line.
+   ??? We don't handle error returns from fprintf (disk full); presumably
+   other code will catch a disk full though.  */
+
+static int
+print_single_switch (file, pos, max, indent, sep, term, type, name)
+     FILE *file;
+     int pos, max;
+     const 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 + len > max)
+    {
+      fprintf (file, "%s", term);
+      pos = 0;
+    }
+  if (pos == 0)
+    {
+      fprintf (file, "%s", indent);
+      pos = strlen (indent);
+    }
+  fprintf (file, "%s%s%s", sep, type, name);
+  pos += len;
+  return pos;
+}
+
+/* Print active target switches to FILE.
+   POS is the current cursor position and MAX is the size of a "line".
+   Each line begins with INDENT and ends with TERM.
+   Each switch is separated from the next by SEP.  */
+
+static void
+print_switch_values (file, pos, max, indent, sep, term)
+     FILE *file;
+     int pos, max;
+     const char *indent, *sep, *term;
+{
+  size_t j;
+  char **p;
+
+  /* Print the options as passed.  */
+
+  pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term,
+                            _("options passed: "), "");
+
+  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)
+         continue;
+       if ((*p)[1] == 'd')
+         continue;
+
+       pos = print_single_switch (file, pos, max, indent, sep, term, *p, "");
+      }
+  if (pos > 0)
+    fprintf (file, "%s", term);
+
+  /* Print the -f and -m options that have been enabled.
+     We don't handle language specific options but printing argv
+     should suffice.  */
+
+  pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term,
+                            _("options enabled: "), "");
+
+  for (j = 0; j < ARRAY_SIZE (f_options); j++)
+    if (*f_options[j].variable == f_options[j].on_value)
+      pos = print_single_switch (file, pos, max, indent, sep, term,
+                                "-f", f_options[j].string);
+
+  /* Print target specific options.  */
+
+  for (j = 0; j < ARRAY_SIZE (target_switches); j++)
+    if (target_switches[j].name[0] != '\0'
+       && target_switches[j].value > 0
+       && ((target_switches[j].value & target_flags)
+           == target_switches[j].value))
+      {
+       pos = print_single_switch (file, pos, max, indent, sep, term,
+                                  "-m", target_switches[j].name);
+      }
+
+#ifdef TARGET_OPTIONS
+  for (j = 0; j < ARRAY_SIZE (target_options); j++)
+    if (*target_options[j].variable != NULL)
+      {
+       char prefix[256];
+       sprintf (prefix, "-m%s", target_options[j].prefix);
+       pos = print_single_switch (file, pos, max, indent, sep, term,
+                                  prefix, *target_options[j].variable);
+      }
+#endif
+
+  fprintf (file, "%s", term);
+}
+\f
+/* Open assembly 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.  NAME is the file specified on
+   the command line, possibly NULL.  */
+static void
+init_asm_output (name)
+     const char *name;
+{
+  if (name == NULL && 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);
+    }
+
+#ifdef IO_BUFFER_SIZE
+  setvbuf (asm_out_file, (char *) xmalloc (IO_BUFFER_SIZE),
+           _IOFBF, IO_BUFFER_SIZE);
 #endif
 
-  (void) bindtextdomain (PACKAGE, localedir);
-  (void) textdomain (PACKAGE);
+  if (!flag_syntax_only)
+    {
+#ifdef ASM_FILE_START
+      ASM_FILE_START (asm_out_file);
+#endif
+
+#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,
+                              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
+    }
+}
+\f
+/* Initialization of the front end environment, before command line
+   options are parsed.  Signal handlers, internationalization etc.
+   ARGV0 is main's argv[0].  */
+static void
+general_init (argv0)
+     char *argv0;
+{
+  char *p;
+
+  p = argv0 + strlen (argv0);
+  while (p != argv0 && !IS_DIR_SEPARATOR (p[-1]))
+    --p;
+  progname = p;
+
+  xmalloc_set_program_name (progname);
+
+  gcc_init_libintl ();
 
   /* Install handler for SIGFPE, which may be received while we do
      compile-time floating point arithmetic.  */
@@ -4663,32 +4614,34 @@ toplev_main (argc, argv)
   signal (SIGIOT, crash_signal);
 #endif
 
-  decl_printable_name = decl_name;
-  lang_expand_expr = (lang_expand_expr_t) do_abort;
-
-  /* Initialize whether `char' is signed.  */
-  flag_signed_char = DEFAULT_SIGNED_CHAR;
-#ifdef DEFAULT_SHORT_ENUMS
-  /* Initialize how much space enums occupy, by default.  */
-  flag_short_enums = DEFAULT_SHORT_ENUMS;
-#endif
+  /* Initialize the diagnostics reporting machinery, so option parsing
+     can give warnings and errors.  */
+  diagnostic_initialize (global_dc);
+}
+\f
+/* Parse command line options and set default flag values, called
+   after language-independent option-independent intialization.  Do
+   minimal options processing.  Outputting diagnostics is OK, but GC
+   and identifier hashtables etc. are not initialized yet.  */
+static void
+parse_options_and_default_flags (argc, argv)
+     int argc;
+     char **argv;
+{
+  int i;
 
-  /* Initialize the garbage-collector.  */
-  init_ggc ();
-  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);
+  /* Save in case md file wants to emit args as a comment.  */
+  save_argc = argc;
+  save_argv = argv;
 
-  /* Initialize the diagnostics reporting machinery.  */
-  initialize_diagnostics ();
+  /* Initialize register usage now so switches may override.  */
+  init_reg_sets ();
 
   /* Register the language-independent parameters.  */
   add_params (lang_independent_params, LAST_PARAM);
 
-  /* Perform language-specific options intialization.  */
-  if (lang_hooks.init_options)
-    (*lang_hooks.init_options) ();
+  /* Perform language-specific options initialization.  */
+  (*lang_hooks.init_options) ();
 
   /* Scan to see what optimization level has been specified.  That will
      determine the default value of many flags.  */
@@ -4723,6 +4676,11 @@ toplev_main (argc, argv)
        }
     }
 
+  if (!optimize)
+    {
+      flag_merge_constants = 0;
+    }
+
   if (optimize >= 1)
     {
       flag_defer_pop = 1;
@@ -4773,6 +4731,13 @@ toplev_main (argc, argv)
       align_functions = 1;
     }
 
+  /* Initialize whether `char' is signed.  */
+  flag_signed_char = DEFAULT_SIGNED_CHAR;
+#ifdef DEFAULT_SHORT_ENUMS
+  /* Initialize how much space enums occupy, by default.  */
+  flag_short_enums = DEFAULT_SHORT_ENUMS;
+#endif
+
   /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
      modify it.  */
   target_flags = 0;
@@ -4789,9 +4754,6 @@ toplev_main (argc, argv)
   OPTIMIZATION_OPTIONS (optimize, optimize_size);
 #endif
 
-  /* Initialize register usage now so switches may override.  */
-  init_reg_sets ();
-
   /* Perform normal command line switch decoding.  */
   for (i = 1; i < argc;)
     {
@@ -4858,15 +4820,13 @@ toplev_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 ();
-
+  (*lang_hooks.post_options) ();
+}
+\f
+/* Process the options that have been parsed.  */
+static void
+process_options ()
+{
   /* Checker uses the frame pointer.  */
   if (flag_check_memory_usage)
     flag_omit_frame_pointer = 0;
@@ -4885,6 +4845,12 @@ toplev_main (argc, argv)
        warning ("-Wuninitialized is not supported without -O");
     }
 
+  /* We do not currently support sibling-call optimization in the
+     presence of exceptions.  See PR2975 for a test-case that will
+     fail if we try to combine both of these features.  */
+  if (flag_exceptions)
+    flag_optimize_sibling_calls = 0;
+
 #ifdef OVERRIDE_OPTIONS
   /* Some machines may reject certain combinations of options.  */
   OVERRIDE_OPTIONS;
@@ -4893,11 +4859,17 @@ toplev_main (argc, argv)
   /* Set up the align_*_log variables, defaulting them to 1 if they
      were still unset.  */
   if (align_loops <= 0) align_loops = 1;
+  if (align_loops_max_skip > align_loops || !align_loops)
+    align_loops_max_skip = align_loops - 1;
   align_loops_log = floor_log2 (align_loops * 2 - 1);
   if (align_jumps <= 0) align_jumps = 1;
+  if (align_jumps_max_skip > align_jumps || !align_jumps)
+    align_jumps_max_skip = align_jumps - 1;
   align_jumps_log = floor_log2 (align_jumps * 2 - 1);
   if (align_labels <= 0) align_labels = 1;
   align_labels_log = floor_log2 (align_labels * 2 - 1);
+  if (align_labels_max_skip > align_labels || !align_labels)
+    align_labels_max_skip = align_labels - 1;
   if (align_functions <= 0) align_functions = 1;
   align_functions_log = floor_log2 (align_functions * 2 - 1);
 
@@ -4921,6 +4893,11 @@ toplev_main (argc, argv)
       flag_rerun_cse_after_loop = 1;
     }
 
+  if (flag_non_call_exceptions)
+    flag_asynchronous_unwind_tables = 1;
+  if (flag_asynchronous_unwind_tables)
+    flag_unwind_tables = 1;
+
   /* Warn about options that are not supported on this machine.  */
 #ifndef INSN_SCHEDULING
   if (flag_schedule_insns || flag_schedule_insns_after_reload)
@@ -4931,6 +4908,16 @@ toplev_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)
     {
@@ -4955,293 +4942,276 @@ toplev_main (argc, argv)
        print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n");
     }
 
-  compile_file (filename);
-
-  if (errorcount)
-    return (FATAL_EXIT_CODE);
-  if (sorrycount)
-    return (FATAL_EXIT_CODE);
-  return (SUCCESS_EXIT_CODE);
-}
-\f
-/* Decode -m switches.  */
-/* Decode the switch -mNAME.  */
-
-static void
-set_target_switch (name)
-     const char *name;
-{
-  register size_t j;
-  int valid_target_option = 0;
+  if (! quiet_flag)
+    time_report = 1;
 
-  for (j = 0; j < ARRAY_SIZE (target_switches); j++)
-    if (!strcmp (target_switches[j].name, name))
-      {
-       if (target_switches[j].value < 0)
-         target_flags &= ~-target_switches[j].value;
-       else
-         target_flags |= target_switches[j].value;
-       valid_target_option = 1;
-      }
+  if (flag_syntax_only)
+    {
+      write_symbols = NO_DEBUG;
+      profile_flag = 0;
+      profile_block_flag = 0;
+    }
 
-#ifdef TARGET_OPTIONS
-  if (!valid_target_option)
-    for (j = 0; j < ARRAY_SIZE (target_options); j++)
-      {
-       int len = strlen (target_options[j].prefix);
-       if (!strncmp (target_options[j].prefix, name, len))
-         {
-           *target_options[j].variable = name + len;
-           valid_target_option = 1;
-         }
-      }
+  /* Now we know write_symbols, set up the debug hooks based on it.
+     By default we do nothing for debug output.  */
+#if defined(DBX_DEBUGGING_INFO)
+  if (write_symbols == DBX_DEBUG)
+    debug_hooks = &dbx_debug_hooks;
 #endif
-
-  if (!valid_target_option)
-    error ("Invalid option `%s'", name);
-}
-\f
-/* Print version information to FILE.
-   Each line begins with INDENT (for the case where FILE is the
-   assembler output file).  */
-
-static void
-print_version (file, indent)
-     FILE *file;
-     const char *indent;
-{
-#ifndef __VERSION__
-#define __VERSION__ "[?]"
+#if defined(XCOFF_DEBUGGING_INFO)
+  if (write_symbols == XCOFF_DEBUG)
+    debug_hooks = &xcoff_debug_hooks;
 #endif
-  fnotice (file,
-#ifdef __GNUC__
-          "%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"
+#ifdef SDB_DEBUGGING_INFO
+  if (write_symbols == SDB_DEBUG)
+    debug_hooks = &sdb_debug_hooks;
+#endif
+#ifdef DWARF_DEBUGGING_INFO
+  if (write_symbols == DWARF_DEBUG)
+    debug_hooks = &dwarf_debug_hooks;
+#endif
+#ifdef DWARF2_DEBUGGING_INFO
+  if (write_symbols == DWARF2_DEBUG)
+    debug_hooks = &dwarf2_debug_hooks;
 #endif
-          , indent, *indent != 0 ? " " : "",
-          language_string, version_string, TARGET_NAME,
-          indent, __VERSION__);
-}
-
-/* Print an option value and return the adjusted position in the line.
-   ??? We don't handle error returns from fprintf (disk full); presumably
-   other code will catch a disk full though.  */
-
-static int
-print_single_switch (file, pos, max, indent, sep, term, type, name)
-     FILE *file;
-     int pos, max;
-     const 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 + len > max)
+  /* If auxiliary info generation is desired, open the output file.
+     This goes in the same directory as the source file--unlike
+     all the other output files.  */
+  if (flag_gen_aux_info)
     {
-      fprintf (file, "%s", term);
-      pos = 0;
+      aux_info_file = fopen (aux_info_file_name, "w");
+      if (aux_info_file == 0)
+       fatal_io_error ("can't open %s", aux_info_file_name);
     }
-  if (pos == 0)
+
+  if (! targetm.have_named_sections)
     {
-      fprintf (file, "%s", indent);
-      pos = strlen (indent);
+      if (flag_function_sections)
+       {
+         warning ("-ffunction-sections not supported for this target.");
+         flag_function_sections = 0;
+       }
+      if (flag_data_sections)
+       {
+         warning ("-fdata-sections not supported for this target.");
+         flag_data_sections = 0;
+       }
     }
-  fprintf (file, "%s%s%s", sep, type, name);
-  pos += len;
-  return pos;
-}
 
-/* Print active target switches to FILE.
-   POS is the current cursor position and MAX is the size of a "line".
-   Each line begins with INDENT and ends with TERM.
-   Each switch is separated from the next by SEP.  */
+  if (flag_function_sections
+      && (profile_flag || profile_block_flag))
+    {
+      warning ("-ffunction-sections disabled; it makes profiling impossible.");
+      flag_function_sections = 0;
+    }
 
+#ifndef OBJECT_FORMAT_ELF
+  if (flag_function_sections && write_symbols != NO_DEBUG)
+    warning ("-ffunction-sections may affect debugging on some targets.");
+#endif
+}
+\f
+/* Language-independent initialization, before language-dependent
+   initialization.  */
 static void
-print_switch_values (file, pos, max, indent, sep, term)
-     FILE *file;
-     int pos, max;
-     const char *indent, *sep, *term;
+lang_independent_init ()
 {
-  size_t j;
-  char **p;
+  decl_printable_name = decl_name;
+  lang_expand_expr = (lang_expand_expr_t) do_abort;
 
-  /* Print the options as passed.  */
+  /* Set the language-dependent identifer size.  */
+  tree_code_length[(int) IDENTIFIER_NODE]
+    = ((lang_hooks.identifier_size - sizeof (struct tree_common))
+       / sizeof (tree));
 
-  pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term,
-                            _("options passed: "), "");
+  /* Initialize the garbage-collector, and string pools.  FIXME: We
+     should do this later, in independent_init () when we know we
+     actually want to compile something, but cpplib currently wants to
+     use the hash table immediately in cpp_create_reader.  */
+  init_ggc ();
+  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);
 
-  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)
-         continue;
-       if ((*p)[1] == 'd')
-         continue;
+  init_stringpool ();
+  init_obstacks ();
 
-       pos = print_single_switch (file, pos, max, indent, sep, term, *p, "");
-      }
-  if (pos > 0)
-    fprintf (file, "%s", term);
+  init_emit_once (debug_info_level == DINFO_LEVEL_NORMAL
+                 || debug_info_level == DINFO_LEVEL_VERBOSE
+                 || flag_test_coverage
+                 || warn_notreached);
+  init_regs ();
+  init_alias_once ();
+  init_stmt ();
+  init_loop ();
+  init_reload ();
+  init_function_once ();
+  init_stor_layout_once ();
+  init_varasm_once ();
+  init_EXPR_INSN_LIST_cache ();
 
-  /* Print the -f and -m options that have been enabled.
-     We don't handle language specific options but printing argv
-     should suffice.  */
+  /* The following initialization functions need to generate rtl, so
+     provide a dummy function context for them.  */
+  init_dummy_function_start ();
+  init_expmed ();
+  init_expr_once ();
+  if (flag_caller_saves)
+    init_caller_save ();
+  expand_dummy_function_end ();
+}
+\f
+/* Language-dependent initialization.  Returns non-zero on success.  */
+static int
+lang_dependent_init (name)
+     const char *name;
+{
+  if (dump_base_name == 0)
+    dump_base_name = name ? name : "gccdump";
 
-  pos = print_single_switch (file, 0, max, indent, *indent ? " " : "", term,
-                            _("options enabled: "), "");
+  /* Front-end initialization.  This hook can assume that GC,
+     identifier hashes etc. are set up, but debug initialization is
+     not done yet.  This routine must return the original filename
+     (e.g. foo.i -> foo.c) so can correctly initialize debug output.  */
+  name = (*lang_hooks.init) (name);
+  if (name == NULL)
+    return 0;
 
-  for (j = 0; j < ARRAY_SIZE (f_options); j++)
-    if (*f_options[j].variable == f_options[j].on_value)
-      pos = print_single_switch (file, pos, max, indent, sep, term,
-                                "-f", f_options[j].string);
+  /* Is this duplication necessary?  */
+  name = ggc_strdup (name);
+  main_input_filename = input_filename = name;
+  init_asm_output (name);
 
-  /* Print target specific options.  */
+  /* These create various _DECL nodes, so need to be called after the
+     front end is initialized.  */
+  init_eh ();
+  init_optabs ();
 
-  for (j = 0; j < ARRAY_SIZE (target_switches); j++)
-    if (target_switches[j].name[0] != '\0'
-       && target_switches[j].value > 0
-       && ((target_switches[j].value & target_flags)
-           == target_switches[j].value))
-      {
-       pos = print_single_switch (file, pos, max, indent, sep, term,
-                                  "-m", target_switches[j].name);
-      }
+  /* Put an entry on the input file stack for the main input file.  */
+  push_srcloc (input_filename, 0);
 
-#ifdef TARGET_OPTIONS
-  for (j = 0; j < ARRAY_SIZE (target_options); j++)
-    if (*target_options[j].variable != NULL)
-      {
-       char prefix[256];
-       sprintf (prefix, "-m%s", target_options[j].prefix);
-       pos = print_single_switch (file, pos, max, indent, sep, term,
-                                  prefix, *target_options[j].variable);
-      }
+  /* If dbx symbol table desired, initialize writing it and output the
+     predefined types.  */
+  timevar_push (TV_SYMOUT);
+
+#ifdef DWARF2_UNWIND_INFO
+  if (dwarf2out_do_frame ())
+    dwarf2out_frame_init ();
 #endif
 
-  fprintf (file, "%s", term);
-}
+  /* Now we have the correct original filename, we can initialize
+     debug output.  */
+  (*debug_hooks->init) (name);
 
-/* Record the beginning of a new source file, named FILENAME.  */
+  timevar_pop (TV_SYMOUT);
 
-void
-debug_start_source_file (filename)
-     register const char *filename ATTRIBUTE_UNUSED;
-{
-#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 (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
+  return 1;
 }
+\f
+/* Clean up: close opened files, etc.  */
 
-/* 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 ATTRIBUTE_UNUSED;
+static void
+finalize ()
 {
-#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 (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
-}
+  /* Close the dump files.  */
+  if (flag_gen_aux_info)
+    {
+      fclose (aux_info_file);
+      if (errorcount)
+       unlink (aux_info_file_name);
+    }
 
-/* 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.  */
+  /* 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.  */
 
-void
-debug_define (lineno, buffer)
-     register unsigned lineno ATTRIBUTE_UNUSED;
-     register const char *buffer ATTRIBUTE_UNUSED;
-{
-#ifdef DWARF_DEBUGGING_INFO
-  if (write_symbols == DWARF_DEBUG)
-    dwarfout_define (lineno, buffer);
-#endif /* DWARF_DEBUGGING_INFO  */
-#ifdef DWARF2_DEBUGGING_INFO
-  if (write_symbols == DWARF2_DEBUG)
-    dwarf2out_define (lineno, buffer);
-#endif /* DWARF2_DEBUGGING_INFO  */
-}
+  if (asm_out_file)
+    {
+      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);
+    }
 
-/* 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.  */
+  /* Do whatever is necessary to finish printing the graphs.  */
+  if (graph_dump_format != no_graph)
+    {
+      int i;
 
-void
-debug_undef (lineno, buffer)
-     register unsigned lineno ATTRIBUTE_UNUSED;
-     register const char *buffer ATTRIBUTE_UNUSED;
-{
-#ifdef DWARF_DEBUGGING_INFO
-  if (write_symbols == DWARF_DEBUG)
-    dwarfout_undef (lineno, buffer);
-#endif /* DWARF_DEBUGGING_INFO  */
-#ifdef DWARF2_DEBUGGING_INFO
-  if (write_symbols == DWARF2_DEBUG)
-    dwarf2out_undef (lineno, buffer);
-#endif /* DWARF2_DEBUGGING_INFO  */
+      for (i = 0; i < (int) DFI_MAX; ++i)
+       if (dump_file[i].initialized && dump_file[i].graph_dump_p)
+         {
+           char seq[16];
+           char *suffix;
+
+           sprintf (seq, ".%02d.", i);
+           suffix = concat (seq, dump_file[i].extension, NULL);
+           finish_graph_dump_file (dump_base_name, suffix);
+           free (suffix);
+         }
+    }
+
+  if (mem_report)
+    {
+      ggc_print_statistics ();
+      stringpool_statistics ();
+      dump_tree_statistics ();
+    }
+
+  /* Free up memory for the benefit of leak detectors.  */
+  free_reg_info ();
+
+  /* Language-specific end of compilation actions.  */
+  (*lang_hooks.finish) ();
 }
+\f
+/* 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.
 
-/* Returns nonzero if it is appropriate not to emit any debugging
-   information for BLOCK, because it doesn't contain any instructions.
-   This may not be the case for blocks containing nested functions, since
-   we may actually call such a function even though the BLOCK information
-   is messed up.  */
+   It is not safe to call this function more than once.  */
 
 int
-debug_ignore_block (block)
-     tree block ATTRIBUTE_UNUSED;
+toplev_main (argc, argv)
+     int argc;
+     char **argv;
 {
-  /* Never delete the BLOCK for the outermost scope
-     of the function; we can refer to names from
-     that scope even if the block notes are messed up.  */
-  if (is_body_block (block))
-    return 0;
+  /* Initialization of GCC's environment, and diagnostics.  */
+  general_init (argv [0]);
 
-#ifdef DWARF2_DEBUGGING_INFO
-  if (write_symbols == DWARF2_DEBUG)
-    return dwarf2out_ignore_block (block);
-#endif
+  /* Parse the options and do minimal processing; basically just
+     enough to default flags appropriately.  */
+  parse_options_and_default_flags (argc, argv);
 
-  return 1;
+  /* Exit early if we can (e.g. -help).  */
+  if (exit_after_options)
+    return (SUCCESS_EXIT_CODE);
+
+  /* The bulk of command line switch processing.  */
+  process_options ();
+
+  /* We cannot start timing until after options are processed since that
+     says if we run timers or not.  */
+  init_timevar ();
+  timevar_start (TV_TOTAL);
+
+  /* Language-independent initialization.  Also sets up GC, identifier
+     hashes etc.  */
+  lang_independent_init ();
+
+  /* Language-dependent initialization.  Returns true on success.  */
+  if (lang_dependent_init (filename))
+    compile_file ();
+
+  finalize ();
+
+  /* Stop timing and print the times.  */
+  timevar_stop (TV_TOTAL);
+  timevar_print (stderr);
+
+  if (errorcount || sorrycount)
+    return (FATAL_EXIT_CODE);
+
+  return (SUCCESS_EXIT_CODE);
 }