Patchwork More use of structures in option processing

login
register
mail settings
Submitter Joseph S. Myers
Date Sept. 30, 2010, 12:48 p.m.
Message ID <Pine.LNX.4.64.1009301247020.32746@digraph.polyomino.org.uk>
Download mbox | patch
Permalink /patch/66153/
State New
Headers show

Comments

Joseph S. Myers - Sept. 30, 2010, 12:48 p.m.
This patch continues moving towards the explicit use of structures in
option processing instead of implicit use of global state.

* The optimize and optimize_size variables move into the gcc_options
  structure (so requiring the changes to files that redeclare them or
  that have function parameters with those names).

* The table of options no longer stores pointers to variables or
  fields in global_options in which to store values; it stores
  structure offsets instead.  (Where static variables in options.c
  were previously used to track state of some target options, there
  are now structure fields, whose names get defined as macros to
  prevent accidental use.)

* Functions in options.c (the generated file) generally no longer use
  global state implicitly, but get pointers to gcc_options structures
  passed in.

* Similarly, functions in opts-common.c do not use global state
  implicitly.  The exceptions, to be fixed in subsequent patches, are
  (a) checks for target_flags and consequent setting of
  target_flags_explicit (to be fixed by using a pointer to a structure
  that records which options have been used explicitly, so replacing
  target_flags_explicit, various similar variables that are set by
  special code in option handlers and various uses of -1 or 2 as
  initial values) and (b) use of global_dc for setting diagnostic
  state (to be fixed by passing an explicit diagnostic context pointer
  as needed, so that processing options for other gcc_options
  structures need not affect global diagnostic state).  Some functions
  in opts.c are fixed similarly.

* The interface opts-common.c uses to option handlers passes a
  gcc_options pointer explicitly.  Where option handlers are not ready
  for this, appropriate assertions that the pointer points to
  global_options are inserted.  In due course common and target
  handlers will be prepared to take pointers to other structures and
  this assertion removed in those cases; I expect it can stay for
  language option handlers which should not need to become available
  in the driver or be used in multilib selection.

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  Also
tested building cc1 for the following targets (where "optimize"
declarations were removed from target headers): pdp11-none
powerpc-eabi sh-elf xtensa-elf.  OK to commit?

2010-09-30  Joseph Myers  <joseph@codesourcery.com>

	* opt-functions.awk (static_var): Update comment.
	(var_ref): Return offsetof expression or -1, not variable address.
	* optc-gen.awk: Generate structure field initializers instead of
	static variables.  Expect -1 for missing variables instead of null
	pointer.  Add gcc_options parameters to generated functions.
	* opth-gen.awk: Generate structure fields for static variables.
	Add gcc_options parameters to generated functions.
	* common.opt (optimize, optimize_size): Add variables.
	* config/i386/i386-c.c (ix86_pragma_target_parse): Pass
	&global_options to cl_target_option_restore.
	* config/i386/i386.c (ix86_valid_target_attribute_p): Pass
	&global_options to cl_optimization_restore, cl_target_option_save
	and cl_target_option_restore.
	(ix86_set_current_function): Pass &global_options to
	cl_target_option_restore.
	* config/pdp11/pdp11.h (optimize): Remove.
	* config/rs6000/rs6000.h (optimize): Remove.
	* config/sh/sh.h (optimize): Remove.
	* config/xtensa/xtensa.h (optimize): Remove.
	* coretypes.h (struct gcc_options): Declare.
	* diagnostic.c (diagnostic_initialize): Initialize
	context->option_state.
	(diagnostic_report_diagnostic): Pass option_state to
	option_enabled hook.
	* diagnostic.h (diagnostic_context.option_enabled): Add void *
	parameter.
	(diagnostic_context.option_state): New field.
	* final.c (final_start_function, final, final_scan_insn): Rename
	optimize parameter to optimize_p.
	* flags.h (optimize, optimize_size): Remove.
	* function.c (invoke_set_current_function_hook): Pass
	&global_options to cl_optimization_restore.
	* gcc.c (driver_handle_option): Take gcc_options parameter.
	Assert that it is &global_options.
	(process_command): Pass &global_options to read_cmdline_option.
	* ipa-pure-const.c (suggest_attribute): Pass &global_options to
	option_enabled.
	* lto-opts.c (lto_reissue_options): Use option_flag_var.  Pass
	&global_options to set_option.
	* opts-common.c (handle_option, handle_generated_option,
	read_cmdline_option, set_option): Take explicit gcc_options
	parameters.  Use option_flag_var.
	(option_flag_var): New.
	* opts.c (common_handle_option, lang_handle_option,
	target_handle_option): Take gcc_options parameter.  Assert that it
	is &global_options.
	(read_cmdline_options): Pass &global_options to
	read_cmdline_option.
	(print_filtered_help): Use option_flag_var.  Pass &global_options
	to option_enabled.
	(common_handle_option): Use option_flag_var.
	(option_enabled): Take opts parameter.  Use option_flag_var.
	(get_option_state): Take gcc_options parameter.  Use
	option_flag_var.  Pass gcc_options parameter to option_enabled.
	(enable_warning_as_error): Pass &global_options to
	handle_generated_option.
	* opts.h (struct cl_option): Change flag_var to flag_var_offset.
	(cl_option_handler_func.handler): Take gcc_options parameter.
	(option_enabled, get_option_state, set_option, handle_option,
	handle_generated_option, read_cmdline_option): Take gcc_options
	parameters.
	* toplev.c (optimize, optimize_size): Remove.
	(print_switch_values): Pass &global_options to option_enabled.
	(option_affects_pch_p): Use option_flag_var.  Pass &global_options
	to get_option_state.
	(general_init): Initialize global_dc->option_state.
	* tree.c (build_optimization_node): Pass &global_options to
	cl_optimization_save.
	(build_target_option_node): Pass &global_options to
	cl_target_option_save.

c-family:
2010-09-30  Joseph Myers  <joseph@codesourcery.com>

	* c-common.c (handle_optimize_attribute): Pass &global_options to
	cl_optimization_save and cl_optimization_restore.
	* c-opts.c (c_common_handle_option): Pass &global_options to
	handle_generated_option.
	* c-pragma.c (handle_pragma_diagnostic): Use option_flag_var.
	(handle_pragma_pop_options, handle_pragma_reset_options): Pass
	&global_options to cl_optimization_restore.
Richard Guenther - Sept. 30, 2010, 1:08 p.m.
On Thu, Sep 30, 2010 at 2:48 PM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> This patch continues moving towards the explicit use of structures in
> option processing instead of implicit use of global state.
>
> * The optimize and optimize_size variables move into the gcc_options
>  structure (so requiring the changes to files that redeclare them or
>  that have function parameters with those names).
>
> * The table of options no longer stores pointers to variables or
>  fields in global_options in which to store values; it stores
>  structure offsets instead.  (Where static variables in options.c
>  were previously used to track state of some target options, there
>  are now structure fields, whose names get defined as macros to
>  prevent accidental use.)
>
> * Functions in options.c (the generated file) generally no longer use
>  global state implicitly, but get pointers to gcc_options structures
>  passed in.
>
> * Similarly, functions in opts-common.c do not use global state
>  implicitly.  The exceptions, to be fixed in subsequent patches, are
>  (a) checks for target_flags and consequent setting of
>  target_flags_explicit (to be fixed by using a pointer to a structure
>  that records which options have been used explicitly, so replacing
>  target_flags_explicit, various similar variables that are set by
>  special code in option handlers and various uses of -1 or 2 as
>  initial values) and (b) use of global_dc for setting diagnostic
>  state (to be fixed by passing an explicit diagnostic context pointer
>  as needed, so that processing options for other gcc_options
>  structures need not affect global diagnostic state).  Some functions
>  in opts.c are fixed similarly.
>
> * The interface opts-common.c uses to option handlers passes a
>  gcc_options pointer explicitly.  Where option handlers are not ready
>  for this, appropriate assertions that the pointer points to
>  global_options are inserted.  In due course common and target
>  handlers will be prepared to take pointers to other structures and
>  this assertion removed in those cases; I expect it can stay for
>  language option handlers which should not need to become available
>  in the driver or be used in multilib selection.
>
> Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  Also
> tested building cc1 for the following targets (where "optimize"
> declarations were removed from target headers): pdp11-none
> powerpc-eabi sh-elf xtensa-elf.  OK to commit?

Ok.

Thanks,
Richard.

> 2010-09-30  Joseph Myers  <joseph@codesourcery.com>
>
>        * opt-functions.awk (static_var): Update comment.
>        (var_ref): Return offsetof expression or -1, not variable address.
>        * optc-gen.awk: Generate structure field initializers instead of
>        static variables.  Expect -1 for missing variables instead of null
>        pointer.  Add gcc_options parameters to generated functions.
>        * opth-gen.awk: Generate structure fields for static variables.
>        Add gcc_options parameters to generated functions.
>        * common.opt (optimize, optimize_size): Add variables.
>        * config/i386/i386-c.c (ix86_pragma_target_parse): Pass
>        &global_options to cl_target_option_restore.
>        * config/i386/i386.c (ix86_valid_target_attribute_p): Pass
>        &global_options to cl_optimization_restore, cl_target_option_save
>        and cl_target_option_restore.
>        (ix86_set_current_function): Pass &global_options to
>        cl_target_option_restore.
>        * config/pdp11/pdp11.h (optimize): Remove.
>        * config/rs6000/rs6000.h (optimize): Remove.
>        * config/sh/sh.h (optimize): Remove.
>        * config/xtensa/xtensa.h (optimize): Remove.
>        * coretypes.h (struct gcc_options): Declare.
>        * diagnostic.c (diagnostic_initialize): Initialize
>        context->option_state.
>        (diagnostic_report_diagnostic): Pass option_state to
>        option_enabled hook.
>        * diagnostic.h (diagnostic_context.option_enabled): Add void *
>        parameter.
>        (diagnostic_context.option_state): New field.
>        * final.c (final_start_function, final, final_scan_insn): Rename
>        optimize parameter to optimize_p.
>        * flags.h (optimize, optimize_size): Remove.
>        * function.c (invoke_set_current_function_hook): Pass
>        &global_options to cl_optimization_restore.
>        * gcc.c (driver_handle_option): Take gcc_options parameter.
>        Assert that it is &global_options.
>        (process_command): Pass &global_options to read_cmdline_option.
>        * ipa-pure-const.c (suggest_attribute): Pass &global_options to
>        option_enabled.
>        * lto-opts.c (lto_reissue_options): Use option_flag_var.  Pass
>        &global_options to set_option.
>        * opts-common.c (handle_option, handle_generated_option,
>        read_cmdline_option, set_option): Take explicit gcc_options
>        parameters.  Use option_flag_var.
>        (option_flag_var): New.
>        * opts.c (common_handle_option, lang_handle_option,
>        target_handle_option): Take gcc_options parameter.  Assert that it
>        is &global_options.
>        (read_cmdline_options): Pass &global_options to
>        read_cmdline_option.
>        (print_filtered_help): Use option_flag_var.  Pass &global_options
>        to option_enabled.
>        (common_handle_option): Use option_flag_var.
>        (option_enabled): Take opts parameter.  Use option_flag_var.
>        (get_option_state): Take gcc_options parameter.  Use
>        option_flag_var.  Pass gcc_options parameter to option_enabled.
>        (enable_warning_as_error): Pass &global_options to
>        handle_generated_option.
>        * opts.h (struct cl_option): Change flag_var to flag_var_offset.
>        (cl_option_handler_func.handler): Take gcc_options parameter.
>        (option_enabled, get_option_state, set_option, handle_option,
>        handle_generated_option, read_cmdline_option): Take gcc_options
>        parameters.
>        * toplev.c (optimize, optimize_size): Remove.
>        (print_switch_values): Pass &global_options to option_enabled.
>        (option_affects_pch_p): Use option_flag_var.  Pass &global_options
>        to get_option_state.
>        (general_init): Initialize global_dc->option_state.
>        * tree.c (build_optimization_node): Pass &global_options to
>        cl_optimization_save.
>        (build_target_option_node): Pass &global_options to
>        cl_target_option_save.
>
> c-family:
> 2010-09-30  Joseph Myers  <joseph@codesourcery.com>
>
>        * c-common.c (handle_optimize_attribute): Pass &global_options to
>        cl_optimization_save and cl_optimization_restore.
>        * c-opts.c (c_common_handle_option): Pass &global_options to
>        handle_generated_option.
>        * c-pragma.c (handle_pragma_diagnostic): Use option_flag_var.
>        (handle_pragma_pop_options, handle_pragma_reset_options): Pass
>        &global_options to cl_optimization_restore.
>
> Index: gcc/flags.h
> ===================================================================
> --- gcc/flags.h (revision 164724)
> +++ gcc/flags.h (working copy)
> @@ -107,14 +107,6 @@ struct visibility_flags
>  /* Global visibility options.  */
>  extern struct visibility_flags visibility_options;
>
> -/* Nonzero means do optimizations.  -opt.  */
> -
> -extern int optimize;
> -
> -/* Nonzero means optimize for size.  -Os.  */
> -
> -extern int optimize_size;
> -
>  /* True if this is the LTO front end (lto1).  This is used to disable
>    gimple generation and lowering passes that are normally run on the
>    output of a front end.  These passes must be bypassed for lto since
> Index: gcc/opts-common.c
> ===================================================================
> --- gcc/opts-common.c   (revision 164724)
> +++ gcc/opts-common.c   (working copy)
> @@ -799,12 +799,13 @@ keep:
>  }
>
>  /* Handle option DECODED for the language indicated by LANG_MASK,
> -   using the handlers in HANDLERS.  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.  KIND is
> +   the diagnostic_t if this is a diagnostics option, DK_UNSPECIFIED
> +   otherwise.  Returns false if the switch was invalid.  */
>
>  bool
> -handle_option (const struct cl_decoded_option *decoded,
> +handle_option (struct gcc_options *opts,
> +              const struct cl_decoded_option *decoded,
>               unsigned int lang_mask, int kind,
>               const struct cl_option_handlers *handlers)
>  {
> @@ -812,15 +813,16 @@ handle_option (const struct cl_decoded_o
>   const char *arg = decoded->arg;
>   int value = decoded->value;
>   const struct cl_option *option = &cl_options[opt_index];
> +  void *flag_var = option_flag_var (opt_index, opts);
>   size_t i;
>
> -  if (option->flag_var)
> -    set_option (opt_index, value, arg, kind);
> +  if (flag_var)
> +    set_option (opts, 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 (decoded,
> +       if (!handlers->handlers[i].handler (opts, decoded,
>                                            lang_mask, kind, handlers))
>          return false;
>        else
> @@ -837,14 +839,15 @@ handle_option (const struct cl_decoded_o
>    command line.  */
>
>  bool
> -handle_generated_option (size_t opt_index, const char *arg, int value,
> +handle_generated_option (struct gcc_options *opts, 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 (&decoded, lang_mask, kind, handlers);
> +  return handle_option (opts, &decoded, lang_mask, kind, handlers);
>  }
>
>  /* Fill in *DECODED with an option described by OPT_INDEX, ARG and
> @@ -903,10 +906,11 @@ generate_option_input_file (const char *
>  }
>
>  /* Handle the switch DECODED for the language indicated by LANG_MASK,
> -   using the handlers in *HANDLERS.  */
> +   using the handlers in *HANDLERS and setting fields in OPTS.  */
>
>  void
> -read_cmdline_option (struct cl_decoded_option *decoded,
> +read_cmdline_option (struct gcc_options *opts,
> +                    struct cl_decoded_option *decoded,
>                     unsigned int lang_mask,
>                     const struct cl_option_handlers *handlers)
>  {
> @@ -959,45 +963,47 @@ read_cmdline_option (struct cl_decoded_o
>
>   gcc_assert (!decoded->errors);
>
> -  if (!handle_option (decoded, lang_mask, DK_UNSPECIFIED, handlers))
> +  if (!handle_option (opts, decoded, lang_mask, DK_UNSPECIFIED, handlers))
>     error ("unrecognized command line option %qs", opt);
>  }
>
> -/* Set any variable for option OPT_INDEX according to VALUE and ARG,
> +/* Set any field in OPTS for option OPT_INDEX according to VALUE and ARG,
>    diagnostic kind KIND.  */
>
>  void
> -set_option (int opt_index, int value, const char *arg, int kind)
> +set_option (struct gcc_options *opts, 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);
>
> -  if (!option->flag_var)
> +  if (!flag_var)
>     return;
>
>   switch (option->var_type)
>     {
>     case CLVC_BOOLEAN:
> -       *(int *) option->flag_var = value;
> +       *(int *) flag_var = value;
>        break;
>
>     case CLVC_EQUAL:
> -       *(int *) option->flag_var = (value
> -                                    ? option->var_value
> -                                    : !option->var_value);
> +       *(int *) 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;
> +         *(int *) flag_var |= option->var_value;
>        else
> -         *(int *) option->flag_var &= ~option->var_value;
> -       if (option->flag_var == &target_flags)
> +         *(int *) flag_var &= ~option->var_value;
> +       if (flag_var == &target_flags)
>          target_flags_explicit |= option->var_value;
>        break;
>
>     case CLVC_STRING:
> -       *(const char **) option->flag_var = arg;
> +       *(const char **) flag_var = arg;
>        break;
>     }
>
> @@ -1005,3 +1011,16 @@ set_option (int opt_index, int value, co
>     diagnostic_classify_diagnostic (global_dc, opt_index, (diagnostic_t) kind,
>                                    UNKNOWN_LOCATION);
>  }
> +
> +/* Return the address of the flag variable for option OPT_INDEX in
> +   options structure OPTS, or NULL if there is no flag variable.  */
> +
> +void *
> +option_flag_var (int opt_index, struct gcc_options *opts)
> +{
> +  const struct cl_option *option = &cl_options[opt_index];
> +
> +  if (option->flag_var_offset == (unsigned short) -1)
> +    return NULL;
> +  return (void *)(((char *) opts) + option->flag_var_offset);
> +}
> Index: gcc/c-family/c-opts.c
> ===================================================================
> --- gcc/c-family/c-opts.c       (revision 164724)
> +++ gcc/c-family/c-opts.c       (working copy)
> @@ -436,7 +436,7 @@ c_common_handle_option (size_t scode, co
>     case OPT_Wall:
>       warn_unused = value;
>       set_Wformat (value);
> -      handle_generated_option (OPT_Wimplicit, NULL, value,
> +      handle_generated_option (&global_options, OPT_Wimplicit, NULL, value,
>                               c_family_lang_mask, kind, handlers);
>       warn_char_subscripts = value;
>       warn_missing_braces = value;
> @@ -530,10 +530,12 @@ 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 (OPT_Wimplicit_int, NULL, value,
> +       handle_generated_option (&global_options, OPT_Wimplicit_int,
> +                                NULL, value,
>                                 c_family_lang_mask, kind, handlers);
>       if (warn_implicit_function_declaration == -1)
> -       handle_generated_option (OPT_Wimplicit_function_declaration, NULL,
> +       handle_generated_option (&global_options,
> +                                OPT_Wimplicit_function_declaration, NULL,
>                                 value, c_family_lang_mask, kind, handlers);
>       break;
>
> Index: gcc/c-family/c-common.c
> ===================================================================
> --- gcc/c-family/c-common.c     (revision 164724)
> +++ gcc/c-family/c-common.c     (working copy)
> @@ -7831,12 +7831,13 @@ handle_optimize_attribute (tree *node, t
>       tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
>
>       /* Save current options.  */
> -      cl_optimization_save (&cur_opts);
> +      cl_optimization_save (&cur_opts, &global_options);
>
>       /* If we previously had some optimization options, use them as the
>         default.  */
>       if (old_opts)
> -       cl_optimization_restore (TREE_OPTIMIZATION (old_opts));
> +       cl_optimization_restore (&global_options,
> +                                TREE_OPTIMIZATION (old_opts));
>
>       /* Parse options, and update the vector.  */
>       parse_optimize_options (args, true);
> @@ -7844,7 +7845,7 @@ handle_optimize_attribute (tree *node, t
>        = build_optimization_node ();
>
>       /* Restore current options.  */
> -      cl_optimization_restore (&cur_opts);
> +      cl_optimization_restore (&global_options, &cur_opts);
>     }
>
>   return NULL_TREE;
> Index: gcc/c-family/c-pragma.c
> ===================================================================
> --- gcc/c-family/c-pragma.c     (revision 164724)
> +++ gcc/c-family/c-pragma.c     (working copy)
> @@ -1,6 +1,6 @@
>  /* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
>    Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
> -   2006, 2007, 2008 Free Software Foundation, Inc.
> +   2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
>
>  This file is part of GCC.
>
> @@ -751,13 +751,15 @@ handle_pragma_diagnostic(cpp_reader *ARG
>   for (option_index = 0; option_index < cl_options_count; option_index++)
>     if (strcmp (cl_options[option_index].opt_text, option_string) == 0)
>       {
> +       void *flag_var = option_flag_var (option_index, &global_options);
> +
>        /* This overrides -Werror, for example.  */
>        diagnostic_classify_diagnostic (global_dc, option_index, kind, input_location);
>        /* This makes sure the option is enabled, like -Wfoo would do.  */
>        if (cl_options[option_index].var_type == CLVC_BOOLEAN
> -           && cl_options[option_index].flag_var
> +           && flag_var
>            && kind != DK_IGNORED)
> -           *(int *) cl_options[option_index].flag_var = 1;
> +           *(int *) flag_var = 1;
>        return;
>       }
>   GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
> @@ -983,7 +985,8 @@ handle_pragma_pop_options (cpp_reader *A
>   if (p->optimize_binary != optimization_current_node)
>     {
>       tree old_optimize = optimization_current_node;
> -      cl_optimization_restore (TREE_OPTIMIZATION (p->optimize_binary));
> +      cl_optimization_restore (&global_options,
> +                              TREE_OPTIMIZATION (p->optimize_binary));
>       c_cpp_builtins_optimize_pragma (parse_in, old_optimize,
>                                      p->optimize_binary);
>       optimization_current_node = p->optimize_binary;
> @@ -1020,7 +1023,8 @@ handle_pragma_reset_options (cpp_reader
>   if (new_optimize != optimization_current_node)
>     {
>       tree old_optimize = optimization_current_node;
> -      cl_optimization_restore (TREE_OPTIMIZATION (new_optimize));
> +      cl_optimization_restore (&global_options,
> +                              TREE_OPTIMIZATION (new_optimize));
>       c_cpp_builtins_optimize_pragma (parse_in, old_optimize, new_optimize);
>       optimization_current_node = new_optimize;
>     }
> Index: gcc/tree.c
> ===================================================================
> --- gcc/tree.c  (revision 164724)
> +++ gcc/tree.c  (working copy)
> @@ -10750,7 +10750,8 @@ build_optimization_node (void)
>
>   /* Use the cache of optimization nodes.  */
>
> -  cl_optimization_save (TREE_OPTIMIZATION (cl_optimization_node));
> +  cl_optimization_save (TREE_OPTIMIZATION (cl_optimization_node),
> +                       &global_options);
>
>   slot = htab_find_slot (cl_option_hash_table, cl_optimization_node, INSERT);
>   t = (tree) *slot;
> @@ -10777,7 +10778,8 @@ build_target_option_node (void)
>
>   /* Use the cache of optimization nodes.  */
>
> -  cl_target_option_save (TREE_TARGET_OPTION (cl_target_option_node));
> +  cl_target_option_save (TREE_TARGET_OPTION (cl_target_option_node),
> +                        &global_options);
>
>   slot = htab_find_slot (cl_option_hash_table, cl_target_option_node, INSERT);
>   t = (tree) *slot;
> Index: gcc/diagnostic.c
> ===================================================================
> --- gcc/diagnostic.c    (revision 164724)
> +++ gcc/diagnostic.c    (working copy)
> @@ -113,6 +113,7 @@ diagnostic_initialize (diagnostic_contex
>   diagnostic_starter (context) = default_diagnostic_starter;
>   diagnostic_finalizer (context) = default_diagnostic_finalizer;
>   context->option_enabled = NULL;
> +  context->option_state = NULL;
>   context->option_name = NULL;
>   context->last_module = 0;
>   context->x_data = NULL;
> @@ -435,7 +436,8 @@ diagnostic_report_diagnostic (diagnostic
>
>       /* This tests if the user provided the appropriate -Wfoo or
>         -Wno-foo option.  */
> -      if (! context->option_enabled (diagnostic->option_index))
> +      if (! context->option_enabled (diagnostic->option_index,
> +                                    context->option_state))
>        return false;
>
>       /* This tests for #pragma diagnostic changes.  */
> Index: gcc/diagnostic.h
> ===================================================================
> --- gcc/diagnostic.h    (revision 164724)
> +++ gcc/diagnostic.h    (working copy)
> @@ -146,7 +146,11 @@ struct diagnostic_context
>
>   /* Client hook to say whether the option controlling a diagnostic is
>      enabled.  Returns nonzero if enabled, zero if disabled.  */
> -  int (*option_enabled) (int);
> +  int (*option_enabled) (int, void *);
> +
> +  /* Client information to pass as second argument to
> +     option_enabled.  */
> +  void *option_state;
>
>   /* Client hook to return the name of an option that controls a
>      diagnostic.  Returns malloced memory.  The first diagnostic_t
> Index: gcc/final.c
> ===================================================================
> --- gcc/final.c (revision 164724)
> +++ gcc/final.c (working copy)
> @@ -1512,12 +1512,12 @@ dwarf2_debug_info_emitted_p (tree decl)
>
>    FIRST is the first insn of the rtl for the function being compiled.
>    FILE is the file to write assembler code to.
> -   OPTIMIZE is nonzero if we should eliminate redundant
> +   OPTIMIZE_P is nonzero if we should eliminate redundant
>      test and compare insns.  */
>
>  void
>  final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file,
> -                     int optimize ATTRIBUTE_UNUSED)
> +                     int optimize_p ATTRIBUTE_UNUSED)
>  {
>   block_depth = 0;
>
> @@ -1662,7 +1662,7 @@ final_end_function (void)
>    For description of args, see `final_start_function', above.  */
>
>  void
> -final (rtx first, FILE *file, int optimize)
> +final (rtx first, FILE *file, int optimize_p)
>  {
>   rtx insn;
>   int max_uid = 0;
> @@ -1677,7 +1677,7 @@ final (rtx first, FILE *file, int optimi
>  #ifdef HAVE_cc0
>       /* If CC tracking across branches is enabled, record the insn which
>         jumps to each branch only reached from one place.  */
> -      if (optimize && JUMP_P (insn))
> +      if (optimize_p && JUMP_P (insn))
>        {
>          rtx lab = JUMP_LABEL (insn);
>          if (lab && LABEL_NUSES (lab) == 1)
> @@ -1707,7 +1707,7 @@ final (rtx first, FILE *file, int optimi
>        insn_current_address = INSN_ADDRESSES (INSN_UID (insn));
>  #endif /* HAVE_ATTR_length */
>
> -      insn = final_scan_insn (insn, file, optimize, 0, &seen);
> +      insn = final_scan_insn (insn, file, optimize_p, 0, &seen);
>     }
>  }
>
> @@ -1803,7 +1803,7 @@ call_from_call_insn (rtx insn)
>    first.  */
>
>  rtx
> -final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
> +final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
>                 int nopeepholes ATTRIBUTE_UNUSED, int *seen)
>  {
>  #ifdef HAVE_cc0
> @@ -2327,7 +2327,7 @@ final_scan_insn (rtx insn, FILE *file, i
>           and the next statement should reexamine the variable
>           to compute the condition codes.  */
>
> -       if (optimize)
> +       if (optimize_p)
>          {
>            if (set
>                && GET_CODE (SET_DEST (set)) == CC0
> @@ -2512,7 +2512,7 @@ final_scan_insn (rtx insn, FILE *file, i
>  #ifdef HAVE_peephole
>        /* Do machine-specific peephole optimizations if desired.  */
>
> -       if (optimize && !flag_no_peephole && !nopeepholes)
> +       if (optimize_p && !flag_no_peephole && !nopeepholes)
>          {
>            rtx next = peephole (insn);
>            /* When peepholing, if there were notes within the peephole,
> @@ -2523,7 +2523,7 @@ final_scan_insn (rtx insn, FILE *file, i
>
>                for (note = NEXT_INSN (insn); note != next;
>                     note = NEXT_INSN (note))
> -                 final_scan_insn (note, file, optimize, nopeepholes, seen);
> +                 final_scan_insn (note, file, optimize_p, nopeepholes, seen);
>
>                /* Put the notes in the proper position for a later
>                   rescan.  For example, the SH target can do this
> Index: gcc/gcc.c
> ===================================================================
> --- gcc/gcc.c   (revision 164724)
> +++ gcc/gcc.c   (working copy)
> @@ -3150,7 +3150,8 @@ static int last_language_n_infiles;
>    handle_option.  */
>
>  static bool
> -driver_handle_option (const struct cl_decoded_option *decoded,
> +driver_handle_option (struct gcc_options *opts,
> +                     const struct cl_decoded_option *decoded,
>                      unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
>                      const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
>  {
> @@ -3161,6 +3162,7 @@ driver_handle_option (const struct cl_de
>   bool validated = false;
>   bool do_save = true;
>
> +  gcc_assert (opts == &global_options);
>   gcc_assert (kind == DK_UNSPECIFIED);
>
>   switch (opt_index)
> @@ -3801,7 +3803,8 @@ process_command (unsigned int decoded_op
>          continue;
>        }
>
> -      read_cmdline_option (decoded_options + j, CL_DRIVER, &handlers);
> +      read_cmdline_option (&global_options, 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 164724)
> +++ gcc/toplev.c        (working copy)
> @@ -174,22 +174,6 @@ enum graph_dump_types graph_dump_format;
>
>  const char *asm_file_name;
>
> -/* Nonzero means do optimizations.  -O.
> -   Particular numeric values stand for particular amounts of optimization;
> -   thus, -O2 stores 2 here.  However, the optimizations beyond the basic
> -   ones are not controlled directly by this variable.  Instead, they are
> -   controlled by individual `flag_...' variables that are defaulted
> -   based on this variable.  */
> -
> -int optimize = 0;
> -
> -/* Nonzero means optimize for size.  -Os.
> -   The only valid values are zero and nonzero. When optimize_size is
> -   nonzero, optimize defaults to 2, but certain individual code
> -   bloating optimizations are disabled.  */
> -
> -int optimize_size = 0;
> -
>  /* True if this is the lto front end.  This is used to disable
>    gimple generation and lowering passes that are normally run on the
>    output of a front end.  These passes must be bypassed for lto since
> @@ -1316,7 +1300,7 @@ print_switch_values (print_switch_fn_typ
>
>   for (j = 0; j < cl_options_count; j++)
>     if ((cl_options[j].flags & CL_REPORT)
> -       && option_enabled (j) > 0)
> +       && option_enabled (j, &global_options) > 0)
>       pos = print_single_switch (print_fn, pos,
>                                 SWITCH_TYPE_ENABLED, cl_options[j].opt_text);
>
> @@ -1395,10 +1379,10 @@ option_affects_pch_p (int option, struct
>  {
>   if ((cl_options[option].flags & CL_TARGET) == 0)
>     return false;
> -  if (cl_options[option].flag_var == &target_flags)
> +  if (option_flag_var (option, &global_options) == &target_flags)
>     if (targetm.check_pch_target_flags)
>       return false;
> -  return get_option_state (option, state);
> +  return get_option_state (&global_options, option, state);
>  }
>
>  /* Default version of get_pch_validity.
> @@ -1686,6 +1670,7 @@ general_init (const char *argv0)
>   global_dc->show_column = flag_show_column;
>   global_dc->internal_error = plugins_internal_error_function;
>   global_dc->option_enabled = option_enabled;
> +  global_dc->option_state = &global_options;
>   global_dc->option_name = option_name;
>
>   /* Trap fatal signals, e.g. SIGSEGV, and convert them to ICE messages.  */
> Index: gcc/ipa-pure-const.c
> ===================================================================
> --- gcc/ipa-pure-const.c        (revision 164724)
> +++ gcc/ipa-pure-const.c        (working copy)
> @@ -138,7 +138,7 @@ suggest_attribute (int option, tree decl
>                   struct pointer_set_t *warned_about,
>                   const char * attrib_name)
>  {
> -  if (!option_enabled (option))
> +  if (!option_enabled (option, &global_options))
>     return warned_about;
>   if (TREE_THIS_VOLATILE (decl)
>       || (known_finite && function_always_visible_to_compiler_p (decl)))
> Index: gcc/opts.c
> ===================================================================
> --- gcc/opts.c  (revision 164724)
> +++ gcc/opts.c  (working copy)
> @@ -376,7 +376,8 @@ bool flag_warn_unused_result = false;
>  const char **in_fnames;
>  unsigned num_in_fnames;
>
> -static bool common_handle_option (const struct cl_decoded_option *decoded,
> +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 *);
> @@ -515,10 +516,12 @@ post_handling_callback (const struct cl_
>    handle_option.  */
>
>  static bool
> -lang_handle_option (const struct cl_decoded_option *decoded,
> +lang_handle_option (struct gcc_options *opts,
> +                   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 (decoded->canonical_option_num_elements <= 2);
>   return lang_hooks.handle_option (decoded->opt_index, decoded->arg,
>                                   decoded->value, kind, handlers);
> @@ -528,10 +531,12 @@ lang_handle_option (const struct cl_deco
>    handle_option.  */
>
>  static bool
> -target_handle_option (const struct cl_decoded_option *decoded,
> +target_handle_option (struct gcc_options *opts,
> +                     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 (decoded->canonical_option_num_elements <= 2);
>   gcc_assert (kind == DK_UNSPECIFIED);
>   return targetm.handle_option (decoded->opt_index, decoded->arg,
> @@ -644,7 +649,8 @@ read_cmdline_options (struct cl_decoded_
>          continue;
>        }
>
> -      read_cmdline_option (decoded_options + i, lang_mask, handlers);
> +      read_cmdline_option (&global_options, decoded_options + i,
> +                          lang_mask, handlers);
>     }
>  }
>
> @@ -1254,28 +1260,30 @@ print_filtered_help (unsigned int includ
>         with an option to be an indication of its current setting.  */
>       if (!quiet_flag)
>        {
> +         void *flag_var = option_flag_var (i, &global_options);
> +
>          if (len < (LEFT_COLUMN + 2))
>            strcpy (new_help, "\t\t");
>          else
>            strcpy (new_help, "\t");
>
> -         if (option->flag_var != NULL)
> +         if (flag_var != NULL)
>            {
>              if (option->flags & CL_JOINED)
>                {
>                  if (option->var_type == CLVC_STRING)
>                    {
> -                     if (* (const char **) option->flag_var != NULL)
> +                     if (* (const char **) flag_var != NULL)
>                        snprintf (new_help + strlen (new_help),
>                                  sizeof (new_help) - strlen (new_help),
> -                                 * (const char **) option->flag_var);
> +                                 * (const char **) flag_var);
>                    }
>                  else
>                    sprintf (new_help + strlen (new_help),
> -                            "%#x", * (int *) option->flag_var);
> +                            "%#x", * (int *) flag_var);
>                }
>              else
> -               strcat (new_help, option_enabled (i)
> +               strcat (new_help, option_enabled (i, &global_options)
>                        ? _("[enabled]") : _("[disabled]"));
>            }
>
> @@ -1423,7 +1431,8 @@ print_specific_help (unsigned int includ
>    DECODED->value assigned to a variable, it happens automatically.  */
>
>  static bool
> -common_handle_option (const struct cl_decoded_option *decoded,
> +common_handle_option (struct gcc_options *opts,
> +                     const struct cl_decoded_option *decoded,
>                      unsigned int lang_mask, int kind ATTRIBUTE_UNUSED,
>                      const struct cl_option_handlers *handlers)
>  {
> @@ -1433,6 +1442,7 @@ common_handle_option (const struct cl_de
>   static bool verbose = false;
>   enum opt_code code = (enum opt_code) scode;
>
> +  gcc_assert (opts == &global_options);
>   gcc_assert (decoded->canonical_option_num_elements <= 2);
>
>   switch (code)
> @@ -2102,7 +2112,7 @@ common_handle_option (const struct cl_de
>     default:
>       /* If the flag was handled in a standard way, assume the lack of
>         processing here is intentional.  */
> -      gcc_assert (cl_options[scode].flag_var);
> +      gcc_assert (option_flag_var (scode, opts));
>       break;
>     }
>
> @@ -2258,28 +2268,30 @@ set_debug_level (enum debug_info_type ty
>     }
>  }
>
> -/* Return 1 if OPTION is enabled, 0 if it is disabled, or -1 if it isn't
> -   a simple on-off switch.  */
> +/* Return 1 if option OPT_IDX is enabled in OPTS, 0 if it is disabled,
> +   or -1 if it isn't a simple on-off switch.  */
>
>  int
> -option_enabled (int opt_idx)
> +option_enabled (int opt_idx, void *opts)
>  {
>   const struct cl_option *option = &(cl_options[opt_idx]);
> +  struct gcc_options *optsg = (struct gcc_options *) opts;
> +  void *flag_var = option_flag_var (opt_idx, optsg);
>
> -  if (option->flag_var)
> +  if (flag_var)
>     switch (option->var_type)
>       {
>       case CLVC_BOOLEAN:
> -       return *(int *) option->flag_var != 0;
> +       return *(int *) flag_var != 0;
>
>       case CLVC_EQUAL:
> -       return *(int *) option->flag_var == option->var_value;
> +       return *(int *) flag_var == option->var_value;
>
>       case CLVC_BIT_CLEAR:
> -       return (*(int *) option->flag_var & option->var_value) == 0;
> +       return (*(int *) flag_var & option->var_value) == 0;
>
>       case CLVC_BIT_SET:
> -       return (*(int *) option->flag_var & option->var_value) != 0;
> +       return (*(int *) flag_var & option->var_value) != 0;
>
>       case CLVC_STRING:
>        break;
> @@ -2287,32 +2299,35 @@ option_enabled (int opt_idx)
>   return -1;
>  }
>
> -/* Fill STATE with the current state of option OPTION.  Return true if
> -   there is some state to store.  */
> +/* Fill STATE with the current state of option OPTION in OPTS.  Return
> +   true if there is some state to store.  */
>
>  bool
> -get_option_state (int option, struct cl_option_state *state)
> +get_option_state (struct gcc_options *opts, int option,
> +                 struct cl_option_state *state)
>  {
> -  if (cl_options[option].flag_var == 0)
> +  void *flag_var = option_flag_var (option, opts);
> +
> +  if (flag_var == 0)
>     return false;
>
>   switch (cl_options[option].var_type)
>     {
>     case CLVC_BOOLEAN:
>     case CLVC_EQUAL:
> -      state->data = cl_options[option].flag_var;
> +      state->data = flag_var;
>       state->size = sizeof (int);
>       break;
>
>     case CLVC_BIT_CLEAR:
>     case CLVC_BIT_SET:
> -      state->ch = option_enabled (option);
> +      state->ch = option_enabled (option, opts);
>       state->data = &state->ch;
>       state->size = 1;
>       break;
>
>     case CLVC_STRING:
> -      state->data = *(const char **) cl_options[option].flag_var;
> +      state->data = *(const char **) flag_var;
>       if (state->data == 0)
>        state->data = "";
>       state->size = strlen ((const char *) state->data) + 1;
> @@ -2369,7 +2384,8 @@ enable_warning_as_error (const char *arg
>
>          /* -Werror=foo implies -Wfoo.  */
>          if (option->var_type == CLVC_BOOLEAN)
> -           handle_generated_option (option_index, NULL, value, lang_mask,
> +           handle_generated_option (&global_options, option_index,
> +                                    NULL, value, lang_mask,
>                                     (int)kind, handlers);
>
>          if (warning_as_error_callback)
> Index: gcc/opts.h
> ===================================================================
> --- gcc/opts.h  (revision 164724)
> +++ gcc/opts.h  (working copy)
> @@ -53,7 +53,7 @@ struct cl_option
>   unsigned char opt_len;
>   int neg_index;
>   unsigned int flags;
> -  void *flag_var;
> +  unsigned short flag_var_offset;
>   enum cl_var_type var_type;
>   int var_value;
>  };
> @@ -156,7 +156,8 @@ struct cl_decoded_option
>  struct cl_option_handler_func
>  {
>   /* The function called to handle the option.  */
> -  bool (*handler) (const struct cl_decoded_option *decoded,
> +  bool (*handler) (struct gcc_options *opts,
> +                  const struct cl_decoded_option *decoded,
>                   unsigned int lang_mask, int kind,
>                   const struct cl_option_handlers *handlers);
>
> @@ -209,13 +210,18 @@ extern void decode_cmdline_options_to_ar
>  extern void decode_options (unsigned int argc, const char **argv,
>                            struct cl_decoded_option **decoded_options,
>                            unsigned int *decoded_options_count);
> -extern int option_enabled (int opt_idx);
> -extern bool get_option_state (int, struct cl_option_state *);
> -extern void set_option (int opt_index, int value, const char *arg, int);
> -bool handle_option (const struct cl_decoded_option *decoded,
> +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 *option_flag_var (int opt_index, struct gcc_options *opts);
> +bool handle_option (struct gcc_options *opts,
> +                   const struct cl_decoded_option *decoded,
>                    unsigned int lang_mask, int kind,
>                    const struct cl_option_handlers *handlers);
> -bool handle_generated_option (size_t opt_index, const char *arg, int value,
> +bool handle_generated_option (struct gcc_options *opts,
> +                             size_t opt_index, const char *arg, int value,
>                              unsigned int lang_mask, int kind,
>                              const struct cl_option_handlers *handlers);
>  void generate_option (size_t opt_index, const char *arg, int value,
> @@ -223,7 +229,8 @@ void generate_option (size_t opt_index,
>                      struct cl_decoded_option *decoded);
>  void generate_option_input_file (const char *file,
>                                 struct cl_decoded_option *decoded);
> -extern void read_cmdline_option (struct cl_decoded_option *decoded,
> +extern void read_cmdline_option (struct gcc_options *opts,
> +                                struct cl_decoded_option *decoded,
>                                 unsigned int lang_mask,
>                                 const struct cl_option_handlers *handlers);
>  extern void register_warning_as_error_callback (void (*callback) (int));
> Index: gcc/optc-gen.awk
> ===================================================================
> --- gcc/optc-gen.awk    (revision 164724)
> +++ gcc/optc-gen.awk    (working copy)
> @@ -131,15 +131,14 @@ for (i = 0; i < n_opts; i++) {
>
>        var_seen[name] = 1;
>  }
> -print "};"
> -
> -print ""
> -print "/* Local state variables.  */"
>  for (i = 0; i < n_opts; i++) {
>        name = static_var(opts[i], flags[i]);
> -       if (name != "")
> -               print "static " var_type(flags[i]) name ";"
> +       if (name != "") {
> +               print "  0, /* " name " (private state) */"
> +               print "#undef x_" name
> +       }
>  }
> +print "};"
>  print ""
>
>  print "const char * const lang_names[] =\n{"
> @@ -235,7 +234,7 @@ for (i = 0; i < n_opts; i++) {
>                alias_posarg = nth_arg(1, alias_arg)
>                alias_negarg = nth_arg(2, alias_arg)
>
> -               if (var_ref(opts[i], flags[i]) != "0")
> +               if (var_ref(opts[i], flags[i]) != "-1")
>                        print "#error Alias setting variable"
>
>                if (alias_posarg != "" && alias_negarg == "") {
> @@ -298,7 +297,7 @@ print "#if !defined(GCC_DRIVER) && !defi
>  print "";
>  print "/* Save optimization variables into a structure.  */"
>  print "void";
> -print "cl_optimization_save (struct cl_optimization *ptr)";
> +print "cl_optimization_save (struct cl_optimization *ptr, struct gcc_options *opts)";
>  print "{";
>
>  n_opt_char = 2;
> @@ -345,24 +344,24 @@ for (i = 0; i < n_opts; i++) {
>  for (i = 0; i < n_opt_char; i++) {
>        name = var_opt_char[i];
>        if (var_opt_range[name] != "")
> -               print "  gcc_assert (IN_RANGE (" name ", " var_opt_range[name] "));";
> +               print "  gcc_assert (IN_RANGE (opts->x_" name ", " var_opt_range[name] "));";
>  }
>
>  print "";
>  for (i = 0; i < n_opt_other; i++) {
> -       print "  ptr->x_" var_opt_other[i] " = " var_opt_other[i] ";";
> +       print "  ptr->x_" var_opt_other[i] " = opts->x_" var_opt_other[i] ";";
>  }
>
>  for (i = 0; i < n_opt_int; i++) {
> -       print "  ptr->x_" var_opt_int[i] " = " var_opt_int[i] ";";
> +       print "  ptr->x_" var_opt_int[i] " = opts->x_" var_opt_int[i] ";";
>  }
>
>  for (i = 0; i < n_opt_short; i++) {
> -       print "  ptr->x_" var_opt_short[i] " = " var_opt_short[i] ";";
> +       print "  ptr->x_" var_opt_short[i] " = opts->x_" var_opt_short[i] ";";
>  }
>
>  for (i = 0; i < n_opt_char; i++) {
> -       print "  ptr->x_" var_opt_char[i] " = " var_opt_char[i] ";";
> +       print "  ptr->x_" var_opt_char[i] " = opts->x_" var_opt_char[i] ";";
>  }
>
>  print "}";
> @@ -370,23 +369,23 @@ print "}";
>  print "";
>  print "/* Restore optimization options from a structure.  */";
>  print "void";
> -print "cl_optimization_restore (struct cl_optimization *ptr)";
> +print "cl_optimization_restore (struct gcc_options *opts, struct cl_optimization *ptr)";
>  print "{";
>
>  for (i = 0; i < n_opt_other; i++) {
> -       print "  " var_opt_other[i] " = ptr->x_" var_opt_other[i] ";";
> +       print "  opts->x_" var_opt_other[i] " = ptr->x_" var_opt_other[i] ";";
>  }
>
>  for (i = 0; i < n_opt_int; i++) {
> -       print "  " var_opt_int[i] " = ptr->x_" var_opt_int[i] ";";
> +       print "  opts->x_" var_opt_int[i] " = ptr->x_" var_opt_int[i] ";";
>  }
>
>  for (i = 0; i < n_opt_short; i++) {
> -       print "  " var_opt_short[i] " = ptr->x_" var_opt_short[i] ";";
> +       print "  opts->x_" var_opt_short[i] " = ptr->x_" var_opt_short[i] ";";
>  }
>
>  for (i = 0; i < n_opt_char; i++) {
> -       print "  " var_opt_char[i] " = ptr->x_" var_opt_char[i] ";";
> +       print "  opts->x_" var_opt_char[i] " = ptr->x_" var_opt_char[i] ";";
>  }
>
>  print "  targetm.override_options_after_change ();";
> @@ -442,7 +441,7 @@ print "}";
>  print "";
>  print "/* Save selected option variables into a structure.  */"
>  print "void";
> -print "cl_target_option_save (struct cl_target_option *ptr)";
> +print "cl_target_option_save (struct cl_target_option *ptr, struct gcc_options *opts)";
>  print "{";
>
>  n_target_char = 0;
> @@ -488,7 +487,7 @@ for (i = 0; i < n_target_char; i++) {
>        name = var_target_char[i];
>        if (var_target_range[name] != "") {
>                have_assert = 1;
> -               print "  gcc_assert (IN_RANGE (" name ", " var_target_range[name] "));";
> +               print "  gcc_assert (IN_RANGE (opts->x_" name ", " var_target_range[name] "));";
>        }
>  }
>
> @@ -500,19 +499,19 @@ print "    targetm.target_option.save (p
>  print "";
>
>  for (i = 0; i < n_target_other; i++) {
> -       print "  ptr->x_" var_target_other[i] " = " var_target_other[i] ";";
> +       print "  ptr->x_" var_target_other[i] " = opts->x_" var_target_other[i] ";";
>  }
>
>  for (i = 0; i < n_target_int; i++) {
> -       print "  ptr->x_" var_target_int[i] " = " var_target_int[i] ";";
> +       print "  ptr->x_" var_target_int[i] " = opts->x_" var_target_int[i] ";";
>  }
>
>  for (i = 0; i < n_target_short; i++) {
> -       print "  ptr->x_" var_target_short[i] " = " var_target_short[i] ";";
> +       print "  ptr->x_" var_target_short[i] " = opts->x_" var_target_short[i] ";";
>  }
>
>  for (i = 0; i < n_target_char; i++) {
> -       print "  ptr->x_" var_target_char[i] " = " var_target_char[i] ";";
> +       print "  ptr->x_" var_target_char[i] " = opts->x_" var_target_char[i] ";";
>  }
>
>  print "}";
> @@ -520,23 +519,23 @@ print "}";
>  print "";
>  print "/* Restore selected current options from a structure.  */";
>  print "void";
> -print "cl_target_option_restore (struct cl_target_option *ptr)";
> +print "cl_target_option_restore (struct gcc_options *opts, struct cl_target_option *ptr)";
>  print "{";
>
>  for (i = 0; i < n_target_other; i++) {
> -       print "  " var_target_other[i] " = ptr->x_" var_target_other[i] ";";
> +       print "  opts->x_" var_target_other[i] " = ptr->x_" var_target_other[i] ";";
>  }
>
>  for (i = 0; i < n_target_int; i++) {
> -       print "  " var_target_int[i] " = ptr->x_" var_target_int[i] ";";
> +       print "  opts->x_" var_target_int[i] " = ptr->x_" var_target_int[i] ";";
>  }
>
>  for (i = 0; i < n_target_short; i++) {
> -       print "  " var_target_short[i] " = ptr->x_" var_target_short[i] ";";
> +       print "  opts->x_" var_target_short[i] " = ptr->x_" var_target_short[i] ";";
>  }
>
>  for (i = 0; i < n_target_char; i++) {
> -       print "  " var_target_char[i] " = ptr->x_" var_target_char[i] ";";
> +       print "  opts->x_" var_target_char[i] " = ptr->x_" var_target_char[i] ";";
>  }
>
>  # This must occur after the normal variables in case the code depends on those
> Index: gcc/function.c
> ===================================================================
> --- gcc/function.c      (revision 164724)
> +++ gcc/function.c      (working copy)
> @@ -4254,7 +4254,7 @@ invoke_set_current_function_hook (tree f
>       if (optimization_current_node != opts)
>        {
>          optimization_current_node = opts;
> -         cl_optimization_restore (TREE_OPTIMIZATION (opts));
> +         cl_optimization_restore (&global_options, TREE_OPTIMIZATION (opts));
>        }
>
>       targetm.set_current_function (fndecl);
> Index: gcc/coretypes.h
> ===================================================================
> --- gcc/coretypes.h     (revision 164724)
> +++ gcc/coretypes.h     (working copy)
> @@ -64,6 +64,7 @@ typedef const union tree_node *const_tre
>  typedef const union gimple_statement_d *const_gimple;
>  union section;
>  typedef union section section;
> +struct gcc_options;
>  struct cl_target_option;
>  struct cl_optimization;
>  struct cl_option;
> Index: gcc/opth-gen.awk
> ===================================================================
> --- gcc/opth-gen.awk    (revision 164724)
> +++ gcc/opth-gen.awk    (working copy)
> @@ -115,6 +115,15 @@ for (i = 0; i < n_opts; i++) {
>        print "#define " name " global_options.x_" name
>        print "#endif"
>  }
> +for (i = 0; i < n_opts; i++) {
> +       name = static_var(opts[i], flags[i]);
> +       if (name != "") {
> +               print "#ifndef GENERATOR_FILE"
> +               print "  " var_type(flags[i]) "x_" name ";"
> +               print "#define x_" name " do_not_use"
> +               print "#endif"
> +       }
> +}
>  print "#ifndef GENERATOR_FILE"
>  print "};"
>  print "extern struct gcc_options global_options;"
> @@ -258,19 +267,19 @@ print "};";
>  print "";
>  print "";
>  print "/* Save optimization variables into a structure.  */"
> -print "extern void cl_optimization_save (struct cl_optimization *);";
> +print "extern void cl_optimization_save (struct cl_optimization *, struct gcc_options *);";
>  print "";
>  print "/* Restore optimization variables from a structure.  */";
> -print "extern void cl_optimization_restore (struct cl_optimization *);";
> +print "extern void cl_optimization_restore (struct gcc_options *, struct cl_optimization *);";
>  print "";
>  print "/* Print optimization variables from a structure.  */";
>  print "extern void cl_optimization_print (FILE *, int, struct cl_optimization *);";
>  print "";
>  print "/* Save selected option variables into a structure.  */"
> -print "extern void cl_target_option_save (struct cl_target_option *);";
> +print "extern void cl_target_option_save (struct cl_target_option *, struct gcc_options *);";
>  print "";
>  print "/* Restore selected option variables from a structure.  */"
> -print "extern void cl_target_option_restore (struct cl_target_option *);";
> +print "extern void cl_target_option_restore (struct gcc_options *, struct cl_target_option *);";
>  print "";
>  print "/* Print target option variables from a structure.  */";
>  print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);";
> Index: gcc/common.opt
> ===================================================================
> --- gcc/common.opt      (revision 164724)
> +++ gcc/common.opt      (working copy)
> @@ -26,6 +26,12 @@
>  Variable
>  int target_flags
>
> +Variable
> +int optimize
> +
> +Variable
> +int optimize_size
> +
>  ###
>  Driver
>
> Index: gcc/opt-functions.awk
> ===================================================================
> --- gcc/opt-functions.awk       (revision 164724)
> +++ gcc/opt-functions.awk       (working copy)
> @@ -120,9 +120,9 @@ function needs_state_p(flags)
>                && !flag_set_p("Ignore", flags))
>  }
>
> -# If FLAGS describes an option that needs a static state variable,
> -# return the name of that variable, otherwise return "".  NAME is
> -# the name of the option.
> +# If FLAGS describes an option that needs state without a public
> +# variable name, return the name of that field, minus the initial
> +# "x_", otherwise return "".  NAME is the name of the option.
>  function static_var(name, flags)
>  {
>        if (global_state_p(flags) || !needs_state_p(flags))
> @@ -193,12 +193,12 @@ function var_ref(name, flags)
>  {
>        name = var_name(flags) static_var(name, flags)
>        if (name != "")
> -               return "&" name
> +               return "offsetof (struct gcc_options, x_" name ")"
>        if (opt_args("Mask", flags) != "")
> -               return "&target_flags"
> +               return "offsetof (struct gcc_options, x_target_flags)"
>        if (opt_args("InverseMask", flags) != "")
> -               return "&target_flags"
> -       return "0"
> +               return "offsetof (struct gcc_options, x_target_flags)"
> +       return "-1"
>  }
>
>  # Given the option called NAME return a sanitized version of its name.
> Index: gcc/lto-opts.c
> ===================================================================
> --- gcc/lto-opts.c      (revision 164724)
> +++ gcc/lto-opts.c      (working copy)
> @@ -1,6 +1,6 @@
>  /* LTO IL options.
>
> -   Copyright 2009 Free Software Foundation, Inc.
> +   Copyright 2009, 2010 Free Software Foundation, Inc.
>    Contributed by Simon Baldwin <simonb@google.com>
>
>  This file is part of GCC.
> @@ -399,15 +399,16 @@ lto_reissue_options (void)
>
>   FOR_EACH_VEC_ELT (opt_t, opts, i, o)
>     {
> -      const struct cl_option *option = &cl_options[o->code];
> +      void *flag_var = option_flag_var (o->code, &global_options);
>
> -      if (option->flag_var)
> -       set_option (o->code, o->value, o->arg, 0 /*DK_UNSPECIFIED*/);
> +      if (flag_var)
> +       set_option (&global_options, o->code, o->value, o->arg,
> +                   0 /*DK_UNSPECIFIED*/);
>
>       if (o->type == CL_TARGET)
>        targetm.handle_option (o->code, o->arg, o->value);
>       else if (o->type == CL_COMMON)
> -       gcc_assert (option->flag_var);
> +       gcc_assert (flag_var);
>       else
>        gcc_unreachable ();
>     }
> Index: gcc/config/i386/i386-c.c
> ===================================================================
> --- gcc/config/i386/i386-c.c    (revision 164724)
> +++ gcc/config/i386/i386-c.c    (working copy)
> @@ -283,7 +283,8 @@ ix86_pragma_target_parse (tree args, tre
>       cur_tree = ((pop_target)
>                  ? pop_target
>                  : target_option_default_node);
> -      cl_target_option_restore (TREE_TARGET_OPTION (cur_tree));
> +      cl_target_option_restore (&global_options,
> +                               TREE_TARGET_OPTION (cur_tree));
>     }
>   else
>     {
> Index: gcc/config/i386/i386.c
> ===================================================================
> --- gcc/config/i386/i386.c      (revision 164724)
> +++ gcc/config/i386/i386.c      (working copy)
> @@ -4180,11 +4180,12 @@ ix86_valid_target_attribute_p (tree fnde
>   /* If the function changed the optimization levels as well as setting target
>      options, start with the optimizations specified.  */
>   if (func_optimize && func_optimize != old_optimize)
> -    cl_optimization_restore (TREE_OPTIMIZATION (func_optimize));
> +    cl_optimization_restore (&global_options,
> +                            TREE_OPTIMIZATION (func_optimize));
>
>   /* The target attributes may also change some optimization flags, so update
>      the optimization options if necessary.  */
> -  cl_target_option_save (&cur_target);
> +  cl_target_option_save (&cur_target, &global_options);
>   new_target = ix86_valid_target_attribute_tree (args);
>   new_optimize = build_optimization_node ();
>
> @@ -4199,10 +4200,11 @@ ix86_valid_target_attribute_p (tree fnde
>        DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
>     }
>
> -  cl_target_option_restore (&cur_target);
> +  cl_target_option_restore (&global_options, &cur_target);
>
>   if (old_optimize != new_optimize)
> -    cl_optimization_restore (TREE_OPTIMIZATION (old_optimize));
> +    cl_optimization_restore (&global_options,
> +                            TREE_OPTIMIZATION (old_optimize));
>
>   return ret;
>  }
> @@ -4291,7 +4293,8 @@ ix86_set_current_function (tree fndecl)
>
>       else if (new_tree)
>        {
> -         cl_target_option_restore (TREE_TARGET_OPTION (new_tree));
> +         cl_target_option_restore (&global_options,
> +                                   TREE_TARGET_OPTION (new_tree));
>          target_reinit ();
>        }
>
> @@ -4300,7 +4303,7 @@ ix86_set_current_function (tree fndecl)
>          struct cl_target_option *def
>            = TREE_TARGET_OPTION (target_option_current_node);
>
> -         cl_target_option_restore (def);
> +         cl_target_option_restore (&global_options, def);
>          target_reinit ();
>        }
>     }
> Index: gcc/config/sh/sh.h
> ===================================================================
> --- gcc/config/sh/sh.h  (revision 164724)
> +++ gcc/config/sh/sh.h  (working copy)
> @@ -2544,8 +2544,6 @@ enum processor_type {
>  #define sh_cpu_attr ((enum attr_cpu)sh_cpu)
>  extern enum processor_type sh_cpu;
>
> -extern int optimize; /* needed for gen_casesi.  */
> -
>  enum mdep_reorg_phase_e
>  {
>   SH_BEFORE_MDEP_REORG,
> Index: gcc/config/pdp11/pdp11.h
> ===================================================================
> --- gcc/config/pdp11/pdp11.h    (revision 164724)
> +++ gcc/config/pdp11/pdp11.h    (working copy)
> @@ -767,7 +767,6 @@ extern int may_call_alloca;
>   pdp11_register_move_cost (CLASS1, CLASS2)
>
>  /* Tell emit-rtl.c how to initialize special values on a per-function base.  */
> -extern int optimize;
>  extern struct rtx_def *cc0_reg_rtx;
>
>  #define CC_STATUS_MDEP rtx
> Index: gcc/config/xtensa/xtensa.h
> ===================================================================
> --- gcc/config/xtensa/xtensa.h  (revision 164724)
> +++ gcc/config/xtensa/xtensa.h  (working copy)
> @@ -22,9 +22,6 @@ along with GCC; see the file COPYING3.
>  /* Get Xtensa configuration settings */
>  #include "xtensa-config.h"
>
> -/* Standard GCC variables that we reference.  */
> -extern int optimize;
> -
>  /* External variables defined in xtensa.c.  */
>
>  extern unsigned xtensa_current_frame_size;
> Index: gcc/config/rs6000/rs6000.h
> ===================================================================
> --- gcc/config/rs6000/rs6000.h  (revision 164724)
> +++ gcc/config/rs6000/rs6000.h  (working copy)
> @@ -2416,7 +2416,6 @@ extern char rs6000_reg_names[][8];        /* re
>  /* #define  MACHINE_no_sched_speculative_load */
>
>  /* General flags.  */
> -extern int optimize;
>  extern int frame_pointer_needed;
>
>  /* Classification of the builtin functions to properly set the declaration tree
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
>
Paul Koning - Sept. 30, 2010, 1:54 p.m.
Ok for pdp11.

	paul

On Sep 30, 2010, at 8:48 AM, Joseph S. Myers wrote:

> This patch continues moving towards the explicit use of structures in
> option processing instead of implicit use of global state.
> ...
> 	* config/pdp11/pdp11.h (optimize): Remove.
Jakub Jelinek - Sept. 30, 2010, 4:07 p.m.
On Thu, Sep 30, 2010 at 12:48:27PM +0000, Joseph S. Myers wrote:
> * The optimize and optimize_size variables move into the gcc_options
>   structure (so requiring the changes to files that redeclare them or
>   that have function parameters with those names).

This change broke Ada bootstrap it seems, ada/opts.ads has
   Optimization_Level : Int;                                                                                                                       
   pragma Import (C, Optimization_Level, "optimize");                                                                                              
   --  Constant reflecting the optimization level (0,1,2,3 for -O0,-O1,-O2,-O3)                                                                    
   --  See jmissing.c and aamissing.c for definitions for dotnet/jgnat and                                                                         
   --  GNAAMP back ends.                                                                                                                           
                                                                                                                                                   
   Optimize_Size : Int;                                                                                                                            
   pragma Import (C, Optimize_Size, "optimize_size");                                                                                              
   --  Constant reflecting setting of -Os (optimize for size). Set to nonzero                                                                      
   --  in -Os mode and set to zero otherwise. See jmissing.c and aamissing.c                                                                       
   --  for definitions of "optimize_size" for dotnet/jgnat and GNAAMP backends                                                                     

No idea whether it is possible just to change the "optimize" string to
"global_options.x_optimize" or whether some other change is needed.

	Jakub

Patch

Index: gcc/flags.h
===================================================================
--- gcc/flags.h	(revision 164724)
+++ gcc/flags.h	(working copy)
@@ -107,14 +107,6 @@  struct visibility_flags
 /* Global visibility options.  */
 extern struct visibility_flags visibility_options;
 
-/* Nonzero means do optimizations.  -opt.  */
-
-extern int optimize;
-
-/* Nonzero means optimize for size.  -Os.  */
-
-extern int optimize_size;
-
 /* True if this is the LTO front end (lto1).  This is used to disable
    gimple generation and lowering passes that are normally run on the
    output of a front end.  These passes must be bypassed for lto since
Index: gcc/opts-common.c
===================================================================
--- gcc/opts-common.c	(revision 164724)
+++ gcc/opts-common.c	(working copy)
@@ -799,12 +799,13 @@  keep:
 }
 
 /* Handle option DECODED for the language indicated by LANG_MASK,
-   using the handlers in HANDLERS.  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.  KIND is
+   the diagnostic_t if this is a diagnostics option, DK_UNSPECIFIED
+   otherwise.  Returns false if the switch was invalid.  */
 
 bool
-handle_option (const struct cl_decoded_option *decoded,
+handle_option (struct gcc_options *opts,
+	       const struct cl_decoded_option *decoded,
 	       unsigned int lang_mask, int kind,
 	       const struct cl_option_handlers *handlers)
 {
@@ -812,15 +813,16 @@  handle_option (const struct cl_decoded_o
   const char *arg = decoded->arg;
   int value = decoded->value;
   const struct cl_option *option = &cl_options[opt_index];
+  void *flag_var = option_flag_var (opt_index, opts);
   size_t i;
 
-  if (option->flag_var)
-    set_option (opt_index, value, arg, kind);
+  if (flag_var)
+    set_option (opts, 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 (decoded,
+	if (!handlers->handlers[i].handler (opts, decoded,
 					    lang_mask, kind, handlers))
 	  return false;
 	else
@@ -837,14 +839,15 @@  handle_option (const struct cl_decoded_o
    command line.  */
 
 bool
-handle_generated_option (size_t opt_index, const char *arg, int value,
+handle_generated_option (struct gcc_options *opts, 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 (&decoded, lang_mask, kind, handlers);
+  return handle_option (opts, &decoded, lang_mask, kind, handlers);
 }
 
 /* Fill in *DECODED with an option described by OPT_INDEX, ARG and
@@ -903,10 +906,11 @@  generate_option_input_file (const char *
 }
 
 /* Handle the switch DECODED for the language indicated by LANG_MASK,
-   using the handlers in *HANDLERS.  */
+   using the handlers in *HANDLERS and setting fields in OPTS.  */
 
 void
-read_cmdline_option (struct cl_decoded_option *decoded,
+read_cmdline_option (struct gcc_options *opts,
+		     struct cl_decoded_option *decoded,
 		     unsigned int lang_mask,
 		     const struct cl_option_handlers *handlers)
 {
@@ -959,45 +963,47 @@  read_cmdline_option (struct cl_decoded_o
 
   gcc_assert (!decoded->errors);
 
-  if (!handle_option (decoded, lang_mask, DK_UNSPECIFIED, handlers))
+  if (!handle_option (opts, decoded, lang_mask, DK_UNSPECIFIED, handlers))
     error ("unrecognized command line option %qs", opt);
 }
 
-/* Set any variable for option OPT_INDEX according to VALUE and ARG,
+/* Set any field in OPTS for option OPT_INDEX according to VALUE and ARG,
    diagnostic kind KIND.  */
 
 void
-set_option (int opt_index, int value, const char *arg, int kind)
+set_option (struct gcc_options *opts, 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);
 
-  if (!option->flag_var)
+  if (!flag_var)
     return;
 
   switch (option->var_type)
     {
     case CLVC_BOOLEAN:
-	*(int *) option->flag_var = value;
+	*(int *) flag_var = value;
 	break;
 
     case CLVC_EQUAL:
-	*(int *) option->flag_var = (value
-				     ? option->var_value
-				     : !option->var_value);
+	*(int *) 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;
+	  *(int *) flag_var |= option->var_value;
 	else
-	  *(int *) option->flag_var &= ~option->var_value;
-	if (option->flag_var == &target_flags)
+	  *(int *) flag_var &= ~option->var_value;
+	if (flag_var == &target_flags)
 	  target_flags_explicit |= option->var_value;
 	break;
 
     case CLVC_STRING:
-	*(const char **) option->flag_var = arg;
+	*(const char **) flag_var = arg;
 	break;
     }
 
@@ -1005,3 +1011,16 @@  set_option (int opt_index, int value, co
     diagnostic_classify_diagnostic (global_dc, opt_index, (diagnostic_t) kind,
 				    UNKNOWN_LOCATION);
 }
+
+/* Return the address of the flag variable for option OPT_INDEX in
+   options structure OPTS, or NULL if there is no flag variable.  */
+
+void *
+option_flag_var (int opt_index, struct gcc_options *opts)
+{
+  const struct cl_option *option = &cl_options[opt_index];
+
+  if (option->flag_var_offset == (unsigned short) -1)
+    return NULL;
+  return (void *)(((char *) opts) + option->flag_var_offset);
+}
Index: gcc/c-family/c-opts.c
===================================================================
--- gcc/c-family/c-opts.c	(revision 164724)
+++ gcc/c-family/c-opts.c	(working copy)
@@ -436,7 +436,7 @@  c_common_handle_option (size_t scode, co
     case OPT_Wall:
       warn_unused = value;
       set_Wformat (value);
-      handle_generated_option (OPT_Wimplicit, NULL, value,
+      handle_generated_option (&global_options, OPT_Wimplicit, NULL, value,
 			       c_family_lang_mask, kind, handlers);
       warn_char_subscripts = value;
       warn_missing_braces = value;
@@ -530,10 +530,12 @@  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 (OPT_Wimplicit_int, NULL, value,
+	handle_generated_option (&global_options, OPT_Wimplicit_int,
+				 NULL, value,
 				 c_family_lang_mask, kind, handlers);
       if (warn_implicit_function_declaration == -1)
-	handle_generated_option (OPT_Wimplicit_function_declaration, NULL,
+	handle_generated_option (&global_options,
+				 OPT_Wimplicit_function_declaration, NULL,
 				 value, c_family_lang_mask, kind, handlers);
       break;
 
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 164724)
+++ gcc/c-family/c-common.c	(working copy)
@@ -7831,12 +7831,13 @@  handle_optimize_attribute (tree *node, t
       tree old_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (*node);
 
       /* Save current options.  */
-      cl_optimization_save (&cur_opts);
+      cl_optimization_save (&cur_opts, &global_options);
 
       /* If we previously had some optimization options, use them as the
 	 default.  */
       if (old_opts)
-	cl_optimization_restore (TREE_OPTIMIZATION (old_opts));
+	cl_optimization_restore (&global_options,
+				 TREE_OPTIMIZATION (old_opts));
 
       /* Parse options, and update the vector.  */
       parse_optimize_options (args, true);
@@ -7844,7 +7845,7 @@  handle_optimize_attribute (tree *node, t
 	= build_optimization_node ();
 
       /* Restore current options.  */
-      cl_optimization_restore (&cur_opts);
+      cl_optimization_restore (&global_options, &cur_opts);
     }
 
   return NULL_TREE;
Index: gcc/c-family/c-pragma.c
===================================================================
--- gcc/c-family/c-pragma.c	(revision 164724)
+++ gcc/c-family/c-pragma.c	(working copy)
@@ -1,6 +1,6 @@ 
 /* Handle #pragma, system V.4 style.  Supports #pragma weak and #pragma pack.
    Copyright (C) 1992, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2008 Free Software Foundation, Inc.
+   2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -751,13 +751,15 @@  handle_pragma_diagnostic(cpp_reader *ARG
   for (option_index = 0; option_index < cl_options_count; option_index++)
     if (strcmp (cl_options[option_index].opt_text, option_string) == 0)
       {
+	void *flag_var = option_flag_var (option_index, &global_options);
+
 	/* This overrides -Werror, for example.  */
 	diagnostic_classify_diagnostic (global_dc, option_index, kind, input_location);
 	/* This makes sure the option is enabled, like -Wfoo would do.  */
 	if (cl_options[option_index].var_type == CLVC_BOOLEAN
-	    && cl_options[option_index].flag_var
+	    && flag_var
 	    && kind != DK_IGNORED)
-	    *(int *) cl_options[option_index].flag_var = 1;
+	    *(int *) flag_var = 1;
 	return;
       }
   GCC_BAD ("unknown option after %<#pragma GCC diagnostic%> kind");
@@ -983,7 +985,8 @@  handle_pragma_pop_options (cpp_reader *A
   if (p->optimize_binary != optimization_current_node)
     {
       tree old_optimize = optimization_current_node;
-      cl_optimization_restore (TREE_OPTIMIZATION (p->optimize_binary));
+      cl_optimization_restore (&global_options,
+			       TREE_OPTIMIZATION (p->optimize_binary));
       c_cpp_builtins_optimize_pragma (parse_in, old_optimize,
 				      p->optimize_binary);
       optimization_current_node = p->optimize_binary;
@@ -1020,7 +1023,8 @@  handle_pragma_reset_options (cpp_reader 
   if (new_optimize != optimization_current_node)
     {
       tree old_optimize = optimization_current_node;
-      cl_optimization_restore (TREE_OPTIMIZATION (new_optimize));
+      cl_optimization_restore (&global_options,
+			       TREE_OPTIMIZATION (new_optimize));
       c_cpp_builtins_optimize_pragma (parse_in, old_optimize, new_optimize);
       optimization_current_node = new_optimize;
     }
Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(revision 164724)
+++ gcc/tree.c	(working copy)
@@ -10750,7 +10750,8 @@  build_optimization_node (void)
 
   /* Use the cache of optimization nodes.  */
 
-  cl_optimization_save (TREE_OPTIMIZATION (cl_optimization_node));
+  cl_optimization_save (TREE_OPTIMIZATION (cl_optimization_node),
+			&global_options);
 
   slot = htab_find_slot (cl_option_hash_table, cl_optimization_node, INSERT);
   t = (tree) *slot;
@@ -10777,7 +10778,8 @@  build_target_option_node (void)
 
   /* Use the cache of optimization nodes.  */
 
-  cl_target_option_save (TREE_TARGET_OPTION (cl_target_option_node));
+  cl_target_option_save (TREE_TARGET_OPTION (cl_target_option_node),
+			 &global_options);
 
   slot = htab_find_slot (cl_option_hash_table, cl_target_option_node, INSERT);
   t = (tree) *slot;
Index: gcc/diagnostic.c
===================================================================
--- gcc/diagnostic.c	(revision 164724)
+++ gcc/diagnostic.c	(working copy)
@@ -113,6 +113,7 @@  diagnostic_initialize (diagnostic_contex
   diagnostic_starter (context) = default_diagnostic_starter;
   diagnostic_finalizer (context) = default_diagnostic_finalizer;
   context->option_enabled = NULL;
+  context->option_state = NULL;
   context->option_name = NULL;
   context->last_module = 0;
   context->x_data = NULL;
@@ -435,7 +436,8 @@  diagnostic_report_diagnostic (diagnostic
 
       /* This tests if the user provided the appropriate -Wfoo or
 	 -Wno-foo option.  */
-      if (! context->option_enabled (diagnostic->option_index))
+      if (! context->option_enabled (diagnostic->option_index,
+				     context->option_state))
 	return false;
 
       /* This tests for #pragma diagnostic changes.  */
Index: gcc/diagnostic.h
===================================================================
--- gcc/diagnostic.h	(revision 164724)
+++ gcc/diagnostic.h	(working copy)
@@ -146,7 +146,11 @@  struct diagnostic_context
 
   /* Client hook to say whether the option controlling a diagnostic is
      enabled.  Returns nonzero if enabled, zero if disabled.  */
-  int (*option_enabled) (int);
+  int (*option_enabled) (int, void *);
+
+  /* Client information to pass as second argument to
+     option_enabled.  */
+  void *option_state;
 
   /* Client hook to return the name of an option that controls a
      diagnostic.  Returns malloced memory.  The first diagnostic_t
Index: gcc/final.c
===================================================================
--- gcc/final.c	(revision 164724)
+++ gcc/final.c	(working copy)
@@ -1512,12 +1512,12 @@  dwarf2_debug_info_emitted_p (tree decl)
 
    FIRST is the first insn of the rtl for the function being compiled.
    FILE is the file to write assembler code to.
-   OPTIMIZE is nonzero if we should eliminate redundant
+   OPTIMIZE_P is nonzero if we should eliminate redundant
      test and compare insns.  */
 
 void
 final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file,
-		      int optimize ATTRIBUTE_UNUSED)
+		      int optimize_p ATTRIBUTE_UNUSED)
 {
   block_depth = 0;
 
@@ -1662,7 +1662,7 @@  final_end_function (void)
    For description of args, see `final_start_function', above.  */
 
 void
-final (rtx first, FILE *file, int optimize)
+final (rtx first, FILE *file, int optimize_p)
 {
   rtx insn;
   int max_uid = 0;
@@ -1677,7 +1677,7 @@  final (rtx first, FILE *file, int optimi
 #ifdef HAVE_cc0
       /* If CC tracking across branches is enabled, record the insn which
 	 jumps to each branch only reached from one place.  */
-      if (optimize && JUMP_P (insn))
+      if (optimize_p && JUMP_P (insn))
 	{
 	  rtx lab = JUMP_LABEL (insn);
 	  if (lab && LABEL_NUSES (lab) == 1)
@@ -1707,7 +1707,7 @@  final (rtx first, FILE *file, int optimi
 	insn_current_address = INSN_ADDRESSES (INSN_UID (insn));
 #endif /* HAVE_ATTR_length */
 
-      insn = final_scan_insn (insn, file, optimize, 0, &seen);
+      insn = final_scan_insn (insn, file, optimize_p, 0, &seen);
     }
 }
 
@@ -1803,7 +1803,7 @@  call_from_call_insn (rtx insn)
    first.  */
 
 rtx
-final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
+final_scan_insn (rtx insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
 		 int nopeepholes ATTRIBUTE_UNUSED, int *seen)
 {
 #ifdef HAVE_cc0
@@ -2327,7 +2327,7 @@  final_scan_insn (rtx insn, FILE *file, i
 	   and the next statement should reexamine the variable
 	   to compute the condition codes.  */
 
-	if (optimize)
+	if (optimize_p)
 	  {
 	    if (set
 		&& GET_CODE (SET_DEST (set)) == CC0
@@ -2512,7 +2512,7 @@  final_scan_insn (rtx insn, FILE *file, i
 #ifdef HAVE_peephole
 	/* Do machine-specific peephole optimizations if desired.  */
 
-	if (optimize && !flag_no_peephole && !nopeepholes)
+	if (optimize_p && !flag_no_peephole && !nopeepholes)
 	  {
 	    rtx next = peephole (insn);
 	    /* When peepholing, if there were notes within the peephole,
@@ -2523,7 +2523,7 @@  final_scan_insn (rtx insn, FILE *file, i
 
 		for (note = NEXT_INSN (insn); note != next;
 		     note = NEXT_INSN (note))
-		  final_scan_insn (note, file, optimize, nopeepholes, seen);
+		  final_scan_insn (note, file, optimize_p, nopeepholes, seen);
 
 		/* Put the notes in the proper position for a later
 		   rescan.  For example, the SH target can do this
Index: gcc/gcc.c
===================================================================
--- gcc/gcc.c	(revision 164724)
+++ gcc/gcc.c	(working copy)
@@ -3150,7 +3150,8 @@  static int last_language_n_infiles;
    handle_option.  */
 
 static bool
-driver_handle_option (const struct cl_decoded_option *decoded,
+driver_handle_option (struct gcc_options *opts,
+		      const struct cl_decoded_option *decoded,
 		      unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
 		      const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
 {
@@ -3161,6 +3162,7 @@  driver_handle_option (const struct cl_de
   bool validated = false;
   bool do_save = true;
 
+  gcc_assert (opts == &global_options);
   gcc_assert (kind == DK_UNSPECIFIED);
 
   switch (opt_index)
@@ -3801,7 +3803,8 @@  process_command (unsigned int decoded_op
 	  continue;
 	}
 
-      read_cmdline_option (decoded_options + j, CL_DRIVER, &handlers);
+      read_cmdline_option (&global_options, 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 164724)
+++ gcc/toplev.c	(working copy)
@@ -174,22 +174,6 @@  enum graph_dump_types graph_dump_format;
 
 const char *asm_file_name;
 
-/* Nonzero means do optimizations.  -O.
-   Particular numeric values stand for particular amounts of optimization;
-   thus, -O2 stores 2 here.  However, the optimizations beyond the basic
-   ones are not controlled directly by this variable.  Instead, they are
-   controlled by individual `flag_...' variables that are defaulted
-   based on this variable.  */
-
-int optimize = 0;
-
-/* Nonzero means optimize for size.  -Os.
-   The only valid values are zero and nonzero. When optimize_size is
-   nonzero, optimize defaults to 2, but certain individual code
-   bloating optimizations are disabled.  */
-
-int optimize_size = 0;
-
 /* True if this is the lto front end.  This is used to disable
    gimple generation and lowering passes that are normally run on the
    output of a front end.  These passes must be bypassed for lto since
@@ -1316,7 +1300,7 @@  print_switch_values (print_switch_fn_typ
 
   for (j = 0; j < cl_options_count; j++)
     if ((cl_options[j].flags & CL_REPORT)
-	&& option_enabled (j) > 0)
+	&& option_enabled (j, &global_options) > 0)
       pos = print_single_switch (print_fn, pos,
 				 SWITCH_TYPE_ENABLED, cl_options[j].opt_text);
 
@@ -1395,10 +1379,10 @@  option_affects_pch_p (int option, struct
 {
   if ((cl_options[option].flags & CL_TARGET) == 0)
     return false;
-  if (cl_options[option].flag_var == &target_flags)
+  if (option_flag_var (option, &global_options) == &target_flags)
     if (targetm.check_pch_target_flags)
       return false;
-  return get_option_state (option, state);
+  return get_option_state (&global_options, option, state);
 }
 
 /* Default version of get_pch_validity.
@@ -1686,6 +1670,7 @@  general_init (const char *argv0)
   global_dc->show_column = flag_show_column;
   global_dc->internal_error = plugins_internal_error_function;
   global_dc->option_enabled = option_enabled;
+  global_dc->option_state = &global_options;
   global_dc->option_name = option_name;
 
   /* Trap fatal signals, e.g. SIGSEGV, and convert them to ICE messages.  */
Index: gcc/ipa-pure-const.c
===================================================================
--- gcc/ipa-pure-const.c	(revision 164724)
+++ gcc/ipa-pure-const.c	(working copy)
@@ -138,7 +138,7 @@  suggest_attribute (int option, tree decl
 		   struct pointer_set_t *warned_about,
 		   const char * attrib_name)
 {
-  if (!option_enabled (option))
+  if (!option_enabled (option, &global_options))
     return warned_about;
   if (TREE_THIS_VOLATILE (decl)
       || (known_finite && function_always_visible_to_compiler_p (decl)))
Index: gcc/opts.c
===================================================================
--- gcc/opts.c	(revision 164724)
+++ gcc/opts.c	(working copy)
@@ -376,7 +376,8 @@  bool flag_warn_unused_result = false;
 const char **in_fnames;
 unsigned num_in_fnames;
 
-static bool common_handle_option (const struct cl_decoded_option *decoded,
+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 *);
@@ -515,10 +516,12 @@  post_handling_callback (const struct cl_
    handle_option.  */
 
 static bool
-lang_handle_option (const struct cl_decoded_option *decoded,
+lang_handle_option (struct gcc_options *opts,
+		    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 (decoded->canonical_option_num_elements <= 2);
   return lang_hooks.handle_option (decoded->opt_index, decoded->arg,
 				   decoded->value, kind, handlers);
@@ -528,10 +531,12 @@  lang_handle_option (const struct cl_deco
    handle_option.  */
 
 static bool
-target_handle_option (const struct cl_decoded_option *decoded,
+target_handle_option (struct gcc_options *opts,
+		      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 (decoded->canonical_option_num_elements <= 2);
   gcc_assert (kind == DK_UNSPECIFIED);
   return targetm.handle_option (decoded->opt_index, decoded->arg,
@@ -644,7 +649,8 @@  read_cmdline_options (struct cl_decoded_
 	  continue;
 	}
 
-      read_cmdline_option (decoded_options + i, lang_mask, handlers);
+      read_cmdline_option (&global_options, decoded_options + i,
+			   lang_mask, handlers);
     }
 }
 
@@ -1254,28 +1260,30 @@  print_filtered_help (unsigned int includ
 	 with an option to be an indication of its current setting.  */
       if (!quiet_flag)
 	{
+	  void *flag_var = option_flag_var (i, &global_options);
+
 	  if (len < (LEFT_COLUMN + 2))
 	    strcpy (new_help, "\t\t");
 	  else
 	    strcpy (new_help, "\t");
 
-	  if (option->flag_var != NULL)
+	  if (flag_var != NULL)
 	    {
 	      if (option->flags & CL_JOINED)
 		{
 		  if (option->var_type == CLVC_STRING)
 		    {
-		      if (* (const char **) option->flag_var != NULL)
+		      if (* (const char **) flag_var != NULL)
 			snprintf (new_help + strlen (new_help),
 				  sizeof (new_help) - strlen (new_help),
-				  * (const char **) option->flag_var);
+				  * (const char **) flag_var);
 		    }
 		  else
 		    sprintf (new_help + strlen (new_help),
-			     "%#x", * (int *) option->flag_var);
+			     "%#x", * (int *) flag_var);
 		}
 	      else
-		strcat (new_help, option_enabled (i)
+		strcat (new_help, option_enabled (i, &global_options)
 			? _("[enabled]") : _("[disabled]"));
 	    }
 
@@ -1423,7 +1431,8 @@  print_specific_help (unsigned int includ
    DECODED->value assigned to a variable, it happens automatically.  */
 
 static bool
-common_handle_option (const struct cl_decoded_option *decoded,
+common_handle_option (struct gcc_options *opts,
+		      const struct cl_decoded_option *decoded,
 		      unsigned int lang_mask, int kind ATTRIBUTE_UNUSED,
 		      const struct cl_option_handlers *handlers)
 {
@@ -1433,6 +1442,7 @@  common_handle_option (const struct cl_de
   static bool verbose = false;
   enum opt_code code = (enum opt_code) scode;
 
+  gcc_assert (opts == &global_options);
   gcc_assert (decoded->canonical_option_num_elements <= 2);
 
   switch (code)
@@ -2102,7 +2112,7 @@  common_handle_option (const struct cl_de
     default:
       /* If the flag was handled in a standard way, assume the lack of
 	 processing here is intentional.  */
-      gcc_assert (cl_options[scode].flag_var);
+      gcc_assert (option_flag_var (scode, opts));
       break;
     }
 
@@ -2258,28 +2268,30 @@  set_debug_level (enum debug_info_type ty
     }
 }
 
-/* Return 1 if OPTION is enabled, 0 if it is disabled, or -1 if it isn't
-   a simple on-off switch.  */
+/* Return 1 if option OPT_IDX is enabled in OPTS, 0 if it is disabled,
+   or -1 if it isn't a simple on-off switch.  */
 
 int
-option_enabled (int opt_idx)
+option_enabled (int opt_idx, void *opts)
 {
   const struct cl_option *option = &(cl_options[opt_idx]);
+  struct gcc_options *optsg = (struct gcc_options *) opts;
+  void *flag_var = option_flag_var (opt_idx, optsg);
 
-  if (option->flag_var)
+  if (flag_var)
     switch (option->var_type)
       {
       case CLVC_BOOLEAN:
-	return *(int *) option->flag_var != 0;
+	return *(int *) flag_var != 0;
 
       case CLVC_EQUAL:
-	return *(int *) option->flag_var == option->var_value;
+	return *(int *) flag_var == option->var_value;
 
       case CLVC_BIT_CLEAR:
-	return (*(int *) option->flag_var & option->var_value) == 0;
+	return (*(int *) flag_var & option->var_value) == 0;
 
       case CLVC_BIT_SET:
-	return (*(int *) option->flag_var & option->var_value) != 0;
+	return (*(int *) flag_var & option->var_value) != 0;
 
       case CLVC_STRING:
 	break;
@@ -2287,32 +2299,35 @@  option_enabled (int opt_idx)
   return -1;
 }
 
-/* Fill STATE with the current state of option OPTION.  Return true if
-   there is some state to store.  */
+/* Fill STATE with the current state of option OPTION in OPTS.  Return
+   true if there is some state to store.  */
 
 bool
-get_option_state (int option, struct cl_option_state *state)
+get_option_state (struct gcc_options *opts, int option,
+		  struct cl_option_state *state)
 {
-  if (cl_options[option].flag_var == 0)
+  void *flag_var = option_flag_var (option, opts);
+
+  if (flag_var == 0)
     return false;
 
   switch (cl_options[option].var_type)
     {
     case CLVC_BOOLEAN:
     case CLVC_EQUAL:
-      state->data = cl_options[option].flag_var;
+      state->data = flag_var;
       state->size = sizeof (int);
       break;
 
     case CLVC_BIT_CLEAR:
     case CLVC_BIT_SET:
-      state->ch = option_enabled (option);
+      state->ch = option_enabled (option, opts);
       state->data = &state->ch;
       state->size = 1;
       break;
 
     case CLVC_STRING:
-      state->data = *(const char **) cl_options[option].flag_var;
+      state->data = *(const char **) flag_var;
       if (state->data == 0)
 	state->data = "";
       state->size = strlen ((const char *) state->data) + 1;
@@ -2369,7 +2384,8 @@  enable_warning_as_error (const char *arg
 
 	  /* -Werror=foo implies -Wfoo.  */
 	  if (option->var_type == CLVC_BOOLEAN)
-	    handle_generated_option (option_index, NULL, value, lang_mask,
+	    handle_generated_option (&global_options, option_index,
+				     NULL, value, lang_mask,
 				     (int)kind, handlers);
 
 	  if (warning_as_error_callback)
Index: gcc/opts.h
===================================================================
--- gcc/opts.h	(revision 164724)
+++ gcc/opts.h	(working copy)
@@ -53,7 +53,7 @@  struct cl_option
   unsigned char opt_len;
   int neg_index;
   unsigned int flags;
-  void *flag_var;
+  unsigned short flag_var_offset;
   enum cl_var_type var_type;
   int var_value;
 };
@@ -156,7 +156,8 @@  struct cl_decoded_option
 struct cl_option_handler_func
 {
   /* The function called to handle the option.  */
-  bool (*handler) (const struct cl_decoded_option *decoded,
+  bool (*handler) (struct gcc_options *opts,
+		   const struct cl_decoded_option *decoded,
 		   unsigned int lang_mask, int kind,
 		   const struct cl_option_handlers *handlers);
 
@@ -209,13 +210,18 @@  extern void decode_cmdline_options_to_ar
 extern void decode_options (unsigned int argc, const char **argv,
 			    struct cl_decoded_option **decoded_options,
 			    unsigned int *decoded_options_count);
-extern int option_enabled (int opt_idx);
-extern bool get_option_state (int, struct cl_option_state *);
-extern void set_option (int opt_index, int value, const char *arg, int);
-bool handle_option (const struct cl_decoded_option *decoded,
+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 *option_flag_var (int opt_index, struct gcc_options *opts);
+bool handle_option (struct gcc_options *opts,
+		    const struct cl_decoded_option *decoded,
 		    unsigned int lang_mask, int kind,
 		    const struct cl_option_handlers *handlers);
-bool handle_generated_option (size_t opt_index, const char *arg, int value,
+bool handle_generated_option (struct gcc_options *opts,
+			      size_t opt_index, const char *arg, int value,
 			      unsigned int lang_mask, int kind,
 			      const struct cl_option_handlers *handlers);
 void generate_option (size_t opt_index, const char *arg, int value,
@@ -223,7 +229,8 @@  void generate_option (size_t opt_index, 
 		      struct cl_decoded_option *decoded);
 void generate_option_input_file (const char *file,
 				 struct cl_decoded_option *decoded);
-extern void read_cmdline_option (struct cl_decoded_option *decoded,
+extern void read_cmdline_option (struct gcc_options *opts,
+				 struct cl_decoded_option *decoded,
 				 unsigned int lang_mask,
 				 const struct cl_option_handlers *handlers);
 extern void register_warning_as_error_callback (void (*callback) (int));
Index: gcc/optc-gen.awk
===================================================================
--- gcc/optc-gen.awk	(revision 164724)
+++ gcc/optc-gen.awk	(working copy)
@@ -131,15 +131,14 @@  for (i = 0; i < n_opts; i++) {
 
 	var_seen[name] = 1;
 }
-print "};"
-
-print ""
-print "/* Local state variables.  */"
 for (i = 0; i < n_opts; i++) {
 	name = static_var(opts[i], flags[i]);
-	if (name != "")
-		print "static " var_type(flags[i]) name ";"
+	if (name != "") {
+		print "  0, /* " name " (private state) */"
+		print "#undef x_" name
+	}
 }
+print "};"
 print ""
 
 print "const char * const lang_names[] =\n{"
@@ -235,7 +234,7 @@  for (i = 0; i < n_opts; i++) {
 		alias_posarg = nth_arg(1, alias_arg)
 		alias_negarg = nth_arg(2, alias_arg)
 
-		if (var_ref(opts[i], flags[i]) != "0")
+		if (var_ref(opts[i], flags[i]) != "-1")
 			print "#error Alias setting variable"
 
 		if (alias_posarg != "" && alias_negarg == "") {
@@ -298,7 +297,7 @@  print "#if !defined(GCC_DRIVER) && !defi
 print "";
 print "/* Save optimization variables into a structure.  */"
 print "void";
-print "cl_optimization_save (struct cl_optimization *ptr)";
+print "cl_optimization_save (struct cl_optimization *ptr, struct gcc_options *opts)";
 print "{";
 
 n_opt_char = 2;
@@ -345,24 +344,24 @@  for (i = 0; i < n_opts; i++) {
 for (i = 0; i < n_opt_char; i++) {
 	name = var_opt_char[i];
 	if (var_opt_range[name] != "")
-		print "  gcc_assert (IN_RANGE (" name ", " var_opt_range[name] "));";
+		print "  gcc_assert (IN_RANGE (opts->x_" name ", " var_opt_range[name] "));";
 }
 
 print "";
 for (i = 0; i < n_opt_other; i++) {
-	print "  ptr->x_" var_opt_other[i] " = " var_opt_other[i] ";";
+	print "  ptr->x_" var_opt_other[i] " = opts->x_" var_opt_other[i] ";";
 }
 
 for (i = 0; i < n_opt_int; i++) {
-	print "  ptr->x_" var_opt_int[i] " = " var_opt_int[i] ";";
+	print "  ptr->x_" var_opt_int[i] " = opts->x_" var_opt_int[i] ";";
 }
 
 for (i = 0; i < n_opt_short; i++) {
-	print "  ptr->x_" var_opt_short[i] " = " var_opt_short[i] ";";
+	print "  ptr->x_" var_opt_short[i] " = opts->x_" var_opt_short[i] ";";
 }
 
 for (i = 0; i < n_opt_char; i++) {
-	print "  ptr->x_" var_opt_char[i] " = " var_opt_char[i] ";";
+	print "  ptr->x_" var_opt_char[i] " = opts->x_" var_opt_char[i] ";";
 }
 
 print "}";
@@ -370,23 +369,23 @@  print "}";
 print "";
 print "/* Restore optimization options from a structure.  */";
 print "void";
-print "cl_optimization_restore (struct cl_optimization *ptr)";
+print "cl_optimization_restore (struct gcc_options *opts, struct cl_optimization *ptr)";
 print "{";
 
 for (i = 0; i < n_opt_other; i++) {
-	print "  " var_opt_other[i] " = ptr->x_" var_opt_other[i] ";";
+	print "  opts->x_" var_opt_other[i] " = ptr->x_" var_opt_other[i] ";";
 }
 
 for (i = 0; i < n_opt_int; i++) {
-	print "  " var_opt_int[i] " = ptr->x_" var_opt_int[i] ";";
+	print "  opts->x_" var_opt_int[i] " = ptr->x_" var_opt_int[i] ";";
 }
 
 for (i = 0; i < n_opt_short; i++) {
-	print "  " var_opt_short[i] " = ptr->x_" var_opt_short[i] ";";
+	print "  opts->x_" var_opt_short[i] " = ptr->x_" var_opt_short[i] ";";
 }
 
 for (i = 0; i < n_opt_char; i++) {
-	print "  " var_opt_char[i] " = ptr->x_" var_opt_char[i] ";";
+	print "  opts->x_" var_opt_char[i] " = ptr->x_" var_opt_char[i] ";";
 }
 
 print "  targetm.override_options_after_change ();";
@@ -442,7 +441,7 @@  print "}";
 print "";
 print "/* Save selected option variables into a structure.  */"
 print "void";
-print "cl_target_option_save (struct cl_target_option *ptr)";
+print "cl_target_option_save (struct cl_target_option *ptr, struct gcc_options *opts)";
 print "{";
 
 n_target_char = 0;
@@ -488,7 +487,7 @@  for (i = 0; i < n_target_char; i++) {
 	name = var_target_char[i];
 	if (var_target_range[name] != "") {
 		have_assert = 1;
-		print "  gcc_assert (IN_RANGE (" name ", " var_target_range[name] "));";
+		print "  gcc_assert (IN_RANGE (opts->x_" name ", " var_target_range[name] "));";
 	}
 }
 
@@ -500,19 +499,19 @@  print "    targetm.target_option.save (p
 print "";
 
 for (i = 0; i < n_target_other; i++) {
-	print "  ptr->x_" var_target_other[i] " = " var_target_other[i] ";";
+	print "  ptr->x_" var_target_other[i] " = opts->x_" var_target_other[i] ";";
 }
 
 for (i = 0; i < n_target_int; i++) {
-	print "  ptr->x_" var_target_int[i] " = " var_target_int[i] ";";
+	print "  ptr->x_" var_target_int[i] " = opts->x_" var_target_int[i] ";";
 }
 
 for (i = 0; i < n_target_short; i++) {
-	print "  ptr->x_" var_target_short[i] " = " var_target_short[i] ";";
+	print "  ptr->x_" var_target_short[i] " = opts->x_" var_target_short[i] ";";
 }
 
 for (i = 0; i < n_target_char; i++) {
-	print "  ptr->x_" var_target_char[i] " = " var_target_char[i] ";";
+	print "  ptr->x_" var_target_char[i] " = opts->x_" var_target_char[i] ";";
 }
 
 print "}";
@@ -520,23 +519,23 @@  print "}";
 print "";
 print "/* Restore selected current options from a structure.  */";
 print "void";
-print "cl_target_option_restore (struct cl_target_option *ptr)";
+print "cl_target_option_restore (struct gcc_options *opts, struct cl_target_option *ptr)";
 print "{";
 
 for (i = 0; i < n_target_other; i++) {
-	print "  " var_target_other[i] " = ptr->x_" var_target_other[i] ";";
+	print "  opts->x_" var_target_other[i] " = ptr->x_" var_target_other[i] ";";
 }
 
 for (i = 0; i < n_target_int; i++) {
-	print "  " var_target_int[i] " = ptr->x_" var_target_int[i] ";";
+	print "  opts->x_" var_target_int[i] " = ptr->x_" var_target_int[i] ";";
 }
 
 for (i = 0; i < n_target_short; i++) {
-	print "  " var_target_short[i] " = ptr->x_" var_target_short[i] ";";
+	print "  opts->x_" var_target_short[i] " = ptr->x_" var_target_short[i] ";";
 }
 
 for (i = 0; i < n_target_char; i++) {
-	print "  " var_target_char[i] " = ptr->x_" var_target_char[i] ";";
+	print "  opts->x_" var_target_char[i] " = ptr->x_" var_target_char[i] ";";
 }
 
 # This must occur after the normal variables in case the code depends on those
Index: gcc/function.c
===================================================================
--- gcc/function.c	(revision 164724)
+++ gcc/function.c	(working copy)
@@ -4254,7 +4254,7 @@  invoke_set_current_function_hook (tree f
       if (optimization_current_node != opts)
 	{
 	  optimization_current_node = opts;
-	  cl_optimization_restore (TREE_OPTIMIZATION (opts));
+	  cl_optimization_restore (&global_options, TREE_OPTIMIZATION (opts));
 	}
 
       targetm.set_current_function (fndecl);
Index: gcc/coretypes.h
===================================================================
--- gcc/coretypes.h	(revision 164724)
+++ gcc/coretypes.h	(working copy)
@@ -64,6 +64,7 @@  typedef const union tree_node *const_tre
 typedef const union gimple_statement_d *const_gimple;
 union section;
 typedef union section section;
+struct gcc_options;
 struct cl_target_option;
 struct cl_optimization;
 struct cl_option;
Index: gcc/opth-gen.awk
===================================================================
--- gcc/opth-gen.awk	(revision 164724)
+++ gcc/opth-gen.awk	(working copy)
@@ -115,6 +115,15 @@  for (i = 0; i < n_opts; i++) {
 	print "#define " name " global_options.x_" name
 	print "#endif"
 }
+for (i = 0; i < n_opts; i++) {
+	name = static_var(opts[i], flags[i]);
+	if (name != "") {
+		print "#ifndef GENERATOR_FILE"
+		print "  " var_type(flags[i]) "x_" name ";"
+		print "#define x_" name " do_not_use"
+		print "#endif"
+	}
+}
 print "#ifndef GENERATOR_FILE"
 print "};"
 print "extern struct gcc_options global_options;"
@@ -258,19 +267,19 @@  print "};";
 print "";
 print "";
 print "/* Save optimization variables into a structure.  */"
-print "extern void cl_optimization_save (struct cl_optimization *);";
+print "extern void cl_optimization_save (struct cl_optimization *, struct gcc_options *);";
 print "";
 print "/* Restore optimization variables from a structure.  */";
-print "extern void cl_optimization_restore (struct cl_optimization *);";
+print "extern void cl_optimization_restore (struct gcc_options *, struct cl_optimization *);";
 print "";
 print "/* Print optimization variables from a structure.  */";
 print "extern void cl_optimization_print (FILE *, int, struct cl_optimization *);";
 print "";
 print "/* Save selected option variables into a structure.  */"
-print "extern void cl_target_option_save (struct cl_target_option *);";
+print "extern void cl_target_option_save (struct cl_target_option *, struct gcc_options *);";
 print "";
 print "/* Restore selected option variables from a structure.  */"
-print "extern void cl_target_option_restore (struct cl_target_option *);";
+print "extern void cl_target_option_restore (struct gcc_options *, struct cl_target_option *);";
 print "";
 print "/* Print target option variables from a structure.  */";
 print "extern void cl_target_option_print (FILE *, int, struct cl_target_option *);";
Index: gcc/common.opt
===================================================================
--- gcc/common.opt	(revision 164724)
+++ gcc/common.opt	(working copy)
@@ -26,6 +26,12 @@ 
 Variable
 int target_flags
 
+Variable
+int optimize
+
+Variable
+int optimize_size
+
 ###
 Driver
 
Index: gcc/opt-functions.awk
===================================================================
--- gcc/opt-functions.awk	(revision 164724)
+++ gcc/opt-functions.awk	(working copy)
@@ -120,9 +120,9 @@  function needs_state_p(flags)
 		&& !flag_set_p("Ignore", flags))
 }
 
-# If FLAGS describes an option that needs a static state variable,
-# return the name of that variable, otherwise return "".  NAME is
-# the name of the option.
+# If FLAGS describes an option that needs state without a public
+# variable name, return the name of that field, minus the initial
+# "x_", otherwise return "".  NAME is the name of the option.
 function static_var(name, flags)
 {
 	if (global_state_p(flags) || !needs_state_p(flags))
@@ -193,12 +193,12 @@  function var_ref(name, flags)
 {
 	name = var_name(flags) static_var(name, flags)
 	if (name != "")
-		return "&" name
+		return "offsetof (struct gcc_options, x_" name ")"
 	if (opt_args("Mask", flags) != "")
-		return "&target_flags"
+		return "offsetof (struct gcc_options, x_target_flags)"
 	if (opt_args("InverseMask", flags) != "")
-		return "&target_flags"
-	return "0"
+		return "offsetof (struct gcc_options, x_target_flags)"
+	return "-1"
 }
 
 # Given the option called NAME return a sanitized version of its name.
Index: gcc/lto-opts.c
===================================================================
--- gcc/lto-opts.c	(revision 164724)
+++ gcc/lto-opts.c	(working copy)
@@ -1,6 +1,6 @@ 
 /* LTO IL options.
 
-   Copyright 2009 Free Software Foundation, Inc.
+   Copyright 2009, 2010 Free Software Foundation, Inc.
    Contributed by Simon Baldwin <simonb@google.com>
 
 This file is part of GCC.
@@ -399,15 +399,16 @@  lto_reissue_options (void)
 
   FOR_EACH_VEC_ELT (opt_t, opts, i, o)
     {
-      const struct cl_option *option = &cl_options[o->code];
+      void *flag_var = option_flag_var (o->code, &global_options);
 
-      if (option->flag_var)
-	set_option (o->code, o->value, o->arg, 0 /*DK_UNSPECIFIED*/);
+      if (flag_var)
+	set_option (&global_options, o->code, o->value, o->arg,
+		    0 /*DK_UNSPECIFIED*/);
 
       if (o->type == CL_TARGET)
 	targetm.handle_option (o->code, o->arg, o->value);
       else if (o->type == CL_COMMON)
-	gcc_assert (option->flag_var);
+	gcc_assert (flag_var);
       else
 	gcc_unreachable ();
     }
Index: gcc/config/i386/i386-c.c
===================================================================
--- gcc/config/i386/i386-c.c	(revision 164724)
+++ gcc/config/i386/i386-c.c	(working copy)
@@ -283,7 +283,8 @@  ix86_pragma_target_parse (tree args, tre
       cur_tree = ((pop_target)
 		  ? pop_target
 		  : target_option_default_node);
-      cl_target_option_restore (TREE_TARGET_OPTION (cur_tree));
+      cl_target_option_restore (&global_options,
+				TREE_TARGET_OPTION (cur_tree));
     }
   else
     {
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 164724)
+++ gcc/config/i386/i386.c	(working copy)
@@ -4180,11 +4180,12 @@  ix86_valid_target_attribute_p (tree fnde
   /* If the function changed the optimization levels as well as setting target
      options, start with the optimizations specified.  */
   if (func_optimize && func_optimize != old_optimize)
-    cl_optimization_restore (TREE_OPTIMIZATION (func_optimize));
+    cl_optimization_restore (&global_options,
+			     TREE_OPTIMIZATION (func_optimize));
 
   /* The target attributes may also change some optimization flags, so update
      the optimization options if necessary.  */
-  cl_target_option_save (&cur_target);
+  cl_target_option_save (&cur_target, &global_options);
   new_target = ix86_valid_target_attribute_tree (args);
   new_optimize = build_optimization_node ();
 
@@ -4199,10 +4200,11 @@  ix86_valid_target_attribute_p (tree fnde
 	DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
     }
 
-  cl_target_option_restore (&cur_target);
+  cl_target_option_restore (&global_options, &cur_target);
 
   if (old_optimize != new_optimize)
-    cl_optimization_restore (TREE_OPTIMIZATION (old_optimize));
+    cl_optimization_restore (&global_options,
+			     TREE_OPTIMIZATION (old_optimize));
 
   return ret;
 }
@@ -4291,7 +4293,8 @@  ix86_set_current_function (tree fndecl)
 
       else if (new_tree)
 	{
-	  cl_target_option_restore (TREE_TARGET_OPTION (new_tree));
+	  cl_target_option_restore (&global_options,
+				    TREE_TARGET_OPTION (new_tree));
 	  target_reinit ();
 	}
 
@@ -4300,7 +4303,7 @@  ix86_set_current_function (tree fndecl)
 	  struct cl_target_option *def
 	    = TREE_TARGET_OPTION (target_option_current_node);
 
-	  cl_target_option_restore (def);
+	  cl_target_option_restore (&global_options, def);
 	  target_reinit ();
 	}
     }
Index: gcc/config/sh/sh.h
===================================================================
--- gcc/config/sh/sh.h	(revision 164724)
+++ gcc/config/sh/sh.h	(working copy)
@@ -2544,8 +2544,6 @@  enum processor_type {
 #define sh_cpu_attr ((enum attr_cpu)sh_cpu)
 extern enum processor_type sh_cpu;
 
-extern int optimize; /* needed for gen_casesi.  */
-
 enum mdep_reorg_phase_e
 {
   SH_BEFORE_MDEP_REORG,
Index: gcc/config/pdp11/pdp11.h
===================================================================
--- gcc/config/pdp11/pdp11.h	(revision 164724)
+++ gcc/config/pdp11/pdp11.h	(working copy)
@@ -767,7 +767,6 @@  extern int may_call_alloca;
   pdp11_register_move_cost (CLASS1, CLASS2)
 
 /* Tell emit-rtl.c how to initialize special values on a per-function base.  */
-extern int optimize;
 extern struct rtx_def *cc0_reg_rtx;
 
 #define CC_STATUS_MDEP rtx
Index: gcc/config/xtensa/xtensa.h
===================================================================
--- gcc/config/xtensa/xtensa.h	(revision 164724)
+++ gcc/config/xtensa/xtensa.h	(working copy)
@@ -22,9 +22,6 @@  along with GCC; see the file COPYING3.  
 /* Get Xtensa configuration settings */
 #include "xtensa-config.h"
 
-/* Standard GCC variables that we reference.  */
-extern int optimize;
-
 /* External variables defined in xtensa.c.  */
 
 extern unsigned xtensa_current_frame_size;
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 164724)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -2416,7 +2416,6 @@  extern char rs6000_reg_names[][8];	/* re
 /* #define  MACHINE_no_sched_speculative_load */
 
 /* General flags.  */
-extern int optimize;
 extern int frame_pointer_needed;
 
 /* Classification of the builtin functions to properly set the declaration tree