OSDN Git Service

* config/avr/avr.h (PREFERRED_RELOAD_CLASS): Remove.
[pf3gnuchains/gcc-fork.git] / gcc / opts.c
index 393c8b1..52f8c6d 100644 (file)
@@ -46,10 +46,6 @@ along with GCC; see the file COPYING3.  If not see
 #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;
-
 /* True if we should exit after parsing options.  */
 bool exit_after_options;
 
@@ -357,9 +353,6 @@ DEF_VEC_ALLOC_P(const_char_p,heap);
 
 static VEC(const_char_p,heap) *ignored_options;
 
-/* Language specific warning pass for unused results.  */
-bool flag_warn_unused_result = false;
-
 /* Input file names.  */
 const char **in_fnames;
 unsigned num_in_fnames;
@@ -369,12 +362,15 @@ static bool common_handle_option (struct gcc_options *opts,
                                  const struct cl_decoded_option *decoded,
                                  unsigned int lang_mask, int kind,
                                  const struct cl_option_handlers *handlers);
-static void handle_param (const char *);
+static void handle_param (struct gcc_options *opts,
+                         struct gcc_options *opts_set, const char *carg);
 static char *write_langs (unsigned int lang_mask);
 static void complain_wrong_lang (const struct cl_decoded_option *,
                                 unsigned int lang_mask);
 static void set_debug_level (enum debug_info_type type, int extended,
                             const char *arg);
+static void set_fast_math_flags (int set);
+static void set_unsafe_math_optimizations_flags (int set);
 
 /* Return a malloced slash-separated list of languages in MASK.  */
 static char *
@@ -617,11 +613,14 @@ flag_instrument_functions_exclude_p (tree fndecl)
 }
 
 
-/* Handle the vector of command line options.  LANG_MASK
-   contains has a single bit set representing the current
-   language.  HANDLERS describes what functions to call for the options.  */
+/* Handle the vector of command line options, storing the results of
+   processing DECODED_OPTIONS and DECODED_OPTIONS_COUNT in OPTS and
+   OPTS_SET.  LANG_MASK contains has a single bit set representing the
+   current language.  HANDLERS describes what functions to call for
+   the options.  */
 static void
-read_cmdline_options (struct cl_decoded_option *decoded_options,
+read_cmdline_options (struct gcc_options *opts, struct gcc_options *opts_set,
+                     struct cl_decoded_option *decoded_options,
                      unsigned int decoded_options_count,
                      unsigned int lang_mask,
                      const struct cl_option_handlers *handlers)
@@ -632,6 +631,11 @@ read_cmdline_options (struct cl_decoded_option *decoded_options,
     {
       if (decoded_options[i].opt_index == OPT_SPECIAL_input_file)
        {
+         /* Input files should only ever appear on the main command
+            line.  */
+         gcc_assert (opts == &global_options);
+         gcc_assert (opts_set == &global_options_set);
+
          if (main_input_filename == NULL)
            {
              main_input_filename = decoded_options[i].arg;
@@ -642,75 +646,100 @@ read_cmdline_options (struct cl_decoded_option *decoded_options,
          continue;
        }
 
-      read_cmdline_option (&global_options, &global_options_set,
-                          decoded_options + i, lang_mask, handlers);
+      read_cmdline_option (opts, opts_set,
+                          decoded_options + i, lang_mask, handlers,
+                          global_dc);
     }
 }
 
-/* Parse command line options and set default flag values.  Do minimal
-   options processing.  The decoded options are placed in *DECODED_OPTIONS
-   and *DECODED_OPTIONS_COUNT.  */
+/* Language mask determined at initialization.  */
+static unsigned int initial_lang_mask;
+
+/* Initialize global options-related settings at start-up.  */
+
 void
-decode_options (unsigned int argc, const char **argv,
-               struct cl_decoded_option **decoded_options,
-               unsigned int *decoded_options_count)
+init_options_once (void)
 {
-  static bool first_time_p = true;
-  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;
-  struct cl_option_handlers handlers;
+  /* Perform language-specific options initialization.  */
+  initial_lang_mask = lang_hooks.option_lang_mask ();
+
+  lang_hooks.initialize_diagnostics (global_dc);
+}
+
+/* Initialize OPTS and OPTS_SET before using them in parsing options.  */
+
+void
+init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set)
+{
+  size_t num_params = get_num_compiler_params ();
+
+  *opts = global_options_init;
+  memset (opts_set, 0, sizeof (*opts_set));
+
+  opts->x_param_values = XNEWVEC (int, num_params);
+  opts_set->x_param_values = XCNEWVEC (int, num_params);
+  init_param_values (opts->x_param_values);
+
+  /* Use priority coloring if cover classes is not defined for the
+     target.  */
+  if (targetm.ira_cover_classes == NULL)
+    opts->x_flag_ira_algorithm = IRA_ALGORITHM_PRIORITY;
+
+  /* Initialize whether `char' is signed.  */
+  opts->x_flag_signed_char = DEFAULT_SIGNED_CHAR;
+  /* Set this to a special "uninitialized" value.  The actual default
+     is set after target options have been processed.  */
+  opts->x_flag_short_enums = 2;
+
+  /* Initialize target_flags before targetm.target_option.optimization
+     so the latter can modify it.  */
+  opts->x_target_flags = targetm.default_target_flags;
+
+  /* Some targets have ABI-specified unwind tables.  */
+  opts->x_flag_unwind_tables = targetm.unwind_tables_default;
+
+  /* Some targets have other target-specific initialization.  */
+  targetm.target_option.init_struct (opts);
+}
+
+/* Decode command-line options to an array, like
+   decode_cmdline_options_to_array and with the same arguments but
+   using the default lang_mask.  */
 
-  unsigned int i, lang_mask;
+void
+decode_cmdline_options_to_array_default_mask (unsigned int argc,
+                                             const char **argv, 
+                                             struct cl_decoded_option **decoded_options,
+                                             unsigned int *decoded_options_count)
+{
+  decode_cmdline_options_to_array (argc, argv,
+                                  initial_lang_mask | CL_COMMON | CL_TARGET,
+                                  decoded_options, decoded_options_count);
+}
+
+/* Default the options in OPTS and OPTS_SET based on the optimization
+   settings in DECODED_OPTIONS and DECODED_OPTIONS_COUNT.  */
+static void
+default_options_optimization (struct gcc_options *opts,
+                             struct gcc_options *opts_set,
+                             struct cl_decoded_option *decoded_options,
+                             unsigned int decoded_options_count)
+{
+  unsigned int i;
   int opt1;
   int opt2;
   int opt3;
   int opt1_max;
   int ofast = 0;
-  enum unwind_info_type ui_except;
 
-  if (first_time_p)
-    {
-      /* Perform language-specific options initialization.  */
-      initial_lang_mask = lang_mask = lang_hooks.option_lang_mask ();
-
-      lang_hooks.initialize_diagnostics (global_dc);
-
-      /* Save initial values of parameters we reset.  */
-      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;
-
-  decode_cmdline_options_to_array (argc, argv,
-                                  lang_mask | CL_COMMON | CL_TARGET,
-                                  decoded_options, decoded_options_count);
-  if (first_time_p)
-    /* Perform language-specific options initialization.  */
-    lang_hooks.init_options (*decoded_options_count, *decoded_options);
-
-  handlers.unknown_option_callback = unknown_option_callback;
-  handlers.wrong_lang_callback = complain_wrong_lang;
-  handlers.post_handling_callback = post_handling_callback;
-  handlers.num_handlers = 3;
-  handlers.handlers[0].handler = lang_handle_option;
-  handlers.handlers[0].mask = lang_mask;
-  handlers.handlers[1].handler = common_handle_option;
-  handlers.handlers[1].mask = CL_COMMON;
-  handlers.handlers[2].handler = target_handle_option;
-  handlers.handlers[2].mask = CL_TARGET;
+  gcc_assert (opts == &global_options);
+  gcc_assert (opts_set = &global_options_set);
 
   /* Scan to see what optimization level has been specified.  That will
      determine the default value of many flags.  */
-  for (i = 1; i < *decoded_options_count; i++)
+  for (i = 1; i < decoded_options_count; i++)
     {
-      struct cl_decoded_option *opt = &(*decoded_options)[i];
+      struct cl_decoded_option *opt = &decoded_options[i];
       switch (opt->opt_index)
        {
        case OPT_O:
@@ -758,11 +787,6 @@ decode_options (unsigned int argc, const char **argv,
        }
     }
 
-  /* 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);
   flag_defer_pop = opt1;
@@ -828,12 +852,16 @@ decode_options (unsigned int argc, const char **argv,
   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);
+  maybe_set_param_value
+    (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,
+     opt2 ? 100 : default_param_value (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE),
+     opts->x_param_values, opts_set->x_param_values);
 
   /* 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);
+  maybe_set_param_value
+    (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,
+     opt2 ? default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) : 1000,
+     opts->x_param_values, opts_set->x_param_values);
 
   /* -O3 optimizations.  */
   opt3 = (optimize >= 3);
@@ -866,10 +894,13 @@ decode_options (unsigned int argc, const char **argv,
        optimize = 2;
 
       /* We want to crossjump as much as possible.  */
-      set_param_value ("min-crossjump-insns", 1);
+      maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, 1,
+                            opts->x_param_values, opts_set->x_param_values);
     }
   else
-    set_param_value ("min-crossjump-insns", initial_min_crossjump_insns);
+    maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS,
+                          default_param_value (PARAM_MIN_CROSSJUMP_INSNS),
+                          opts->x_param_values, opts_set->x_param_values);
 
   /* -Ofast adds optimizations to -O3.  */
   if (ofast)
@@ -882,37 +913,68 @@ decode_options (unsigned int argc, const char **argv,
       targetm.handle_ofast ();
     }
 
+  /* Allow default optimizations to be specified on a per-machine basis.  */
+  targetm.target_option.optimization (optimize, optimize_size);
+}
+
+static void finish_options (struct gcc_options *, struct gcc_options *);
+
+/* Parse command line options and set default flag values.  Do minimal
+   options processing.  The decoded options are in *DECODED_OPTIONS
+   and *DECODED_OPTIONS_COUNT.  */
+void
+decode_options (struct gcc_options *opts, struct gcc_options *opts_set,
+               struct cl_decoded_option *decoded_options,
+               unsigned int decoded_options_count)
+{
+  struct cl_option_handlers handlers;
+
+  unsigned int lang_mask;
+
+  lang_mask = initial_lang_mask;
+
+  handlers.unknown_option_callback = unknown_option_callback;
+  handlers.wrong_lang_callback = complain_wrong_lang;
+  handlers.post_handling_callback = post_handling_callback;
+  handlers.num_handlers = 3;
+  handlers.handlers[0].handler = lang_handle_option;
+  handlers.handlers[0].mask = lang_mask;
+  handlers.handlers[1].handler = common_handle_option;
+  handlers.handlers[1].mask = CL_COMMON;
+  handlers.handlers[2].handler = target_handle_option;
+  handlers.handlers[2].mask = CL_TARGET;
+
   /* Enable -Werror=coverage-mismatch by default */
-  enable_warning_as_error ("coverage-mismatch", 1, lang_mask, &handlers);
+  enable_warning_as_error ("coverage-mismatch", 1, lang_mask, &handlers,
+                          global_dc);
 
-  if (first_time_p)
-    {
-      /* Initialize whether `char' is signed.  */
-      flag_signed_char = DEFAULT_SIGNED_CHAR;
-      /* Set this to a special "uninitialized" value.  The actual default is
-        set after target options have been processed.  */
-      flag_short_enums = 2;
-
-      /* Initialize target_flags before
-        targetm.target_option.optimization so the latter can modify
-        it.  */
-      target_flags = targetm.default_target_flags;
-
-      /* Some targets have ABI-specified unwind tables.  */
-      flag_unwind_tables = targetm.unwind_tables_default;
-    }
+  default_options_optimization (opts, opts_set,
+                               decoded_options, decoded_options_count);
 
 #ifdef ENABLE_LTO
   /* Clear any options currently held for LTO.  */
   lto_clear_user_options ();
 #endif
 
-  /* Allow default optimizations to be specified on a per-machine basis.  */
-  targetm.target_option.optimization (optimize, optimize_size);
-
-  read_cmdline_options (*decoded_options, *decoded_options_count, lang_mask,
+  read_cmdline_options (opts, opts_set,
+                       decoded_options, decoded_options_count, lang_mask,
                        &handlers);
 
+  finish_options (opts, opts_set);
+}
+
+/* After all options have been read into OPTS and OPTS_SET, finalize
+   settings of those options and diagnose incompatible
+   combinations.  */
+static void
+finish_options (struct gcc_options *opts, struct gcc_options *opts_set)
+{
+  static bool first_time_p = true;
+  enum unwind_info_type ui_except;
+
+  gcc_assert (opts == &global_options);
+  gcc_assert (opts_set = &global_options_set);
+
   if (dump_base_name && ! IS_ABSOLUTE_PATH (dump_base_name))
     {
       /* First try to make DUMP_BASE_NAME relative to the DUMP_DIR_NAME
@@ -945,7 +1007,7 @@ decode_options (unsigned int argc, const char **argv,
      section-anchors.  */
   if (!flag_unit_at_a_time)
     {
-      if (flag_section_anchors == 1)
+      if (flag_section_anchors && opts_set->x_flag_section_anchors)
        error ("Section anchors must be disabled when unit-at-a-time "
               "is disabled.");
       flag_section_anchors = 0;
@@ -962,14 +1024,16 @@ decode_options (unsigned int argc, const char **argv,
   /* 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)
+  if (!optimize
+      && flag_toplevel_reorder == 2
+      && !(flag_section_anchors && opts_set->x_flag_section_anchors))
     {
       flag_toplevel_reorder = 0;
       flag_section_anchors = 0;
     }
   if (!flag_toplevel_reorder)
     {
-      if (flag_section_anchors == 1)
+      if (flag_section_anchors && opts_set->x_flag_section_anchors)
        error ("section anchors must be disabled when toplevel reorder"
               " is disabled");
       flag_section_anchors = 0;
@@ -1058,10 +1122,10 @@ decode_options (unsigned int argc, const char **argv,
 
   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;
+      maybe_set_param_value (PARAM_LARGE_STACK_FRAME, 100,
+                            opts->x_param_values, opts_set->x_param_values);
+      maybe_set_param_value (PARAM_STACK_FRAME_GROWTH, 40,
+                            opts->x_param_values, opts_set->x_param_values);
     }
   if (flag_wpa || flag_ltrans)
     {
@@ -1083,6 +1147,13 @@ decode_options (unsigned int argc, const char **argv,
       error ("LTO support has not been enabled in this configuration");
 #endif
     }
+  if (flag_lto_partition_balanced || flag_lto_partition_1to1)
+    {
+      if (flag_lto_partition_balanced && flag_lto_partition_1to1)
+       error ("Only one -flto-partitoin value can be specified");
+      if (!flag_whopr)
+       error ("-flto-partitoin has effect only with -fwhopr");
+    }
 
   /* Reconcile -flto and -fwhopr.  Set additional flags as appropriate and
      check option consistency.  */
@@ -1444,7 +1515,7 @@ common_handle_option (struct gcc_options *opts,
   switch (code)
     {
     case OPT__param:
-      handle_param (arg);
+      handle_param (opts, opts_set, arg);
       break;
 
     case OPT_v:
@@ -1610,7 +1681,7 @@ common_handle_option (struct gcc_options *opts,
       break;
 
     case OPT_Werror_:
-      enable_warning_as_error (arg, value, lang_mask, handlers);
+      enable_warning_as_error (arg, value, lang_mask, handlers, global_dc);
       break;
 
     case OPT_Wlarger_than_:
@@ -1764,8 +1835,10 @@ common_handle_option (struct gcc_options *opts,
       break;
 
     case OPT_finline_limit_:
-      set_param_value ("max-inline-insns-single", value / 2);
-      set_param_value ("max-inline-insns-auto", value / 2);
+      set_param_value ("max-inline-insns-single", value / 2,
+                      opts->x_param_values, opts_set->x_param_values);
+      set_param_value ("max-inline-insns-auto", value / 2,
+                      opts->x_param_values, opts_set->x_param_values);
       break;
 
     case OPT_finstrument_functions_exclude_function_list_:
@@ -2060,7 +2133,8 @@ common_handle_option (struct gcc_options *opts,
 
 /* Handle --param NAME=VALUE.  */
 static void
-handle_param (const char *carg)
+handle_param (struct gcc_options *opts, struct gcc_options *opts_set,
+             const char *carg)
 {
   char *equal, *arg;
   int value;
@@ -2077,7 +2151,8 @@ handle_param (const char *carg)
       else
        {
          *equal = '\0';
-         set_param_value (arg, value);
+         set_param_value (arg, value,
+                          opts->x_param_values, opts_set->x_param_values);
        }
     }
 
@@ -2102,7 +2177,7 @@ set_Wstrict_aliasing (int onoff)
 
 /* The following routines are useful in setting all the flags that
    -ffast-math and -fno-fast-math imply.  */
-void
+static void
 set_fast_math_flags (int set)
 {
   flag_unsafe_math_optimizations = set;
@@ -2119,7 +2194,7 @@ set_fast_math_flags (int set)
 
 /* When -funsafe-math-optimizations is set the following
    flags are set as well.  */
-void
+static void
 set_unsafe_math_optimizations_flags (int set)
 {
   flag_trapping_math = !set;
@@ -2288,12 +2363,15 @@ register_warning_as_error_callback (void (*callback) (int))
   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.  */
+/* Enable (or disable if VALUE is 0) a warning option ARG (language
+   mask LANG_MASK, option handlers HANDLERS) as an error for
+   diagnostic context DC (possibly NULL).  This is used by
+   -Werror=.  */
 
 void
 enable_warning_as_error (const char *arg, int value, unsigned int lang_mask,
-                        const struct cl_option_handlers *handlers)
+                        const struct cl_option_handlers *handlers,
+                        diagnostic_context *dc)
 {
   char *new_option;
   int option_index;
@@ -2315,8 +2393,9 @@ enable_warning_as_error (const char *arg, int value, unsigned int lang_mask,
        option_index = option->alias_target;
       if (option_index == OPT_SPECIAL_ignore)
        return;
-      diagnostic_classify_diagnostic (global_dc, option_index, kind,
-                                     UNKNOWN_LOCATION);
+      if (dc)
+       diagnostic_classify_diagnostic (dc, option_index, kind,
+                                       UNKNOWN_LOCATION);
       if (kind == DK_ERROR)
        {
          const struct cl_option * const option = cl_options + option_index;
@@ -2325,7 +2404,8 @@ enable_warning_as_error (const char *arg, int value, unsigned int lang_mask,
          if (option->var_type == CLVC_BOOLEAN)
            handle_generated_option (&global_options, &global_options_set,
                                     option_index, NULL, value, lang_mask,
-                                    (int)kind, handlers);
+                                    (int)kind, handlers,
+                                    dc);
 
          if (warning_as_error_callback)
            warning_as_error_callback (option_index);