OSDN Git Service

* c-decl.c (finish_decl): When setting the DECL_ASSEMBLER_NAME
[pf3gnuchains/gcc-fork.git] / gcc / toplev.c
index 1ab3f82..7cfb29e 100644 (file)
@@ -74,6 +74,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "langhooks.h"
 #include "cfglayout.h"
 #include "cfgloop.h"
+#include "hosthooks.h"
+#include "cgraph.h"
 
 #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
 #include "dwarf2out.h"
@@ -112,6 +114,7 @@ static void finalize PARAMS ((void));
 static void set_target_switch PARAMS ((const char *));
 
 static void crash_signal PARAMS ((int)) ATTRIBUTE_NORETURN;
+static void setup_core_dumping PARAMS ((void));
 static void compile_file PARAMS ((void));
 static void display_help PARAMS ((void));
 static void display_target_options PARAMS ((void));
@@ -121,6 +124,7 @@ 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 **));
+static void set_Wextra PARAMS ((int));
 
 static void print_version PARAMS ((FILE *, const char *));
 static int print_single_switch PARAMS ((FILE *, int, int, const char *,
@@ -132,6 +136,9 @@ static void print_switch_values PARAMS ((FILE *, int, int, const char *,
 /* Nonzero to dump debug info whilst parsing (-dy option).  */
 static int set_yydebug;
 
+/* True if we don't need a backend (e.g. preprocessing only).  */
+static bool no_backend;
+
 /* Length of line when printing switch values.  */
 #define MAX_LINE 75
 
@@ -143,20 +150,15 @@ const char *progname;
 int save_argc;
 char **save_argv;
 \f
-/* Name of current original source file (what was input to cpp).
-   This comes from each #-command in the actual input.  */
-
-const char *input_filename;
-
 /* Name of top-level original source file (what was input to cpp).
    This comes from the #-command at the beginning of the actual input.
    If there isn't any there, then this is the cc1 input file name.  */
 
 const char *main_input_filename;
 
-/* Current line number in real source file.  */
+/* Current position in real source file.  */
 
-int lineno;
+location_t input_location;
 
 /* Nonzero if it is unsafe to create any new pseudo registers.  */
 int no_new_pseudos;
@@ -174,7 +176,7 @@ const char *dump_base_name;
 
 /* Name to use as a base for auxiliary output files.  */
 
-const char *aux_base_name;
+static const char *aux_base_name;
 
 /* Format to use to print dumpfile index value */
 #ifndef DUMPFILE_FORMAT
@@ -238,6 +240,7 @@ enum dump_file_index
   DFI_bp,
   DFI_ce1,
   DFI_tracer,
+  DFI_loop2,
   DFI_cse2,
   DFI_life,
   DFI_combine,
@@ -250,10 +253,10 @@ enum dump_file_index
   DFI_flow2,
   DFI_peephole2,
   DFI_rnreg,
+  DFI_bbro,
   DFI_ce3,
   DFI_sched2,
   DFI_stack,
-  DFI_bbro,
   DFI_mach,
   DFI_dbr,
   DFI_MAX
@@ -288,6 +291,7 @@ static struct dump_file_info dump_file[DFI_MAX] =
   { "bp",      'b', 1, 0, 0 },
   { "ce1",     'C', 1, 0, 0 },
   { "tracer",  'T', 1, 0, 0 },
+  { "loop2",   'L', 1, 0, 0 },
   { "cse2",    't', 1, 0, 0 },
   { "life",    'f', 1, 0, 0 }, /* Yes, duplicate enable switch.  */
   { "combine", 'c', 1, 0, 0 },
@@ -300,10 +304,10 @@ static struct dump_file_info dump_file[DFI_MAX] =
   { "flow2",   'w', 1, 0, 0 },
   { "peephole2", 'z', 1, 0, 0 },
   { "rnreg",   'n', 1, 0, 0 },
+  { "bbro",    'B', 1, 0, 0 },
   { "ce3",     'E', 1, 0, 0 },
   { "sched2",  'R', 1, 0, 0 },
   { "stack",   'k', 1, 0, 0 },
-  { "bbro",    'B', 1, 0, 0 },
   { "mach",    'M', 1, 0, 0 },
   { "dbr",     'd', 0, 0, 0 },
 };
@@ -317,7 +321,7 @@ static void close_dump_file PARAMS ((enum dump_file_index,
 int rtl_dump_and_exit;
 int flag_print_asm_name;
 static int version_flag;
-static char *filename;
+static const char *filename;
 enum graph_dump_types graph_dump_format;
 
 /* Name for output file of assembly code, specified with -o.  */
@@ -325,7 +329,7 @@ enum graph_dump_types graph_dump_format;
 char *asm_file_name;
 
 /* Value of the -G xx switch, and whether it was passed or not.  */
-int g_switch_value;
+unsigned HOST_WIDE_INT g_switch_value;
 int g_switch_set;
 
 /* Type(s) of debugging information we are producing (if any).
@@ -374,6 +378,10 @@ tree current_function_func_begin_label;
 
 int flag_eliminate_dwarf2_dups = 0;
 
+/* Nonzero if doing unused type elimination.  */
+
+int flag_eliminate_unused_debug_types = 1;
+
 /* Nonzero if generating code to do profiling.  */
 
 int profile_flag = 0;
@@ -419,7 +427,7 @@ int quiet_flag = 0;
 
 /* Print times taken by the various passes.  -ftime-report.  */
 
-int time_report = 0;
+static int time_report = 0;
 
 /* Print memory still in use at end of compilation (which may have little
    to do with peak memory consumption).  -fmem-report.  */
@@ -511,13 +519,25 @@ int flag_strength_reduce = 0;
    UNROLL_MODULO) or at run-time (preconditioned to be UNROLL_MODULO) are
    unrolled.  */
 
-int flag_unroll_loops;
+int flag_old_unroll_loops;
 
 /* Nonzero enables loop unrolling in unroll.c.  All loops are unrolled.
    This is generally not a win.  */
 
+int flag_old_unroll_all_loops;
+
+/* Enables unrolling of simple loops in loop-unroll.c.  */
+int flag_unroll_loops;
+
+/* Enables unrolling of all loops in loop-unroll.c.  */
 int flag_unroll_all_loops;
 
+/* Nonzero enables loop peeling.  */
+int flag_peel_loops;
+
+/* Nonzero enables loop unswitching.  */
+int flag_unswitch_loops;
+
 /* Nonzero enables prefetch optimizations for arrays in loops.  */
 
 int flag_prefetch_loop_arrays;
@@ -589,7 +609,7 @@ int flag_finite_math_only = 0;
 /* Zero means that floating-point math operations cannot generate a
    (user-visible) trap.  This is the case, for example, in nonstop
    IEEE 754 arithmetic.  Trapping conditions include division by zero,
-   overflow, underflow, invalid and inexact, but does not include 
+   overflow, underflow, invalid and inexact, but does not include
    operations on signaling NaNs (see below).  */
 
 int flag_trapping_math = 1;
@@ -606,18 +626,6 @@ int flag_signaling_nans = 0;
 
 int flag_complex_divide_method = 0;
 
-/* Nonzero means all references through pointers are volatile.  */
-
-int flag_volatile;
-
-/* Nonzero means treat all global and extern variables as volatile.  */
-
-int flag_volatile_global;
-
-/* Nonzero means treat all static variables as volatile.  */
-
-int flag_volatile_static;
-
 /* Nonzero means just do syntax checking; don't output anything.  */
 
 int flag_syntax_only = 0;
@@ -750,6 +758,13 @@ int flag_pedantic_errors = 0;
 int flag_schedule_insns = 0;
 int flag_schedule_insns_after_reload = 0;
 
+/* When flag_schedule_insns_after_reload is set, use EBB scheduler.  */
+int flag_sched2_use_superblocks = 0;
+
+/* When flag_schedule_insns_after_reload is set, construct traces and EBB
+   scheduler.  */
+int flag_sched2_use_traces = 0;
+
 /* The following flags have effect only for scheduling before register
    allocation:
 
@@ -888,6 +903,10 @@ int flag_new_regalloc = 0;
 
 int flag_tracer = 0;
 
+/* Nonzero if we perform whole unit at a time compilation.  */
+
+int flag_unit_at_a_time = 0;
+
 /* Values of the -falign-* flags: how much to align labels in code.
    0 means `use default', 1 means `don't align'.
    For each variable, there is an _log variant which is the power
@@ -984,14 +1003,10 @@ static const lang_independent_options f_options[] =
 {
   {"eliminate-dwarf2-dups", &flag_eliminate_dwarf2_dups, 1,
    N_("Perform DWARF2 duplicate elimination") },
+  {"eliminate-unused-debug-types", &flag_eliminate_unused_debug_types, 1,
+   N_("Perform unused type elimination in debug info") },
   {"float-store", &flag_float_store, 1,
    N_("Do not store floats in registers") },
-  {"volatile", &flag_volatile, 1,
-   N_("Consider all mem refs through pointers as volatile") },
-  {"volatile-global", &flag_volatile_global, 1,
-   N_("Consider all mem refs to global data to be volatile") },
-  {"volatile-static", &flag_volatile_static, 1,
-   N_("Consider all mem refs to static data to be volatile") },
   {"defer-pop", &flag_defer_pop, 1,
    N_("Defer popping functions args from stack until later") },
   {"omit-frame-pointer", &flag_omit_frame_pointer, 1,
@@ -1000,6 +1015,8 @@ static const lang_independent_options f_options[] =
    N_("Optimize sibling and tail recursive calls") },
   {"tracer", &flag_tracer, 1,
    N_("Perform superblock formation via tail duplication") },
+  {"unit-at-a-time", &flag_unit_at_a_time, 1,
+   N_("Compile whole compilation unit at a time") },
   {"cse-follow-jumps", &flag_cse_follow_jumps, 1,
    N_("When running CSE, follow jumps to their targets") },
   {"cse-skip-blocks", &flag_cse_skip_blocks, 1,
@@ -1014,6 +1031,14 @@ static const lang_independent_options f_options[] =
    N_("Perform loop unrolling when iteration count is known") },
   {"unroll-all-loops", &flag_unroll_all_loops, 1,
    N_("Perform loop unrolling for all loops") },
+  {"old-unroll-loops", &flag_old_unroll_loops, 1,
+   N_("Perform loop unrolling when iteration count is known") },
+  {"old-unroll-all-loops", &flag_old_unroll_all_loops, 1,
+   N_("Perform loop unrolling for all loops") },
+  {"peel-loops", &flag_peel_loops, 1,
+   N_("Perform loop peeling") },
+  {"unswitch-loops", &flag_unswitch_loops, 1,
+   N_("Perform loop unswitching") },
   {"prefetch-loop-arrays", &flag_prefetch_loop_arrays, 1,
    N_("Generate prefetch instructions, if available, for arrays in loops") },
   {"move-all-movables", &flag_move_all_movables, 1,
@@ -1082,6 +1107,10 @@ static const lang_independent_options f_options[] =
    N_("Allow speculative motion of some loads") },
   {"sched-spec-load-dangerous",&flag_schedule_speculative_load_dangerous, 1,
    N_("Allow speculative motion of more loads") },
+  {"sched2-use-superblocks", &flag_sched2_use_superblocks, 1,
+   N_("If scheduling post reload, do superblock scheduling") },
+  {"sched2-use-traces", &flag_sched2_use_traces, 1,
+   N_("If scheduling post reload, do trace scheduling") },
   {"branch-count-reg",&flag_branch_on_count_reg, 1,
    N_("Replace add,compare,branch with branch on count reg") },
   {"pic", &flag_pic, 1,
@@ -1120,7 +1149,7 @@ static const lang_independent_options f_options[] =
   {"data-sections", &flag_data_sections, 1,
    N_("place data items into their own section") },
   {"verbose-asm", &flag_verbose_asm, 1,
-   N_("Add extra commentry to assembler output") },
+   N_("Add extra commentary to assembler output") },
   {"gnu-linker", &flag_gnu_linker, 1,
    N_("Output GNU ld formatted global initializers") },
   {"regmove", &flag_regmove, 1,
@@ -1148,7 +1177,7 @@ static const lang_independent_options f_options[] =
   {"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") },
+   N_("Attempt to merge identical constants across compilation units") },
   {"merge-all-constants", &flag_merge_constants, 2,
    N_("Attempt to merge identical constants and constant variables") },
   {"dump-unnumbered", &flag_dump_unnumbered, 1,
@@ -1398,6 +1427,7 @@ static const struct
   const char *const prefix;
   const char **const variable;
   const char *const description;
+  const char *const value;
 }
 target_options[] = TARGET_OPTIONS;
 #endif
@@ -1428,6 +1458,9 @@ int warn_unused_parameter;
 int warn_unused_variable;
 int warn_unused_value;
 
+/* Used for cooperation between set_Wunused and set_Wextra.  */
+static int maybe_warn_unused_parameter;
+
 /* Nonzero to warn about code which is never reached.  */
 
 int warn_notreached;
@@ -1551,8 +1584,6 @@ static const lang_independent_options W_options[] =
    N_("Warn when an optimization pass is disabled") },
   {"deprecated-declarations", &warn_deprecated_decl, 1,
    N_("Warn about uses of __attribute__((deprecated)) declarations") },
-  {"extra", &extra_warnings, 1,
-   N_("Print extra (possibly unwanted) warnings") },
   {"missing-noreturn", &warn_missing_noreturn, 1,
    N_("Warn about functions which might be candidates for attribute noreturn") },
   {"strict-aliasing", &warn_strict_aliasing, 1,
@@ -1565,17 +1596,34 @@ set_Wunused (setting)
 {
   warn_unused_function = setting;
   warn_unused_label = setting;
-  /* Unused function parameter warnings are reported when either ``-W
-     -Wunused'' or ``-Wunused-parameter'' is specified.  Differentiate
-     -Wunused by setting WARN_UNUSED_PARAMETER to -1.  */
-  if (!setting)
-    warn_unused_parameter = 0;
-  else if (!warn_unused_parameter)
-    warn_unused_parameter = -1;
+  /* Unused function parameter warnings are reported when either
+     ``-Wextra -Wunused'' or ``-Wunused-parameter'' is specified.
+     Thus, if -Wextra has already been seen, set warn_unused_parameter;
+     otherwise set maybe_warn_extra_parameter, which will be picked up
+     by set_Wextra.  */
+  maybe_warn_unused_parameter = setting;
+  warn_unused_parameter = (setting && extra_warnings);
   warn_unused_variable = setting;
   warn_unused_value = setting;
 }
 
+static void
+set_Wextra (setting)
+     int setting;
+{
+  extra_warnings = setting;
+  warn_unused_value = setting;
+  warn_unused_parameter = (setting && maybe_warn_unused_parameter);
+
+  /* We save the value of warn_uninitialized, since if they put
+     -Wuninitialized on the command line, we need to generate a
+     warning about not using it without also specifying -O.  */
+  if (setting == 0)
+    warn_uninitialized = 0;
+  else if (warn_uninitialized != 1)
+    warn_uninitialized = 2;
+}
+
 /* The following routines are useful in setting all the flags that
    -ffast-math and -fno-fast-math imply.  */
 
@@ -1633,7 +1681,7 @@ read_integral_parameter (p, pname, defval)
   if (*endp != 0)
     {
       if (pname != 0)
-       error ("invalid option `%s'", pname);
+       error ("invalid option argument `%s'", pname);
       return defval;
     }
 
@@ -1703,6 +1751,29 @@ crash_signal (signo)
   internal_error ("%s", strsignal (signo));
 }
 
+/* Arrange to dump core on error.  (The regular error message is still
+   printed first, except in the case of abort().)  */
+
+static void
+setup_core_dumping ()
+{
+#ifdef SIGABRT
+  signal (SIGABRT, SIG_DFL);
+#endif
+#if defined(HAVE_SETRLIMIT)
+  {
+    struct rlimit rlim;
+    if (getrlimit (RLIMIT_CORE, &rlim) != 0)
+      fatal_error ("getting core file size maximum limit: %m");
+    rlim.rlim_cur = rlim.rlim_max;
+    if (setrlimit (RLIMIT_CORE, &rlim) != 0)
+      fatal_error ("setting core file size limit to maximum: %m");
+  }
+#endif
+  diagnostic_abort_on_error (global_dc);
+}
+
+
 /* Strip off a legitimate source ending from the input string NAME of
    length LEN.  Rather than having to know the names used by all of
    our front ends, we strip off an ending of a period followed by
@@ -1842,7 +1913,7 @@ open_dump_file (index, decl)
 
   rtl_dump_file = fopen (dump_name, open_arg);
   if (rtl_dump_file == NULL)
-    fatal_io_error ("can't open %s", dump_name);
+    fatal_error ("can't open %s: %m", dump_name);
 
   free (dump_name);
 
@@ -1913,8 +1984,10 @@ wrapup_global_declarations (vec, len)
     {
       decl = vec[i];
 
-      /* We're not deferring this any longer.  */
-      DECL_DEFER_OUTPUT (decl) = 0;
+      /* We're not deferring this any longer.  Assignment is
+        conditional to avoid needlessly dirtying PCH pages.  */
+      if (DECL_DEFER_OUTPUT (decl) != 0)
+       DECL_DEFER_OUTPUT (decl) = 0;
 
       if (TREE_CODE (decl) == VAR_DECL && DECL_SIZE (decl) == 0)
        (*lang_hooks.finish_incomplete_decl) (decl);
@@ -2053,6 +2126,8 @@ check_global_declarations (vec, len)
          && ! TREE_USED (DECL_NAME (decl))
          && ! DECL_EXTERNAL (decl)
          && ! TREE_PUBLIC (decl)
+         /* A volatile variable might be used in some non-obvious way.  */
+         && ! TREE_THIS_VOLATILE (decl)
          /* Global register variables must be declared to reserve them.  */
          && ! (TREE_CODE (decl) == VAR_DECL && DECL_REGISTER (decl))
          /* Otherwise, ask the language.  */
@@ -2070,9 +2145,9 @@ check_global_declarations (vec, len)
     }
 }
 
-/* Save the current INPUT_FILENAME and LINENO on the top entry in the
+/* Save the current INPUT_LOCATION on the top entry in the
    INPUT_FILE_STACK.  Push a new entry for FILE and LINE, and set the
-   INPUT_FILENAME and LINENO accordingly.  */
+   INPUT_LOCATION accordingly.  */
 
 void
 push_srcloc (file, line)
@@ -2082,22 +2157,20 @@ push_srcloc (file, line)
   struct file_stack *fs;
 
   if (input_file_stack)
-    {
-      input_file_stack->name = input_filename;
-      input_file_stack->line = lineno;
-    }
+    input_file_stack->location = input_location;
 
   fs = (struct file_stack *) xmalloc (sizeof (struct file_stack));
-  fs->name = input_filename = file;
-  fs->line = lineno = line;
+  input_filename = file;
+  input_line = line;
+  fs->location = input_location;
   fs->next = input_file_stack;
   input_file_stack = fs;
   input_file_stack_tick++;
 }
 
 /* Pop the top entry off the stack of presently open source files.
-   Restore the INPUT_FILENAME and LINENO from the new topmost entry on
-   the stack.  */
+   Restore the INPUT_LOCATION from the new topmost entry on the
+   stack.  */
 
 void
 pop_srcloc ()
@@ -2108,11 +2181,14 @@ pop_srcloc ()
   input_file_stack = fs->next;
   free (fs);
   input_file_stack_tick++;
-  /* The initial source file is never popped.  */
-  if (!input_file_stack)
-    abort ();
-  input_filename = input_file_stack->name;
-  lineno = input_file_stack->line;
+
+  if (input_file_stack)
+    input_location = input_file_stack->location;
+  else
+    {
+      input_filename = NULL;
+      input_line = 0;
+    }
 }
 
 /* Compile an entire translation unit.  Write a file of assembly
@@ -2121,12 +2197,10 @@ pop_srcloc ()
 static void
 compile_file ()
 {
-  tree globals;
-
   /* Initialize yet another pass.  */
 
   init_final (main_input_filename);
-  init_branch_prob (aux_base_name);
+  coverage_init (aux_base_name);
 
   timevar_push (TV_PARSE);
 
@@ -2145,37 +2219,12 @@ compile_file ()
   if (flag_syntax_only)
     return;
 
-  globals = (*lang_hooks.decls.getdecls) ();
+  (*lang_hooks.decls.final_write_globals)();
 
-  /* Really define vars that have had only a tentative definition.
-     Really output inline functions that must actually be callable
-     and have not been output so far.  */
-
-  {
-    int len = list_length (globals);
-    tree *vec = (tree *) xmalloc (sizeof (tree) * len);
-    int i;
-    tree decl;
-
-    /* Process the decls in reverse order--earliest first.
-       Put them into VEC from back to front, then take out from front.  */
-
-    for (i = 0, decl = globals; i < len; i++, decl = TREE_CHAIN (decl))
-      vec[len - i - 1] = decl;
-
-    wrapup_global_declarations (vec, len);
-
-    if (profile_arc_flag)
-      /* This must occur after the loop to output deferred functions.
-         Else the profiler initializer would not be emitted if all the
-         functions in this compilation unit were deferred.  */
-      create_profiler ();
-
-    check_global_declarations (vec, len);
-
-    /* Clean up.  */
-    free (vec);
-  }
+  /* This must occur after the loop to output deferred functions.
+     Else the coverage initializer would not be emitted if all the
+     functions in this compilation unit were deferred.  */
+  coverage_finish ();
 
   /* Write out any pending weak symbol declarations.  */
 
@@ -2249,14 +2298,6 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
      int top_level;
      int at_end;
 {
-  /* Declarations of variables, and of functions defined elsewhere.  */
-
-/* The most obvious approach, to put an #ifndef around where
-   this macro is used, doesn't work since it's inside a macro call.  */
-#ifndef ASM_FINISH_DECLARE_OBJECT
-#define ASM_FINISH_DECLARE_OBJECT(FILE, DECL, TOP, END)
-#endif
-
   /* We deferred calling assemble_alias so that we could collect
      other attributes such as visibility.  Emit the alias now.  */
   {
@@ -2284,11 +2325,14 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
         is seen.  But at end of compilation, do output code for them.  */
       if (at_end || !DECL_DEFER_OUTPUT (decl))
        assemble_variable (decl, top_level, at_end, 0);
+
+#ifdef ASM_FINISH_DECLARE_OBJECT
       if (decl == last_assemble_variable_decl)
        {
          ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
                                     top_level, at_end);
        }
+#endif
 
       timevar_pop (TV_VARCONST);
     }
@@ -2342,7 +2386,8 @@ rest_of_decl_compilation (decl, asmspec, top_level, at_end)
 
 void
 rest_of_type_compilation (type, toplev)
-#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO) || defined (SDB_DEBUGGING_INFO)
+#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)     \
+    || defined (SDB_DEBUGGING_INFO) || defined (DWARF2_DEBUGGING_INFO)
      tree type;
      int toplev;
 #else
@@ -2387,7 +2432,6 @@ rest_of_compilation (decl)
   int tem;
   int failure = 0;
   int rebuild_label_notes_after_reload;
-  int register_life_up_to_date;
 
   timevar_push (TV_REST_OF_COMPILATION);
 
@@ -2458,12 +2502,16 @@ rest_of_compilation (decl)
                  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.  */
+         else {
+           /* ??? Note that we used to just make it look like if
+                the "inline" keyword was specified when we decide
+                to inline it (because of -finline-functions).
+                garloff@suse.de, 2002-04-24: Add another flag to
+                actually record this piece of information.  */
+           if (!DECL_INLINE (decl))
+              DID_INLINE_FUNC (decl) = 1;
            inlinable = DECL_INLINE (decl) = 1;
+         }
        }
 
       insns = get_insns ();
@@ -2491,6 +2539,7 @@ rest_of_compilation (decl)
 
       if (inlinable
          || (DECL_INLINE (decl)
+             && flag_inline_functions
              && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
                   && ! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
                   && ! flag_keep_inline_functions)
@@ -2602,10 +2651,17 @@ rest_of_compilation (decl)
 
   delete_unreachable_blocks ();
 
+  /* We have to issue these warnings now already, because CFG cleanups
+     further down may destroy the required information.  */
+  check_function_return_warnings ();
+
   /* Turn NOTE_INSN_PREDICTIONs into branch predictions.  */
-  timevar_push (TV_BRANCH_PROB);
-  note_prediction_to_br_prob ();
-  timevar_pop (TV_BRANCH_PROB);
+  if (flag_guess_branch_prob)
+    {
+      timevar_push (TV_BRANCH_PROB);
+      note_prediction_to_br_prob ();
+      timevar_pop (TV_BRANCH_PROB);
+    }
 
   /* We may have potential sibling or tail recursion sites.  Select one
      (of possibly multiple) methods of performing the call.  */
@@ -2686,21 +2742,25 @@ rest_of_compilation (decl)
   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 ();
+  if (flag_guess_branch_prob)
+    expected_value_to_br_prob ();
 
   reg_scan (insns, max_reg_num (), 0);
   rebuild_jump_labels (insns);
   find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+  delete_trivially_dead_insns (insns, max_reg_num ());
   if (rtl_dump_file)
     dump_flow_info (rtl_dump_file);
   cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP
               | (flag_thread_jumps ? CLEANUP_THREADING : 0));
 
-  /* CFG is no longer maintained up-to-date.  */
-  free_bb_for_insn ();
-  copy_loop_headers (insns);
+  if (optimize)
+    {
+      free_bb_for_insn ();
+      copy_loop_headers (insns);
+      find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
+    }
   purge_line_number_notes (insns);
-  find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
 
   timevar_pop (TV_JUMP);
   close_dump_file (DFI_jump, print_rtl, insns);
@@ -2778,7 +2838,8 @@ rest_of_compilation (decl)
     }
 
   timevar_push (TV_JUMP);
-  cleanup_cfg (optimize ? CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP: 0);
+  if (optimize)
+    cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
 
   /* Try to identify useless null pointer tests and delete them.  */
   if (flag_delete_null_pointer_checks)
@@ -2879,6 +2940,10 @@ rest_of_compilation (decl)
       save_cfj = flag_cse_follow_jumps;
       flag_cse_skip_blocks = flag_cse_follow_jumps = 0;
 
+      /* Instantiate any remaining CONSTANT_P_RTX nodes.  */
+      if (current_function_calls_constant_p)
+       purge_builtin_constant_p ();
+
       /* If -fexpensive-optimizations, re-run CSE to clean up things done
         by gcse.  */
       if (flag_expensive_optimizations)
@@ -2924,9 +2989,6 @@ rest_of_compilation (decl)
 #endif
     }
 
-  /* Instantiate any remaining CONSTANT_P_RTX nodes.  */
-  purge_builtin_constant_p ();
-
   /* Move constant computations out of loops.  */
 
   if (optimize > 0 && flag_loop_optimize)
@@ -2940,7 +3002,10 @@ rest_of_compilation (decl)
       /* CFG is no longer maintained up-to-date.  */
       free_bb_for_insn ();
 
-      do_unroll = flag_unroll_loops ? LOOP_UNROLL : LOOP_AUTO_UNROLL;
+      if (flag_unroll_loops)
+       do_unroll = 0;          /* Having two unrollers is useless.  */
+      else
+       do_unroll = flag_old_unroll_loops ? LOOP_UNROLL : LOOP_AUTO_UNROLL;
       do_prefetch = flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0;
       if (flag_rerun_loop_opt)
        {
@@ -3005,8 +3070,9 @@ rest_of_compilation (decl)
   open_dump_file (DFI_cfg, decl);
   if (rtl_dump_file)
     dump_flow_info (rtl_dump_file);
-  cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0)
-              | (flag_thread_jumps ? CLEANUP_THREADING : 0));
+  if (optimize)
+    cleanup_cfg (CLEANUP_EXPENSIVE
+                | (flag_thread_jumps ? CLEANUP_THREADING : 0));
 
   /* It may make more sense to mark constant functions after dead code is
      eliminated by life_analysis, but we need to do it early, as -fprofile-arcs
@@ -3021,13 +3087,14 @@ rest_of_compilation (decl)
   close_dump_file (DFI_cfg, print_rtl_with_bb, insns);
 
   /* Do branch profiling and static profile estimation passes.  */
-  if (optimize > 0 || cfun->arc_profile || flag_branch_probabilities)
+  if (optimize > 0
+      || profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
     {
       struct loops loops;
 
       timevar_push (TV_BRANCH_PROB);
       open_dump_file (DFI_bp, decl);
-      if (cfun->arc_profile || flag_branch_probabilities)
+      if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
        branch_prob ();
 
       /* Discover and record the loop depth at the head of each basic
@@ -3045,7 +3112,7 @@ rest_of_compilation (decl)
       close_dump_file (DFI_bp, print_rtl_with_bb, insns);
       timevar_pop (TV_BRANCH_PROB);
     }
-  if (optimize >= 0)
+  if (optimize > 0)
     {
       open_dump_file (DFI_ce1, decl);
       if (flag_if_conversion)
@@ -3077,6 +3144,46 @@ rest_of_compilation (decl)
       timevar_pop (TV_TRACER);
     }
 
+  /* Perform loop optimalizations.  It might be better to do them a bit
+     sooner, but we want the profile feedback to work more efficiently.  */
+  if (optimize > 0
+      && (flag_unswitch_loops
+         || flag_peel_loops
+         || flag_unroll_loops))
+    {
+      struct loops *loops;
+      timevar_push (TV_LOOP);
+      open_dump_file (DFI_loop2, decl);
+      if (rtl_dump_file)
+       dump_flow_info (rtl_dump_file);
+
+      loops = loop_optimizer_init (rtl_dump_file);
+
+      if (loops)
+       {
+         /* The optimalizations:  */
+         if (flag_unswitch_loops)
+           unswitch_loops (loops);
+
+         if (flag_peel_loops || flag_unroll_loops)
+           unroll_and_peel_loops (loops,
+               (flag_peel_loops ? UAP_PEEL : 0) |
+               (flag_unroll_loops ? UAP_UNROLL : 0) |
+               (flag_unroll_all_loops ? UAP_UNROLL_ALL : 0));
+
+         loop_optimizer_finalize (loops, rtl_dump_file);
+       }
+
+      cleanup_cfg (CLEANUP_EXPENSIVE);
+      delete_trivially_dead_insns (insns, max_reg_num ());
+      reg_scan (insns, max_reg_num (), 0);
+      if (rtl_dump_file)
+       dump_flow_info (rtl_dump_file);
+      close_dump_file (DFI_loop2, print_rtl_with_bb, get_insns ());
+      timevar_pop (TV_LOOP);
+      ggc_collect ();
+    }
+
   if (flag_rerun_cse_after_loop)
     {
       timevar_push (TV_CSE2);
@@ -3106,8 +3213,6 @@ rest_of_compilation (decl)
   open_dump_file (DFI_life, decl);
   regclass_init ();
 
-  check_function_return_warnings ();
-
 #ifdef ENABLE_CHECKING
   verify_flow_info ();
 #endif
@@ -3117,9 +3222,7 @@ rest_of_compilation (decl)
                 | (flag_thread_jumps ? CLEANUP_THREADING : 0));
   timevar_pop (TV_FLOW);
 
-  no_new_pseudos = 1;
-
-  if (warn_uninitialized || extra_warnings)
+  if (warn_uninitialized)
     {
       uninitialized_vars_warning (DECL_INITIAL (decl));
       if (extra_warnings)
@@ -3128,17 +3231,19 @@ rest_of_compilation (decl)
 
   if (optimize)
     {
-      clear_bb_flags ();
       if (!flag_new_regalloc && initialize_uninitialized_subregs ())
        {
-         /* Insns were inserted, so things might look a bit different.  */
+         /* Insns were inserted, and possibly pseudos created, so
+            things might look a bit different.  */
          insns = get_insns ();
-         update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
-                                           PROP_LOG_LINKS | PROP_REG_INFO
-                                           | PROP_DEATH_NOTES);
+         allocate_reg_life_data ();
+         update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
+                           PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES);
        }
     }
 
+  no_new_pseudos = 1;
+
   close_dump_file (DFI_life, print_rtl_with_bb, insns);
 
   ggc_collect ();
@@ -3208,10 +3313,6 @@ rest_of_compilation (decl)
      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.  */
-  register_life_up_to_date = 0;
-
 #ifdef OPTIMIZE_MODE_SWITCHING
   timevar_push (TV_MODE_SWITCH);
 
@@ -3222,6 +3323,11 @@ rest_of_compilation (decl)
   timevar_pop (TV_MODE_SWITCH);
 #endif
 
+  /* Any of the several passes since flow1 will have munged register
+     lifetime data a bit.  We need it to be up to date for scheduling
+     (see handling of reg_known_equiv in init_alias_analysis).  */
+  recompute_reg_usage (insns, !optimize_size);
+
   timevar_push (TV_SCHED);
 
 #ifdef INSN_SCHEDULING
@@ -3238,10 +3344,6 @@ rest_of_compilation (decl)
       schedule_insns (rtl_dump_file);
 
       close_dump_file (DFI_sched, print_rtl_with_bb, insns);
-
-      /* Register lifetime information was updated as part of verifying
-        the schedule.  */
-      register_life_up_to_date = 1;
     }
 #endif
   timevar_pop (TV_SCHED);
@@ -3261,9 +3363,6 @@ rest_of_compilation (decl)
      RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the
      jump optimizer after register allocation and reloading are finished.  */
 
-  if (! register_life_up_to_date)
-    recompute_reg_usage (insns, ! optimize_size);
-
   if (flag_new_regalloc)
     {
       delete_trivially_dead_insns (insns, max_reg_num ());
@@ -3396,10 +3495,13 @@ rest_of_compilation (decl)
 #endif
 
   /* If optimizing, then go ahead and split insns now.  */
+#ifndef STACK_REGS
   if (optimize > 0)
+#endif
     split_all_insns (0);
 
-  cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0);
+  if (optimize)
+    cleanup_cfg (CLEANUP_EXPENSIVE);
 
   /* On some machines, the prologue and epilogue code, or parts thereof,
      can be represented as RTL.  Doing so lets us schedule insns between
@@ -3457,6 +3559,28 @@ rest_of_compilation (decl)
       timevar_pop (TV_RENAME_REGISTERS);
     }
 
+  if (optimize > 0)
+    {
+      timevar_push (TV_REORDER_BLOCKS);
+      open_dump_file (DFI_bbro, decl);
+
+      /* Last attempt to optimize CFG, as scheduling, peepholing and insn
+        splitting possibly introduced more crossjumping opportunities.  */
+      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE
+                  | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
+
+      if (flag_sched2_use_traces && flag_schedule_insns_after_reload)
+        tracer ();
+      if (flag_reorder_blocks)
+       reorder_basic_blocks ();
+      if (flag_reorder_blocks
+         || (flag_sched2_use_traces && flag_schedule_insns_after_reload))
+         cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
+
+      close_dump_file (DFI_bbro, print_rtl_with_bb, insns);
+      timevar_pop (TV_REORDER_BLOCKS);
+    }
+
   if (flag_if_conversion2)
     {
       timevar_push (TV_IFCVT2);
@@ -3467,10 +3591,6 @@ rest_of_compilation (decl)
       close_dump_file (DFI_ce3, 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)
@@ -3483,7 +3603,16 @@ rest_of_compilation (decl)
 
       split_all_insns (1);
 
-      schedule_insns (rtl_dump_file);
+      if (flag_sched2_use_superblocks || flag_sched2_use_traces)
+       {
+         schedule_ebbs (rtl_dump_file);
+         /* No liveness updating code yet, but it should be easy to do.
+            reg-stack recompute the liveness when needed for now.  */
+         count_or_remove_death_notes (NULL, 1);
+         cleanup_cfg (CLEANUP_EXPENSIVE);
+       }
+      else
+        schedule_insns (rtl_dump_file);
 
       close_dump_file (DFI_sched2, print_rtl_with_bb, insns);
       timevar_pop (TV_SCHED2);
@@ -3501,50 +3630,40 @@ rest_of_compilation (decl)
   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)
+  if (reg_to_stack (insns, rtl_dump_file) && optimize)
     {
-      timevar_push (TV_REORDER_BLOCKS);
-      open_dump_file (DFI_bbro, decl);
-
-      /* Last attempt to optimize CFG, as scheduling, peepholing and insn
-        splitting possibly introduced more crossjumping opportunities.
-        Except that we can't actually run crossjumping without running
-        another DCE pass, which we can't do after reg-stack.  */
-      cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
-                  | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
-      if (flag_reorder_blocks)
+      if (cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
+                      | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0))
+         && 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);
     }
+
+  close_dump_file (DFI_stack, print_rtl_with_bb, insns);
+  timevar_pop (TV_REG_STACK);
+
+  ggc_collect ();
+#endif
   compute_alignments ();
 
   /* CFG is no longer maintained up-to-date.  */
   free_bb_for_insn ();
 
   /* If a machine dependent reorganization is needed, call it.  */
-#ifdef MACHINE_DEPENDENT_REORG
-  timevar_push (TV_MACH_DEP);
-  open_dump_file (DFI_mach, decl);
+  if (targetm.machine_dependent_reorg != 0)
+    {
+      timevar_push (TV_MACH_DEP);
+      open_dump_file (DFI_mach, decl);
 
-  MACHINE_DEPENDENT_REORG (insns);
+      (*targetm.machine_dependent_reorg) ();
 
-  close_dump_file (DFI_mach, print_rtl, insns);
-  timevar_pop (TV_MACH_DEP);
+      close_dump_file (DFI_mach, print_rtl, insns);
+      timevar_pop (TV_MACH_DEP);
 
-  ggc_collect ();
-#endif
+      ggc_collect ();
+    }
 
   purge_line_number_notes (insns);
   cleanup_barriers ();
@@ -3652,6 +3771,8 @@ rest_of_compilation (decl)
 
  exit_rest_of_compilation:
 
+  coverage_end_function ();
+  
   /* In case the function was not output,
      don't leave any temporary anonymous types
      queued up for sdb output.  */
@@ -3678,6 +3799,16 @@ rest_of_compilation (decl)
 
   timevar_pop (TV_FINAL);
 
+  if ((*targetm.binds_local_p) (current_function_decl))
+    {
+      int pref = cfun->preferred_stack_boundary;
+      if (cfun->recursive_call_emit
+          && cfun->stack_alignment_needed > cfun->preferred_stack_boundary)
+       pref = cfun->stack_alignment_needed;
+      cgraph_rtl_info (current_function_decl)->preferred_incoming_stack_boundary
+        = pref;
+    }
+
   /* Make sure volatile mem refs aren't considered valid operands for
      arithmetic insns.  We must call this here if this is a nested inline
      function, since the above code leaves us in the init_recog state
@@ -3720,6 +3851,10 @@ display_help ()
   printf (_("  -fmessage-length=<number> Limits diagnostics messages lengths to <number> characters per line.  0 suppresses line-wrapping\n"));
   printf (_("  -fdiagnostics-show-location=[once | every-line] Indicates how often source location information should be emitted, as prefix, at the beginning of diagnostics when line-wrapping\n"));
   printf (_("  -ftls-model=[global-dynamic | local-dynamic | initial-exec | local-exec] Indicates the default thread-local storage code generation model\n"));
+  printf (_("  -fstack-limit-register=<register>  Trap if the stack goes past <register>\n"));
+  printf (_("  -fstack-limit-symbol=<name>  Trap if the stack goes past symbol <name>\n"));
+  printf (_("  -frandom-seed=<string>  Make compile reproducible using <string>\n"));
+  
 
   for (i = ARRAY_SIZE (f_options); i--;)
     {
@@ -3756,6 +3891,7 @@ display_help ()
                W_options[i].string, _(description));
     }
 
+  printf (_("  -Wextra                 Print extra (possibly unwanted) warnings\n"));
   printf (_("  -Wunused                Enable unused warnings\n"));
   printf (_("  -Wlarger-than-<number>  Warn if an object is larger than <number> bytes\n"));
   printf (_("  -p                      Enable function profiling\n"));
@@ -3941,6 +4077,9 @@ decode_d_option (arg)
       case 'D':        /* These are handled by the preprocessor.  */
       case 'I':
        break;
+      case 'H':
+       setup_core_dumping();
+       break;
 
       default:
        matched = 0;
@@ -3996,6 +4135,16 @@ decode_f_option (arg)
        read_integral_parameter (option_value, arg - 2,
                                 MAX_INLINE_INSNS);
       set_param_value ("max-inline-insns", val);
+      set_param_value ("max-inline-insns-single", val/2);
+      set_param_value ("max-inline-insns-auto", val/2);
+      set_param_value ("max-inline-insns-rtl", val);
+      if (val/4 < MIN_INLINE_INSNS)
+       {
+         if (val/4 > 10)
+           set_param_value ("min-inline-insns", val/4);
+         else
+           set_param_value ("min-inline-insns", 10);
+       }
     }
   else if ((option_value = skip_leading_substring (arg, "tls-model=")))
     {
@@ -4064,6 +4213,10 @@ decode_f_option (arg)
     }
   else if (!strcmp (arg, "no-stack-limit"))
     stack_limit_rtx = NULL_RTX;
+  else if ((option_value = skip_leading_substring (arg, "random-seed=")))
+    flag_random_seed = option_value;
+  else if (!strcmp (arg, "no-random-seed"))
+    flag_random_seed = NULL;
   else if (!strcmp (arg, "preprocessed"))
     /* Recognize this switch but do nothing.  This prevents warnings
        about an unrecognized switch if cpplib has not been linked in.  */
@@ -4121,11 +4274,11 @@ decode_W_option (arg)
     }
   else if (!strcmp (arg, "extra"))
     {
-      /* We save the value of warn_uninitialized, since if they put
-        -Wuninitialized on the command line, we need to generate a
-        warning about not using it without also specifying -O.  */
-      if (warn_uninitialized != 1)
-       warn_uninitialized = 2;
+      set_Wextra (1);
+    }
+  else if (!strcmp (arg, "no-extra"))
+    {
+      set_Wextra (0);
     }
   else
     return 0;
@@ -4133,6 +4286,12 @@ decode_W_option (arg)
   return 1;
 }
 
+/* Indexed by enum debug_info_type.  */
+const char *const debug_type_names[] =
+{
+  "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff", "vms"
+};
+
 /* Parse a -g... command line switch.  ARG is the value after the -g.
    It is safe to access 'ARG - 2' to generate the full switch name.
    Return the number of strings consumed.  */
@@ -4152,11 +4311,6 @@ decode_g_option (arg)
      -g and -ggdb don't explicitly set the debugging format so
      -gdwarf -g3 is equivalent to -gdwarf3.  */
   static int type_explicitly_set_p = 0;
-  /* Indexed by enum debug_info_type.  */
-  static const char *const debug_type_names[] =
-  {
-    "none", "stabs", "coff", "dwarf-1", "dwarf-2", "xcoff", "vms"
-  };
 
   /* The maximum admissible debug level value.  */
   static const unsigned max_debug_level = 3;
@@ -4285,18 +4439,21 @@ independent_decode_option (argc, argv)
     {
       display_help ();
       exit_after_options = 1;
+      return 1;
     }
 
   if (!strcmp (arg, "-target-help"))
     {
       display_target_options ();
       exit_after_options = 1;
+      return 1;
     }
 
   if (!strcmp (arg, "-version"))
     {
       print_version (stderr, "");
       exit_after_options = 1;
+      return 1;
     }
 
   /* Handle '--param <name>=<value>'.  */
@@ -4333,9 +4490,6 @@ independent_decode_option (argc, argv)
       return 2;
     }
 
-  if (*arg == 'Y')
-    arg++;
-
   switch (*arg)
     {
     default:
@@ -4363,7 +4517,7 @@ independent_decode_option (argc, argv)
 
          if (argv[1][0])
            dump_base_name = argv[1];
-         
+
          return 2;
        }
       else
@@ -4403,15 +4557,9 @@ independent_decode_option (argc, argv)
       break;
 
     case 'W':
+      /* For backward compatibility, -W is the same as -Wextra.  */
       if (arg[1] == 0)
-       {
-         extra_warnings = 1;
-         /* We save the value of warn_uninitialized, since if they put
-            -Wuninitialized on the command line, we need to generate a
-            warning about not using it without also specifying -O.  */
-         if (warn_uninitialized != 1)
-           warn_uninitialized = 2;
-       }
+       set_Wextra (1);
       else
        return decode_W_option (arg + 1);
       break;
@@ -4443,7 +4591,7 @@ independent_decode_option (argc, argv)
 
          if (argv[1][0])
            aux_base_name = argv[1];
-         
+
          return 2;
        }
       else if (!strcmp (arg, "auxbase-strip"))
@@ -4457,7 +4605,7 @@ independent_decode_option (argc, argv)
              if (argv[1][0])
                aux_base_name = argv[1];
            }
-         
+
          return 2;
        }
       else
@@ -4541,10 +4689,21 @@ set_target_switch (name)
     for (j = 0; j < ARRAY_SIZE (target_options); j++)
       {
        int len = strlen (target_options[j].prefix);
-       if (!strncmp (target_options[j].prefix, name, len))
+       if (target_options[j].value)
          {
-           *target_options[j].variable = name + len;
-           valid_target_option = 1;
+           if (!strcmp (target_options[j].prefix, name))
+             {
+               *target_options[j].variable = target_options[j].value;
+               valid_target_option = 1;
+             }
+         }
+       else
+         {
+           if (!strncmp (target_options[j].prefix, name, len))
+             {
+               *target_options[j].variable = name + len;
+               valid_target_option = 1;
+             }
          }
       }
 #endif
@@ -4574,6 +4733,9 @@ print_version (file, indent)
           , indent, *indent != 0 ? " " : "",
           lang_hooks.name, version_string, TARGET_NAME,
           indent, __VERSION__);
+  fnotice (file, "%s%sGGC heuristics: --param ggc-min-expand=%d --param ggc-min-heapsize=%d\n",
+          indent, *indent != 0 ? " " : "",
+          PARAM_VALUE (GGC_MIN_EXPAND), PARAM_VALUE (GGC_MIN_HEAPSIZE));
 }
 
 /* Print an option value and return the adjusted position in the line.
@@ -4620,6 +4782,12 @@ print_switch_values (file, pos, max, indent, sep, term)
   size_t j;
   char **p;
 
+  /* Fill in the -frandom-seed option, if the user didn't pass it, so
+     that it can be printed below.  This helps reproducibility.  Of
+     course, the string may never be used, but we can't tell that at
+     this point in the compile.  */
+  default_flag_random_seed ();
+
   /* Print the options as passed.  */
 
   pos = print_single_switch (file, pos, max, indent, *indent ? " " : "", term,
@@ -4711,7 +4879,7 @@ init_asm_output (name)
       else
        asm_out_file = fopen (asm_file_name, "w+");
       if (asm_out_file == 0)
-       fatal_io_error ("can't open %s for writing", asm_file_name);
+       fatal_error ("can't open %s for writing: %m", asm_file_name);
     }
 
 #ifdef IO_BUFFER_SIZE
@@ -4780,6 +4948,9 @@ general_init (argv0)
   signal (SIGFPE, crash_signal);
 #endif
 
+  /* Other host-specific signal setup.  */
+  (*host_hooks.extra_signals)();
+
   /* Initialize the diagnostics reporting machinery, so option parsing
      can give warnings and errors.  */
   diagnostic_initialize (global_dc);
@@ -4814,6 +4985,9 @@ parse_options_and_default_flags (argc, argv)
   /* Register the language-independent parameters.  */
   add_params (lang_independent_params, LAST_PARAM);
 
+  /* This must be done after add_params but before argument processing.  */
+  init_ggc_heuristics();
+
   /* Perform language-specific options initialization.  */
   (*lang_hooks.init_options) ();
 
@@ -4901,6 +5075,8 @@ parse_options_and_default_flags (argc, argv)
     {
       flag_inline_functions = 1;
       flag_rename_registers = 1;
+      flag_unswitch_loops = 1;
+      flag_unit_at_a_time = 1;
     }
 
   if (optimize < 2 || optimize_size)
@@ -5040,11 +5216,31 @@ parse_options_and_default_flags (argc, argv)
 static void
 process_options ()
 {
+  /* Allow the front end to perform consistency checks and do further
+     initialization based on the command line options.  This hook also
+     sets the original filename if appropriate (e.g. foo.i -> foo.c)
+     so we can correctly initialize debug output.  */
+  no_backend = (*lang_hooks.post_options) (&filename);
+  main_input_filename = input_filename = filename;
+
 #ifdef OVERRIDE_OPTIONS
   /* Some machines may reject certain combinations of options.  */
   OVERRIDE_OPTIONS;
 #endif
 
+  /* Set aux_base_name if not already set.  */
+  if (aux_base_name)
+    ;
+  else if (filename)
+    {
+      char *name = xstrdup (lbasename (filename));
+      
+      strip_off_ending (name, strlen (name));
+      aux_base_name = name;
+    }
+  else
+    aux_base_name = "gccaux";
+
   /* Set up the align_*_log variables, defaulting them to 1 if they
      were still unset.  */
   if (align_loops <= 0) align_loops = 1;
@@ -5066,21 +5262,38 @@ process_options ()
      be done.  */
   if (flag_unroll_all_loops)
     flag_unroll_loops = 1;
-  /* Loop unrolling requires that strength_reduction be on also.  Silently
+
+  if (flag_unroll_loops)
+    {
+      flag_old_unroll_loops = 0;
+      flag_old_unroll_all_loops = 0;
+    }
+
+  if (flag_old_unroll_all_loops)
+    flag_old_unroll_loops = 1;
+
+  /* Old loop unrolling requires that strength_reduction be on also.  Silently
      turn on strength reduction here if it isn't already on.  Also, the loop
      unrolling code assumes that cse will be run after loop, so that must
      be turned on also.  */
-  if (flag_unroll_loops)
+  if (flag_old_unroll_loops)
     {
       flag_strength_reduce = 1;
       flag_rerun_cse_after_loop = 1;
     }
+  if (flag_unroll_loops || flag_peel_loops)
+    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;
 
+  /* Disable unit-at-a-time mode for frontends not supporting callgraph
+     interface.  */
+  if (flag_unit_at_a_time && ! lang_hooks.callgraph.expand_function)
+    flag_unit_at_a_time = 0;
+
   /* Warn about options that are not supported on this machine.  */
 #ifndef INSN_SCHEDULING
   if (flag_schedule_insns || flag_schedule_insns_after_reload)
@@ -5115,9 +5328,6 @@ process_options ()
        print_switch_values (stderr, 0, MAX_LINE, "", " ", "\n");
     }
 
-  if (! quiet_flag)
-    time_report = 1;
-
   if (flag_syntax_only)
     {
       write_symbols = NO_DEBUG;
@@ -5158,7 +5368,7 @@ process_options ()
     {
       aux_info_file = fopen (aux_info_file_name, "w");
       if (aux_info_file == 0)
-       fatal_io_error ("can't open %s", aux_info_file_name);
+       fatal_error ("can't open %s: %m", aux_info_file_name);
     }
 
   if (! targetm.have_named_sections)
@@ -5251,18 +5461,11 @@ lang_dependent_init (name)
 {
   if (dump_base_name == 0)
     dump_base_name = name ? name : "gccdump";
-  
-  /* Front-end initialization.  This hook can assume that GC,
-     identifier hashes etc. are set up, but debug initialization is
-     not done yet.  This routine must return the original filename
-     (e.g. foo.i -> foo.c) so can correctly initialize debug output.  */
-  name = (*lang_hooks.init) (name);
-  if (name == NULL)
+
+  /* Other front-end initialization.  */
+  if ((*lang_hooks.init) () == 0)
     return 0;
 
-  /* Is this duplication necessary?  */
-  name = ggc_strdup (name);
-  main_input_filename = input_filename = name;
   init_asm_output (name);
 
   /* These create various _DECL nodes, so need to be called after the
@@ -5317,9 +5520,9 @@ finalize ()
   if (asm_out_file)
     {
       if (ferror (asm_out_file) != 0)
-       fatal_io_error ("error writing to %s", asm_file_name);
+       fatal_error ("error writing to %s: %m", asm_file_name);
       if (fclose (asm_out_file) != 0)
-       fatal_io_error ("error closing %s", asm_file_name);
+       fatal_error ("error closing %s: %m", asm_file_name);
     }
 
   /* Do whatever is necessary to finish printing the graphs.  */
@@ -5358,43 +5561,27 @@ finalize ()
 static void
 do_compile ()
 {
-  /* All command line options have been parsed; allow the front end to
-     perform consistency checks, etc.  */
-  bool no_backend = (*lang_hooks.post_options) ();
+  /* Initialize timing first.  The C front ends read the main file in
+     the post_options hook, and C++ does file timings.  */
+  if (time_report || !quiet_flag  || flag_detailed_statistics)
+    timevar_init ();
+  timevar_start (TV_TOTAL);
 
-  /* The bulk of command line switch processing.  */
   process_options ();
 
-  /* If an error has already occurred, give up.  */
-  if (errorcount)
-    return;
-
-  if (aux_base_name)
-    /*NOP*/;
-  else if (filename)
+  /* Don't do any more if an error has already occurred.  */
+  if (!errorcount)
     {
-      char *name = xstrdup (lbasename (filename));
-      
-      aux_base_name = name;
-      strip_off_ending (name, strlen (name));
-    }
-  else
-    aux_base_name = "gccaux";
+      /* Set up the back-end if requested.  */
+      if (!no_backend)
+       backend_init ();
 
-  /* We cannot start timing until after options are processed since that
-     says if we run timers or not.  */
-  init_timevar ();
-  timevar_start (TV_TOTAL);
+      /* Language-dependent initialization.  Returns true on success.  */
+      if (lang_dependent_init (filename))
+       compile_file ();
 
-  /* Set up the back-end if requested.  */
-  if (!no_backend)
-    backend_init ();
-
-  /* Language-dependent initialization.  Returns true on success.  */
-  if (lang_dependent_init (filename))
-    compile_file ();
-
-  finalize ();
+      finalize ();
+    }
 
   /* Stop timing and print the times.  */
   timevar_stop (TV_TOTAL);