OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index 198790e..1320013 100644 (file)
@@ -2,22 +2,22 @@
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001 Free Software Foundation, Inc.
 
-This file is part of GNU CC.
+This file is part of GCC.
 
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
 
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
 
 You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
 
 /* This is the top level of cc1/c++.
    It parses command args, opens files, invokes the various passes
@@ -67,10 +67,7 @@ Boston, MA 02111-1307, USA.  */
 #include "dwarf2asm.h"
 #include "integrate.h"
 #include "debug.h"
-
-#ifdef DWARF_DEBUGGING_INFO
-#include "dwarfout.h"
-#endif
+#include "target.h"
 
 #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
 #include "dwarf2out.h"
@@ -85,7 +82,8 @@ Boston, MA 02111-1307, USA.  */
 #endif
 
 #ifdef XCOFF_DEBUGGING_INFO
-#include "xcoffout.h"
+#include "xcoffout.h"          /* Needed for external data
+                                  declarations for e.g. AIX 4.x.  */
 #endif
 \f
 #ifdef VMS
@@ -163,6 +161,7 @@ static const char *decl_name PARAMS ((tree, int));
 
 static void float_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
 static void crash_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
+static void set_float_handler PARAMS ((jmp_buf));
 static void compile_file PARAMS ((const char *));
 static void display_help PARAMS ((void));
 static void display_target_options PARAMS ((void));
@@ -282,11 +281,10 @@ enum dump_file_index
   DFI_rnreg,
   DFI_ce2,
   DFI_sched2,
+  DFI_stack,
   DFI_bbro,
-  DFI_jump2,
   DFI_mach,
   DFI_dbr,
-  DFI_stack,
   DFI_MAX
 };
 
@@ -296,7 +294,7 @@ enum dump_file_index
    Remaining -d letters:
 
        "              o q   u     "
-       "       H  K   OPQ  TUV  YZ"
+       "       H JK   OPQ  TUV  YZ"
 */
 
 struct dump_file_info dump_file[DFI_MAX] =
@@ -329,11 +327,10 @@ struct dump_file_info dump_file[DFI_MAX] =
   { "rnreg",   'n', 1, 0, 0 },
   { "ce2",     'E', 1, 0, 0 },
   { "sched2",  'R', 1, 0, 0 },
+  { "stack",   'k', 1, 0, 0 },
   { "bbro",    'B', 1, 0, 0 },
-  { "jump2",   'J', 1, 0, 0 },
   { "mach",    'M', 1, 0, 0 },
   { "dbr",     'd', 0, 0, 0 },
-  { "stack",   'k', 1, 0, 0 },
 };
 
 static int open_dump_file PARAMS ((enum dump_file_index, tree));
@@ -740,6 +737,10 @@ int flag_exceptions;
 
 int flag_unwind_tables = 0;
 
+/* Nonzero means generate frame unwind info table exact at each insn boundary */
+
+int flag_asynchronous_unwind_tables = 0;
+
 /* Nonzero means don't place uninitialized global data in common storage
    by default.  */
 
@@ -901,6 +902,11 @@ int flag_bounded_pointers = 0;
    For CHILL: defaults to off.  */
 int flag_bounds_check = 0;
 
+/* This will attempt to merge constant section constants, if 1 only
+   string constants and constants from constant pool, if 2 also constant
+   variables.  */
+int flag_merge_constants = 1;
+
 /* If one, renumber instruction UIDs to reduce the number of
    unused UIDs if there are a lot of instructions.  If greater than
    one, unconditionally renumber instruction UIDs.  */
@@ -921,14 +927,14 @@ int align_functions;
 int align_functions_log;
 
 /* Table of supported debugging formats.  */
-static struct
+static const struct
 {
-  const char *arg;
+  const char *const arg;
   /* Since PREFERRED_DEBUGGING_TYPE isn't necessarily a
      constant expression, we use NO_DEBUG in its place.  */
-  enum debug_info_type debug_type;
-  int use_extensions_p;
-  const char *description;
+  const enum debug_info_type debug_type;
+  const int use_extensions_p;
+  const char *const description;
 } *da,
 debug_args[] =
 {
@@ -1094,6 +1100,8 @@ lang_independent_options f_options[] =
    N_("Enable exception handling") },
   {"unwind-tables", &flag_unwind_tables, 1,
    N_("Just generate unwind tables for exception handling") },
+  {"asynchronous-unwind-tables", &flag_asynchronous_unwind_tables, 1,
+   N_("Generate unwind tables exact at each instruction boundary") },
   {"non-call-exceptions", &flag_non_call_exceptions, 1,
    N_("Support synchronous non-call exceptions") },
   {"profile-arcs", &profile_arc_flag, 1,
@@ -1142,6 +1150,10 @@ lang_independent_options f_options[] =
    N_("Align all labels") },
   {"align-functions", &align_functions, 0,
    N_("Align the start of functions") },
+  {"merge-constants", &flag_merge_constants, 1,
+   N_("Attempt to merge identical constants accross compilation units") },
+  {"merge-all-constants", &flag_merge_constants, 2,
+   N_("Attempt to merge identical constants and constant variables") },
   {"check-memory-usage", &flag_check_memory_usage, 1,
    N_("Generate code to check every memory access") },
   {"prefix-function-name", &flag_prefix_function_name, 1,
@@ -1186,10 +1198,10 @@ lang_independent_options f_options[] =
 
 /* Table of language-specific options.  */
 
-static struct lang_opt
+static const struct lang_opt
 {
-  const char *option;
-  const char *description;
+  const char *const option;
+  const char *const description;
 }
 documented_lang_options[] =
 {
@@ -1372,22 +1384,22 @@ documented_lang_options[] =
    If VALUE is negative, -VALUE is bits to clear.
    (The sign bit is not used so there is no confusion.)  */
 
-struct
+static const struct
 {
-  const char *name;
-  int value;
-  const char *description;
+  const char *const name;
+  const int value;
+  const char *const description;
 }
 target_switches [] = TARGET_SWITCHES;
 
 /* This table is similar, but allows the switch to have a value.  */
 
 #ifdef TARGET_OPTIONS
-struct
+static const struct
 {
-  const char *prefix;
-  const char **variable;
-  const char *description;
+  const char *const prefix;
+  const char **const variable;
+  const char *const description;
 }
 target_options [] = TARGET_OPTIONS;
 #endif
@@ -1443,7 +1455,7 @@ int warn_notreached;
 
 int warn_uninitialized;
 
-/* Nonzero means warn about all declarations which shadow others.   */
+/* Nonzero means warn about all declarations which shadow others.  */
 
 int warn_shadow;
 
@@ -1578,7 +1590,7 @@ read_integral_parameter (p, pname, defval)
 
   while (*endp)
     {
-      if (*endp >= '0' && *endp <= '9')
+      if (ISDIGIT (*endp))
        endp++;
       else
        break;
@@ -1632,9 +1644,9 @@ botch (s)
 
 int
 exact_log2_wide (x)
-     register unsigned HOST_WIDE_INT x;
+     unsigned HOST_WIDE_INT x;
 {
-  register int log = 0;
+  int log = 0;
   /* Test for 0 or a power of 2.  */
   if (x == 0 || x != (x & -x))
     return -1;
@@ -1650,9 +1662,9 @@ exact_log2_wide (x)
 
 int
 floor_log2_wide (x)
-     register unsigned HOST_WIDE_INT x;
+     unsigned HOST_WIDE_INT x;
 {
-  register int log = -1;
+  int log = -1;
   while (x != 0)
     log++,
     x >>= 1;
@@ -1683,7 +1695,7 @@ float_signal (signo)
 /* Specify where to longjmp to when a floating arithmetic error happens.
    If HANDLER is 0, it means don't handle the errors any more.  */
 
-void
+static void
 set_float_handler (handler)
      jmp_buf handler;
 {
@@ -2061,47 +2073,7 @@ check_global_declarations (vec, len)
        warning_with_decl (decl, "`%s' defined but not used");
 
       timevar_push (TV_SYMOUT);
-#ifdef SDB_DEBUGGING_INFO
-      /* The COFF linker can move initialized global vars to the end.
-        And that can screw up the symbol ordering.
-        By putting the symbols in that order to begin with,
-        we avoid a problem.  mcsun!unido!fauern!tumuc!pes@uunet.uu.net.  */
-      if (write_symbols == SDB_DEBUG && TREE_CODE (decl) == VAR_DECL
-         && TREE_PUBLIC (decl) && DECL_INITIAL (decl)
-         && ! DECL_EXTERNAL (decl)
-         && DECL_RTL (decl) != 0)
-       sdbout_symbol (decl, 0);
-
-      /* Output COFF information for non-global
-        file-scope initialized variables.  */
-      if (write_symbols == SDB_DEBUG
-         && TREE_CODE (decl) == VAR_DECL
-         && DECL_INITIAL (decl)
-         && ! DECL_EXTERNAL (decl)
-         && DECL_RTL (decl) != 0
-         && GET_CODE (DECL_RTL (decl)) == MEM)
-       sdbout_toplevel_data (decl);
-#endif /* SDB_DEBUGGING_INFO  */
-#ifdef DWARF_DEBUGGING_INFO
-      /* Output DWARF information for file-scope tentative data object
-        declarations, file-scope (extern) function declarations (which
-        had no corresponding body) and file-scope tagged type declarations
-        and definitions which have not yet been forced out.  */
-
-      if (write_symbols == DWARF_DEBUG
-         && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
-       dwarfout_file_scope_decl (decl, 1);
-#endif
-#ifdef DWARF2_DEBUGGING_INFO
-      /* Output DWARF2 information for file-scope tentative data object
-        declarations, file-scope (extern) function declarations (which
-        had no corresponding body) and file-scope tagged type declarations
-        and definitions which have not yet been forced out.  */
-
-      if (write_symbols == DWARF2_DEBUG
-         && (TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)))
-       dwarf2out_decl (decl);
-#endif
+      (*debug_hooks->global_decl) (decl);
       timevar_pop (TV_SYMOUT);
     }
 }
@@ -2152,8 +2124,9 @@ pop_srcloc ()
   lineno = input_file_stack->line;
 }
 
-/* Compile an entire file of output from cpp, named NAME.
-   Write a file of assembly output and various debugging dumps.  */
+/* Compile an entire translation unit, whose primary source file is
+   named NAME.  Write a file of assembly output and various debugging
+   dumps.  */
 
 static void
 compile_file (name)
@@ -2174,7 +2147,7 @@ compile_file (name)
   init_timevar ();
   timevar_start (TV_TOTAL);
 
-  /* Open assembler code output file.  Do this even if -fsyntax-only is on,
+  /* Open assembly code output file.  Do this even if -fsyntax-only is on,
      because then the driver will have provided the name of a temporary
      file or bit bucket for us.  */
 
@@ -2254,8 +2227,7 @@ compile_file (name)
 
   /* Perform language-specific initialization.
      This may set main_input_filename.  */
-  if (lang_hooks.init)
-    (*lang_hooks.init) ();
+  (*lang_hooks.init) ();
 
   /* If the input doesn't start with a #line, use the input name
      as the official input file name.  */
@@ -2312,18 +2284,19 @@ compile_file (name)
     debug_hooks = &dwarf2_debug_hooks;
 #endif
 
-#ifndef ASM_OUTPUT_SECTION_NAME
-  if (flag_function_sections)
-    {
-      warning ("-ffunction-sections not supported for this target.");
-      flag_function_sections = 0;
-    }
-  if (flag_data_sections)
+  if (! targetm.have_named_sections)
     {
-      warning ("-fdata-sections not supported for this target.");
-      flag_data_sections = 0;
+      if (flag_function_sections)
+       {
+         warning ("-ffunction-sections not supported for this target.");
+         flag_function_sections = 0;
+       }
+      if (flag_data_sections)
+       {
+         warning ("-fdata-sections not supported for this target.");
+         flag_data_sections = 0;
+       }
     }
-#endif
 
   if (flag_function_sections
       && (profile_flag || profile_block_flag))
@@ -2345,7 +2318,7 @@ compile_file (name)
     dwarf2out_frame_init ();
 #endif
 
-  (*debug_hooks->init) (asm_out_file, main_input_filename);
+  (*debug_hooks->init) (main_input_filename);
   timevar_pop (TV_SYMOUT);
 
   /* Initialize yet another pass.  */
@@ -2357,17 +2330,12 @@ compile_file (name)
 
   /* Call the parser, which parses the entire file
      (calling rest_of_compilation for each function).  */
+  yyparse ();
 
-  if (yyparse () != 0)
-    {
-      if (errorcount == 0)
-       fnotice (stderr, "Errors detected in input file (your bison.simple is out of date)\n");
-
-      /* In case there were missing closebraces,
-        get us back to the global binding level.  */
-      while (! global_bindings_p ())
-       poplevel (0, 0, 0);
-    }
+  /* In case there were missing block closers,
+     get us back to the global binding level.  */
+  while (! global_bindings_p ())
+    poplevel (0, 0, 0);
 
   /* Compilation is now finished except for writing
      what's left of the symbol table output.  */
@@ -2424,7 +2392,7 @@ compile_file (name)
     dwarf2out_frame_finish ();
 #endif
 
-  (*debug_hooks->finish) (asm_out_file, main_input_filename);
+  (*debug_hooks->finish) (main_input_filename);
   timevar_pop (TV_SYMOUT);
 
   /* Output some stuff at end of file if nec.  */
@@ -2459,8 +2427,7 @@ compile_file (name)
 
   /* Language-specific end of compilation actions.  */
  finish_syntax:
-  if (lang_hooks.finish)
-    (*lang_hooks.finish) ();
+  (*lang_hooks.finish) ();
 
   /* Close the dump files.  */
 
@@ -2636,64 +2603,6 @@ rest_of_type_compilation (type, toplev)
   timevar_pop (TV_SYMOUT);
 }
 
-/* DECL is an inline function, whose body is present, but which is not
-   being output at this point.  (We're putting that off until we need
-   to do it.)  If there are any actions that need to take place,
-   including the emission of debugging information for the function,
-   this is where they should go.  This function may be called by
-   language-dependent code for front-ends that do not even generate
-   RTL for functions that don't need to be put out.  */
-
-void
-note_deferral_of_defined_inline_function (decl)
-     tree decl ATTRIBUTE_UNUSED;
-{
-#ifdef DWARF_DEBUGGING_INFO
-  /* Generate the DWARF info for the "abstract" instance of a function
-     which we may later generate inlined and/or out-of-line instances
-     of.  */
-  if (write_symbols == DWARF_DEBUG
-      && (DECL_INLINE (decl) || DECL_ABSTRACT (decl))
-      && ! DECL_ABSTRACT_ORIGIN (decl))
-    {
-      /* The front-end may not have set CURRENT_FUNCTION_DECL, but the
-        DWARF code expects it to be set in this case.  Intuitively,
-        DECL is the function we just finished defining, so setting
-        CURRENT_FUNCTION_DECL is sensible.  */
-      tree saved_cfd = current_function_decl;
-      int was_abstract = DECL_ABSTRACT (decl);
-      current_function_decl = decl;
-
-      /* Let the DWARF code do its work.  */
-      set_decl_abstract_flags (decl, 1);
-      dwarfout_file_scope_decl (decl, 0);
-      if (! was_abstract)
-       set_decl_abstract_flags (decl, 0);
-
-      /* Reset CURRENT_FUNCTION_DECL.  */
-      current_function_decl = saved_cfd;
-    }
-#endif
-}
-
-/* FNDECL is an inline function which is about to be emitted out of line.
-   Do any preparation, such as emitting abstract debug info for the inline
-   before it gets mangled by optimization.  */
-
-void
-note_outlining_of_inline_function (fndecl)
-     tree fndecl ATTRIBUTE_UNUSED;
-{
-#ifdef DWARF2_DEBUGGING_INFO
-  /* The DWARF 2 backend tries to reduce debugging bloat by not emitting
-     the abstract description of inline functions until something tries to
-     reference them.  Force it out now, before optimizations mangle the
-     block tree.  */
-  if (write_symbols == DWARF2_DEBUG)
-    dwarf2out_abstract_function (fndecl);
-#endif
-}
-
 /* This is called from finish_function (within yyparse)
    after each top-level definition is parsed.
    It is supposed to compile that function or variable
@@ -2704,7 +2613,7 @@ void
 rest_of_compilation (decl)
      tree decl;
 {
-  register rtx insns;
+  rtx insns;
   int tem;
   int failure = 0;
   int rebuild_label_notes_after_reload;
@@ -2819,29 +2728,32 @@ rest_of_compilation (decl)
        DECL_DEFER_OUTPUT (decl) = 1;
 
       if (DECL_INLINE (decl))
-       /* DWARF wants seperate debugging info for abstract and
+       /* DWARF wants separate debugging info for abstract and
           concrete instances of all inline functions, including those
           declared inline but not inlined, and those inlined even
           though they weren't declared inline.  Conveniently, that's
           what DECL_INLINE means at this point.  */
-       note_deferral_of_defined_inline_function (decl);
+       (*debug_hooks->deferred_inline_function) (decl);
 
       if (DECL_DEFER_OUTPUT (decl))
        {
          /* If -Wreturn-type, we have to do a bit of compilation.  We just
-            want to call jump_optimize to figure out whether or not we can
+            want to call cleanup the cfg to figure out whether or not we can
             fall off the end of the function; we do the minimum amount of
-            work necessary to make that safe.  And, we set optimize to zero
-            to keep jump_optimize from working too hard.  */
+            work necessary to make that safe.  */
          if (warn_return_type)
            {
              int saved_optimize = optimize;
 
              optimize = 0;
+             rebuild_jump_labels (insns);
              find_exception_handler_labels ();
-             jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
-                            !JUMP_AFTER_REGSCAN);
+             find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+             cleanup_cfg (CLEANUP_PRE_SIBCALL | CLEANUP_PRE_LOOP);
              optimize = saved_optimize;
+
+             /* CFG is no longer maitained up-to-date.  */
+             free_bb_for_insn ();
            }
 
          current_function_nothrow = nothrow_function_p ();
@@ -2882,7 +2794,7 @@ rest_of_compilation (decl)
   purge_hard_subreg_sets (get_insns ());
   emit_initial_value_sets ();
 
-  /* Don't return yet if -Wreturn-type; we need to do jump_optimize.  */
+  /* Don't return yet if -Wreturn-type; we need to do cleanup_cfg.  */
   if ((rtl_dump_and_exit || flag_syntax_only) && !warn_return_type)
     goto exit_rest_of_compilation;
 
@@ -2927,7 +2839,7 @@ rest_of_compilation (decl)
   unshare_all_rtl (current_function_decl, insns);
 
 #ifdef SETJMP_VIA_SAVE_AREA
-  /* This must be performed before virutal register instantiation.  */
+  /* This must be performed before virtual register instantiation.  */
   if (current_function_calls_alloca)
     optimize_save_area_alloca (insns);
 #endif
@@ -2947,8 +2859,14 @@ rest_of_compilation (decl)
   expected_value_to_br_prob ();
 
   reg_scan (insns, max_reg_num (), 0);
-  jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
-                JUMP_AFTER_REGSCAN);
+  rebuild_jump_labels (insns);
+  find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+  cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP);
+
+  /* CFG is no longer maitained up-to-date.  */
+  free_bb_for_insn ();
+  copy_loop_headers (insns);
+  purge_line_number_notes (insns);
 
   timevar_pop (TV_JUMP);
 
@@ -2970,7 +2888,7 @@ rest_of_compilation (decl)
       open_dump_file (DFI_ssa, decl);
 
       find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-      cleanup_cfg (CLEANUP_EXPENSIVE);
+      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
       convert_to_ssa ();
 
       close_dump_file (DFI_ssa, print_rtl_with_bb, insns);
@@ -2999,7 +2917,7 @@ rest_of_compilation (decl)
 
       if (flag_ssa_dce)
        {
-         /* Remove dead code. */
+         /* Remove dead code.  */
 
          timevar_push (TV_SSA_DCE);
          open_dump_file (DFI_ssa_dce, decl);
@@ -3019,15 +2937,13 @@ rest_of_compilation (decl)
       convert_from_ssa ();
       /* New registers have been created.  Rescan their usage.  */
       reg_scan (insns, max_reg_num (), 1);
-      /* Life analysis used in SSA adds log_links but these
-        shouldn't be there until the flow stage, so clear
-        them away.  */
-      clear_log_links (insns);
 
       close_dump_file (DFI_ussa, print_rtl_with_bb, insns);
       timevar_pop (TV_FROM_SSA);
 
       ggc_collect ();
+      /* CFG is no longer maitained up-to-date.  */
+      free_bb_for_insn ();
     }
 
   timevar_push (TV_JUMP);
@@ -3035,7 +2951,7 @@ rest_of_compilation (decl)
   if (optimize > 0)
     {
       find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-      cleanup_cfg (CLEANUP_EXPENSIVE);
+      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
 
       /* ??? Run if-conversion before delete_null_pointer_checks,
          since the later does not preserve the CFG.  This should
@@ -3045,6 +2961,8 @@ rest_of_compilation (decl)
       if_convert (0);
       timevar_pop (TV_IFCVT);
 
+      /* CFG is no longer maitained up-to-date.  */
+      free_bb_for_insn ();
       /* Try to identify useless null pointer tests and delete them.  */
       if (flag_delete_null_pointer_checks)
        delete_null_pointer_checks (insns);
@@ -3090,14 +3008,17 @@ rest_of_compilation (decl)
       if (tem || optimize > 1)
        {
          timevar_push (TV_JUMP);
-         jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
-                        !JUMP_AFTER_REGSCAN);
+         rebuild_jump_labels (insns);
+         find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+         cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
          timevar_pop (TV_JUMP);
+         /* CFG is no longer maitained up-to-date.  */
+         free_bb_for_insn ();
        }
 
       /* Run this after jump optmizations remove all the unreachable code
         so that unreachable code will not keep values live.  */
-      delete_trivially_dead_insns (insns, max_reg_num ());
+      delete_trivially_dead_insns (insns, max_reg_num (), 0);
 
       /* Try to identify useless null pointer tests and delete them.  */
       if (flag_delete_null_pointer_checks)
@@ -3105,9 +3026,11 @@ rest_of_compilation (decl)
          timevar_push (TV_JUMP);
          find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
 
-         cleanup_cfg (CLEANUP_EXPENSIVE);
+         cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
 
          delete_null_pointer_checks (insns);
+         /* CFG is no longer maitained up-to-date.  */
+         free_bb_for_insn ();
          timevar_pop (TV_JUMP);
        }
 
@@ -3139,13 +3062,15 @@ rest_of_compilation (decl)
       open_dump_file (DFI_gcse, decl);
 
       find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-      cleanup_cfg (CLEANUP_EXPENSIVE);
+      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
       tem = gcse_main (insns, rtl_dump_file);
 
       save_csb = flag_cse_skip_blocks;
       save_cfj = flag_cse_follow_jumps;
       flag_cse_skip_blocks = flag_cse_follow_jumps = 0;
 
+      /* CFG is no longer maitained up-to-date.  */
+      free_bb_for_insn ();
       /* If -fexpensive-optimizations, re-run CSE to clean up things done
         by gcse.  */
       if (flag_expensive_optimizations)
@@ -3163,8 +3088,12 @@ rest_of_compilation (decl)
        {
          tem = tem2 = 0;
          timevar_push (TV_JUMP);
-         jump_optimize (insns, !JUMP_CROSS_JUMP, !JUMP_NOOP_MOVES,
-                        !JUMP_AFTER_REGSCAN);
+         rebuild_jump_labels (insns);
+         delete_trivially_dead_insns (insns, max_reg_num (), 0);
+         find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+         cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
+         /* CFG is no longer maitained up-to-date.  */
+         free_bb_for_insn ();
          timevar_pop (TV_JUMP);
 
          if (flag_expensive_optimizations)
@@ -3190,9 +3119,12 @@ rest_of_compilation (decl)
     {
       timevar_push (TV_LOOP);
       open_dump_file (DFI_loop, decl);
+      free_bb_for_insn ();
 
       if (flag_rerun_loop_opt)
        {
+         cleanup_barriers ();
+
          /* We only want to perform unrolling once.  */
 
          loop_optimize (insns, rtl_dump_file, 0);
@@ -3201,12 +3133,13 @@ rest_of_compilation (decl)
             trivially dead.  We delete those instructions now in the
             hope that doing so will make the heuristics in loop work
             better and possibly speed up compilation.  */
-         delete_trivially_dead_insns (insns, max_reg_num ());
+         delete_trivially_dead_insns (insns, max_reg_num (), 0);
 
          /* The regscan pass is currently necessary as the alias
                  analysis code depends on this information.  */
          reg_scan (insns, max_reg_num (), 1);
        }
+      cleanup_barriers ();
       loop_optimize (insns, rtl_dump_file,
                     (flag_unroll_loops ? LOOP_UNROLL : 0) | LOOP_BCT);
 
@@ -3234,11 +3167,9 @@ rest_of_compilation (decl)
             trivially dead.  We delete those instructions now in the
             hope that doing so will make the heuristics in jump work
             better and possibly speed up compilation.  */
-         delete_trivially_dead_insns (insns, max_reg_num ());
+         delete_trivially_dead_insns (insns, max_reg_num (), 0);
 
          reg_scan (insns, max_reg_num (), 0);
-         jump_optimize (insns, !JUMP_CROSS_JUMP,
-                        !JUMP_NOOP_MOVES, JUMP_AFTER_REGSCAN);
 
          timevar_push (TV_IFCVT);
 
@@ -3250,14 +3181,19 @@ rest_of_compilation (decl)
 
          timevar_pop (TV_JUMP);
 
+         /* CFG is no longer maitained up-to-date.  */
+         free_bb_for_insn ();
          reg_scan (insns, max_reg_num (), 0);
          tem = cse_main (insns, max_reg_num (), 1, rtl_dump_file);
 
          if (tem)
            {
              timevar_push (TV_JUMP);
-             jump_optimize (insns, !JUMP_CROSS_JUMP,
-                            !JUMP_NOOP_MOVES, !JUMP_AFTER_REGSCAN);
+             rebuild_jump_labels (insns);
+             find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+             cleanup_cfg (CLEANUP_EXPENSIVE);
+             /* CFG is no longer maitained up-to-date.  */
+             free_bb_for_insn ();
              timevar_pop (TV_JUMP);
            }
        }
@@ -3335,7 +3271,6 @@ rest_of_compilation (decl)
   life_analysis (insns, rtl_dump_file, PROP_FINAL);
   timevar_pop (TV_FLOW);
 
-  register_life_up_to_date = 1;
   no_new_pseudos = 1;
 
   if (warn_uninitialized || extra_warnings)
@@ -3361,6 +3296,10 @@ rest_of_compilation (decl)
       rebuild_jump_labels_after_combine
        = combine_instructions (insns, max_reg_num ());
 
+      /* Always purge dead edges, as we may eliminate an insn throwing
+         exception.  */
+      rebuild_jump_labels_after_combine |= purge_all_dead_edges ();
+
       /* Combining insns may have turned an indirect jump into a
         direct jump.  Rebuid the JUMP_LABEL fields of jumping
         instructions.  */
@@ -3370,20 +3309,7 @@ rest_of_compilation (decl)
          rebuild_jump_labels (insns);
          timevar_pop (TV_JUMP);
 
-         timevar_push (TV_FLOW);
-         find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
-         cleanup_cfg (CLEANUP_EXPENSIVE);
-
-         /* Blimey.  We've got to have the CFG up to date for the call to
-            if_convert below.  However, the random deletion of blocks
-            without updating life info can wind up with Wierd Stuff in
-            global_live_at_end.  We then run sched1, which updates things
-            properly, discovers the wierdness and aborts.  */
-         update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
-                           PROP_DEATH_NOTES | PROP_KILL_DEAD_CODE
-                           | PROP_SCAN_DEAD_CODE);
-
-         timevar_pop (TV_FLOW);
+         cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
        }
 
       close_dump_file (DFI_combine, print_rtl_with_bb, insns);
@@ -3422,14 +3348,18 @@ rest_of_compilation (decl)
       ggc_collect ();
     }
 
+  /* Do unconditional splitting before register allocation to allow machine
+     description to add extra information not needed previously.  */
+  split_all_insns (1);
+
   /* Any of the several passes since flow1 will have munged register
      lifetime data a bit.  */
-  if (optimize > 0)
-    register_life_up_to_date = 0;
+  register_life_up_to_date = 0;
 
 #ifdef OPTIMIZE_MODE_SWITCHING
-  timevar_push (TV_GCSE);
+  timevar_push (TV_MODE_SWITCH);
 
+  no_new_pseudos = 0;
   if (optimize_mode_switching (NULL))
     {
       /* We did work, and so had to regenerate global life information.
@@ -3437,14 +3367,13 @@ rest_of_compilation (decl)
         information below.  */
       register_life_up_to_date = 1;
     }
+  no_new_pseudos = 1;
 
-  timevar_pop (TV_GCSE);
+  timevar_pop (TV_MODE_SWITCH);
 #endif
 
   timevar_push (TV_SCHED);
 
-  split_all_insns (1);
-
 #ifdef INSN_SCHEDULING
 
   /* Print function header into sched dump now
@@ -3484,6 +3413,15 @@ rest_of_compilation (decl)
 
   if (! register_life_up_to_date)
     recompute_reg_usage (insns, ! optimize_size);
+
+  /* Allocate the reg_renumber array.  */
+  allocate_reg_info (max_regno, FALSE, TRUE);
+
+  /* And the reg_equiv_memory_loc array.  */
+  reg_equiv_memory_loc = (rtx *) xcalloc (max_regno, sizeof (rtx));
+
+  allocate_initial_values (reg_equiv_memory_loc);
+
   regclass (insns, max_reg_num (), rtl_dump_file);
   rebuild_label_notes_after_reload = local_alloc ();
 
@@ -3543,16 +3481,6 @@ rest_of_compilation (decl)
       timevar_pop (TV_RELOAD_CSE_REGS);
     }
 
-  /* If optimizing, then go ahead and split insns now since we are about
-     to recompute flow information anyway.  */
-  if (optimize > 0)
-    {
-      int old_labelnum = max_label_num ();
-
-      split_all_insns (0);
-      rebuild_label_notes_after_reload |= old_labelnum != max_label_num ();
-    }
-
   /* Register allocation and reloading may have turned an indirect jump into
      a direct jump.  If so, we must rebuild the JUMP_LABEL fields of
      jumping instructions.  */
@@ -3571,9 +3499,15 @@ rest_of_compilation (decl)
   timevar_push (TV_FLOW2);
   open_dump_file (DFI_flow2, decl);
 
-  jump_optimize (insns, !JUMP_CROSS_JUMP,
-                JUMP_NOOP_MOVES, !JUMP_AFTER_REGSCAN);
-  find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+#ifdef ENABLE_CHECKING
+  verify_flow_info ();
+#endif
+
+  /* If optimizing, then go ahead and split insns now.  */
+  if (optimize > 0)
+    split_all_insns (0);
+
+  cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0);
 
   /* On some machines, the prologue and epilogue code, or parts thereof,
      can be represented as RTL.  Doing so lets us schedule insns between
@@ -3637,6 +3571,10 @@ rest_of_compilation (decl)
       close_dump_file (DFI_ce2, print_rtl_with_bb, insns);
       timevar_pop (TV_IFCVT2);
     }
+#ifdef STACK_REGS
+  if (optimize)
+    split_all_insns (1);
+#endif
 
 #ifdef INSN_SCHEDULING
   if (optimize > 0 && flag_schedule_insns_after_reload)
@@ -3663,45 +3601,56 @@ rest_of_compilation (decl)
     = optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
 #endif
 
-  if (optimize > 0 && flag_reorder_blocks)
+#ifdef STACK_REGS
+  timevar_push (TV_REG_STACK);
+  open_dump_file (DFI_stack, decl);
+
+  reg_to_stack (insns, rtl_dump_file);
+
+  close_dump_file (DFI_stack, print_rtl_with_bb, insns);
+  timevar_pop (TV_REG_STACK);
+
+  ggc_collect ();
+#endif
+  if (optimize > 0)
     {
       timevar_push (TV_REORDER_BLOCKS);
       open_dump_file (DFI_bbro, decl);
 
-      reorder_basic_blocks ();
+      /* Last attempt to optimize CFG, as life analyzis possibly removed
+        some instructions.  */
+      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
+                  | CLEANUP_CROSSJUMP);
+      if (flag_reorder_blocks)
+       {
+         reorder_basic_blocks ();
+         cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
+       }
 
       close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
       timevar_pop (TV_REORDER_BLOCKS);
     }
+  compute_alignments ();
 
-  /* One more attempt to remove jumps to .+1 left by dead-store elimination.
-     Also do cross-jumping this time and delete no-op move insns.  */
-
-  if (optimize > 0)
-    {
-      timevar_push (TV_JUMP);
-      open_dump_file (DFI_jump2, decl);
-
-      jump_optimize (insns, JUMP_CROSS_JUMP, JUMP_NOOP_MOVES,
-                    !JUMP_AFTER_REGSCAN);
-
-      /* CFG no longer kept up to date.  */
-
-      close_dump_file (DFI_jump2, print_rtl, insns);
-      timevar_pop (TV_JUMP);
-    }
+  /* CFG is no longer maitained up-to-date.  */
+  free_bb_for_insn ();
 
   /* If a machine dependent reorganization is needed, call it.  */
 #ifdef MACHINE_DEPENDENT_REORG
+  timevar_push (TV_MACH_DEP);
   open_dump_file (DFI_mach, decl);
 
   MACHINE_DEPENDENT_REORG (insns);
 
   close_dump_file (DFI_mach, print_rtl, insns);
+  timevar_pop (TV_MACH_DEP);
 
   ggc_collect ();
 #endif
 
+  purge_line_number_notes (insns);
+  cleanup_barriers ();
+
   /* If a scheduling pass for delayed branches is to be done,
      call the scheduling code.  */
 
@@ -3720,28 +3669,10 @@ rest_of_compilation (decl)
     }
 #endif
 
+#if defined (HAVE_ATTR_length) && !defined (STACK_REGS)
   timevar_push (TV_SHORTEN_BRANCH);
-  if (0
-#ifdef HAVE_ATTR_length
-      || 1
-#endif
-#ifdef STACK_REGS
-      || 1
-#endif
-      )
-    split_all_insns (0);
+  split_all_insns_noflow ();
   timevar_pop (TV_SHORTEN_BRANCH);
-
-#ifdef STACK_REGS
-  timevar_push (TV_REG_STACK);
-  open_dump_file (DFI_stack, decl);
-
-  reg_to_stack (insns, rtl_dump_file);
-
-  close_dump_file (DFI_stack, print_rtl, insns);
-  timevar_pop (TV_REG_STACK);
-
-  ggc_collect ();
 #endif
 
   convert_to_eh_region_ranges ();
@@ -3778,7 +3709,7 @@ rest_of_compilation (decl)
     assemble_start_function (decl, fnname);
     final_start_function (insns, asm_out_file, optimize);
     final (insns, asm_out_file, optimize, 0);
-    final_end_function (insns, asm_out_file, optimize);
+    final_end_function ();
 
 #ifdef IA64_UNWIND_INFO
     /* ??? The IA-64 ".handlerdata" directive must be issued before
@@ -3817,20 +3748,7 @@ rest_of_compilation (decl)
      generated.  During that call, we *will* be routed past here.  */
 
   timevar_push (TV_SYMOUT);
-#ifdef DBX_DEBUGGING_INFO
-  if (write_symbols == DBX_DEBUG)
-    dbxout_function (decl);
-#endif
-
-#ifdef DWARF_DEBUGGING_INFO
-  if (write_symbols == DWARF_DEBUG)
-    dwarfout_file_scope_decl (decl, 0);
-#endif
-
-#ifdef DWARF2_DEBUGGING_INFO
-  if (write_symbols == DWARF2_DEBUG)
-    dwarf2out_decl (decl);
-#endif
+  (*debug_hooks->function_decl) (decl);
   timevar_pop (TV_SYMOUT);
 
  exit_rest_of_compilation:
@@ -3878,7 +3796,13 @@ rest_of_compilation (decl)
   /* We're done with this function.  Free up memory if we can.  */
   free_after_parsing (cfun);
   if (! DECL_DEFER_OUTPUT (decl))
-    free_after_compilation (cfun);
+    {
+      free_after_compilation (cfun);
+
+      /* Clear integrate.c's pointer to the cfun structure we just
+        destroyed.  */
+      DECL_SAVED_INSNS (decl) = 0;
+    }
   cfun = 0;
 
   ggc_collect ();
@@ -4312,7 +4236,7 @@ decode_g_option (arg)
      -gdwarf -g3 is equivalent to -gdwarf3.  */
   static int type_explicitly_set_p = 0;
   /* Indexed by enum debug_info_type.  */
-  static const char *debug_type_names[] =
+  static const char *const debug_type_names[] =
   {
     "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff"
   };
@@ -4330,7 +4254,7 @@ decode_g_option (arg)
          enum debug_info_type type = da->debug_type;
          const char *p = arg + da_len;
 
-         if (*p && (*p < '0' || *p > '9'))
+         if (*p && ! ISDIGIT (*p))
            continue;
 
          /* A debug flag without a level defaults to level 2.
@@ -4671,7 +4595,7 @@ toplev_main (argc, argv)
      int argc;
      char **argv;
 {
-  register int i;
+  int i;
   char *p;
 
   /* save in case md file wants to emit args as a comment.  */
@@ -4685,18 +4609,7 @@ toplev_main (argc, argv)
 
   xmalloc_set_program_name (progname);
 
-/* LC_CTYPE determines the character set used by the terminal so it has be set
-   to output messages correctly.  */
-
-#ifdef HAVE_LC_MESSAGES
-  setlocale (LC_CTYPE, "");
-  setlocale (LC_MESSAGES, "");
-#else
-  setlocale (LC_ALL, "");
-#endif
-
-  (void) bindtextdomain (PACKAGE, localedir);
-  (void) textdomain (PACKAGE);
+  gcc_init_libintl ();
 
   /* Install handler for SIGFPE, which may be received while we do
      compile-time floating point arithmetic.  */
@@ -4743,8 +4656,7 @@ toplev_main (argc, argv)
   add_params (lang_independent_params, LAST_PARAM);
 
   /* Perform language-specific options intialization.  */
-  if (lang_hooks.init_options)
-    (*lang_hooks.init_options) ();
+  (*lang_hooks.init_options) ();
 
   /* Scan to see what optimization level has been specified.  That will
      determine the default value of many flags.  */
@@ -4779,6 +4691,11 @@ toplev_main (argc, argv)
        }
     }
 
+  if (!optimize)
+    {
+      flag_merge_constants = 0;
+    }
+
   if (optimize >= 1)
     {
       flag_defer_pop = 1;
@@ -4914,8 +4831,7 @@ toplev_main (argc, argv)
     }
 
   /* All command line options have been processed.  */
-  if (lang_hooks.post_options)
-    (*lang_hooks.post_options) ();
+  (*lang_hooks.post_options) ();
 
   if (exit_after_options)
     exit (0);
@@ -4980,6 +4896,11 @@ toplev_main (argc, argv)
       flag_rerun_cse_after_loop = 1;
     }
 
+  if (flag_non_call_exceptions)
+    flag_asynchronous_unwind_tables = 1;
+  if (flag_asynchronous_unwind_tables)
+    flag_unwind_tables = 1;
+
   /* Warn about options that are not supported on this machine.  */
 #ifndef INSN_SCHEDULING
   if (flag_schedule_insns || flag_schedule_insns_after_reload)
@@ -5040,7 +4961,7 @@ static void
 set_target_switch (name)
      const char *name;
 {
-  register size_t j;
+  size_t j;
   int valid_target_option = 0;
 
   for (j = 0; j < ARRAY_SIZE (target_switches); j++)
@@ -5201,27 +5122,3 @@ print_switch_values (file, pos, max, indent, sep, term)
 
   fprintf (file, "%s", term);
 }
-
-/* 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;
-}