OSDN Git Service

* config/sol2.c (solaris_assemble_visibility): Declare decl, vis
[pf3gnuchains/gcc-fork.git] / gcc / opts.c
index 2a88ce2..cf1fd2d 100644 (file)
@@ -1,5 +1,5 @@
 /* Command line option handling.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Neil Booth.
 
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tm.h"
 #include "tree.h"
 #include "rtl.h"
+#include "expr.h"
 #include "ggc.h"
 #include "output.h"
 #include "langhooks.h"
@@ -41,17 +42,20 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "dbgcnt.h"
 #include "debug.h"
+#include "plugin.h"
+#include "except.h"
+#include "lto-streamer.h"
 
 /* Value of the -G xx switch, and whether it was passed or not.  */
 unsigned HOST_WIDE_INT g_switch_value;
 bool g_switch_set;
 
+/* Same for selective scheduling.  */
+bool sel_sched_switch_set;
+
 /* True if we should exit after parsing options.  */
 bool exit_after_options;
 
-/* Print various extra warnings.  -W/-Wextra.  */
-bool extra_warnings;
-
 /* True to warn about any objects definitions whose size is larger
    than N bytes.  Also want about function definitions whose returned
    values are larger than N bytes, where N is `larger_than_size'.  */
@@ -63,9 +67,6 @@ HOST_WIDE_INT larger_than_size;
 bool warn_frame_larger_than;
 HOST_WIDE_INT frame_larger_than_size;
 
-/* Hack for cooperation between set_Wunused and set_Wextra.  */
-static bool maybe_warn_unused_parameter;
-
 /* Type(s) of debugging information we are producing (if any).  See
    flags.h for the definitions of the different possible types of
    debugging information.  */
@@ -337,11 +338,7 @@ enum symbol_visibility default_visibility = VISIBILITY_DEFAULT;
 struct visibility_flags visibility_options;
 
 /* What to print when a switch has no documentation.  */
-#ifdef ENABLE_CHECKING
 static const char undocumented_msg[] = N_("This switch lacks documentation");
-#else
-static const char undocumented_msg[] = "";
-#endif
 
 /* Used for bookkeeping on whether user set these flags so
    -fprofile-use/-fprofile-generate does not use them.  */
@@ -349,7 +346,8 @@ static bool profile_arc_flag_set, flag_profile_values_set;
 static bool flag_unroll_loops_set, flag_tracer_set;
 static bool flag_value_profile_transformations_set;
 static bool flag_peel_loops_set, flag_branch_probabilities_set;
-static bool flag_inline_functions_set;
+static bool flag_inline_functions_set, flag_ipa_cp_set, flag_ipa_cp_clone_set;
+static bool flag_predictive_commoning_set, flag_unswitch_loops_set, flag_gcse_after_reload_set;
 
 /* Functions excluded from profiling.  */
 
@@ -366,25 +364,19 @@ DEF_VEC_ALLOC_P(const_char_p,heap);
 
 static VEC(const_char_p,heap) *ignored_options;
 
-/* Function calls disallowed under -Wdisallowed-function-list=...  */
-static VEC(char_p,heap) *warning_disallowed_functions;
-
-/* If -Wdisallowed-function-list=...  */
-bool warn_disallowed_functions = false;
+/* Language specific warning pass for unused results.  */
+bool flag_warn_unused_result = false;
 
 /* Input file names.  */
 const char **in_fnames;
 unsigned num_in_fnames;
 
 static int common_handle_option (size_t scode, const char *arg, int value,
-                                unsigned int lang_mask);
+                                unsigned int lang_mask, int kind);
 static void handle_param (const char *);
-static void set_Wextra (int);
-static unsigned int handle_option (const char **argv, unsigned int lang_mask);
 static char *write_langs (unsigned int lang_mask);
 static void complain_wrong_lang (const char *, const struct cl_option *,
                                 unsigned int lang_mask);
-static void handle_options (unsigned int, const char **, unsigned int);
 static void set_debug_level (enum debug_info_type type, int extended,
                             const char *arg);
 
@@ -439,6 +431,17 @@ complain_wrong_lang (const char *text, const struct cl_option *option,
 {
   char *ok_langs, *bad_lang;
 
+  /* The LTO front end inherits all the options from the first front
+     end that was used.  However, not all the original front end
+     options make sense in LTO.
+
+     A real solution would be to filter this in collect2, but collect2
+     does not have access to all the option attributes to know what to
+     filter.  So, in lto1 we silently accept inherited flags and do
+     nothing about it.  */
+  if (lang_mask & CL_LTO)
+    return;
+
   ok_langs = write_langs (option->flags);
   bad_lang = write_langs (lang_mask);
 
@@ -480,10 +483,51 @@ void print_ignored_options (void)
   input_location = saved_loc;
 }
 
+
+/* Handle option OPT_INDEX, and argument ARG, for the language
+   indicated by LANG_MASK.  VALUE is true, unless no- form of an -f or
+   -W option was given.  KIND is the diagnostic_t if this is a
+   diagnostics option, DK_UNSPECIFIED otherwise.  Returns false if the
+   switch was invalid.  */
+bool
+handle_option (int opt_index, int value, const char *arg,
+               unsigned int lang_mask, int kind)
+{
+  const struct cl_option *option = &cl_options[opt_index];
+
+  if (option->flag_var)
+    set_option (opt_index, value, arg, kind);
+  
+  if (option->flags & lang_mask)
+    {
+      if (lang_hooks.handle_option (opt_index, arg, value, kind) == 0)
+       return false;
+      else
+       lto_register_user_option (opt_index, arg, value, lang_mask);
+    }
+
+  if (option->flags & CL_COMMON)
+    {
+      if (common_handle_option (opt_index, arg, value, lang_mask, kind) == 0)
+       return false;
+      else
+       lto_register_user_option (opt_index, arg, value, CL_COMMON);
+    }
+
+  if (option->flags & CL_TARGET)
+    {
+      if (!targetm.handle_option (opt_index, arg, value))
+       return false;
+      else
+       lto_register_user_option (opt_index, arg, value, CL_TARGET);
+    }
+  return true;
+}
+
 /* Handle the switch beginning at ARGV for the language indicated by
    LANG_MASK.  Returns the number of switches consumed.  */
 static unsigned int
-handle_option (const char **argv, unsigned int lang_mask)
+read_cmdline_option (const char **argv, unsigned int lang_mask)
 {
   size_t opt_index;
   const char *opt, *arg = 0;
@@ -604,45 +648,8 @@ handle_option (const char **argv, unsigned int lang_mask)
        }
     }
 
-  if (option->flag_var)
-    switch (option->var_type)
-      {
-      case CLVC_BOOLEAN:
-       *(int *) option->flag_var = value;
-       break;
-
-      case CLVC_EQUAL:
-       *(int *) option->flag_var = (value
-                                    ? option->var_value
-                                    : !option->var_value);
-       break;
-
-      case CLVC_BIT_CLEAR:
-      case CLVC_BIT_SET:
-       if ((value != 0) == (option->var_type == CLVC_BIT_SET))
-         *(int *) option->flag_var |= option->var_value;
-       else
-         *(int *) option->flag_var &= ~option->var_value;
-       if (option->flag_var == &target_flags)
-         target_flags_explicit |= option->var_value;
-       break;
-
-      case CLVC_STRING:
-       *(const char **) option->flag_var = arg;
-       break;
-      }
-
-  if (option->flags & lang_mask)
-    if (lang_hooks.handle_option (opt_index, arg, value) == 0)
-      result = 0;
-
-  if (result && (option->flags & CL_COMMON))
-    if (common_handle_option (opt_index, arg, value, lang_mask) == 0)
-      result = 0;
-
-  if (result && (option->flags & CL_TARGET))
-    if (!targetm.handle_option (opt_index, arg, value))
-      result = 0;
+  if (!handle_option (opt_index, value, arg, lang_mask, DK_UNSPECIFIED))
+    result = 0;
 
  done:
   if (dup)
@@ -739,35 +746,11 @@ flag_instrument_functions_exclude_p (tree fndecl)
 }
 
 
-/* Return whether this function call is disallowed.  */
-void
-warn_if_disallowed_function_p (const_tree exp)
-{
-  if (TREE_CODE(exp) == CALL_EXPR
-      && VEC_length (char_p, warning_disallowed_functions) > 0)
-    {
-      int i;
-      char *s;
-      const char *fnname =
-          IDENTIFIER_POINTER (DECL_NAME (get_callee_fndecl (exp)));
-      for (i = 0; VEC_iterate (char_p, warning_disallowed_functions, i, s);
-           ++i)
-        {
-          if (strcmp (fnname, s) == 0)
-            {
-              warning (OPT_Wdisallowed_function_list_,
-                       "disallowed call to %qs", fnname);
-              break;
-            }
-        }
-    }
-}
-
 /* Decode and handle the vector of command line options.  LANG_MASK
    contains has a single bit set representing the current
    language.  */
 static void
-handle_options (unsigned int argc, const char **argv, unsigned int lang_mask)
+read_cmdline_options (unsigned int argc, const char **argv, unsigned int lang_mask)
 {
   unsigned int n, i;
 
@@ -789,7 +772,7 @@ handle_options (unsigned int argc, const char **argv, unsigned int lang_mask)
          continue;
        }
 
-      n = handle_option (argv + i, lang_mask);
+      n = read_cmdline_option (argv + i, lang_mask);
 
       if (!n)
        {
@@ -805,10 +788,9 @@ void
 decode_options (unsigned int argc, const char **argv)
 {
   static bool first_time_p = true;
-  static int initial_max_aliased_vops;
-  static int initial_avg_aliased_vops;
   static int initial_min_crossjump_insns;
   static int initial_max_fields_for_field_sensitive;
+  static int initial_loop_invariant_max_bbs_in_loop;
   static unsigned int initial_lang_mask;
 
   unsigned int i, lang_mask;
@@ -825,12 +807,12 @@ decode_options (unsigned int argc, const char **argv)
       lang_hooks.initialize_diagnostics (global_dc);
 
       /* Save initial values of parameters we reset.  */
-      initial_max_aliased_vops = MAX_ALIASED_VOPS;
-      initial_avg_aliased_vops = AVG_ALIASED_VOPS;
       initial_min_crossjump_insns
        = compiler_params[PARAM_MIN_CROSSJUMP_INSNS].value;
       initial_max_fields_for_field_sensitive
        = compiler_params[PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE].value;
+      initial_loop_invariant_max_bbs_in_loop
+       = compiler_params[PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP].value;
     }
   else
     lang_mask = initial_lang_mask;
@@ -862,39 +844,18 @@ decode_options (unsigned int argc, const char **argv)
              if (optimize_val != -1)
                {
                  optimize = optimize_val;
+                 if ((unsigned int) optimize > 255)
+                   optimize = 255;
                  optimize_size = 0;
                }
            }
        }
     }
-  
-  if (!flag_unit_at_a_time)
-    {
-      flag_section_anchors = 0;
-      flag_toplevel_reorder = 0;
-    }
-  if (!flag_toplevel_reorder)
-    {
-      if (flag_section_anchors == 1)
-        error ("Section anchors must be disabled when toplevel reorder is disabled.");
-      flag_section_anchors = 0;
-    }
-
-  /* Originally we just set the variables if a particular optimization level,
-     but with the advent of being able to change the optimization level for a
-     function, we need to reset optimizations.  */
-  if (!optimize)
-    {
-      flag_merge_constants = 0;
 
-      /* We disable toplevel reordering at -O0 to disable transformations that
-         might be surprising to end users and to get -fno-toplevel-reorder
-        tested, but we keep section anchors.  */
-      if (flag_toplevel_reorder == 2)
-        flag_toplevel_reorder = 0;
-    }
-  else
-    flag_merge_constants = 1;
+  /* Use priority coloring if cover classes is not defined for the
+     target.  */
+  if (targetm.ira_cover_classes == NULL)
+    flag_ira_algorithm = IRA_ALGORITHM_PRIORITY;
 
   /* -O1 optimizations.  */
   opt1 = (optimize >= 1);
@@ -907,10 +868,13 @@ decode_options (unsigned int argc, const char **argv)
 #endif
   flag_guess_branch_prob = opt1;
   flag_cprop_registers = opt1;
+  flag_forward_propagate = opt1;
   flag_if_conversion = opt1;
   flag_if_conversion2 = opt1;
   flag_ipa_pure_const = opt1;
   flag_ipa_reference = opt1;
+  flag_ipa_profile = opt1;
+  flag_merge_constants = opt1;
   flag_split_wide_types = opt1;
   flag_tree_ccp = opt1;
   flag_tree_dce = opt1;
@@ -931,7 +895,6 @@ decode_options (unsigned int argc, const char **argv)
   flag_thread_jumps = opt2;
   flag_crossjumping = opt2;
   flag_optimize_sibling_calls = opt2;
-  flag_forward_propagate = opt2;
   flag_cse_follow_jumps = opt2;
   flag_gcse = opt2;
   flag_expensive_optimizations = opt2;
@@ -939,30 +902,30 @@ decode_options (unsigned int argc, const char **argv)
   flag_caller_saves = opt2;
   flag_peephole2 = opt2;
 #ifdef INSN_SCHEDULING
-  flag_schedule_insns = opt2;
+  /* Only run the pre-regalloc scheduling pass if optimizing for speed.  */
+  flag_schedule_insns = opt2 && ! optimize_size;
   flag_schedule_insns_after_reload = opt2;
 #endif
   flag_regmove = opt2;
   flag_strict_aliasing = opt2;
   flag_strict_overflow = opt2;
-  flag_delete_null_pointer_checks = opt2;
   flag_reorder_blocks = opt2;
   flag_reorder_functions = opt2;
-  flag_tree_store_ccp = opt2;
   flag_tree_vrp = opt2;
   flag_tree_builtin_call_dce = opt2;
   flag_tree_pre = opt2;
-      flag_tree_switch_conversion = 1;
-
-      /* Allow more virtual operators to increase alias precision.  */
-
-  set_param_value ("max-aliased-vops",
-                  (opt2) ? 500 : initial_max_aliased_vops);
+  flag_tree_switch_conversion = opt2;
+  flag_ipa_cp = opt2;
+  flag_ipa_sra = opt2;
 
   /* Track fields in field-sensitive alias analysis.  */
   set_param_value ("max-fields-for-field-sensitive",
                   (opt2) ? 100 : initial_max_fields_for_field_sensitive);
 
+  /* For -O1 only do loop invariant motion for very small loops.  */
+  set_param_value ("loop-invariant-max-bbs-in-loop",
+                  (opt2) ? initial_loop_invariant_max_bbs_in_loop : 1000);
+
   /* -O3 optimizations.  */
   opt3 = (optimize >= 3);
   flag_predictive_commoning = opt3;
@@ -970,13 +933,9 @@ decode_options (unsigned int argc, const char **argv)
   flag_unswitch_loops = opt3;
   flag_gcse_after_reload = opt3;
   flag_tree_vectorize = opt3;
-
-  /* Allow even more virtual operators.  Max-aliased-vops was set above for
-     -O2, so don't reset it unless we are at -O3.  */
-  if (opt3)
-    set_param_value ("max-aliased-vops", 1000);
-
-  set_param_value ("avg-aliased-vops", (opt3) ? 3 : initial_avg_aliased_vops);
+  flag_ipa_cp_clone = opt3;
+  if (flag_ipa_cp_clone)
+    flag_ipa_cp = 1;
 
   /* Just -O1/-O0 optimizations.  */
   opt1_max = (optimize <= 1);
@@ -987,51 +946,10 @@ decode_options (unsigned int argc, const char **argv)
 
   if (optimize_size)
     {
-      /* Loop header copying usually increases size of the code.  This used not to
-        be true, since quite often it is possible to verify that the condition is
-        satisfied in the first iteration and therefore to eliminate it.  Jump
-        threading handles these cases now.  */
-      flag_tree_ch = 0;
-
-      /* Conditional DCE generates bigger code.  */
-      flag_tree_builtin_call_dce = 0;
-
-      /* PRE tends to generate bigger code.  */
-      flag_tree_pre = 0;
-
-      /* These options are set with -O3, so reset for -Os */
-      flag_predictive_commoning = 0;
-      flag_inline_functions = 0;
-      flag_unswitch_loops = 0;
-      flag_gcse_after_reload = 0;
-      flag_tree_vectorize = 0;
-
-      /* Don't reorder blocks when optimizing for size because extra jump insns may
-        be created; also barrier may create extra padding.
-
-        More correctly we should have a block reordering mode that tried to
-        minimize the combined size of all the jumps.  This would more or less
-        automatically remove extra jumps, but would also try to use more short
-        jumps instead of long jumps.  */
-      flag_reorder_blocks = 0;
-      flag_reorder_blocks_and_partition = 0;
-
       /* Inlining of functions reducing size is a good idea regardless of them
         being declared inline.  */
       flag_inline_functions = 1;
 
-      /* Don't align code.  */
-      align_loops = 1;
-      align_jumps = 1;
-      align_labels = 1;
-      align_functions = 1;
-
-      /* Unroll/prefetch switches that may be set on the command line, and tend to
-        generate bigger code.  */
-      flag_unroll_loops = 0;
-      flag_unroll_all_loops = 0;
-      flag_prefetch_loop_arrays = 0;
-
       /* Basic optimization options.  */
       optimize_size = 1;
       if (optimize > 2)
@@ -1043,6 +961,9 @@ decode_options (unsigned int argc, const char **argv)
   else
     set_param_value ("min-crossjump-insns", initial_min_crossjump_insns);
 
+  /* Enable -Werror=coverage-mismatch by default */
+  enable_warning_as_error("coverage-mismatch", 1, lang_mask);
+
   if (first_time_p)
     {
       /* Initialize whether `char' is signed.  */
@@ -1059,12 +980,72 @@ decode_options (unsigned int argc, const char **argv)
       flag_unwind_tables = targetm.unwind_tables_default;
     }
 
+  /* Clear any options currently held for LTO.  */
+  lto_clear_user_options ();
+
 #ifdef OPTIMIZATION_OPTIONS
   /* Allow default optimizations to be specified on a per-machine basis.  */
   OPTIMIZATION_OPTIONS (optimize, optimize_size);
 #endif
 
-  handle_options (argc, argv, lang_mask);
+  read_cmdline_options (argc, argv, lang_mask);
+
+  if (dump_base_name && ! IS_ABSOLUTE_PATH (dump_base_name))
+    {
+      /* First try to make DUMP_BASE_NAME relative to the DUMP_DIR_NAME
+        directory.  Then try to make DUMP_BASE_NAME relative to the
+        AUX_BASE_NAME directory, typically the directory to contain
+        the object file.  */
+      if (dump_dir_name)
+       dump_base_name = concat (dump_dir_name, dump_base_name, NULL);
+      else if (aux_base_name)
+       {
+         const char *aux_base;
+
+         base_of_path (aux_base_name, &aux_base);
+         if (aux_base_name != aux_base)
+           {
+             int dir_len = aux_base - aux_base_name;
+             char *new_dump_base_name =
+               XNEWVEC (char, strlen(dump_base_name) + dir_len + 1);
+
+             /* Copy directory component from AUX_BASE_NAME.  */
+             memcpy (new_dump_base_name, aux_base_name, dir_len);
+             /* Append existing DUMP_BASE_NAME.  */
+             strcpy (new_dump_base_name + dir_len, dump_base_name);
+             dump_base_name = new_dump_base_name;
+           }
+       }
+    }
+
+  /* Handle related options for unit-at-a-time, toplevel-reorder, and
+     section-anchors.  */
+  if (!flag_unit_at_a_time)
+    {
+      if (flag_section_anchors == 1)
+       error ("Section anchors must be disabled when unit-at-a-time "
+              "is disabled.");
+      flag_section_anchors = 0;
+      if (flag_toplevel_reorder == 1)
+       error ("Toplevel reorder must be disabled when unit-at-a-time "
+              "is disabled.");
+      flag_toplevel_reorder = 0;
+    }
+  /* Unless the user has asked for section anchors, we disable toplevel
+     reordering at -O0 to disable transformations that might be surprising
+     to end users and to get -fno-toplevel-reorder tested.  */
+  if (!optimize && flag_toplevel_reorder == 2 && flag_section_anchors != 1)
+    {
+      flag_toplevel_reorder = 0;
+      flag_section_anchors = 0;
+    }
+  if (!flag_toplevel_reorder)
+    {
+      if (flag_section_anchors == 1)
+       error ("section anchors must be disabled when toplevel reorder"
+              " is disabled");
+      flag_section_anchors = 0;
+    }
 
   if (first_time_p)
     {
@@ -1072,46 +1053,32 @@ decode_options (unsigned int argc, const char **argv)
        flag_pic = flag_pie;
       if (flag_pic && !flag_pie)
        flag_shlib = 1;
-
-      if (flag_no_inline == 2)
-       flag_no_inline = 0;
-      else
-       flag_really_no_inline = flag_no_inline;
+      first_time_p = false;
     }
 
-  /* Set flag_no_inline before the post_options () hook.  The C front
-     ends use it to determine tree inlining defaults.  FIXME: such
-     code should be lang-independent when all front ends use tree
-     inlining, in which case it, and this condition, should be moved
-     to the top of process_options() instead.  */
   if (optimize == 0)
     {
       /* Inlining does not work if not optimizing,
         so force it not to be done.  */
-      flag_no_inline = 1;
       warn_inline = 0;
-
-      /* The c_decode_option function and decode_option hook set
-        this to `2' if -Wall is used, so we can avoid giving out
-        lots of errors for people who don't realize what -Wall does.  */
-      if (warn_uninitialized == 1)
-       warning (OPT_Wuninitialized,
-                "-Wuninitialized is not supported without -O");
+      flag_no_inline = 1;
     }
 
-  if (flag_really_no_inline == 2)
-    flag_really_no_inline = flag_no_inline;
-
   /* The optimization to partition hot and cold basic blocks into separate
      sections of the .o and executable files does not work (currently)
      with exception handling.  This is because there is no support for
      generating unwind info.  If flag_exceptions is turned on we need to
      turn off the partitioning optimization.  */
 
-  if (flag_exceptions && flag_reorder_blocks_and_partition)
+  if (flag_exceptions && flag_reorder_blocks_and_partition
+      && (USING_SJLJ_EXCEPTIONS
+#ifdef TARGET_UNWIND_INFO
+         || 1
+#endif
+        ))
     {
-      inform
-           ("-freorder-blocks-and-partition does not work with exceptions");
+      inform (input_location,
+             "-freorder-blocks-and-partition does not work with exceptions on this architecture");
       flag_reorder_blocks_and_partition = 0;
       flag_reorder_blocks = 1;
     }
@@ -1120,9 +1087,15 @@ decode_options (unsigned int argc, const char **argv)
      optimization.  */
 
   if (flag_unwind_tables && ! targetm.unwind_tables_default
-      && flag_reorder_blocks_and_partition)
+      && flag_reorder_blocks_and_partition
+      && (USING_SJLJ_EXCEPTIONS
+#ifdef TARGET_UNWIND_INFO
+         || 1
+#endif
+        ))
     {
-      inform ("-freorder-blocks-and-partition does not support unwind info");
+      inform (input_location,
+             "-freorder-blocks-and-partition does not support unwind info on this architecture");
       flag_reorder_blocks_and_partition = 0;
       flag_reorder_blocks = 1;
     }
@@ -1133,21 +1106,67 @@ decode_options (unsigned int argc, const char **argv)
 
   if (flag_reorder_blocks_and_partition
       && (!targetm.have_named_sections
-         || (flag_unwind_tables && targetm.unwind_tables_default)))
+         || (flag_unwind_tables && targetm.unwind_tables_default
+             && (USING_SJLJ_EXCEPTIONS
+#ifdef TARGET_UNWIND_INFO
+                 || 1
+#endif
+                ))))
     {
-      inform
-       ("-freorder-blocks-and-partition does not work on this architecture");
+      inform (input_location,
+             "-freorder-blocks-and-partition does not work on this architecture");
       flag_reorder_blocks_and_partition = 0;
       flag_reorder_blocks = 1;
     }
 
-  /* Save the current optimization options if this is the first call.  */
-  if (first_time_p)
+  /* Pipelining of outer loops is only possible when general pipelining
+     capabilities are requested.  */
+  if (!flag_sel_sched_pipelining)
+    flag_sel_sched_pipelining_outer_loops = 0;
+
+  if (!targetm.ira_cover_classes
+      && flag_ira_algorithm == IRA_ALGORITHM_CB)
     {
-      optimization_default_node = build_optimization_node ();
-      optimization_current_node = optimization_default_node;
-      first_time_p = false;
+      inform (input_location,
+             "-fira-algorithm=CB does not work on this architecture");
+      flag_ira_algorithm = IRA_ALGORITHM_PRIORITY;
+    }
+
+  if (flag_conserve_stack)
+    {
+      if (!PARAM_SET_P (PARAM_LARGE_STACK_FRAME))
+        PARAM_VALUE (PARAM_LARGE_STACK_FRAME) = 100;
+      if (!PARAM_SET_P (PARAM_STACK_FRAME_GROWTH))
+        PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) = 40;
+    }
+  if (flag_wpa || flag_ltrans)
+    {
+      /* These passes are not WHOPR compatible yet.  */
+      flag_ipa_cp = 0;
+      flag_ipa_reference = 0;
+      flag_ipa_type_escape = 0;
+      flag_ipa_pta = 0;
+      flag_ipa_struct_reorg = 0;
+    }
+
+  if (flag_lto || flag_whopr)
+    {
+#ifdef ENABLE_LTO
+      flag_generate_lto = 1;
+
+      /* When generating IL, do not operate in whole-program mode.
+        Otherwise, symbols will be privatized too early, causing link
+        errors later.  */
+      flag_whole_program = 0;
+#else
+      error ("LTO support has not been enabled in this configuration");
+#endif
     }
+
+  /* Reconcile -flto and -fwhopr.  Set additional flags as appropriate and
+     check option consistency.  */
+  if (flag_lto && flag_whopr)
+    error ("-flto and -fwhopr are mutually exclusive");
 }
 
 #define LEFT_COLUMN    27
@@ -1343,7 +1362,7 @@ print_filtered_help (unsigned int include_flags,
              printf (_(" None found.  Use --help=%s to show *all* the options supported by the %s front-end\n"),
                      lang_names[i], lang_names[i]);
        }
-       
+
     }
   else if (! displayed)
     printf (_(" All options with the desired characteristics have already been displayed\n"));
@@ -1417,7 +1436,7 @@ print_specific_help (unsigned int include_flags,
        default:
          if (i >= cl_lang_count)
            break;
-         if ((exclude_flags & ((1U << cl_lang_count) - 1)) != 0)
+         if (exclude_flags & all_langs_mask)
            description = _("The following options are specific to just the language ");
          else
            description = _("The following options are supported by the language ");
@@ -1430,8 +1449,12 @@ print_specific_help (unsigned int include_flags,
     {
       if (any_flags == 0)
        {
-         if (include_flags == CL_UNDOCUMENTED)
+         if (include_flags & CL_UNDOCUMENTED)
            description = _("The following options are not documented");
+         else if (include_flags & CL_SEPARATE)
+           description = _("The following options take separate arguments");
+         else if (include_flags & CL_JOINED)
+           description = _("The following options take joined arguments");
          else
            {
              internal_error ("unrecognized include_flags 0x%x passed to print_specific_help",
@@ -1459,7 +1482,7 @@ print_specific_help (unsigned int include_flags,
 
 static int
 common_handle_option (size_t scode, const char *arg, int value,
-                     unsigned int lang_mask)
+                     unsigned int lang_mask, int kind ATTRIBUTE_UNUSED)
 {
   static bool verbose = false;
   enum opt_code code = (enum opt_code) scode;
@@ -1542,7 +1565,7 @@ common_handle_option (size_t scode, const char *arg, int value,
              { NULL, 0 }
            };
            unsigned int * pflags;
-           char * comma;
+           const char * comma;
            unsigned int lang_flag, specific_flag;
            unsigned int len;
            unsigned int i;
@@ -1560,6 +1583,11 @@ common_handle_option (size_t scode, const char *arg, int value,
              len = strlen (a);
            else
              len = comma - a;
+           if (len == 0)
+             {
+               a = comma + 1;
+               continue;
+             }
 
            /* Check to see if the string matches an option class name.  */
            for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++)
@@ -1568,7 +1596,7 @@ common_handle_option (size_t scode, const char *arg, int value,
                  specific_flag = specifics[i].flag;
                  break;
                }
-           
+
            /* Check to see if the string matches a language name.
               Note - we rely upon the alpha-sorted nature of the entries in
               the lang_names array, specifically that shorter names appear
@@ -1619,8 +1647,8 @@ common_handle_option (size_t scode, const char *arg, int value,
        break;
       }
 
+    case OPT_fversion:
     case OPT__version:
-      print_version (stderr, "");
       exit_after_options = true;
       break;
 
@@ -1634,28 +1662,13 @@ common_handle_option (size_t scode, const char *arg, int value,
       /* Currently handled in a prescan.  */
       break;
 
-    case OPT_W:
-      /* For backward compatibility, -W is the same as -Wextra.  */
-      set_Wextra (value);
-      break;
-
-    case OPT_Wdisallowed_function_list_:
-      warn_disallowed_functions = true;
-      add_comma_separated_to_vector
-       (&warning_disallowed_functions, arg);
-      break;
-
     case OPT_Werror_:
       enable_warning_as_error (arg, value, lang_mask);
       break;
 
-    case OPT_Wextra:
-      set_Wextra (value);
-      break;
-
     case OPT_Wlarger_than_:
-      /* This form corresponds to -Wlarger-than-.  
-        Kept for backward compatibility. 
+      /* This form corresponds to -Wlarger-than-.
+        Kept for backward compatibility.
         Don't use it as the first argument of warning().  */
 
     case OPT_Wlarger_than_eq:
@@ -1687,7 +1700,7 @@ common_handle_option (size_t scode, const char *arg, int value,
       break;
 
     case OPT_Wunused:
-      set_Wunused (value);
+      warn_unused = value;
       break;
 
     case OPT_aux_info:
@@ -1717,6 +1730,10 @@ common_handle_option (size_t scode, const char *arg, int value,
       dump_base_name = arg;
       break;
 
+    case OPT_dumpdir:
+      dump_dir_name = arg;
+      break;
+
     case OPT_falign_functions_:
       align_functions = value;
       break;
@@ -1768,7 +1785,7 @@ common_handle_option (size_t scode, const char *arg, int value,
       break;
 
     case OPT_fdiagnostics_show_option:
-      global_dc->show_option_requested = true;
+      global_dc->show_option_requested = value;
       break;
 
     case OPT_fdump_:
@@ -1776,6 +1793,15 @@ common_handle_option (size_t scode, const char *arg, int value,
        return 0;
       break;
 
+    case OPT_fexcess_precision_:
+      if (!strcmp (arg, "fast"))
+       flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;
+      else if (!strcmp (arg, "standard"))
+       flag_excess_precision_cmdline = EXCESS_PRECISION_STANDARD;
+      else
+       error ("unknown excess precision style \"%s\"", arg);
+      break;
+
     case OPT_ffast_math:
       set_fast_math_flags (value);
       break;
@@ -1822,6 +1848,22 @@ common_handle_option (size_t scode, const char *arg, int value,
       flag_peel_loops_set = true;
       break;
 
+    case OPT_fplugin_:
+#ifdef ENABLE_PLUGIN
+      add_new_plugin (arg);
+#else
+      error ("Plugin support is disabled.  Configure with --enable-plugin.");
+#endif
+      break;
+
+    case OPT_fplugin_arg_:
+#ifdef ENABLE_PLUGIN
+      parse_plugin_arg_opt (arg);
+#else
+      error ("Plugin support is disabled.  Configure with --enable-plugin.");
+#endif
+      break;
+
     case OPT_fprofile_arcs:
       profile_arc_flag_set = true;
       break;
@@ -1854,6 +1896,17 @@ common_handle_option (size_t scode, const char *arg, int value,
         flag_value_profile_transformations = value;
       if (!flag_inline_functions_set)
         flag_inline_functions = value;
+      if (!flag_ipa_cp_set)
+        flag_ipa_cp = value;
+      if (!flag_ipa_cp_clone_set
+         && value && flag_ipa_cp)
+       flag_ipa_cp_clone = value;
+      if (!flag_predictive_commoning_set)
+       flag_predictive_commoning = value;
+      if (!flag_unswitch_loops_set)
+       flag_unswitch_loops = value;
+      if (!flag_gcse_after_reload_set)
+       flag_gcse_after_reload = value;
       break;
 
     case OPT_fprofile_generate_:
@@ -1905,6 +1958,11 @@ common_handle_option (size_t scode, const char *arg, int value,
       set_random_seed (arg);
       break;
 
+    case OPT_fselective_scheduling:
+    case OPT_fselective_scheduling2:
+      sel_sched_switch_set = true;
+      break;
+
     case OPT_fsched_verbose_:
 #ifdef INSN_SCHEDULING
       fix_sched_param ("verbose", arg);
@@ -1923,6 +1981,37 @@ common_handle_option (size_t scode, const char *arg, int value,
       flag_sched_stalled_insns_dep = value;
       break;
 
+    case OPT_fstack_check_:
+      if (!strcmp (arg, "no"))
+       flag_stack_check = NO_STACK_CHECK;
+      else if (!strcmp (arg, "generic"))
+       /* This is the old stack checking method.  */
+       flag_stack_check = STACK_CHECK_BUILTIN
+                          ? FULL_BUILTIN_STACK_CHECK
+                          : GENERIC_STACK_CHECK;
+      else if (!strcmp (arg, "specific"))
+       /* This is the new stack checking method.  */
+       flag_stack_check = STACK_CHECK_BUILTIN
+                          ? FULL_BUILTIN_STACK_CHECK
+                          : STACK_CHECK_STATIC_BUILTIN
+                            ? STATIC_BUILTIN_STACK_CHECK
+                            : GENERIC_STACK_CHECK;
+      else
+       warning (0, "unknown stack check parameter \"%s\"", arg);
+      break;
+
+    case OPT_fstack_check:
+      /* This is the same as the "specific" mode above.  */
+      if (value)
+       flag_stack_check = STACK_CHECK_BUILTIN
+                          ? FULL_BUILTIN_STACK_CHECK
+                          : STACK_CHECK_STATIC_BUILTIN
+                            ? STATIC_BUILTIN_STACK_CHECK
+                            : GENERIC_STACK_CHECK;
+      else
+       flag_stack_check = NO_STACK_CHECK;
+      break;
+
     case OPT_fstack_limit:
       /* The real switch is -fno-stack-limit.  */
       if (value)
@@ -1961,10 +2050,54 @@ common_handle_option (size_t scode, const char *arg, int value,
        warning (0, "unknown tls-model \"%s\"", arg);
       break;
 
+    case OPT_fira_algorithm_:
+      if (!strcmp (arg, "CB"))
+       flag_ira_algorithm = IRA_ALGORITHM_CB;
+      else if (!strcmp (arg, "priority"))
+       flag_ira_algorithm = IRA_ALGORITHM_PRIORITY;
+      else
+       warning (0, "unknown ira algorithm \"%s\"", arg);
+      break;
+
+    case OPT_fira_region_:
+      if (!strcmp (arg, "one"))
+       flag_ira_region = IRA_REGION_ONE;
+      else if (!strcmp (arg, "all"))
+       flag_ira_region = IRA_REGION_ALL;
+      else if (!strcmp (arg, "mixed"))
+       flag_ira_region = IRA_REGION_MIXED;
+      else
+       warning (0, "unknown ira region \"%s\"", arg);
+      break;
+
+    case OPT_fira_verbose_:
+      flag_ira_verbose = value;
+      break;
+
     case OPT_ftracer:
       flag_tracer_set = true;
       break;
 
+    case OPT_fipa_cp:
+      flag_ipa_cp_set = true;
+      break;
+
+    case OPT_fipa_cp_clone:
+      flag_ipa_cp_clone_set = true;
+      break;
+
+    case OPT_fpredictive_commoning:
+      flag_predictive_commoning_set = true;
+      break;
+
+    case OPT_funswitch_loops:
+      flag_unswitch_loops_set = true;
+      break;
+
+    case OPT_fgcse_after_reload:
+      flag_gcse_after_reload_set = true;
+      break;
+
     case OPT_funroll_loops:
       flag_unroll_loops_set = true;
       break;
@@ -1977,8 +2110,12 @@ common_handle_option (size_t scode, const char *arg, int value,
       set_debug_level (SDB_DEBUG, false, arg);
       break;
 
-    case OPT_gdwarf_2:
-      set_debug_level (DWARF2_DEBUG, false, arg);
+    case OPT_gdwarf_:
+      if (value < 2 || value > 4)
+       error ("dwarf version %d is not supported", value);
+      else
+       dwarf_version = value;
+      set_debug_level (DWARF2_DEBUG, false, "");
       break;
 
     case OPT_ggdb:
@@ -2007,15 +2144,28 @@ common_handle_option (size_t scode, const char *arg, int value,
       flag_pedantic_errors = pedantic = 1;
       break;
 
+    case OPT_fsee:
+    case OPT_fcse_skip_blocks:
     case OPT_floop_optimize:
     case OPT_frerun_loop_opt:
+    case OPT_fsched2_use_traces:
     case OPT_fstrength_reduce:
     case OPT_ftree_store_copy_prop:
     case OPT_fforce_addr:
     case OPT_ftree_salias:
+    case OPT_ftree_store_ccp:
+    case OPT_Wunreachable_code:
+    case OPT_fargument_alias:
+    case OPT_fargument_noalias:
+    case OPT_fargument_noalias_anything:
+    case OPT_fargument_noalias_global:
       /* These are no-ops, preserved for backward compatibility.  */
       break;
 
+    case OPT_fuse_linker_plugin:
+      /* No-op. Used by the driver and passed to us because it starts with f.*/
+      break;
+
     default:
       /* If the flag was handled in a standard way, assume the lack of
         processing here is intentional.  */
@@ -2052,40 +2202,7 @@ handle_param (const char *carg)
   free (arg);
 }
 
-/* Handle -W and -Wextra.  */
-static void
-set_Wextra (int setting)
-{
-  extra_warnings = 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;
-}
-
-/* Initialize unused warning flags.  */
-void
-set_Wunused (int setting)
-{
-  warn_unused_function = setting;
-  warn_unused_label = setting;
-  /* 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;
-}
-
-/* Used to set the level of strict aliasing warnings, 
+/* Used to set the level of strict aliasing warnings,
    when no level is specified (i.e., when -Wstrict-aliasing, and not
    -Wstrict-aliasing=level was given).
    ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
@@ -2118,8 +2235,8 @@ set_fast_math_flags (int set)
     }
 }
 
-/* When -funsafe-math-optimizations is set the following 
-   flags are set as well.  */ 
+/* When -funsafe-math-optimizations is set the following
+   flags are set as well.  */
 void
 set_unsafe_math_optimizations_flags (int set)
 {
@@ -2194,15 +2311,17 @@ set_debug_level (enum debug_info_type type, int extended, const char *arg)
   if (*arg == '\0')
     {
       if (!debug_info_level)
-       debug_info_level = 2;
+       debug_info_level = DINFO_LEVEL_NORMAL;
     }
   else
     {
-      debug_info_level = integral_argument (arg);
-      if (debug_info_level == (unsigned int) -1)
+      int argval = integral_argument (arg);
+      if (argval == -1)
        error ("unrecognised debug output level \"%s\"", arg);
-      else if (debug_info_level > 3)
+      else if (argval > 3)
        error ("debug output level %s is too high", arg);
+      else
+       debug_info_level = (enum debug_info_level) argval;
     }
 }
 
@@ -2269,6 +2388,61 @@ get_option_state (int option, struct cl_option_state *state)
   return true;
 }
 
+/* Set *OPTION according to VALUE and ARG.  */
+
+void
+set_option (int opt_index, int value, const char *arg, int kind)
+{
+  const struct cl_option *option = &cl_options[opt_index];
+
+  if (!option->flag_var)
+    return;
+
+  switch (option->var_type)
+    {
+    case CLVC_BOOLEAN:
+       *(int *) option->flag_var = value;
+       break;
+
+    case CLVC_EQUAL:
+       *(int *) option->flag_var = (value
+                                    ? option->var_value
+                                    : !option->var_value);
+       break;
+
+    case CLVC_BIT_CLEAR:
+    case CLVC_BIT_SET:
+       if ((value != 0) == (option->var_type == CLVC_BIT_SET))
+         *(int *) option->flag_var |= option->var_value;
+       else
+         *(int *) option->flag_var &= ~option->var_value;
+       if (option->flag_var == &target_flags)
+         target_flags_explicit |= option->var_value;
+       break;
+
+    case CLVC_STRING:
+       *(const char **) option->flag_var = arg;
+       break;
+    }
+
+  if ((diagnostic_t)kind != DK_UNSPECIFIED)
+    diagnostic_classify_diagnostic (global_dc, opt_index, (diagnostic_t)kind);
+}
+
+
+/* Callback function, called when -Werror= enables a warning.  */
+
+static void (*warning_as_error_callback) (int) = NULL;
+
+/* Register a callback for enable_warning_as_error calls.  */
+
+void
+register_warning_as_error_callback (void (*callback) (int))
+{
+  gcc_assert (warning_as_error_callback == NULL || callback == NULL);
+  warning_as_error_callback = callback;
+}
+
 /* Enable a warning option as an error.  This is used by -Werror= and
    also by legacy Werror-implicit-function-declaration.  */
 
@@ -2288,14 +2462,20 @@ enable_warning_as_error (const char *arg, int value, unsigned int lang_mask)
     }
   else
     {
-      int kind = value ? DK_ERROR : DK_WARNING;
+      const diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
+
       diagnostic_classify_diagnostic (global_dc, option_index, kind);
-      
-      /* -Werror=foo implies -Wfoo.  */
-      if (cl_options[option_index].var_type == CLVC_BOOLEAN
-         && cl_options[option_index].flag_var
-         && kind == DK_ERROR)
-       *(int *) cl_options[option_index].flag_var = 1;
+      if (kind == DK_ERROR)
+       {
+         const struct cl_option * const option = cl_options + option_index;
+
+         /* -Werror=foo implies -Wfoo.  */
+         if (option->var_type == CLVC_BOOLEAN)
+           handle_option (option_index, value, arg, lang_mask, (int)kind);
+
+         if (warning_as_error_callback)
+           warning_as_error_callback (option_index);
+       }
     }
   free (new_option);
 }