OSDN Git Service

Patches from David Mosberger, and a patch to make bootstrap work.
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index 028aad8..1a35497 100644 (file)
@@ -60,6 +60,11 @@ Boston, MA 02111-1307, USA.  */
 #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"
@@ -158,18 +163,14 @@ static void pipe_closed PARAMS ((int)) ATTRIBUTE_NORETURN;
 /* This might or might not be used in ASM_IDENTIFY_LANGUAGE. */
 static void output_lang_identify PARAMS ((FILE *)) ATTRIBUTE_UNUSED;
 #endif
-static void open_dump_file PARAMS ((const char *, const char *));
-static void close_dump_file PARAMS ((void (*) (FILE *, rtx), rtx));
-static void dump_rtl PARAMS ((const char *, tree, void (*) (FILE *, rtx), rtx));
-static void clean_dump_file PARAMS ((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 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));
 
@@ -226,42 +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 reorder_blocks_dump = 0;
-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
-int ssa_dump = 0;
-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.  */
@@ -366,6 +438,10 @@ int flag_branch_probabilities = 0;
 
 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.  */
 
@@ -519,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.  */
 
@@ -863,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,
@@ -956,6 +1038,8 @@ lang_independent_options f_options[] =
    "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,
@@ -1329,120 +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 peephole2_time;
-int sched2_time;
-int dbr_sched_time;
-int reorder_blocks_time;
-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,
-          all_time == 0 ? 0.00 : (double) total / (double) all_time * 100.0);
-}
-
 /* This is the default decl_printable_name function.  */
 
 static const char *
@@ -1454,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;
@@ -1726,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) PARAMS ((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));
+
+  timevar_pop (TV_DUMP);
+  return 1;
 }
 
-/* Routine to dump rtl into a file.  */
+/* Routine to close a dump file.  */
+
 static void
-dump_rtl (suffix, decl, func, insns)
-     const char *suffix;
-     tree   decl;
+close_dump_file (index, func, insns)
+     enum dump_file_index index;
      void (*func) PARAMS ((FILE *, rtx));
      rtx    insns;
 {
-  open_dump_file (suffix, decl_printable_name (decl, 2));
-  close_dump_file (func, insns);
-}
-
-/* Routine to empty a dump file.  */
-static void
-clean_dump_file (suffix)
-  const char *suffix;
-{
-  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
@@ -1967,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.
@@ -1976,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.  */
@@ -1986,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
@@ -1996,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
@@ -2006,8 +1984,9 @@ 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);
     }
 }
 
@@ -2065,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;
-  peephole2_time = 0;
-  sched2_time = 0;
-  dbr_sched_time = 0;
-  reorder_blocks_time = 0;
-  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 ();
@@ -2138,153 +2095,6 @@ compile_file (name)
        pfatal_with_name (aux_info_file_name);
     }
 
-  /* Clear the dump files.  */
-  if (rtl_dump)
-    clean_dump_file (".00.rtl");
-  if (jump_opt_dump)
-    {
-      clean_dump_file (".01.jump");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".01.jump");
-    }
-  if (cse_dump)
-    {
-      clean_dump_file (".02.cse");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".02.cse");
-    }
-  if (addressof_dump)
-    {
-      clean_dump_file (".03.addressof");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".03.addressof");
-    }
-  if (ssa_dump)
-    {
-      clean_dump_file (".033.ssa");
-      clean_dump_file (".037.ussa");
-    }
-  if (gcse_dump)
-    {
-      clean_dump_file (".04.gcse");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".04.gcse");
-    }
-  if (loop_dump)
-    {
-      clean_dump_file (".05.loop");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".05.loop");
-    }
-  if (cse2_dump)
-    {
-      clean_dump_file (".06.cse2");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".06.cse2");
-    }
-  if (branch_prob_dump)
-    {
-      clean_dump_file (".07.bp");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".07.bp");
-    }
-  if (flow_dump)
-    {
-      clean_dump_file (".08.flow");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".08.flow");
-    }
-  if (combine_dump)
-    {
-      clean_dump_file (".09.combine");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".09.combine");
-    }
-  if (regmove_dump)
-    {
-      clean_dump_file (".10.regmove");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".10.regmove");
-    }
-#ifdef INSN_SCHEDULING
-  if (sched_dump)
-    {
-      clean_dump_file (".11.sched");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".11.sched");
-    }
-#endif
-  if (local_reg_dump)
-    {
-      clean_dump_file (".12.lreg");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".12.lreg");
-    }
-  if (global_reg_dump)
-    {
-      clean_dump_file (".13.greg");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".13.greg");
-    }
-  if (flow2_dump)
-    {
-      clean_dump_file (".14.flow2");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".14.flow2");
-    }
-#ifdef HAVE_peephole2
-  if (peephole2_dump)
-    {
-      clean_dump_file (".15.peephole2");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".15.peephole2");
-    }
-#endif
-#ifdef INSN_SCHEDULING
-  if (sched2_dump)
-    {
-      clean_dump_file (".16.sched2");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".16.sched2");
-    }
-#endif
-  if (reorder_blocks_dump)
-    {
-      clean_dump_file (".bbro");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".bbro");
-    }
-  if (jump2_opt_dump)
-    {
-      clean_dump_file (".17.jump2");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".17.jump2");
-    }
-#ifdef MACHINE_DEPENDENT_REORG
-  if (mach_dep_reorg_dump)
-    {
-      clean_dump_file (".18.mach");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".18.mach");
-    }
-#endif
-#ifdef DELAY_SLOTS
-  if (dbr_sched_dump)
-    {
-      clean_dump_file (".19.dbr");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".19.dbr");
-    }
-#endif
-#ifdef STACK_REGS
-  if (stack_reg_dump)
-    {
-      clean_dump_file (".20.stack");
-      if (graph_dump_format != no_graph)
-       clean_graph_dump_file (dump_base_name, ".20.stack");
-    }
-#endif
-
   /* Open assembler code output file.  */
 
   if (flag_syntax_only)
@@ -2416,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 ())
@@ -2436,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).  */
@@ -2463,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;
@@ -2516,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
@@ -2539,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 (".07.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 ();
@@ -2575,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 (".09.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
@@ -2595,111 +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, ".01.jump");
-      if (cse_dump)
-       finish_graph_dump_file (dump_base_name, ".02.cse");
-      if (addressof_dump)
-       finish_graph_dump_file (dump_base_name, ".03.addressof");
-      if (gcse_dump)
-       finish_graph_dump_file (dump_base_name, ".04.gcse");
-      if (loop_dump)
-       finish_graph_dump_file (dump_base_name, ".05.loop");
-      if (cse2_dump)
-       finish_graph_dump_file (dump_base_name, ".06.cse2");
-      if (branch_prob_dump)
-       finish_graph_dump_file (dump_base_name, ".07.bp");
-      if (flow_dump)
-       finish_graph_dump_file (dump_base_name, ".08.flow");
-      if (combine_dump)
-       finish_graph_dump_file (dump_base_name, ".09.combine");
-      if (regmove_dump)
-       finish_graph_dump_file (dump_base_name, ".10.regmove");
-#ifdef INSN_SCHEDULING
-      if (sched_dump)
-       finish_graph_dump_file (dump_base_name, ".11.sched");
-#endif
-      if (local_reg_dump)
-       finish_graph_dump_file (dump_base_name, ".12.lreg");
-      if (global_reg_dump)
-       finish_graph_dump_file (dump_base_name, ".13.greg");
-      if (flow2_dump)
-       finish_graph_dump_file (dump_base_name, ".14.flow2");
-#ifdef HAVE_peephole2
-      if (flow2_dump)
-       finish_graph_dump_file (dump_base_name, ".15.peephole2");
-#endif
-#ifdef INSN_SCHEDULING
-      if (sched2_dump)
-       finish_graph_dump_file (dump_base_name, ".16.sched2");
-#endif
-      if (reorder_blocks_dump)
-       finish_graph_dump_file (dump_base_name, ".bbro");
-      if (jump2_opt_dump)
-       finish_graph_dump_file (dump_base_name, ".17.jump2");
-#ifdef MACHINE_DEPENDENT_REORG
-      if (mach_dep_reorg_dump)
-       finish_graph_dump_file (dump_base_name, ".18.mach");
-#endif
-#ifdef DELAY_SLOTS
-      if (dbr_sched_dump)
-       finish_graph_dump_file (dump_base_name, ".19.dbr");
-#endif
-#ifdef STACK_REGS
-      if (stack_reg_dump)
-       finish_graph_dump_file (dump_base_name, ".20.stack");
-#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);
-#ifdef INSN_SCHEDULING
-      print_time ("sched", sched_time);
-#endif
-      print_time ("local-alloc", local_alloc_time);
-      print_time ("global-alloc", global_alloc_time);
-      print_time ("flow2", flow2_time);
-#ifdef HAVE_peephole2
-      print_time ("peephole2", peephole2_time);
-#endif
-#ifdef INSN_SCHEDULING
-      print_time ("sched2", sched2_time);
-#endif
-#ifdef DELAY_SLOTS
-      print_time ("dbranch", dbr_sched_time);
-#endif
-      print_time ("bbro", reorder_blocks_time);
-      print_time ("shorten-branch", shorten_branch_time);
-#ifdef STACK_REGS
-      print_time ("stack-reg", stack_reg_time);
-#endif
-      print_time ("final", final_time);
-      print_time ("varconst", varconst_time);
-      print_time ("symout", symout_time);
-      print_time ("dump", dump_time);
-      if (ggc_p)
-       print_time ("gc", gc_time);
-    }
+    timevar_print (stderr);
 }
 \f
 /* This is called from various places for FUNCTION_DECL, VAR_DECL,
@@ -2734,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)
@@ -2770,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
 }
 
@@ -2791,14 +2521,16 @@ 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
@@ -2817,7 +2549,7 @@ note_deferral_of_defined_inline_function (decl)
   /* Generate the DWARF info for the "abstract" instance of a function
      which we may later generate inlined and/or out-of-line instances
      of.  */
-  if (write_symbols == DWARF_DEBUG)
+  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,
@@ -2848,11 +2580,12 @@ rest_of_compilation (decl)
      tree decl;
 {
   register rtx insns;
-  int start_time = get_run_time ();
   int tem;
   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;
@@ -2865,7 +2598,7 @@ rest_of_compilation (decl)
   /* 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_unncessary_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.  */
@@ -2897,43 +2630,41 @@ rest_of_compilation (decl)
 
       /* 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 (".00.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
@@ -2949,6 +2680,14 @@ rest_of_compilation (decl)
                  || DECL_EXTERNAL (decl))))
        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.
@@ -2964,7 +2703,7 @@ 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;
            }
@@ -2975,8 +2714,9 @@ rest_of_compilation (decl)
               of other functions later in this translation unit.  */
            TREE_NOTHROW (current_function_decl) = 1;
 
-         note_deferral_of_defined_inline_function (decl);
-         TIMEVAR (integration_time, save_for_inline_nocopy (decl));
+         timevar_push (TV_INTEGRATION);
+         save_for_inline_nocopy (decl);
+         timevar_pop (TV_INTEGRATION);
          DECL_SAVED_INSNS (decl)->inlinable = inlinable;
          goto exit_rest_of_compilation;
        }
@@ -2988,12 +2728,8 @@ rest_of_compilation (decl)
        goto exit_rest_of_compilation;
     }
 
-  /* We may have potential sibling or tail recursion sites.  Select one
-     (of possibly multiple) methods of performing the call.  */
   init_EXPR_INSN_LIST_cache ();
-  if (optimize)
-    optimize_sibling_and_tail_recursive_calls ();
-  
+
   if (ggc_p)
     ggc_collect ();
 
@@ -3010,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.
@@ -3038,7 +2785,6 @@ rest_of_compilation (decl)
   insns = get_insns ();
 
   /* Copy any shared structure that should not be shared.  */
-
   unshare_all_rtl (current_function_decl, insns);
 
 #ifdef SETJMP_VIA_SAVE_AREA
@@ -3048,45 +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 ();
 
-  if (jump_opt_dump)
-    open_dump_file (".01.jump", decl_printable_name (decl, 2));
+  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));
 
-  /* 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_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);
 
-  /* Dump rtl code after jump, if we are doing that.  */
-  if (jump_opt_dump)
-    close_dump_file (print_rtl, insns);
+  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);
+    }
+
+  /* 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);
 
-  /* 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 ()));
+  close_dump_file (DFI_jump, print_rtl, insns);
 
   if (ggc_p)
     ggc_collect ();
@@ -3098,79 +2863,98 @@ rest_of_compilation (decl)
 
   if (optimize > 0)
     {
-      if (cse_dump)
-       open_dump_file (".02.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);
+       }
+
+      tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file);
 
-      TIMEVAR (cse_time, 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.  */
-      TIMEVAR (cse_time, delete_trivially_dead_insns (insns, max_reg_num ()));
+      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);
+
+         cleanup_cfg (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);
 
-      /* Dump rtl code after cse, if we are doing that.  */
-      if (cse_dump)
-       {
-         close_dump_file (print_rtl, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".02.cse", insns);
-       }
+      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 (".03.addressof", decl, print_rtl, insns);
-      if (graph_dump_format != no_graph)
-       print_rtl_graph_with_bb (dump_base_name, ".03.addressof", insns);
-    }
+  close_dump_file (DFI_addressof, print_rtl, insns);
 
   if (ggc_p)
     ggc_collect ();
 
-  if (flag_ssa)
+  if (optimize > 0 && flag_ssa)
     {
-      if (ssa_dump)
-       open_dump_file (".033.ssa", decl_printable_name (decl, 2));
+      /* 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 ();
-      if (ssa_dump)
-       close_dump_file (print_rtl_with_bb, insns);
 
-      if (ssa_dump)
-       open_dump_file (".037.ussa", decl_printable_name (decl, 2));
+      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);
-      if (ssa_dump)
-       close_dump_file (print_rtl_with_bb, insns);
-
-      /* Life analysis used in SSA adds log_links but these shouldn't
-        be there until the flow stage, so clear them away.  */
+      /* 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 ();
     }
@@ -3179,82 +2963,66 @@ rest_of_compilation (decl)
 
   if (optimize > 0 && flag_gcse)
     {
-      if (gcse_dump)
-       open_dump_file (".04.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, ".04.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 (".05.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, ".05.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 ();
     }
 
-  /* ??? Well, nearly.  If HAVE_conditional_arithmetic, jump_optimize
-     has put off all if-conversion until "after CSE".  If we put this
-     off any longer we may miss out doing if-conversion entirely.  */
-  cse_not_expected = 1;
-
   if (optimize > 0)
     {
-      if (cse2_dump)
-       open_dump_file (".06.cse2", decl_printable_name (decl, 2));
+      timevar_push (TV_CSE2);
+      open_dump_file (DFI_cse2, decl);
 
       if (flag_rerun_cse_after_loop)
        {
@@ -3263,57 +3031,62 @@ 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, ".06.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 (".07.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, ".07.bp", insns);
-       }
+      close_dump_file (DFI_bp, print_rtl, insns);
+      timevar_pop (TV_BRANCH_PROB);
 
       if (ggc_p)
        ggc_collect ();
@@ -3324,22 +3097,34 @@ rest_of_compilation (decl)
   /* Print function header into flow dump now
      because doing the flow analysis makes some of the dump.  */
 
-  if (flow_dump)
-    open_dump_file (".08.flow", decl_printable_name (decl, 2));
+  open_dump_file (DFI_flow, decl);
   
   /* Do control and data flow analysis; wrote some of the results to
      the dump file.  */
 
-  TIMEVAR
-    (flow_time,
-     {
-       find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-       cleanup_cfg (insns);
-       if (optimize)
-        calculate_loop_depth (rtl_dump_file);
-       life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
-       mark_constant_function ();
-     });
+  timevar_push (TV_FLOW);
+  find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+  cleanup_cfg (insns);
+  if (optimize)
+    {
+      struct loops loops;
+
+      /* 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);
+
+      /* 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);
+
+      flow_loops_free (&loops);
+    }
+  life_analysis (insns, rtl_dump_file, PROP_FINAL);
+  mark_constant_function ();
+  timevar_pop (TV_FLOW);
 
   if (warn_uninitialized || extra_warnings)
     {
@@ -3348,71 +3133,78 @@ rest_of_compilation (decl)
        setjmp_args_warning ();
     }
 
-  /* Dump rtl after flow analysis.  */
-
-  if (flow_dump)
-    {
-      close_dump_file (print_rtl_with_bb, insns);
-      if (graph_dump_format != no_graph)
-       print_rtl_graph_with_bb (dump_base_name, ".08.flow", insns);
-    }
+  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)
     {
       int rebuild_jump_labels_after_combine = 0;
 
-      TIMEVAR (combine_time, 
-              {
-                rebuild_jump_labels_after_combine
-                  = combine_instructions (insns, max_reg_num ());
-              });
+      timevar_push (TV_COMBINE);
+      open_dump_file (DFI_combine, decl);
+
+      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)
        {
-         TIMEVAR (jump_time, rebuild_jump_labels (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);
        }
 
-      /* Dump rtl code after insn combination.  */
-
-      if (combine_dump)
-       {
-         dump_rtl (".09.combine", decl, print_rtl_with_bb, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".09.combine", insns);
-       }
+      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 (".10.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, ".10.regmove", insns);
-       }
+      close_dump_file (DFI_regmove, print_rtl_with_bb, insns);
+      timevar_pop (TV_REGMOVE);
 
       if (ggc_p)
        ggc_collect ();
@@ -3420,7 +3212,9 @@ rest_of_compilation (decl)
 
   if (optimize && n_basic_blocks)
     {
-      TIMEVAR (gcse_time, optimize_mode_switching (NULL_PTR));
+      timevar_push (TV_GCSE);
+      optimize_mode_switching (NULL_PTR);
+      timevar_pop (TV_GCSE);
     }
 
 #ifdef INSN_SCHEDULING
@@ -3429,25 +3223,23 @@ rest_of_compilation (decl)
      because doing the sched analysis makes some of the dump.  */
   if (optimize > 0 && flag_schedule_insns)
     {
-      if (sched_dump)
-       open_dump_file (".11.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, ".11.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
 
@@ -3456,55 +3248,58 @@ rest_of_compilation (decl)
      epilogue thus changing register elimination offsets.  */
   current_function_is_leaf = leaf_function_p ();
 
-  if (local_reg_dump)
-    open_dump_file (".12.lreg", decl_printable_name (decl, 2));
+  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.  */
 
-  TIMEVAR (local_alloc_time,
-          {
-            /* 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);
-            regclass (insns, max_reg_num (), rtl_dump_file);
-            rebuild_label_notes_after_reload = local_alloc ();
-          });
+  /* 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)
     {
-      TIMEVAR (dump_time, dump_flow_info (rtl_dump_file));
-      TIMEVAR (dump_time, dump_local_alloc (rtl_dump_file));
+      timevar_push (TV_DUMP);
+
+      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, ".12.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 (".13.greg", decl_printable_name (decl, 2));
+  timevar_push (TV_GLOBAL_ALLOC);
+  open_dump_file (DFI_greg, decl);
 
   /* If optimizing, allocate remaining pseudo-regs.  Do the reload
      pass fixing up any insns that are invalid.  */
 
-  TIMEVAR (global_alloc_time,
-          {
-            if (optimize)
-              failure = global_alloc (rtl_dump_file);
-            else
-              {
-                build_insn_chain (insns);
-                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;
@@ -3514,39 +3309,45 @@ rest_of_compilation (decl)
 
   /* Do a very simple CSE pass over just the hard registers.  */
   if (optimize > 0)
-    reload_cse_regs (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.
+    {
+      timevar_push (TV_RELOAD_CSE_REGS);
+      reload_cse_regs (insns);
+      timevar_pop (TV_RELOAD_CSE_REGS); 
+    }
 
-     reload_cse_regs may expose more splitting opportunities, expecially
-     for double-word operations.  */
-  if (optimize > 0 && flag_schedule_insns_after_reload)
+  /* 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));
+    {
+      timevar_push (TV_JUMP);
+
+      rebuild_jump_labels (insns);
 
-  if (global_reg_dump)
+      timevar_pop (TV_JUMP);
+    }
+
+  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, ".13.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 (".14.flow2", decl_printable_name (decl, 2));
-  
-  TIMEVAR (flow2_time,
-          {
-            find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-          });
+  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
@@ -3556,15 +3357,17 @@ rest_of_compilation (decl)
 
   if (optimize)
     {
-      TIMEVAR (flow2_time,
-              {
-                cleanup_cfg (insns);
-                life_analysis (insns, max_reg_num (), rtl_dump_file, 1);
-              });
+      cleanup_cfg (insns);
+      life_analysis (insns, rtl_dump_file, PROP_FINAL);
 
-#ifndef ACCUMULATE_OUTGOING_ARGS
-      TIMEVAR (flow2_time, { combine_stack_adjustments (); });
+      /* 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 ();
@@ -3572,49 +3375,46 @@ rest_of_compilation (decl)
 
   flow2_completed = 1;
 
-  if (flow2_dump)
+  close_dump_file (DFI_flow2, print_rtl_with_bb, insns);
+  timevar_pop (TV_FLOW2);
+
+  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, ".14.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 (".15.peephole2", decl_printable_name (decl, 2));
+      timevar_push (TV_PEEPHOLE2);
+      open_dump_file (DFI_peephole2, decl);
 
-      TIMEVAR (peephole2_time, peephole2_optimize (rtl_dump_file));
+      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, ".15.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 (".16.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, ".16.sched2", insns);
-       }
+      close_dump_file (DFI_sched2, print_rtl_with_bb, insns);
+      timevar_pop (TV_SCHED2);
 
       if (ggc_p)
        ggc_collect ();
@@ -3628,17 +3428,24 @@ rest_of_compilation (decl)
 
   if (optimize > 0 && flag_reorder_blocks)
     {
-      if (reorder_blocks_dump)
-       open_dump_file (".bbro", decl_printable_name (decl, 2));
+      timevar_push (TV_REORDER_BLOCKS);
+      open_dump_file (DFI_bbro, decl);
 
-      TIMEVAR (reorder_blocks_time, reorder_basic_blocks ());
+      reorder_basic_blocks ();
 
-      if (reorder_blocks_dump)
-       {
-         close_dump_file (print_rtl_with_bb, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".bbro", insns);
-       }
+      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. 
@@ -3646,36 +3453,28 @@ rest_of_compilation (decl)
 
   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 (".17.jump2", decl, print_rtl_with_bb, insns);
-         if (graph_dump_format != no_graph)
-           print_rtl_graph_with_bb (dump_base_name, ".17.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 (".18.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, ".18.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,
@@ -3684,48 +3483,35 @@ rest_of_compilation (decl)
 #ifdef DELAY_SLOTS
   if (optimize > 0 && flag_delayed_branch)
     {
-      if (dbr_sched_dump)
-       open_dump_file (".19.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, ".19.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. 
 
      Note this must run before reg-stack because of death note (ab)use
      in the ia32 backend.  */
-  TIMEVAR (shorten_branch_time,
-          {
-            shorten_branches (get_insns ());
-          });
+  timevar_push (TV_SHORTEN_BRANCH);
+  shorten_branches (get_insns ());
+  timevar_pop (TV_SHORTEN_BRANCH);
 
 #ifdef STACK_REGS
-  if (stack_reg_dump)
-    open_dump_file (".20.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)
-    {
-      close_dump_file (print_rtl_with_bb, insns);
-      if (graph_dump_format != no_graph)
-       print_rtl_graph_with_bb (dump_base_name, ".20.stack", insns);
-    }
+  close_dump_file (DFI_stack, print_rtl_with_bb, insns);
+  timevar_pop (TV_REG_STACK);
 
   if (ggc_p)
     ggc_collect ();
@@ -3739,37 +3525,38 @@ rest_of_compilation (decl)
 
   /* Now turn the rtl into assembler code.  */
 
-  TIMEVAR (final_time,
-          {
-            rtx x;
-            const 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 ();
@@ -3784,20 +3571,22 @@ 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:
 
@@ -3813,24 +3602,25 @@ rest_of_compilation (decl)
   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 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
+  /* 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
@@ -3852,10 +3642,7 @@ rest_of_compilation (decl)
   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
@@ -3924,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");
 
@@ -4042,138 +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
-       reorder_blocks_dump = 1;
-       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;
-       ssa_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 'B':
-       reorder_blocks_dump = 1;
-       break;
-      case 'c':
-       combine_dump = 1;
-       break;
-#ifdef DELAY_SLOTS
-      case 'd':
-       dbr_sched_dump = 1;
-       break;
-#endif
-      case 'e':
-       ssa_dump = 1;
-       break;
-      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 ("unrecognized 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;
       }
 }
@@ -4733,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;
@@ -5226,16 +4924,26 @@ debug_undef (lineno, buffer)
 #endif /* DWARF2_DEBUGGING_INFO */
 }
 
-/* Tell the debugging backend that we've decided not to emit any
-   debugging information for BLOCK, so it can clean up after any local
-   classes or nested functions.  */
+/* 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.  */
 
-void
+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)
-    dwarf2out_ignore_block (block);
+    return dwarf2out_ignore_block (block);
 #endif
+
+  return 1;
 }