Patchwork Make options machinery track which options are explicitly used

login
register
mail settings
Submitter Joseph S. Myers
Date Oct. 1, 2010, 7:52 p.m.
Message ID <Pine.LNX.4.64.1010011952150.21749@digraph.polyomino.org.uk>
Download mbox | patch
Permalink /patch/66508/
State New
Headers show

Comments

Joseph S. Myers - Oct. 1, 2010, 7:52 p.m.
This patch continues the move to making option processing use
structures through pointers to those structures, instead of directly
using global variables, by adding general support for tracking which
options have been explicitly set - so avoiding various special-case
variables used for this purpose, and so meaning various options no
longer need special code in option handlers at all.

target_flags_explicit becomes a macro for
global_options_set.x_target_flags, since it is widely used; uses of
other variables are changed directly.
flag_speculative_prefetching_set was neither used nor defined; it only
had an extern declaration.

The -G handling is not converted to use this mechanism since
converting to set variables automatically will change the type of
g_switch_value from unsigned HOST_WIDE_INT to int.  This is fine in
that the value is already constrained to be within the range of int,
but more care will be needed to avoid causing signed/unsigned warnings
and it seems best to test this separately.

The global_options_set structure records strictly which options, with
Var settings in the .opt file (or equivalent implicit use of
target_flags) were explicitly used; it does not record implicit uses
from generated options.  The present _set uses do not overlap with the
cases of generated options so the present patch should not affect the
semantics of the compiler.  Subsequent patches replacing Init(-1) or
Init(2) by uses this mechanism will require more care for each
individual option; such changes can fix bugs (e.g. -Wall -Wno-implicit
not in fact disabling the -Wimplicit warnings that -Wall enabled) but
can also introduce them unless care is taken.

(A pointer to the _set structure is still passed down for generated
options, for read-only use.)

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  Also
tested building cc1 for a cross to ia64-elf.  OK to commit?

2010-10-01  Joseph Myers  <joseph@codesourcery.com>

	* optc-gen.awk: Define global_options_set.  Don't define
	target_flags_explicit.
	* opth-gen.awk: Declare global_options_set.  Define
	target_flags_explicit as macro.
	* opts-common.c (handle_option): Take opts_set and generated_p
	parameters.
	(handle_generated_option, read_cmdline_option, set_option): Take
	opts_set parameter.
	(set_option): Use opts_set instead of hardcoding target_flags and
	target_flags_explicit.
	* opts.c (sel_sched_switch_set, profile_arc_flag_set,
	flag_profile_values_set, flag_unroll_loops_set, flag_tracer_set,
	flag_value_profile_transformations_set, flag_peel_loops_set,
	flag_branch_probabilities_set, flag_inline_functions_set,
	flag_ipa_cp_set, flag_ipa_cp_clone_set,
	flag_predictive_commoning_set, flag_unswitch_loops_set,
	flag_gcse_after_reload_set): Remove.
	(common_handle_option, lang_handle_option, target_handle_option):
	Take opts_set parameter.  Assert that it is &global_options_set.
	(common_handle_option): Don't set _set variables.  Check opts_set
	instead of such variables.
	(enable_warning_as_error): Pass &global_options_set to
	handle_generated_option.
	* opts.h (cl_option_handler_func.handler, set_option,
	handle_option, handle_generated_option, read_cmdline_option): Add
	opts_set parameters.
	(handle_option): Add generated_p parameter.
	* config/i386/i386.c (ix86_function_specific_save,
	ix86_function_specific_restore): Updat for renaming of
	target_flags_explicit field.
	* config/i386/i386.opt (target_flags_explicit): Rename to
	ix86_target_flags_explicit.
	* config/ia64/ia64.c (ia64_override_options_after_change): Check
	global_options_set.x_flag_selective_scheduling and
	global_options_set.x_flag_selective_scheduling2, not
	sel_sched_switch_set.
	* flags.h (sel_sched_switch_set,
	flag_speculative_prefetching_set): Remove.
	* gcc.c (driver_handle_option): Take opts_set parameter.  Assert
	that it is &global_options_set.
	(process_command): Pass &global_options_set to
	read_cmdline_option.
	* lto-opts.c (lto_reissue_options): Pass &global_options_set to
	set_option.
	* toplev.c (target_flags_explicit): Remove.

c-family:
2010-10-01  Joseph Myers  <joseph@codesourcery.com>

	* c-opts.c (c_common_handle_option): Pass &global_options_set to
	handle_generated_option.
Richard Guenther - Oct. 4, 2010, 9:26 a.m.
On Fri, Oct 1, 2010 at 9:52 PM, Joseph S. Myers <joseph@codesourcery.com> wrote:
> This patch continues the move to making option processing use
> structures through pointers to those structures, instead of directly
> using global variables, by adding general support for tracking which
> options have been explicitly set - so avoiding various special-case
> variables used for this purpose, and so meaning various options no
> longer need special code in option handlers at all.
>
> target_flags_explicit becomes a macro for
> global_options_set.x_target_flags, since it is widely used; uses of
> other variables are changed directly.
> flag_speculative_prefetching_set was neither used nor defined; it only
> had an extern declaration.
>
> The -G handling is not converted to use this mechanism since
> converting to set variables automatically will change the type of
> g_switch_value from unsigned HOST_WIDE_INT to int.  This is fine in
> that the value is already constrained to be within the range of int,
> but more care will be needed to avoid causing signed/unsigned warnings
> and it seems best to test this separately.
>
> The global_options_set structure records strictly which options, with
> Var settings in the .opt file (or equivalent implicit use of
> target_flags) were explicitly used; it does not record implicit uses
> from generated options.  The present _set uses do not overlap with the
> cases of generated options so the present patch should not affect the
> semantics of the compiler.  Subsequent patches replacing Init(-1) or
> Init(2) by uses this mechanism will require more care for each
> individual option; such changes can fix bugs (e.g. -Wall -Wno-implicit
> not in fact disabling the -Wimplicit warnings that -Wall enabled) but
> can also introduce them unless care is taken.
>
> (A pointer to the _set structure is still passed down for generated
> options, for read-only use.)
>
> Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  Also
> tested building cc1 for a cross to ia64-elf.  OK to commit?

Ok.

I'm starting to get excited about this - it looks we might be able to
just dump the options structure to LTO files to carry over options
to link-time, being able to drop the most ugly (and non-working)
pieces of LTO streaming.  Hah!

Thanks,
Richard.

> 2010-10-01  Joseph Myers  <joseph@codesourcery.com>
>
>        * optc-gen.awk: Define global_options_set.  Don't define
>        target_flags_explicit.
>        * opth-gen.awk: Declare global_options_set.  Define
>        target_flags_explicit as macro.
>        * opts-common.c (handle_option): Take opts_set and generated_p
>        parameters.
>        (handle_generated_option, read_cmdline_option, set_option): Take
>        opts_set parameter.
>        (set_option): Use opts_set instead of hardcoding target_flags and
>        target_flags_explicit.
>        * opts.c (sel_sched_switch_set, profile_arc_flag_set,
>        flag_profile_values_set, flag_unroll_loops_set, flag_tracer_set,
>        flag_value_profile_transformations_set, flag_peel_loops_set,
>        flag_branch_probabilities_set, flag_inline_functions_set,
>        flag_ipa_cp_set, flag_ipa_cp_clone_set,
>        flag_predictive_commoning_set, flag_unswitch_loops_set,
>        flag_gcse_after_reload_set): Remove.
>        (common_handle_option, lang_handle_option, target_handle_option):
>        Take opts_set parameter.  Assert that it is &global_options_set.
>        (common_handle_option): Don't set _set variables.  Check opts_set
>        instead of such variables.
>        (enable_warning_as_error): Pass &global_options_set to
>        handle_generated_option.
>        * opts.h (cl_option_handler_func.handler, set_option,
>        handle_option, handle_generated_option, read_cmdline_option): Add
>        opts_set parameters.
>        (handle_option): Add generated_p parameter.
>        * config/i386/i386.c (ix86_function_specific_save,
>        ix86_function_specific_restore): Updat for renaming of
>        target_flags_explicit field.
>        * config/i386/i386.opt (target_flags_explicit): Rename to
>        ix86_target_flags_explicit.
>        * config/ia64/ia64.c (ia64_override_options_after_change): Check
>        global_options_set.x_flag_selective_scheduling and
>        global_options_set.x_flag_selective_scheduling2, not
>        sel_sched_switch_set.
>        * flags.h (sel_sched_switch_set,
>        flag_speculative_prefetching_set): Remove.
>        * gcc.c (driver_handle_option): Take opts_set parameter.  Assert
>        that it is &global_options_set.
>        (process_command): Pass &global_options_set to
>        read_cmdline_option.
>        * lto-opts.c (lto_reissue_options): Pass &global_options_set to
>        set_option.
>        * toplev.c (target_flags_explicit): Remove.
>
> c-family:
> 2010-10-01  Joseph Myers  <joseph@codesourcery.com>
>
>        * c-opts.c (c_common_handle_option): Pass &global_options_set to
>        handle_generated_option.
>
> Index: gcc/flags.h
> ===================================================================
> --- gcc/flags.h (revision 164755)
> +++ gcc/flags.h (working copy)
> @@ -276,9 +276,6 @@ extern int flag_evaluation_order;
>  extern unsigned HOST_WIDE_INT g_switch_value;
>  extern bool g_switch_set;
>
> -/* Same for selective scheduling.  */
> -extern bool sel_sched_switch_set;
> -
>  /* Whether to run the warn_unused_result attribute pass.  */
>  extern bool flag_warn_unused_result;
>
> @@ -293,10 +290,6 @@ enum graph_dump_types
>  };
>  extern enum graph_dump_types graph_dump_format;
>
> -/* True if flag_speculative_prefetching was set by user.  Used to suppress
> -   warning message in case flag was set by -fprofile-{generate,use}.  */
> -extern bool flag_speculative_prefetching_set;
> -
>  /* Type of stack check.  */
>  enum stack_check_type
>  {
> Index: gcc/opts-common.c
> ===================================================================
> --- gcc/opts-common.c   (revision 164755)
> +++ gcc/opts-common.c   (working copy)
> @@ -799,15 +799,20 @@ keep:
>  }
>
>  /* Handle option DECODED for the language indicated by LANG_MASK,
> -   using the handlers in HANDLERS and setting fields in OPTS.  KIND is
> -   the diagnostic_t if this is a diagnostics option, DK_UNSPECIFIED
> -   otherwise.  Returns false if the switch was invalid.  */
> +   using the handlers in HANDLERS and setting fields in OPTS and
> +   OPTS_SET.  KIND is the diagnostic_t if this is a diagnostics
> +   option, DK_UNSPECIFIED otherwise.  GENERATED_P is true for an
> +   option generated as part of processing another option or otherwise
> +   generated internally, false for one explicitly passed by the user.
> +   Returns false if the switch was invalid.  */
>
>  bool
>  handle_option (struct gcc_options *opts,
> +              struct gcc_options *opts_set,
>               const struct cl_decoded_option *decoded,
>               unsigned int lang_mask, int kind,
> -              const struct cl_option_handlers *handlers)
> +              const struct cl_option_handlers *handlers,
> +              bool generated_p)
>  {
>   size_t opt_index = decoded->opt_index;
>   const char *arg = decoded->arg;
> @@ -817,12 +822,13 @@ handle_option (struct gcc_options *opts,
>   size_t i;
>
>   if (flag_var)
> -    set_option (opts, opt_index, value, arg, kind);
> +    set_option (opts, (generated_p ? NULL : opts_set),
> +               opt_index, value, arg, kind);
>
>   for (i = 0; i < handlers->num_handlers; i++)
>     if (option->flags & handlers->handlers[i].mask)
>       {
> -       if (!handlers->handlers[i].handler (opts, decoded,
> +       if (!handlers->handlers[i].handler (opts, opts_set, decoded,
>                                            lang_mask, kind, handlers))
>          return false;
>        else
> @@ -839,15 +845,17 @@ handle_option (struct gcc_options *opts,
>    command line.  */
>
>  bool
> -handle_generated_option (struct gcc_options *opts, size_t opt_index,
> -                        const char *arg, int value,
> +handle_generated_option (struct gcc_options *opts,
> +                        struct gcc_options *opts_set,
> +                        size_t opt_index, const char *arg, int value,
>                         unsigned int lang_mask, int kind,
>                         const struct cl_option_handlers *handlers)
>  {
>   struct cl_decoded_option decoded;
>
>   generate_option (opt_index, arg, value, lang_mask, &decoded);
> -  return handle_option (opts, &decoded, lang_mask, kind, handlers);
> +  return handle_option (opts, opts_set, &decoded, lang_mask, kind, handlers,
> +                       true);
>  }
>
>  /* Fill in *DECODED with an option described by OPT_INDEX, ARG and
> @@ -906,10 +914,12 @@ generate_option_input_file (const char *
>  }
>
>  /* Handle the switch DECODED for the language indicated by LANG_MASK,
> -   using the handlers in *HANDLERS and setting fields in OPTS.  */
> +   using the handlers in *HANDLERS and setting fields in OPTS and
> +   OPTS_SET.  */
>
>  void
>  read_cmdline_option (struct gcc_options *opts,
> +                    struct gcc_options *opts_set,
>                     struct cl_decoded_option *decoded,
>                     unsigned int lang_mask,
>                     const struct cl_option_handlers *handlers)
> @@ -963,33 +973,42 @@ read_cmdline_option (struct gcc_options
>
>   gcc_assert (!decoded->errors);
>
> -  if (!handle_option (opts, decoded, lang_mask, DK_UNSPECIFIED, handlers))
> +  if (!handle_option (opts, opts_set, decoded, lang_mask, DK_UNSPECIFIED,
> +                     handlers, false))
>     error ("unrecognized command line option %qs", opt);
>  }
>
> -/* Set any field in OPTS for option OPT_INDEX according to VALUE and ARG,
> -   diagnostic kind KIND.  */
> +/* Set any field in OPTS, and OPTS_SET if not NULL, for option
> +   OPT_INDEX according to VALUE and ARG, diagnostic kind KIND.  */
>
>  void
> -set_option (struct gcc_options *opts, int opt_index, int value,
> -           const char *arg, int kind)
> +set_option (struct gcc_options *opts, struct gcc_options *opts_set,
> +           int opt_index, int value, const char *arg, int kind)
>  {
>   const struct cl_option *option = &cl_options[opt_index];
>   void *flag_var = option_flag_var (opt_index, opts);
> +  void *set_flag_var = NULL;
>
>   if (!flag_var)
>     return;
>
> +  if (opts_set != NULL)
> +    set_flag_var = option_flag_var (opt_index, opts_set);
> +
>   switch (option->var_type)
>     {
>     case CLVC_BOOLEAN:
>        *(int *) flag_var = value;
> +       if (set_flag_var)
> +         *(int *) set_flag_var = 1;
>        break;
>
>     case CLVC_EQUAL:
>        *(int *) flag_var = (value
>                             ? option->var_value
>                             : !option->var_value);
> +       if (set_flag_var)
> +         *(int *) set_flag_var = 1;
>        break;
>
>     case CLVC_BIT_CLEAR:
> @@ -998,12 +1017,14 @@ set_option (struct gcc_options *opts, in
>          *(int *) flag_var |= option->var_value;
>        else
>          *(int *) flag_var &= ~option->var_value;
> -       if (flag_var == &target_flags)
> -         target_flags_explicit |= option->var_value;
> +       if (set_flag_var)
> +         *(int *) set_flag_var |= option->var_value;
>        break;
>
>     case CLVC_STRING:
>        *(const char **) flag_var = arg;
> +       if (set_flag_var)
> +         *(const char **) set_flag_var = "";
>        break;
>     }
>
> Index: gcc/c-family/c-opts.c
> ===================================================================
> --- gcc/c-family/c-opts.c       (revision 164755)
> +++ gcc/c-family/c-opts.c       (working copy)
> @@ -436,7 +436,8 @@ c_common_handle_option (size_t scode, co
>     case OPT_Wall:
>       warn_unused = value;
>       set_Wformat (value);
> -      handle_generated_option (&global_options, OPT_Wimplicit, NULL, value,
> +      handle_generated_option (&global_options, &global_options_set,
> +                              OPT_Wimplicit, NULL, value,
>                               c_family_lang_mask, kind, handlers);
>       warn_char_subscripts = value;
>       warn_missing_braces = value;
> @@ -530,11 +531,11 @@ c_common_handle_option (size_t scode, co
>     case OPT_Wimplicit:
>       gcc_assert (value == 0 || value == 1);
>       if (warn_implicit_int == -1)
> -       handle_generated_option (&global_options, OPT_Wimplicit_int,
> -                                NULL, value,
> +       handle_generated_option (&global_options, &global_options_set,
> +                                OPT_Wimplicit_int, NULL, value,
>                                 c_family_lang_mask, kind, handlers);
>       if (warn_implicit_function_declaration == -1)
> -       handle_generated_option (&global_options,
> +       handle_generated_option (&global_options, &global_options_set,
>                                 OPT_Wimplicit_function_declaration, NULL,
>                                 value, c_family_lang_mask, kind, handlers);
>       break;
> Index: gcc/gcc.c
> ===================================================================
> --- gcc/gcc.c   (revision 164755)
> +++ gcc/gcc.c   (working copy)
> @@ -3151,6 +3151,7 @@ static int last_language_n_infiles;
>
>  static bool
>  driver_handle_option (struct gcc_options *opts,
> +                     struct gcc_options *opts_set,
>                      const struct cl_decoded_option *decoded,
>                      unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
>                      const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
> @@ -3163,6 +3164,7 @@ driver_handle_option (struct gcc_options
>   bool do_save = true;
>
>   gcc_assert (opts == &global_options);
> +  gcc_assert (opts_set == &global_options_set);
>   gcc_assert (kind == DK_UNSPECIFIED);
>
>   switch (opt_index)
> @@ -3803,8 +3805,8 @@ process_command (unsigned int decoded_op
>          continue;
>        }
>
> -      read_cmdline_option (&global_options, decoded_options + j,
> -                          CL_DRIVER, &handlers);
> +      read_cmdline_option (&global_options, &global_options_set,
> +                          decoded_options + j, CL_DRIVER, &handlers);
>     }
>
>   /* If -save-temps=obj and -o name, create the prefix to use for %b.
> Index: gcc/toplev.c
> ===================================================================
> --- gcc/toplev.c        (revision 164755)
> +++ gcc/toplev.c        (working copy)
> @@ -155,11 +155,6 @@ const char *aux_base_name;
>  /* Prefix for profile data files */
>  const char *profile_data_prefix;
>
> -/* A mask of target_flags that includes bit X if X was set or cleared
> -   on the command line.  */
> -
> -int target_flags_explicit;
> -
>  /* Debug hooks - dependent upon command line options.  */
>
>  const struct gcc_debug_hooks *debug_hooks;
> Index: gcc/opts.c
> ===================================================================
> --- gcc/opts.c  (revision 164755)
> +++ gcc/opts.c  (working copy)
> @@ -50,9 +50,6 @@ along with GCC; see the file COPYING3.
>  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;
>
> @@ -345,15 +342,6 @@ struct visibility_flags visibility_optio
>  /* What to print when a switch has no documentation.  */
>  static const char undocumented_msg[] = N_("This switch lacks documentation");
>
> -/* Used for bookkeeping on whether user set these flags so
> -   -fprofile-use/-fprofile-generate does not use them.  */
> -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, 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.  */
>
>  typedef char *char_p; /* For DEF_VEC_P.  */
> @@ -377,6 +365,7 @@ const char **in_fnames;
>  unsigned num_in_fnames;
>
>  static bool common_handle_option (struct gcc_options *opts,
> +                                 struct gcc_options *opts_set,
>                                  const struct cl_decoded_option *decoded,
>                                  unsigned int lang_mask, int kind,
>                                  const struct cl_option_handlers *handlers);
> @@ -517,11 +506,13 @@ post_handling_callback (const struct cl_
>
>  static bool
>  lang_handle_option (struct gcc_options *opts,
> +                   struct gcc_options *opts_set,
>                    const struct cl_decoded_option *decoded,
>                    unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
>                    const struct cl_option_handlers *handlers)
>  {
>   gcc_assert (opts == &global_options);
> +  gcc_assert (opts_set == &global_options_set);
>   gcc_assert (decoded->canonical_option_num_elements <= 2);
>   return lang_hooks.handle_option (decoded->opt_index, decoded->arg,
>                                   decoded->value, kind, handlers);
> @@ -532,11 +523,13 @@ lang_handle_option (struct gcc_options *
>
>  static bool
>  target_handle_option (struct gcc_options *opts,
> +                     struct gcc_options *opts_set,
>                      const struct cl_decoded_option *decoded,
>                      unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
>                      const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
>  {
>   gcc_assert (opts == &global_options);
> +  gcc_assert (opts_set == &global_options_set);
>   gcc_assert (decoded->canonical_option_num_elements <= 2);
>   gcc_assert (kind == DK_UNSPECIFIED);
>   return targetm.handle_option (decoded->opt_index, decoded->arg,
> @@ -649,8 +642,8 @@ read_cmdline_options (struct cl_decoded_
>          continue;
>        }
>
> -      read_cmdline_option (&global_options, decoded_options + i,
> -                          lang_mask, handlers);
> +      read_cmdline_option (&global_options, &global_options_set,
> +                          decoded_options + i, lang_mask, handlers);
>     }
>  }
>
> @@ -1432,6 +1425,7 @@ print_specific_help (unsigned int includ
>
>  static bool
>  common_handle_option (struct gcc_options *opts,
> +                     struct gcc_options *opts_set,
>                      const struct cl_decoded_option *decoded,
>                      unsigned int lang_mask, int kind ATTRIBUTE_UNUSED,
>                      const struct cl_option_handlers *handlers)
> @@ -1443,6 +1437,7 @@ common_handle_option (struct gcc_options
>   enum opt_code code = (enum opt_code) scode;
>
>   gcc_assert (opts == &global_options);
> +  gcc_assert (opts_set == &global_options_set);
>   gcc_assert (decoded->canonical_option_num_elements <= 2);
>
>   switch (code)
> @@ -1703,10 +1698,6 @@ common_handle_option (struct gcc_options
>       align_loops = value;
>       break;
>
> -    case OPT_fbranch_probabilities:
> -      flag_branch_probabilities_set = true;
> -      break;
> -
>     case OPT_fcall_used_:
>       fix_register (arg, 0, 1);
>       break;
> @@ -1800,10 +1791,6 @@ common_handle_option (struct gcc_options
>        }
>       break;
>
> -    case OPT_fpeel_loops:
> -      flag_peel_loops_set = true;
> -      break;
> -
>     case OPT_fplugin_:
>  #ifdef ENABLE_PLUGIN
>       add_new_plugin (arg);
> @@ -1820,14 +1807,6 @@ common_handle_option (struct gcc_options
>  #endif
>       break;
>
> -    case OPT_fprofile_arcs:
> -      profile_arc_flag_set = true;
> -      break;
> -
> -    case OPT_finline_functions:
> -      flag_inline_functions_set = true;
> -      break;
> -
>     case OPT_fprofile_dir_:
>       profile_data_prefix = xstrdup (arg);
>       break;
> @@ -1838,30 +1817,30 @@ common_handle_option (struct gcc_options
>       value = true;
>       /* No break here - do -fprofile-use processing. */
>     case OPT_fprofile_use:
> -      if (!flag_branch_probabilities_set)
> +      if (!opts_set->x_flag_branch_probabilities)
>         flag_branch_probabilities = value;
> -      if (!flag_profile_values_set)
> +      if (!opts_set->x_flag_profile_values)
>         flag_profile_values = value;
> -      if (!flag_unroll_loops_set)
> +      if (!opts_set->x_flag_unroll_loops)
>         flag_unroll_loops = value;
> -      if (!flag_peel_loops_set)
> +      if (!opts_set->x_flag_peel_loops)
>         flag_peel_loops = value;
> -      if (!flag_tracer_set)
> +      if (!opts_set->x_flag_tracer)
>         flag_tracer = value;
> -      if (!flag_value_profile_transformations_set)
> +      if (!opts_set->x_flag_value_profile_transformations)
>         flag_value_profile_transformations = value;
> -      if (!flag_inline_functions_set)
> +      if (!opts_set->x_flag_inline_functions)
>         flag_inline_functions = value;
> -      if (!flag_ipa_cp_set)
> +      if (!opts_set->x_flag_ipa_cp)
>         flag_ipa_cp = value;
> -      if (!flag_ipa_cp_clone_set
> +      if (!opts_set->x_flag_ipa_cp_clone
>          && value && flag_ipa_cp)
>        flag_ipa_cp_clone = value;
> -      if (!flag_predictive_commoning_set)
> +      if (!opts_set->x_flag_predictive_commoning)
>        flag_predictive_commoning = value;
> -      if (!flag_unswitch_loops_set)
> +      if (!opts_set->x_flag_unswitch_loops)
>        flag_unswitch_loops = value;
> -      if (!flag_gcse_after_reload_set)
> +      if (!opts_set->x_flag_gcse_after_reload)
>        flag_gcse_after_reload = value;
>       break;
>
> @@ -1870,20 +1849,16 @@ common_handle_option (struct gcc_options
>       value = true;
>       /* No break here - do -fprofile-generate processing. */
>     case OPT_fprofile_generate:
> -      if (!profile_arc_flag_set)
> +      if (!opts_set->x_profile_arc_flag)
>         profile_arc_flag = value;
> -      if (!flag_profile_values_set)
> +      if (!opts_set->x_flag_profile_values)
>         flag_profile_values = value;
> -      if (!flag_value_profile_transformations_set)
> +      if (!opts_set->x_flag_value_profile_transformations)
>         flag_value_profile_transformations = value;
> -      if (!flag_inline_functions_set)
> +      if (!opts_set->x_flag_inline_functions)
>         flag_inline_functions = value;
>       break;
>
> -    case OPT_fprofile_values:
> -      flag_profile_values_set = true;
> -      break;
> -
>     case OPT_fshow_column:
>       global_dc->show_column = value;
>       break;
> @@ -1903,10 +1878,6 @@ common_handle_option (struct gcc_options
>       }
>       break;
>
> -    case OPT_fvpt:
> -      flag_value_profile_transformations_set = true;
> -      break;
> -
>     case OPT_frandom_seed:
>       /* The real switch is -fno-random-seed.  */
>       if (value)
> @@ -1918,11 +1889,6 @@ common_handle_option (struct gcc_options
>       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);
> @@ -2022,34 +1988,6 @@ common_handle_option (struct gcc_options
>       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;
> -
>     case OPT_g:
>       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg);
>       break;
> @@ -2384,8 +2322,8 @@ enable_warning_as_error (const char *arg
>
>          /* -Werror=foo implies -Wfoo.  */
>          if (option->var_type == CLVC_BOOLEAN)
> -           handle_generated_option (&global_options, option_index,
> -                                    NULL, value, lang_mask,
> +           handle_generated_option (&global_options, &global_options_set,
> +                                    option_index, NULL, value, lang_mask,
>                                     (int)kind, handlers);
>
>          if (warning_as_error_callback)
> Index: gcc/opts.h
> ===================================================================
> --- gcc/opts.h  (revision 164755)
> +++ gcc/opts.h  (working copy)
> @@ -157,6 +157,7 @@ struct cl_option_handler_func
>  {
>   /* The function called to handle the option.  */
>   bool (*handler) (struct gcc_options *opts,
> +                  struct gcc_options *opts_set,
>                   const struct cl_decoded_option *decoded,
>                   unsigned int lang_mask, int kind,
>                   const struct cl_option_handlers *handlers);
> @@ -213,14 +214,18 @@ extern void decode_options (unsigned int
>  extern int option_enabled (int opt_idx, void *opts);
>  extern bool get_option_state (struct gcc_options *, int,
>                              struct cl_option_state *);
> -extern void set_option (struct gcc_options *opts, int opt_index, int value,
> -                       const char *arg, int);
> +extern void set_option (struct gcc_options *opts,
> +                       struct gcc_options *opts_set,
> +                       int opt_index, int value, const char *arg, int);
>  extern void *option_flag_var (int opt_index, struct gcc_options *opts);
>  bool handle_option (struct gcc_options *opts,
> +                   struct gcc_options *opts_set,
>                    const struct cl_decoded_option *decoded,
>                    unsigned int lang_mask, int kind,
> -                   const struct cl_option_handlers *handlers);
> +                   const struct cl_option_handlers *handlers,
> +                   bool generated_p);
>  bool handle_generated_option (struct gcc_options *opts,
> +                             struct gcc_options *opts_set,
>                              size_t opt_index, const char *arg, int value,
>                              unsigned int lang_mask, int kind,
>                              const struct cl_option_handlers *handlers);
> @@ -230,6 +235,7 @@ void generate_option (size_t opt_index,
>  void generate_option_input_file (const char *file,
>                                 struct cl_decoded_option *decoded);
>  extern void read_cmdline_option (struct gcc_options *opts,
> +                                struct gcc_options *opts_set,
>                                 struct cl_decoded_option *decoded,
>                                 unsigned int lang_mask,
>                                 const struct cl_option_handlers *handlers);
> Index: gcc/optc-gen.awk
> ===================================================================
> --- gcc/optc-gen.awk    (revision 164755)
> +++ gcc/optc-gen.awk    (working copy)
> @@ -76,9 +76,7 @@ for (i = 1; i <= n_headers; i++)
>  print "#include " quote "opts.h" quote
>  print "#include " quote "intl.h" quote
>  print ""
> -print "#ifdef GCC_DRIVER"
> -print "int target_flags_explicit;"
> -print "#else"
> +print "#ifndef GCC_DRIVER"
>  print "#include " quote "flags.h" quote
>  print "#include " quote "target.h" quote
>  print "#endif /* GCC_DRIVER */"
> @@ -140,6 +138,8 @@ for (i = 0; i < n_opts; i++) {
>  }
>  print "};"
>  print ""
> +print "struct gcc_options global_options_set;"
> +print ""
>
>  print "const char * const lang_names[] =\n{"
>  for (i = 0; i < n_langs; i++) {
> Index: gcc/opth-gen.awk
> ===================================================================
> --- gcc/opth-gen.awk    (revision 164755)
> +++ gcc/opth-gen.awk    (working copy)
> @@ -70,8 +70,6 @@ print ""
>  print "#ifndef OPTIONS_H"
>  print "#define OPTIONS_H"
>  print ""
> -print "extern int target_flags_explicit;"
> -print ""
>
>  have_save = 0;
>
> @@ -127,6 +125,8 @@ for (i = 0; i < n_opts; i++) {
>  print "#ifndef GENERATOR_FILE"
>  print "};"
>  print "extern struct gcc_options global_options;"
> +print "extern struct gcc_options global_options_set;"
> +print "#define target_flags_explicit global_options_set.x_target_flags"
>  print "#endif"
>  print ""
>
> Index: gcc/lto-opts.c
> ===================================================================
> --- gcc/lto-opts.c      (revision 164755)
> +++ gcc/lto-opts.c      (working copy)
> @@ -402,7 +402,8 @@ lto_reissue_options (void)
>       void *flag_var = option_flag_var (o->code, &global_options);
>
>       if (flag_var)
> -       set_option (&global_options, o->code, o->value, o->arg,
> +       set_option (&global_options, &global_options_set,
> +                   o->code, o->value, o->arg,
>                    0 /*DK_UNSPECIFIED*/);
>
>       if (o->type == CL_TARGET)
> Index: gcc/config/i386/i386.opt
> ===================================================================
> --- gcc/config/i386/i386.opt    (revision 164755)
> +++ gcc/config/i386/i386.opt    (working copy)
> @@ -50,7 +50,7 @@ int ix86_isa_flags_explicit
>
>  ;; which flags were passed by the user
>  TargetSave
> -int target_flags_explicit
> +int ix86_target_flags_explicit
>
>  ;; whether -mtune was not specified
>  TargetSave
> Index: gcc/config/i386/i386.c
> ===================================================================
> --- gcc/config/i386/i386.c      (revision 164755)
> +++ gcc/config/i386/i386.c      (working copy)
> @@ -3802,7 +3802,7 @@ ix86_function_specific_save (struct cl_t
>   ptr->tune_defaulted = ix86_tune_defaulted;
>   ptr->arch_specified = ix86_arch_specified;
>   ptr->ix86_isa_flags_explicit = ix86_isa_flags_explicit;
> -  ptr->target_flags_explicit = target_flags_explicit;
> +  ptr->ix86_target_flags_explicit = target_flags_explicit;
>
>   /* The fields are char but the variables are not; make sure the
>      values fit in the fields.  */
> @@ -3831,7 +3831,7 @@ ix86_function_specific_restore (struct c
>   ix86_tune_defaulted = ptr->tune_defaulted;
>   ix86_arch_specified = ptr->arch_specified;
>   ix86_isa_flags_explicit = ptr->ix86_isa_flags_explicit;
> -  target_flags_explicit = ptr->target_flags_explicit;
> +  target_flags_explicit = ptr->ix86_target_flags_explicit;
>
>   /* Recreate the arch feature tests if the arch changed */
>   if (old_arch != ix86_arch)
> Index: gcc/config/ia64/ia64.c
> ===================================================================
> --- gcc/config/ia64/ia64.c      (revision 164755)
> +++ gcc/config/ia64/ia64.c      (working copy)
> @@ -5650,7 +5650,8 @@ ia64_override_options_after_change (void
>   flag_schedule_insns_after_reload = 0;
>
>   if (optimize >= 3
> -      && ! sel_sched_switch_set)
> +      && !global_options_set.x_flag_selective_scheduling
> +      && !global_options_set.x_flag_selective_scheduling2)
>     {
>       flag_selective_scheduling2 = 1;
>       flag_sel_sched_pipelining = 1;
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
>

Patch

Index: gcc/flags.h
===================================================================
--- gcc/flags.h	(revision 164755)
+++ gcc/flags.h	(working copy)
@@ -276,9 +276,6 @@  extern int flag_evaluation_order;
 extern unsigned HOST_WIDE_INT g_switch_value;
 extern bool g_switch_set;
 
-/* Same for selective scheduling.  */
-extern bool sel_sched_switch_set;
-
 /* Whether to run the warn_unused_result attribute pass.  */
 extern bool flag_warn_unused_result;
 
@@ -293,10 +290,6 @@  enum graph_dump_types
 };
 extern enum graph_dump_types graph_dump_format;
 
-/* True if flag_speculative_prefetching was set by user.  Used to suppress
-   warning message in case flag was set by -fprofile-{generate,use}.  */
-extern bool flag_speculative_prefetching_set;
-
 /* Type of stack check.  */
 enum stack_check_type
 {
Index: gcc/opts-common.c
===================================================================
--- gcc/opts-common.c	(revision 164755)
+++ gcc/opts-common.c	(working copy)
@@ -799,15 +799,20 @@  keep:
 }
 
 /* Handle option DECODED for the language indicated by LANG_MASK,
-   using the handlers in HANDLERS and setting fields in OPTS.  KIND is
-   the diagnostic_t if this is a diagnostics option, DK_UNSPECIFIED
-   otherwise.  Returns false if the switch was invalid.  */
+   using the handlers in HANDLERS and setting fields in OPTS and
+   OPTS_SET.  KIND is the diagnostic_t if this is a diagnostics
+   option, DK_UNSPECIFIED otherwise.  GENERATED_P is true for an
+   option generated as part of processing another option or otherwise
+   generated internally, false for one explicitly passed by the user.
+   Returns false if the switch was invalid.  */
 
 bool
 handle_option (struct gcc_options *opts,
+	       struct gcc_options *opts_set,
 	       const struct cl_decoded_option *decoded,
 	       unsigned int lang_mask, int kind,
-	       const struct cl_option_handlers *handlers)
+	       const struct cl_option_handlers *handlers,
+	       bool generated_p)
 {
   size_t opt_index = decoded->opt_index;
   const char *arg = decoded->arg;
@@ -817,12 +822,13 @@  handle_option (struct gcc_options *opts,
   size_t i;
 
   if (flag_var)
-    set_option (opts, opt_index, value, arg, kind);
+    set_option (opts, (generated_p ? NULL : opts_set),
+		opt_index, value, arg, kind);
 
   for (i = 0; i < handlers->num_handlers; i++)
     if (option->flags & handlers->handlers[i].mask)
       {
-	if (!handlers->handlers[i].handler (opts, decoded,
+	if (!handlers->handlers[i].handler (opts, opts_set, decoded,
 					    lang_mask, kind, handlers))
 	  return false;
 	else
@@ -839,15 +845,17 @@  handle_option (struct gcc_options *opts,
    command line.  */
 
 bool
-handle_generated_option (struct gcc_options *opts, size_t opt_index,
-			 const char *arg, int value,
+handle_generated_option (struct gcc_options *opts,
+			 struct gcc_options *opts_set,
+			 size_t opt_index, const char *arg, int value,
 			 unsigned int lang_mask, int kind,
 			 const struct cl_option_handlers *handlers)
 {
   struct cl_decoded_option decoded;
 
   generate_option (opt_index, arg, value, lang_mask, &decoded);
-  return handle_option (opts, &decoded, lang_mask, kind, handlers);
+  return handle_option (opts, opts_set, &decoded, lang_mask, kind, handlers,
+			true);
 }
 
 /* Fill in *DECODED with an option described by OPT_INDEX, ARG and
@@ -906,10 +914,12 @@  generate_option_input_file (const char *
 }
 
 /* Handle the switch DECODED for the language indicated by LANG_MASK,
-   using the handlers in *HANDLERS and setting fields in OPTS.  */
+   using the handlers in *HANDLERS and setting fields in OPTS and
+   OPTS_SET.  */
 
 void
 read_cmdline_option (struct gcc_options *opts,
+		     struct gcc_options *opts_set,
 		     struct cl_decoded_option *decoded,
 		     unsigned int lang_mask,
 		     const struct cl_option_handlers *handlers)
@@ -963,33 +973,42 @@  read_cmdline_option (struct gcc_options 
 
   gcc_assert (!decoded->errors);
 
-  if (!handle_option (opts, decoded, lang_mask, DK_UNSPECIFIED, handlers))
+  if (!handle_option (opts, opts_set, decoded, lang_mask, DK_UNSPECIFIED,
+		      handlers, false))
     error ("unrecognized command line option %qs", opt);
 }
 
-/* Set any field in OPTS for option OPT_INDEX according to VALUE and ARG,
-   diagnostic kind KIND.  */
+/* Set any field in OPTS, and OPTS_SET if not NULL, for option
+   OPT_INDEX according to VALUE and ARG, diagnostic kind KIND.  */
 
 void
-set_option (struct gcc_options *opts, int opt_index, int value,
-	    const char *arg, int kind)
+set_option (struct gcc_options *opts, struct gcc_options *opts_set,
+	    int opt_index, int value, const char *arg, int kind)
 {
   const struct cl_option *option = &cl_options[opt_index];
   void *flag_var = option_flag_var (opt_index, opts);
+  void *set_flag_var = NULL;
 
   if (!flag_var)
     return;
 
+  if (opts_set != NULL)
+    set_flag_var = option_flag_var (opt_index, opts_set);
+
   switch (option->var_type)
     {
     case CLVC_BOOLEAN:
 	*(int *) flag_var = value;
+	if (set_flag_var)
+	  *(int *) set_flag_var = 1;
 	break;
 
     case CLVC_EQUAL:
 	*(int *) flag_var = (value
 			     ? option->var_value
 			     : !option->var_value);
+	if (set_flag_var)
+	  *(int *) set_flag_var = 1;
 	break;
 
     case CLVC_BIT_CLEAR:
@@ -998,12 +1017,14 @@  set_option (struct gcc_options *opts, in
 	  *(int *) flag_var |= option->var_value;
 	else
 	  *(int *) flag_var &= ~option->var_value;
-	if (flag_var == &target_flags)
-	  target_flags_explicit |= option->var_value;
+	if (set_flag_var)
+	  *(int *) set_flag_var |= option->var_value;
 	break;
 
     case CLVC_STRING:
 	*(const char **) flag_var = arg;
+	if (set_flag_var)
+	  *(const char **) set_flag_var = "";
 	break;
     }
 
Index: gcc/c-family/c-opts.c
===================================================================
--- gcc/c-family/c-opts.c	(revision 164755)
+++ gcc/c-family/c-opts.c	(working copy)
@@ -436,7 +436,8 @@  c_common_handle_option (size_t scode, co
     case OPT_Wall:
       warn_unused = value;
       set_Wformat (value);
-      handle_generated_option (&global_options, OPT_Wimplicit, NULL, value,
+      handle_generated_option (&global_options, &global_options_set,
+			       OPT_Wimplicit, NULL, value,
 			       c_family_lang_mask, kind, handlers);
       warn_char_subscripts = value;
       warn_missing_braces = value;
@@ -530,11 +531,11 @@  c_common_handle_option (size_t scode, co
     case OPT_Wimplicit:
       gcc_assert (value == 0 || value == 1);
       if (warn_implicit_int == -1)
-	handle_generated_option (&global_options, OPT_Wimplicit_int,
-				 NULL, value,
+	handle_generated_option (&global_options, &global_options_set,
+				 OPT_Wimplicit_int, NULL, value,
 				 c_family_lang_mask, kind, handlers);
       if (warn_implicit_function_declaration == -1)
-	handle_generated_option (&global_options,
+	handle_generated_option (&global_options, &global_options_set,
 				 OPT_Wimplicit_function_declaration, NULL,
 				 value, c_family_lang_mask, kind, handlers);
       break;
Index: gcc/gcc.c
===================================================================
--- gcc/gcc.c	(revision 164755)
+++ gcc/gcc.c	(working copy)
@@ -3151,6 +3151,7 @@  static int last_language_n_infiles;
 
 static bool
 driver_handle_option (struct gcc_options *opts,
+		      struct gcc_options *opts_set,
 		      const struct cl_decoded_option *decoded,
 		      unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
 		      const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
@@ -3163,6 +3164,7 @@  driver_handle_option (struct gcc_options
   bool do_save = true;
 
   gcc_assert (opts == &global_options);
+  gcc_assert (opts_set == &global_options_set);
   gcc_assert (kind == DK_UNSPECIFIED);
 
   switch (opt_index)
@@ -3803,8 +3805,8 @@  process_command (unsigned int decoded_op
 	  continue;
 	}
 
-      read_cmdline_option (&global_options, decoded_options + j,
-			   CL_DRIVER, &handlers);
+      read_cmdline_option (&global_options, &global_options_set,
+			   decoded_options + j, CL_DRIVER, &handlers);
     }
 
   /* If -save-temps=obj and -o name, create the prefix to use for %b.
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c	(revision 164755)
+++ gcc/toplev.c	(working copy)
@@ -155,11 +155,6 @@  const char *aux_base_name;
 /* Prefix for profile data files */
 const char *profile_data_prefix;
 
-/* A mask of target_flags that includes bit X if X was set or cleared
-   on the command line.  */
-
-int target_flags_explicit;
-
 /* Debug hooks - dependent upon command line options.  */
 
 const struct gcc_debug_hooks *debug_hooks;
Index: gcc/opts.c
===================================================================
--- gcc/opts.c	(revision 164755)
+++ gcc/opts.c	(working copy)
@@ -50,9 +50,6 @@  along with GCC; see the file COPYING3.  
 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;
 
@@ -345,15 +342,6 @@  struct visibility_flags visibility_optio
 /* What to print when a switch has no documentation.  */
 static const char undocumented_msg[] = N_("This switch lacks documentation");
 
-/* Used for bookkeeping on whether user set these flags so
-   -fprofile-use/-fprofile-generate does not use them.  */
-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, 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.  */
 
 typedef char *char_p; /* For DEF_VEC_P.  */
@@ -377,6 +365,7 @@  const char **in_fnames;
 unsigned num_in_fnames;
 
 static bool common_handle_option (struct gcc_options *opts,
+				  struct gcc_options *opts_set,
 				  const struct cl_decoded_option *decoded,
 				  unsigned int lang_mask, int kind,
 				  const struct cl_option_handlers *handlers);
@@ -517,11 +506,13 @@  post_handling_callback (const struct cl_
 
 static bool
 lang_handle_option (struct gcc_options *opts,
+		    struct gcc_options *opts_set,
 		    const struct cl_decoded_option *decoded,
 		    unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
 		    const struct cl_option_handlers *handlers)
 {
   gcc_assert (opts == &global_options);
+  gcc_assert (opts_set == &global_options_set);
   gcc_assert (decoded->canonical_option_num_elements <= 2);
   return lang_hooks.handle_option (decoded->opt_index, decoded->arg,
 				   decoded->value, kind, handlers);
@@ -532,11 +523,13 @@  lang_handle_option (struct gcc_options *
 
 static bool
 target_handle_option (struct gcc_options *opts,
+		      struct gcc_options *opts_set,
 		      const struct cl_decoded_option *decoded,
 		      unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
 		      const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
 {
   gcc_assert (opts == &global_options);
+  gcc_assert (opts_set == &global_options_set);
   gcc_assert (decoded->canonical_option_num_elements <= 2);
   gcc_assert (kind == DK_UNSPECIFIED);
   return targetm.handle_option (decoded->opt_index, decoded->arg,
@@ -649,8 +642,8 @@  read_cmdline_options (struct cl_decoded_
 	  continue;
 	}
 
-      read_cmdline_option (&global_options, decoded_options + i,
-			   lang_mask, handlers);
+      read_cmdline_option (&global_options, &global_options_set,
+			   decoded_options + i, lang_mask, handlers);
     }
 }
 
@@ -1432,6 +1425,7 @@  print_specific_help (unsigned int includ
 
 static bool
 common_handle_option (struct gcc_options *opts,
+		      struct gcc_options *opts_set,
 		      const struct cl_decoded_option *decoded,
 		      unsigned int lang_mask, int kind ATTRIBUTE_UNUSED,
 		      const struct cl_option_handlers *handlers)
@@ -1443,6 +1437,7 @@  common_handle_option (struct gcc_options
   enum opt_code code = (enum opt_code) scode;
 
   gcc_assert (opts == &global_options);
+  gcc_assert (opts_set == &global_options_set);
   gcc_assert (decoded->canonical_option_num_elements <= 2);
 
   switch (code)
@@ -1703,10 +1698,6 @@  common_handle_option (struct gcc_options
       align_loops = value;
       break;
 
-    case OPT_fbranch_probabilities:
-      flag_branch_probabilities_set = true;
-      break;
-
     case OPT_fcall_used_:
       fix_register (arg, 0, 1);
       break;
@@ -1800,10 +1791,6 @@  common_handle_option (struct gcc_options
 	}
       break;
 
-    case OPT_fpeel_loops:
-      flag_peel_loops_set = true;
-      break;
-
     case OPT_fplugin_:
 #ifdef ENABLE_PLUGIN
       add_new_plugin (arg);
@@ -1820,14 +1807,6 @@  common_handle_option (struct gcc_options
 #endif
       break;
 
-    case OPT_fprofile_arcs:
-      profile_arc_flag_set = true;
-      break;
-
-    case OPT_finline_functions:
-      flag_inline_functions_set = true;
-      break;
-
     case OPT_fprofile_dir_:
       profile_data_prefix = xstrdup (arg);
       break;
@@ -1838,30 +1817,30 @@  common_handle_option (struct gcc_options
       value = true;
       /* No break here - do -fprofile-use processing. */
     case OPT_fprofile_use:
-      if (!flag_branch_probabilities_set)
+      if (!opts_set->x_flag_branch_probabilities)
         flag_branch_probabilities = value;
-      if (!flag_profile_values_set)
+      if (!opts_set->x_flag_profile_values)
         flag_profile_values = value;
-      if (!flag_unroll_loops_set)
+      if (!opts_set->x_flag_unroll_loops)
         flag_unroll_loops = value;
-      if (!flag_peel_loops_set)
+      if (!opts_set->x_flag_peel_loops)
         flag_peel_loops = value;
-      if (!flag_tracer_set)
+      if (!opts_set->x_flag_tracer)
         flag_tracer = value;
-      if (!flag_value_profile_transformations_set)
+      if (!opts_set->x_flag_value_profile_transformations)
         flag_value_profile_transformations = value;
-      if (!flag_inline_functions_set)
+      if (!opts_set->x_flag_inline_functions)
         flag_inline_functions = value;
-      if (!flag_ipa_cp_set)
+      if (!opts_set->x_flag_ipa_cp)
         flag_ipa_cp = value;
-      if (!flag_ipa_cp_clone_set
+      if (!opts_set->x_flag_ipa_cp_clone
 	  && value && flag_ipa_cp)
 	flag_ipa_cp_clone = value;
-      if (!flag_predictive_commoning_set)
+      if (!opts_set->x_flag_predictive_commoning)
 	flag_predictive_commoning = value;
-      if (!flag_unswitch_loops_set)
+      if (!opts_set->x_flag_unswitch_loops)
 	flag_unswitch_loops = value;
-      if (!flag_gcse_after_reload_set)
+      if (!opts_set->x_flag_gcse_after_reload)
 	flag_gcse_after_reload = value;
       break;
 
@@ -1870,20 +1849,16 @@  common_handle_option (struct gcc_options
       value = true;
       /* No break here - do -fprofile-generate processing. */
     case OPT_fprofile_generate:
-      if (!profile_arc_flag_set)
+      if (!opts_set->x_profile_arc_flag)
         profile_arc_flag = value;
-      if (!flag_profile_values_set)
+      if (!opts_set->x_flag_profile_values)
         flag_profile_values = value;
-      if (!flag_value_profile_transformations_set)
+      if (!opts_set->x_flag_value_profile_transformations)
         flag_value_profile_transformations = value;
-      if (!flag_inline_functions_set)
+      if (!opts_set->x_flag_inline_functions)
         flag_inline_functions = value;
       break;
 
-    case OPT_fprofile_values:
-      flag_profile_values_set = true;
-      break;
-
     case OPT_fshow_column:
       global_dc->show_column = value;
       break;
@@ -1903,10 +1878,6 @@  common_handle_option (struct gcc_options
       }
       break;
 
-    case OPT_fvpt:
-      flag_value_profile_transformations_set = true;
-      break;
-
     case OPT_frandom_seed:
       /* The real switch is -fno-random-seed.  */
       if (value)
@@ -1918,11 +1889,6 @@  common_handle_option (struct gcc_options
       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);
@@ -2022,34 +1988,6 @@  common_handle_option (struct gcc_options
       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;
-
     case OPT_g:
       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg);
       break;
@@ -2384,8 +2322,8 @@  enable_warning_as_error (const char *arg
 
 	  /* -Werror=foo implies -Wfoo.  */
 	  if (option->var_type == CLVC_BOOLEAN)
-	    handle_generated_option (&global_options, option_index,
-				     NULL, value, lang_mask,
+	    handle_generated_option (&global_options, &global_options_set,
+				     option_index, NULL, value, lang_mask,
 				     (int)kind, handlers);
 
 	  if (warning_as_error_callback)
Index: gcc/opts.h
===================================================================
--- gcc/opts.h	(revision 164755)
+++ gcc/opts.h	(working copy)
@@ -157,6 +157,7 @@  struct cl_option_handler_func
 {
   /* The function called to handle the option.  */
   bool (*handler) (struct gcc_options *opts,
+		   struct gcc_options *opts_set,
 		   const struct cl_decoded_option *decoded,
 		   unsigned int lang_mask, int kind,
 		   const struct cl_option_handlers *handlers);
@@ -213,14 +214,18 @@  extern void decode_options (unsigned int
 extern int option_enabled (int opt_idx, void *opts);
 extern bool get_option_state (struct gcc_options *, int,
 			      struct cl_option_state *);
-extern void set_option (struct gcc_options *opts, int opt_index, int value,
-			const char *arg, int);
+extern void set_option (struct gcc_options *opts,
+			struct gcc_options *opts_set,
+			int opt_index, int value, const char *arg, int);
 extern void *option_flag_var (int opt_index, struct gcc_options *opts);
 bool handle_option (struct gcc_options *opts,
+		    struct gcc_options *opts_set,
 		    const struct cl_decoded_option *decoded,
 		    unsigned int lang_mask, int kind,
-		    const struct cl_option_handlers *handlers);
+		    const struct cl_option_handlers *handlers,
+		    bool generated_p);
 bool handle_generated_option (struct gcc_options *opts,
+			      struct gcc_options *opts_set,
 			      size_t opt_index, const char *arg, int value,
 			      unsigned int lang_mask, int kind,
 			      const struct cl_option_handlers *handlers);
@@ -230,6 +235,7 @@  void generate_option (size_t opt_index, 
 void generate_option_input_file (const char *file,
 				 struct cl_decoded_option *decoded);
 extern void read_cmdline_option (struct gcc_options *opts,
+				 struct gcc_options *opts_set,
 				 struct cl_decoded_option *decoded,
 				 unsigned int lang_mask,
 				 const struct cl_option_handlers *handlers);
Index: gcc/optc-gen.awk
===================================================================
--- gcc/optc-gen.awk	(revision 164755)
+++ gcc/optc-gen.awk	(working copy)
@@ -76,9 +76,7 @@  for (i = 1; i <= n_headers; i++)
 print "#include " quote "opts.h" quote
 print "#include " quote "intl.h" quote
 print ""
-print "#ifdef GCC_DRIVER"
-print "int target_flags_explicit;"
-print "#else"
+print "#ifndef GCC_DRIVER"
 print "#include " quote "flags.h" quote
 print "#include " quote "target.h" quote
 print "#endif /* GCC_DRIVER */"
@@ -140,6 +138,8 @@  for (i = 0; i < n_opts; i++) {
 }
 print "};"
 print ""
+print "struct gcc_options global_options_set;"
+print ""
 
 print "const char * const lang_names[] =\n{"
 for (i = 0; i < n_langs; i++) {
Index: gcc/opth-gen.awk
===================================================================
--- gcc/opth-gen.awk	(revision 164755)
+++ gcc/opth-gen.awk	(working copy)
@@ -70,8 +70,6 @@  print ""
 print "#ifndef OPTIONS_H"
 print "#define OPTIONS_H"
 print ""
-print "extern int target_flags_explicit;"
-print ""
 
 have_save = 0;
 
@@ -127,6 +125,8 @@  for (i = 0; i < n_opts; i++) {
 print "#ifndef GENERATOR_FILE"
 print "};"
 print "extern struct gcc_options global_options;"
+print "extern struct gcc_options global_options_set;"
+print "#define target_flags_explicit global_options_set.x_target_flags"
 print "#endif"
 print ""
 
Index: gcc/lto-opts.c
===================================================================
--- gcc/lto-opts.c	(revision 164755)
+++ gcc/lto-opts.c	(working copy)
@@ -402,7 +402,8 @@  lto_reissue_options (void)
       void *flag_var = option_flag_var (o->code, &global_options);
 
       if (flag_var)
-	set_option (&global_options, o->code, o->value, o->arg,
+	set_option (&global_options, &global_options_set,
+		    o->code, o->value, o->arg,
 		    0 /*DK_UNSPECIFIED*/);
 
       if (o->type == CL_TARGET)
Index: gcc/config/i386/i386.opt
===================================================================
--- gcc/config/i386/i386.opt	(revision 164755)
+++ gcc/config/i386/i386.opt	(working copy)
@@ -50,7 +50,7 @@  int ix86_isa_flags_explicit
 
 ;; which flags were passed by the user
 TargetSave
-int target_flags_explicit
+int ix86_target_flags_explicit
 
 ;; whether -mtune was not specified
 TargetSave
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 164755)
+++ gcc/config/i386/i386.c	(working copy)
@@ -3802,7 +3802,7 @@  ix86_function_specific_save (struct cl_t
   ptr->tune_defaulted = ix86_tune_defaulted;
   ptr->arch_specified = ix86_arch_specified;
   ptr->ix86_isa_flags_explicit = ix86_isa_flags_explicit;
-  ptr->target_flags_explicit = target_flags_explicit;
+  ptr->ix86_target_flags_explicit = target_flags_explicit;
 
   /* The fields are char but the variables are not; make sure the
      values fit in the fields.  */
@@ -3831,7 +3831,7 @@  ix86_function_specific_restore (struct c
   ix86_tune_defaulted = ptr->tune_defaulted;
   ix86_arch_specified = ptr->arch_specified;
   ix86_isa_flags_explicit = ptr->ix86_isa_flags_explicit;
-  target_flags_explicit = ptr->target_flags_explicit;
+  target_flags_explicit = ptr->ix86_target_flags_explicit;
 
   /* Recreate the arch feature tests if the arch changed */
   if (old_arch != ix86_arch)
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c	(revision 164755)
+++ gcc/config/ia64/ia64.c	(working copy)
@@ -5650,7 +5650,8 @@  ia64_override_options_after_change (void
   flag_schedule_insns_after_reload = 0;
 
   if (optimize >= 3
-      && ! sel_sched_switch_set)
+      && !global_options_set.x_flag_selective_scheduling
+      && !global_options_set.x_flag_selective_scheduling2)
     {
       flag_selective_scheduling2 = 1;
       flag_sel_sched_pipelining = 1;