OSDN Git Service

Patches from David Mosberger, and a patch to make bootstrap work.
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index 55c48da..1a35497 100644 (file)
@@ -1,5 +1,6 @@
 /* Top level of GNU C compiler
-   Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+   1999, 2000 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -56,6 +57,14 @@ Boston, MA 02111-1307, USA.  */
 #include "basic-block.h"
 #include "intl.h"
 #include "ggc.h"
+#include "graph.h"
+#include "loop.h"
+#include "regs.h"
+#include "timevar.h"
+
+#ifndef ACCUMULATE_OUTGOING_ARGS
+#define ACCUMULATE_OUTGOING_ARGS 0
+#endif
 
 #ifdef DWARF_DEBUGGING_INFO
 #include "dwarfout.h"
@@ -135,14 +144,9 @@ You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
 #define PREFERRED_DEBUGGING_TYPE NO_DEBUG
 #endif
 
-#ifndef DIR_SEPARATOR
-#define DIR_SEPARATOR '/'
-#endif
-
-#if ! (defined (VMS) || defined (OS2))
+#ifdef NEED_DECLARATION_ENVIRON
 extern char **environ;
 #endif
-extern char *version_string;
 
 /* Carry information from ASM_DECLARE_OBJECT_NAME
    to ASM_FINISH_DECLARE_OBJECT.  */
@@ -150,63 +154,33 @@ extern char *version_string;
 extern int size_directive_output;
 extern tree last_assemble_variable_decl;
 
-static void notice PVPROTO((const char *s, ...)) ATTRIBUTE_PRINTF_1;
-static void set_target_switch PROTO((const char *));
-static const char *decl_name PROTO((tree, int));
-static void vmessage PROTO((const char *, const char *, va_list));
-static void v_message_with_file_and_line PROTO((const char *, int, int,
-                                               const char *, va_list));
-static void v_message_with_decl PROTO((tree, int, const char *, va_list));
-static void file_and_line_for_asm PROTO((rtx, char **, int *));
-static void v_error_with_file_and_line PROTO((const char *, int,
-                                             const char *, va_list));
-static void v_error_with_decl PROTO((tree, const char *, va_list));
-static void v_error_for_asm PROTO((rtx, const char *, va_list));
-static void verror PROTO((const char *, va_list));
-static void vfatal PROTO((const char *, va_list)) ATTRIBUTE_NORETURN;
-static void v_warning_with_file_and_line PROTO ((const char *, int,
-                                                const char *, va_list));
-static void v_warning_with_decl PROTO((tree, const char *, va_list));
-static void v_warning_for_asm PROTO((rtx, const char *, va_list));
-static void vwarning PROTO((const char *, va_list));
-static void vpedwarn PROTO((const char *, va_list));
-static void v_pedwarn_with_decl PROTO((tree, const char *, va_list));
-static void v_pedwarn_with_file_and_line PROTO((const char *, int,
-                                               const char *, va_list));
-static void vsorry PROTO((const char *, va_list));
-extern void set_fatal_function PROTO((void (*)(const char *, va_list)));
-static void float_signal PROTO((int)) ATTRIBUTE_NORETURN;
-static void pipe_closed PROTO((int)) ATTRIBUTE_NORETURN;
+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 pipe_closed PARAMS ((int)) ATTRIBUTE_NORETURN;
 #ifdef ASM_IDENTIFY_LANGUAGE
 /* This might or might not be used in ASM_IDENTIFY_LANGUAGE. */
-static void output_lang_identify PROTO((FILE *)) ATTRIBUTE_UNUSED;
+static void output_lang_identify PARAMS ((FILE *)) ATTRIBUTE_UNUSED;
 #endif
-static void open_dump_file PROTO((const char *, const char *));
-static void close_dump_file PROTO((void (*) (FILE *, rtx), rtx));
-static void dump_rtl PROTO((const char *, tree, void (*) (FILE *, rtx), rtx));
-static void clean_dump_file PROTO((const char *));
-static void compile_file PROTO((char *));
-static void display_help PROTO ((void));
-static void report_file_and_line PROTO ((const char *, int, int));
-static void vnotice PROTO ((FILE *, const char *, va_list));
-static void mark_file_stack PROTO ((void *));
-
-static void decode_d_option PROTO ((const char *));
-static int  decode_f_option PROTO ((const char *));
-static int  decode_W_option PROTO ((const char *));
-static int  decode_g_option PROTO ((const char *));
-static unsigned independent_decode_option PROTO ((int, char **, unsigned));
-
-static void print_version PROTO((FILE *, const char *));
-static int print_single_switch PROTO((FILE *, int, int, const char *,
+static void compile_file PARAMS ((char *));
+static void display_help PARAMS ((void));
+static void mark_file_stack PARAMS ((void *));
+
+static void decode_d_option PARAMS ((const char *));
+static int decode_f_option PARAMS ((const char *));
+static int decode_W_option PARAMS ((const char *));
+static int decode_g_option PARAMS ((const char *));
+static unsigned int independent_decode_option PARAMS ((int, char **,
+                                                      unsigned int));
+
+static void print_version PARAMS ((FILE *, const char *));
+static int print_single_switch PARAMS ((FILE *, int, int, const char *,
                                      const char *, const char *,
                                      const char *, const char *));
-static void print_switch_values PROTO((FILE *, int, int, const char *,
+static void print_switch_values PARAMS ((FILE *, int, int, const char *,
                                       const char *, const char *));
 
-void print_rtl_graph_with_bb PROTO ((const char *, const char *, rtx));
-void clean_graph_dump_file PROTO ((const char *, const char *));
-void finish_graph_dump_file PROTO ((const char *, const char *));
 /* Length of line when printing switch values.  */
 #define MAX_LINE 75
 
@@ -253,40 +227,113 @@ const char *dump_base_name;
 
 extern int target_flags;
 
-/* Flags saying which kinds of debugging dump have been requested.  */
-
-int rtl_dump = 0;
-int rtl_dump_and_exit = 0;
-int jump_opt_dump = 0;
-int addressof_dump = 0;
-int cse_dump = 0;
-int gcse_dump = 0;
-int loop_dump = 0;
-int cse2_dump = 0;
-int branch_prob_dump = 0;
-int flow_dump = 0;
-int combine_dump = 0;
-int regmove_dump = 0;
-int sched_dump = 0;
-int local_reg_dump = 0;
-int global_reg_dump = 0;
-int flow2_dump = 0;
-int peephole2_dump = 0;
-int sched2_dump = 0;
-int jump2_opt_dump = 0;
-#ifdef DELAY_SLOTS
-int dbr_sched_dump = 0;
-#endif
-int flag_print_asm_name = 0;
-#ifdef STACK_REGS
-int stack_reg_dump = 0;
-#endif
-#ifdef MACHINE_DEPENDENT_REORG
-int mach_dep_reorg_dump = 0;
-#endif
-static int flag_print_mem = 0;
-static int version_flag = 0;
-static char * filename = 0;
+/* Describes a dump file.  */
+
+struct dump_file_info
+{
+  /* The unique extension to apply, e.g. ".jump".  */
+  const char * const extension;
+
+  /* The -d<c> character that enables this dump file.  */
+  char const debug_switch;
+
+  /* True if there is a corresponding graph dump file.  */
+  char const graph_dump_p;
+
+  /* True if the user selected this dump.  */
+  char enabled;
+
+  /* True if the files have been initialized (ie truncated).  */
+  char initialized;
+};
+
+/* Enumerate the extant dump files.  */
+
+enum dump_file_index
+{
+  DFI_rtl,
+  DFI_sibling,
+  DFI_jump,
+  DFI_cse,
+  DFI_addressof,
+  DFI_ssa,
+  DFI_ussa,
+  DFI_gcse,
+  DFI_loop,
+  DFI_cse2,
+  DFI_bp,
+  DFI_flow,
+  DFI_combine,
+  DFI_ce,
+  DFI_regmove,
+  DFI_sched,
+  DFI_lreg,
+  DFI_greg,
+  DFI_flow2,
+  DFI_ce2,
+  DFI_peephole2,
+  DFI_sched2,
+  DFI_bbro,
+  DFI_rnreg,
+  DFI_jump2,
+  DFI_mach,
+  DFI_dbr,
+  DFI_stack,
+  DFI_MAX
+};
+
+/* Describes all the dump files.  Should be kept in order of the
+   pass and in sync with dump_file_index above.
+
+   Remaining -d letters:
+
+       "       h      o q   u     "
+       "       H  K   OPQ  TUVWXYZ"
+*/
+
+struct dump_file_info dump_file[DFI_MAX] = 
+{
+  { "rtl",     'r', 0, 0, 0 },
+  { "sibling",  'i', 0, 0, 0 },
+  { "jump",    'j', 0, 0, 0 },
+  { "cse",     's', 0, 0, 0 },
+  { "addressof", 'F', 0, 0, 0 },
+  { "ssa",     'e', 1, 0, 0 },
+  { "ussa",    'e', 1, 0, 0 }, /* Yes, duplicate enable switch.  */
+  { "gcse",    'G', 1, 0, 0 },
+  { "loop",    'L', 1, 0, 0 },
+  { "cse2",    't', 1, 0, 0 },
+  { "bp",      'b', 1, 0, 0 },
+  { "flow",    'f', 1, 0, 0 },
+  { "combine", 'c', 1, 0, 0 },
+  { "ce",      'C', 1, 0, 0 },
+  { "regmove", 'N', 1, 0, 0 },
+  { "sched",   'S', 1, 0, 0 },
+  { "lreg",    'l', 1, 0, 0 },
+  { "greg",    'g', 1, 0, 0 },
+  { "flow2",   'w', 1, 0, 0 },
+  { "ce2",     'E', 1, 0, 0 },
+  { "peephole2", 'z', 1, 0, 0 },
+  { "sched2",  'R', 1, 0, 0 },
+  { "bbro",    'B', 1, 0, 0 },
+  { "rnreg",   'n', 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));
+static void close_dump_file PARAMS ((enum dump_file_index,
+                                    void (*) (FILE *, rtx), rtx));
+
+/* Other flags saying which kinds of debugging dump have been requested.  */
+
+int rtl_dump_and_exit;
+int flag_print_asm_name;
+static int flag_print_mem;
+static int version_flag;
+static char * filename;
 enum graph_dump_types graph_dump_format;
 
 /* Name for output file of assembly code, specified with -o.  */
@@ -334,6 +381,14 @@ int errorcount = 0;
 int warningcount = 0;
 int sorrycount = 0;
 
+/* The FUNCTION_DECL for the function currently being compiled,
+   or 0 if between functions.  */
+tree current_function_decl;
+
+/* Set to the FUNC_BEGIN label of the current function, or NULL_TREE
+   if none.  */
+tree current_function_func_begin_label;
+
 /* Pointer to function to compute the name to use to print a declaration.
    DECL is the declaration in question.
    VERBOSITY determines what information will be printed:
@@ -342,22 +397,22 @@ int sorrycount = 0;
      2: and any other information that might be interesting, such as function
         parameter types in C++.  */
 
-const char *(*decl_printable_name)     PROTO ((tree, int));
+const char *(*decl_printable_name)     PARAMS ((tree, int));
 
 /* Pointer to function to compute rtl for a language-specific tree code.  */
 
 typedef rtx (*lang_expand_expr_t)
-  PROTO ((union tree_node *, rtx, enum machine_mode,
+  PARAMS ((union tree_node *, rtx, enum machine_mode,
          enum expand_modifier modifier));
 
 lang_expand_expr_t lang_expand_expr = 0;
 
-tree (*lang_expand_constant) PROTO((tree)) = 0;
+tree (*lang_expand_constant) PARAMS ((tree)) = 0;
 
 /* Pointer to function to finish handling an incomplete decl at the
    end of compilation.  */
 
-void (*incomplete_decl_finalize_hook) PROTO((tree)) = 0;
+void (*incomplete_decl_finalize_hook) PARAMS ((tree)) = 0;
 
 /* Nonzero if generating code to do profiling.  */
 
@@ -379,6 +434,14 @@ int flag_test_coverage = 0;
 
 int flag_branch_probabilities = 0;
 
+/* Nonzero if basic blocks should be reordered. */
+
+int flag_reorder_blocks = 0;
+
+/* Nonzero if registers should be renamed */
+
+int flag_rename_registers = 0;
+
 /* Nonzero for -pedantic switch: warn about anything
    that standard spec forbids.  */
 
@@ -389,11 +452,6 @@ int pedantic = 0;
 
 int in_system_header = 0;
 
-/* Nonzero means do stupid register allocation.
-   Currently, this is 1 if `optimize' is 0.  */
-
-int obey_regdecls = 0;
-
 /* Don't print functions as they are compiled and don't print
    times taken by the various passes.  -quiet.  */
 
@@ -537,6 +595,10 @@ int flag_no_peephole = 0;
 
 int flag_fast_math = 0;
 
+/* Nonzero allows GCC to optimize sibling and tail recursive calls.  */
+
+int flag_optimize_sibling_calls = 0;
+
 /* Nonzero means the front end generally wants `errno' maintained by math
    operations, like built-in SQRT, unless overridden by flag_fast_math.  */
 
@@ -635,6 +697,10 @@ int flag_exceptions;
 
 int flag_new_exceptions = 1;
 
+/* Nonzero means generate frame unwind info table when supported */
+
+int flag_unwind_tables = 0;
+
 /* Nonzero means don't place uninitialized global data in common storage
    by default.  */
 
@@ -711,6 +777,9 @@ int flag_gnu_linker = 0;
 int flag_gnu_linker = 1;
 #endif
 
+/* Enable SSA.  */
+int flag_ssa = 0;
+
 /* Tag all structures with __attribute__(packed) */
 int flag_pack_struct = 0;
 
@@ -718,6 +787,15 @@ int flag_pack_struct = 0;
    to be allocated dynamically.  */
 int flag_stack_check;
 
+/* When non-NULL, indicates that whenever space is allocated on the
+   stack, the resulting stack pointer must not pass this
+   address---that is, for stacks that grow downward, the stack pointer
+   must always be greater than or equal to this address; for stacks
+   that grow upward, the stack pointer must be less than this address.
+   At present, the rtx may be either a REG or a SYMBOL_REF, although
+   the support provided depends on the backend.  */
+rtx stack_limit_rtx;
+
 /* -fcheck-memory-usage causes extra code to be generated in order to check
    memory accesses.  This is used by a detector of bad memory accesses such
    as Checker.  */
@@ -754,6 +832,26 @@ int flag_no_ident = 0;
 /* This will perform a peephole pass before sched2. */
 int flag_peephole2 = 0;
 
+/* -fbounded-pointers causes gcc to compile pointers as composite
+   objects occupying three words: the pointer value, the base address
+   of the referent object, and the address immediately beyond the end
+   of the referent object.  The base and extent allow us to perform
+   runtime bounds checking.  -fbounded-pointers implies -fcheck-bounds.  */
+int flag_bounded_pointers = 0;
+
+/* -fcheck-bounds causes gcc to generate array bounds checks.
+   For C, C++: defaults to value of flag_bounded_pointers.
+   For ObjC: defaults to off.
+   For Java: defaults to on.
+   For Fortran: defaults to off.
+   For CHILL: defaults to off.  */
+int flag_bounds_check = 0;
+
+/* 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.  */
+int flag_renumber_insns = 1;
+
 /* Values of the -falign-* flags: how much to align labels in code. 
    0 means `use default', 1 means `don't align'.  
    For each variable, there is an _log variant which is the power
@@ -845,6 +943,8 @@ lang_independent_options f_options[] =
    "Defer popping functions args from stack until later" },
   {"omit-frame-pointer", &flag_omit_frame_pointer, 1,
    "When possible do not generate stack frames"},
+  {"optimize-sibling-calls", &flag_optimize_sibling_calls, 1,
+   "Optimize sibling and tail recursive calls" },
   {"cse-follow-jumps", &flag_cse_follow_jumps, 1,
    "When running CSE, follow jumps to their targets" },
   {"cse-skip-blocks", &flag_cse_skip_blocks, 1,
@@ -924,6 +1024,8 @@ lang_independent_options f_options[] =
    "Enable exception handling" },
   {"new-exceptions", &flag_new_exceptions, 1,
    "Use the new model for exception handling" },
+  {"unwind-tables", &flag_unwind_tables, 1,
+    "Just generate unwind tables for exception handling" },
   {"sjlj-exceptions", &exceptions_via_longjmp, 1,
    "Use setjmp/longjmp to handle exceptions" },
   {"asynchronous-exceptions", &asynchronous_exceptions, 1,
@@ -934,6 +1036,10 @@ lang_independent_options f_options[] =
    "Create data files needed by gcov" },
   {"branch-probabilities", &flag_branch_probabilities, 1,
    "Use profiling information for branch probabilities" },
+  {"reorder-blocks", &flag_reorder_blocks, 1,
+   "Reorder basic blocks to improve code placement" },
+  {"rename-registers", &flag_rename_registers, 1,
+   "Do the register renaming optimization pass"},
   {"fast-math", &flag_fast_math, 1,
    "Improve FP speed by violating ANSI & IEEE rules" },
   {"common", &flag_no_common, 0,
@@ -980,6 +1086,8 @@ lang_independent_options f_options[] =
    "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"},
+  {"ssa", &flag_ssa, 1,
+   "Enable SSA optimizations" },
   {"leading-underscore", &flag_leading_underscore, 1,
    "External symbols have a leading underscore" },
   {"ident", &flag_no_ident, 0,
@@ -987,7 +1095,11 @@ lang_independent_options f_options[] =
   { "peephole2", &flag_peephole2, 1,
     "Enables an rtl peephole pass run before sched2" },
   {"math-errno", &flag_errno_math, 1,
-   "Set errno after built-in math functions"}
+   "Set errno after built-in math functions"},
+  {"bounded-pointers", &flag_bounded_pointers, 1,
+   "Compile pointers as triples: value, base & end" },
+  {"bounds-check", &flag_bounds_check, 1,
+   "Generate code to check bounds before dereferencing pointers and arrays" }
 };
 
 #define NUM_ELEM(a)  (sizeof (a) / sizeof ((a)[0]))
@@ -1100,7 +1212,9 @@ documented_lang_options[] =
   { "-Wno-redundant-decls", "" },
   { "-Wsign-compare", "Warn about signed/unsigned comparisons" },
   { "-Wno-sign-compare", "" },
-  { "-Wunknown-pragmas", "Warn about unrecognised pragmas" },
+  { "-Wfloat-equal", "Warn about testing equality of floating point numbers" },
+  { "-Wno-float-equal", "" },
+  { "-Wunknown-pragmas", "Warn about unrecognized pragmas" },
   { "-Wno-unknown-pragmas", "" },
   { "-Wstrict-prototypes", "Warn about non-prototyped function decls" },
   { "-Wno-strict-prototypes", "" },
@@ -1210,14 +1324,14 @@ int warn_cast_align;
    characters.  The value N is in `id_clash_len'.  */
 
 int warn_id_clash;
-unsigned id_clash_len;
+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'.  */
  
 int warn_larger_than;
-unsigned larger_than_size;
+HOST_WIDE_INT larger_than_size;
 
 /* Nonzero means warn if inline function is too large.  */
 
@@ -1228,6 +1342,14 @@ int warn_inline;
 
 int warn_aggregate_return;
 
+/* Warn if packed attribute on struct is unnecessary and inefficient.  */
+
+int warn_packed;
+
+/* Warn when gcc pads a structure to an alignment boundary.  */
+
+int warn_padded;
+
 /* Likewise for -W.  */
 
 lang_independent_options W_options[] =
@@ -1246,7 +1368,11 @@ lang_independent_options W_options[] =
   {"uninitialized", &warn_uninitialized, 1,
    "Warn about unitialized automatic variables"},
   {"inline", &warn_inline, 1,
-   "Warn when an inlined function cannot be inlined"}
+   "Warn when an inlined function cannot be inlined"},
+  {"packed", &warn_packed, 1,
+   "Warn when the packed attribute has no effect on struct layout"},
+  {"padded", &warn_padded, 1,
+   "Warn when padding is required to align struct members"}
 };
 \f
 /* Output files for assembler code (real compiler output)
@@ -1287,166 +1413,7 @@ read_integral_parameter (p, pname, defval)
   return atoi (p);
 }
 
-
-/* Time accumulators, to count the total time spent in various passes.  */
-
-int parse_time;
-int varconst_time;
-int integration_time;
-int jump_time;
-int cse_time;
-int gcse_time;
-int loop_time;
-int cse2_time;
-int branch_prob_time;
-int flow_time;
-int combine_time;
-int regmove_time;
-int sched_time;
-int local_alloc_time;
-int global_alloc_time;
-int flow2_time;
-int sched2_time;
-#ifdef DELAY_SLOTS
-int dbr_sched_time;
-#endif
-int shorten_branch_time;
-int stack_reg_time;
-int final_time;
-int symout_time;
-int dump_time;
-int gc_time;
-int all_time;
 \f
-/* Return time used so far, in microseconds.  */
-
-long
-get_run_time ()
-{
-  if (quiet_flag)
-    return 0;
-
-#ifdef __BEOS__
-  return 0;
-#else /* not BeOS */
-#if defined (_WIN32) && !defined (__CYGWIN__)
-  if (clock() < 0)
-    return 0;
-  else
-    return (clock() * 1000);
-#else /* not _WIN32 */
-#ifdef _SC_CLK_TCK
-  {
-    static int tick;
-    struct tms tms;
-    if (tick == 0)
-      tick = 1000000 / sysconf(_SC_CLK_TCK);
-    times (&tms);
-    return (tms.tms_utime + tms.tms_stime) * tick;
-  }
-#else
-#ifdef USG
-  {
-    struct tms tms;
-#   if HAVE_SYSCONF && defined _SC_CLK_TCK
-#    define TICKS_PER_SECOND sysconf (_SC_CLK_TCK) /* POSIX 1003.1-1996 */
-#   else
-#    ifdef CLK_TCK
-#     define TICKS_PER_SECOND CLK_TCK /* POSIX 1003.1-1988; obsolescent */
-#    else
-#     define TICKS_PER_SECOND HZ /* traditional UNIX */
-#    endif
-#   endif
-    times (&tms);
-    return (tms.tms_utime + tms.tms_stime) * (1000000 / TICKS_PER_SECOND);
-  }
-#else
-#ifndef VMS
-  {
-    struct rusage rusage;
-    getrusage (0, &rusage);
-    return (rusage.ru_utime.tv_sec * 1000000 + rusage.ru_utime.tv_usec
-           + rusage.ru_stime.tv_sec * 1000000 + rusage.ru_stime.tv_usec);
-  }
-#else /* VMS */
-  {
-    struct
-      {
-        int proc_user_time;
-        int proc_system_time;
-        int child_user_time;
-        int child_system_time;
-      } vms_times;
-    times ((void *) &vms_times);
-    return (vms_times.proc_user_time + vms_times.proc_system_time) * 10000;
-  }
-#endif /* VMS */
-#endif /* USG */
-#endif  /* _SC_CLK_TCK */
-#endif /* _WIN32 */
-#endif /* __BEOS__ */
-}
-
-#define TIMEVAR(VAR, BODY)    \
-do { int otime = get_run_time (); BODY; VAR += get_run_time () - otime; } while (0)
-
-void
-print_time (str, total)
-     const char *str;
-     int total;
-{
-  fprintf (stderr,
-          "time in %s: %d.%06d (%.0f%%)\n",
-          str, total / 1000000, total % 1000000,
-          (double)total / (double)all_time * 100.0);
-}
-
-/* Count an error or warning.  Return 1 if the message should be printed.  */
-
-int
-count_error (warningp)
-     int warningp;
-{
-  if (warningp && inhibit_warnings)
-    return 0;
-
-  if (warningp && !warnings_are_errors)
-    warningcount++;
-  else
-    {
-      static int warning_message = 0;
-
-      if (warningp && !warning_message)
-       {
-         notice ("%s: warnings being treated as errors\n", progname);
-         warning_message = 1;
-       }
-      errorcount++;
-    }
-
-  return 1;
-}
-
-/* Print a fatal error message.  NAME is the text.
-   Also include a system error message based on `errno'.  */
-
-void
-pfatal_with_name (name)
-  const char *name;
-{
-  fprintf (stderr, "%s: ", progname);
-  perror (name);
-  exit (FATAL_EXIT_CODE);
-}
-
-void
-fatal_io_error (name)
-  const char *name;
-{
-  notice ("%s: %s: I/O error\n", progname, name);
-  exit (FATAL_EXIT_CODE);
-}
-
 /* This is the default decl_printable_name function.  */
 
 static const char *
@@ -1458,6 +1425,7 @@ decl_name (decl, verbosity)
 }
 \f
 /* Mark P for GC.  Also mark main_input_filename and input_filename.  */
+
 static void
 mark_file_stack (p)
      void *p;
@@ -1475,943 +1443,160 @@ mark_file_stack (p)
       stack = stack->next;
     }
 }
+\f
 
-static int need_error_newline;
-
-/* Function of last error message;
-   more generally, function such that if next error message is in it
-   then we don't have to mention the function name.  */
-static tree last_error_function = NULL;
-
-/* Used to detect when input_file_stack has changed since last described.  */
-static int last_error_tick;
-
-/* Called when the start of a function definition is parsed,
-   this function prints on stderr the name of the function.  */
+/* This calls abort and is used to avoid problems when abort if a macro.
+   It is used when we need to pass the address of abort.  */
 
 void
-announce_function (decl)
-     tree decl;
+do_abort ()
 {
-  if (! quiet_flag)
-    {
-      if (rtl_dump_and_exit)
-       fprintf (stderr, "%s ", IDENTIFIER_POINTER (DECL_NAME (decl)));
-      else
-       fprintf (stderr, " %s", (*decl_printable_name) (decl, 2));
-      fflush (stderr);
-      need_error_newline = 1;
-      last_error_function = current_function_decl;
-    }
+  abort ();
 }
 
-/* The default function to print out name of current function that caused
-   an error.  */
+/* When `malloc.c' is compiled with `rcheck' defined,
+   it calls this function to report clobberage.  */
 
 void
-default_print_error_function (file)
-  const char *file;
+botch (s)
+  const char * s ATTRIBUTE_UNUSED;
 {
-  if (last_error_function != current_function_decl)
-    {
-      if (file)
-       fprintf (stderr, "%s: ", file);
-
-      if (current_function_decl == NULL)
-       notice ("At top level:\n");
-      else
-       notice ((TREE_CODE (TREE_TYPE (current_function_decl)) == METHOD_TYPE
-                ? "In method `%s':\n"
-                : "In function `%s':\n"),
-               (*decl_printable_name) (current_function_decl, 2));
-
-      last_error_function = current_function_decl;
-    }
+  abort ();
 }
+\f
+/* Return the logarithm of X, base 2, considering X unsigned,
+   if X is a power of 2.  Otherwise, returns -1.
 
-/* Called by report_error_function to print out function name.
- * Default may be overridden by language front-ends.  */
-
-void (*print_error_function) PROTO((const char *)) =
-  default_print_error_function;
-
-/* Prints out, if necessary, the name of the current function
-  that caused an error.  Called from all error and warning functions.
-  We ignore the FILE parameter, as it cannot be relied upon.  */
+   This should be used via the `exact_log2' macro.  */
 
-void
-report_error_function (file)
-  const char *file ATTRIBUTE_UNUSED;
+int
+exact_log2_wide (x)
+     register unsigned HOST_WIDE_INT x;
 {
-  struct file_stack *p;
-
-  if (need_error_newline)
-    {
-      fprintf (stderr, "\n");
-      need_error_newline = 0;
-    }
+  register int log = 0;
+  /* Test for 0 or a power of 2.  */
+  if (x == 0 || x != (x & -x))
+    return -1;
+  while ((x >>= 1) != 0)
+    log++;
+  return log;
+}
 
-  if (input_file_stack && input_file_stack->next != 0
-      && input_file_stack_tick != last_error_tick)
-    {
-      for (p = input_file_stack->next; p; p = p->next)
-       notice ((p == input_file_stack->next
-                ?    "In file included from %s:%d"
-                : ",\n                 from %s:%d"),
-               p->name, p->line);
-      fprintf (stderr, ":\n");
-      last_error_tick = input_file_stack_tick;
-    }
+/* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
+   If X is 0, return -1.
 
-  (*print_error_function) (input_filename);
-}
-\f
-/* Print a message.  */
+   This should be used via the floor_log2 macro.  */
 
-static void
-vnotice (file, msgid, ap)
-     FILE *file;
-     const char *msgid;
-     va_list ap;
+int
+floor_log2_wide (x)
+     register unsigned HOST_WIDE_INT x;
 {
-  vfprintf (file, _(msgid), ap);
+  register int log = -1;
+  while (x != 0)
+    log++,
+    x >>= 1;
+  return log;
 }
 
+static int float_handler_set;
+int float_handled;
+jmp_buf float_handler;
+
+/* Signals actually come here.  */
+
 static void
-notice VPROTO((const char *msgid, ...))
+float_signal (signo)
+     /* If this is missing, some compilers complain.  */
+     int signo ATTRIBUTE_UNUSED;
 {
-#ifndef ANSI_PROTOTYPES
-  char *msgid;
+  if (float_handled == 0)
+    abort ();
+#if defined (USG) || defined (hpux)
+  signal (SIGFPE, float_signal);  /* re-enable the signal catcher */
 #endif
-  va_list ap;
+  float_handled = 0;
+  signal (SIGFPE, float_signal);
+  longjmp (float_handler, 1);
+}
 
-  VA_START (ap, msgid);
+/* Specify where to longjmp to when a floating arithmetic error happens.
+   If HANDLER is 0, it means don't handle the errors any more.  */
 
-#ifndef ANSI_PROTOTYPES
-  msgid = va_arg (ap, char *);
-#endif
+void
+set_float_handler (handler)
+     jmp_buf handler;
+{
+  float_handled = (handler != 0);
+  if (handler)
+    bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
 
-  vnotice (stderr, msgid, ap);
-  va_end (ap);
+  if (float_handled && ! float_handler_set)
+    {
+      signal (SIGFPE, float_signal);
+      float_handler_set = 1;
+    }
 }
 
-void
-fnotice VPROTO((FILE *file, const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  FILE *file;
-  const char *msgid;
-#endif
-  va_list ap;
+/* This is a wrapper function for code which might elicit an
+   arithmetic exception.  That code should be passed in as a function
+   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. */
 
-  VA_START (ap, msgid);
+int
+do_float_handler (fn, data)
+  void (*fn) PARAMS ((PTR));
+  PTR data;
+{
+  jmp_buf buf;
 
-#ifndef ANSI_PROTOTYPES
-  file = va_arg (ap, FILE *);
-  msgid = va_arg (ap, const char *);
-#endif
+  if (setjmp (buf))
+    {
+      /* We got here via longjmp() caused by an exception in function fn() */
+      set_float_handler (NULL);
+      return 0;
+    }
 
-  vnotice (file, msgid, ap);
-  va_end (ap);
+  set_float_handler (buf);
+  (*fn)(data);
+  set_float_handler (NULL);
+  return 1;
 }
 
-/* Report FILE and LINE (or program name), and optionally just WARN.  */
+/* Specify, in HANDLER, where to longjmp to when a floating arithmetic
+   error happens, pushing the previous specification into OLD_HANDLER.
+   Return an indication of whether there was a previous handler in effect.  */
 
-static void
-report_file_and_line (file, line, warn)
-     const char *file;
-     int line;
-     int warn;
+int
+push_float_handler (handler, old_handler)
+     jmp_buf handler, old_handler;
 {
-  if (file)
-    fprintf (stderr, "%s:%d: ", file, line);
-  else
-    fprintf (stderr, "%s: ", progname);
+  int was_handled = float_handled;
+
+  float_handled = 1;
+  if (was_handled)
+    memcpy ((char *) old_handler, (char *) float_handler,
+          sizeof (float_handler));
 
-  if (warn)
-    notice ("warning: ");
+  memcpy ((char *) float_handler, (char *) handler, sizeof (float_handler));
+  return was_handled;
 }
 
-/* Print a message.  */
+/* Restore the previous specification of whether and where to longjmp to
+   when a floating arithmetic error happens.  */
 
-static void
-vmessage (prefix, msgid, ap)
-     const char *prefix;
-     const char *msgid;
-     va_list ap;
+void
+pop_float_handler (handled, handler)
+     int handled;
+     jmp_buf handler;
 {
-  if (prefix)
-    fprintf (stderr, "%s: ", prefix);
-
-  vfprintf (stderr, msgid, ap);
+  float_handled = handled;
+  if (handled)
+    bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
 }
 
-/* Print a message relevant to line LINE of file FILE.  */
-
-static void
-v_message_with_file_and_line (file, line, warn, msgid, ap)
-     const char *file;
-     int line;
-     int warn;
-     const char *msgid;
-     va_list ap;
-{
-  report_file_and_line (file, line, warn);
-  vnotice (stderr, msgid, ap);
-  fputc ('\n', stderr);
-}
-
-/* Print a message relevant to the given DECL.  */
-
-static void
-v_message_with_decl (decl, warn, msgid, ap)
-     tree decl;
-     int warn;
-     const char *msgid;
-     va_list ap;
-{
-  const char *p;
-
-  report_file_and_line (DECL_SOURCE_FILE (decl),
-                       DECL_SOURCE_LINE (decl), warn);
-
-  /* Do magic to get around lack of varargs support for insertion
-     of arguments into existing list.  We know that the decl is first;
-     we ass_u_me that it will be printed with "%s".  */
-
-  for (p = _(msgid); *p; ++p)
-    {
-      if (*p == '%')
-       {
-         if (*(p + 1) == '%')
-           ++p;
-         else if (*(p + 1) != 's')
-           abort ();
-         else
-           break;
-       }
-    }
-
-  if (p > _(msgid))                    /* Print the left-hand substring.  */
-    {
-      char fmt[sizeof "%.255s"];
-      long width = p - _(msgid);
-             
-      if (width > 255L) width = 255L;  /* arbitrary */
-      sprintf (fmt, "%%.%lds", width);
-      fprintf (stderr, fmt, _(msgid));
-    }
-
-  if (*p == '%')               /* Print the name.  */
-    {
-      const char *n = (DECL_NAME (decl)
-                ? (*decl_printable_name) (decl, 2)
-                : "((anonymous))");
-      fputs (n, stderr);
-      while (*p)
-       {
-         ++p;
-         if (ISALPHA (*(p - 1) & 0xFF))
-           break;
-       }
-    }
-
-  if (*p)                      /* Print the rest of the message.  */
-    vmessage ((char *)NULL, p, ap);
-
-  fputc ('\n', stderr);
-}
-
-/* Figure file and line of the given INSN.  */
-
-static void
-file_and_line_for_asm (insn, pfile, pline)
-     rtx insn;
-     char **pfile;
-     int *pline;
-{
-  rtx body = PATTERN (insn);
-  rtx asmop;
-
-  /* Find the (or one of the) ASM_OPERANDS in the insn.  */
-  if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
-    asmop = SET_SRC (body);
-  else if (GET_CODE (body) == ASM_OPERANDS)
-    asmop = body;
-  else if (GET_CODE (body) == PARALLEL
-          && GET_CODE (XVECEXP (body, 0, 0)) == SET)
-    asmop = SET_SRC (XVECEXP (body, 0, 0));
-  else if (GET_CODE (body) == PARALLEL
-          && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
-    asmop = XVECEXP (body, 0, 0);
-  else
-    asmop = NULL;
-
-  if (asmop)
-    {
-      *pfile = ASM_OPERANDS_SOURCE_FILE (asmop);
-      *pline = ASM_OPERANDS_SOURCE_LINE (asmop);
-    }
-  else
-    {
-      *pfile = input_filename;
-      *pline = lineno;
-    }
-}
-
-/* Report an error at line LINE of file FILE.  */
-
-static void
-v_error_with_file_and_line (file, line, msgid, ap)
-     const char *file;
-     int line;
-     const char *msgid;
-     va_list ap;
-{
-  count_error (0);
-  report_error_function (file);
-  v_message_with_file_and_line (file, line, 0, msgid, ap);
-}
-
-void
-error_with_file_and_line VPROTO((const char *file, int line,
-                                const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  const char *file;
-  int line;
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  file = va_arg (ap, const char *);
-  line = va_arg (ap, int);
-  msgid = va_arg (ap, const char *);
-#endif
-
-  v_error_with_file_and_line (file, line, msgid, ap);
-  va_end (ap);
-}
-
-/* Report an error at the declaration DECL.
-   MSGID is a format string which uses %s to substitute the declaration
-   name; subsequent substitutions are a la printf.  */
-
-static void
-v_error_with_decl (decl, msgid, ap)
-     tree decl;
-     const char *msgid;
-     va_list ap;
-{
-  count_error (0);
-  report_error_function (DECL_SOURCE_FILE (decl));
-  v_message_with_decl (decl, 0, msgid, ap);
-}
-
-void
-error_with_decl VPROTO((tree decl, const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  tree decl;
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  decl = va_arg (ap, tree);
-  msgid = va_arg (ap, const char *);
-#endif
-
-  v_error_with_decl (decl, msgid, ap);
-  va_end (ap);
-}
-
-/* Report an error at the line number of the insn INSN.
-   This is used only when INSN is an `asm' with operands,
-   and each ASM_OPERANDS records its own source file and line.  */
-
-static void
-v_error_for_asm (insn, msgid, ap)
-     rtx insn;
-     const char *msgid;
-     va_list ap;
-{
-  char *file;
-  int line;
-
-  count_error (0);
-  file_and_line_for_asm (insn, &file, &line);
-  report_error_function (file);
-  v_message_with_file_and_line (file, line, 0, msgid, ap);
-}
-
-void
-error_for_asm VPROTO((rtx insn, const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  rtx insn;
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  insn = va_arg (ap, rtx);
-  msgid = va_arg (ap, const char *);
-#endif
-
-  v_error_for_asm (insn, msgid, ap);
-  va_end (ap);
-}
-
-/* Report an error at the current line number.  */
-
-static void
-verror (msgid, ap)
-     const char *msgid;
-     va_list ap;
-{
-  v_error_with_file_and_line (input_filename, lineno, msgid, ap);
-}
-
-void
-error VPROTO((const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  msgid = va_arg (ap, const char *);
-#endif
-
-  verror (msgid, ap);
-  va_end (ap);
-}
-
-/* Report a fatal error at the current line number.  Allow a front end to
-   intercept the message.  */
-
-static void (*fatal_function) PROTO ((const char *, va_list));
-
-/* Set the function to call when a fatal error occurs.  */
-
-void
-set_fatal_function (f)
-     void (*f) PROTO ((const char *, va_list));
-{
-  fatal_function = f;
-}
-
-static void
-vfatal (msgid, ap)
-     const char *msgid;
-     va_list ap;
-{
-   if (fatal_function != 0)
-     (*fatal_function) (_(msgid), ap);
-
-  verror (msgid, ap);
-  exit (FATAL_EXIT_CODE);
-}
-
-void
-fatal VPROTO((const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  msgid = va_arg (ap, const char *);
-#endif
-
-  vfatal (msgid, ap);
-  va_end (ap);
-}
-
-void
-_fatal_insn (msgid, insn, file, line, function)
-     const char *msgid;
-     rtx insn;
-     const char *file;
-     int line;
-     const char *function;
-{
-  error (msgid);
-  debug_rtx (insn);
-  fancy_abort (file, line, function);
-}
-
-void
-_fatal_insn_not_found (insn, file, line, function)
-     rtx insn;
-     const char *file;
-     int line;
-     const char *function;
-{
-  if (INSN_CODE (insn) < 0)
-    _fatal_insn ("Unrecognizable insn:", insn, file, line, function);
-  else
-    _fatal_insn ("Insn does not satisfy its constraints:",
-               insn, file, line, function);
-}
-
-/* Report a warning at line LINE of file FILE.  */
-
-static void
-v_warning_with_file_and_line (file, line, msgid, ap)
-     const char *file;
-     int line;
-     const char *msgid;
-     va_list ap;
-{
-  if (count_error (1))
-    {
-      report_error_function (file);
-      v_message_with_file_and_line (file, line, 1, msgid, ap);
-    }
-}
-
-void
-warning_with_file_and_line VPROTO((const char *file, int line,
-                                  const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  const char *file;
-  int line;
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  file = va_arg (ap, const char *);
-  line = va_arg (ap, int);
-  msgid = va_arg (ap, const char *);
-#endif
-
-  v_warning_with_file_and_line (file, line, msgid, ap);
-  va_end (ap);
-}
-
-/* Report a warning at the declaration DECL.
-   MSGID is a format string which uses %s to substitute the declaration
-   name; subsequent substitutions are a la printf.  */
-
-static void
-v_warning_with_decl (decl, msgid, ap)
-     tree decl;
-     const char *msgid;
-     va_list ap;
-{
-  if (count_error (1))
-    {
-      report_error_function (DECL_SOURCE_FILE (decl));
-      v_message_with_decl (decl, 1, msgid, ap);
-    }
-}
-
-void
-warning_with_decl VPROTO((tree decl, const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  tree decl;
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  decl = va_arg (ap, tree);
-  msgid = va_arg (ap, const char *);
-#endif
-
-  v_warning_with_decl (decl, msgid, ap);
-  va_end (ap);
-}
-
-/* Report a warning at the line number of the insn INSN.
-   This is used only when INSN is an `asm' with operands,
-   and each ASM_OPERANDS records its own source file and line.  */
-
-static void
-v_warning_for_asm (insn, msgid, ap)
-     rtx insn;
-     const char *msgid;
-     va_list ap;
-{
-  if (count_error (1))
-    {
-      char *file;
-      int line;
-
-      file_and_line_for_asm (insn, &file, &line);
-      report_error_function (file);
-      v_message_with_file_and_line (file, line, 1, msgid, ap);
-    }
-}
-
-void
-warning_for_asm VPROTO((rtx insn, const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  rtx insn;
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  insn = va_arg (ap, rtx);
-  msgid = va_arg (ap, const char *);
-#endif
-
-  v_warning_for_asm (insn, msgid, ap);
-  va_end (ap);
-}
-
-/* Report a warning at the current line number.  */
-
-static void
-vwarning (msgid, ap)
-     const char *msgid;
-     va_list ap;
-{
-  v_warning_with_file_and_line (input_filename, lineno, msgid, ap);
-}
-
-void
-warning VPROTO((const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  msgid = va_arg (ap, const char *);
-#endif
-
-  vwarning (msgid, ap);
-  va_end (ap);
-}
-
-/* These functions issue either warnings or errors depending on
-   -pedantic-errors.  */
-
-static void
-vpedwarn (msgid, ap)
-     const char *msgid;
-     va_list ap;
-{
-  if (flag_pedantic_errors)
-    verror (msgid, ap);
-  else
-    vwarning (msgid, ap);
-}
-
-void
-pedwarn VPROTO((const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  msgid = va_arg (ap, const char *);
-#endif
-
-  vpedwarn (msgid, ap);
-  va_end (ap);
-}
-
-static void
-v_pedwarn_with_decl (decl, msgid, ap)
-     tree decl;
-     const char *msgid;
-     va_list ap;
-{
-  /* We don't want -pedantic-errors to cause the compilation to fail from
-     "errors" in system header files.  Sometimes fixincludes can't fix what's
-     broken (eg: unsigned char bitfields - fixing it may change the alignment
-     which will cause programs to mysteriously fail because the C library
-     or kernel uses the original layout).  There's no point in issuing a
-     warning either, it's just unnecessary noise.  */
-
-  if (! DECL_IN_SYSTEM_HEADER (decl))
-    {
-      if (flag_pedantic_errors)
-       v_error_with_decl (decl, msgid, ap);
-      else
-       v_warning_with_decl (decl, msgid, ap);
-    }
-}
-
-void
-pedwarn_with_decl VPROTO((tree decl, const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  tree decl;
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  decl = va_arg (ap, tree);
-  msgid = va_arg (ap, const char *);
-#endif
-
-  v_pedwarn_with_decl (decl, msgid, ap);
-  va_end (ap);
-}
-
-static void
-v_pedwarn_with_file_and_line (file, line, msgid, ap)
-     const char *file;
-     int line;
-     const char *msgid;
-     va_list ap;
-{
-  if (flag_pedantic_errors)
-    v_error_with_file_and_line (file, line, msgid, ap);
-  else
-    v_warning_with_file_and_line (file, line, msgid, ap);
-}
-
-void
-pedwarn_with_file_and_line VPROTO((const char *file, int line,
-                                  const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  const char *file;
-  int line;
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  file = va_arg (ap, const char *);
-  line = va_arg (ap, int);
-  msgid = va_arg (ap, const char *);
-#endif
-
-  v_pedwarn_with_file_and_line (file, line, msgid, ap);
-  va_end (ap);
-}
-
-/* Apologize for not implementing some feature.  */
-
-static void
-vsorry (msgid, ap)
-     const char *msgid;
-     va_list ap;
-{
-  sorrycount++;
-  if (input_filename)
-    fprintf (stderr, "%s:%d: ", input_filename, lineno);
-  else
-    fprintf (stderr, "%s: ", progname);
-  notice ("sorry, not implemented: ");
-  vnotice (stderr, msgid, ap);
-  fputc ('\n', stderr);
-}
-
-void
-sorry VPROTO((const char *msgid, ...))
-{
-#ifndef ANSI_PROTOTYPES
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
-  msgid = va_arg (ap, const char *);
-#endif
-
-  vsorry (msgid, ap);
-  va_end (ap);
-}
-\f
-
-/* This calls abort and is used to avoid problems when abort if a macro.
-   It is used when we need to pass the address of abort.  */
-
-void
-do_abort ()
-{
-  abort ();
-}
-
-/* When `malloc.c' is compiled with `rcheck' defined,
-   it calls this function to report clobberage.  */
-
-void
-botch (s)
-  const char * s ATTRIBUTE_UNUSED;
-{
-  abort ();
-}
-\f
-/* Return the logarithm of X, base 2, considering X unsigned,
-   if X is a power of 2.  Otherwise, returns -1.
-
-   This should be used via the `exact_log2' macro.  */
-
-int
-exact_log2_wide (x)
-     register unsigned HOST_WIDE_INT x;
-{
-  register int log = 0;
-  /* Test for 0 or a power of 2.  */
-  if (x == 0 || x != (x & -x))
-    return -1;
-  while ((x >>= 1) != 0)
-    log++;
-  return log;
-}
-
-/* Given X, an unsigned number, return the largest int Y such that 2**Y <= X.
-   If X is 0, return -1.
-
-   This should be used via the floor_log2 macro.  */
-
-int
-floor_log2_wide (x)
-     register unsigned HOST_WIDE_INT x;
-{
-  register int log = -1;
-  while (x != 0)
-    log++,
-    x >>= 1;
-  return log;
-}
-
-static int float_handler_set;
-int float_handled;
-jmp_buf float_handler;
-
-/* Signals actually come here.  */
-
-static void
-float_signal (signo)
-     /* If this is missing, some compilers complain.  */
-     int signo ATTRIBUTE_UNUSED;
-{
-  if (float_handled == 0)
-    abort ();
-#if defined (USG) || defined (hpux)
-  signal (SIGFPE, float_signal);  /* re-enable the signal catcher */
-#endif
-  float_handled = 0;
-  signal (SIGFPE, float_signal);
-  longjmp (float_handler, 1);
-}
-
-/* Specify where to longjmp to when a floating arithmetic error happens.
-   If HANDLER is 0, it means don't handle the errors any more.  */
-
-void
-set_float_handler (handler)
-     jmp_buf handler;
-{
-  float_handled = (handler != 0);
-  if (handler)
-    bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
-
-  if (float_handled && ! float_handler_set)
-    {
-      signal (SIGFPE, float_signal);
-      float_handler_set = 1;
-    }
-}
-
-/* This is a wrapper function for code which might elicit an
-   arithmetic exception.  That code should be passed in as a function
-   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. */
-
-int
-do_float_handler (fn, data)
-  void (*fn) PROTO ((PTR));
-  PTR data;
-{
-  jmp_buf buf;
-
-  if (setjmp (buf))
-    {
-      /* We got here via longjmp() caused by an exception in function fn() */
-      set_float_handler (NULL);
-      return 0;
-    }
-
-  set_float_handler (buf);
-  (*fn)(data);
-  set_float_handler (NULL);
-  return 1;
-}
-
-/* Specify, in HANDLER, where to longjmp to when a floating arithmetic
-   error happens, pushing the previous specification into OLD_HANDLER.
-   Return an indication of whether there was a previous handler in effect.  */
-
-int
-push_float_handler (handler, old_handler)
-     jmp_buf handler, old_handler;
-{
-  int was_handled = float_handled;
-
-  float_handled = 1;
-  if (was_handled)
-    memcpy ((char *) old_handler, (char *) float_handler,
-          sizeof (float_handler));
-
-  memcpy ((char *) float_handler, (char *) handler, sizeof (float_handler));
-  return was_handled;
-}
-
-/* Restore the previous specification of whether and where to longjmp to
-   when a floating arithmetic error happens.  */
-
-void
-pop_float_handler (handled, handler)
-     int handled;
-     jmp_buf handler;
-{
-  float_handled = handled;
-  if (handled)
-    bcopy ((char *) handler, (char *) float_handler, sizeof (float_handler));
-}
-
-/* Handler for SIGPIPE.  */
+/* Handler for SIGPIPE.  */
 
 static void
 pipe_closed (signo)
@@ -2513,87 +1698,92 @@ output_lang_identify (asm_out_file)
 }
 #endif
 
-/* Routine to open a dump file.  */
-static void
-open_dump_file (suffix, function_name)
-     const char *suffix;
-     const char *function_name;
+/* Routine to open a dump file.  Return true if the dump file is enabled.  */
+
+static int
+open_dump_file (index, decl)
+     enum dump_file_index index;
+     tree decl;
 {
-  char *dumpname;
+  char *dump_name;
+  const char *open_arg;
+  char seq[16];
 
-  TIMEVAR
-    (dump_time,
-     {
-       dumpname = concat (dump_base_name, suffix, NULL);
+  if (! dump_file[index].enabled)
+    return 0;
 
-       if (rtl_dump_file != NULL)
-        fclose (rtl_dump_file);
+  timevar_push (TV_DUMP);
+  if (rtl_dump_file != NULL)
+    fclose (rtl_dump_file);
   
-       rtl_dump_file = fopen (dumpname, "a");
-       
-       if (rtl_dump_file == NULL)
-        pfatal_with_name (dumpname);
-       
-       free (dumpname);
+  sprintf (seq, ".%02d.", index);
 
-       if (function_name)
-        fprintf (rtl_dump_file, "\n;; Function %s\n\n", function_name);
-     });
-  
-  return;
-}
+  if (! dump_file[index].initialized)
+    {
+      /* If we've not initialized the files, do so now.  */
+      if (graph_dump_format != no_graph
+         && dump_file[index].graph_dump_p)
+       {
+         dump_name = concat (seq, dump_file[index].extension, NULL);
+         clean_graph_dump_file (dump_base_name, dump_name);
+         free (dump_name);
+       }
+      dump_file[index].initialized = 1;
+      open_arg = "w";
+    }
+  else
+    open_arg = "a";
 
-/* Routine to close a dump file.  */
-static void
-close_dump_file (func, insns)
-     void (*func) PROTO ((FILE *, rtx));
-     rtx    insns;
-{
-  TIMEVAR
-    (dump_time,
-     {
-       if (func)
-        func (rtl_dump_file, insns);
-       
-       fflush (rtl_dump_file);
-       fclose (rtl_dump_file);
+  dump_name = concat (dump_base_name, seq,
+                     dump_file[index].extension, NULL);
+
+  rtl_dump_file = fopen (dump_name, open_arg);
+  if (rtl_dump_file == NULL)
+    pfatal_with_name (dump_name);
        
-       rtl_dump_file = NULL;
-     });
+  free (dump_name);
 
-  return;
-}
+  if (decl)
+    fprintf (rtl_dump_file, "\n;; Function %s\n\n",
+            decl_printable_name (decl, 2));
 
-/* Routine to dump rtl into a file.  */
-static void
-dump_rtl (suffix, decl, func, insns)
-     const char *suffix;
-     tree   decl;
-     void (*func) PROTO ((FILE *, rtx));
-     rtx    insns;
-{
-  open_dump_file (suffix, decl_printable_name (decl, 2));
-  close_dump_file (func, insns);
+  timevar_pop (TV_DUMP);
+  return 1;
 }
 
-/* Routine to empty a dump file.  */
+/* Routine to close a dump file.  */
+
 static void
-clean_dump_file (suffix)
-  const char *suffix;
+close_dump_file (index, func, insns)
+     enum dump_file_index index;
+     void (*func) PARAMS ((FILE *, rtx));
+     rtx    insns;
 {
-  char * const dumpname = concat (dump_base_name, suffix, NULL);
-
-  rtl_dump_file = fopen (dumpname, "w");
+  if (! rtl_dump_file)
+    return;
 
-  if (rtl_dump_file == NULL)
-    pfatal_with_name (dumpname);       
+  timevar_push (TV_DUMP);
+  if (insns
+      && graph_dump_format != no_graph
+      && dump_file[index].graph_dump_p)
+    {
+      char seq[16];
+      char *suffix;
 
-  free (dumpname);
+      sprintf (seq, ".%02d.", index);
+      suffix = concat (seq, dump_file[index].extension, NULL);
+      print_rtl_graph_with_bb (dump_base_name, suffix, insns);
+      free (suffix);
+    }
 
+  if (func && insns)
+    func (rtl_dump_file, insns);
+       
+  fflush (rtl_dump_file);
   fclose (rtl_dump_file);
+       
   rtl_dump_file = NULL;
-  
-  return;
+  timevar_pop (TV_DUMP);
 }
 
 /* Do any final processing required for the declarations in VEC, of
@@ -2754,6 +1944,7 @@ check_global_declarations (vec, len)
          && ! TREE_USED (DECL_NAME (decl)))
        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.
@@ -2763,7 +1954,7 @@ check_global_declarations (vec, len)
          && TREE_PUBLIC (decl) && DECL_INITIAL (decl)
          && ! DECL_EXTERNAL (decl)
          && DECL_RTL (decl) != 0)
-       TIMEVAR (symout_time, sdbout_symbol (decl, 0));
+       sdbout_symbol (decl, 0);
 
       /* Output COFF information for non-global
         file-scope initialized variables.  */
@@ -2773,7 +1964,7 @@ check_global_declarations (vec, len)
          && ! DECL_EXTERNAL (decl)
          && DECL_RTL (decl) != 0
          && GET_CODE (DECL_RTL (decl)) == MEM)
-       TIMEVAR (symout_time, sdbout_toplevel_data (decl));
+       sdbout_toplevel_data (decl);
 #endif /* SDB_DEBUGGING_INFO */
 #ifdef DWARF_DEBUGGING_INFO
       /* Output DWARF information for file-scope tentative data object
@@ -2783,7 +1974,7 @@ check_global_declarations (vec, len)
 
       if (write_symbols == DWARF_DEBUG
          && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
-       TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 1));
+       dwarfout_file_scope_decl (decl, 1);
 #endif
 #ifdef DWARF2_DEBUGGING_INFO
       /* Output DWARF2 information for file-scope tentative data object
@@ -2793,9 +1984,56 @@ check_global_declarations (vec, len)
 
       if (write_symbols == DWARF2_DEBUG
          && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
-       TIMEVAR (symout_time, dwarf2out_decl (decl));
+       dwarf2out_decl (decl);
 #endif
+      timevar_pop (TV_SYMOUT);
+    }
+}
+
+/* Save the current INPUT_FILENAME and LINENO on the top entry in the
+   INPUT_FILE_STACK.  Push a new entry for FILE and LINE, and set the
+   INPUT_FILENAME and LINENO accordingly.  */
+
+void
+push_srcloc (file, line)
+     char *file;
+     int line;
+{
+  struct file_stack *fs;
+
+  if (input_file_stack)
+    {
+      input_file_stack->name = input_filename;
+      input_file_stack->line = lineno;
     }
+
+  fs = (struct file_stack *) xmalloc (sizeof (struct file_stack));
+  fs->name = input_filename = file;
+  fs->line = lineno = line;
+  fs->indent_level = 0;
+  fs->next = input_file_stack;
+  input_file_stack = fs;
+  input_file_stack_tick++;
+}
+
+/* Pop the top entry off the stack of presently open source files.
+   Restore the INPUT_FILENAME and LINENO from the new topmost entry on
+   the stack.  */
+
+void
+pop_srcloc ()
+{
+  struct file_stack *fs;
+  
+  fs = input_file_stack;
+  input_file_stack = fs->next;
+  free (fs);
+  input_file_stack_tick++;
+  /* The initial souce file is never popped.  */
+  if (!input_file_stack)
+    abort ();
+  input_filename = input_file_stack->name;
+  lineno = input_file_stack->line;
 }
 
 /* Compile an entire file of output from cpp, named NAME.
@@ -2806,39 +2044,17 @@ compile_file (name)
      char *name;
 {
   tree globals;
-  int start_time;
 
   int name_specified = name != 0;
 
   if (dump_base_name == 0)
     dump_base_name = name ? name : "gccdump";
 
-  parse_time = 0;
-  varconst_time = 0;
-  integration_time = 0;
-  jump_time = 0;
-  cse_time = 0;
-  gcse_time = 0;
-  loop_time = 0;
-  cse2_time = 0;
-  branch_prob_time = 0;
-  flow_time = 0;
-  combine_time = 0;
-  regmove_time = 0;
-  sched_time = 0;
-  local_alloc_time = 0;
-  global_alloc_time = 0;
-  flow2_time = 0;
-  sched2_time = 0;
-#ifdef DELAY_SLOTS
-  dbr_sched_time = 0;
-#endif
-  shorten_branch_time = 0;
-  stack_reg_time = 0;
-  final_time = 0;
-  symout_time = 0;
-  dump_time = 0;
+  /* Start timing total execution time.  */
 
+  init_timevar ();
+  timevar_start (TV_TOTAL);
+  
   /* Initialize data in various passes.  */
 
   init_obstacks ();
@@ -2879,136 +2095,6 @@ compile_file (name)
        pfatal_with_name (aux_info_file_name);
     }
 
-  /* Clear the dump files.  */
-  if (rtl_dump)
-    clean_dump_file (".rtl");
-  if (jump_opt_dump)
-    {
-      clean_dump_file (".jump");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".jump");
-    }
-  if (addressof_dump)
-    {
-      clean_dump_file (".addressof");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".addressof");
-    }
-  if (cse_dump)
-    {
-      clean_dump_file (".cse");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".cse");
-    }
-  if (loop_dump)
-    {
-      clean_dump_file (".loop");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".loop");
-    }
-  if (cse2_dump)
-    {
-      clean_dump_file (".cse2");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".cse2");
-    }
-  if (branch_prob_dump)
-    {
-      clean_dump_file (".bp");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".bp");
-    }
-  if (flow_dump)
-    {
-      clean_dump_file (".flow");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".flow");
-    }
-  if (combine_dump)
-    {
-      clean_dump_file (".combine");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".combine");
-    }
-  if (regmove_dump)
-    {
-      clean_dump_file (".regmove");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".regmove");
-    }
-  if (sched_dump)
-    {
-      clean_dump_file (".sched");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".sched");
-    }
-  if (local_reg_dump)
-    {
-      clean_dump_file (".lreg");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".lreg");
-    }
-  if (global_reg_dump)
-    {
-      clean_dump_file (".greg");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".greg");
-    }
-  if (flow2_dump)
-    {
-      clean_dump_file (".flow2");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".flow2");
-    }
-  if (peephole2_dump)
-    {
-      clean_dump_file (".peephole2");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".peephole2");
-    }
-  if (sched2_dump)
-    {
-      clean_dump_file (".sched2");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".sched2");
-    }
-  if (jump2_opt_dump)
-    {
-      clean_dump_file (".jump2");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".jump2");
-    }
-#ifdef DELAY_SLOTS
-  if (dbr_sched_dump)
-    {
-      clean_dump_file (".dbr");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".dbr");
-    }
-#endif
-  if (gcse_dump)
-    {
-      clean_dump_file (".gcse");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".gcse");
-    }
-#ifdef STACK_REGS
-  if (stack_reg_dump)
-    {
-      clean_dump_file (".stack");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".stack");
-    }
-#endif
-#ifdef MACHINE_DEPENDENT_REORG
-  if (mach_dep_reorg_dump)
-    {
-      clean_dump_file (".mach");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".mach");
-    }
-#endif
-
   /* Open assembler code output file.  */
 
   if (flag_syntax_only)
@@ -3019,13 +2105,15 @@ compile_file (name)
        asm_out_file = stdout;
       else
        {
-         int len = strlen (dump_base_name);
-         register char *dumpname = (char *) xmalloc (len + 6);
-         strcpy (dumpname, dump_base_name);
-         strip_off_ending (dumpname, len);
-         strcat (dumpname, ".s");
          if (asm_file_name == 0)
-           asm_file_name = xstrdup (dumpname);
+           {
+             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
@@ -3045,10 +2133,7 @@ compile_file (name)
   input_filename = name;
 
   /* Put an entry on the input file stack for the main input file.  */
-  input_file_stack
-    = (struct file_stack *) xmalloc (sizeof (struct file_stack));
-  input_file_stack->next = 0;
-  input_file_stack->name = input_filename;
+  push_srcloc (input_filename, 0);
 
   /* Perform language-specific initialization.
      This may set main_input_filename.  */
@@ -3141,19 +2226,18 @@ compile_file (name)
 
   /* 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)
-    TIMEVAR (symout_time, dbxout_init (asm_out_file, main_input_filename,
-                                      getdecls ()));
+    dbxout_init (asm_out_file, main_input_filename, getdecls ());
 #endif
 #ifdef SDB_DEBUGGING_INFO
   if (write_symbols == SDB_DEBUG)
-    TIMEVAR (symout_time, sdbout_init (asm_out_file, main_input_filename,
-                                      getdecls ()));
+    sdbout_init (asm_out_file, main_input_filename, getdecls ());
 #endif
 #ifdef DWARF_DEBUGGING_INFO
   if (write_symbols == DWARF_DEBUG)
-    TIMEVAR (symout_time, dwarfout_init (asm_out_file, main_input_filename));
+    dwarfout_init (asm_out_file, main_input_filename);
 #endif
 #ifdef DWARF2_UNWIND_INFO
   if (dwarf2out_do_frame ())
@@ -3161,15 +2245,16 @@ compile_file (name)
 #endif
 #ifdef DWARF2_DEBUGGING_INFO
   if (write_symbols == DWARF2_DEBUG)
-    TIMEVAR (symout_time, dwarf2out_init (asm_out_file, main_input_filename));
+    dwarf2out_init (asm_out_file, main_input_filename);
 #endif
+  timevar_pop (TV_SYMOUT);
 
   /* Initialize yet another pass.  */
 
   init_final (main_input_filename);
   init_branch_prob (dump_base_name);
 
-  start_time = get_run_time ();
+  timevar_push (TV_PARSE);
 
   /* Call the parser, which parses the entire file
      (calling rest_of_compilation for each function).  */
@@ -3177,7 +2262,7 @@ compile_file (name)
   if (yyparse () != 0)
     {
       if (errorcount == 0)
-       notice ("Errors detected in input file (your bison.simple is out of date)\n");
+       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.  */
@@ -3188,10 +2273,7 @@ compile_file (name)
   /* Compilation is now finished except for writing
      what's left of the symbol table output.  */
 
-  parse_time += get_run_time () - start_time;
-
-  parse_time -= integration_time;
-  parse_time -= varconst_time;
+  timevar_pop (TV_PARSE);
 
   if (flag_syntax_only)
     goto finish_syntax;
@@ -3204,7 +2286,7 @@ compile_file (name)
 
   {
     int len = list_length (globals);
-    tree *vec = (tree *) alloca (sizeof (tree) * len);
+    tree *vec = (tree *) xmalloc (sizeof (tree) * len);
     int i;
     tree decl;
 
@@ -3231,6 +2313,9 @@ compile_file (name)
     output_exception_table ();
 
     check_global_declarations (vec, len);
+
+    /* Clean up.  */
+    free (vec);
   }
 
   /* Write out any pending weak symbol declarations.  */
@@ -3238,20 +2323,15 @@ compile_file (name)
   weak_finish ();
 
   /* 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)
-    TIMEVAR (symout_time,
-            {
-              dbxout_finish (asm_out_file, main_input_filename);
-            });
+    dbxout_finish (asm_out_file, main_input_filename);
 #endif
 
 #ifdef DWARF_DEBUGGING_INFO
   if (write_symbols == DWARF_DEBUG)
-    TIMEVAR (symout_time,
-            {
-              dwarfout_finish ();
-            });
+    dwarfout_finish ();
 #endif
 
 #ifdef DWARF2_UNWIND_INFO
@@ -3261,29 +2341,27 @@ compile_file (name)
 
 #ifdef DWARF2_DEBUGGING_INFO
   if (write_symbols == DWARF2_DEBUG)
-    TIMEVAR (symout_time,
-            {
-              dwarf2out_finish ();
-            });
+    dwarf2out_finish ();
 #endif
+  timevar_pop (TV_SYMOUT);
 
   /* Output some stuff at end of file if nec.  */
 
   end_final (dump_base_name);
    
-  if (branch_prob_dump)
-    open_dump_file (".bp", NULL);
-   
-  TIMEVAR (dump_time, end_branch_prob (rtl_dump_file));
-   
-  if (branch_prob_dump)
-    close_dump_file (NULL, NULL_RTX);
+  if (flag_test_coverage || flag_branch_probabilities)
+    {
+      timevar_push (TV_DUMP);
+      open_dump_file (DFI_bp, NULL);
+      end_branch_prob (rtl_dump_file);
+      close_dump_file (DFI_bp, NULL, NULL_RTX);
+      timevar_pop (TV_DUMP);
+    }
    
 #ifdef ASM_FILE_END
   ASM_FILE_END (asm_out_file);
 #endif
 
-
   /* Language-specific end of compilation actions.  */
  finish_syntax:
   lang_finish ();
@@ -3297,11 +2375,12 @@ compile_file (name)
        unlink (aux_info_file_name);
     }
 
-  if (combine_dump)
+  if (optimize > 0 && open_dump_file (DFI_combine, NULL))
     {
-      open_dump_file (".combine", NULL);
-      TIMEVAR (dump_time, dump_combine_total_stats (rtl_dump_file));
-      close_dump_file (NULL, NULL_RTX);
+      timevar_push (TV_DUMP);
+      dump_combine_total_stats (rtl_dump_file);
+      close_dump_file (DFI_combine, NULL, NULL_RTX);
+      timevar_pop (TV_DUMP);
     }
 
   /* Close non-debugging input and output files.  Take special care to note
@@ -3317,90 +2396,31 @@ compile_file (name)
   /* Do whatever is necessary to finish printing the graphs.  */
   if (graph_dump_format != no_graph)
     {
-      if (jump_opt_dump)
-       finish_graph_dump_file (dump_base_name, ".jump");
-      if (addressof_dump)
-       finish_graph_dump_file (dump_base_name, ".addressof");
-      if (cse_dump)
-       finish_graph_dump_file (dump_base_name, ".cse");
-      if (loop_dump)
-       finish_graph_dump_file (dump_base_name, ".loop");
-      if (cse2_dump)
-       finish_graph_dump_file (dump_base_name, ".cse2");
-      if (branch_prob_dump)
-       finish_graph_dump_file (dump_base_name, ".bp");
-      if (flow_dump)
-       finish_graph_dump_file (dump_base_name, ".flow");
-      if (combine_dump)
-       finish_graph_dump_file (dump_base_name, ".combine");
-      if (regmove_dump)
-       finish_graph_dump_file (dump_base_name, ".regmove");
-      if (sched_dump)
-       finish_graph_dump_file (dump_base_name, ".sched");
-      if (local_reg_dump)
-       finish_graph_dump_file (dump_base_name, ".lreg");
-      if (global_reg_dump)
-       finish_graph_dump_file (dump_base_name, ".greg");
-      if (flow2_dump)
-       finish_graph_dump_file (dump_base_name, ".flow2");
-      if (sched2_dump)
-       finish_graph_dump_file (dump_base_name, ".sched2");
-      if (jump2_opt_dump)
-       finish_graph_dump_file (dump_base_name, ".jump2");
-#ifdef DELAY_SLOTS
-      if (dbr_sched_dump)
-       finish_graph_dump_file (dump_base_name, ".dbr");
-#endif
-      if (gcse_dump)
-       finish_graph_dump_file (dump_base_name, ".gcse");
-#ifdef STACK_REGS
-      if (stack_reg_dump)
-       finish_graph_dump_file (dump_base_name, ".stack");
-#endif
-#ifdef MACHINE_DEPENDENT_REORG
-      if (mach_dep_reorg_dump)
-       finish_graph_dump_file (dump_base_name, ".mach");
-#endif
+      int i;
+
+      for (i = 0; i < 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);
+         }
     }
 
   /* Free up memory for the benefit of leak detectors.  */
   free_reg_info ();
 
+  /* Stop timing total execution time.  */
+  timevar_stop (TV_TOTAL);
+
   /* Print the times.  */
 
   if (! quiet_flag)
-    {
-      all_time = get_run_time ();
-
-      fprintf (stderr,"\n");
-
-      print_time ("parse", parse_time);
-      print_time ("integration", integration_time);
-      print_time ("jump", jump_time);
-      print_time ("cse", cse_time);
-      print_time ("gcse", gcse_time);
-      print_time ("loop", loop_time);
-      print_time ("cse2", cse2_time);
-      print_time ("branch-prob", branch_prob_time);
-      print_time ("flow", flow_time);
-      print_time ("combine", combine_time);
-      print_time ("regmove", regmove_time);
-      print_time ("sched", sched_time);
-      print_time ("local-alloc", local_alloc_time);
-      print_time ("global-alloc", global_alloc_time);
-      print_time ("flow2", flow2_time);
-      print_time ("sched2", sched2_time);
-#ifdef DELAY_SLOTS
-      print_time ("dbranch", dbr_sched_time);
-#endif
-      print_time ("shorten-branch", shorten_branch_time);
-      print_time ("stack-reg", stack_reg_time);
-      print_time ("final", final_time);
-      print_time ("varconst", varconst_time);
-      print_time ("symout", symout_time);
-      print_time ("dump", dump_time);
-      print_time ("gc", gc_time);
-    }
+    timevar_print (stderr);
 }
 \f
 /* This is called from various places for FUNCTION_DECL, VAR_DECL,
@@ -3435,29 +2455,30 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
      but we need to treat them as if they were.  */
   if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
       || TREE_CODE (decl) == FUNCTION_DECL)
-    TIMEVAR (varconst_time,
-            {
-              make_decl_rtl (decl, asmspec, top_level);
-              /* Initialized extern variable exists to be replaced
-                 with its value, or represents something that will be
-                 output in another file.  */
-              if (! (TREE_CODE (decl) == VAR_DECL
-                     && DECL_EXTERNAL (decl) && TREE_READONLY (decl)
-                     && DECL_INITIAL (decl) != 0
-                     && DECL_INITIAL (decl) != error_mark_node))
-                /* Don't output anything
-                   when a tentative file-scope definition is seen.
-                   But at end of compilation, do output code for them.  */
-                if (! (! at_end && top_level
-                       && (DECL_INITIAL (decl) == 0
-                           || DECL_INITIAL (decl) == error_mark_node)))
-                  assemble_variable (decl, top_level, at_end, 0);
-              if (decl == last_assemble_variable_decl)
-                {
-                  ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
-                                             top_level, at_end);
-                }
-            });
+    {
+      timevar_push (TV_VARCONST);
+      make_decl_rtl (decl, asmspec, top_level);
+      /* Initialized extern variable exists to be replaced
+        with its value, or represents something that will be
+        output in another file.  */
+      if (! (TREE_CODE (decl) == VAR_DECL
+            && DECL_EXTERNAL (decl) && TREE_READONLY (decl)
+            && DECL_INITIAL (decl) != 0
+            && DECL_INITIAL (decl) != error_mark_node))
+       /* Don't output anything
+            when a tentative file-scope definition is seen.
+            But at end of compilation, do output code for them.  */
+       if (! (! at_end && top_level
+              && (DECL_INITIAL (decl) == 0
+                  || DECL_INITIAL (decl) == error_mark_node)))
+         assemble_variable (decl, top_level, at_end, 0);
+      if (decl == last_assemble_variable_decl)
+       {
+         ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
+                                    top_level, at_end);
+       }
+      timevar_pop (TV_VARCONST);
+    }
   else if (DECL_REGISTER (decl) && asmspec != 0)
     {
       if (decode_reg_name (asmspec) >= 0)
@@ -3471,12 +2492,20 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
   else if ((write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
           && TREE_CODE (decl) == TYPE_DECL)
-    TIMEVAR (symout_time, dbxout_symbol (decl, 0));
+    {
+      timevar_push (TV_SYMOUT);
+      dbxout_symbol (decl, 0);
+      timevar_pop (TV_SYMOUT);
+    }
 #endif
 #ifdef SDB_DEBUGGING_INFO
   else if (write_symbols == SDB_DEBUG && top_level
           && TREE_CODE (decl) == TYPE_DECL)
-    TIMEVAR (symout_time, sdbout_symbol (decl, 0));
+    {
+      timevar_push (TV_SYMOUT);
+      sdbout_symbol (decl, 0);
+      timevar_pop (TV_SYMOUT);
+    }
 #endif
 }
 
@@ -3492,13 +2521,51 @@ rest_of_type_compilation (type, toplev)
      int toplev ATTRIBUTE_UNUSED;
 #endif
 {
+  timevar_push (TV_SYMOUT);
 #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
   if (write_symbols == DBX_DEBUG || write_symbols == XCOFF_DEBUG)
-    TIMEVAR (symout_time, dbxout_symbol (TYPE_STUB_DECL (type), !toplev));
+    dbxout_symbol (TYPE_STUB_DECL (type), !toplev);
 #endif
 #ifdef SDB_DEBUGGING_INFO
   if (write_symbols == SDB_DEBUG)
-    TIMEVAR (symout_time, sdbout_symbol (TYPE_STUB_DECL (type), !toplev));
+    sdbout_symbol (TYPE_STUB_DECL (type), !toplev);
+#endif
+  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))
+    {
+      /* 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;
+      current_function_decl = decl;
+
+      /* Let the DWARF code do its work.  */
+      set_decl_abstract_flags (decl, 1);
+      dwarfout_file_scope_decl (decl, 0);
+      set_decl_abstract_flags (decl, 0);
+
+      /* Reset CURRENT_FUNCTION_DECL.  */
+      current_function_decl = saved_cfd;
+    }
 #endif
 }
 
@@ -3513,64 +2580,91 @@ rest_of_compilation (decl)
      tree decl;
 {
   register rtx insns;
-  int start_time = get_run_time ();
   int tem;
-  /* Nonzero if we have saved the original DECL_INITIAL of the function,
-     to be restored after we finish compiling the function
-     (for use when compiling inline calls to this function).  */
-  tree saved_block_tree = 0;
-  /* Likewise, for DECL_ARGUMENTS.  */
-  tree saved_arguments = 0;
   int failure = 0;
   int rebuild_label_notes_after_reload;
 
+  timevar_push (TV_REST_OF_COMPILATION);
+
+  /* When processing delayed functions, prepare_function_start() won't
+     have been run to re-initialize it.  */
+  cse_not_expected = ! optimize;
+
+  /* First, make sure that NOTE_BLOCK is set correctly for each
+     NOTE_INSN_BLOCK_BEG/NOTE_INSN_BLOCK_END note.  */
+  if (!cfun->x_whole_function_mode_p)
+    identify_blocks ();
+
+  /* Then remove any notes we don't need.  That will make iterating
+     over the instruction sequence faster, and allow the garbage
+     collector to reclaim the memory used by the notes.  */
+  remove_unnecessary_notes ();
+
+  /* In function-at-a-time mode, we do not attempt to keep the BLOCK
+     tree in sensible shape.  So, we just recalculate it here.  */
+  if (cfun->x_whole_function_mode_p)
+    reorder_blocks ();
+
   /* If we are reconsidering an inline function
      at the end of compilation, skip the stuff for making it inline.  */
 
   if (DECL_SAVED_INSNS (decl) == 0)
     {
       int inlinable = 0;
+      tree parent;
       const char *lose;
 
+      /* If this is nested inside an inlined external function, pretend
+        it was only declared.  Since we cannot inline such functions,
+        generating code for this one is not only not necessary but will
+        confuse some debugging output writers.  */
+      for (parent = DECL_CONTEXT (current_function_decl);
+          parent != NULL_TREE; 
+          parent = get_containing_scope (parent))
+       if (TREE_CODE (parent) == FUNCTION_DECL
+           && DECL_INLINE (parent) && DECL_EXTERNAL (parent))
+         {
+           DECL_INITIAL (decl) = 0;
+           goto exit_rest_of_compilation;
+         }
+
       /* If requested, consider whether to make this function inline.  */
       if (DECL_INLINE (decl) || flag_inline_functions)
-       TIMEVAR (integration_time,
-                {
-                  lose = function_cannot_inline_p (decl);
-                  if (lose || ! optimize)
-                    {
-                      if (warn_inline && DECL_INLINE (decl))
-                        warning_with_decl (decl, lose);
-                      DECL_ABSTRACT_ORIGIN (decl) = 0;
-                      /* Don't really compile an extern inline function.
-                         If we can't make it inline, pretend
-                         it was only declared.  */
-                      if (DECL_EXTERNAL (decl))
-                        {
-                          DECL_INITIAL (decl) = 0;
-                          goto exit_rest_of_compilation;
-                        }
-                    }
-                  else
-                    /* ??? Note that this has the effect of making it look
-                       like "inline" was specified for a function if we choose
-                       to inline it.  This isn't quite right, but it's
-                       probably not worth the trouble to fix.  */
-                    inlinable = DECL_INLINE (decl) = 1;
-                });
+       {
+         timevar_push (TV_INTEGRATION);
+         lose = function_cannot_inline_p (decl);
+         timevar_pop (TV_INTEGRATION);
+         if (lose || ! optimize)
+           {
+             if (warn_inline && DECL_INLINE (decl))
+               warning_with_decl (decl, lose);
+             DECL_ABSTRACT_ORIGIN (decl) = 0;
+             /* Don't really compile an extern inline function.
+                If we can't make it inline, pretend
+                it was only declared.  */
+             if (DECL_EXTERNAL (decl))
+               {
+                 DECL_INITIAL (decl) = 0;
+                 goto exit_rest_of_compilation;
+               }
+           }
+         else
+           /* ??? Note that this has the effect of making it look
+                like "inline" was specified for a function if we choose
+                to inline it.  This isn't quite right, but it's
+                probably not worth the trouble to fix.  */
+           inlinable = DECL_INLINE (decl) = 1;
+       }
 
       insns = get_insns ();
 
       /* Dump the rtl code if we are dumping rtl.  */
 
-      if (rtl_dump)
+      if (open_dump_file (DFI_rtl, decl))
        {
-         open_dump_file (".rtl", decl_printable_name (decl, 2));
-         
          if (DECL_SAVED_INSNS (decl))
            fprintf (rtl_dump_file, ";; (integrable)\n\n");
-         
-         close_dump_file (print_rtl, insns);
+         close_dump_file (DFI_rtl, print_rtl, insns);
        }
 
       /* If function is inline, and we don't yet know whether to
@@ -3579,17 +2673,23 @@ rest_of_compilation (decl)
         for those functions that need to be output.  Also defer those
         functions that we are supposed to defer.  */
 
-      if (inlinable)
-       DECL_DEFER_OUTPUT (decl) = 1;
-
-      if (DECL_DEFER_OUTPUT (decl)
+      if (inlinable
          || (DECL_INLINE (decl)
              && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
                   && ! flag_keep_inline_functions)
                  || DECL_EXTERNAL (decl))))
-       {
-         DECL_DEFER_OUTPUT (decl) = 1;
+       DECL_DEFER_OUTPUT (decl) = 1;
+
+      if (DECL_INLINE (decl))
+       /* DWARF wants seperate 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);
 
+      if (DECL_DEFER_OUTPUT (decl))
+       {
          /* If -Wreturn-type, we have to do a bit of compilation.
             However, if we just fall through we will call
             save_for_inline_copying() which results in excessive
@@ -3603,34 +2703,20 @@ rest_of_compilation (decl)
              int saved_optimize = optimize;
              optimize = 0;
              find_exception_handler_labels ();
-             jump_optimize (get_insns(), !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
+             jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
                             !JUMP_AFTER_REGSCAN);
              optimize = saved_optimize;
            }
 
-#ifdef DWARF_DEBUGGING_INFO
-         /* Generate the DWARF info for the "abstract" instance
-            of a function which we may later generate inlined and/or
-            out-of-line instances of.  */
-         if (write_symbols == DWARF_DEBUG)
-           {
-             set_decl_abstract_flags (decl, 1);
-             TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
-             set_decl_abstract_flags (decl, 0);
-           }
-#endif
-#ifdef DWARF2_DEBUGGING_INFO
-         /* Generate the DWARF2 info for the "abstract" instance
-            of a function which we may later generate inlined and/or
-            out-of-line instances of.  */
-         if (write_symbols == DWARF2_DEBUG)
-           {
-             set_decl_abstract_flags (decl, 1);
-             TIMEVAR (symout_time, dwarf2out_decl (decl));
-             set_decl_abstract_flags (decl, 0);
-           }
-#endif
-         TIMEVAR (integration_time, save_for_inline_nocopy (decl));
+         current_function_nothrow = nothrow_function_p ();
+         if (current_function_nothrow)
+           /* Now we know that this can't throw; set the flag for the benefit
+              of other functions later in this translation unit.  */
+           TREE_NOTHROW (current_function_decl) = 1;
+
+         timevar_push (TV_INTEGRATION);
+         save_for_inline_nocopy (decl);
+         timevar_pop (TV_INTEGRATION);
          DECL_SAVED_INSNS (decl)->inlinable = inlinable;
          goto exit_rest_of_compilation;
        }
@@ -3642,6 +2728,11 @@ rest_of_compilation (decl)
        goto exit_rest_of_compilation;
     }
 
+  init_EXPR_INSN_LIST_cache ();
+
+  if (ggc_p)
+    ggc_collect ();
+
   /* Initialize some variables used by the optimizers.  */
   init_function_for_compilation ();
 
@@ -3655,13 +2746,24 @@ rest_of_compilation (decl)
 
   /* Don't return yet if -Wreturn-type; we need to do jump_optimize.  */
   if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
-    {
-      goto exit_rest_of_compilation;
-    }
+    goto exit_rest_of_compilation;
 
   /* Emit code to get eh context, if needed. */
   emit_eh_context ();
 
+  /* We may have potential sibling or tail recursion sites.  Select one
+     (of possibly multiple) methods of performing the call.  */
+  if (flag_optimize_sibling_calls)
+    {
+      timevar_push (TV_JUMP);
+      open_dump_file (DFI_sibling, decl);
+
+      optimize_sibling_and_tail_recursive_calls ();
+
+      close_dump_file (DFI_sibling, print_rtl, get_insns ());
+      timevar_pop (TV_JUMP);
+    }
+
 #ifdef FINALIZE_PIC
   /* If we are doing position-independent code generation, now
      is the time to output special prologues and epilogues.
@@ -3683,10 +2785,7 @@ rest_of_compilation (decl)
   insns = get_insns ();
 
   /* Copy any shared structure that should not be shared.  */
-
-  unshare_all_rtl (insns);
-
-  init_EXPR_INSN_LIST_cache ();
+  unshare_all_rtl (current_function_decl, insns);
 
 #ifdef SETJMP_VIA_SAVE_AREA
   /* This must be performed before virutal register instantiation.  */
@@ -3695,35 +2794,64 @@ rest_of_compilation (decl)
 #endif
 
   /* Instantiate all virtual registers.  */
-
-  instantiate_virtual_regs (current_function_decl, get_insns ());
-
-  /* See if we have allocated stack slots that are not directly addressable.
-     If so, scan all the insns and create explicit address computation
-     for all references to such slots.  */
-  /* fixup_stack_slots (); */
+  instantiate_virtual_regs (current_function_decl, insns);
 
   /* Find all the EH handlers.  */
   find_exception_handler_labels ();
 
+  open_dump_file (DFI_jump, decl);
+
   /* Always do one jump optimization pass to ensure that JUMP_LABEL fields
      are initialized and to compute whether control can drop off the end
      of the function.  */
-  TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
-  TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
-                                    JUMP_AFTER_REGSCAN));
+
+  timevar_push (TV_JUMP);
+  /* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB.  Do this
+     before jump optimization switches branch directions.  */
+  expected_value_to_br_prob ();
+
+  reg_scan (insns, max_reg_num (), 0);
+  jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
+                JUMP_AFTER_REGSCAN);
+
+  timevar_pop (TV_JUMP);
 
   /* Now is when we stop if -fsyntax-only and -Wreturn-type.  */
   if (rtl_dump_and_exit || flag_syntax_only || DECL_DEFER_OUTPUT (decl))
-    goto exit_rest_of_compilation;
+    {
+      close_dump_file (DFI_jump, print_rtl, insns);
+      goto exit_rest_of_compilation;
+    }
+
+  timevar_push (TV_JUMP);
+
+  if (optimize > 0)
+    {
+      find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+      cleanup_cfg (insns);
+
+      /* ??? Run if-conversion before delete_null_pointer_checks,
+         since the later does not preserve the CFG.  This should
+        be changed -- no since converting if's that are going to
+        be deleted.  */
+      timevar_push (TV_IFCVT);
+      if_convert (0);
+      timevar_pop (TV_IFCVT);
+
+      /* Try to identify useless null pointer tests and delete them.  */
+      if (flag_delete_null_pointer_checks)
+       delete_null_pointer_checks (insns);
+    }
 
-  /* Try to identify useless null pointer tests and delete them.  */
-  if (flag_delete_null_pointer_checks)
-    TIMEVAR (jump_time, delete_null_pointer_checks (get_insns ()));
+  /* Jump optimization, and the removal of NULL pointer checks, may
+     have reduced the number of instructions substantially.  CSE, and
+     future passes, allocate arrays whose dimensions involve the
+     maximum instruction UID, so if we can reduce the maximum UID
+     we'll save big on memory.  */
+  renumber_insns (rtl_dump_file);
+  timevar_pop (TV_JUMP);
 
-  /* Dump rtl code after jump, if we are doing that.  */
-  if (jump_opt_dump)
-    dump_rtl (".jump", decl, print_rtl, insns);
+  close_dump_file (DFI_jump, print_rtl, insns);
 
   if (ggc_p)
     ggc_collect ();
@@ -3735,120 +2863,157 @@ rest_of_compilation (decl)
 
   if (optimize > 0)
     {
-      if (cse_dump)
-       open_dump_file (".cse", decl_printable_name (decl, 2));
+      open_dump_file (DFI_cse, decl);
+      timevar_push (TV_CSE);
 
-      TIMEVAR (cse_time, reg_scan (insns, max_reg_num (), 1));
+      reg_scan (insns, max_reg_num (), 1);
 
       if (flag_thread_jumps)
-       TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 1));
+       {
+         timevar_push (TV_JUMP);
+         thread_jumps (insns, max_reg_num (), 1);
+         timevar_pop (TV_JUMP);
+       }
 
-      TIMEVAR (cse_time, tem = cse_main (insns, max_reg_num (),
-                                        0, rtl_dump_file));
-      TIMEVAR (cse_time, delete_trivially_dead_insns (insns, max_reg_num ()));
+      tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
 
       /* If we are not running the second CSE pass, then we are no longer
         expecting CSE to be run.  */
       cse_not_expected = !flag_rerun_cse_after_loop;
 
       if (tem || optimize > 1)
-       TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
-                                          !JUMP_NOOP_MOVES,
-                                          !JUMP_AFTER_REGSCAN));
+       {
+         timevar_push (TV_JUMP);
+         jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
+                        !JUMP_AFTER_REGSCAN);
+         timevar_pop (TV_JUMP);
+       }
  
+      /* 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 ());
+
       /* Try to identify useless null pointer tests and delete them.  */
       if (flag_delete_null_pointer_checks)
-       TIMEVAR (jump_time, delete_null_pointer_checks (get_insns ()));
+       {
+         timevar_push (TV_JUMP);
+         find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
 
-      /* Dump rtl code after cse, if we are doing that.  */
+         cleanup_cfg (insns);
 
-      if (cse_dump)
-       {
-         close_dump_file (print_rtl, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".cse", insns);
+         delete_null_pointer_checks (insns);
+         timevar_pop (TV_JUMP);
        }
+
+      /* The second pass of jump optimization is likely to have
+         removed a bunch more instructions.  */
+      renumber_insns (rtl_dump_file);
+
+      timevar_pop (TV_CSE);
+      close_dump_file (DFI_cse, print_rtl, insns);
     }
 
+  open_dump_file (DFI_addressof, decl);
+
   purge_addressof (insns);
   reg_scan (insns, max_reg_num (), 1);
 
-  if (addressof_dump)
-    {
-      dump_rtl (".addressof", decl, print_rtl, insns);
-      if (graph_dump_format != no_graph)
-       print_rtl_graph_with_bb (dump_base_name, ".addressof", insns);
-    }
+  close_dump_file (DFI_addressof, print_rtl, insns);
 
   if (ggc_p)
     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 (insns);
+      convert_to_ssa ();
+
+      close_dump_file (DFI_ssa, print_rtl_with_bb, insns);
+      timevar_pop (TV_TO_SSA);
+
+      /* Currently, there's nothing to do in SSA form.  */
+
+      /* 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);
+
+      if (ggc_p)
+       ggc_collect ();
+    }
+
   /* Perform global cse.  */
 
   if (optimize > 0 && flag_gcse)
     {
-      if (gcse_dump)
-       open_dump_file (".gcse", decl_printable_name (decl, 2));
+      timevar_push (TV_GCSE);
+      open_dump_file (DFI_gcse, decl);
 
-      TIMEVAR (gcse_time, tem = gcse_main (insns, rtl_dump_file));
+      find_basic_blocks (insns, max_reg_num(), rtl_dump_file);
+      cleanup_cfg (insns);
+      tem = gcse_main (insns, rtl_dump_file);
 
       /* If gcse altered any jumps, rerun jump optimizations to clean
         things up.  */
       if (tem)
        {
-         TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
-                                            !JUMP_NOOP_MOVES,
-                                            !JUMP_AFTER_REGSCAN));
+         timevar_push (TV_JUMP);
+         jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
+                        !JUMP_AFTER_REGSCAN);
+         timevar_pop (TV_JUMP);
         }
 
-      if (gcse_dump)
-       {
-         close_dump_file (print_rtl, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".gcse", insns);
-       }
+      close_dump_file (DFI_gcse, print_rtl, insns);
+      timevar_pop (TV_GCSE);
 
       if (ggc_p)
        ggc_collect ();
     }
+
   /* Move constant computations out of loops.  */
 
   if (optimize > 0)
     {
-      if (loop_dump)
-       open_dump_file (".loop", decl_printable_name (decl, 2));
-       
-      TIMEVAR
-       (loop_time,
-        {
-          if (flag_rerun_loop_opt)
-            {
-              /* We only want to perform unrolling once.  */
-              
-              loop_optimize (insns, rtl_dump_file, 0, 0);
+      timevar_push (TV_LOOP);
+      open_dump_file (DFI_loop, decl);
+      
+      if (flag_rerun_loop_opt)
+       {
+         /* We only want to perform unrolling once.  */
               
-       
-              /* The first call to loop_optimize makes some instructions
-                 trivially dead.  We delete those instructions now in the
-                 hope that doing so will make the heuristics in loop work
-                 better and possibly speed up compilation.  */
-              delete_trivially_dead_insns (insns, max_reg_num ());
-
-              /* The regscan pass is currently necessary as the alias
-                 analysis code depends on this information.  */
-              reg_scan (insns, max_reg_num (), 1);
-            }
-          loop_optimize (insns, rtl_dump_file, flag_unroll_loops, 1);
-        });
+         loop_optimize (insns, rtl_dump_file, 0, 0);
 
-      /* Dump rtl code after loop opt, if we are doing that.  */
+         /* The first call to loop_optimize makes some instructions
+            trivially dead.  We delete those instructions now in the
+            hope that doing so will make the heuristics in loop work
+            better and possibly speed up compilation.  */
+         delete_trivially_dead_insns (insns, max_reg_num ());
 
-      if (loop_dump)
-       {
-         close_dump_file (print_rtl, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".loop", insns);
+         /* The regscan pass is currently necessary as the alias
+                 analysis code depends on this information.  */
+         reg_scan (insns, max_reg_num (), 1);
        }
+      loop_optimize (insns, rtl_dump_file, flag_unroll_loops, 1);
+
+      close_dump_file (DFI_loop, print_rtl, insns);
+      timevar_pop (TV_LOOP);
 
       if (ggc_p)
        ggc_collect ();
@@ -3856,8 +3021,8 @@ rest_of_compilation (decl)
 
   if (optimize > 0)
     {
-      if (cse2_dump)
-       open_dump_file (".cse2", decl_printable_name (decl, 2));
+      timevar_push (TV_CSE2);
+      open_dump_file (DFI_cse2, decl);
 
       if (flag_rerun_cse_after_loop)
        {
@@ -3866,245 +3031,275 @@ rest_of_compilation (decl)
             the second CSE pass to do a better job.  Jump_optimize can change
             max_reg_num so we must rerun reg_scan afterwards.
             ??? Rework to not call reg_scan so often.  */
-         TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
-         TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
-                                            !JUMP_NOOP_MOVES,
-                                            JUMP_AFTER_REGSCAN));
+         timevar_push (TV_JUMP);
+
+         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 (insns);
+         if_convert (0);
+
+         timevar_pop(TV_IFCVT);
+
+         timevar_pop (TV_JUMP);
          
-         TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0));
-         TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (),
-                                             1, rtl_dump_file));
+         reg_scan (insns, max_reg_num (), 0);
+         tem = cse_main (insns, max_reg_num (), 1, rtl_dump_file);
+
          if (tem)
-           TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
-                                              !JUMP_NOOP_MOVES,
-                                              !JUMP_AFTER_REGSCAN));
+           {
+             timevar_push (TV_JUMP);
+             jump_optimize (insns, !JUMP_CROSS_JUMP,
+                            !JUMP_NOOP_MOVES, !JUMP_AFTER_REGSCAN);
+             timevar_pop (TV_JUMP);
+           }
        }
 
       if (flag_thread_jumps)
        {
          /* This pass of jump threading straightens out code
             that was kinked by loop optimization.  */
-         TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
-         TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0));
+         timevar_push (TV_JUMP);
+         reg_scan (insns, max_reg_num (), 0);
+         thread_jumps (insns, max_reg_num (), 0);
+         timevar_pop (TV_JUMP);
        }
 
-      /* Dump rtl code after cse, if we are doing that.  */
-
-      if (cse2_dump)
-       {
-         close_dump_file (print_rtl, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".cse2", insns);
-       }
+      close_dump_file (DFI_cse2, print_rtl, insns);
+      timevar_pop (TV_CSE2);
 
       if (ggc_p)
        ggc_collect ();
     }
 
+  cse_not_expected = 1;
+
   if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
     {
-      if (branch_prob_dump)
-       open_dump_file (".bp", decl_printable_name (decl, 2));
+      timevar_push (TV_BRANCH_PROB);
+      open_dump_file (DFI_bp, decl);
 
-      TIMEVAR
-       (branch_prob_time,
-        {
-          branch_prob (insns, rtl_dump_file);
-        });
+      branch_prob (insns, rtl_dump_file);
 
-      if (branch_prob_dump)
-       {
-         close_dump_file (print_rtl, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".bp", insns);
-       }
+      close_dump_file (DFI_bp, print_rtl, insns);
+      timevar_pop (TV_BRANCH_PROB);
 
       if (ggc_p)
        ggc_collect ();
     }
 
-  /* We are no longer anticipating cse in this function, at least.  */
-
-  cse_not_expected = 1;
-
-  /* Now we choose between stupid (pcc-like) register allocation
-     (if we got the -noreg switch and not -opt)
-     and smart register allocation.  */
-
-  if (optimize > 0)            /* Stupid allocation probably won't work */
-    obey_regdecls = 0;         /* if optimizations being done.  */
-
   regclass_init ();
 
   /* Print function header into flow dump now
      because doing the flow analysis makes some of the dump.  */
 
-  if (flow_dump)
-    open_dump_file (".flow", decl_printable_name (decl, 2));
+  open_dump_file (DFI_flow, decl);
   
-  if (obey_regdecls)
-    {
-      TIMEVAR (flow_time,
-              {
-                regclass (insns, max_reg_num ());
-                stupid_life_analysis (insns, max_reg_num (),
-                                      rtl_dump_file);
-              });
-    }
-  else
+  /* Do control and data flow analysis; wrote some of the results to
+     the dump file.  */
+
+  timevar_push (TV_FLOW);
+  find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+  cleanup_cfg (insns);
+  if (optimize)
     {
-      /* Do control and data flow analysis,
-        and write some of the results to dump file.  */
+      struct loops loops;
 
-      TIMEVAR
-       (flow_time,
-        {
-          find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
-          life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
-        });
+      /* Discover and record the loop depth at the head of each basic
+        block.  The loop infrastructure does the real job for us.  */
+      flow_loops_find (&loops);
 
-      if (warn_uninitialized)
-       {
-         uninitialized_vars_warning (DECL_INITIAL (decl));
-         setjmp_args_warning ();
-       }
-    }
+      /* Estimate using heuristics if no profiling info is available.  */
+      if (! flag_branch_probabilities)
+       estimate_probability (&loops);
+
+      if (rtl_dump_file)
+       flow_loops_dump (&loops, rtl_dump_file, 0);
 
-  /* Dump rtl after flow analysis.  */
+      flow_loops_free (&loops);
+    }
+  life_analysis (insns, rtl_dump_file, PROP_FINAL);
+  mark_constant_function ();
+  timevar_pop (TV_FLOW);
 
-  if (flow_dump)
+  if (warn_uninitialized || extra_warnings)
     {
-      close_dump_file (print_rtl_with_bb, insns);
-      if (graph_dump_format != no_graph)
-       print_rtl_graph_with_bb (dump_base_name, ".flow", insns);
+      uninitialized_vars_warning (DECL_INITIAL (decl));
+      if (extra_warnings)
+       setjmp_args_warning ();
     }
 
+  close_dump_file (DFI_flow, print_rtl_with_bb, insns);
+
   if (ggc_p)
     ggc_collect ();
 
-  /* The first life analysis pass has finished.  From now on we can not
-     generate any new pseudos.  */
-  no_new_pseudos = 1;
-
   /* If -opt, try combining insns through substitution.  */
 
   if (optimize > 0)
     {
-      TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
+      int rebuild_jump_labels_after_combine = 0;
 
-      /* Dump rtl code after insn combination.  */
+      timevar_push (TV_COMBINE);
+      open_dump_file (DFI_combine, decl);
 
-      if (combine_dump)
+      rebuild_jump_labels_after_combine
+       = combine_instructions (insns, max_reg_num ());
+      
+      /* Combining insns may have turned an indirect jump into a
+        direct jump.  Rebuid the JUMP_LABEL fields of jumping
+        instructions.  */
+      if (rebuild_jump_labels_after_combine)
        {
-         dump_rtl (".combine", decl, print_rtl_with_bb, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".combine", insns);
+         timevar_push (TV_JUMP);
+         rebuild_jump_labels (insns);
+         timevar_pop (TV_JUMP);
+
+         timevar_push (TV_FLOW);
+         find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+         cleanup_cfg (insns);
+
+         /* 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);
+
+         timevar_pop (TV_FLOW);
        }
 
+      close_dump_file (DFI_combine, print_rtl_with_bb, insns);
+      timevar_pop (TV_COMBINE);
+
       if (ggc_p)
        ggc_collect ();
     }
 
+  /* Rerun if-conversion, as combine may have simplified things enough to
+     now meet sequence length restrictions.  */
+  if (optimize > 0)
+    {
+      timevar_push (TV_IFCVT);
+      open_dump_file (DFI_ce, decl);
+
+      if_convert (1);
+
+      close_dump_file (DFI_ce, print_rtl_with_bb, insns);
+      timevar_pop (TV_IFCVT);
+    }
+
   /* Register allocation pre-pass, to reduce number of moves
      necessary for two-address machines.  */
   if (optimize > 0 && (flag_regmove || flag_expensive_optimizations))
     {
-      if (regmove_dump)
-       open_dump_file (".regmove", decl_printable_name (decl, 2));
+      timevar_push (TV_REGMOVE);
+      open_dump_file (DFI_regmove, decl);
 
-      TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (),
-                                              rtl_dump_file));
+      regmove_optimize (insns, max_reg_num (), rtl_dump_file);
 
-      if (regmove_dump)
-       {
-         close_dump_file (print_rtl_with_bb, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".regmove", insns);
-       }
+      close_dump_file (DFI_regmove, print_rtl_with_bb, insns);
+      timevar_pop (TV_REGMOVE);
 
       if (ggc_p)
        ggc_collect ();
     }
 
+  if (optimize && n_basic_blocks)
+    {
+      timevar_push (TV_GCSE);
+      optimize_mode_switching (NULL_PTR);
+      timevar_pop (TV_GCSE);
+    }
+
+#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)
     {
-      if (sched_dump)
-       open_dump_file (".sched", decl_printable_name (decl, 2));
+      timevar_push (TV_SCHED);
+      open_dump_file (DFI_sched, decl);
 
       /* Do control and data sched analysis,
         and write some of the results to dump file.  */
 
-      TIMEVAR (sched_time, schedule_insns (rtl_dump_file));
-
-      /* Dump rtl after instruction scheduling.  */
+      schedule_insns (rtl_dump_file);
 
-      if (sched_dump)
-       {
-         close_dump_file (print_rtl_with_bb, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".sched", insns);
-       }
+      close_dump_file (DFI_sched, print_rtl_with_bb, insns);
+      timevar_pop (TV_SCHED);
 
       if (ggc_p)
        ggc_collect ();
+
+      /* Register lifetime information is up to date.  From now on
+        we can not generate any new pseudos.  */
+      no_new_pseudos = 1;
     }
+#endif
 
   /* Determine if the current function is a leaf before running reload
      since this can impact optimizations done by the prologue and
      epilogue thus changing register elimination offsets.  */
   current_function_is_leaf = leaf_function_p ();
 
-  /* Unless we did stupid register allocation,
-     allocate pseudo-regs that are used only within 1 basic block. 
+  timevar_push (TV_LOCAL_ALLOC);
+  open_dump_file (DFI_lreg, decl);
+
+  /* Allocate pseudo-regs that are used only within 1 basic block. 
 
      RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the
      jump optimizer after register allocation and reloading are finished.  */
 
-  if (!obey_regdecls)
-    TIMEVAR (local_alloc_time,
-            {
-              recompute_reg_usage (insns, ! optimize_size);
-              regclass (insns, max_reg_num ());
-              rebuild_label_notes_after_reload = local_alloc ();
-            });
-  else
-    rebuild_label_notes_after_reload = 0;
+  /* We recomputed reg usage as part of updating the rest
+     of life info during sched.  */
+  if (! flag_schedule_insns)
+    {
+      recompute_reg_usage (insns, ! optimize_size);
+
+      /* Register lifetime information is up to date.  From now on
+        we can not generate any new pseudos.  */
+      no_new_pseudos = 1;
+    }
+  regclass (insns, max_reg_num (), rtl_dump_file);
+  rebuild_label_notes_after_reload = local_alloc ();
 
-  /* Dump rtl code after allocating regs within basic blocks.  */
+  timevar_pop (TV_LOCAL_ALLOC);
 
-  if (local_reg_dump)
+  if (dump_file[DFI_lreg].enabled)
     {
-      open_dump_file (".lreg", decl_printable_name (decl, 2));
+      timevar_push (TV_DUMP);
 
-      TIMEVAR (dump_time, dump_flow_info (rtl_dump_file));
-      TIMEVAR (dump_time, dump_local_alloc (rtl_dump_file));
+      dump_flow_info (rtl_dump_file);
+      dump_local_alloc (rtl_dump_file);
 
-      close_dump_file (print_rtl_with_bb, insns);
-      if (graph_dump_format != no_graph)
-       print_rtl_graph_with_bb (dump_base_name, ".lreg", insns);
+      close_dump_file (DFI_lreg, print_rtl_with_bb, insns);
+      timevar_pop (TV_DUMP);
     }
 
   if (ggc_p)
     ggc_collect ();
 
-  if (global_reg_dump)
-    open_dump_file (".greg", decl_printable_name (decl, 2));
+  timevar_push (TV_GLOBAL_ALLOC);
+  open_dump_file (DFI_greg, decl);
 
-  /* Unless we did stupid register allocation,
-     allocate remaining pseudo-regs, then do the reload pass
-     fixing up any insns that are invalid.  */
+  /* If optimizing, allocate remaining pseudo-regs.  Do the reload
+     pass fixing up any insns that are invalid.  */
 
-  TIMEVAR (global_alloc_time,
-          {
-            if (!obey_regdecls)
-              failure = global_alloc (rtl_dump_file);
-            else
-              failure = reload (insns, 0, rtl_dump_file);
-          });
+  if (optimize)
+    failure = global_alloc (rtl_dump_file);
+  else
+    {
+      build_insn_chain (insns);
+      failure = reload (insns, 0, rtl_dump_file);
+    }
 
+  timevar_pop (TV_GLOBAL_ALLOC);
 
   if (failure)
     goto exit_rest_of_compilation;
@@ -4114,62 +3309,65 @@ rest_of_compilation (decl)
 
   /* Do a very simple CSE pass over just the hard registers.  */
   if (optimize > 0)
-    reload_cse_regs (insns);
+    {
+      timevar_push (TV_RELOAD_CSE_REGS);
+      reload_cse_regs (insns);
+      timevar_pop (TV_RELOAD_CSE_REGS); 
+    }
+
+  /* If optimizing, then go ahead and split insns now since we are about
+     to recompute flow information anyway.  */
+  if (optimize > 0)
+    split_all_insns (0);
 
   /* 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.  */
   if (rebuild_label_notes_after_reload)
-    TIMEVAR (jump_time, rebuild_jump_labels (insns));
-
-  /* If optimizing and we are performing instruction scheduling after
-     reload, then go ahead and split insns now since we are about to
-     recompute flow information anyway.
-
-     reload_cse_regs may expose more splitting opportunities, expecially
-     for double-word operations.  */
-  if (optimize > 0 && flag_schedule_insns_after_reload)
     {
-      rtx insn;
+      timevar_push (TV_JUMP);
 
-      for (insn = insns; insn; insn = NEXT_INSN (insn))
-       {
-         rtx last;
-
-         if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
-           continue;
-
-         last = try_split (PATTERN (insn), insn, 1);
+      rebuild_jump_labels (insns);
 
-         if (last != insn)
-           {
-             PUT_CODE (insn, NOTE);
-             NOTE_SOURCE_FILE (insn) = 0;
-             NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
-           }
-       }
+      timevar_pop (TV_JUMP);
     }
 
-  if (global_reg_dump)
+  if (dump_file[DFI_greg].enabled)
     {
-      TIMEVAR (dump_time, dump_global_regs (rtl_dump_file));
-      close_dump_file (print_rtl_with_bb, insns);
-      if (graph_dump_format != no_graph)
-       print_rtl_graph_with_bb (dump_base_name, ".greg", insns);
+      timevar_push (TV_DUMP);
+
+      dump_global_regs (rtl_dump_file);
+
+      close_dump_file (DFI_greg, print_rtl_with_bb, insns);
+      timevar_pop (TV_DUMP);
     }
 
   /* Re-create the death notes which were deleted during reload.  */
-  if (flow2_dump)
-    open_dump_file (".flow2", decl_printable_name (decl, 2));
-  
+  timevar_push (TV_FLOW2);
+  open_dump_file (DFI_flow2, decl);
+
+  jump_optimize_minimal (insns);
+  find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+
+  /* On some machines, the prologue and epilogue code, or parts thereof,
+     can be represented as RTL.  Doing so lets us schedule insns between
+     it and the rest of the code and also allows delayed branch
+     scheduling to operate in the epilogue.  */
+  thread_prologue_and_epilogue_insns (insns);
+
   if (optimize)
     {
-      TIMEVAR
-       (flow2_time,
-        {
-          find_basic_blocks (insns, max_reg_num (), rtl_dump_file, 1);
-          life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
-        });
+      cleanup_cfg (insns);
+      life_analysis (insns, rtl_dump_file, PROP_FINAL);
+
+      /* This is kind of heruistics.  We need to run combine_stack_adjustments
+         even for machines with possibly nonzero RETURN_POPS_ARGS
+         and ACCUMULATE_OUTGOING_ARGS.  We expect that only ports having
+         push instructions will have popping returns.  */
+#ifndef PUSH_ROUNDING
+      if (!ACCUMULATE_OUTGOING_ARGS)
+#endif
+       combine_stack_adjustments ();
 
       if (ggc_p)
        ggc_collect ();
@@ -4177,102 +3375,106 @@ rest_of_compilation (decl)
 
   flow2_completed = 1;
 
-  /* On some machines, the prologue and epilogue code, or parts thereof,
-     can be represented as RTL.  Doing so lets us schedule insns between
-     it and the rest of the code and also allows delayed branch
-     scheduling to operate in the epilogue.  */
-
-  thread_prologue_and_epilogue_insns (insns);
+  close_dump_file (DFI_flow2, print_rtl_with_bb, insns);
+  timevar_pop (TV_FLOW2);
 
-  if (flow2_dump)
+  if (optimize > 0)
     {
-      close_dump_file (print_rtl_with_bb, insns);
-      if (graph_dump_format != no_graph)
-       print_rtl_graph_with_bb (dump_base_name, ".flow2", insns);
+      timevar_push (TV_IFCVT2);
+      open_dump_file (DFI_ce2, decl);
+
+      if_convert (1);
+
+      close_dump_file (DFI_ce2, print_rtl_with_bb, insns);
+      timevar_pop (TV_IFCVT2);
     }
 
 #ifdef HAVE_peephole2
   if (optimize > 0 && flag_peephole2)
     {
-      if (peephole2_dump)
-       open_dump_file (".peephole2", decl_printable_name (decl, 2));
+      timevar_push (TV_PEEPHOLE2);
+      open_dump_file (DFI_peephole2, decl);
 
       peephole2_optimize (rtl_dump_file);
 
-      if (peephole2_dump)
-       {
-         close_dump_file (print_rtl_with_bb, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".peephole2", insns);
-       }
+      close_dump_file (DFI_peephole2, print_rtl_with_bb, insns);
+      timevar_pop (TV_PEEPHOLE2);
     }
 #endif
 
+#ifdef INSN_SCHEDULING
   if (optimize > 0 && flag_schedule_insns_after_reload)
     {
-      if (sched2_dump)
-       open_dump_file (".sched2", decl_printable_name (decl, 2));
+      timevar_push (TV_SCHED2);
+      open_dump_file (DFI_sched2, decl);
 
       /* Do control and data sched analysis again,
         and write some more of the results to dump file.  */
 
-      TIMEVAR (sched2_time, schedule_insns (rtl_dump_file));
+      schedule_insns (rtl_dump_file);
 
-      /* Dump rtl after post-reorder instruction scheduling.  */
-
-      if (sched2_dump)
-       {
-         close_dump_file (print_rtl_with_bb, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".sched2", insns);
-       }
+      close_dump_file (DFI_sched2, print_rtl_with_bb, insns);
+      timevar_pop (TV_SCHED2);
 
       if (ggc_p)
        ggc_collect ();
     }
+#endif
 
 #ifdef LEAF_REGISTERS
   current_function_uses_only_leaf_regs
     = optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
 #endif
 
-  /* 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 && flag_reorder_blocks)
+    {
+      timevar_push (TV_REORDER_BLOCKS);
+      open_dump_file (DFI_bbro, decl);
+
+      reorder_basic_blocks ();
+
+      close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
+      timevar_pop (TV_REORDER_BLOCKS);
+    }    
+
+  if (optimize > 0 && flag_rename_registers)
+    {
+      timevar_push (TV_RENAME_REGISTERS);
+      open_dump_file (DFI_rnreg, decl);
+
+      regrename_optimize ();
+
+      close_dump_file (DFI_rnreg, print_rtl_with_bb, insns);
+      timevar_pop (TV_RENAME_REGISTERS);
+    }    
+
+  /* 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 (jump_time, jump_optimize (insns, JUMP_CROSS_JUMP,
-                                        JUMP_NOOP_MOVES,
-                                        !JUMP_AFTER_REGSCAN));
+      timevar_push (TV_JUMP);
+      open_dump_file (DFI_jump2, decl);
 
-      /* Dump rtl code after jump, if we are doing that.  */
+      jump_optimize (insns, JUMP_CROSS_JUMP, JUMP_NOOP_MOVES, 
+                    !JUMP_AFTER_REGSCAN);
 
-      if (jump2_opt_dump)
-       {
-         dump_rtl (".jump2", decl, print_rtl_with_bb, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".jump2", insns);
-       }
+      /* CFG no longer kept up to date.  */
+
+      close_dump_file (DFI_jump2, print_rtl_with_bb, insns);
+      timevar_pop (TV_JUMP);
     }
 
   /* If a machine dependent reorganization is needed, call it.  */
 #ifdef MACHINE_DEPENDENT_REORG
-  if (mach_dep_reorg_dump)
-    open_dump_file (".mach", decl_printable_name (decl, 2));
+  open_dump_file (DFI_mach, decl);
 
-   MACHINE_DEPENDENT_REORG (insns);
+  MACHINE_DEPENDENT_REORG (insns);
 
-   if (mach_dep_reorg_dump)
-     {
-       close_dump_file (print_rtl_with_bb, insns);
-       if (graph_dump_format != no_graph)
-        print_rtl_graph_with_bb (dump_base_name, ".mach", insns);
-     }
+  close_dump_file (DFI_mach, print_rtl_with_bb, insns);
 
-   if (ggc_p)
-     ggc_collect ();
+  if (ggc_p)
+    ggc_collect ();
 #endif
 
   /* If a scheduling pass for delayed branches is to be done,
@@ -4281,82 +3483,83 @@ rest_of_compilation (decl)
 #ifdef DELAY_SLOTS
   if (optimize > 0 && flag_delayed_branch)
     {
-      if (dbr_sched_dump)
-       open_dump_file (".dbr", decl_printable_name (decl, 2));
+      timevar_push (TV_DBR_SCHED);
+      open_dump_file (DFI_dbr, decl);
 
-      TIMEVAR (dbr_sched_time, dbr_schedule (insns, rtl_dump_file));
+      dbr_schedule (insns, rtl_dump_file);
 
-      if (dbr_sched_dump)
-       {
-         close_dump_file (print_rtl_with_bb, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".dbr", insns);
-       }
-    }
+      close_dump_file (DFI_dbr, print_rtl_with_bb, insns);
+      timevar_pop (TV_DBR_SCHED);
 
-   if (ggc_p)
-     ggc_collect ();
+      if (ggc_p)
+       ggc_collect ();
+    }
 #endif
 
-  /* Shorten branches.  */
-  TIMEVAR (shorten_branch_time,
-          {
-            shorten_branches (get_insns ());
-          });
+  /* Shorten branches. 
+
+     Note this must run before reg-stack because of death note (ab)use
+     in the ia32 backend.  */
+  timevar_push (TV_SHORTEN_BRANCH);
+  shorten_branches (get_insns ());
+  timevar_pop (TV_SHORTEN_BRANCH);
 
 #ifdef STACK_REGS
-  if (stack_reg_dump)
-    open_dump_file (".stack", decl_printable_name (decl, 2));
+  timevar_push (TV_REG_STACK);
+  open_dump_file (DFI_stack, decl);
 
-  TIMEVAR (stack_reg_time, reg_to_stack (insns, rtl_dump_file));
+  reg_to_stack (insns, rtl_dump_file);
 
-  if (stack_reg_dump)
-    {
-      dump_rtl (".stack", decl, print_rtl_with_bb, insns);
-      if (graph_dump_format != no_graph)
-       print_rtl_graph_with_bb (dump_base_name, ".stack", insns);
-    }
+  close_dump_file (DFI_stack, print_rtl_with_bb, insns);
+  timevar_pop (TV_REG_STACK);
 
-   if (ggc_p)
-     ggc_collect ();
+  if (ggc_p)
+    ggc_collect ();
 #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
+       of other functions later in this translation unit.  */
+    TREE_NOTHROW (current_function_decl) = 1;
+
   /* Now turn the rtl into assembler code.  */
 
-  TIMEVAR (final_time,
-          {
-            rtx x;
-            char *fnname;
+  timevar_push (TV_FINAL);
+  {
+    rtx x;
+    const char *fnname;
 
-            /* Get the function's name, as described by its RTL.
+    /* Get the function's name, as described by its RTL.
                This may be different from the DECL_NAME name used
                in the source file.  */
 
-            x = DECL_RTL (decl);
-            if (GET_CODE (x) != MEM)
-              abort ();
-            x = XEXP (x, 0);
-            if (GET_CODE (x) != SYMBOL_REF)
-              abort ();
-            fnname = XSTR (x, 0);
-
-            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);
-            assemble_end_function (decl, fnname);
-            if (! quiet_flag)
-              fflush (asm_out_file);
+    x = DECL_RTL (decl);
+    if (GET_CODE (x) != MEM)
+      abort ();
+    x = XEXP (x, 0);
+    if (GET_CODE (x) != SYMBOL_REF)
+      abort ();
+    fnname = XSTR (x, 0);
+
+    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);
+    assemble_end_function (decl, fnname);
+    if (! quiet_flag)
+      fflush (asm_out_file);
 
             /* Release all memory allocated by flow.  */
-            free_basic_block_vars (0);
+    free_basic_block_vars (0);
 
-            /* Release all memory held by regsets now */
-            regset_release_memory ();
-          });
+    /* Release all memory held by regsets now */
+    regset_release_memory ();
+  }
+  timevar_pop (TV_FINAL);
 
-   if (ggc_p)
-     ggc_collect ();
+  if (ggc_p)
+    ggc_collect ();
 
   /* Write DBX symbols if requested */
 
@@ -4368,25 +3571,25 @@ rest_of_compilation (decl)
      for those inline functions that need to have out-of-line copies
      generated.  During that call, we *will* be routed past here.  */
 
+  timevar_push (TV_SYMOUT);
 #ifdef DBX_DEBUGGING_INFO
   if (write_symbols == DBX_DEBUG)
-    TIMEVAR (symout_time, dbxout_function (decl));
+    dbxout_function (decl);
 #endif
 
 #ifdef DWARF_DEBUGGING_INFO
   if (write_symbols == DWARF_DEBUG)
-    TIMEVAR (symout_time, dwarfout_file_scope_decl (decl, 0));
+    dwarfout_file_scope_decl (decl, 0);
 #endif
 
 #ifdef DWARF2_DEBUGGING_INFO
   if (write_symbols == DWARF2_DEBUG)
-    TIMEVAR (symout_time, dwarf2out_decl (decl));
+    dwarf2out_decl (decl);
 #endif
+  timevar_pop (TV_SYMOUT);
 
  exit_rest_of_compilation:
 
-  free_bb_mem ();
-
   /* In case the function was not output,
      don't leave any temporary anonymous types
      queued up for sdb output.  */
@@ -4395,40 +3598,29 @@ rest_of_compilation (decl)
     sdbout_types (NULL_TREE);
 #endif
 
-  /* Put back the tree of subblocks and list of arguments
-     from before we copied them.
-     Code generation and the output of debugging info may have modified
-     the copy, but the original is unchanged.  */
-
-  if (saved_block_tree != 0)
-    {
-      DECL_INITIAL (decl) = saved_block_tree;
-      DECL_ARGUMENTS (decl) = saved_arguments;
-      DECL_ABSTRACT_ORIGIN (decl) = NULL_TREE;
-    }
-
   reload_completed = 0;
   flow2_completed = 0;
   no_new_pseudos = 0;
 
-  TIMEVAR (final_time,
-          {
-             /* Clear out the insn_length contents now that they are no
-                longer valid.  */
-             init_insn_lengths ();
+  timevar_push (TV_FINAL);
 
-             /* Clear out the real_constant_chain before some of the rtx's
+  /* Clear out the insn_length contents now that they are no
+     longer valid.  */
+  init_insn_lengths ();
+
+  /* Clear out the real_constant_chain before some of the rtx's
                 it runs through become garbage.  */
-             clear_const_double_mem ();
+  clear_const_double_mem ();
+
+  /* Cancel the effect of rtl_in_current_obstack.  */
+  resume_temporary_allocation ();
 
-             /* Cancel the effect of rtl_in_current_obstack.  */
-             resume_temporary_allocation ();
+  /* Show no temporary slots allocated.  */
+  init_temp_slots ();
 
-             /* Show no temporary slots allocated.  */
-             init_temp_slots ();
+  free_basic_block_vars (0);
 
-             free_basic_block_vars (0);
-          });
+  timevar_pop (TV_FINAL);
 
   /* Make sure volatile mem refs aren't considered valid operands for
      arithmetic insns.  We must call this here if this is a nested inline
@@ -4442,18 +3634,15 @@ rest_of_compilation (decl)
   init_recog_no_volatile ();
 
   /* We're done with this function.  Free up memory if we can.  */
-  free_after_parsing (current_function);
+  free_after_parsing (cfun);
   if (! DECL_DEFER_OUTPUT (decl))
-    free_after_compilation (current_function);
-  current_function = 0;
+    free_after_compilation (cfun);
+  cfun = 0;
 
   if (ggc_p)
     ggc_collect ();
 
-  /* The parsing time is all the time spent in yyparse
-     *except* what is spent in this function.  */
-
-  parse_time -= get_run_time () - start_time;
+  timevar_pop (TV_REST_OF_COMPILATION);
 }
 \f
 static void
@@ -4522,7 +3711,7 @@ display_help ()
   printf ("  -d[letters]             Enable dumps from specific passes of the compiler\n");
   printf ("  -dumpbase <file>        Base name to be used for dumps from specific passes\n");
 #if defined INSN_SCHEDULING
-  printf ("  -sched-verbose=<number> Set the verbosity level of the scheduler\n");
+  printf ("  -fsched-verbose=<number> Set the verbosity level of the scheduler\n");
 #endif
   printf ("  --help                  Display this information\n");
 
@@ -4640,130 +3829,48 @@ static void
 decode_d_option (arg)
      const char * arg;
 {
-  while (* arg)
-    switch (* arg ++)
+  int i, c, matched;
+
+  while (*arg)
+    switch (c = *arg++)
       {
       case 'a':
-       branch_prob_dump = 1;
-       combine_dump = 1;
-#ifdef DELAY_SLOTS
-       dbr_sched_dump = 1;
-#endif
-       flow_dump = 1;
-       flow2_dump = 1;
-       global_reg_dump = 1;
-       jump_opt_dump = 1;
-       addressof_dump = 1;
-       jump2_opt_dump = 1;
-       local_reg_dump = 1;
-       loop_dump = 1;
-       regmove_dump = 1;
-       rtl_dump = 1;
-       cse_dump = 1;
-       cse2_dump = 1;
-       gcse_dump = 1;
-       sched_dump = 1;
-       sched2_dump = 1;
-#ifdef STACK_REGS
-       stack_reg_dump = 1;
-#endif
-#ifdef MACHINE_DEPENDENT_REORG
-       mach_dep_reorg_dump = 1;
-#endif
-       peephole2_dump = 1;
+       for (i = 0; i < DFI_MAX; ++i)
+         dump_file[i].enabled = 1;
        break;
       case 'A':
        flag_debug_asm = 1;
        break;
-      case 'b':
-       branch_prob_dump = 1;
-       break;
-      case 'c':
-       combine_dump = 1;
-       break;
-#ifdef DELAY_SLOTS
-      case 'd':
-       dbr_sched_dump = 1;
-       break;
-#endif
-      case 'f':
-       flow_dump = 1;
-       break;
-      case 'F':
-       addressof_dump = 1;
-       break;
-      case 'g':
-       global_reg_dump = 1;
-       break;
-      case 'G':
-       gcse_dump = 1;
-       break;
-      case 'j':
-       jump_opt_dump = 1;
-       break;
-      case 'J':
-       jump2_opt_dump = 1;
-       break;
-#ifdef STACK_REGS                  
-      case 'k':
-       stack_reg_dump = 1;
-       break;
-#endif
-      case 'l':
-       local_reg_dump = 1;
-       break;
-      case 'L':
-       loop_dump = 1;
-       break;
       case 'm':
        flag_print_mem = 1;
        break;
-#ifdef MACHINE_DEPENDENT_REORG
-      case 'M':
-       mach_dep_reorg_dump = 1;
-       break;
-#endif
       case 'p':
        flag_print_asm_name = 1;
        break;
-      case 'r':
-       rtl_dump = 1;
-       break;
-      case 'R':
-       sched2_dump = 1;
-       break;
-      case 's':
-       cse_dump = 1;
-       break;
-      case 'S':
-       sched_dump = 1;
-       break;
-      case 't':
-       cse2_dump = 1;
-       break;
-      case 'N':
-       regmove_dump = 1;
-       break;
       case 'v':
        graph_dump_format = vcg;
        break;
-      case 'w':
-       flow2_dump = 1;
-       break;
       case 'x':
        rtl_dump_and_exit = 1;
        break;
       case 'y':
        set_yydebug (1);
        break;
-      case 'z':
-       peephole2_dump = 1;
-       break;
       case 'D':        /* These are handled by the preprocessor.  */
       case 'I':
        break;
+
       default:
-       warning ("unrecognised gcc debugging option: %c", arg[-1]);
+       matched = 0;
+       for (i = 0; i < DFI_MAX; ++i)
+         if (c == dump_file[i].debug_switch)
+           {
+             dump_file[i].enabled = 1;
+             matched = 1;
+           }
+
+       if (! matched)
+         warning ("unrecognized gcc debugging option: %c", c);
        break;
       }
 }
@@ -4801,26 +3908,45 @@ decode_f_option (arg)
       read_integral_parameter (arg + 13, arg - 2, inline_max_insns);
 #ifdef INSN_SCHEDULING
   else if (!strncmp (arg, "sched-verbose=", 14))
-    fix_sched_param ("verbose", (char *)(arg + 14));
+    fix_sched_param ("verbose", (const char *)(arg + 14));
 #endif
   else if (!strncmp (arg, "fixed-", 6))
-    fix_register ((char *)(arg + 6), 1, 1);
+    fix_register ((const char *)(arg + 6), 1, 1);
   else if (!strncmp (arg, "call-used-", 10))
-    fix_register ((char *)(arg + 10), 0, 1);
+    fix_register ((const char *)(arg + 10), 0, 1);
   else if (!strncmp (arg, "call-saved-", 11))
-    fix_register ((char *)(arg + 11), 0, 0);
+    fix_register ((const char *)(arg + 11), 0, 0);
   else if (!strncmp (arg, "align-loops=", 12))
     align_loops = read_integral_parameter (arg + 12, arg - 2, align_loops);
   else if (!strncmp (arg, "align-functions=", 16))
-    align_functions =
-      read_integral_parameter (arg + 16, arg - 2, align_functions);
+    align_functions
+      read_integral_parameter (arg + 16, arg - 2, align_functions);
   else if (!strncmp (arg, "align-jumps=", 12))
     align_jumps = read_integral_parameter (arg + 12, arg - 2, align_jumps);
   else if (!strncmp (arg, "align-labels=", 13))
     align_labels = read_integral_parameter (arg + 13, arg - 2, align_labels);
+  else if (!strncmp (arg, "stack-limit-register=", 21))
+    {
+      int reg = decode_reg_name (arg + 21);
+      if (reg < 0)
+       error ("unrecognized register name `%s'", arg + 21);
+      else
+       stack_limit_rtx = gen_rtx_REG (Pmode, reg);
+    }
+  else if (!strncmp (arg, "stack-limit-symbol=", 19))
+    {
+      char *nm;
+      if (ggc_p)
+       nm = ggc_alloc_string (arg + 19, strlen (arg + 19));
+      else
+       nm = xstrdup (arg + 19);
+      stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, nm);
+    }
+  else if (!strcmp (arg, "no-stack-limit"))
+    stack_limit_rtx = NULL_RTX;
   else if (!strcmp (arg, "preprocessed"))
     /* Recognise this switch but do nothing.  This prevents warnings
-       about an unrecognised switch if cpplib has not been linked in.  */
+       about an unrecognized switch if cpplib has not been linked in.  */
     ;
   else
     return 0;
@@ -4831,6 +3957,7 @@ decode_f_option (arg)
 /* Parse a -W... comand 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.  */
+
 static int
 decode_W_option (arg)
      const char * arg;
@@ -4857,23 +3984,17 @@ decode_W_option (arg)
 
   if (!strncmp (arg, "id-clash-", 9))
     {
-      const int id_clash_val = read_integral_parameter (arg + 9, arg - 2, -1);
+      id_clash_len = read_integral_parameter (arg + 9, arg - 2, -1);
       
-      if (id_clash_val != -1)
-       {
-         id_clash_len = id_clash_val;
-         warn_id_clash = 1;
-       }
+      if (id_clash_len != -1)
+       warn_id_clash = 1;
     }
   else if (!strncmp (arg, "larger-than-", 12))
     {
-      const int larger_than_val =
-       read_integral_parameter (arg + 12, arg - 2, -1);
-      if (larger_than_val != -1)
-       {
-         larger_than_size = larger_than_val;
-         warn_larger_than = 1;
-       }
+      larger_than_size = read_integral_parameter (arg + 12, arg - 2, -1);
+
+      if (larger_than_size != -1)
+       warn_larger_than = 1;
     }
   else
     return 0;
@@ -4884,6 +4005,7 @@ decode_W_option (arg)
 /* Parse a -g... comand 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.  */
+
 static int
 decode_g_option (arg)
      const char * arg;
@@ -4967,8 +4089,7 @@ ignoring option `%s' due to invalid debug level specification",
            }
          
          if (type == NO_DEBUG)
-           warning ("`%s' not supported by this configuration of GCC",
-                    arg - 2);
+           warning ("`%s': unknown or unsupported -g option", arg - 2);
 
          /* Does it conflict with an already selected type?  */
          if (type_explicitly_set_p
@@ -5001,7 +4122,7 @@ ignoring option `%s' due to invalid debug level specification",
     }
   
   if (! da->arg)
-    warning ("`%s' not supported by this configuration of GCC", arg - 2);
+    warning ("`%s': unknown or unsupported -g option", arg - 2);
 
   return 1;
 }
@@ -5011,13 +4132,13 @@ ignoring option `%s' due to invalid debug level specification",
    number of strings that have already been decoded in a language
    specific fashion before this function was invoked.  */
    
-static unsigned
+static unsigned int
 independent_decode_option (argc, argv, strings_processed)
      int argc;
-     char ** argv;
-     unsigned strings_processed ATTRIBUTE_UNUSED;
+     char **argv;
+     unsigned int strings_processed;
 {
-  char * arg = argv[0];
+  char *arg = argv[0];
   
   if (arg[0] != '-' || arg[1] == 0)
     {
@@ -5040,7 +4161,7 @@ independent_decode_option (argc, argv, strings_processed)
   if (* arg == 'Y')
     arg ++;
   
-  switch (* arg)
+  switch (*arg)
     {
     default:
       return 0;
@@ -5057,7 +4178,10 @@ independent_decode_option (argc, argv, strings_processed)
       return decode_f_option (arg + 1);
            
     case 'g':
-      return decode_g_option (arg + 1);
+      if (strings_processed == 0)
+       return decode_g_option (arg + 1);
+      else
+       return strings_processed;
 
     case 'd':
       if (!strcmp (arg, "dumpbase"))
@@ -5203,7 +4327,7 @@ independent_decode_option (argc, argv, strings_processed)
    Exit code is 35 if can't open files, 34 if fatal error,
    33 if had nonfatal errors, else success.  */
 
-extern int main PROTO ((int, char **));
+extern int main PARAMS ((int, char **));
 
 int
 main (argc, argv)
@@ -5226,18 +4350,6 @@ main (argc, argv)
     --p;
   progname = p;
 
-#if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
-  /* Get rid of any avoidable limit on stack size.  */
-  {
-    struct rlimit rlim;
-
-    /* Set the stack limit huge so that alloca does not fail.  */
-    getrlimit (RLIMIT_STACK, &rlim);
-    rlim.rlim_cur = rlim.rlim_max;
-    setrlimit (RLIMIT_STACK, &rlim);
-  }
-#endif
-
 #ifdef HAVE_LC_MESSAGES
   setlocale (LC_MESSAGES, "");
 #endif
@@ -5263,7 +4375,10 @@ main (argc, argv)
   /* Initialize the garbage-collector.  */
   init_ggc ();
   ggc_add_root (&input_file_stack, 1, sizeof input_file_stack,
-               &mark_file_stack);
+               mark_file_stack);
+  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);
 
   /* Perform language-specific options intialization.  */
   lang_init_options ();
@@ -5301,8 +4416,6 @@ main (argc, argv)
        }
     }
 
-  obey_regdecls = (optimize == 0);
-
   if (optimize >= 1)
     {
       flag_defer_pop = 1;
@@ -5317,6 +4430,7 @@ main (argc, argv)
 
   if (optimize >= 2)
     {
+      flag_optimize_sibling_calls = 1;
       flag_cse_follow_jumps = 1;
       flag_cse_skip_blocks = 1;
       flag_gcse = 1;
@@ -5365,25 +4479,60 @@ main (argc, argv)
   /* Perform normal command line switch decoding.  */
   for (i = 1; i < argc;)
     {
-      unsigned lang_processed;
-      unsigned indep_processed;
-      
+      unsigned int lang_processed;
+      unsigned int indep_processed;
+
       /* Give the language a chance to decode the option for itself.  */
       lang_processed = lang_decode_option (argc - i, argv + i);
+
       /* Now see if the option also has a language independent meaning.
         Some options are both language specific and language independent,
         eg --help.  It is possible that there might be options that should
-        only be decoded in a language independent way if the were not
+        only be decoded in a language independent way if they were not
         decoded in a langauge specific way, which is why 'lang_processed'
         is passed in.  */
-      indep_processed = independent_decode_option (argc - i, argv + i, lang_processed);
+      indep_processed = independent_decode_option (argc - i, argv + i,
+                                                  lang_processed);
 
       if (lang_processed || indep_processed)
-       i += lang_processed > indep_processed ? lang_processed : indep_processed;
+       i += (lang_processed > indep_processed
+             ? lang_processed : indep_processed);
       else
        {
-         error ("Invalid option `%s'", argv[i]);
+         const char * option = NULL;
+         const char * lang = NULL;
+         unsigned int j;
+         
+         /* It is possible that the command line switch is not valid for the
+            current language, but it is valid for another language.  In order
+            to be compatible with previous versions of the compiler (which
+            did not issue an error message in this case) we check for this
+            possibilty here.  If we do find a match, then if extra_warnings
+            is set we generate a warning message, otherwise we will just
+            ignore the option.  */
+         for (j = 0; j < NUM_ELEM (documented_lang_options); j++)
+           {
+             option = documented_lang_options[j].option;
+             
+             if (option == NULL)
+               lang = documented_lang_options[j].description;
+             else if (! strncmp (argv[i], option, strlen (option)))
+               break;
+           }
+
+         if (j != NUM_ELEM (documented_lang_options))
+           {
+             if (extra_warnings)
+               {
+                 warning ("Ignoring command line option '%s'", argv[i]);
+                 if (lang)
+                   warning ("\
+(It is valid for %s but not the selected langauge)", lang);
+               }
+           }
+         else
+           error ("Unrecognized option `%s'", argv[i]);
+         
          i++;
        }
     }
@@ -5492,7 +4641,7 @@ main (argc, argv)
     {
       char *lim = (char *) sbrk (0);
 
-      notice ("Data size %ld.\n", (long) (lim - (char *) &environ));
+      fnotice (stderr, "Data size %ld.\n", (long) (lim - (char *) &environ));
       fflush (stderr);
 
 #ifndef __MSDOS__
@@ -5774,3 +4923,27 @@ debug_undef (lineno, buffer)
     dwarf2out_undef (lineno, buffer);
 #endif /* DWARF2_DEBUGGING_INFO */
 }
+
+/* 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.  */
+
+int
+debug_ignore_block (block)
+     tree block ATTRIBUTE_UNUSED;
+{
+  /* 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;
+
+#ifdef DWARF2_DEBUGGING_INFO
+  if (write_symbols == DWARF2_DEBUG)
+    return dwarf2out_ignore_block (block);
+#endif
+
+  return 1;
+}