different sets of optimization levels.  (A few places setting
variables to 2 rather than using settings directly corresponding with
applying an existing option at that point will need adjusting to use
global_options_set when determining defaults at a later point, before
all the hooks can be replaced by a new hook that provides an array
rather than a function.)  TARGET_HANDLE_OFAST (a hook that no target
defines at present) will also be subsumed in this new table mechanism
- it doesn't need its own hook, just the ability for table entries to
be marked "-Ofast only" as well as "-O2 and above", "-Os only" and
similar cases.

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  Also
tested building cc1 for crosses to: pdp11-none powerpc-eabi
s390-linux-gnu sh-elf spu-elf.  OK to commit?

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

	* target.def (target_option.init_struct): New hook.
	* doc/tm.texi.in (TARGET_OPTION_INIT_STRUCT): New @hook.
	* doc/tm.texi: Regenerate.
	* hooks.c (hook_void_gcc_optionsp): New.
	* hooks.h (hook_void_gcc_optionsp): Declare.
	* langhooks-def.h (lhd_init_options_struct): Remove.
	(LANG_HOOKS_INIT_OPTIONS_STRUCT): Define to
	hook_void_gcc_optionsp.
	* langhooks.c (lhd_init_options_struct): Remove.
	* opts.c (init_options_struct): Also call
	targetm.target_option.init_struct.
	* config/i386/i386.c (ix86_option_init_struct,
	TARGET_OPTION_INIT_STRUCT): New.
	(ix86_option_optimization): Move some settings to
	ix86_option_init_struct.
	* config/pdp11/pdp11.c (pdp11_option_init_struct,
	TARGET_OPTION_INIT_STRUCT): New.
	(pdp11_option_optimization): Move some settings to
	pdp11_option_init_struct.
	* config/rs6000/rs6000.c (rs6000_option_optimization): Replace by
	rs6000_option_init_struct.  Use options structure pointer.
	(TARGET_OPTION_OPTIMIZATION): Replace by
	TARGET_OPTION_INIT_STRUCT.
	* config/s390/s390.c (s390_option_init_struct,
	TARGET_OPTION_INIT_STRUCT): New.
	(s390_option_optimization): Don't set
	flag_asynchronous_unwind_tables here.
	* config/sh/sh.c (sh_option_init_struct,
	TARGET_OPTION_INIT_STRUCT): New.
	(sh_option_optimization): Don't set flag_finite_math_only here.
	* config/spu/spu.c (spu_option_optimization): Replace by
	spu_option_optimization.  Use options structure pointer.
	(TARGET_OPTION_OPTIMIZATION): Replace by
	TARGET_OPTION_INIT_STRUCT.

Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 165508)
+++ gcc/doc/tm.texi	(working copy)
@@ -812,6 +812,10 @@ this hook!}  The debugging options are n
 generated code.
 @end deftypefn
 
+@deftypefn {Target Hook} void TARGET_OPTION_INIT_STRUCT (struct gcc_options *@var{opts})
+Set target-dependent initial values of fields in @var{opts}.
+@end deftypefn
+
 @deftypefn {Target Hook} void TARGET_OPTION_DEFAULT_PARAMS (void)
 Set target-dependent default values for @option{--param} settings, using calls to @code{set_default_param_value}.
 @end deftypefn
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	(revision 165508)
+++ gcc/doc/tm.texi.in	(working copy)
@@ -812,6 +812,8 @@ this hook!}  The debugging options are n
 generated code.
 @end deftypefn
 
+@hook TARGET_OPTION_INIT_STRUCT
+
 @hook TARGET_OPTION_DEFAULT_PARAMS
 
 @hook TARGET_HELP
Index: gcc/hooks.c
===================================================================
--- gcc/hooks.c	(revision 165508)
+++ gcc/hooks.c	(working copy)
@@ -360,3 +360,10 @@ void
 hook_void_rtx_int (rtx insn ATTRIBUTE_UNUSED, int mode ATTRIBUTE_UNUSED)
 {
 }
+
+/* Generic hook that takes a struct gcc_options * and returns void.  */
+
+void
+hook_void_gcc_optionsp (struct gcc_options *opts ATTRIBUTE_UNUSED)
+{
+}
Index: gcc/hooks.h
===================================================================
--- gcc/hooks.h	(revision 165508)
+++ gcc/hooks.h	(working copy)
@@ -61,6 +61,7 @@ extern void hook_void_FILEptr_constcharp
 extern void hook_void_tree (tree);
 extern void hook_void_tree_treeptr (tree, tree *);
 extern void hook_void_int_int (int, int);
+extern void hook_void_gcc_optionsp (struct gcc_options *);
 
 extern int hook_int_const_tree_0 (const_tree);
 extern int hook_int_const_tree_const_tree_1 (const_tree, const_tree);
Index: gcc/target.def
===================================================================
--- gcc/target.def	(revision 165508)
+++ gcc/target.def	(working copy)
@@ -2356,6 +2356,12 @@ DEFHOOK
  void, (void),
  hook_void_void)
 
+DEFHOOK
+(init_struct,
+"Set target-dependent initial values of fields in @var{opts}.",
+ void, (struct gcc_options *opts),
+ hook_void_gcc_optionsp)
+
 /* Function to determine if one function can inline another function.  */
 #undef HOOK_PREFIX
 #define HOOK_PREFIX "TARGET_"
Index: gcc/opts.c
===================================================================
--- gcc/opts.c	(revision 165508)
+++ gcc/opts.c	(working copy)
@@ -695,6 +695,9 @@ init_options_struct (struct gcc_options 
 
   /* Some targets have ABI-specified unwind tables.  */
   opts->x_flag_unwind_tables = targetm.unwind_tables_default;
+
+  /* Some targets have other target-specific initialization.  */
+  targetm.target_option.init_struct (opts);
 }
 
 /* Decode command-line options to an array, like
Index: gcc/langhooks.c
===================================================================
--- gcc/langhooks.c	(revision 165508)
+++ gcc/langhooks.c	(working copy)
@@ -337,12 +337,6 @@ lhd_initialize_diagnostics (diagnostic_c
 {
 }
 
-/* Called to perform language-specific options initialization of OPTS.  */
-void
-lhd_init_options_struct (struct gcc_options *opts ATTRIBUTE_UNUSED)
-{
-}
-
 /* Called to perform language-specific options initialization.  */
 void
 lhd_init_options (unsigned int decoded_options_count ATTRIBUTE_UNUSED,
Index: gcc/config/s390/s390.c
===================================================================
--- gcc/config/s390/s390.c	(revision 165508)
+++ gcc/config/s390/s390.c	(working copy)
@@ -1503,15 +1503,21 @@ s390_option_optimization (int level ATTR
   /* ??? There are apparently still problems with -fcaller-saves.  */
   flag_caller_saves = 0;
 
-  /* By default, always emit DWARF-2 unwind info.  This allows debugging
-     without maintaining a stack frame back-chain.  */
-  flag_asynchronous_unwind_tables = 1;
-
   /* Use MVCLE instructions to decrease code size if requested.  */
   if (size != 0)
     target_flags |= MASK_MVCLE;
 }
 
+/* Implement TARGET_OPTION_INIT_STRUCT.  */
+
+static void
+s390_option_init_struct (struct gcc_options *opts)
+{
+  /* By default, always emit DWARF-2 unwind info.  This allows debugging
+     without maintaining a stack frame back-chain.  */
+  opts->x_flag_asynchronous_unwind_tables = 1;
+}
+
 /* Return true if ARG is the name of a processor.  Set *TYPE and *FLAGS
    to the associated processor_type and processor_flags if so.  */
 
@@ -10507,6 +10513,9 @@ s390_loop_unroll_adjust (unsigned nunrol
 #undef TARGET_OPTION_OPTIMIZATION
 #define TARGET_OPTION_OPTIMIZATION s390_option_optimization
 
+#undef TARGET_OPTION_INIT_STRUCT
+#define TARGET_OPTION_INIT_STRUCT s390_option_init_struct
+
 #undef	TARGET_ENCODE_SECTION_INFO
 #define TARGET_ENCODE_SECTION_INFO s390_encode_section_info
 
Index: gcc/config/spu/spu.c
===================================================================
--- gcc/config/spu/spu.c	(revision 165508)
+++ gcc/config/spu/spu.c	(working copy)
@@ -150,7 +150,7 @@ char regs_ever_allocated[FIRST_PSEUDO_RE
 
 /*  Prototypes and external defs.  */
 static void spu_option_override (void);
-static void spu_option_optimization (int, int);
+static void spu_option_init_struct (struct gcc_options *opts);
 static void spu_option_default_params (void);
 static void spu_init_builtins (void);
 static tree spu_builtin_decl (unsigned, bool);
@@ -480,8 +480,8 @@ static const struct attribute_spec spu_a
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE spu_option_override
 
-#undef TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION spu_option_optimization
+#undef TARGET_OPTION_INIT_STRUCT
+#define TARGET_OPTION_INIT_STRUCT spu_option_init_struct
 
 #undef TARGET_OPTION_DEFAULT_PARAMS
 #define TARGET_OPTION_DEFAULT_PARAMS spu_option_default_params
@@ -492,10 +492,10 @@ static const struct attribute_spec spu_a
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 static void
-spu_option_optimization (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
+spu_option_init_struct (struct gcc_options *opts)
 {
   /* With so many registers this is better on by default. */
-  flag_rename_registers = 1;
+  opts->x_flag_rename_registers = 1;
 }
 
 /* Implement TARGET_OPTION_DEFAULT_PARAMS.  */
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 165508)
+++ gcc/config/i386/i386.c	(working copy)
@@ -4537,11 +4537,6 @@ ix86_option_optimization (int level, int
     flag_schedule_insns = 0;
 #endif
 
-  if (TARGET_MACHO)
-    /* The Darwin libraries never set errno, so we might as well
-       avoid calling them when that's the only reason we would.  */
-    flag_errno_math = 0;
-
   /* The default values of these switches depend on the TARGET_64BIT
      that is not known at this moment.  Mark these values with 2 and
      let user the to override these.  In case there is no command line
@@ -4554,14 +4549,26 @@ ix86_option_optimization (int level, int
   if (level > 1)
     flag_zee = 2;
 
-  flag_pcc_struct_return = 2;
-  flag_asynchronous_unwind_tables = 2;
-  flag_vect_cost_model = 1;
 #ifdef SUBTARGET_OPTIMIZATION_OPTIONS
   SUBTARGET_OPTIMIZATION_OPTIONS;
 #endif
 }
 
+/* Implement TARGET_OPTION_INIT_STRUCT.  */
+
+static void
+ix86_option_init_struct (struct gcc_options *opts)
+{
+  if (TARGET_MACHO)
+    /* The Darwin libraries never set errno, so we might as well
+       avoid calling them when that's the only reason we would.  */
+    opts->x_flag_errno_math = 0;
+
+  opts->x_flag_pcc_struct_return = 2;
+  opts->x_flag_asynchronous_unwind_tables = 2;
+  opts->x_flag_vect_cost_model = 1;
+}
+
 /* Decide whether we must probe the stack before any space allocation
    on this target.  It's essentially TARGET_STACK_PROBE except when
    -fstack-check causes the stack to be already probed differently.  */
@@ -33269,6 +33276,8 @@ ix86_autovectorize_vector_sizes (void)
 #define TARGET_OPTION_OVERRIDE ix86_option_override
 #undef TARGET_OPTION_OPTIMIZATION
 #define TARGET_OPTION_OPTIMIZATION ix86_option_optimization
+#undef TARGET_OPTION_INIT_STRUCT
+#define TARGET_OPTION_INIT_STRUCT ix86_option_init_struct
 
 #undef TARGET_REGISTER_MOVE_COST
 #define TARGET_REGISTER_MOVE_COST ix86_register_move_cost
Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c	(revision 165508)
+++ gcc/config/sh/sh.c	(working copy)
@@ -184,6 +184,7 @@ static rtx gen_block_redirect (rtx, int,
 static void sh_reorg (void);
 static void sh_option_override (void);
 static void sh_option_optimization (int, int);
+static void sh_option_init_struct (struct gcc_options *);
 static void sh_option_default_params (void);
 static void output_stack_adjust (int, rtx, int, HARD_REG_SET *, bool);
 static rtx frame_insn (rtx);
@@ -343,6 +344,8 @@ static const struct attribute_spec sh_at
 #define TARGET_OPTION_OVERRIDE sh_option_override
 #undef TARGET_OPTION_OPTIMIZATION
 #define TARGET_OPTION_OPTIMIZATION sh_option_optimization
+#undef TARGET_OPTION_INIT_STRUCT
+#define TARGET_OPTION_INIT_STRUCT sh_option_init_struct
 #undef TARGET_OPTION_DEFAULT_PARAMS
 #define TARGET_OPTION_DEFAULT_PARAMS sh_option_default_params
 
@@ -725,17 +728,23 @@ sh_option_optimization (int level, int s
       if (!size)
 	target_flags |= MASK_SAVE_ALL_TARGET_REGS;
     }
-  /* Likewise, we can't meaningfully test TARGET_SH2E / TARGET_IEEE
-     here, so leave it to TARGET_OPTION_OVERRIDE to set
-    flag_finite_math_only.  We set it to 2 here so we know if the user
-    explicitly requested this to be on or off.  */
-  flag_finite_math_only = 2;
   /* If flag_schedule_insns is 1, we set it to 2 here so we know if
      the user explicitly requested this to be on or off.  */
   if (flag_schedule_insns > 0)
     flag_schedule_insns = 2;
 }
 
+/* Implement TARGET_OPTION_INIT_STRUCT.  */
+static void
+sh_option_init_struct (struct gcc_options *opts)
+{
+  /* We can't meaningfully test TARGET_SH2E / TARGET_IEEE
+     here, so leave it to TARGET_OPTION_OVERRIDE to set
+     flag_finite_math_only.  We set it to 2 here so we know if the user
+     explicitly requested this to be on or off.  */
+  opts->x_flag_finite_math_only = 2;
+}
+
 /* Implement TARGET_OPTION_DEFAULT_PARAMS.  */
 static void
 sh_option_default_params (void)
Index: gcc/config/pdp11/pdp11.c
===================================================================
--- gcc/config/pdp11/pdp11.c	(revision 165508)
+++ gcc/config/pdp11/pdp11.c	(working copy)
@@ -146,6 +146,7 @@ decode_pdp11_d (const struct real_format
 
 static bool pdp11_handle_option (size_t, const char *, int);
 static void pdp11_option_optimization (int, int);
+static void pdp11_option_init_struct (struct gcc_options *);
 static rtx find_addr_reg (rtx); 
 static const char *singlemove_string (rtx *);
 static bool pdp11_assemble_integer (rtx, unsigned int, int);
@@ -189,6 +190,8 @@ static void pdp11_function_arg_advance (
 #define TARGET_HANDLE_OPTION pdp11_handle_option
 #undef TARGET_OPTION_OPTIMIZATION
 #define TARGET_OPTION_OPTIMIZATION pdp11_option_optimization
+#undef TARGET_OPTION_INIT_STRUCT
+#define TARGET_OPTION_INIT_STRUCT pdp11_option_init_struct
 
 #undef TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS pdp11_rtx_costs
@@ -235,9 +238,6 @@ pdp11_handle_option (size_t code, const 
 static void
 pdp11_option_optimization (int level, int size ATTRIBUTE_UNUSED)
 {
-  flag_finite_math_only = 0;
-  flag_trapping_math = 0;
-  flag_signaling_nans = 0;
   if (level >= 3)
     {
       flag_omit_frame_pointer = 1;
@@ -245,6 +245,16 @@ pdp11_option_optimization (int level, in
     }
 }
 
+/* Implement TARGET_OPTION_INIT_STRUCT.  */
+
+static void
+pdp11_option_init_struct (struct gcc_options *opts)
+{
+  opts->x_flag_finite_math_only = 0;
+  opts->x_flag_trapping_math = 0;
+  opts->x_flag_signaling_nans = 0;
+}
+
 /* Nonzero if OP is a valid second operand for an arithmetic insn.  */
 
 int
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 165508)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -1136,7 +1136,7 @@ static rtx altivec_expand_vec_set_builti
 static rtx altivec_expand_vec_ext_builtin (tree, rtx);
 static int get_element_number (tree, tree);
 static void rs6000_option_override (void);
-static void rs6000_option_optimization (int, int);
+static void rs6000_option_init_struct (struct gcc_options *);
 static void rs6000_option_default_params (void);
 static bool rs6000_handle_option (size_t, const char *, int);
 static void rs6000_parse_tls_size_option (void);
@@ -1602,8 +1602,8 @@ static const struct attribute_spec rs600
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE rs6000_option_override
 
-#undef TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION rs6000_option_optimization
+#undef TARGET_OPTION_INIT_STRUCT
+#define TARGET_OPTION_INIT_STRUCT rs6000_option_init_struct
 
 #undef TARGET_OPTION_DEFAULT_PARAMS
 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
@@ -3681,18 +3681,19 @@ rs6000_parse_tls_size_option (void)
     error ("bad value %qs for -mtls-size switch", rs6000_tls_size_string);
 }
 
+/* Implement TARGET_OPTION_INIT_STRUCT.  */
+
 static void
-rs6000_option_optimization (int level ATTRIBUTE_UNUSED,
-			    int size ATTRIBUTE_UNUSED)
+rs6000_option_init_struct (struct gcc_options *opts)
 {
   if (DEFAULT_ABI == ABI_DARWIN)
     /* The Darwin libraries never set errno, so we might as well
        avoid calling them when that's the only reason we would.  */
-    flag_errno_math = 0;
+    opts->x_flag_errno_math = 0;
 
   /* Enable section anchors by default.  */
   if (!TARGET_MACHO)
-    flag_section_anchors = 2;
+    opts->x_flag_section_anchors = 2;
 }
 
 /* Implement TARGET_OPTION_DEFAULT_PARAMS.  */
Index: gcc/langhooks-def.h
===================================================================
--- gcc/langhooks-def.h	(revision 165508)
+++ gcc/langhooks-def.h	(working copy)
@@ -65,7 +65,6 @@ extern tree lhd_builtin_function (tree);
 
 /* Declarations of default tree inlining hooks.  */
 extern void lhd_initialize_diagnostics (diagnostic_context *);
-extern void lhd_init_options_struct (struct gcc_options *);
 extern void lhd_init_options (unsigned int,
 			      struct cl_decoded_option *);
 extern bool lhd_complain_wrong_lang_p (const struct cl_option *);
@@ -88,7 +87,7 @@ extern void lhd_omp_firstprivatize_type_
 #define LANG_HOOKS_FINISH		lhd_do_nothing
 #define LANG_HOOKS_PARSE_FILE		lhd_do_nothing_i
 #define LANG_HOOKS_OPTION_LANG_MASK	hook_uint_void_0
-#define LANG_HOOKS_INIT_OPTIONS_STRUCT	lhd_init_options_struct
+#define LANG_HOOKS_INIT_OPTIONS_STRUCT	hook_void_gcc_optionsp
 #define LANG_HOOKS_INIT_OPTIONS		lhd_init_options
 #define LANG_HOOKS_INITIALIZE_DIAGNOSTICS lhd_initialize_diagnostics
 #define LANG_HOOKS_COMPLAIN_WRONG_LANG_P lhd_complain_wrong_lang_p
