diff mbox

Table-based default_options_optimization

Message ID Pine.LNX.4.64.1010211708380.2491@digraph.polyomino.org.uk
State New
Headers show

Commit Message

Joseph Myers Oct. 21, 2010, 5:09 p.m. UTC
This patch converts default_options_optimization, along with the hooks
it uses, to be based on tables of options implied by different
optimization level, and to work entirely on gcc_options structures
instead of global variables.

A new TARGET_OPTION_OPTIMIZATION_TABLE hook is created, which replaces
not just TARGET_OPTION_OPTIMIZATION but also TARGET_HANDLE_OFAST (not
currently defined by any target) and the target macro
CAN_DEBUG_WITHOUT_FP.

The old function would generally set variables unconditionally, to a
value of 0 or 1 depending on the optimization level, so that optimize
attributes reducing the level work properly.  The old
TARGET_OPTION_OPTIMIZATION hooks generally did not do so; with this
patch, all the options implied by -O options are now handled
consistently the same way.

This unconditional setting of variables means that Init settings for
variables so set are meaningless and potentially confusing.  Thus this
patch removes such settings for flag_tree_ter and
flag_rerun_cse_after_loop - and dead code in toplev.c to default the
latter variable.

Because of how the variables were set, the code

  if (flag_ipa_cp_clone)
    flag_ipa_cp = 1;

was redundant so has no direct equivalent in the table.  Some target
hooks also had redundant conditionals such as "level || size" (-Os
implies level 2).  The new code is intended to enable the same
options, but not necessarily reproducing the literal logic used to do
so.  As another example, alignment options were set on a -O1-and-below
basis, and are now described on the equivalent -O2-and-above basis.
This showed up that the semantics of -falign-loops and
-fno-align-loops had been reversed since the Var facility in .opt
files was added in r83105, which is fixed by this patch.  (For those
options, a value of 0 means enabled and 1 means disabled.)  The
alignment options are documented as disabled with -Os; there is no
direct indication of this in the code since it's handled on a
per-function or per-basic-block basis (or so I understand) since
r139801.

The SH changes are more complicated than those for other targets.
Optimization options could enable MASK_SMALLCODE and
MASK_SAVE_ALL_TARGET_REGS.  The former corresponded to a deprecated
-mspace option; rather than having -Os imply a deprecated option, I
made the deprecated option into an alias for -Os and changed all the
TARGET_SMALLCODE tests to test optimize_size.  (Some should probably
move to being on a per-basic-block basis; I leave that to the SH
maintainers.)  There is no option corresponding to
MASK_SAVE_ALL_TARGET_REGS, and the tables can only represent implying
options, not settings without a corresponding option, so I moved that
implication into sh_option_override.

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  Also
tested building cc1 for crosses to: alpha-linux-gnu arm-eabi avr-elf
cris-elf crx-elf fr30-elf frv-elf h8300-elf i386-solaris2.10 ia64-elf
ia64-hp-vms iq2000-elf lm32-elf m32r-elf mcore-elf mep-elf
microblaze-elf mips-elf mmix-knuth-mmixware mn10300-elf hppa-linux-gnu
pdp11-none picochip-none powerpc-eabi rx-elf s390-linux-gnu score-elf
sh-elf sparc-elf xstormy16-elf v850-elf xtensa-elf.  (The mn10300
build was broken for other reasons at the revision I tested:
"mn10300.md:1798: unknown mode `CC_FLOAT'".)  OK to commit?

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

	* target.h (enum opt_levels, struct default_options): New.
	* target.def (handle_ofast): Remove hook.
	(target_option.optimization): Change to
	target_option.optimization_table.
	* doc/tm.texi.in (TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	(CAN_DEBUG_WITHOUT_FP): Remove.
	* doc/tm.texi: Regenerate.
	* opts.c (maybe_default_option, maybe_default_options,
	default_options_table): New.
	(default_options_optimization): Take extra parameters.  Don't
	assert that global_options and global_options_set are in use.  Use
	maybe_default_options.
	(decode_options): Pass extra parameters to
	default_options_optimization.
	* common.opt (falign-loops): Use value 0 with Var.
	(frerun-cse-after-loop, ftree-ter): Remove Init.
	* system.h (CAN_DEBUG_WITHOUT_FP, TARGET_HANDLE_OFAST,
	TARGET_OPTION_OPTIMIZATION): Remove.
	* targhooks.c (empty_optimization_table): New.
	* targhooks.h (empty_optimization_table): Declare.
	* toplev.c (process_options): Don't set flag_rerun_cse_after_loop.
	* config/alpha/alpha.c (alpha_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/alpha/alpha.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/arm/arm.c (arm_option_optimization: Change to
	arm_option_optimization_table.
	(TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	* config/arm/arm.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/avr/avr.c (avr_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/avr/avr.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/cris/cris.c (cris_option_optimization): Change to
	cris_option_optimization_table.
	(TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	* config/crx/crx.c (crx_option_optimization): Change to
	crx_option_optimization_table.
	(TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	* config/crx/crx.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/fr30/fr30.c (fr30_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/fr30/fr30.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/frv/frv.c (frv_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/frv/frv.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/h8300/h8300.c (h8300_option_optimization): Change to
	h8300_option_optimization_table.
	(TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	* config/h8300/h8300.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/i386/i386.c (ix86_option_optimization): Change to
	ix86_option_optimization_table.
	(TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	* config/i386/sol2-10.h (SUBTARGET_OPTIMIZATION_OPTIONS): Define
	as initializer.
	* config/ia64/ia64.c (ia64_option_optimization): Change to
	ia64_option_optimization_table.
	(TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	* config/ia64/ia64.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/ia64/vms.h (SUBTARGET_OPTIMIZATION_OPTIONS): Define as
	initializer.
	* config/iq2000/iq2000.c (iq2000_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/iq2000/iq2000.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/lm32/lm32.c (lm32_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/lm32/lm32.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/m32r/m32r.c (m32r_option_optimization): Change to
	m32r_option_optimization_table.
	(TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	* config/m32r/m32r.h (SUBTARGET_OPTIMIZATION_OPTIONS,
	CAN_DEBUG_WITHOUT_FP): Remove.
	* config/mcore/mcore.c (mcore_option_optimization): Change to
	mcore_option_optimization_table.
	(TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	* config/mep/mep.c (mep_option_optimization): Change to
	mep_option_optimization_table.
	(TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	* config/mep/mep.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/microblaze/microblaze.c
	(microblaze_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/microblaze/microblaze.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/mips/mips.c (mips_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/mips/mips.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/mmix/mmix.c (mmix_option_optimization): Change to
	mmix_option_optimization_table.
	(TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	* config/mmix/mmix.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/mn10300/mn10300.c (mn10300_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/mn10300/mn10300.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/pa/pa.c (pa_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/pa/pa.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/pdp11/pdp11.c (pdp11_option_optimization): Change to
	pdp11_option_optimization_table.
	(TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	* config/picochip/picochip.c (picochip_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/picochip/picochip.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/rs6000/rs6000.c (rs6000_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/rs6000/rs6000.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/rx/rx.c (rx_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/rx/rx.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/s390/s390.c (s390_option_optimization): Change to
	s390_option_optimization_table.
	(s390_option_override): Update comment.
	(TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	* config/s390/s390.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/score/score.c (score_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/score/score.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/sh/sh.c (sh_option_optimization): Change to
	sh_option_optimization_table.
	(TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	(sh_option_override): Set MASK_SAVE_ALL_TARGET_REGS here.
	(sh_option_override, expand_block_move, multcosts, find_barrier,
	barrier_align): Use optimize_size instead of TARGET_SMALLCODE.
	* config/sh/sh.h (CAN_DEBUG_WITHOUT_FP): Remove.
	(LOOP_ALIGN, TRAMPOLINE_ALIGNMENT, MOVE_BY_PIECES_P,
	STORE_BY_PIECES_P, SH_DYNAMIC_SHIFT_COST): Use optimize_size
	instead of TARGET_SMALLCODE.
	* config/sh/sh.opt (mspace): Make into an alias for -Os.
	* config/sparc/sparc.c (sparc_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/sparc/sparc.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/stormy16/stormy16.c (xstorym16_option_optimization_table,
	TARGET_OPTION_OPTIMIZATION_TABLE): New.
	* config/stormy16/stormy16.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/v850/v850.c (v850_option_optimization): Change to
	v850_option_optimization_table.
	(TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	* config/v850/v850.h (CAN_DEBUG_WITHOUT_FP): Remove.
	* config/xtensa/xtensa.c (xtensa_option_optimization): Change to
	xtensa_option_optimization_table.
	(TARGET_OPTION_OPTIMIZATION): Change to
	TARGET_OPTION_OPTIMIZATION_TABLE.
	* config/xtensa/xtensa.h (CAN_DEBUG_WITHOUT_FP): Remove.

Comments

Paul Koning Oct. 21, 2010, 5:29 p.m. UTC | #1
pdp11 looks good.  Thanks!

	paul

On Oct 21, 2010, at 1:09 PM, Joseph S. Myers wrote:

> This patch converts default_options_optimization, along with the hooks
> it uses, to be based on tables of options implied by different
> optimization level, and to work entirely on gcc_options structures
> instead of global variables....  OK to commit?
Richard Biener Oct. 22, 2010, 9:23 a.m. UTC | #2
On Thu, Oct 21, 2010 at 7:09 PM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> This patch converts default_options_optimization, along with the hooks
> it uses, to be based on tables of options implied by different
> optimization level, and to work entirely on gcc_options structures
> instead of global variables.
>
> A new TARGET_OPTION_OPTIMIZATION_TABLE hook is created, which replaces
> not just TARGET_OPTION_OPTIMIZATION but also TARGET_HANDLE_OFAST (not
> currently defined by any target) and the target macro
> CAN_DEBUG_WITHOUT_FP.
>
> The old function would generally set variables unconditionally, to a
> value of 0 or 1 depending on the optimization level, so that optimize
> attributes reducing the level work properly.  The old
> TARGET_OPTION_OPTIMIZATION hooks generally did not do so; with this
> patch, all the options implied by -O options are now handled
> consistently the same way.
>
> This unconditional setting of variables means that Init settings for
> variables so set are meaningless and potentially confusing.  Thus this
> patch removes such settings for flag_tree_ter and
> flag_rerun_cse_after_loop - and dead code in toplev.c to default the
> latter variable.
>
> Because of how the variables were set, the code
>
>  if (flag_ipa_cp_clone)
>    flag_ipa_cp = 1;
>
> was redundant so has no direct equivalent in the table.  Some target
> hooks also had redundant conditionals such as "level || size" (-Os
> implies level 2).  The new code is intended to enable the same
> options, but not necessarily reproducing the literal logic used to do
> so.  As another example, alignment options were set on a -O1-and-below
> basis, and are now described on the equivalent -O2-and-above basis.
> This showed up that the semantics of -falign-loops and
> -fno-align-loops had been reversed since the Var facility in .opt
> files was added in r83105, which is fixed by this patch.  (For those
> options, a value of 0 means enabled and 1 means disabled.)  The
> alignment options are documented as disabled with -Os; there is no
> direct indication of this in the code since it's handled on a
> per-function or per-basic-block basis (or so I understand) since
> r139801.
>
> The SH changes are more complicated than those for other targets.
> Optimization options could enable MASK_SMALLCODE and
> MASK_SAVE_ALL_TARGET_REGS.  The former corresponded to a deprecated
> -mspace option; rather than having -Os imply a deprecated option, I
> made the deprecated option into an alias for -Os and changed all the
> TARGET_SMALLCODE tests to test optimize_size.  (Some should probably
> move to being on a per-basic-block basis; I leave that to the SH
> maintainers.)  There is no option corresponding to
> MASK_SAVE_ALL_TARGET_REGS, and the tables can only represent implying
> options, not settings without a corresponding option, so I moved that
> implication into sh_option_override.
>
> Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  Also
> tested building cc1 for crosses to: alpha-linux-gnu arm-eabi avr-elf
> cris-elf crx-elf fr30-elf frv-elf h8300-elf i386-solaris2.10 ia64-elf
> ia64-hp-vms iq2000-elf lm32-elf m32r-elf mcore-elf mep-elf
> microblaze-elf mips-elf mmix-knuth-mmixware mn10300-elf hppa-linux-gnu
> pdp11-none picochip-none powerpc-eabi rx-elf s390-linux-gnu score-elf
> sh-elf sparc-elf xstormy16-elf v850-elf xtensa-elf.  (The mn10300
> build was broken for other reasons at the revision I tested:
> "mn10300.md:1798: unknown mode `CC_FLOAT'".)  OK to commit?

Ok for the non-SH parts.

Thanks,
Richard.

> 2010-10-21  Joseph Myers  <joseph@codesourcery.com>
>
>        * target.h (enum opt_levels, struct default_options): New.
>        * target.def (handle_ofast): Remove hook.
>        (target_option.optimization): Change to
>        target_option.optimization_table.
>        * doc/tm.texi.in (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        (CAN_DEBUG_WITHOUT_FP): Remove.
>        * doc/tm.texi: Regenerate.
>        * opts.c (maybe_default_option, maybe_default_options,
>        default_options_table): New.
>        (default_options_optimization): Take extra parameters.  Don't
>        assert that global_options and global_options_set are in use.  Use
>        maybe_default_options.
>        (decode_options): Pass extra parameters to
>        default_options_optimization.
>        * common.opt (falign-loops): Use value 0 with Var.
>        (frerun-cse-after-loop, ftree-ter): Remove Init.
>        * system.h (CAN_DEBUG_WITHOUT_FP, TARGET_HANDLE_OFAST,
>        TARGET_OPTION_OPTIMIZATION): Remove.
>        * targhooks.c (empty_optimization_table): New.
>        * targhooks.h (empty_optimization_table): Declare.
>        * toplev.c (process_options): Don't set flag_rerun_cse_after_loop.
>        * config/alpha/alpha.c (alpha_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/alpha/alpha.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/arm/arm.c (arm_option_optimization: Change to
>        arm_option_optimization_table.
>        (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        * config/arm/arm.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/avr/avr.c (avr_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/avr/avr.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/cris/cris.c (cris_option_optimization): Change to
>        cris_option_optimization_table.
>        (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        * config/crx/crx.c (crx_option_optimization): Change to
>        crx_option_optimization_table.
>        (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        * config/crx/crx.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/fr30/fr30.c (fr30_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/fr30/fr30.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/frv/frv.c (frv_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/frv/frv.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/h8300/h8300.c (h8300_option_optimization): Change to
>        h8300_option_optimization_table.
>        (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        * config/h8300/h8300.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/i386/i386.c (ix86_option_optimization): Change to
>        ix86_option_optimization_table.
>        (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        * config/i386/sol2-10.h (SUBTARGET_OPTIMIZATION_OPTIONS): Define
>        as initializer.
>        * config/ia64/ia64.c (ia64_option_optimization): Change to
>        ia64_option_optimization_table.
>        (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        * config/ia64/ia64.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/ia64/vms.h (SUBTARGET_OPTIMIZATION_OPTIONS): Define as
>        initializer.
>        * config/iq2000/iq2000.c (iq2000_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/iq2000/iq2000.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/lm32/lm32.c (lm32_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/lm32/lm32.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/m32r/m32r.c (m32r_option_optimization): Change to
>        m32r_option_optimization_table.
>        (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        * config/m32r/m32r.h (SUBTARGET_OPTIMIZATION_OPTIONS,
>        CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/mcore/mcore.c (mcore_option_optimization): Change to
>        mcore_option_optimization_table.
>        (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        * config/mep/mep.c (mep_option_optimization): Change to
>        mep_option_optimization_table.
>        (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        * config/mep/mep.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/microblaze/microblaze.c
>        (microblaze_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/microblaze/microblaze.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/mips/mips.c (mips_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/mips/mips.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/mmix/mmix.c (mmix_option_optimization): Change to
>        mmix_option_optimization_table.
>        (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        * config/mmix/mmix.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/mn10300/mn10300.c (mn10300_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/mn10300/mn10300.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/pa/pa.c (pa_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/pa/pa.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/pdp11/pdp11.c (pdp11_option_optimization): Change to
>        pdp11_option_optimization_table.
>        (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        * config/picochip/picochip.c (picochip_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/picochip/picochip.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/rs6000/rs6000.c (rs6000_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/rs6000/rs6000.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/rx/rx.c (rx_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/rx/rx.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/s390/s390.c (s390_option_optimization): Change to
>        s390_option_optimization_table.
>        (s390_option_override): Update comment.
>        (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        * config/s390/s390.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/score/score.c (score_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/score/score.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/sh/sh.c (sh_option_optimization): Change to
>        sh_option_optimization_table.
>        (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        (sh_option_override): Set MASK_SAVE_ALL_TARGET_REGS here.
>        (sh_option_override, expand_block_move, multcosts, find_barrier,
>        barrier_align): Use optimize_size instead of TARGET_SMALLCODE.
>        * config/sh/sh.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        (LOOP_ALIGN, TRAMPOLINE_ALIGNMENT, MOVE_BY_PIECES_P,
>        STORE_BY_PIECES_P, SH_DYNAMIC_SHIFT_COST): Use optimize_size
>        instead of TARGET_SMALLCODE.
>        * config/sh/sh.opt (mspace): Make into an alias for -Os.
>        * config/sparc/sparc.c (sparc_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/sparc/sparc.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/stormy16/stormy16.c (xstorym16_option_optimization_table,
>        TARGET_OPTION_OPTIMIZATION_TABLE): New.
>        * config/stormy16/stormy16.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/v850/v850.c (v850_option_optimization): Change to
>        v850_option_optimization_table.
>        (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        * config/v850/v850.h (CAN_DEBUG_WITHOUT_FP): Remove.
>        * config/xtensa/xtensa.c (xtensa_option_optimization): Change to
>        xtensa_option_optimization_table.
>        (TARGET_OPTION_OPTIMIZATION): Change to
>        TARGET_OPTION_OPTIMIZATION_TABLE.
>        * config/xtensa/xtensa.h (CAN_DEBUG_WITHOUT_FP): Remove.
>
> Index: gcc/doc/tm.texi
> ===================================================================
> --- gcc/doc/tm.texi     (revision 165714)
> +++ gcc/doc/tm.texi     (working copy)
> @@ -791,26 +791,19 @@ used to alter option flag variables whic
>  frontends.
>  @end defmac
>
> -@deftypefn {Target Hook} void TARGET_OPTION_OPTIMIZATION (int @var{level}, int @var{size})
> +@deftypevr {Target Hook} {const struct default_options *} TARGET_OPTION_OPTIMIZATION_TABLE
>  Some machines may desire to change what optimizations are performed for
> -various optimization levels.   This hook, if defined, is executed once
> +various optimization levels.   This variable, if defined, describes
> +options to enable at particular sets of optimization levels.  These
> +options are processed once
>  just after the optimization level is determined and before the remainder
> -of the command options have been parsed.  Values set in this macro are
> -used as the default values for the other command line options.
> +of the command options have been parsed, so may be overridden by other
> +options passed explicily.
>
> -@var{level} is the optimization level specified; 2 if @option{-O2} is
> -specified, 1 if @option{-O} is specified, and 0 if neither is specified.
> -
> -@var{size} is nonzero if @option{-Os} is specified and zero otherwise.
> -
> -This macro is run once at program startup and when the optimization
> +This processing is run once at program startup and when the optimization
>  options are changed via @code{#pragma GCC optimize} or by using the
>  @code{optimize} attribute.
> -
> -@strong{Do not examine @code{write_symbols} in
> -this hook!}  The debugging options are not supposed to alter the
> -generated code.
> -@end deftypefn
> +@end deftypevr
>
>  @deftypefn {Target Hook} void TARGET_OPTION_INIT_STRUCT (struct gcc_options *@var{opts})
>  Set target-dependent initial values of fields in @var{opts}.
> @@ -827,12 +820,6 @@ chance to display extra information on t
>  line options found in its @file{.opt} file.
>  @end deftypefn
>
> -@defmac CAN_DEBUG_WITHOUT_FP
> -Define this macro if debugging can be performed even without a frame
> -pointer.  If this macro is defined, GCC will turn on the
> -@option{-fomit-frame-pointer} option whenever @option{-O} is specified.
> -@end defmac
> -
>  @defmac SWITCHABLE_TARGET
>  Some targets need to switch between substantially different subtargets
>  during compilation.  For example, the MIPS target has one subtarget for
> Index: gcc/doc/tm.texi.in
> ===================================================================
> --- gcc/doc/tm.texi.in  (revision 165714)
> +++ gcc/doc/tm.texi.in  (working copy)
> @@ -791,26 +791,19 @@ used to alter option flag variables whic
>  frontends.
>  @end defmac
>
> -@hook TARGET_OPTION_OPTIMIZATION
> +@hook TARGET_OPTION_OPTIMIZATION_TABLE
>  Some machines may desire to change what optimizations are performed for
> -various optimization levels.   This hook, if defined, is executed once
> +various optimization levels.   This variable, if defined, describes
> +options to enable at particular sets of optimization levels.  These
> +options are processed once
>  just after the optimization level is determined and before the remainder
> -of the command options have been parsed.  Values set in this macro are
> -used as the default values for the other command line options.
> +of the command options have been parsed, so may be overridden by other
> +options passed explicily.
>
> -@var{level} is the optimization level specified; 2 if @option{-O2} is
> -specified, 1 if @option{-O} is specified, and 0 if neither is specified.
> -
> -@var{size} is nonzero if @option{-Os} is specified and zero otherwise.
> -
> -This macro is run once at program startup and when the optimization
> +This processing is run once at program startup and when the optimization
>  options are changed via @code{#pragma GCC optimize} or by using the
>  @code{optimize} attribute.
> -
> -@strong{Do not examine @code{write_symbols} in
> -this hook!}  The debugging options are not supposed to alter the
> -generated code.
> -@end deftypefn
> +@end deftypevr
>
>  @hook TARGET_OPTION_INIT_STRUCT
>
> @@ -823,12 +816,6 @@ chance to display extra information on t
>  line options found in its @file{.opt} file.
>  @end deftypefn
>
> -@defmac CAN_DEBUG_WITHOUT_FP
> -Define this macro if debugging can be performed even without a frame
> -pointer.  If this macro is defined, GCC will turn on the
> -@option{-fomit-frame-pointer} option whenever @option{-O} is specified.
> -@end defmac
> -
>  @defmac SWITCHABLE_TARGET
>  Some targets need to switch between substantially different subtargets
>  during compilation.  For example, the MIPS target has one subtarget for
> Index: gcc/targhooks.c
> ===================================================================
> --- gcc/targhooks.c     (revision 165714)
> +++ gcc/targhooks.c     (working copy)
> @@ -1333,4 +1333,9 @@ sjlj_except_unwind_info (void)
>   return UI_SJLJ;
>  }
>
> +const struct default_options empty_optimization_table[] =
> +  {
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
> +
>  #include "gt-targhooks.h"
> Index: gcc/targhooks.h
> ===================================================================
> --- gcc/targhooks.h     (revision 165714)
> +++ gcc/targhooks.h     (working copy)
> @@ -167,3 +167,5 @@ extern int default_label_align_after_bar
>  extern int default_loop_align_max_skip (rtx);
>  extern int default_label_align_max_skip (rtx);
>  extern int default_jump_align_max_skip (rtx);
> +
> +extern const struct default_options empty_optimization_table[];
> Index: gcc/target.def
> ===================================================================
> --- gcc/target.def      (revision 165714)
> +++ gcc/target.def      (working copy)
> @@ -961,13 +961,6 @@ DEFHOOK
>  bool, (size_t code, const char *arg, int value),
>  hook_bool_size_t_constcharptr_int_true)
>
> -/* ??? Documenting this hook requires a GFDL license grant.  */
> -DEFHOOK_UNDOC
> -(handle_ofast,
> - "Handle target-specific parts of specifying -Ofast.",
> - void, (void),
> - hook_void_void)
> -
>  /* Display extra, target specific information in response to a
>    --target-help switch.  */
>  DEFHOOK
> @@ -2384,11 +2377,10 @@ DEFHOOK
>  hook_void_void)
>
>  /* Set default optimizations for the target.  */
> -DEFHOOK
> -(optimization,
> +DEFHOOKPOD
> +(optimization_table,
>  "",
> - void, (int level, int size),
> - hook_void_int_int)
> + const struct default_options *, empty_optimization_table)
>
>  DEFHOOK
>  (default_params,
> Index: gcc/target.h
> ===================================================================
> --- gcc/target.h        (revision 165714)
> +++ gcc/target.h        (working copy)
> @@ -128,6 +128,41 @@ enum vect_cost_for_stmt
>   vec_perm
>  };
>
> +/* Sets of optimization levels at which an option may be enabled by
> +   default_options_optimization.  */
> +enum opt_levels
> +{
> +  OPT_LEVELS_NONE, /* No levels (mark end of array).  */
> +  OPT_LEVELS_ALL, /* All levels (used by targets to disable options
> +                    enabled in target-independent code).  */
> +  OPT_LEVELS_0_ONLY, /* -O0 only.  */
> +  OPT_LEVELS_1_PLUS, /* -O1 and above, including -Os.  */
> +  OPT_LEVELS_1_PLUS_SPEED_ONLY, /* -O1 and above, but not -Os.  */
> +  OPT_LEVELS_2_PLUS, /* -O2 and above, including -Os.  */
> +  OPT_LEVELS_2_PLUS_SPEED_ONLY, /* -O2 and above, but not -Os.  */
> +  OPT_LEVELS_3_PLUS, /* -O3 and above.  */
> +  OPT_LEVELS_3_PLUS_AND_SIZE, /* -O3 and above and -Os.  */
> +  OPT_LEVELS_SIZE, /* -Os only.  */
> +  OPT_LEVELS_FAST /* -Ofast only.  */
> +};
> +
> +/* Description of options to enable by default at given levels.  */
> +struct default_options
> +{
> +  /* The levels at which to enable the option.  */
> +  enum opt_levels levels;
> +
> +  /* The option index and argument or enabled/disabled sense of the
> +     option, as passed to handle_generated_option.  If ARG is NULL and
> +     the option allows a negative form, the option is considered to be
> +     passed in negative form when the optimization level is not one of
> +     those in LEVELS (in order to handle changes to the optimization
> +     level with the "optimize" attribute).  */
> +  size_t opt_index;
> +  const char *arg;
> +  int value;
> +};
> +
>  /* The target structure.  This holds all the backend hooks.  */
>  #define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME;
>  #define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS;
> Index: gcc/toplev.c
> ===================================================================
> --- gcc/toplev.c        (revision 165714)
> +++ gcc/toplev.c        (working copy)
> @@ -1822,11 +1822,7 @@ process_options (void)
>   if (flag_unroll_all_loops)
>     flag_unroll_loops = 1;
>
> -  /* The loop unrolling code assumes that cse will be run after loop.
> -     web and rename-registers also help when run after loop unrolling.  */
> -  if (flag_rerun_cse_after_loop == AUTODETECT_VALUE)
> -    flag_rerun_cse_after_loop = flag_unroll_loops || flag_peel_loops;
> -
> +  /* web and rename-registers help when run after loop unrolling.  */
>   if (flag_web == AUTODETECT_VALUE)
>     flag_web = flag_unroll_loops || flag_peel_loops;
>
> Index: gcc/opts.c
> ===================================================================
> --- gcc/opts.c  (revision 165714)
> +++ gcc/opts.c  (working copy)
> @@ -717,24 +717,206 @@ decode_cmdline_options_to_array_default_
>                                   decoded_options, decoded_options_count);
>  }
>
> +/* If indicated by the optimization level LEVEL (-Os if SIZE is set,
> +   -Ofast if FAST is set), apply the option DEFAULT_OPT to OPTS and
> +   OPTS_SET, diagnostic context DC, with language mask LANG_MASK and
> +   option handlers HANDLERS.  */
> +
> +static void
> +maybe_default_option (struct gcc_options *opts,
> +                     struct gcc_options *opts_set,
> +                     const struct default_options *default_opt,
> +                     int level, bool size, bool fast,
> +                     unsigned int lang_mask,
> +                     const struct cl_option_handlers *handlers,
> +                     diagnostic_context *dc)
> +{
> +  const struct cl_option *option = &cl_options[default_opt->opt_index];
> +  bool enabled;
> +
> +  if (size)
> +    gcc_assert (level == 2);
> +  if (fast)
> +    gcc_assert (level == 3);
> +
> +  switch (default_opt->levels)
> +    {
> +    case OPT_LEVELS_ALL:
> +      enabled = true;
> +      break;
> +
> +    case OPT_LEVELS_0_ONLY:
> +      enabled = (level == 0);
> +      break;
> +
> +    case OPT_LEVELS_1_PLUS:
> +      enabled = (level >= 1);
> +      break;
> +
> +    case OPT_LEVELS_1_PLUS_SPEED_ONLY:
> +      enabled = (level >= 1 && !size);
> +      break;
> +
> +    case OPT_LEVELS_2_PLUS:
> +      enabled = (level >= 2);
> +      break;
> +
> +    case OPT_LEVELS_2_PLUS_SPEED_ONLY:
> +      enabled = (level >= 2 && !size);
> +      break;
> +
> +    case OPT_LEVELS_3_PLUS:
> +      enabled = (level >= 3);
> +      break;
> +
> +    case OPT_LEVELS_3_PLUS_AND_SIZE:
> +      enabled = (level >= 3 || size);
> +      break;
> +
> +    case OPT_LEVELS_SIZE:
> +      enabled = size;
> +      break;
> +
> +    case OPT_LEVELS_FAST:
> +      enabled = fast;
> +      break;
> +
> +    case OPT_LEVELS_NONE:
> +    default:
> +      gcc_unreachable ();
> +    }
> +
> +  if (enabled)
> +    handle_generated_option (opts, opts_set, default_opt->opt_index,
> +                            default_opt->arg, default_opt->value,
> +                            lang_mask, DK_UNSPECIFIED, handlers, dc);
> +  else if (default_opt->arg == NULL
> +          && !(option->flags & CL_REJECT_NEGATIVE))
> +    handle_generated_option (opts, opts_set, default_opt->opt_index,
> +                            default_opt->arg, !default_opt->value,
> +                            lang_mask, DK_UNSPECIFIED, handlers, dc);
> +}
> +
> +/* As indicated by the optimization level LEVEL (-Os if SIZE is set,
> +   -Ofast if FAST is set), apply the options in array DEFAULT_OPTS to
> +   OPTS and OPTS_SET, diagnostic context DC, with language mask
> +   LANG_MASK and option handlers HANDLERS.  */
> +
> +static void
> +maybe_default_options (struct gcc_options *opts,
> +                      struct gcc_options *opts_set,
> +                      const struct default_options *default_opts,
> +                      int level, bool size, bool fast,
> +                      unsigned int lang_mask,
> +                      const struct cl_option_handlers *handlers,
> +                      diagnostic_context *dc)
> +{
> +  size_t i;
> +
> +  for (i = 0; default_opts[i].levels != OPT_LEVELS_NONE; i++)
> +    maybe_default_option (opts, opts_set, &default_opts[i],
> +                         level, size, fast, lang_mask, handlers, dc);
> +}
> +
> +/* Table of options enabled by default at different levels.  */
> +
> +static const struct default_options default_options_table[] =
> +  {
> +    /* -O1 optimizations.  */
> +    { OPT_LEVELS_1_PLUS, OPT_fdefer_pop, NULL, 1 },
> +#ifdef DELAY_SLOTS
> +    { OPT_LEVELS_1_PLUS, OPT_fdelayed_branch, NULL, 1 },
> +#endif
> +    { OPT_LEVELS_1_PLUS, OPT_fguess_branch_probability, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_fif_conversion, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_fif_conversion2, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_fmerge_constants, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_fsplit_wide_types, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_ftree_ccp, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_ftree_bit_ccp, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_ftree_dce, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_ftree_dominator_opts, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_ftree_dse, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_ftree_ter, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_ftree_sra, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_ftree_copyrename, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_ftree_sink, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_ftree_ch, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_fcombine_stack_adjustments, NULL, 1 },
> +
> +    /* -O2 optimizations.  */
> +    { OPT_LEVELS_2_PLUS, OPT_finline_small_functions, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_fpartial_inlining, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_fthread_jumps, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_fcrossjumping, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_foptimize_sibling_calls, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_fcse_follow_jumps, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_frerun_cse_after_loop, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_fcaller_saves, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_fpeephole2, NULL, 1 },
> +#ifdef INSN_SCHEDULING
> +  /* Only run the pre-regalloc scheduling pass if optimizing for speed.  */
> +    { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_fschedule_insns, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_fschedule_insns2, NULL, 1 },
> +#endif
> +    { OPT_LEVELS_2_PLUS, OPT_fregmove, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_fstrict_aliasing, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_fstrict_overflow, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_freorder_blocks, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_freorder_functions, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_ftree_vrp, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_ftree_builtin_call_dce, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_falign_loops, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_falign_jumps, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_falign_labels, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_falign_functions, NULL, 1 },
> +
> +    /* -O3 optimizations.  */
> +    { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
> +    { OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
> +    /* Inlining of functions reducing size is a good idea with -Os
> +       regardless of them being declared inline.  */
> +    { OPT_LEVELS_3_PLUS_AND_SIZE, OPT_finline_functions, NULL, 1 },
> +    { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
> +    { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
> +    { OPT_LEVELS_3_PLUS, OPT_ftree_vectorize, NULL, 1 },
> +    { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
> +
> +    /* -Ofast adds optimizations to -O3.  */
> +    { OPT_LEVELS_FAST, OPT_ffast_math, NULL, 1 },
> +
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
> +
>  /* Default the options in OPTS and OPTS_SET based on the optimization
>    settings in DECODED_OPTIONS and DECODED_OPTIONS_COUNT.  */
>  static void
>  default_options_optimization (struct gcc_options *opts,
>                              struct gcc_options *opts_set,
>                              struct cl_decoded_option *decoded_options,
> -                             unsigned int decoded_options_count)
> +                             unsigned int decoded_options_count,
> +                             unsigned int lang_mask,
> +                             const struct cl_option_handlers *handlers,
> +                             diagnostic_context *dc)
>  {
>   unsigned int i;
> -  int opt1;
>   int opt2;
> -  int opt3;
> -  int opt1_max;
>   int ofast = 0;
>
> -  gcc_assert (opts == &global_options);
> -  gcc_assert (opts_set = &global_options_set);
> -
>   /* Scan to see what optimization level has been specified.  That will
>      determine the default value of many flags.  */
>   for (i = 1; i < decoded_options_count; i++)
> @@ -745,8 +927,8 @@ default_options_optimization (struct gcc
>        case OPT_O:
>          if (*opt->arg == '\0')
>            {
> -             optimize = 1;
> -             optimize_size = 0;
> +             opts->x_optimize = 1;
> +             opts->x_optimize_size = 0;
>              ofast = 0;
>            }
>          else
> @@ -757,27 +939,27 @@ default_options_optimization (struct gcc
>                       "-O");
>              else
>                {
> -                 optimize = optimize_val;
> -                 if ((unsigned int) optimize > 255)
> -                   optimize = 255;
> -                 optimize_size = 0;
> +                 opts->x_optimize = optimize_val;
> +                 if ((unsigned int) opts->x_optimize > 255)
> +                   opts->x_optimize = 255;
> +                 opts->x_optimize_size = 0;
>                  ofast = 0;
>                }
>            }
>          break;
>
>        case OPT_Os:
> -         optimize_size = 1;
> +         opts->x_optimize_size = 1;
>
>          /* Optimizing for size forces optimize to be 2.  */
> -         optimize = 2;
> +         opts->x_optimize = 2;
>          ofast = 0;
>          break;
>
>        case OPT_Ofast:
>          /* -Ofast only adds flags to -O3.  */
> -         optimize_size = 0;
> -         optimize = 3;
> +         opts->x_optimize_size = 0;
> +         opts->x_optimize = 3;
>          ofast = 1;
>          break;
>
> @@ -787,69 +969,12 @@ default_options_optimization (struct gcc
>        }
>     }
>
> -  /* -O1 optimizations.  */
> -  opt1 = (optimize >= 1);
> -  flag_defer_pop = opt1;
> -#ifdef DELAY_SLOTS
> -  flag_delayed_branch = opt1;
> -#endif
> -#ifdef CAN_DEBUG_WITHOUT_FP
> -  flag_omit_frame_pointer = opt1;
> -#endif
> -  flag_guess_branch_prob = opt1;
> -  flag_cprop_registers = opt1;
> -  flag_forward_propagate = opt1;
> -  flag_if_conversion = opt1;
> -  flag_if_conversion2 = opt1;
> -  flag_ipa_pure_const = opt1;
> -  flag_ipa_reference = opt1;
> -  flag_ipa_profile = opt1;
> -  flag_merge_constants = opt1;
> -  flag_split_wide_types = opt1;
> -  flag_tree_ccp = opt1;
> -  flag_tree_bit_ccp = opt1;
> -  flag_tree_dce = opt1;
> -  flag_tree_dom = opt1;
> -  flag_tree_dse = opt1;
> -  flag_tree_ter = opt1;
> -  flag_tree_sra = opt1;
> -  flag_tree_copyrename = opt1;
> -  flag_tree_fre = opt1;
> -  flag_tree_copy_prop = opt1;
> -  flag_tree_sink = opt1;
> -  flag_tree_ch = opt1;
> -  flag_combine_stack_adjustments = opt1;
> -
> -  /* -O2 optimizations.  */
> -  opt2 = (optimize >= 2);
> -  flag_inline_small_functions = opt2;
> -  flag_indirect_inlining = opt2;
> -  flag_partial_inlining = opt2;
> -  flag_thread_jumps = opt2;
> -  flag_crossjumping = opt2;
> -  flag_optimize_sibling_calls = opt2;
> -  flag_cse_follow_jumps = opt2;
> -  flag_gcse = opt2;
> -  flag_expensive_optimizations = opt2;
> -  flag_rerun_cse_after_loop = opt2;
> -  flag_caller_saves = opt2;
> -  flag_peephole2 = opt2;
> -#ifdef INSN_SCHEDULING
> -  /* Only run the pre-regalloc scheduling pass if optimizing for speed.  */
> -  flag_schedule_insns = opt2 && ! optimize_size;
> -  flag_schedule_insns_after_reload = opt2;
> -#endif
> -  flag_regmove = opt2;
> -  flag_strict_aliasing = opt2;
> -  flag_strict_overflow = opt2;
> -  flag_reorder_blocks = opt2;
> -  flag_reorder_functions = opt2;
> -  flag_tree_vrp = opt2;
> -  flag_tree_builtin_call_dce = opt2;
> -  flag_tree_pre = opt2;
> -  flag_tree_switch_conversion = opt2;
> -  flag_ipa_cp = opt2;
> -  flag_ipa_sra = opt2;
> +  maybe_default_options (opts, opts_set, default_options_table,
> +                        opts->x_optimize, opts->x_optimize_size,
> +                        ofast, lang_mask, handlers, dc);
> +
> +  /* -O2 param settings.  */
> +  opt2 = (opts->x_optimize >= 2);
>
>   /* Track fields in field-sensitive alias analysis.  */
>   maybe_set_param_value
> @@ -863,58 +988,20 @@ default_options_optimization (struct gcc
>      opt2 ? default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) : 1000,
>      opts->x_param_values, opts_set->x_param_values);
>
> -  /* -O3 optimizations.  */
> -  opt3 = (optimize >= 3);
> -  flag_tree_loop_distribute_patterns = opt3;
> -  flag_predictive_commoning = opt3;
> -  flag_inline_functions = opt3;
> -  flag_unswitch_loops = opt3;
> -  flag_gcse_after_reload = opt3;
> -  flag_tree_vectorize = opt3;
> -  flag_ipa_cp_clone = opt3;
> -  if (flag_ipa_cp_clone)
> -    flag_ipa_cp = 1;
> -
> -  /* Just -O1/-O0 optimizations.  */
> -  opt1_max = (optimize <= 1);
> -  align_loops = opt1_max;
> -  align_jumps = opt1_max;
> -  align_labels = opt1_max;
> -  align_functions = opt1_max;
> -
> -  if (optimize_size)
> -    {
> -      /* Inlining of functions reducing size is a good idea regardless of them
> -        being declared inline.  */
> -      flag_inline_functions = 1;
> -
> -      /* Basic optimization options.  */
> -      optimize_size = 1;
> -      if (optimize > 2)
> -       optimize = 2;
> -
> -      /* We want to crossjump as much as possible.  */
> -      maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, 1,
> -                            opts->x_param_values, opts_set->x_param_values);
> -    }
> +  if (opts->x_optimize_size)
> +    /* We want to crossjump as much as possible.  */
> +    maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, 1,
> +                          opts->x_param_values, opts_set->x_param_values);
>   else
>     maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS,
>                           default_param_value (PARAM_MIN_CROSSJUMP_INSNS),
>                           opts->x_param_values, opts_set->x_param_values);
>
> -  /* -Ofast adds optimizations to -O3.  */
> -  if (ofast)
> -    {
> -      /* Which is -ffast-math for now.  */
> -      set_fast_math_flags (1);
> -      /* Allow targets to enable extra options with -Ofast
> -        before general options processing so disabling them
> -        again afterwards works.  */
> -      targetm.handle_ofast ();
> -    }
> -
>   /* Allow default optimizations to be specified on a per-machine basis.  */
> -  targetm.target_option.optimization (optimize, optimize_size);
> +  maybe_default_options (opts, opts_set,
> +                        targetm.target_option.optimization_table,
> +                        opts->x_optimize, opts->x_optimize_size,
> +                        ofast, lang_mask, handlers, dc);
>  }
>
>  static void finish_options (struct gcc_options *, struct gcc_options *);
> @@ -949,7 +1036,8 @@ decode_options (struct gcc_options *opts
>                           global_dc);
>
>   default_options_optimization (opts, opts_set,
> -                               decoded_options, decoded_options_count);
> +                               decoded_options, decoded_options_count,
> +                               lang_mask, &handlers, global_dc);
>
>  #ifdef ENABLE_LTO
>   /* Clear any options currently held for LTO.  */
> Index: gcc/common.opt
> ===================================================================
> --- gcc/common.opt      (revision 165714)
> +++ gcc/common.opt      (working copy)
> @@ -589,7 +589,7 @@ falign-labels=
>  Common RejectNegative Joined UInteger
>
>  falign-loops
> -Common Report Var(align_loops) Optimization UInteger
> +Common Report Var(align_loops,0) Optimization UInteger
>  Align the start of loops
>
>  falign-loops=
> @@ -1318,7 +1318,7 @@ Common Report Var(flag_reorder_functions
>  Reorder functions to improve code placement
>
>  frerun-cse-after-loop
> -Common Report Var(flag_rerun_cse_after_loop) Init(2) Optimization
> +Common Report Var(flag_rerun_cse_after_loop) Optimization
>  Add a common subexpression elimination pass after loop optimizations
>
>  frerun-loop-opt
> @@ -1681,7 +1681,7 @@ Common Report Var(flag_tree_sra) Optimiz
>  Perform scalar replacement of aggregates
>
>  ftree-ter
> -Common Report Var(flag_tree_ter) Init(1) Optimization
> +Common Report Var(flag_tree_ter) Optimization
>  Replace temporary expressions in the SSA->normal pass
>
>  ftree-lrs
> Index: gcc/system.h
> ===================================================================
> --- gcc/system.h        (revision 165714)
> +++ gcc/system.h        (working copy)
> @@ -719,7 +719,8 @@ extern void fancy_abort (const char *, i
>        OPTIMIZATION_OPTIONS CLASS_LIKELY_SPILLED_P                     \
>        USING_SJLJ_EXCEPTIONS TARGET_UNWIND_INFO                        \
>        LABEL_ALIGN_MAX_SKIP LOOP_ALIGN_MAX_SKIP                        \
> -       LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP JUMP_ALIGN_MAX_SKIP
> +       LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP JUMP_ALIGN_MAX_SKIP \
> +       CAN_DEBUG_WITHOUT_FP
>
>  /* Other obsolete target macros, or macros that used to be in target
>    headers and were not used, and may be obsolete or may never have
> @@ -784,7 +785,8 @@ extern void fancy_abort (const char *, i
>        LANG_HOOKS_MAYBE_BUILD_CLEANUP LANG_HOOKS_UPDATE_DECL_AFTER_SAVING \
>        LANG_HOOKS_POPLEVEL LANG_HOOKS_TRUTHVALUE_CONVERSION \
>        TARGET_PROMOTE_FUNCTION_ARGS TARGET_PROMOTE_FUNCTION_RETURN \
> -       LANG_HOOKS_MISSING_ARGUMENT LANG_HOOKS_HASH_TYPES
> +       LANG_HOOKS_MISSING_ARGUMENT LANG_HOOKS_HASH_TYPES \
> +       TARGET_HANDLE_OFAST TARGET_OPTION_OPTIMIZATION
>
>  /* Hooks into libgcc2.  */
>  #pragma GCC poison LIBGCC2_DOUBLE_TYPE_SIZE
> Index: gcc/config/alpha/alpha.c
> ===================================================================
> --- gcc/config/alpha/alpha.c    (revision 165714)
> +++ gcc/config/alpha/alpha.c    (working copy)
> @@ -208,6 +208,13 @@ static void unicosmk_gen_dsib (unsigned
>  static void unicosmk_output_ssib (FILE *, const char *);
>  static int unicosmk_need_dex (rtx);
>
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options alpha_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
> +
>  /* Implement TARGET_HANDLE_OPTION.  */
>
>  static bool
> @@ -11140,6 +11147,9 @@ alpha_init_libfuncs (void)
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE alpha_option_override
>
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE alpha_option_optimization_table
> +
>  #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
>  #undef TARGET_MANGLE_TYPE
>  #define TARGET_MANGLE_TYPE alpha_mangle_type
> Index: gcc/config/alpha/alpha.h
> ===================================================================
> --- gcc/config/alpha/alpha.h    (revision 165714)
> +++ gcc/config/alpha/alpha.h    (working copy)
> @@ -1,6 +1,6 @@
>  /* Definitions of target machine for GNU compiler, for DEC Alpha.
>    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
> -   2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009
> +   2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009, 2010
>    Free Software Foundation, Inc.
>    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
>
> @@ -223,10 +223,6 @@ extern enum alpha_fp_trap_mode alpha_fpt
>     for (i = 32; i < 63; i++)                  \
>       fixed_regs[i] = call_used_regs[i] = 1;   \
>  }
> -
> -
> -/* Show we can debug even without a frame pointer.  */
> -#define CAN_DEBUG_WITHOUT_FP
>
>  /* target machine storage layout */
>
> Index: gcc/config/frv/frv.h
> ===================================================================
> --- gcc/config/frv/frv.h        (revision 165714)
> +++ gcc/config/frv/frv.h        (working copy)
> @@ -328,13 +328,6 @@
>         #endif  */
>  #define TARGET_VERSION fprintf (stderr, _(" (frv)"))
>
> -/* Define this macro if debugging can be performed even without a frame
> -   pointer.  If this macro is defined, GCC will turn on the
> -   `-fomit-frame-pointer' option whenever `-O' is specified.  */
> -/* Frv needs a specific frame layout that includes the frame pointer.  */
> -
> -#define CAN_DEBUG_WITHOUT_FP
> -
>  #define LABEL_ALIGN_AFTER_BARRIER(LABEL) (TARGET_ALIGN_LABELS ? 3 : 0)
>
>  /* Small Data Area Support.  */
> Index: gcc/config/frv/frv.c
> ===================================================================
> --- gcc/config/frv/frv.c        (revision 165714)
> +++ gcc/config/frv/frv.c        (working copy)
> @@ -397,6 +397,13 @@ static bool frv_frame_pointer_required
>  static bool frv_can_eliminate                  (const int, const int);
>  static void frv_trampoline_init                        (rtx, tree, rtx);
>  static bool frv_class_likely_spilled_p                 (reg_class_t);
> +
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options frv_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  /* Allow us to easily change the default for -malloc-cc.  */
>  #ifndef DEFAULT_NO_ALLOC_CC
> @@ -431,6 +438,8 @@ static bool frv_class_likely_spilled_p
>  #define TARGET_HANDLE_OPTION frv_handle_option
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE frv_option_override
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE frv_option_optimization_table
>  #undef TARGET_INIT_BUILTINS
>  #define TARGET_INIT_BUILTINS frv_init_builtins
>  #undef TARGET_EXPAND_BUILTIN
> Index: gcc/config/s390/s390.c
> ===================================================================
> --- gcc/config/s390/s390.c      (revision 165714)
> +++ gcc/config/s390/s390.c      (working copy)
> @@ -1490,23 +1490,20 @@ s390_init_machine_status (void)
>  }
>
>  /* Change optimizations to be performed, depending on the
> -   optimization level.
> +   optimization level.  */
>
> -   LEVEL is the optimization level specified; 2 if `-O2' is
> -   specified, 1 if `-O' is specified, and 0 if neither is specified.
> +static const struct default_options s390_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
>
> -   SIZE is nonzero if `-Os' is specified and zero otherwise.  */
> +    /* ??? There are apparently still problems with -fcaller-saves.  */
> +    { OPT_LEVELS_ALL, OPT_fcaller_saves, NULL, 0 },
>
> -static void
> -s390_option_optimization (int level ATTRIBUTE_UNUSED, int size)
> -{
> -  /* ??? There are apparently still problems with -fcaller-saves.  */
> -  flag_caller_saves = 0;
> +    /* Use MVCLE instructions to decrease code size if requested.  */
> +    { OPT_LEVELS_SIZE, OPT_mmvcle, NULL, 1 },
>
> -  /* Use MVCLE instructions to decrease code size if requested.  */
> -  if (size != 0)
> -    target_flags |= MASK_MVCLE;
> -}
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  /* Implement TARGET_OPTION_INIT_STRUCT.  */
>
> @@ -1730,7 +1727,7 @@ s390_option_override (void)
>                         global_options.x_param_values,
>                         global_options_set.x_param_values);
>
> -  /* This cannot reside in s390_option_optimization since HAVE_prefetch
> +  /* This cannot reside in s390_option_optimization_table since HAVE_prefetch
>      requires the arch flags to be evaluated already.  Since prefetching
>      is beneficial on s390, we enable it if available.  */
>   if (flag_prefetch_loop_arrays < 0 && HAVE_prefetch && optimize >= 3)
> @@ -10510,8 +10507,8 @@ s390_loop_unroll_adjust (unsigned nunrol
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE s390_option_override
>
> -#undef TARGET_OPTION_OPTIMIZATION
> -#define TARGET_OPTION_OPTIMIZATION s390_option_optimization
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE s390_option_optimization_table
>
>  #undef TARGET_OPTION_INIT_STRUCT
>  #define TARGET_OPTION_INIT_STRUCT s390_option_init_struct
> Index: gcc/config/s390/s390.h
> ===================================================================
> --- gcc/config/s390/s390.h      (revision 165714)
> +++ gcc/config/s390/s390.h      (working copy)
> @@ -158,9 +158,6 @@ extern int s390_arch_flags;
>  #define TARGET_VERSION fprintf (stderr, " (S/390)");
>  #endif
>
> -/* Frame pointer is not used for debugging.  */
> -#define CAN_DEBUG_WITHOUT_FP
> -
>  /* Constants needed to control the TEST DATA CLASS (TDC) instruction.  */
>  #define S390_TDC_POSITIVE_ZERO                     (1 << 11)
>  #define S390_TDC_NEGATIVE_ZERO                     (1 << 10)
> Index: gcc/config/sparc/sparc.c
> ===================================================================
> --- gcc/config/sparc/sparc.c    (revision 165714)
> +++ gcc/config/sparc/sparc.c    (working copy)
> @@ -477,6 +477,13 @@ enum processor_type sparc_cpu;
>  /* Whether an FPU option was specified.  */
>  static bool fpu_option_set = false;
>
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options sparc_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
> +
>  /* Initialize the GCC target structure.  */
>
>  /* The default is to use .half rather than .short for aligned HI objects.  */
> @@ -612,6 +619,8 @@ static bool fpu_option_set = false;
>  #define TARGET_HANDLE_OPTION sparc_handle_option
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE sparc_option_override
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE sparc_option_optimization_table
>
>  #if TARGET_GNU_TLS && defined(HAVE_AS_SPARC_UA_PCREL)
>  #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
> Index: gcc/config/sparc/sparc.h
> ===================================================================
> --- gcc/config/sparc/sparc.h    (revision 165714)
> +++ gcc/config/sparc/sparc.h    (working copy)
> @@ -496,9 +496,6 @@ extern enum cmodel sparc_cmodel;
>  /* ??? This should be 32 bits for v9 but what can we do?  */
>  #define WCHAR_TYPE "short unsigned int"
>  #define WCHAR_TYPE_SIZE 16
> -
> -/* Show we can debug even without a frame pointer.  */
> -#define CAN_DEBUG_WITHOUT_FP
>
>  /* Mask of all CPU selection flags.  */
>  #define MASK_ISA \
> Index: gcc/config/mep/mep.c
> ===================================================================
> --- gcc/config/mep/mep.c        (revision 165714)
> +++ gcc/config/mep/mep.c        (working copy)
> @@ -295,16 +295,20 @@ mep_conditional_register_usage (void)
>     global_regs[i] = 1;
>  }
>
> -static void
> -mep_option_optimization (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
> -{
> -  /* The first scheduling pass often increases register pressure and tends
> -     to result in more spill code.  Only run it when specifically asked.  */
> -  flag_schedule_insns = 0;
>
> -  /* Using $fp doesn't gain us much, even when debugging is important.  */
> -  flag_omit_frame_pointer = 1;
> -}
> +static const struct default_options mep_option_optimization_table[] =
> +  {
> +    /* The first scheduling pass often increases register pressure and
> +       tends to result in more spill code.  Only run it when
> +       specifically asked.  */
> +    { OPT_LEVELS_ALL, OPT_fschedule_insns, NULL, 0 },
> +
> +    /* Using $fp doesn't gain us much, even when debugging is
> +       important.  */
> +    { OPT_LEVELS_ALL, OPT_fomit_frame_pointer, NULL, 1 },
> +
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  static void
>  mep_option_override (void)
> @@ -7426,8 +7430,8 @@ mep_asm_init_sections (void)
>  #define TARGET_HANDLE_OPTION            mep_handle_option
>  #undef  TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE         mep_option_override
> -#undef  TARGET_OPTION_OPTIMIZATION
> -#define TARGET_OPTION_OPTIMIZATION     mep_option_optimization
> +#undef  TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE       mep_option_optimization_table
>  #undef  TARGET_DEFAULT_TARGET_FLAGS
>  #define TARGET_DEFAULT_TARGET_FLAGS    TARGET_DEFAULT
>  #undef  TARGET_ALLOCATE_INITIAL_VALUE
> Index: gcc/config/mep/mep.h
> ===================================================================
> --- gcc/config/mep/mep.h        (revision 165714)
> +++ gcc/config/mep/mep.h        (working copy)
> @@ -159,8 +159,6 @@ crtbegin.o%s"
>  #define COPROC_SELECTION_TABLE \
>  {"default", ISA_EXT1}
>  /* end-coproc-selection-table */
> -
> -#define CAN_DEBUG_WITHOUT_FP
>
>
>  #define BITS_BIG_ENDIAN 0
> Index: gcc/config/m32r/m32r.c
> ===================================================================
> --- gcc/config/m32r/m32r.c      (revision 165714)
> +++ gcc/config/m32r/m32r.c      (working copy)
> @@ -64,7 +64,6 @@ enum m32r_sdata m32r_sdata = M32R_SDATA_
>  /* Forward declaration.  */
>  static bool  m32r_handle_option (size_t, const char *, int);
>  static void  m32r_option_override (void);
> -static void  m32r_option_optimization (int, int);
>  static void  init_reg_tables (void);
>  static void  block_move_call (rtx, rtx, rtx);
>  static int   m32r_is_insn (rtx);
> @@ -113,6 +112,13 @@ static const struct attribute_spec m32r_
>   { "model",     1, 1, true,  false, false, m32r_handle_model_attribute },
>   { NULL,        0, 0, false, false, false, NULL }
>  };
> +
> +static const struct default_options m32r_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_fregmove, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  /* Initialize the GCC target structure.  */
>  #undef  TARGET_ATTRIBUTE_TABLE
> @@ -154,8 +160,8 @@ static const struct attribute_spec m32r_
>  #define TARGET_HANDLE_OPTION m32r_handle_option
>  #undef  TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE m32r_option_override
> -#undef  TARGET_OPTION_OPTIMIZATION
> -#define TARGET_OPTION_OPTIMIZATION m32r_option_optimization
> +#undef  TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE m32r_option_optimization_table
>
>  #undef  TARGET_ENCODE_SECTION_INFO
>  #define TARGET_ENCODE_SECTION_INFO m32r_encode_section_info
> @@ -278,18 +284,6 @@ m32r_option_override (void)
>   SUBTARGET_OVERRIDE_OPTIONS;
>  }
>
> -static void
> -m32r_option_optimization (int level, int size)
> -{
> -  if (level == 1)
> -    flag_regmove = 1;
> -
> -  if (size)
> -    flag_omit_frame_pointer = 1;
> -
> -  SUBTARGET_OPTIMIZATION_OPTIONS;
> -}
> -
>  /* Vectors to keep interesting information about registers where it can easily
>    be got.  We use to use the actual mode value as the bit number, but there
>    is (or may be) more than 32 modes now.  Instead we use two tables: one
> Index: gcc/config/m32r/m32r.h
> ===================================================================
> --- gcc/config/m32r/m32r.h      (revision 165714)
> +++ gcc/config/m32r/m32r.h      (working copy)
> @@ -305,15 +305,6 @@ extern enum m32r_sdata m32r_sdata;
>  #ifndef SUBTARGET_OVERRIDE_OPTIONS
>  #define SUBTARGET_OVERRIDE_OPTIONS
>  #endif
> -
> -#ifndef SUBTARGET_OPTIMIZATION_OPTIONS
> -#define SUBTARGET_OPTIMIZATION_OPTIONS
> -#endif
> -
> -/* Define this macro if debugging can be performed even without a
> -   frame pointer.  If this macro is defined, GCC will turn on the
> -   `-fomit-frame-pointer' option whenever `-O' is specified.  */
> -#define CAN_DEBUG_WITHOUT_FP
>
>  /* Target machine storage layout.  */
>
> Index: gcc/config/i386/sol2-10.h
> ===================================================================
> --- gcc/config/i386/sol2-10.h   (revision 165714)
> +++ gcc/config/i386/sol2-10.h   (working copy)
> @@ -91,13 +91,8 @@ along with GCC; see the file COPYING3.
>  #define TARGET_SUBTARGET_DEFAULT \
>        (MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS)
>
> -#define SUBTARGET_OPTIMIZATION_OPTIONS                 \
> -  do                                                   \
> -    {                                                  \
> -      if (optimize >= 1)                               \
> -       target_flags |= MASK_OMIT_LEAF_FRAME_POINTER;   \
> -    }                                                  \
> -  while (0)
> +#define SUBTARGET_OPTIMIZATION_OPTIONS                         \
> +  { OPT_LEVELS_1_PLUS, OPT_momit_leaf_frame_pointer, NULL, 1 }
>
>  #define MULTILIB_DEFAULTS { "m32" }
>
> Index: gcc/config/i386/i386.c
> ===================================================================
> --- gcc/config/i386/i386.c      (revision 165714)
> +++ gcc/config/i386/i386.c      (working copy)
> @@ -4529,20 +4529,19 @@ x86_output_aligned_bss (FILE *file, tree
>   ASM_OUTPUT_SKIP (file, size ? size : 1);
>  }
>
> -static void
> -ix86_option_optimization (int level, int size ATTRIBUTE_UNUSED)
> -{
> -  /* For -O2 and beyond, turn off -fschedule-insns by default.  It tends to
> -     make the problem with not enough registers even worse.  */
> +static const struct default_options ix86_option_optimization_table[] =
> +  {
> +    /* Turn off -fschedule-insns by default.  It tends to make the
> +       problem with not enough registers even worse.  */
>  #ifdef INSN_SCHEDULING
> -  if (level > 1)
> -    flag_schedule_insns = 0;
> +    { OPT_LEVELS_ALL, OPT_fschedule_insns, NULL, 0 },
>  #endif
>
>  #ifdef SUBTARGET_OPTIMIZATION_OPTIONS
> -  SUBTARGET_OPTIMIZATION_OPTIONS;
> +    SUBTARGET_OPTIMIZATION_OPTIONS,
>  #endif
> -}
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  /* Implement TARGET_OPTION_INIT_STRUCT.  */
>
> @@ -33237,8 +33236,8 @@ ix86_autovectorize_vector_sizes (void)
>
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE ix86_option_override
> -#undef TARGET_OPTION_OPTIMIZATION
> -#define TARGET_OPTION_OPTIMIZATION ix86_option_optimization
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE ix86_option_optimization_table
>  #undef TARGET_OPTION_INIT_STRUCT
>  #define TARGET_OPTION_INIT_STRUCT ix86_option_init_struct
>
> Index: gcc/config/rx/rx.h
> ===================================================================
> --- gcc/config/rx/rx.h  (revision 165714)
> +++ gcc/config/rx/rx.h  (working copy)
> @@ -609,8 +609,6 @@ extern int rx_float_compare_mode;
>  /* Like REG_P except that this macro is true for SET expressions.  */
>  #define SET_P(rtl)    (GET_CODE (rtl) == SET)
>
> -#define CAN_DEBUG_WITHOUT_FP 1
> -
>  /* The AS100 assembler does not support .leb128 and .uleb128, but
>    the compiler-build-time configure tests will have enabled their
>    use because GAS supports them.  So default to generating STABS
> Index: gcc/config/rx/rx.c
> ===================================================================
> --- gcc/config/rx/rx.c  (revision 165714)
> +++ gcc/config/rx/rx.c  (working copy)
> @@ -2253,6 +2253,13 @@ rx_option_override (void)
>   rx_override_options_after_change ();
>  }
>
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options rx_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
> +
>
>  static bool
>  rx_allocate_stack_slots_for_args (void)
> @@ -2850,6 +2857,9 @@ rx_memory_move_cost (enum machine_mode m
>  #undef  TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE                 rx_option_override
>
> +#undef  TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE       rx_option_optimization_table
> +
>  #undef  TARGET_PROMOTE_FUNCTION_MODE
>  #define TARGET_PROMOTE_FUNCTION_MODE           rx_promote_function_mode
>
> Index: gcc/config/sh/sh.c
> ===================================================================
> --- gcc/config/sh/sh.c  (revision 165714)
> +++ gcc/config/sh/sh.c  (working copy)
> @@ -183,7 +183,6 @@ static int noncall_uses_reg (rtx, rtx, r
>  static rtx gen_block_redirect (rtx, int, 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);
> @@ -323,6 +322,23 @@ static const struct attribute_spec sh_at
>  #endif
>   { NULL,                0, 0, false, false, false, NULL }
>  };
> +
> +/* Set default optimization options.  */
> +static const struct default_options sh_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS_SPEED_ONLY, OPT_mdiv_, "inv:minlat", 1 },
> +    { OPT_LEVELS_SIZE, OPT_mdiv_, SH_DIV_STR_FOR_SIZE, 1 },
> +    { OPT_LEVELS_0_ONLY, OPT_mdiv_, "", 1 },
> +    { OPT_LEVELS_SIZE, OPT_mcbranchdi, NULL, 0 },
> +    /* We can't meaningfully test TARGET_SHMEDIA here, because -m
> +       options haven't been parsed yet, hence we'd read only the
> +       default.  sh_target_reg_class will return NO_REGS if this is
> +       not SHMEDIA, so it's OK to always set
> +       flag_branch_target_load_optimize.  */
> +    { OPT_LEVELS_2_PLUS, OPT_fbranch_target_load_optimize, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  /* Initialize the GCC target structure.  */
>  #undef TARGET_ATTRIBUTE_TABLE
> @@ -342,8 +358,8 @@ static const struct attribute_spec sh_at
>
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE sh_option_override
> -#undef TARGET_OPTION_OPTIMIZATION
> -#define TARGET_OPTION_OPTIMIZATION sh_option_optimization
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE sh_option_optimization_table
>  #undef TARGET_OPTION_INIT_STRUCT
>  #define TARGET_OPTION_INIT_STRUCT sh_option_init_struct
>  #undef TARGET_OPTION_DEFAULT_PARAMS
> @@ -702,34 +718,6 @@ sh_handle_option (size_t code, const cha
>     }
>  }
>
> -/* Set default optimization options.  */
> -static void
> -sh_option_optimization (int level, int size)
> -{
> -  if (level)
> -    {
> -      if (!size)
> -       sh_div_str = "inv:minlat";
> -    }
> -  if (size)
> -    {
> -      target_flags |= MASK_SMALLCODE;
> -      sh_div_str = SH_DIV_STR_FOR_SIZE ;
> -    }
> -  else
> -    TARGET_CBRANCHDI4 = 1;
> -  /* We can't meaningfully test TARGET_SHMEDIA here, because -m options
> -     haven't been parsed yet, hence we'd read only the default.
> -     sh_target_reg_class will return NO_REGS if this is not SHMEDIA, so
> -     it's OK to always set flag_branch_target_load_optimize.  */
> -  if (level > 1)
> -    {
> -      flag_branch_target_load_optimize = 1;
> -      if (!size)
> -       target_flags |= MASK_SAVE_ALL_TARGET_REGS;
> -    }
> -}
> -
>  /* Implement TARGET_OPTION_INIT_STRUCT.  */
>  static void
>  sh_option_init_struct (struct gcc_options *opts)
> @@ -756,6 +744,8 @@ sh_option_override (void)
>   int regno;
>
>   SUBTARGET_OVERRIDE_OPTIONS;
> +  if (optimize > 1 && !optimize_size)
> +    target_flags |= MASK_SAVE_ALL_TARGET_REGS;
>   if (flag_finite_math_only == 2)
>     flag_finite_math_only
>       = !flag_signaling_nans && TARGET_SH2E && ! TARGET_IEEE;
> @@ -991,7 +981,7 @@ sh_option_override (void)
>      SH2 .. SH5 : align to cache line start.  */
>   if (align_functions == 0)
>     align_functions
> -      = TARGET_SMALLCODE ? FUNCTION_BOUNDARY/8 : (1 << CACHE_LOG);
> +      = optimize_size ? FUNCTION_BOUNDARY/8 : (1 << CACHE_LOG);
>   /* The linker relaxation code breaks when a function contains
>      alignments that are larger than that at the start of a
>      compilation unit.  */
> @@ -1555,7 +1545,7 @@ expand_block_move (rtx *operands)
>          emit_insn (gen_block_move_real_i4 (func_addr_rtx));
>          return 1;
>        }
> -      else if (! TARGET_SMALLCODE)
> +      else if (! optimize_size)
>        {
>          const char *entry_name;
>          rtx func_addr_rtx = gen_reg_rtx (Pmode);
> @@ -1594,7 +1584,7 @@ expand_block_move (rtx *operands)
>
>   /* This is the same number of bytes as a memcpy call, but to a different
>      less common function name, so this will occasionally use more space.  */
> -  if (! TARGET_SMALLCODE)
> +  if (! optimize_size)
>     {
>       rtx func_addr_rtx = gen_reg_rtx (Pmode);
>       int final_switch, while_loop;
> @@ -2975,21 +2965,21 @@ multcosts (rtx x ATTRIBUTE_UNUSED)
>        Using a multiply first and splitting it later if it's a loss
>        doesn't work because of different sign / zero extension semantics
>        of multiplies vs. shifts.  */
> -    return TARGET_SMALLCODE ? 2 : 3;
> +    return optimize_size ? 2 : 3;
>
>   if (TARGET_SH2)
>     {
>       /* We have a mul insn, so we can never take more than the mul and the
>         read of the mac reg, but count more because of the latency and extra
>         reg usage.  */
> -      if (TARGET_SMALLCODE)
> +      if (optimize_size)
>        return 2;
>       return 3;
>     }
>
>   /* If we're aiming at small code, then just count the number of
>      insns in a multiply call sequence.  */
> -  if (TARGET_SMALLCODE)
> +  if (optimize_size)
>     return 5;
>
>   /* Otherwise count all the insns in the routine we'd be calling too.  */
> @@ -4660,7 +4650,7 @@ find_barrier (int num_mova, rtx mova, rt
>       /* For the SH1, we generate alignments even after jumps-around-jumps.  */
>       else if (JUMP_P (from)
>               && ! TARGET_SH2
> -              && ! TARGET_SMALLCODE)
> +              && ! optimize_size)
>        new_align = 4;
>
>       /* There is a possibility that a bf is transformed into a bf/s by the
> @@ -5258,13 +5248,13 @@ barrier_align (rtx barrier_or_label)
>       pat = PATTERN (prev);
>       /* If this is a very small table, we want to keep the alignment after
>         the table to the minimum for proper code alignment.  */
> -      return ((TARGET_SMALLCODE
> +      return ((optimize_size
>               || ((unsigned) XVECLEN (pat, 1) * GET_MODE_SIZE (GET_MODE (pat))
>                   <= (unsigned) 1 << (CACHE_LOG - 2)))
>              ? 1 << TARGET_SHMEDIA : align_jumps_log);
>     }
>
> -  if (TARGET_SMALLCODE)
> +  if (optimize_size)
>     return 0;
>
>   if (! TARGET_SH2 || ! optimize)
> Index: gcc/config/sh/sh.h
> ===================================================================
> --- gcc/config/sh/sh.h  (revision 165714)
> +++ gcc/config/sh/sh.h  (working copy)
> @@ -98,8 +98,6 @@ do { \
>                  ? "__LITTLE_ENDIAN__" : "__BIG_ENDIAN__"); \
>  } while (0)
>
> -#define CAN_DEBUG_WITHOUT_FP
> -
>  /* Value should be nonzero if functions must have frame pointers.
>    Zero means the frame pointer need not be set up (and parms may be accessed
>    via the stack pointer) in functions that seem suitable.  */
> @@ -623,7 +621,7 @@ extern enum sh_divide_strategy_e sh_div_
>   barrier_align (LABEL_AFTER_BARRIER)
>
>  #define LOOP_ALIGN(A_LABEL) \
> -  ((! optimize || TARGET_HARD_SH4 || TARGET_SMALLCODE) \
> +  ((! optimize || TARGET_HARD_SH4 || optimize_size) \
>    ? 0 : sh_loop_align (A_LABEL))
>
>  #define LABEL_ALIGN(A_LABEL) \
> @@ -1781,7 +1779,7 @@ struct sh_args {
>
>  /* Alignment required for a trampoline in bits .  */
>  #define TRAMPOLINE_ALIGNMENT \
> -  ((CACHE_LOG < 3 || (TARGET_SMALLCODE && ! TARGET_HARVARD)) ? 32 \
> +  ((CACHE_LOG < 3 || (optimize_size && ! TARGET_HARVARD)) ? 32 \
>    : TARGET_SHMEDIA ? 256 : 64)
>
>  /* A C expression whose value is RTL representing the value of the return
> @@ -1813,11 +1811,11 @@ struct sh_args {
>
>  #define MOVE_BY_PIECES_P(SIZE, ALIGN) \
>   (move_by_pieces_ninsns (SIZE, ALIGN, MOVE_MAX_PIECES + 1) \
> -   < (TARGET_SMALLCODE ? 2 : ((ALIGN >= 32) ? 16 : 2)))
> +   < (optimize_size ? 2 : ((ALIGN >= 32) ? 16 : 2)))
>
>  #define STORE_BY_PIECES_P(SIZE, ALIGN) \
>   (move_by_pieces_ninsns (SIZE, ALIGN, STORE_MAX_PIECES + 1) \
> -   < (TARGET_SMALLCODE ? 2 : ((ALIGN >= 32) ? 16 : 2)))
> +   < (optimize_size ? 2 : ((ALIGN >= 32) ? 16 : 2)))
>
>  #define SET_BY_PIECES_P(SIZE, ALIGN) STORE_BY_PIECES_P(SIZE, ALIGN)
>
> @@ -2597,7 +2595,7 @@ extern int current_function_interrupt;
>  #define ACCUMULATE_OUTGOING_ARGS TARGET_ACCUMULATE_OUTGOING_ARGS
>
>  #define SH_DYNAMIC_SHIFT_COST \
> -  (TARGET_HARD_SH4 ? 1 : TARGET_SH3 ? (TARGET_SMALLCODE ? 1 : 2) : 20)
> +  (TARGET_HARD_SH4 ? 1 : TARGET_SH3 ? (optimize_size ? 1 : 2) : 20)
>
>
>  #define NUM_MODES_FOR_MODE_SWITCHING { FP_MODE_NONE }
> Index: gcc/config/sh/sh.opt
> ===================================================================
> --- gcc/config/sh/sh.opt        (revision 165714)
> +++ gcc/config/sh/sh.opt        (working copy)
> @@ -320,7 +320,7 @@ Target Mask(HITACHI) MaskExists
>  Follow Renesas (formerly Hitachi) / SuperH calling conventions
>
>  mspace
> -Target Report RejectNegative Mask(SMALLCODE)
> +Target RejectNegative Alias(Os)
>  Deprecated.  Use -Os instead
>
>  multcost=
> Index: gcc/config/pdp11/pdp11.c
> ===================================================================
> --- gcc/config/pdp11/pdp11.c    (revision 165714)
> +++ gcc/config/pdp11/pdp11.c    (working copy)
> @@ -145,7 +145,6 @@ decode_pdp11_d (const struct real_format
>  /* rtx cc0_reg_rtx; - no longer needed? */
>
>  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 *);
> @@ -162,6 +161,14 @@ static rtx pdp11_function_arg (CUMULATIV
>                               const_tree, bool);
>  static void pdp11_function_arg_advance (CUMULATIVE_ARGS *,
>                                        enum machine_mode, const_tree, bool);
> +
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +
> +static const struct default_options pdp11_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_3_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  /* Initialize the GCC target structure.  */
>  #undef TARGET_ASM_BYTE_OP
> @@ -188,8 +195,8 @@ static void pdp11_function_arg_advance (
>   (MASK_FPU | MASK_45 | MASK_ABSHI_BUILTIN | TARGET_UNIX_ASM_DEFAULT)
>  #undef TARGET_HANDLE_OPTION
>  #define TARGET_HANDLE_OPTION pdp11_handle_option
> -#undef TARGET_OPTION_OPTIMIZATION
> -#define TARGET_OPTION_OPTIMIZATION pdp11_option_optimization
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE pdp11_option_optimization_table
>  #undef TARGET_OPTION_INIT_STRUCT
>  #define TARGET_OPTION_INIT_STRUCT pdp11_option_init_struct
>
> @@ -233,18 +240,6 @@ pdp11_handle_option (size_t code, const
>     }
>  }
>
> -/* Implement TARGET_OPTION_OPTIMIZATION.  */
> -
> -static void
> -pdp11_option_optimization (int level, int size ATTRIBUTE_UNUSED)
> -{
> -  if (level >= 3)
> -    {
> -      flag_omit_frame_pointer = 1;
> -      /* flag_unroll_loops = 1; */
> -    }
> -}
> -
>  /* Implement TARGET_OPTION_INIT_STRUCT.  */
>
>  static void
> Index: gcc/config/microblaze/microblaze.c
> ===================================================================
> --- gcc/config/microblaze/microblaze.c  (revision 165714)
> +++ gcc/config/microblaze/microblaze.c  (working copy)
> @@ -1423,6 +1423,13 @@ microblaze_option_override (void)
>     }
>  }
>
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options microblaze_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
> +
>  /* Return true if FUNC is an interrupt function as specified
>    by the "interrupt_handler" attribute.  */
>
> @@ -3028,6 +3035,9 @@ microblaze_adjust_cost (rtx insn ATTRIBU
>  #undef  TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE         microblaze_option_override
>
> +#undef  TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE microblaze_option_optimization_table
> +
>  #undef TARGET_EXCEPT_UNWIND_INFO
>  #define TARGET_EXCEPT_UNWIND_INFO  sjlj_except_unwind_info
>
> Index: gcc/config/microblaze/microblaze.h
> ===================================================================
> --- gcc/config/microblaze/microblaze.h  (revision 165714)
> +++ gcc/config/microblaze/microblaze.h  (working copy)
> @@ -61,9 +61,6 @@ extern enum pipeline_type microblaze_pip
>  #define SWITCH_TAKES_ARG(CHAR)                                         \
>   (DEFAULT_SWITCH_TAKES_ARG (CHAR) || (CHAR) == 'G')
>
> -/*  We can debug without having a frame pointer.  */
> -#define CAN_DEBUG_WITHOUT_FP
> -
>  #define DRIVER_SELF_SPECS                              \
>        "%{mxl-soft-mul:%<mno-xl-soft-mul}",            \
>        "%{mno-xl-barrel-shift:%<mxl-barrel-shift}",    \
> Index: gcc/config/avr/avr.c
> ===================================================================
> --- gcc/config/avr/avr.c        (revision 165714)
> +++ gcc/config/avr/avr.c        (working copy)
> @@ -133,6 +133,13 @@ static const struct attribute_spec avr_a
>   { "OS_main",   0, 0, false, true,  true,   avr_handle_fntype_attribute },
>   { NULL,        0, 0, false, false, false, NULL }
>  };
> +
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options avr_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  /* Initialize the GCC target structure.  */
>  #undef TARGET_ASM_ALIGNED_HI_OP
> @@ -208,6 +215,9 @@ static const struct attribute_spec avr_a
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE avr_option_override
>
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE avr_option_optimization_table
> +
>  struct gcc_target targetm = TARGET_INITIALIZER;
>
>  static void
> Index: gcc/config/avr/avr.h
> ===================================================================
> --- gcc/config/avr/avr.h        (revision 165714)
> +++ gcc/config/avr/avr.h        (working copy)
> @@ -124,8 +124,6 @@ extern GTY(()) section *progmem_section;
>
>  #define TARGET_VERSION fprintf (stderr, " (GNU assembler syntax)");
>
> -#define CAN_DEBUG_WITHOUT_FP
> -
>  #define BITS_BIG_ENDIAN 0
>  #define BYTES_BIG_ENDIAN 0
>  #define WORDS_BIG_ENDIAN 0
> Index: gcc/config/crx/crx.h
> ===================================================================
> --- gcc/config/crx/crx.h        (revision 165714)
> +++ gcc/config/crx/crx.h        (working copy)
> @@ -54,9 +54,6 @@ do {                                                          \
>
>  #define TARGET_VERSION fputs (" (CRX/ELF)", stderr);
>
> -/* Show we can debug even without a frame pointer.  */
> -#define CAN_DEBUG_WITHOUT_FP
> -
>  /*****************************************************************************/
>  /* STORAGE LAYOUT                                                           */
>  /*****************************************************************************/
> Index: gcc/config/crx/crx.c
> ===================================================================
> --- gcc/config/crx/crx.c        (revision 165714)
> +++ gcc/config/crx/crx.c        (working copy)
> @@ -130,7 +130,6 @@ static bool crx_return_in_memory (const_
>  static int crx_address_cost (rtx, bool);
>  static bool crx_legitimate_address_p (enum machine_mode, rtx, bool);
>  static bool crx_can_eliminate (const int, const int);
> -static void crx_option_optimization (int, int);
>
>  /*****************************************************************************/
>  /* RTL VALIDITY                                                                     */
> @@ -177,8 +176,17 @@ static const struct attribute_spec crx_a
>
>  /* Option handling.  */
>
> -#undef TARGET_OPTION_OPTIMIZATION
> -#define        TARGET_OPTION_OPTIMIZATION      crx_option_optimization
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define        TARGET_OPTION_OPTIMIZATION_TABLE        crx_option_optimization_table
> +
> +static const struct default_options crx_option_optimization_table[] =
> +  {
> +    /* Put each function in its own section so that PAGE-instruction
> +       relaxation can do its best.  */
> +    { OPT_LEVELS_1_PLUS, OPT_ffunction_sections, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  /* Initialize 'targetm' variable which contains pointers to functions and data
>  * relating to the target machine.  */
> @@ -1447,13 +1455,3 @@ crx_expand_epilogue (void)
>   else
>     emit_jump_insn (gen_pop_and_popret_return (GEN_INT (sum_regs)));
>  }
> -
> -/* Implement TARGET_OPTION_OPTIMIZATION.  */
> -static void
> -crx_option_optimization (int level, int size)
> -{
> -  /* Put each function in its own section so that PAGE-instruction
> -     relaxation can do its best.  */
> -  if (level || size)
> -    flag_function_sections = 1;
> -}
> Index: gcc/config/xtensa/xtensa.c
> ===================================================================
> --- gcc/config/xtensa/xtensa.c  (revision 165714)
> +++ gcc/config/xtensa/xtensa.c  (working copy)
> @@ -119,7 +119,6 @@ const enum reg_class xtensa_regno_to_cla
>  };
>
>  static void xtensa_option_override (void);
> -static void xtensa_option_optimization (int, int);
>  static enum internal_test map_test_to_internal_test (enum rtx_code);
>  static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *);
>  static rtx gen_float_relational (enum rtx_code, rtx, rtx);
> @@ -160,6 +159,20 @@ static void xtensa_trampoline_init (rtx,
>
>  static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
>   REG_ALLOC_ORDER;
> +
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +
> +static const struct default_options xtensa_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    /* Reordering blocks for Xtensa is not a good idea unless the
> +       compiler understands the range of conditional branches.
> +       Currently all branch relaxation for Xtensa is handled in the
> +       assembler, so GCC cannot do a good job of reordering blocks.
> +       Do not enable reordering unless it is explicitly requested.  */
> +    { OPT_LEVELS_ALL, OPT_freorder_blocks, NULL, 0 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>
>  /* This macro generates the assembly code for function exit,
> @@ -255,8 +268,8 @@ static const int reg_nonleaf_alloc_order
>
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE xtensa_option_override
> -#undef TARGET_OPTION_OPTIMIZATION
> -#define TARGET_OPTION_OPTIMIZATION xtensa_option_optimization
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE xtensa_option_optimization_table
>
>  struct gcc_target targetm = TARGET_INITIALIZER;
>
> @@ -2171,20 +2184,6 @@ xtensa_option_override (void)
>     }
>  }
>
> -/* Implement TARGET_OPTION_OPTIMIZATION.  */
> -
> -static void
> -xtensa_option_optimization (int level ATTRIBUTE_UNUSED,
> -                           int size ATTRIBUTE_UNUSED)
> -{
> -  /* Reordering blocks for Xtensa is not a good idea unless the
> -     compiler understands the range of conditional branches.
> -     Currently all branch relaxation for Xtensa is handled in the
> -     assembler, so GCC cannot do a good job of reordering blocks.  Do
> -     not enable reordering unless it is explicitly requested.  */
> -  flag_reorder_blocks = 0;
> -}
> -
>  /* A C compound statement to output to stdio stream STREAM the
>    assembler syntax for an instruction operand X.  X is an RTL
>    expression.
> Index: gcc/config/xtensa/xtensa.h
> ===================================================================
> --- gcc/config/xtensa/xtensa.h  (revision 165714)
> +++ gcc/config/xtensa/xtensa.h  (working copy)
> @@ -100,9 +100,6 @@ extern unsigned xtensa_current_frame_siz
>  #define LIBGCC2_WORDS_BIG_ENDIAN 0
>  #endif
>
> -/* Show we can debug even without a frame pointer.  */
> -#define CAN_DEBUG_WITHOUT_FP
> -
>
>  /* Target machine storage layout */
>
> Index: gcc/config/stormy16/stormy16.c
> ===================================================================
> --- gcc/config/stormy16/stormy16.c      (revision 165714)
> +++ gcc/config/stormy16/stormy16.c      (working copy)
> @@ -1,6 +1,6 @@
>  /* Xstormy16 target functions.
>    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
> -   2006, 2007, 2008, 2009 Free Software Foundation, Inc.
> +   2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
>    Contributed by Red Hat, Inc.
>
>    This file is part of GCC.
> @@ -2623,6 +2623,13 @@ xstormy16_return_in_memory (const_tree t
>   return (size == -1 || size > UNITS_PER_WORD * NUM_ARGUMENT_REGISTERS);
>  }
>
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options xstorym16_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
> +
>  #undef  TARGET_ASM_ALIGNED_HI_OP
>  #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
>  #undef  TARGET_ASM_ALIGNED_SI_OP
> @@ -2671,6 +2678,9 @@ xstormy16_return_in_memory (const_tree t
>  #undef TARGET_TRAMPOLINE_INIT
>  #define TARGET_TRAMPOLINE_INIT xstormy16_trampoline_init
>
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE xstorym16_option_optimization_table
> +
>  struct gcc_target targetm = TARGET_INITIALIZER;
>
>  #include "gt-stormy16.h"
> Index: gcc/config/stormy16/stormy16.h
> ===================================================================
> --- gcc/config/stormy16/stormy16.h      (revision 165714)
> +++ gcc/config/stormy16/stormy16.h      (working copy)
> @@ -53,8 +53,6 @@
>   while (0)
>
>  #define TARGET_VERSION fprintf (stderr, " (xstormy16 cpu core)");
> -
> -#define CAN_DEBUG_WITHOUT_FP
>
>  /* Storage Layout.  */
>
> Index: gcc/config/fr30/fr30.h
> ===================================================================
> --- gcc/config/fr30/fr30.h      (revision 165714)
> +++ gcc/config/fr30/fr30.h      (working copy)
> @@ -1,7 +1,7 @@
>  /*{{{  Comment.  */
>
>  /* Definitions of FR30 target.
> -   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2007, 2008, 2009
> +   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2007, 2008, 2009, 2010
>    Free Software Foundation, Inc.
>    Contributed by Cygnus Solutions.
>
> @@ -50,8 +50,6 @@ along with GCC; see the file COPYING3.
>
>  #define TARGET_VERSION fprintf (stderr, " (fr30)");
>
> -#define CAN_DEBUG_WITHOUT_FP
> -
>  #undef  STARTFILE_SPEC
>  #define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s"
>
> Index: gcc/config/fr30/fr30.c
> ===================================================================
> --- gcc/config/fr30/fr30.c      (revision 165714)
> +++ gcc/config/fr30/fr30.c      (working copy)
> @@ -1,6 +1,6 @@
>  /* FR30 specific functions.
> -   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009
> -   Free Software Foundation, Inc.
> +   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009,
> +   2010 Free Software Foundation, Inc.
>    Contributed by Cygnus Solutions.
>
>    This file is part of GCC.
> @@ -142,6 +142,13 @@ static void fr30_trampoline_init (rtx, t
>  #if UNITS_PER_WORD == 4
>  #define WORD_ALIGN(SIZE) (((SIZE) + 3) & ~3)
>  #endif
> +
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options fr30_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  /* Initialize the GCC target structure.  */
>  #undef  TARGET_ASM_ALIGNED_HI_OP
> @@ -175,6 +182,9 @@ static void fr30_trampoline_init (rtx, t
>  #undef TARGET_EXCEPT_UNWIND_INFO
>  #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
>
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE fr30_option_optimization_table
> +
>  struct gcc_target targetm = TARGET_INITIALIZER;
>
>
> Index: gcc/config/lm32/lm32.h
> ===================================================================
> --- gcc/config/lm32/lm32.h      (revision 165714)
> +++ gcc/config/lm32/lm32.h      (working copy)
> @@ -536,8 +536,6 @@ do {
>
>  #define DBX_REGISTER_NUMBER(REGNO) (REGNO)
>
> -#define CAN_DEBUG_WITHOUT_FP
> -
>  #define DEFAULT_GDB_EXTENSIONS 1
>
>  /*--------*/
> Index: gcc/config/lm32/lm32.c
> ===================================================================
> --- gcc/config/lm32/lm32.c      (revision 165714)
> +++ gcc/config/lm32/lm32.c      (working copy)
> @@ -77,8 +77,17 @@ lm32_legitimate_address_p (enum machine_
>  static HOST_WIDE_INT lm32_compute_frame_size (int size);
>  static void lm32_option_override (void);
>
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options lm32_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
> +
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE lm32_option_override
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE lm32_option_optimization_table
>  #undef TARGET_ADDRESS_COST
>  #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
>  #undef TARGET_RTX_COSTS
> Index: gcc/config/cris/cris.c
> ===================================================================
> --- gcc/config/cris/cris.c      (revision 165714)
> +++ gcc/config/cris/cris.c      (working copy)
> @@ -132,7 +132,6 @@ static int cris_arg_partial_bytes (CUMUL
>  static tree cris_md_asm_clobbers (tree, tree, tree);
>
>  static bool cris_handle_option (size_t, const char *, int);
> -static void cris_option_optimization (int, int);
>  static void cris_option_override (void);
>
>  static bool cris_frame_pointer_required (void);
> @@ -150,6 +149,14 @@ int cris_max_stackframe = 0;
>  /* This is the parsed result of the "-march=" option, if given.  */
>  int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION;
>
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +
> +static const struct default_options cris_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_2_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
> +
>  #undef TARGET_ASM_ALIGNED_HI_OP
>  #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
>  #undef TARGET_ASM_ALIGNED_SI_OP
> @@ -218,8 +225,8 @@ int cris_cpu_version = CRIS_DEFAULT_CPU_
>
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE cris_option_override
> -#undef TARGET_OPTION_OPTIMIZATION
> -#define TARGET_OPTION_OPTIMIZATION cris_option_optimization
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE cris_option_optimization_table
>
>  #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
>  #define TARGET_ASM_TRAMPOLINE_TEMPLATE cris_asm_trampoline_template
> @@ -2422,15 +2429,6 @@ cris_handle_option (size_t code, const c
>   return true;
>  }
>
> -/* Implement TARGET_OPTION_OPTIMIZATION.  */
> -
> -static void
> -cris_option_optimization (int level, int size)
> -{
> -  if (level >= 2 || size)
> -    flag_omit_frame_pointer = 1;
> -}
> -
>  /* The TARGET_OPTION_OVERRIDE worker.
>    As is the norm, this also parses -mfoo=bar type parameters.  */
>
> Index: gcc/config/iq2000/iq2000.h
> ===================================================================
> --- gcc/config/iq2000/iq2000.h  (revision 165714)
> +++ gcc/config/iq2000/iq2000.h  (working copy)
> @@ -68,8 +68,6 @@
>  #ifndef TARGET_VERSION
>  #define TARGET_VERSION TARGET_VERSION_INTERNAL (stderr)
>  #endif
> -
> -#define CAN_DEBUG_WITHOUT_FP
>
>  /* Storage Layout.  */
>
> Index: gcc/config/iq2000/iq2000.c
> ===================================================================
> --- gcc/config/iq2000/iq2000.c  (revision 165714)
> +++ gcc/config/iq2000/iq2000.c  (working copy)
> @@ -175,6 +175,13 @@ static void iq2000_print_operand      (F
>  static void iq2000_print_operand_address (FILE *, rtx);
>  static bool iq2000_print_operand_punct_valid_p (unsigned char code);
>
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options iq2000_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
> +
>  #undef  TARGET_INIT_BUILTINS
>  #define TARGET_INIT_BUILTINS           iq2000_init_builtins
>  #undef  TARGET_EXPAND_BUILTIN
> @@ -185,6 +192,8 @@ static bool iq2000_print_operand_punct_v
>  #define TARGET_HANDLE_OPTION           iq2000_handle_option
>  #undef  TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE         iq2000_option_override
> +#undef  TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE iq2000_option_optimization_table
>  #undef  TARGET_RTX_COSTS
>  #define TARGET_RTX_COSTS               iq2000_rtx_costs
>  #undef  TARGET_ADDRESS_COST
> Index: gcc/config/mn10300/mn10300.c
> ===================================================================
> --- gcc/config/mn10300/mn10300.c        (revision 165714)
> +++ gcc/config/mn10300/mn10300.c        (working copy)
> @@ -92,6 +92,13 @@ static rtx mn10300_function_value (const
>  static rtx mn10300_libcall_value (enum machine_mode, const_rtx);
>  static void mn10300_asm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
>  static bool mn10300_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT, const_tree);
> +
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options mn10300_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  /* Initialize the GCC target structure.  */
>  #undef  TARGET_EXCEPT_UNWIND_INFO
> @@ -119,6 +126,8 @@ static bool mn10300_can_output_mi_thunk
>  #define TARGET_HANDLE_OPTION mn10300_handle_option
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE mn10300_option_override
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE mn10300_option_optimization_table
>
>  #undef  TARGET_ENCODE_SECTION_INFO
>  #define TARGET_ENCODE_SECTION_INFO mn10300_encode_section_info
> Index: gcc/config/mn10300/mn10300.h
> ===================================================================
> --- gcc/config/mn10300/mn10300.h        (revision 165714)
> +++ gcc/config/mn10300/mn10300.h        (working copy)
> @@ -485,10 +485,6 @@ enum reg_class {
>  #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
>   OFFSET = initial_offset (FROM, TO)
>
> -/* We can debug without frame pointers on the mn10300, so eliminate
> -   them whenever possible.  */
> -#define CAN_DEBUG_WITHOUT_FP
> -
>  /* We use d0/d1 for passing parameters, so allocate 8 bytes of space
>    for a register flushback area.  */
>  #define REG_PARM_STACK_SPACE(DECL) 8
> Index: gcc/config/ia64/vms.h
> ===================================================================
> --- gcc/config/ia64/vms.h       (revision 165714)
> +++ gcc/config/ia64/vms.h       (working copy)
> @@ -184,10 +184,8 @@ typedef struct crtl_name_spec
>     } while (0)
>
>  #undef SUBTARGET_OPTIMIZATION_OPTIONS
> -#define SUBTARGET_OPTIMIZATION_OPTIONS                     \
> -  do {                                                     \
> -       flag_merge_constants = 0;                           \
> -  } while (0)
> +#define SUBTARGET_OPTIMIZATION_OPTIONS                 \
> +  { OPT_LEVELS_ALL, OPT_fmerge_constants, NULL, 0 }
>
>  /* Define this to be nonzero if static stack checking is supported.  */
>  #define STACK_CHECK_STATIC_BUILTIN 1
> Index: gcc/config/ia64/ia64.c
> ===================================================================
> --- gcc/config/ia64/ia64.c      (revision 165714)
> +++ gcc/config/ia64/ia64.c      (working copy)
> @@ -202,7 +202,6 @@ static rtx gen_fr_spill_x (rtx, rtx, rtx
>  static rtx gen_fr_restore_x (rtx, rtx, rtx);
>
>  static void ia64_option_override (void);
> -static void ia64_option_optimization (int, int);
>  static void ia64_option_default_params (void);
>  static bool ia64_can_eliminate (const int, const int);
>  static enum machine_mode hfa_element_mode (const_tree, bool);
> @@ -339,6 +338,16 @@ static const struct attribute_spec ia64_
>   { NULL,             0, 0, false, false, false, NULL }
>  };
>
> +/* Implement overriding of the optimization options.  */
> +static const struct default_options ia64_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +#ifdef SUBTARGET_OPTIMIZATION_OPTIONS
> +    SUBTARGET_OPTIMIZATION_OPTIONS,
> +#endif
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
> +
>  /* Initialize the GCC target structure.  */
>  #undef TARGET_ATTRIBUTE_TABLE
>  #define TARGET_ATTRIBUTE_TABLE ia64_attribute_table
> @@ -371,8 +380,8 @@ static const struct attribute_spec ia64_
>
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE ia64_option_override
> -#undef TARGET_OPTION_OPTIMIZATION
> -#define TARGET_OPTION_OPTIMIZATION ia64_option_optimization
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE ia64_option_optimization_table
>  #undef TARGET_OPTION_DEFAULT_PARAMS
>  #define TARGET_OPTION_DEFAULT_PARAMS ia64_option_default_params
>
> @@ -10830,16 +10839,6 @@ ia64_invalid_binary_op (int op ATTRIBUTE
>   return NULL;
>  }
>
> -/* Implement overriding of the optimization options.  */
> -static void
> -ia64_option_optimization (int level ATTRIBUTE_UNUSED,
> -                         int size ATTRIBUTE_UNUSED)
> -{
> -#ifdef SUBTARGET_OPTIMIZATION_OPTIONS
> -  SUBTARGET_OPTIMIZATION_OPTIONS;
> -#endif
> -}
> -
>  /* Implement TARGET_OPTION_DEFAULT_PARAMS.  */
>  static void
>  ia64_option_default_params (void)
> Index: gcc/config/ia64/ia64.h
> ===================================================================
> --- gcc/config/ia64/ia64.h      (revision 165714)
> +++ gcc/config/ia64/ia64.h      (working copy)
> @@ -1001,9 +1001,6 @@ enum reg_class
>
>  /* Eliminating the Frame Pointer and the Arg Pointer */
>
> -/* Show we can debug even without a frame pointer.  */
> -#define CAN_DEBUG_WITHOUT_FP
> -
>  /* If defined, this macro specifies a table of register pairs used to eliminate
>    unneeded registers that point into the stack frame.  */
>
> Index: gcc/config/rs6000/rs6000.c
> ===================================================================
> --- gcc/config/rs6000/rs6000.c  (revision 165714)
> +++ gcc/config/rs6000/rs6000.c  (working copy)
> @@ -1363,6 +1363,13 @@ static const struct attribute_spec rs600
>  #endif
>   { NULL,        0, 0, false, false, false, NULL }
>  };
> +
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options rs6000_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  #ifndef MASK_STRICT_ALIGN
>  #define MASK_STRICT_ALIGN 0
> @@ -1608,6 +1615,9 @@ static const struct attribute_spec rs600
>  #undef TARGET_OPTION_DEFAULT_PARAMS
>  #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
>
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
> +
>  #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
>  #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
>   rs6000_builtin_vectorized_function
> Index: gcc/config/rs6000/rs6000.h
> ===================================================================
> --- gcc/config/rs6000/rs6000.h  (revision 165714)
> +++ gcc/config/rs6000/rs6000.h  (working copy)
> @@ -625,9 +625,6 @@ extern unsigned char rs6000_recip_bits[]
>  /* The default CPU for TARGET_OPTION_OVERRIDE.  */
>  #define OPTION_TARGET_CPU_DEFAULT TARGET_CPU_DEFAULT
>
> -/* Show we can debug even without a frame pointer.  */
> -#define CAN_DEBUG_WITHOUT_FP
> -
>  /* Target pragma.  */
>  #define REGISTER_TARGET_PRAGMAS() do {                         \
>   c_register_pragma (0, "longcall", rs6000_pragma_longcall);   \
> Index: gcc/config/picochip/picochip.c
> ===================================================================
> --- gcc/config/picochip/picochip.c      (revision 165714)
> +++ gcc/config/picochip/picochip.c      (working copy)
> @@ -198,6 +198,13 @@ static struct recog_data picochip_saved_
>  /* Determine which ALU to use for the instruction in
>    picochip_current_prescan_insn. */
>  static char picochip_get_vliw_alu_id (void);
> +
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options picochip_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  /* Initialize the GCC target structure.  */
>
> @@ -326,6 +333,9 @@ static char picochip_get_vliw_alu_id (vo
>  #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
>  #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE picochip_option_override
>
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE picochip_option_optimization_table
> +
>  #undef TARGET_EXCEPT_UNWIND_INFO
>  #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
>
> Index: gcc/config/picochip/picochip.h
> ===================================================================
> --- gcc/config/picochip/picochip.h      (revision 165714)
> +++ gcc/config/picochip/picochip.h      (working copy)
> @@ -84,8 +84,6 @@ extern enum picochip_dfa_type picochip_s
>  #define TARGET_HAS_MAC_UNIT (picochip_has_mac_unit)
>  #define TARGET_HAS_MULTIPLY (picochip_has_mac_unit || picochip_has_mul_unit)
>
> -#define CAN_DEBUG_WITHOUT_FP 1
> -
>  #define TARGET_VERSION fprintf(stderr, "(picoChip)");
>
>  /* Storage Layout */
> Index: gcc/config/mcore/mcore.c
> ===================================================================
> --- gcc/config/mcore/mcore.c    (revision 165714)
> +++ gcc/config/mcore/mcore.c    (working copy)
> @@ -145,7 +145,6 @@ static int        mcore_arg_partial_byte
>  static void       mcore_asm_trampoline_template (FILE *);
>  static void       mcore_trampoline_init                (rtx, tree, rtx);
>  static void       mcore_option_override                (void);
> -static void       mcore_option_optimization    (int, int);
>
>  /* MCore specific attributes.  */
>
> @@ -157,6 +156,23 @@ static const struct attribute_spec mcore
>   { "naked",     0, 0, true,  false, false, mcore_handle_naked_attribute },
>   { NULL,        0, 0, false, false, false, NULL }
>  };
> +
> +/* What options are we going to default to specific settings when
> +   -O* happens; the user can subsequently override these settings.
> +
> +   Omitting the frame pointer is a very good idea on the MCore.
> +   Scheduling isn't worth anything on the current MCore implementation.  */
> +
> +static const struct default_options mcore_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_ffunction_cse, NULL, 0 },
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_ALL, OPT_fcaller_saves, NULL, 0 },
> +    { OPT_LEVELS_ALL, OPT_fschedule_insns, NULL, 0 },
> +    { OPT_LEVELS_ALL, OPT_fschedule_insns2, NULL, 0 },
> +    { OPT_LEVELS_SIZE, OPT_mhardlit, NULL, 0 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  /* Initialize the GCC target structure.  */
>  #undef  TARGET_ASM_EXTERNAL_LIBCALL
> @@ -224,8 +240,8 @@ static const struct attribute_spec mcore
>
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE mcore_option_override
> -#undef TARGET_OPTION_OPTIMIZATION
> -#define TARGET_OPTION_OPTIMIZATION mcore_option_optimization
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE mcore_option_optimization_table
>
>  #undef TARGET_EXCEPT_UNWIND_INFO
>  #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
> @@ -2692,33 +2708,6 @@ mcore_option_override (void)
>     target_flags |= MASK_M340;
>  }
>
> -/* What options are we going to default to specific settings when
> -   -O* happens; the user can subsequently override these settings.
> -
> -   Omitting the frame pointer is a very good idea on the MCore.
> -   Scheduling isn't worth anything on the current MCore implementation.  */
> -
> -static void
> -mcore_option_optimization (int level, int size)
> -{
> -  if (level)
> -    {
> -      flag_no_function_cse = 1;
> -      flag_omit_frame_pointer = 1;
> -
> -      if (level >= 2)
> -        {
> -          flag_caller_saves = 0;
> -          flag_schedule_insns = 0;
> -          flag_schedule_insns_after_reload = 0;
> -        }
> -    }
> -  if (size)
> -    {
> -      target_flags &= ~MASK_HARDLIT;
> -    }
> -}
> -
>
>  /* Compute the number of word sized registers needed to
>    hold a function argument of mode MODE and type TYPE.  */
> Index: gcc/config/score/score.c
> ===================================================================
> --- gcc/config/score/score.c    (revision 165714)
> +++ gcc/config/score/score.c    (working copy)
> @@ -53,6 +53,13 @@
>
>  static void score_option_override (void);
>
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options score_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
> +
>  #undef  TARGET_ASM_FILE_START
>  #define TARGET_ASM_FILE_START           score_asm_file_start
>
> @@ -71,6 +78,8 @@ static void score_option_override (void)
>  #define TARGET_HANDLE_OPTION            score_handle_option
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE          score_option_override
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE score_option_optimization_table
>
>  #undef TARGET_LEGITIMIZE_ADDRESS
>  #define TARGET_LEGITIMIZE_ADDRESS      score_legitimize_address
> Index: gcc/config/score/score.h
> ===================================================================
> --- gcc/config/score/score.h    (revision 165714)
> +++ gcc/config/score/score.h    (working copy)
> @@ -98,9 +98,6 @@
>  #define TARGET_VERSION \
>       fprintf (stderr, "Sunplus S+core rev=%s", SCORE_GCC_VERSION);
>
> -/* Show we can debug even without a frame pointer.  */
> -#define CAN_DEBUG_WITHOUT_FP
> -
>  /* Target machine storage layout.  */
>  #define BITS_BIG_ENDIAN        0
>  #define BYTES_BIG_ENDIAN       (TARGET_LITTLE_ENDIAN == 0)
> Index: gcc/config/arm/arm.c
> ===================================================================
> --- gcc/config/arm/arm.c        (revision 165714)
> +++ gcc/config/arm/arm.c        (working copy)
> @@ -217,7 +217,6 @@ static tree arm_build_builtin_va_list (v
>  static void arm_expand_builtin_va_start (tree, rtx);
>  static tree arm_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
>  static void arm_option_override (void);
> -static void arm_option_optimization (int, int);
>  static bool arm_handle_option (size_t, const char *, int);
>  static void arm_target_help (void);
>  static unsigned HOST_WIDE_INT arm_shift_truncation_mask (enum machine_mode);
> @@ -286,6 +285,15 @@ static const struct attribute_spec arm_a
>  #endif
>   { NULL,           0, 0, false, false, false, NULL }
>  };
> +
> +/* Set default optimization options.  */
> +static const struct default_options arm_option_optimization_table[] =
> +  {
> +    /* Enable section anchors by default at -O1 or higher.  */
> +    { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 },
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  /* Initialize the GCC target structure.  */
>  #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
> @@ -333,8 +341,8 @@ static const struct attribute_spec arm_a
>  #define TARGET_HELP arm_target_help
>  #undef  TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE arm_option_override
> -#undef  TARGET_OPTION_OPTIMIZATION
> -#define TARGET_OPTION_OPTIMIZATION arm_option_optimization
> +#undef  TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE arm_option_optimization_table
>
>  #undef  TARGET_COMP_TYPE_ATTRIBUTES
>  #define TARGET_COMP_TYPE_ATTRIBUTES arm_comp_type_attributes
> @@ -22819,15 +22827,6 @@ arm_order_regs_for_local_alloc (void)
>             sizeof (thumb_core_reg_alloc_order));
>  }
>
> -/* Set default optimization options.  */
> -static void
> -arm_option_optimization (int level, int size ATTRIBUTE_UNUSED)
> -{
> -  /* Enable section anchors by default at -O1 or higher.  */
> -  if (level > 0)
> -    flag_section_anchors = 1;
> -}
> -
>  /* Implement TARGET_FRAME_POINTER_REQUIRED.  */
>
>  bool
> Index: gcc/config/arm/arm.h
> ===================================================================
> --- gcc/config/arm/arm.h        (revision 165714)
> +++ gcc/config/arm/arm.h        (working copy)
> @@ -494,10 +494,6 @@ extern int arm_arch_hwdiv;
>  #define TARGET_DEFAULT  (MASK_APCS_FRAME)
>  #endif
>
> -/* The frame pointer register used in gcc has nothing to do with debugging;
> -   that is controlled by the APCS-FRAME option.  */
> -#define CAN_DEBUG_WITHOUT_FP
> -
>  /* Nonzero if PIC code requires explicit qualifiers to generate
>    PLT and GOT relocs rather than the assembler doing so implicitly.
>    Subtargets can override these if required.  */
> Index: gcc/config/pa/pa.c
> ===================================================================
> --- gcc/config/pa/pa.c  (revision 165714)
> +++ gcc/config/pa/pa.c  (working copy)
> @@ -222,11 +222,20 @@ static GTY((length ("n_deferred_plabels"
>   deferred_plabels;
>  static size_t n_deferred_plabels = 0;
>
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options pa_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
> +
>
>  /* Initialize the GCC target structure.  */
>
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE pa_option_override
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE pa_option_optimization_table
>
>  #undef TARGET_ASM_ALIGNED_HI_OP
>  #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
> Index: gcc/config/pa/pa.h
> ===================================================================
> --- gcc/config/pa/pa.h  (revision 165714)
> +++ gcc/config/pa/pa.h  (working copy)
> @@ -226,9 +226,6 @@ do {                                                                \
>  #define PTRDIFF_TYPE "int"
>  #define WCHAR_TYPE "unsigned int"
>  #define WCHAR_TYPE_SIZE 32
> -
> -/* Show we can debug even without a frame pointer.  */
> -#define CAN_DEBUG_WITHOUT_FP
>
>  /* target machine storage layout */
>  typedef struct GTY(()) machine_function
> Index: gcc/config/mips/mips.c
> ===================================================================
> --- gcc/config/mips/mips.c      (revision 165714)
> +++ gcc/config/mips/mips.c      (working copy)
> @@ -15876,6 +15876,13 @@ mips_option_override (void)
>   mips_set_mips16_mode (false);
>  }
>
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +static const struct default_options mips_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
> +
>  /* Swap the register information for registers I and I + 1, which
>    currently have the wrong endianness.  Note that the registers'
>    fixedness and call-clobberedness might have been set on the
> @@ -16390,6 +16397,8 @@ mips_shift_truncation_mask (enum machine
>
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE mips_option_override
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE mips_option_optimization_table
>
>  #undef TARGET_LEGITIMIZE_ADDRESS
>  #define TARGET_LEGITIMIZE_ADDRESS mips_legitimize_address
> Index: gcc/config/mips/mips.h
> ===================================================================
> --- gcc/config/mips/mips.h      (revision 165714)
> +++ gcc/config/mips/mips.h      (working copy)
> @@ -1082,9 +1082,6 @@ enum mips_code_readable_setting {
>   (DEFAULT_SWITCH_TAKES_ARG (CHAR) || (CHAR) == 'G')
>
>  #define CONDITIONAL_REGISTER_USAGE mips_conditional_register_usage ()
> -
> -/* Show we can debug even without a frame pointer.  */
> -#define CAN_DEBUG_WITHOUT_FP
>
>  /* Tell collect what flags to pass to nm.  */
>  #ifndef NM_FLAGS
> Index: gcc/config/v850/v850.c
> ===================================================================
> --- gcc/config/v850/v850.c      (revision 165714)
> +++ gcc/config/v850/v850.c      (working copy)
> @@ -141,20 +141,20 @@ v850_handle_option (size_t code, const c
>     }
>  }
>
> -/* Implement TARGET_OPTION_OPTIMIZATION.  */
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
>
> -static void
> -v850_option_optimization (int level, int size ATTRIBUTE_UNUSED)
> -{
> -  if (level)
> +static const struct default_options v850_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
>     /* Note - we no longer enable MASK_EP when optimizing.  This is
>        because of a hardware bug which stops the SLD and SST instructions
>        from correctly detecting some hazards.  If the user is sure that
>        their hardware is fixed or that their program will not encounter
>        the conditions that trigger the bug then they can enable -mep by
>        hand.  */
> -    target_flags |= MASK_PROLOG_FUNCTION;
> -}
> +    { OPT_LEVELS_1_PLUS, OPT_mprolog_function, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  /* Handle the TARGET_PASS_BY_REFERENCE target hook.
>    Specify whether to pass the argument by reference.  */
> @@ -3202,8 +3202,8 @@ static const struct attribute_spec v850_
>  #undef  TARGET_STRICT_ARGUMENT_NAMING
>  #define TARGET_STRICT_ARGUMENT_NAMING v850_strict_argument_naming
>
> -#undef  TARGET_OPTION_OPTIMIZATION
> -#define TARGET_OPTION_OPTIMIZATION v850_option_optimization
> +#undef  TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE v850_option_optimization_table
>
>  struct gcc_target targetm = TARGET_INITIALIZER;
>
> Index: gcc/config/v850/v850.h
> ===================================================================
> --- gcc/config/v850/v850.h      (revision 165714)
> +++ gcc/config/v850/v850.h      (working copy)
> @@ -137,9 +137,6 @@ enum small_memory_type {
>  };
>
>  extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max];
> -
> -/* Show we can debug even without a frame pointer.  */
> -#define CAN_DEBUG_WITHOUT_FP
>
>  /* Target machine storage layout */
>
> Index: gcc/config/h8300/h8300.c
> ===================================================================
> --- gcc/config/h8300/h8300.c    (revision 165714)
> +++ gcc/config/h8300/h8300.c    (working copy)
> @@ -303,17 +303,16 @@ enum h8_cpu
>   H8_S
>  };
>
> -/* Implement TARGET_OPTION_OPTIMIZATION.  */
> +/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
>
> -static void
> -h8300_option_optimization (int level ATTRIBUTE_UNUSED,
> -                          int size ATTRIBUTE_UNUSED)
> -{
> -  /* Basic block reordering is only beneficial on targets with cache
> -     and/or variable-cycle branches where (cycle count taken != cycle
> -     count not taken).  */
> -  flag_reorder_blocks = 0;
> -}
> +static const struct default_options h8300_option_optimization_table[] =
> +  {
> +    /* Basic block reordering is only beneficial on targets with cache
> +       and/or variable-cycle branches where (cycle count taken !=
> +       cycle count not taken).  */
> +    { OPT_LEVELS_ALL, OPT_freorder_blocks, NULL, 0 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
>
>  /* Initialize various cpu specific globals at start up.  */
>
> @@ -5937,7 +5936,7 @@ h8300_trampoline_init (rtx m_tramp, tree
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE h8300_option_override
>
> -#undef TARGET_OPTION_OPTIMIZATION
> -#define TARGET_OPTION_OPTIMIZATION h8300_option_optimization
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE h8300_option_optimization_table
>
>  struct gcc_target targetm = TARGET_INITIALIZER;
> Index: gcc/config/h8300/h8300.h
> ===================================================================
> --- gcc/config/h8300/h8300.h    (revision 165714)
> +++ gcc/config/h8300/h8300.h    (working copy)
> @@ -125,9 +125,6 @@ extern const char * const *h8_reg_names;
>  #define TARGET_DEFAULT (MASK_QUICKCALL)
>  #endif
>
> -/* Show we can debug even without a frame pointer.  */
> -/* #define CAN_DEBUG_WITHOUT_FP */
> -
>  /* We want dwarf2 info available to gdb...  */
>  #define DWARF2_DEBUGGING_INFO        1
>  /* ... but we don't actually support full dwarf2 EH.  */
> Index: gcc/config/mmix/mmix.h
> ===================================================================
> --- gcc/config/mmix/mmix.h      (revision 165714)
> +++ gcc/config/mmix/mmix.h      (working copy)
> @@ -147,10 +147,6 @@ struct GTY(()) machine_function
>  #define TARGET_VERSION \
>   fprintf (stderr, " (MMIX)")
>
> -/* This one will have to wait a little bit; right now we can't debug
> -   neither with or without a frame-pointer.  */
> -/* #define CAN_DEBUG_WITHOUT_FP */
> -
>
>  /* Node: Per-Function Data */
>  #define INIT_EXPANDERS mmix_init_expanders ()
> Index: gcc/config/mmix/mmix.c
> ===================================================================
> --- gcc/config/mmix/mmix.c      (revision 165714)
> +++ gcc/config/mmix/mmix.c      (working copy)
> @@ -114,7 +114,6 @@ rtx mmix_compare_op1;
>  static int mmix_output_destination_register;
>
>  static void mmix_option_override (void);
> -static void mmix_option_optimization (int, int);
>  static void mmix_asm_output_source_filename (FILE *, const char *);
>  static void mmix_output_shiftvalue_op_from_str
>   (FILE *, const char *, HOST_WIDEST_INT);
> @@ -160,6 +159,15 @@ static bool mmix_frame_pointer_required
>  static void mmix_asm_trampoline_template (FILE *);
>  static void mmix_trampoline_init (rtx, tree, rtx);
>
> +/* TARGET_OPTION_OPTIMIZATION_TABLE.  */
> +
> +static const struct default_options mmix_option_optimization_table[] =
> +  {
> +    { OPT_LEVELS_1_PLUS, OPT_fregmove, NULL, 1 },
> +    { OPT_LEVELS_2_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
> +    { OPT_LEVELS_NONE, 0, NULL, 0 }
> +  };
> +
>  /* Target structure macros.  Listed by node.  See `Using and Porting GCC'
>    for a general description.  */
>
> @@ -251,8 +259,8 @@ static void mmix_trampoline_init (rtx, t
>
>  #undef TARGET_OPTION_OVERRIDE
>  #define TARGET_OPTION_OVERRIDE mmix_option_override
> -#undef TARGET_OPTION_OPTIMIZATION
> -#define TARGET_OPTION_OPTIMIZATION mmix_option_optimization
> +#undef TARGET_OPTION_OPTIMIZATION_TABLE
> +#define TARGET_OPTION_OPTIMIZATION_TABLE mmix_option_optimization_table
>
>  struct gcc_target targetm = TARGET_INITIALIZER;
>
> @@ -276,18 +284,6 @@ mmix_option_override (void)
>     }
>  }
>
> -/* TARGET_OPTION_OPTIMIZATION.  */
> -
> -static void
> -mmix_option_optimization (int level, int size)
> -{
> -  if (level >= 1)
> -    flag_regmove = 1;
> -
> -  if (size || level > 1)
> -    flag_omit_frame_pointer = 1;
> -}
> -
>  /* INIT_EXPANDERS.  */
>
>  void
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
>
Kaz Kojima Oct. 22, 2010, 11:06 a.m. UTC | #3
"Joseph S. Myers" <joseph@codesourcery.com> wrote:
> The SH changes are more complicated than those for other targets.
> Optimization options could enable MASK_SMALLCODE and
> MASK_SAVE_ALL_TARGET_REGS.  The former corresponded to a deprecated
> -mspace option; rather than having -Os imply a deprecated option, I
> made the deprecated option into an alias for -Os and changed all the
> TARGET_SMALLCODE tests to test optimize_size.  (Some should probably
> move to being on a per-basic-block basis; I leave that to the SH
> maintainers.)  There is no option corresponding to
> MASK_SAVE_ALL_TARGET_REGS, and the tables can only represent implying
> options, not settings without a corresponding option, so I moved that
> implication into sh_option_override.
> 
> Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  Also
> tested building cc1 for crosses to: alpha-linux-gnu arm-eabi avr-elf
> cris-elf crx-elf fr30-elf frv-elf h8300-elf i386-solaris2.10 ia64-elf
> ia64-hp-vms iq2000-elf lm32-elf m32r-elf mcore-elf mep-elf
> microblaze-elf mips-elf mmix-knuth-mmixware mn10300-elf hppa-linux-gnu
> pdp11-none picochip-none powerpc-eabi rx-elf s390-linux-gnu score-elf
> sh-elf sparc-elf xstormy16-elf v850-elf xtensa-elf.  (The mn10300
> build was broken for other reasons at the revision I tested:
> "mn10300.md:1798: unknown mode `CC_FLOAT'".)  OK to commit?

The SH portion is Ok.  Thanks!

Regards,
	kaz
diff mbox

Patch

Index: gcc/doc/tm.texi
===================================================================
--- gcc/doc/tm.texi	(revision 165714)
+++ gcc/doc/tm.texi	(working copy)
@@ -791,26 +791,19 @@  used to alter option flag variables whic
 frontends.
 @end defmac
 
-@deftypefn {Target Hook} void TARGET_OPTION_OPTIMIZATION (int @var{level}, int @var{size})
+@deftypevr {Target Hook} {const struct default_options *} TARGET_OPTION_OPTIMIZATION_TABLE
 Some machines may desire to change what optimizations are performed for
-various optimization levels.   This hook, if defined, is executed once
+various optimization levels.   This variable, if defined, describes
+options to enable at particular sets of optimization levels.  These
+options are processed once
 just after the optimization level is determined and before the remainder
-of the command options have been parsed.  Values set in this macro are
-used as the default values for the other command line options.
+of the command options have been parsed, so may be overridden by other
+options passed explicily.
 
-@var{level} is the optimization level specified; 2 if @option{-O2} is
-specified, 1 if @option{-O} is specified, and 0 if neither is specified.
-
-@var{size} is nonzero if @option{-Os} is specified and zero otherwise.
-
-This macro is run once at program startup and when the optimization
+This processing is run once at program startup and when the optimization
 options are changed via @code{#pragma GCC optimize} or by using the
 @code{optimize} attribute.
-
-@strong{Do not examine @code{write_symbols} in
-this hook!}  The debugging options are not supposed to alter the
-generated code.
-@end deftypefn
+@end deftypevr
 
 @deftypefn {Target Hook} void TARGET_OPTION_INIT_STRUCT (struct gcc_options *@var{opts})
 Set target-dependent initial values of fields in @var{opts}.
@@ -827,12 +820,6 @@  chance to display extra information on t
 line options found in its @file{.opt} file.
 @end deftypefn
 
-@defmac CAN_DEBUG_WITHOUT_FP
-Define this macro if debugging can be performed even without a frame
-pointer.  If this macro is defined, GCC will turn on the
-@option{-fomit-frame-pointer} option whenever @option{-O} is specified.
-@end defmac
-
 @defmac SWITCHABLE_TARGET
 Some targets need to switch between substantially different subtargets
 during compilation.  For example, the MIPS target has one subtarget for
Index: gcc/doc/tm.texi.in
===================================================================
--- gcc/doc/tm.texi.in	(revision 165714)
+++ gcc/doc/tm.texi.in	(working copy)
@@ -791,26 +791,19 @@  used to alter option flag variables whic
 frontends.
 @end defmac
 
-@hook TARGET_OPTION_OPTIMIZATION
+@hook TARGET_OPTION_OPTIMIZATION_TABLE
 Some machines may desire to change what optimizations are performed for
-various optimization levels.   This hook, if defined, is executed once
+various optimization levels.   This variable, if defined, describes
+options to enable at particular sets of optimization levels.  These
+options are processed once
 just after the optimization level is determined and before the remainder
-of the command options have been parsed.  Values set in this macro are
-used as the default values for the other command line options.
+of the command options have been parsed, so may be overridden by other
+options passed explicily.
 
-@var{level} is the optimization level specified; 2 if @option{-O2} is
-specified, 1 if @option{-O} is specified, and 0 if neither is specified.
-
-@var{size} is nonzero if @option{-Os} is specified and zero otherwise.
-
-This macro is run once at program startup and when the optimization
+This processing is run once at program startup and when the optimization
 options are changed via @code{#pragma GCC optimize} or by using the
 @code{optimize} attribute.
-
-@strong{Do not examine @code{write_symbols} in
-this hook!}  The debugging options are not supposed to alter the
-generated code.
-@end deftypefn
+@end deftypevr
 
 @hook TARGET_OPTION_INIT_STRUCT
 
@@ -823,12 +816,6 @@  chance to display extra information on t
 line options found in its @file{.opt} file.
 @end deftypefn
 
-@defmac CAN_DEBUG_WITHOUT_FP
-Define this macro if debugging can be performed even without a frame
-pointer.  If this macro is defined, GCC will turn on the
-@option{-fomit-frame-pointer} option whenever @option{-O} is specified.
-@end defmac
-
 @defmac SWITCHABLE_TARGET
 Some targets need to switch between substantially different subtargets
 during compilation.  For example, the MIPS target has one subtarget for
Index: gcc/targhooks.c
===================================================================
--- gcc/targhooks.c	(revision 165714)
+++ gcc/targhooks.c	(working copy)
@@ -1333,4 +1333,9 @@  sjlj_except_unwind_info (void)
   return UI_SJLJ;
 }
 
+const struct default_options empty_optimization_table[] =
+  {
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 #include "gt-targhooks.h"
Index: gcc/targhooks.h
===================================================================
--- gcc/targhooks.h	(revision 165714)
+++ gcc/targhooks.h	(working copy)
@@ -167,3 +167,5 @@  extern int default_label_align_after_bar
 extern int default_loop_align_max_skip (rtx);
 extern int default_label_align_max_skip (rtx);
 extern int default_jump_align_max_skip (rtx);
+
+extern const struct default_options empty_optimization_table[];
Index: gcc/target.def
===================================================================
--- gcc/target.def	(revision 165714)
+++ gcc/target.def	(working copy)
@@ -961,13 +961,6 @@  DEFHOOK
  bool, (size_t code, const char *arg, int value),
  hook_bool_size_t_constcharptr_int_true)
 
-/* ??? Documenting this hook requires a GFDL license grant.  */
-DEFHOOK_UNDOC
-(handle_ofast,
- "Handle target-specific parts of specifying -Ofast.",
- void, (void),
- hook_void_void)
-
 /* Display extra, target specific information in response to a
    --target-help switch.  */
 DEFHOOK
@@ -2384,11 +2377,10 @@  DEFHOOK
  hook_void_void)
 
 /* Set default optimizations for the target.  */
-DEFHOOK
-(optimization,
+DEFHOOKPOD
+(optimization_table,
  "",
- void, (int level, int size),
- hook_void_int_int)
+ const struct default_options *, empty_optimization_table)
 
 DEFHOOK
 (default_params,
Index: gcc/target.h
===================================================================
--- gcc/target.h	(revision 165714)
+++ gcc/target.h	(working copy)
@@ -128,6 +128,41 @@  enum vect_cost_for_stmt
   vec_perm
 };
 
+/* Sets of optimization levels at which an option may be enabled by
+   default_options_optimization.  */
+enum opt_levels
+{
+  OPT_LEVELS_NONE, /* No levels (mark end of array).  */
+  OPT_LEVELS_ALL, /* All levels (used by targets to disable options
+		     enabled in target-independent code).  */
+  OPT_LEVELS_0_ONLY, /* -O0 only.  */
+  OPT_LEVELS_1_PLUS, /* -O1 and above, including -Os.  */
+  OPT_LEVELS_1_PLUS_SPEED_ONLY, /* -O1 and above, but not -Os.  */
+  OPT_LEVELS_2_PLUS, /* -O2 and above, including -Os.  */
+  OPT_LEVELS_2_PLUS_SPEED_ONLY, /* -O2 and above, but not -Os.  */
+  OPT_LEVELS_3_PLUS, /* -O3 and above.  */
+  OPT_LEVELS_3_PLUS_AND_SIZE, /* -O3 and above and -Os.  */
+  OPT_LEVELS_SIZE, /* -Os only.  */
+  OPT_LEVELS_FAST /* -Ofast only.  */
+};
+
+/* Description of options to enable by default at given levels.  */
+struct default_options
+{
+  /* The levels at which to enable the option.  */
+  enum opt_levels levels;
+
+  /* The option index and argument or enabled/disabled sense of the
+     option, as passed to handle_generated_option.  If ARG is NULL and
+     the option allows a negative form, the option is considered to be
+     passed in negative form when the optimization level is not one of
+     those in LEVELS (in order to handle changes to the optimization
+     level with the "optimize" attribute).  */
+  size_t opt_index;
+  const char *arg;
+  int value;
+};
+
 /* The target structure.  This holds all the backend hooks.  */
 #define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME;
 #define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS;
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c	(revision 165714)
+++ gcc/toplev.c	(working copy)
@@ -1822,11 +1822,7 @@  process_options (void)
   if (flag_unroll_all_loops)
     flag_unroll_loops = 1;
 
-  /* The loop unrolling code assumes that cse will be run after loop.
-     web and rename-registers also help when run after loop unrolling.  */
-  if (flag_rerun_cse_after_loop == AUTODETECT_VALUE)
-    flag_rerun_cse_after_loop = flag_unroll_loops || flag_peel_loops;
-
+  /* web and rename-registers help when run after loop unrolling.  */
   if (flag_web == AUTODETECT_VALUE)
     flag_web = flag_unroll_loops || flag_peel_loops;
 
Index: gcc/opts.c
===================================================================
--- gcc/opts.c	(revision 165714)
+++ gcc/opts.c	(working copy)
@@ -717,24 +717,206 @@  decode_cmdline_options_to_array_default_
 				   decoded_options, decoded_options_count);
 }
 
+/* If indicated by the optimization level LEVEL (-Os if SIZE is set,
+   -Ofast if FAST is set), apply the option DEFAULT_OPT to OPTS and
+   OPTS_SET, diagnostic context DC, with language mask LANG_MASK and
+   option handlers HANDLERS.  */
+
+static void
+maybe_default_option (struct gcc_options *opts,
+		      struct gcc_options *opts_set,
+		      const struct default_options *default_opt,
+		      int level, bool size, bool fast,
+		      unsigned int lang_mask,
+		      const struct cl_option_handlers *handlers,
+		      diagnostic_context *dc)
+{
+  const struct cl_option *option = &cl_options[default_opt->opt_index];
+  bool enabled;
+
+  if (size)
+    gcc_assert (level == 2);
+  if (fast)
+    gcc_assert (level == 3);
+
+  switch (default_opt->levels)
+    {
+    case OPT_LEVELS_ALL:
+      enabled = true;
+      break;
+
+    case OPT_LEVELS_0_ONLY:
+      enabled = (level == 0);
+      break;
+
+    case OPT_LEVELS_1_PLUS:
+      enabled = (level >= 1);
+      break;
+
+    case OPT_LEVELS_1_PLUS_SPEED_ONLY:
+      enabled = (level >= 1 && !size);
+      break;
+
+    case OPT_LEVELS_2_PLUS:
+      enabled = (level >= 2);
+      break;
+
+    case OPT_LEVELS_2_PLUS_SPEED_ONLY:
+      enabled = (level >= 2 && !size);
+      break;
+
+    case OPT_LEVELS_3_PLUS:
+      enabled = (level >= 3);
+      break;
+
+    case OPT_LEVELS_3_PLUS_AND_SIZE:
+      enabled = (level >= 3 || size);
+      break;
+
+    case OPT_LEVELS_SIZE:
+      enabled = size;
+      break;
+
+    case OPT_LEVELS_FAST:
+      enabled = fast;
+      break;
+
+    case OPT_LEVELS_NONE:
+    default:
+      gcc_unreachable ();
+    }
+
+  if (enabled)
+    handle_generated_option (opts, opts_set, default_opt->opt_index,
+			     default_opt->arg, default_opt->value,
+			     lang_mask, DK_UNSPECIFIED, handlers, dc);
+  else if (default_opt->arg == NULL
+	   && !(option->flags & CL_REJECT_NEGATIVE))
+    handle_generated_option (opts, opts_set, default_opt->opt_index,
+			     default_opt->arg, !default_opt->value,
+			     lang_mask, DK_UNSPECIFIED, handlers, dc);
+}
+
+/* As indicated by the optimization level LEVEL (-Os if SIZE is set,
+   -Ofast if FAST is set), apply the options in array DEFAULT_OPTS to
+   OPTS and OPTS_SET, diagnostic context DC, with language mask
+   LANG_MASK and option handlers HANDLERS.  */
+
+static void
+maybe_default_options (struct gcc_options *opts,
+		       struct gcc_options *opts_set,
+		       const struct default_options *default_opts,
+		       int level, bool size, bool fast,
+		       unsigned int lang_mask,
+		       const struct cl_option_handlers *handlers,
+		       diagnostic_context *dc)
+{
+  size_t i;
+
+  for (i = 0; default_opts[i].levels != OPT_LEVELS_NONE; i++)
+    maybe_default_option (opts, opts_set, &default_opts[i],
+			  level, size, fast, lang_mask, handlers, dc);
+}
+
+/* Table of options enabled by default at different levels.  */
+
+static const struct default_options default_options_table[] =
+  {
+    /* -O1 optimizations.  */
+    { OPT_LEVELS_1_PLUS, OPT_fdefer_pop, NULL, 1 },
+#ifdef DELAY_SLOTS
+    { OPT_LEVELS_1_PLUS, OPT_fdelayed_branch, NULL, 1 },
+#endif
+    { OPT_LEVELS_1_PLUS, OPT_fguess_branch_probability, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_fif_conversion, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_fif_conversion2, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_fmerge_constants, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_fsplit_wide_types, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_ftree_ccp, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_ftree_bit_ccp, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_ftree_dce, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_ftree_dominator_opts, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_ftree_dse, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_ftree_ter, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_ftree_sra, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_ftree_copyrename, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_ftree_sink, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_ftree_ch, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_fcombine_stack_adjustments, NULL, 1 },
+
+    /* -O2 optimizations.  */
+    { OPT_LEVELS_2_PLUS, OPT_finline_small_functions, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fpartial_inlining, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fthread_jumps, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fcrossjumping, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_foptimize_sibling_calls, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fcse_follow_jumps, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_frerun_cse_after_loop, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fcaller_saves, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fpeephole2, NULL, 1 },
+#ifdef INSN_SCHEDULING
+  /* Only run the pre-regalloc scheduling pass if optimizing for speed.  */
+    { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_fschedule_insns, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fschedule_insns2, NULL, 1 },
+#endif
+    { OPT_LEVELS_2_PLUS, OPT_fregmove, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fstrict_aliasing, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fstrict_overflow, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_freorder_blocks, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_freorder_functions, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_ftree_vrp, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_ftree_builtin_call_dce, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_falign_loops, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_falign_jumps, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_falign_labels, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_falign_functions, NULL, 1 },
+
+    /* -O3 optimizations.  */
+    { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
+    { OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
+    /* Inlining of functions reducing size is a good idea with -Os
+       regardless of them being declared inline.  */
+    { OPT_LEVELS_3_PLUS_AND_SIZE, OPT_finline_functions, NULL, 1 },
+    { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
+    { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
+    { OPT_LEVELS_3_PLUS, OPT_ftree_vectorize, NULL, 1 },
+    { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
+
+    /* -Ofast adds optimizations to -O3.  */
+    { OPT_LEVELS_FAST, OPT_ffast_math, NULL, 1 },
+
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 /* Default the options in OPTS and OPTS_SET based on the optimization
    settings in DECODED_OPTIONS and DECODED_OPTIONS_COUNT.  */
 static void
 default_options_optimization (struct gcc_options *opts,
 			      struct gcc_options *opts_set,
 			      struct cl_decoded_option *decoded_options,
-			      unsigned int decoded_options_count)
+			      unsigned int decoded_options_count,
+			      unsigned int lang_mask,
+			      const struct cl_option_handlers *handlers,
+			      diagnostic_context *dc)
 {
   unsigned int i;
-  int opt1;
   int opt2;
-  int opt3;
-  int opt1_max;
   int ofast = 0;
 
-  gcc_assert (opts == &global_options);
-  gcc_assert (opts_set = &global_options_set);
-
   /* Scan to see what optimization level has been specified.  That will
      determine the default value of many flags.  */
   for (i = 1; i < decoded_options_count; i++)
@@ -745,8 +927,8 @@  default_options_optimization (struct gcc
 	case OPT_O:
 	  if (*opt->arg == '\0')
 	    {
-	      optimize = 1;
-	      optimize_size = 0;
+	      opts->x_optimize = 1;
+	      opts->x_optimize_size = 0;
 	      ofast = 0;
 	    }
 	  else
@@ -757,27 +939,27 @@  default_options_optimization (struct gcc
 		       "-O");
 	      else
 		{
-		  optimize = optimize_val;
-		  if ((unsigned int) optimize > 255)
-		    optimize = 255;
-		  optimize_size = 0;
+		  opts->x_optimize = optimize_val;
+		  if ((unsigned int) opts->x_optimize > 255)
+		    opts->x_optimize = 255;
+		  opts->x_optimize_size = 0;
 		  ofast = 0;
 		}
 	    }
 	  break;
 
 	case OPT_Os:
-	  optimize_size = 1;
+	  opts->x_optimize_size = 1;
 
 	  /* Optimizing for size forces optimize to be 2.  */
-	  optimize = 2;
+	  opts->x_optimize = 2;
 	  ofast = 0;
 	  break;
 
 	case OPT_Ofast:
 	  /* -Ofast only adds flags to -O3.  */
-	  optimize_size = 0;
-	  optimize = 3;
+	  opts->x_optimize_size = 0;
+	  opts->x_optimize = 3;
 	  ofast = 1;
 	  break;
 
@@ -787,69 +969,12 @@  default_options_optimization (struct gcc
 	}
     }
 
-  /* -O1 optimizations.  */
-  opt1 = (optimize >= 1);
-  flag_defer_pop = opt1;
-#ifdef DELAY_SLOTS
-  flag_delayed_branch = opt1;
-#endif
-#ifdef CAN_DEBUG_WITHOUT_FP
-  flag_omit_frame_pointer = opt1;
-#endif
-  flag_guess_branch_prob = opt1;
-  flag_cprop_registers = opt1;
-  flag_forward_propagate = opt1;
-  flag_if_conversion = opt1;
-  flag_if_conversion2 = opt1;
-  flag_ipa_pure_const = opt1;
-  flag_ipa_reference = opt1;
-  flag_ipa_profile = opt1;
-  flag_merge_constants = opt1;
-  flag_split_wide_types = opt1;
-  flag_tree_ccp = opt1;
-  flag_tree_bit_ccp = opt1;
-  flag_tree_dce = opt1;
-  flag_tree_dom = opt1;
-  flag_tree_dse = opt1;
-  flag_tree_ter = opt1;
-  flag_tree_sra = opt1;
-  flag_tree_copyrename = opt1;
-  flag_tree_fre = opt1;
-  flag_tree_copy_prop = opt1;
-  flag_tree_sink = opt1;
-  flag_tree_ch = opt1;
-  flag_combine_stack_adjustments = opt1;
-
-  /* -O2 optimizations.  */
-  opt2 = (optimize >= 2);
-  flag_inline_small_functions = opt2;
-  flag_indirect_inlining = opt2;
-  flag_partial_inlining = opt2;
-  flag_thread_jumps = opt2;
-  flag_crossjumping = opt2;
-  flag_optimize_sibling_calls = opt2;
-  flag_cse_follow_jumps = opt2;
-  flag_gcse = opt2;
-  flag_expensive_optimizations = opt2;
-  flag_rerun_cse_after_loop = opt2;
-  flag_caller_saves = opt2;
-  flag_peephole2 = opt2;
-#ifdef INSN_SCHEDULING
-  /* Only run the pre-regalloc scheduling pass if optimizing for speed.  */
-  flag_schedule_insns = opt2 && ! optimize_size;
-  flag_schedule_insns_after_reload = opt2;
-#endif
-  flag_regmove = opt2;
-  flag_strict_aliasing = opt2;
-  flag_strict_overflow = opt2;
-  flag_reorder_blocks = opt2;
-  flag_reorder_functions = opt2;
-  flag_tree_vrp = opt2;
-  flag_tree_builtin_call_dce = opt2;
-  flag_tree_pre = opt2;
-  flag_tree_switch_conversion = opt2;
-  flag_ipa_cp = opt2;
-  flag_ipa_sra = opt2;
+  maybe_default_options (opts, opts_set, default_options_table,
+			 opts->x_optimize, opts->x_optimize_size,
+			 ofast, lang_mask, handlers, dc);
+
+  /* -O2 param settings.  */
+  opt2 = (opts->x_optimize >= 2);
 
   /* Track fields in field-sensitive alias analysis.  */
   maybe_set_param_value
@@ -863,58 +988,20 @@  default_options_optimization (struct gcc
      opt2 ? default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) : 1000,
      opts->x_param_values, opts_set->x_param_values);
 
-  /* -O3 optimizations.  */
-  opt3 = (optimize >= 3);
-  flag_tree_loop_distribute_patterns = opt3;
-  flag_predictive_commoning = opt3;
-  flag_inline_functions = opt3;
-  flag_unswitch_loops = opt3;
-  flag_gcse_after_reload = opt3;
-  flag_tree_vectorize = opt3;
-  flag_ipa_cp_clone = opt3;
-  if (flag_ipa_cp_clone)
-    flag_ipa_cp = 1;
-
-  /* Just -O1/-O0 optimizations.  */
-  opt1_max = (optimize <= 1);
-  align_loops = opt1_max;
-  align_jumps = opt1_max;
-  align_labels = opt1_max;
-  align_functions = opt1_max;
-
-  if (optimize_size)
-    {
-      /* Inlining of functions reducing size is a good idea regardless of them
-	 being declared inline.  */
-      flag_inline_functions = 1;
-
-      /* Basic optimization options.  */
-      optimize_size = 1;
-      if (optimize > 2)
-	optimize = 2;
-
-      /* We want to crossjump as much as possible.  */
-      maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, 1,
-			     opts->x_param_values, opts_set->x_param_values);
-    }
+  if (opts->x_optimize_size)
+    /* We want to crossjump as much as possible.  */
+    maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, 1,
+			   opts->x_param_values, opts_set->x_param_values);
   else
     maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS,
 			   default_param_value (PARAM_MIN_CROSSJUMP_INSNS),
 			   opts->x_param_values, opts_set->x_param_values);
 
-  /* -Ofast adds optimizations to -O3.  */
-  if (ofast)
-    {
-      /* Which is -ffast-math for now.  */
-      set_fast_math_flags (1);
-      /* Allow targets to enable extra options with -Ofast
-	 before general options processing so disabling them
-	 again afterwards works.  */
-      targetm.handle_ofast ();
-    }
-
   /* Allow default optimizations to be specified on a per-machine basis.  */
-  targetm.target_option.optimization (optimize, optimize_size);
+  maybe_default_options (opts, opts_set,
+			 targetm.target_option.optimization_table,
+			 opts->x_optimize, opts->x_optimize_size,
+			 ofast, lang_mask, handlers, dc);
 }
 
 static void finish_options (struct gcc_options *, struct gcc_options *);
@@ -949,7 +1036,8 @@  decode_options (struct gcc_options *opts
 			   global_dc);
 
   default_options_optimization (opts, opts_set,
-				decoded_options, decoded_options_count);
+				decoded_options, decoded_options_count,
+				lang_mask, &handlers, global_dc);
 
 #ifdef ENABLE_LTO
   /* Clear any options currently held for LTO.  */
Index: gcc/common.opt
===================================================================
--- gcc/common.opt	(revision 165714)
+++ gcc/common.opt	(working copy)
@@ -589,7 +589,7 @@  falign-labels=
 Common RejectNegative Joined UInteger
 
 falign-loops
-Common Report Var(align_loops) Optimization UInteger
+Common Report Var(align_loops,0) Optimization UInteger
 Align the start of loops
 
 falign-loops=
@@ -1318,7 +1318,7 @@  Common Report Var(flag_reorder_functions
 Reorder functions to improve code placement
 
 frerun-cse-after-loop
-Common Report Var(flag_rerun_cse_after_loop) Init(2) Optimization
+Common Report Var(flag_rerun_cse_after_loop) Optimization
 Add a common subexpression elimination pass after loop optimizations
 
 frerun-loop-opt
@@ -1681,7 +1681,7 @@  Common Report Var(flag_tree_sra) Optimiz
 Perform scalar replacement of aggregates
 
 ftree-ter
-Common Report Var(flag_tree_ter) Init(1) Optimization
+Common Report Var(flag_tree_ter) Optimization
 Replace temporary expressions in the SSA->normal pass
 
 ftree-lrs
Index: gcc/system.h
===================================================================
--- gcc/system.h	(revision 165714)
+++ gcc/system.h	(working copy)
@@ -719,7 +719,8 @@  extern void fancy_abort (const char *, i
 	OPTIMIZATION_OPTIONS CLASS_LIKELY_SPILLED_P			\
 	USING_SJLJ_EXCEPTIONS TARGET_UNWIND_INFO			\
 	LABEL_ALIGN_MAX_SKIP LOOP_ALIGN_MAX_SKIP			\
-	LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP JUMP_ALIGN_MAX_SKIP
+	LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP JUMP_ALIGN_MAX_SKIP \
+	CAN_DEBUG_WITHOUT_FP
 
 /* Other obsolete target macros, or macros that used to be in target
    headers and were not used, and may be obsolete or may never have
@@ -784,7 +785,8 @@  extern void fancy_abort (const char *, i
 	LANG_HOOKS_MAYBE_BUILD_CLEANUP LANG_HOOKS_UPDATE_DECL_AFTER_SAVING \
 	LANG_HOOKS_POPLEVEL LANG_HOOKS_TRUTHVALUE_CONVERSION \
 	TARGET_PROMOTE_FUNCTION_ARGS TARGET_PROMOTE_FUNCTION_RETURN \
-	LANG_HOOKS_MISSING_ARGUMENT LANG_HOOKS_HASH_TYPES
+	LANG_HOOKS_MISSING_ARGUMENT LANG_HOOKS_HASH_TYPES \
+	TARGET_HANDLE_OFAST TARGET_OPTION_OPTIMIZATION
 
 /* Hooks into libgcc2.  */
  #pragma GCC poison LIBGCC2_DOUBLE_TYPE_SIZE
Index: gcc/config/alpha/alpha.c
===================================================================
--- gcc/config/alpha/alpha.c	(revision 165714)
+++ gcc/config/alpha/alpha.c	(working copy)
@@ -208,6 +208,13 @@  static void unicosmk_gen_dsib (unsigned 
 static void unicosmk_output_ssib (FILE *, const char *);
 static int unicosmk_need_dex (rtx);
 
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options alpha_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 /* Implement TARGET_HANDLE_OPTION.  */
 
 static bool
@@ -11140,6 +11147,9 @@  alpha_init_libfuncs (void)
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE alpha_option_override
 
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE alpha_option_optimization_table
+
 #ifdef TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
 #undef TARGET_MANGLE_TYPE
 #define TARGET_MANGLE_TYPE alpha_mangle_type
Index: gcc/config/alpha/alpha.h
===================================================================
--- gcc/config/alpha/alpha.h	(revision 165714)
+++ gcc/config/alpha/alpha.h	(working copy)
@@ -1,6 +1,6 @@ 
 /* Definitions of target machine for GNU compiler, for DEC Alpha.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009
+   2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
 
@@ -223,10 +223,6 @@  extern enum alpha_fp_trap_mode alpha_fpt
     for (i = 32; i < 63; i++)			\
       fixed_regs[i] = call_used_regs[i] = 1;	\
 }
-
-
-/* Show we can debug even without a frame pointer.  */
-#define CAN_DEBUG_WITHOUT_FP
 
 /* target machine storage layout */
 
Index: gcc/config/frv/frv.h
===================================================================
--- gcc/config/frv/frv.h	(revision 165714)
+++ gcc/config/frv/frv.h	(working copy)
@@ -328,13 +328,6 @@ 
         #endif  */
 #define TARGET_VERSION fprintf (stderr, _(" (frv)"))
 
-/* Define this macro if debugging can be performed even without a frame
-   pointer.  If this macro is defined, GCC will turn on the
-   `-fomit-frame-pointer' option whenever `-O' is specified.  */
-/* Frv needs a specific frame layout that includes the frame pointer.  */
-
-#define CAN_DEBUG_WITHOUT_FP
-
 #define LABEL_ALIGN_AFTER_BARRIER(LABEL) (TARGET_ALIGN_LABELS ? 3 : 0)
 
 /* Small Data Area Support.  */
Index: gcc/config/frv/frv.c
===================================================================
--- gcc/config/frv/frv.c	(revision 165714)
+++ gcc/config/frv/frv.c	(working copy)
@@ -397,6 +397,13 @@  static bool frv_frame_pointer_required		
 static bool frv_can_eliminate			(const int, const int);
 static void frv_trampoline_init			(rtx, tree, rtx);
 static bool frv_class_likely_spilled_p 		(reg_class_t);
+
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options frv_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 /* Allow us to easily change the default for -malloc-cc.  */
 #ifndef DEFAULT_NO_ALLOC_CC
@@ -431,6 +438,8 @@  static bool frv_class_likely_spilled_p 	
 #define TARGET_HANDLE_OPTION frv_handle_option
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE frv_option_override
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE frv_option_optimization_table
 #undef TARGET_INIT_BUILTINS
 #define TARGET_INIT_BUILTINS frv_init_builtins
 #undef TARGET_EXPAND_BUILTIN
Index: gcc/config/s390/s390.c
===================================================================
--- gcc/config/s390/s390.c	(revision 165714)
+++ gcc/config/s390/s390.c	(working copy)
@@ -1490,23 +1490,20 @@  s390_init_machine_status (void)
 }
 
 /* Change optimizations to be performed, depending on the
-   optimization level.
+   optimization level.  */
 
-   LEVEL is the optimization level specified; 2 if `-O2' is
-   specified, 1 if `-O' is specified, and 0 if neither is specified.
+static const struct default_options s390_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
 
-   SIZE is nonzero if `-Os' is specified and zero otherwise.  */
+    /* ??? There are apparently still problems with -fcaller-saves.  */
+    { OPT_LEVELS_ALL, OPT_fcaller_saves, NULL, 0 },
 
-static void
-s390_option_optimization (int level ATTRIBUTE_UNUSED, int size)
-{
-  /* ??? There are apparently still problems with -fcaller-saves.  */
-  flag_caller_saves = 0;
+    /* Use MVCLE instructions to decrease code size if requested.  */
+    { OPT_LEVELS_SIZE, OPT_mmvcle, NULL, 1 },
 
-  /* Use MVCLE instructions to decrease code size if requested.  */
-  if (size != 0)
-    target_flags |= MASK_MVCLE;
-}
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 /* Implement TARGET_OPTION_INIT_STRUCT.  */
 
@@ -1730,7 +1727,7 @@  s390_option_override (void)
 			 global_options.x_param_values,
 			 global_options_set.x_param_values);
 
-  /* This cannot reside in s390_option_optimization since HAVE_prefetch
+  /* This cannot reside in s390_option_optimization_table since HAVE_prefetch
      requires the arch flags to be evaluated already.  Since prefetching
      is beneficial on s390, we enable it if available.  */
   if (flag_prefetch_loop_arrays < 0 && HAVE_prefetch && optimize >= 3)
@@ -10510,8 +10507,8 @@  s390_loop_unroll_adjust (unsigned nunrol
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE s390_option_override
 
-#undef TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION s390_option_optimization
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE s390_option_optimization_table
 
 #undef TARGET_OPTION_INIT_STRUCT
 #define TARGET_OPTION_INIT_STRUCT s390_option_init_struct
Index: gcc/config/s390/s390.h
===================================================================
--- gcc/config/s390/s390.h	(revision 165714)
+++ gcc/config/s390/s390.h	(working copy)
@@ -158,9 +158,6 @@  extern int s390_arch_flags;
 #define TARGET_VERSION fprintf (stderr, " (S/390)");
 #endif
 
-/* Frame pointer is not used for debugging.  */
-#define CAN_DEBUG_WITHOUT_FP
-
 /* Constants needed to control the TEST DATA CLASS (TDC) instruction.  */
 #define S390_TDC_POSITIVE_ZERO                     (1 << 11)
 #define S390_TDC_NEGATIVE_ZERO                     (1 << 10)
Index: gcc/config/sparc/sparc.c
===================================================================
--- gcc/config/sparc/sparc.c	(revision 165714)
+++ gcc/config/sparc/sparc.c	(working copy)
@@ -477,6 +477,13 @@  enum processor_type sparc_cpu;
 /* Whetheran FPU option was specified.  */
 static bool fpu_option_set = false;
 
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options sparc_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 /* Initialize the GCC target structure.  */
 
 /* The default is to use .half rather than .short for aligned HI objects.  */
@@ -612,6 +619,8 @@  static bool fpu_option_set = false;
 #define TARGET_HANDLE_OPTION sparc_handle_option
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE sparc_option_override
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE sparc_option_optimization_table
 
 #if TARGET_GNU_TLS && defined(HAVE_AS_SPARC_UA_PCREL)
 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
Index: gcc/config/sparc/sparc.h
===================================================================
--- gcc/config/sparc/sparc.h	(revision 165714)
+++ gcc/config/sparc/sparc.h	(working copy)
@@ -496,9 +496,6 @@  extern enum cmodel sparc_cmodel;
 /* ??? This should be 32 bits for v9 but what can we do?  */
 #define WCHAR_TYPE "short unsigned int"
 #define WCHAR_TYPE_SIZE 16
-
-/* Show we can debug even without a frame pointer.  */
-#define CAN_DEBUG_WITHOUT_FP
 
 /* Mask of all CPU selection flags.  */
 #define MASK_ISA \
Index: gcc/config/mep/mep.c
===================================================================
--- gcc/config/mep/mep.c	(revision 165714)
+++ gcc/config/mep/mep.c	(working copy)
@@ -295,16 +295,20 @@  mep_conditional_register_usage (void)
     global_regs[i] = 1;
 }
 
-static void
-mep_option_optimization (int level ATTRIBUTE_UNUSED, int size ATTRIBUTE_UNUSED)
-{
-  /* The first scheduling pass often increases register pressure and tends
-     to result in more spill code.  Only run it when specifically asked.  */
-  flag_schedule_insns = 0;
 
-  /* Using $fp doesn't gain us much, even when debugging is important.  */
-  flag_omit_frame_pointer = 1;
-}
+static const struct default_options mep_option_optimization_table[] =
+  {
+    /* The first scheduling pass often increases register pressure and
+       tends to result in more spill code.  Only run it when
+       specifically asked.  */
+    { OPT_LEVELS_ALL, OPT_fschedule_insns, NULL, 0 },
+
+    /* Using $fp doesn't gain us much, even when debugging is
+       important.  */
+    { OPT_LEVELS_ALL, OPT_fomit_frame_pointer, NULL, 1 },
+
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 static void
 mep_option_override (void)
@@ -7426,8 +7430,8 @@  mep_asm_init_sections (void)
 #define TARGET_HANDLE_OPTION            mep_handle_option
 #undef  TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE		mep_option_override
-#undef  TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION	mep_option_optimization
+#undef  TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE	mep_option_optimization_table
 #undef  TARGET_DEFAULT_TARGET_FLAGS
 #define TARGET_DEFAULT_TARGET_FLAGS	TARGET_DEFAULT
 #undef  TARGET_ALLOCATE_INITIAL_VALUE
Index: gcc/config/mep/mep.h
===================================================================
--- gcc/config/mep/mep.h	(revision 165714)
+++ gcc/config/mep/mep.h	(working copy)
@@ -159,8 +159,6 @@  crtbegin.o%s"
 #define COPROC_SELECTION_TABLE \
 {"default", ISA_EXT1}
 /* end-coproc-selection-table */
-
-#define CAN_DEBUG_WITHOUT_FP
 
 
 #define BITS_BIG_ENDIAN 0
Index: gcc/config/m32r/m32r.c
===================================================================
--- gcc/config/m32r/m32r.c	(revision 165714)
+++ gcc/config/m32r/m32r.c	(working copy)
@@ -64,7 +64,6 @@  enum m32r_sdata m32r_sdata = M32R_SDATA_
 /* Forward declaration.  */
 static bool  m32r_handle_option (size_t, const char *, int);
 static void  m32r_option_override (void);
-static void  m32r_option_optimization (int, int);
 static void  init_reg_tables (void);
 static void  block_move_call (rtx, rtx, rtx);
 static int   m32r_is_insn (rtx);
@@ -113,6 +112,13 @@  static const struct attribute_spec m32r_
   { "model",     1, 1, true,  false, false, m32r_handle_model_attribute },
   { NULL,        0, 0, false, false, false, NULL }
 };
+
+static const struct default_options m32r_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_fregmove, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 /* Initialize the GCC target structure.  */
 #undef  TARGET_ATTRIBUTE_TABLE
@@ -154,8 +160,8 @@  static const struct attribute_spec m32r_
 #define TARGET_HANDLE_OPTION m32r_handle_option
 #undef  TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE m32r_option_override
-#undef  TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION m32r_option_optimization
+#undef  TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE m32r_option_optimization_table
 
 #undef  TARGET_ENCODE_SECTION_INFO
 #define TARGET_ENCODE_SECTION_INFO m32r_encode_section_info
@@ -278,18 +284,6 @@  m32r_option_override (void)
   SUBTARGET_OVERRIDE_OPTIONS;
 }
 
-static void
-m32r_option_optimization (int level, int size)
-{
-  if (level == 1)
-    flag_regmove = 1;
-
-  if (size)
-    flag_omit_frame_pointer = 1;
-
-  SUBTARGET_OPTIMIZATION_OPTIONS;
-}
-
 /* Vectors to keep interesting information about registers where it can easily
    be got.  We use to use the actual mode value as the bit number, but there
    is (or may be) more than 32 modes now.  Instead we use two tables: one
Index: gcc/config/m32r/m32r.h
===================================================================
--- gcc/config/m32r/m32r.h	(revision 165714)
+++ gcc/config/m32r/m32r.h	(working copy)
@@ -305,15 +305,6 @@  extern enum m32r_sdata m32r_sdata;
 #ifndef SUBTARGET_OVERRIDE_OPTIONS
 #define SUBTARGET_OVERRIDE_OPTIONS
 #endif
-
-#ifndef SUBTARGET_OPTIMIZATION_OPTIONS
-#define SUBTARGET_OPTIMIZATION_OPTIONS
-#endif
-
-/* Define this macro if debugging can be performed even without a
-   frame pointer.  If this macro is defined, GCC will turn on the
-   `-fomit-frame-pointer' option whenever `-O' is specified.  */
-#define CAN_DEBUG_WITHOUT_FP
 
 /* Target machine storage layout.  */
 
Index: gcc/config/i386/sol2-10.h
===================================================================
--- gcc/config/i386/sol2-10.h	(revision 165714)
+++ gcc/config/i386/sol2-10.h	(working copy)
@@ -91,13 +91,8 @@  along with GCC; see the file COPYING3.  
 #define TARGET_SUBTARGET_DEFAULT \
 	(MASK_80387 | MASK_IEEE_FP | MASK_FLOAT_RETURNS)
 
-#define SUBTARGET_OPTIMIZATION_OPTIONS			\
-  do							\
-    {							\
-      if (optimize >= 1)				\
-	target_flags |= MASK_OMIT_LEAF_FRAME_POINTER;	\
-    }							\
-  while (0)
+#define SUBTARGET_OPTIMIZATION_OPTIONS				\
+  { OPT_LEVELS_1_PLUS, OPT_momit_leaf_frame_pointer, NULL, 1 }
 
 #define MULTILIB_DEFAULTS { "m32" }
 
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c	(revision 165714)
+++ gcc/config/i386/i386.c	(working copy)
@@ -4529,20 +4529,19 @@  x86_output_aligned_bss (FILE *file, tree
   ASM_OUTPUT_SKIP (file, size ? size : 1);
 }
 
-static void
-ix86_option_optimization (int level, int size ATTRIBUTE_UNUSED)
-{
-  /* For -O2 and beyond, turn off -fschedule-insns by default.  It tends to
-     make the problem with not enough registers even worse.  */
+static const struct default_options ix86_option_optimization_table[] =
+  {
+    /* Turn off -fschedule-insns by default.  It tends to make the
+       problem with not enough registers even worse.  */
 #ifdef INSN_SCHEDULING
-  if (level > 1)
-    flag_schedule_insns = 0;
+    { OPT_LEVELS_ALL, OPT_fschedule_insns, NULL, 0 },
 #endif
 
 #ifdef SUBTARGET_OPTIMIZATION_OPTIONS
-  SUBTARGET_OPTIMIZATION_OPTIONS;
+    SUBTARGET_OPTIMIZATION_OPTIONS,
 #endif
-}
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 /* Implement TARGET_OPTION_INIT_STRUCT.  */
 
@@ -33237,8 +33236,8 @@  ix86_autovectorize_vector_sizes (void)
 
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE ix86_option_override
-#undef TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION ix86_option_optimization
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE ix86_option_optimization_table
 #undef TARGET_OPTION_INIT_STRUCT
 #define TARGET_OPTION_INIT_STRUCT ix86_option_init_struct
 
Index: gcc/config/rx/rx.h
===================================================================
--- gcc/config/rx/rx.h	(revision 165714)
+++ gcc/config/rx/rx.h	(working copy)
@@ -609,8 +609,6 @@  extern int rx_float_compare_mode;
 /* Like REG_P except that this macro is true for SET expressions.  */
 #define SET_P(rtl)    (GET_CODE (rtl) == SET)
 
-#define CAN_DEBUG_WITHOUT_FP 1
-
 /* The AS100 assembler does not support .leb128 and .uleb128, but
    the compiler-build-time configure tests will have enabled their
    use because GAS supports them.  So default to generating STABS
Index: gcc/config/rx/rx.c
===================================================================
--- gcc/config/rx/rx.c	(revision 165714)
+++ gcc/config/rx/rx.c	(working copy)
@@ -2253,6 +2253,13 @@  rx_option_override (void)
   rx_override_options_after_change ();
 }
 
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options rx_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 
 static bool
 rx_allocate_stack_slots_for_args (void)
@@ -2850,6 +2857,9 @@  rx_memory_move_cost (enum machine_mode m
 #undef  TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE			rx_option_override
 
+#undef  TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE	rx_option_optimization_table
+
 #undef  TARGET_PROMOTE_FUNCTION_MODE
 #define TARGET_PROMOTE_FUNCTION_MODE		rx_promote_function_mode
 
Index: gcc/config/sh/sh.c
===================================================================
--- gcc/config/sh/sh.c	(revision 165714)
+++ gcc/config/sh/sh.c	(working copy)
@@ -183,7 +183,6 @@  static int noncall_uses_reg (rtx, rtx, r
 static rtx gen_block_redirect (rtx, int, 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);
@@ -323,6 +322,23 @@  static const struct attribute_spec sh_at
 #endif
   { NULL,                0, 0, false, false, false, NULL }
 };
+
+/* Set default optimization options.  */
+static const struct default_options sh_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_1_PLUS_SPEED_ONLY, OPT_mdiv_, "inv:minlat", 1 },
+    { OPT_LEVELS_SIZE, OPT_mdiv_, SH_DIV_STR_FOR_SIZE, 1 },
+    { OPT_LEVELS_0_ONLY, OPT_mdiv_, "", 1 },
+    { OPT_LEVELS_SIZE, OPT_mcbranchdi, NULL, 0 },
+    /* We can't meaningfully test TARGET_SHMEDIA here, because -m
+       options haven't been parsed yet, hence we'd read only the
+       default.  sh_target_reg_class will return NO_REGS if this is
+       not SHMEDIA, so it's OK to always set
+       flag_branch_target_load_optimize.  */
+    { OPT_LEVELS_2_PLUS, OPT_fbranch_target_load_optimize, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 /* Initialize the GCC target structure.  */
 #undef TARGET_ATTRIBUTE_TABLE
@@ -342,8 +358,8 @@  static const struct attribute_spec sh_at
 
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE sh_option_override
-#undef TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION sh_option_optimization
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE sh_option_optimization_table
 #undef TARGET_OPTION_INIT_STRUCT
 #define TARGET_OPTION_INIT_STRUCT sh_option_init_struct
 #undef TARGET_OPTION_DEFAULT_PARAMS
@@ -702,34 +718,6 @@  sh_handle_option (size_t code, const cha
     }
 }
 
-/* Set default optimization options.  */
-static void
-sh_option_optimization (int level, int size)
-{
-  if (level)
-    {
-      if (!size)
-	sh_div_str = "inv:minlat";
-    }
-  if (size)
-    {
-      target_flags |= MASK_SMALLCODE;
-      sh_div_str = SH_DIV_STR_FOR_SIZE ;
-    }
-  else
-    TARGET_CBRANCHDI4 = 1;
-  /* We can't meaningfully test TARGET_SHMEDIA here, because -m options
-     haven't been parsed yet, hence we'd read only the default.
-     sh_target_reg_class will return NO_REGS if this is not SHMEDIA, so
-     it's OK to always set flag_branch_target_load_optimize.  */
-  if (level > 1)
-    {
-      flag_branch_target_load_optimize = 1;
-      if (!size)
-	target_flags |= MASK_SAVE_ALL_TARGET_REGS;
-    }
-}
-
 /* Implement TARGET_OPTION_INIT_STRUCT.  */
 static void
 sh_option_init_struct (struct gcc_options *opts)
@@ -756,6 +744,8 @@  sh_option_override (void)
   int regno;
 
   SUBTARGET_OVERRIDE_OPTIONS;
+  if (optimize > 1 && !optimize_size)
+    target_flags |= MASK_SAVE_ALL_TARGET_REGS;
   if (flag_finite_math_only == 2)
     flag_finite_math_only
       = !flag_signaling_nans && TARGET_SH2E && ! TARGET_IEEE;
@@ -991,7 +981,7 @@  sh_option_override (void)
      SH2 .. SH5 : align to cache line start.  */
   if (align_functions == 0)
     align_functions
-      = TARGET_SMALLCODE ? FUNCTION_BOUNDARY/8 : (1 << CACHE_LOG);
+      = optimize_size ? FUNCTION_BOUNDARY/8 : (1 << CACHE_LOG);
   /* The linker relaxation code breaks when a function contains
      alignments that are larger than that at the start of a
      compilation unit.  */
@@ -1555,7 +1545,7 @@  expand_block_move (rtx *operands)
 	  emit_insn (gen_block_move_real_i4 (func_addr_rtx));
 	  return 1;
 	}
-      else if (! TARGET_SMALLCODE)
+      else if (! optimize_size)
 	{
 	  const char *entry_name;
 	  rtx func_addr_rtx = gen_reg_rtx (Pmode);
@@ -1594,7 +1584,7 @@  expand_block_move (rtx *operands)
 
   /* This is the same number of bytes as a memcpy call, but to a different
      less common function name, so this will occasionally use more space.  */
-  if (! TARGET_SMALLCODE)
+  if (! optimize_size)
     {
       rtx func_addr_rtx = gen_reg_rtx (Pmode);
       int final_switch, while_loop;
@@ -2975,21 +2965,21 @@  multcosts (rtx x ATTRIBUTE_UNUSED)
        Using a multiply first and splitting it later if it's a loss
        doesn't work because of different sign / zero extension semantics
        of multiplies vs. shifts.  */
-    return TARGET_SMALLCODE ? 2 : 3;
+    return optimize_size ? 2 : 3;
 
   if (TARGET_SH2)
     {
       /* We have a mul insn, so we can never take more than the mul and the
 	 read of the mac reg, but count more because of the latency and extra
 	 reg usage.  */
-      if (TARGET_SMALLCODE)
+      if (optimize_size)
 	return 2;
       return 3;
     }
 
   /* If we're aiming at small code, then just count the number of
      insns in a multiply call sequence.  */
-  if (TARGET_SMALLCODE)
+  if (optimize_size)
     return 5;
 
   /* Otherwise count all the insns in the routine we'd be calling too.  */
@@ -4660,7 +4650,7 @@  find_barrier (int num_mova, rtx mova, rt
       /* For the SH1, we generate alignments even after jumps-around-jumps.  */
       else if (JUMP_P (from)
 	       && ! TARGET_SH2
-	       && ! TARGET_SMALLCODE)
+	       && ! optimize_size)
 	new_align = 4;
 
       /* There is a possibility that a bf is transformed into a bf/s by the
@@ -5258,13 +5248,13 @@  barrier_align (rtx barrier_or_label)
       pat = PATTERN (prev);
       /* If this is a very small table, we want to keep the alignment after
 	 the table to the minimum for proper code alignment.  */
-      return ((TARGET_SMALLCODE
+      return ((optimize_size
 	       || ((unsigned) XVECLEN (pat, 1) * GET_MODE_SIZE (GET_MODE (pat))
 		   <= (unsigned) 1 << (CACHE_LOG - 2)))
 	      ? 1 << TARGET_SHMEDIA : align_jumps_log);
     }
 
-  if (TARGET_SMALLCODE)
+  if (optimize_size)
     return 0;
 
   if (! TARGET_SH2 || ! optimize)
Index: gcc/config/sh/sh.h
===================================================================
--- gcc/config/sh/sh.h	(revision 165714)
+++ gcc/config/sh/sh.h	(working copy)
@@ -98,8 +98,6 @@  do { \
 		  ? "__LITTLE_ENDIAN__" : "__BIG_ENDIAN__"); \
 } while (0)
 
-#define CAN_DEBUG_WITHOUT_FP 
-
 /* Value should be nonzero if functions must have frame pointers.
    Zero means the frame pointer need not be set up (and parms may be accessed
    via the stack pointer) in functions that seem suitable.  */
@@ -623,7 +621,7 @@  extern enum sh_divide_strategy_e sh_div_
   barrier_align (LABEL_AFTER_BARRIER)
 
 #define LOOP_ALIGN(A_LABEL) \
-  ((! optimize || TARGET_HARD_SH4 || TARGET_SMALLCODE) \
+  ((! optimize || TARGET_HARD_SH4 || optimize_size) \
    ? 0 : sh_loop_align (A_LABEL))
 
 #define LABEL_ALIGN(A_LABEL) \
@@ -1781,7 +1779,7 @@  struct sh_args {
 
 /* Alignment required for a trampoline in bits .  */
 #define TRAMPOLINE_ALIGNMENT \
-  ((CACHE_LOG < 3 || (TARGET_SMALLCODE && ! TARGET_HARVARD)) ? 32 \
+  ((CACHE_LOG < 3 || (optimize_size && ! TARGET_HARVARD)) ? 32 \
    : TARGET_SHMEDIA ? 256 : 64)
 
 /* A C expression whose value is RTL representing the value of the return
@@ -1813,11 +1811,11 @@  struct sh_args {
 
 #define MOVE_BY_PIECES_P(SIZE, ALIGN) \
   (move_by_pieces_ninsns (SIZE, ALIGN, MOVE_MAX_PIECES + 1) \
-   < (TARGET_SMALLCODE ? 2 : ((ALIGN >= 32) ? 16 : 2)))
+   < (optimize_size ? 2 : ((ALIGN >= 32) ? 16 : 2)))
 
 #define STORE_BY_PIECES_P(SIZE, ALIGN) \
   (move_by_pieces_ninsns (SIZE, ALIGN, STORE_MAX_PIECES + 1) \
-   < (TARGET_SMALLCODE ? 2 : ((ALIGN >= 32) ? 16 : 2)))
+   < (optimize_size ? 2 : ((ALIGN >= 32) ? 16 : 2)))
 
 #define SET_BY_PIECES_P(SIZE, ALIGN) STORE_BY_PIECES_P(SIZE, ALIGN)
 
@@ -2597,7 +2595,7 @@  extern int current_function_interrupt;
 #define ACCUMULATE_OUTGOING_ARGS TARGET_ACCUMULATE_OUTGOING_ARGS
 
 #define SH_DYNAMIC_SHIFT_COST \
-  (TARGET_HARD_SH4 ? 1 : TARGET_SH3 ? (TARGET_SMALLCODE ? 1 : 2) : 20)
+  (TARGET_HARD_SH4 ? 1 : TARGET_SH3 ? (optimize_size ? 1 : 2) : 20)
 
 
 #define NUM_MODES_FOR_MODE_SWITCHING { FP_MODE_NONE }
Index: gcc/config/sh/sh.opt
===================================================================
--- gcc/config/sh/sh.opt	(revision 165714)
+++ gcc/config/sh/sh.opt	(working copy)
@@ -320,7 +320,7 @@  Target Mask(HITACHI) MaskExists
 Follow Renesas (formerly Hitachi) / SuperH calling conventions
 
 mspace
-Target Report RejectNegative Mask(SMALLCODE)
+Target RejectNegative Alias(Os)
 Deprecated.  Use -Os instead
 
 multcost=
Index: gcc/config/pdp11/pdp11.c
===================================================================
--- gcc/config/pdp11/pdp11.c	(revision 165714)
+++ gcc/config/pdp11/pdp11.c	(working copy)
@@ -145,7 +145,6 @@  decode_pdp11_d (const struct real_format
 /* rtx cc0_reg_rtx; - no longer needed? */
 
 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 *);
@@ -162,6 +161,14 @@  static rtx pdp11_function_arg (CUMULATIV
 			       const_tree, bool);
 static void pdp11_function_arg_advance (CUMULATIVE_ARGS *,
 					enum machine_mode, const_tree, bool);
+
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+
+static const struct default_options pdp11_option_optimization_table[] =
+  {
+    { OPT_LEVELS_3_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_BYTE_OP
@@ -188,8 +195,8 @@  static void pdp11_function_arg_advance (
   (MASK_FPU | MASK_45 | MASK_ABSHI_BUILTIN | TARGET_UNIX_ASM_DEFAULT)
 #undef TARGET_HANDLE_OPTION
 #define TARGET_HANDLE_OPTION pdp11_handle_option
-#undef TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION pdp11_option_optimization
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE pdp11_option_optimization_table
 #undef TARGET_OPTION_INIT_STRUCT
 #define TARGET_OPTION_INIT_STRUCT pdp11_option_init_struct
 
@@ -233,18 +240,6 @@  pdp11_handle_option (size_t code, const 
     }
 }
 
-/* Implement TARGET_OPTION_OPTIMIZATION.  */
-
-static void
-pdp11_option_optimization (int level, int size ATTRIBUTE_UNUSED)
-{
-  if (level >= 3)
-    {
-      flag_omit_frame_pointer = 1;
-      /* flag_unroll_loops = 1; */
-    }
-}
-
 /* Implement TARGET_OPTION_INIT_STRUCT.  */
 
 static void
Index: gcc/config/microblaze/microblaze.c
===================================================================
--- gcc/config/microblaze/microblaze.c	(revision 165714)
+++ gcc/config/microblaze/microblaze.c	(working copy)
@@ -1423,6 +1423,13 @@  microblaze_option_override (void)
     }
 }
 
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options microblaze_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 /* Return true if FUNC is an interrupt function as specified
    by the "interrupt_handler" attribute.  */
 
@@ -3028,6 +3035,9 @@  microblaze_adjust_cost (rtx insn ATTRIBU
 #undef  TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE		microblaze_option_override 
 
+#undef  TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE microblaze_option_optimization_table
+
 #undef TARGET_EXCEPT_UNWIND_INFO
 #define TARGET_EXCEPT_UNWIND_INFO  sjlj_except_unwind_info
 
Index: gcc/config/microblaze/microblaze.h
===================================================================
--- gcc/config/microblaze/microblaze.h	(revision 165714)
+++ gcc/config/microblaze/microblaze.h	(working copy)
@@ -61,9 +61,6 @@  extern enum pipeline_type microblaze_pip
 #define SWITCH_TAKES_ARG(CHAR)						\
   (DEFAULT_SWITCH_TAKES_ARG (CHAR) || (CHAR) == 'G')
 
-/*  We can debug without having a frame pointer.  */
-#define CAN_DEBUG_WITHOUT_FP
-
 #define DRIVER_SELF_SPECS    				\
 	"%{mxl-soft-mul:%<mno-xl-soft-mul}", 		\
 	"%{mno-xl-barrel-shift:%<mxl-barrel-shift}", 	\
Index: gcc/config/avr/avr.c
===================================================================
--- gcc/config/avr/avr.c	(revision 165714)
+++ gcc/config/avr/avr.c	(working copy)
@@ -133,6 +133,13 @@  static const struct attribute_spec avr_a
   { "OS_main",   0, 0, false, true,  true,   avr_handle_fntype_attribute },
   { NULL,        0, 0, false, false, false, NULL }
 };
+
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options avr_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_ALIGNED_HI_OP
@@ -208,6 +215,9 @@  static const struct attribute_spec avr_a
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE avr_option_override
 
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE avr_option_optimization_table
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 static void
Index: gcc/config/avr/avr.h
===================================================================
--- gcc/config/avr/avr.h	(revision 165714)
+++ gcc/config/avr/avr.h	(working copy)
@@ -124,8 +124,6 @@  extern GTY(()) section *progmem_section;
 
 #define TARGET_VERSION fprintf (stderr, " (GNU assembler syntax)");
 
-#define CAN_DEBUG_WITHOUT_FP
-
 #define BITS_BIG_ENDIAN 0
 #define BYTES_BIG_ENDIAN 0
 #define WORDS_BIG_ENDIAN 0
Index: gcc/config/crx/crx.h
===================================================================
--- gcc/config/crx/crx.h	(revision 165714)
+++ gcc/config/crx/crx.h	(working copy)
@@ -54,9 +54,6 @@  do {								\
 
 #define TARGET_VERSION fputs (" (CRX/ELF)", stderr);
 
-/* Show we can debug even without a frame pointer.  */
-#define CAN_DEBUG_WITHOUT_FP
-
 /*****************************************************************************/
 /* STORAGE LAYOUT							     */
 /*****************************************************************************/
Index: gcc/config/crx/crx.c
===================================================================
--- gcc/config/crx/crx.c	(revision 165714)
+++ gcc/config/crx/crx.c	(working copy)
@@ -130,7 +130,6 @@  static bool crx_return_in_memory (const_
 static int crx_address_cost (rtx, bool);
 static bool crx_legitimate_address_p (enum machine_mode, rtx, bool);
 static bool crx_can_eliminate (const int, const int);
-static void crx_option_optimization (int, int);
 
 /*****************************************************************************/
 /* RTL VALIDITY								     */
@@ -177,8 +176,17 @@  static const struct attribute_spec crx_a
 
 /* Option handling.  */
 
-#undef	TARGET_OPTION_OPTIMIZATION
-#define	TARGET_OPTION_OPTIMIZATION	crx_option_optimization
+#undef	TARGET_OPTION_OPTIMIZATION_TABLE
+#define	TARGET_OPTION_OPTIMIZATION_TABLE	crx_option_optimization_table
+
+static const struct default_options crx_option_optimization_table[] =
+  {
+    /* Put each function in its own section so that PAGE-instruction
+       relaxation can do its best.  */
+    { OPT_LEVELS_1_PLUS, OPT_ffunction_sections, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 /* Initialize 'targetm' variable which contains pointers to functions and data
  * relating to the target machine.  */
@@ -1447,13 +1455,3 @@  crx_expand_epilogue (void)
   else
     emit_jump_insn (gen_pop_and_popret_return (GEN_INT (sum_regs)));
 }
-
-/* Implement TARGET_OPTION_OPTIMIZATION.  */
-static void
-crx_option_optimization (int level, int size)
-{
-  /* Put each function in its own section so that PAGE-instruction
-     relaxation can do its best.  */
-  if (level || size)
-    flag_function_sections = 1;
-}
Index: gcc/config/xtensa/xtensa.c
===================================================================
--- gcc/config/xtensa/xtensa.c	(revision 165714)
+++ gcc/config/xtensa/xtensa.c	(working copy)
@@ -119,7 +119,6 @@  const enum reg_class xtensa_regno_to_cla
 };
 
 static void xtensa_option_override (void);
-static void xtensa_option_optimization (int, int);
 static enum internal_test map_test_to_internal_test (enum rtx_code);
 static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *);
 static rtx gen_float_relational (enum rtx_code, rtx, rtx);
@@ -160,6 +159,20 @@  static void xtensa_trampoline_init (rtx,
 
 static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
   REG_ALLOC_ORDER;
+
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+
+static const struct default_options xtensa_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    /* Reordering blocks for Xtensa is not a good idea unless the
+       compiler understands the range of conditional branches.
+       Currently all branch relaxation for Xtensa is handled in the
+       assembler, so GCC cannot do a good job of reordering blocks.
+       Do not enable reordering unless it is explicitly requested.  */
+    { OPT_LEVELS_ALL, OPT_freorder_blocks, NULL, 0 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 
 /* This macro generates the assembly code for function exit,
@@ -255,8 +268,8 @@  static const int reg_nonleaf_alloc_order
 
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE xtensa_option_override
-#undef TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION xtensa_option_optimization
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE xtensa_option_optimization_table
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
@@ -2171,20 +2184,6 @@  xtensa_option_override (void)
     }
 }
 
-/* Implement TARGET_OPTION_OPTIMIZATION.  */
-
-static void
-xtensa_option_optimization (int level ATTRIBUTE_UNUSED,
-			    int size ATTRIBUTE_UNUSED)
-{
-  /* Reordering blocks for Xtensa is not a good idea unless the
-     compiler understands the range of conditional branches.
-     Currently all branch relaxation for Xtensa is handled in the
-     assembler, so GCC cannot do a good job of reordering blocks.  Do
-     not enable reordering unless it is explicitly requested.  */
-  flag_reorder_blocks = 0;
-}
-
 /* A C compound statement to output to stdio stream STREAM the
    assembler syntax for an instruction operand X.  X is an RTL
    expression.
Index: gcc/config/xtensa/xtensa.h
===================================================================
--- gcc/config/xtensa/xtensa.h	(revision 165714)
+++ gcc/config/xtensa/xtensa.h	(working copy)
@@ -100,9 +100,6 @@  extern unsigned xtensa_current_frame_siz
 #define LIBGCC2_WORDS_BIG_ENDIAN 0
 #endif
 
-/* Show we can debug even without a frame pointer.  */
-#define CAN_DEBUG_WITHOUT_FP
-
 
 /* Target machine storage layout */
 
Index: gcc/config/stormy16/stormy16.c
===================================================================
--- gcc/config/stormy16/stormy16.c	(revision 165714)
+++ gcc/config/stormy16/stormy16.c	(working copy)
@@ -1,6 +1,6 @@ 
 /* Xstormy16 target functions.
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-   2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+   2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
    Contributed by Red Hat, Inc.
 
    This file is part of GCC.
@@ -2623,6 +2623,13 @@  xstormy16_return_in_memory (const_tree t
   return (size == -1 || size > UNITS_PER_WORD * NUM_ARGUMENT_REGISTERS);
 }
 
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options xstorym16_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 #undef  TARGET_ASM_ALIGNED_HI_OP
 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
 #undef  TARGET_ASM_ALIGNED_SI_OP
@@ -2671,6 +2678,9 @@  xstormy16_return_in_memory (const_tree t
 #undef TARGET_TRAMPOLINE_INIT
 #define TARGET_TRAMPOLINE_INIT xstormy16_trampoline_init
 
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE xstorym16_option_optimization_table
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-stormy16.h"
Index: gcc/config/stormy16/stormy16.h
===================================================================
--- gcc/config/stormy16/stormy16.h	(revision 165714)
+++ gcc/config/stormy16/stormy16.h	(working copy)
@@ -53,8 +53,6 @@ 
   while (0)
 
 #define TARGET_VERSION fprintf (stderr, " (xstormy16 cpu core)");
-
-#define CAN_DEBUG_WITHOUT_FP
 
 /* Storage Layout.  */
 
Index: gcc/config/fr30/fr30.h
===================================================================
--- gcc/config/fr30/fr30.h	(revision 165714)
+++ gcc/config/fr30/fr30.h	(working copy)
@@ -1,7 +1,7 @@ 
 /*{{{  Comment.  */ 
 
 /* Definitions of FR30 target. 
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2007, 2008, 2009
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Cygnus Solutions.
 
@@ -50,8 +50,6 @@  along with GCC; see the file COPYING3.  
 
 #define TARGET_VERSION fprintf (stderr, " (fr30)");
 
-#define CAN_DEBUG_WITHOUT_FP
-
 #undef  STARTFILE_SPEC
 #define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s"
 
Index: gcc/config/fr30/fr30.c
===================================================================
--- gcc/config/fr30/fr30.c	(revision 165714)
+++ gcc/config/fr30/fr30.c	(working copy)
@@ -1,6 +1,6 @@ 
 /* FR30 specific functions.
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009
-   Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009,
+   2010 Free Software Foundation, Inc.
    Contributed by Cygnus Solutions.
 
    This file is part of GCC.
@@ -142,6 +142,13 @@  static void fr30_trampoline_init (rtx, t
 #if UNITS_PER_WORD == 4
 #define WORD_ALIGN(SIZE) (((SIZE) + 3) & ~3)
 #endif
+
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options fr30_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 /* Initialize the GCC target structure.  */
 #undef  TARGET_ASM_ALIGNED_HI_OP
@@ -175,6 +182,9 @@  static void fr30_trampoline_init (rtx, t
 #undef TARGET_EXCEPT_UNWIND_INFO
 #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
 
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE fr30_option_optimization_table
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 
Index: gcc/config/lm32/lm32.h
===================================================================
--- gcc/config/lm32/lm32.h	(revision 165714)
+++ gcc/config/lm32/lm32.h	(working copy)
@@ -536,8 +536,6 @@  do {                                    
 
 #define DBX_REGISTER_NUMBER(REGNO) (REGNO)
 
-#define CAN_DEBUG_WITHOUT_FP
-
 #define DEFAULT_GDB_EXTENSIONS 1
 
 /*--------*/
Index: gcc/config/lm32/lm32.c
===================================================================
--- gcc/config/lm32/lm32.c	(revision 165714)
+++ gcc/config/lm32/lm32.c	(working copy)
@@ -77,8 +77,17 @@  lm32_legitimate_address_p (enum machine_
 static HOST_WIDE_INT lm32_compute_frame_size (int size);
 static void lm32_option_override (void);
 
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options lm32_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE lm32_option_override
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE lm32_option_optimization_table
 #undef TARGET_ADDRESS_COST
 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
 #undef TARGET_RTX_COSTS
Index: gcc/config/cris/cris.c
===================================================================
--- gcc/config/cris/cris.c	(revision 165714)
+++ gcc/config/cris/cris.c	(working copy)
@@ -132,7 +132,6 @@  static int cris_arg_partial_bytes (CUMUL
 static tree cris_md_asm_clobbers (tree, tree, tree);
 
 static bool cris_handle_option (size_t, const char *, int);
-static void cris_option_optimization (int, int);
 static void cris_option_override (void);
 
 static bool cris_frame_pointer_required (void);
@@ -150,6 +149,14 @@  int cris_max_stackframe = 0;
 /* This is the parsed result of the "-march=" option, if given.  */
 int cris_cpu_version = CRIS_DEFAULT_CPU_VERSION;
 
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+
+static const struct default_options cris_option_optimization_table[] =
+  {
+    { OPT_LEVELS_2_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 #undef TARGET_ASM_ALIGNED_HI_OP
 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
 #undef TARGET_ASM_ALIGNED_SI_OP
@@ -218,8 +225,8 @@  int cris_cpu_version = CRIS_DEFAULT_CPU_
 
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE cris_option_override
-#undef TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION cris_option_optimization
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE cris_option_optimization_table
 
 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
 #define TARGET_ASM_TRAMPOLINE_TEMPLATE cris_asm_trampoline_template
@@ -2422,15 +2429,6 @@  cris_handle_option (size_t code, const c
   return true;
 }
 
-/* Implement TARGET_OPTION_OPTIMIZATION.  */
-
-static void
-cris_option_optimization (int level, int size)
-{
-  if (level >= 2 || size)
-    flag_omit_frame_pointer = 1;
-}
-
 /* The TARGET_OPTION_OVERRIDE worker.
    As is the norm, this also parses -mfoo=bar type parameters.  */
 
Index: gcc/config/iq2000/iq2000.h
===================================================================
--- gcc/config/iq2000/iq2000.h	(revision 165714)
+++ gcc/config/iq2000/iq2000.h	(working copy)
@@ -68,8 +68,6 @@ 
 #ifndef TARGET_VERSION
 #define TARGET_VERSION TARGET_VERSION_INTERNAL (stderr)
 #endif
-
-#define CAN_DEBUG_WITHOUT_FP
 
 /* Storage Layout.  */
 
Index: gcc/config/iq2000/iq2000.c
===================================================================
--- gcc/config/iq2000/iq2000.c	(revision 165714)
+++ gcc/config/iq2000/iq2000.c	(working copy)
@@ -175,6 +175,13 @@  static void iq2000_print_operand      (F
 static void iq2000_print_operand_address (FILE *, rtx);
 static bool iq2000_print_operand_punct_valid_p (unsigned char code);
 
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options iq2000_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 #undef  TARGET_INIT_BUILTINS
 #define TARGET_INIT_BUILTINS 		iq2000_init_builtins
 #undef  TARGET_EXPAND_BUILTIN
@@ -185,6 +192,8 @@  static bool iq2000_print_operand_punct_v
 #define TARGET_HANDLE_OPTION		iq2000_handle_option
 #undef  TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE		iq2000_option_override
+#undef  TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE iq2000_option_optimization_table
 #undef  TARGET_RTX_COSTS
 #define TARGET_RTX_COSTS		iq2000_rtx_costs
 #undef  TARGET_ADDRESS_COST
Index: gcc/config/mn10300/mn10300.c
===================================================================
--- gcc/config/mn10300/mn10300.c	(revision 165714)
+++ gcc/config/mn10300/mn10300.c	(working copy)
@@ -92,6 +92,13 @@  static rtx mn10300_function_value (const
 static rtx mn10300_libcall_value (enum machine_mode, const_rtx);
 static void mn10300_asm_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
 static bool mn10300_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT, const_tree);
+
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options mn10300_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 /* Initialize the GCC target structure.  */
 #undef  TARGET_EXCEPT_UNWIND_INFO
@@ -119,6 +126,8 @@  static bool mn10300_can_output_mi_thunk 
 #define TARGET_HANDLE_OPTION mn10300_handle_option
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE mn10300_option_override
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE mn10300_option_optimization_table
 
 #undef  TARGET_ENCODE_SECTION_INFO
 #define TARGET_ENCODE_SECTION_INFO mn10300_encode_section_info
Index: gcc/config/mn10300/mn10300.h
===================================================================
--- gcc/config/mn10300/mn10300.h	(revision 165714)
+++ gcc/config/mn10300/mn10300.h	(working copy)
@@ -485,10 +485,6 @@  enum reg_class {
 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
   OFFSET = initial_offset (FROM, TO)
 
-/* We can debug without frame pointers on the mn10300, so eliminate
-   them whenever possible.  */
-#define CAN_DEBUG_WITHOUT_FP
-
 /* We use d0/d1 for passing parameters, so allocate 8 bytes of space
    for a register flushback area.  */
 #define REG_PARM_STACK_SPACE(DECL) 8
Index: gcc/config/ia64/vms.h
===================================================================
--- gcc/config/ia64/vms.h	(revision 165714)
+++ gcc/config/ia64/vms.h	(working copy)
@@ -184,10 +184,8 @@  typedef struct crtl_name_spec
     } while (0)
 
 #undef SUBTARGET_OPTIMIZATION_OPTIONS
-#define SUBTARGET_OPTIMIZATION_OPTIONS                     \
-  do {                                                     \
-       flag_merge_constants = 0;                           \
-  } while (0)
+#define SUBTARGET_OPTIMIZATION_OPTIONS			\
+  { OPT_LEVELS_ALL, OPT_fmerge_constants, NULL, 0 }
 
 /* Define this to be nonzero if static stack checking is supported.  */
 #define STACK_CHECK_STATIC_BUILTIN 1
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c	(revision 165714)
+++ gcc/config/ia64/ia64.c	(working copy)
@@ -202,7 +202,6 @@  static rtx gen_fr_spill_x (rtx, rtx, rtx
 static rtx gen_fr_restore_x (rtx, rtx, rtx);
 
 static void ia64_option_override (void);
-static void ia64_option_optimization (int, int);
 static void ia64_option_default_params (void);
 static bool ia64_can_eliminate (const int, const int);
 static enum machine_mode hfa_element_mode (const_tree, bool);
@@ -339,6 +338,16 @@  static const struct attribute_spec ia64_
   { NULL,	       0, 0, false, false, false, NULL }
 };
 
+/* Implement overriding of the optimization options.  */
+static const struct default_options ia64_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+#ifdef SUBTARGET_OPTIMIZATION_OPTIONS
+    SUBTARGET_OPTIMIZATION_OPTIONS,
+#endif
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 /* Initialize the GCC target structure.  */
 #undef TARGET_ATTRIBUTE_TABLE
 #define TARGET_ATTRIBUTE_TABLE ia64_attribute_table
@@ -371,8 +380,8 @@  static const struct attribute_spec ia64_
 
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE ia64_option_override
-#undef TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION ia64_option_optimization
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE ia64_option_optimization_table
 #undef TARGET_OPTION_DEFAULT_PARAMS
 #define TARGET_OPTION_DEFAULT_PARAMS ia64_option_default_params
 
@@ -10830,16 +10839,6 @@  ia64_invalid_binary_op (int op ATTRIBUTE
   return NULL;
 }
 
-/* Implement overriding of the optimization options.  */
-static void
-ia64_option_optimization (int level ATTRIBUTE_UNUSED,
-			  int size ATTRIBUTE_UNUSED)
-{
-#ifdef SUBTARGET_OPTIMIZATION_OPTIONS
-  SUBTARGET_OPTIMIZATION_OPTIONS;
-#endif
-}
-
 /* Implement TARGET_OPTION_DEFAULT_PARAMS.  */
 static void
 ia64_option_default_params (void)
Index: gcc/config/ia64/ia64.h
===================================================================
--- gcc/config/ia64/ia64.h	(revision 165714)
+++ gcc/config/ia64/ia64.h	(working copy)
@@ -1001,9 +1001,6 @@  enum reg_class
 
 /* Eliminating the Frame Pointer and the Arg Pointer */
 
-/* Show we can debug even without a frame pointer.  */
-#define CAN_DEBUG_WITHOUT_FP
-
 /* If defined, this macro specifies a table of register pairs used to eliminate
    unneeded registers that point into the stack frame.  */
 
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 165714)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -1363,6 +1363,13 @@  static const struct attribute_spec rs600
 #endif
   { NULL,        0, 0, false, false, false, NULL }
 };
+
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options rs6000_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 #ifndef MASK_STRICT_ALIGN
 #define MASK_STRICT_ALIGN 0
@@ -1608,6 +1615,9 @@  static const struct attribute_spec rs600
 #undef TARGET_OPTION_DEFAULT_PARAMS
 #define TARGET_OPTION_DEFAULT_PARAMS rs6000_option_default_params
 
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE rs6000_option_optimization_table
+
 #undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
 #define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
   rs6000_builtin_vectorized_function
Index: gcc/config/rs6000/rs6000.h
===================================================================
--- gcc/config/rs6000/rs6000.h	(revision 165714)
+++ gcc/config/rs6000/rs6000.h	(working copy)
@@ -625,9 +625,6 @@  extern unsigned char rs6000_recip_bits[]
 /* The default CPU for TARGET_OPTION_OVERRIDE.  */
 #define OPTION_TARGET_CPU_DEFAULT TARGET_CPU_DEFAULT
 
-/* Show we can debug even without a frame pointer.  */
-#define CAN_DEBUG_WITHOUT_FP
-
 /* Target pragma.  */
 #define REGISTER_TARGET_PRAGMAS() do {				\
   c_register_pragma (0, "longcall", rs6000_pragma_longcall);	\
Index: gcc/config/picochip/picochip.c
===================================================================
--- gcc/config/picochip/picochip.c	(revision 165714)
+++ gcc/config/picochip/picochip.c	(working copy)
@@ -198,6 +198,13 @@  static struct recog_data picochip_saved_
 /* Determine which ALU to use for the instruction in
    picochip_current_prescan_insn. */
 static char picochip_get_vliw_alu_id (void);
+
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options picochip_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 /* Initialize the GCC target structure.  */
 
@@ -326,6 +333,9 @@  static char picochip_get_vliw_alu_id (vo
 #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
 #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE picochip_option_override
 
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE picochip_option_optimization_table
+
 #undef TARGET_EXCEPT_UNWIND_INFO
 #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
 
Index: gcc/config/picochip/picochip.h
===================================================================
--- gcc/config/picochip/picochip.h	(revision 165714)
+++ gcc/config/picochip/picochip.h	(working copy)
@@ -84,8 +84,6 @@  extern enum picochip_dfa_type picochip_s
 #define TARGET_HAS_MAC_UNIT (picochip_has_mac_unit)
 #define TARGET_HAS_MULTIPLY (picochip_has_mac_unit || picochip_has_mul_unit)
 
-#define CAN_DEBUG_WITHOUT_FP 1
-
 #define TARGET_VERSION fprintf(stderr, "(picoChip)");
 
 /* Storage Layout */
Index: gcc/config/mcore/mcore.c
===================================================================
--- gcc/config/mcore/mcore.c	(revision 165714)
+++ gcc/config/mcore/mcore.c	(working copy)
@@ -145,7 +145,6 @@  static int        mcore_arg_partial_byte
 static void       mcore_asm_trampoline_template (FILE *);
 static void       mcore_trampoline_init		(rtx, tree, rtx);
 static void       mcore_option_override		(void);
-static void       mcore_option_optimization	(int, int);
 
 /* MCore specific attributes.  */
 
@@ -157,6 +156,23 @@  static const struct attribute_spec mcore
   { "naked",     0, 0, true,  false, false, mcore_handle_naked_attribute },
   { NULL,        0, 0, false, false, false, NULL }
 };
+
+/* What options are we going to default to specific settings when
+   -O* happens; the user can subsequently override these settings.
+  
+   Omitting the frame pointer is a very good idea on the MCore.
+   Scheduling isn't worth anything on the current MCore implementation.  */
+
+static const struct default_options mcore_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_ffunction_cse, NULL, 0 },
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_ALL, OPT_fcaller_saves, NULL, 0 },
+    { OPT_LEVELS_ALL, OPT_fschedule_insns, NULL, 0 },
+    { OPT_LEVELS_ALL, OPT_fschedule_insns2, NULL, 0 },
+    { OPT_LEVELS_SIZE, OPT_mhardlit, NULL, 0 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 /* Initialize the GCC target structure.  */
 #undef  TARGET_ASM_EXTERNAL_LIBCALL
@@ -224,8 +240,8 @@  static const struct attribute_spec mcore
 
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE mcore_option_override
-#undef TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION mcore_option_optimization
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE mcore_option_optimization_table
 
 #undef TARGET_EXCEPT_UNWIND_INFO
 #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
@@ -2692,33 +2708,6 @@  mcore_option_override (void)
     target_flags |= MASK_M340;
 }
 
-/* What options are we going to default to specific settings when
-   -O* happens; the user can subsequently override these settings.
-  
-   Omitting the frame pointer is a very good idea on the MCore.
-   Scheduling isn't worth anything on the current MCore implementation.  */
-
-static void
-mcore_option_optimization (int level, int size)
-{
-  if (level)
-    {
-      flag_no_function_cse = 1;
-      flag_omit_frame_pointer = 1;
-
-      if (level >= 2)
-        {
-          flag_caller_saves = 0;
-          flag_schedule_insns = 0;
-          flag_schedule_insns_after_reload = 0;
-        }
-    }
-  if (size)
-    {
-      target_flags &= ~MASK_HARDLIT;
-    }
-}
-
 
 /* Compute the number of word sized registers needed to 
    hold a function argument of mode MODE and type TYPE.  */
Index: gcc/config/score/score.c
===================================================================
--- gcc/config/score/score.c	(revision 165714)
+++ gcc/config/score/score.c	(working copy)
@@ -53,6 +53,13 @@ 
 
 static void score_option_override (void);
 
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options score_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 #undef  TARGET_ASM_FILE_START
 #define TARGET_ASM_FILE_START           score_asm_file_start
 
@@ -71,6 +78,8 @@  static void score_option_override (void)
 #define TARGET_HANDLE_OPTION            score_handle_option
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE          score_option_override
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE score_option_optimization_table
 
 #undef TARGET_LEGITIMIZE_ADDRESS
 #define TARGET_LEGITIMIZE_ADDRESS	score_legitimize_address
Index: gcc/config/score/score.h
===================================================================
--- gcc/config/score/score.h	(revision 165714)
+++ gcc/config/score/score.h	(working copy)
@@ -98,9 +98,6 @@ 
 #define TARGET_VERSION \
       fprintf (stderr, "Sunplus S+core rev=%s", SCORE_GCC_VERSION);
 
-/* Show we can debug even without a frame pointer.  */
-#define CAN_DEBUG_WITHOUT_FP
-
 /* Target machine storage layout.  */
 #define BITS_BIG_ENDIAN        0
 #define BYTES_BIG_ENDIAN       (TARGET_LITTLE_ENDIAN == 0)
Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 165714)
+++ gcc/config/arm/arm.c	(working copy)
@@ -217,7 +217,6 @@  static tree arm_build_builtin_va_list (v
 static void arm_expand_builtin_va_start (tree, rtx);
 static tree arm_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
 static void arm_option_override (void);
-static void arm_option_optimization (int, int);
 static bool arm_handle_option (size_t, const char *, int);
 static void arm_target_help (void);
 static unsigned HOST_WIDE_INT arm_shift_truncation_mask (enum machine_mode);
@@ -286,6 +285,15 @@  static const struct attribute_spec arm_a
 #endif
   { NULL,           0, 0, false, false, false, NULL }
 };
+
+/* Set default optimization options.  */
+static const struct default_options arm_option_optimization_table[] =
+  {
+    /* Enable section anchors by default at -O1 or higher.  */
+    { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 },
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 /* Initialize the GCC target structure.  */
 #if TARGET_DLLIMPORT_DECL_ATTRIBUTES
@@ -333,8 +341,8 @@  static const struct attribute_spec arm_a
 #define TARGET_HELP arm_target_help
 #undef  TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE arm_option_override
-#undef  TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION arm_option_optimization
+#undef  TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE arm_option_optimization_table
 
 #undef  TARGET_COMP_TYPE_ATTRIBUTES
 #define TARGET_COMP_TYPE_ATTRIBUTES arm_comp_type_attributes
@@ -22819,15 +22827,6 @@  arm_order_regs_for_local_alloc (void)
             sizeof (thumb_core_reg_alloc_order));
 }
 
-/* Set default optimization options.  */
-static void
-arm_option_optimization (int level, int size ATTRIBUTE_UNUSED)
-{
-  /* Enable section anchors by default at -O1 or higher.  */
-  if (level > 0)
-    flag_section_anchors = 1;
-}
-
 /* Implement TARGET_FRAME_POINTER_REQUIRED.  */
 
 bool
Index: gcc/config/arm/arm.h
===================================================================
--- gcc/config/arm/arm.h	(revision 165714)
+++ gcc/config/arm/arm.h	(working copy)
@@ -494,10 +494,6 @@  extern int arm_arch_hwdiv;
 #define TARGET_DEFAULT  (MASK_APCS_FRAME)
 #endif
 
-/* The frame pointer register used in gcc has nothing to do with debugging;
-   that is controlled by the APCS-FRAME option.  */
-#define CAN_DEBUG_WITHOUT_FP
-
 /* Nonzero if PIC code requires explicit qualifiers to generate
    PLT and GOT relocs rather than the assembler doing so implicitly.
    Subtargets can override these if required.  */
Index: gcc/config/pa/pa.c
===================================================================
--- gcc/config/pa/pa.c	(revision 165714)
+++ gcc/config/pa/pa.c	(working copy)
@@ -222,11 +222,20 @@  static GTY((length ("n_deferred_plabels"
   deferred_plabels;
 static size_t n_deferred_plabels = 0;
 
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options pa_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 
 /* Initialize the GCC target structure.  */
 
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE pa_option_override
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE pa_option_optimization_table
 
 #undef TARGET_ASM_ALIGNED_HI_OP
 #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
Index: gcc/config/pa/pa.h
===================================================================
--- gcc/config/pa/pa.h	(revision 165714)
+++ gcc/config/pa/pa.h	(working copy)
@@ -226,9 +226,6 @@  do {								\
 #define PTRDIFF_TYPE "int"
 #define WCHAR_TYPE "unsigned int"
 #define WCHAR_TYPE_SIZE 32
-
-/* Show we can debug even without a frame pointer.  */
-#define CAN_DEBUG_WITHOUT_FP
 
 /* target machine storage layout */
 typedef struct GTY(()) machine_function
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	(revision 165714)
+++ gcc/config/mips/mips.c	(working copy)
@@ -15876,6 +15876,13 @@  mips_option_override (void)
   mips_set_mips16_mode (false);
 }
 
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
+static const struct default_options mips_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 /* Swap the register information for registers I and I + 1, which
    currently have the wrong endianness.  Note that the registers'
    fixedness and call-clobberedness might have been set on the
@@ -16390,6 +16397,8 @@  mips_shift_truncation_mask (enum machine
 
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE mips_option_override
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE mips_option_optimization_table
 
 #undef TARGET_LEGITIMIZE_ADDRESS
 #define TARGET_LEGITIMIZE_ADDRESS mips_legitimize_address
Index: gcc/config/mips/mips.h
===================================================================
--- gcc/config/mips/mips.h	(revision 165714)
+++ gcc/config/mips/mips.h	(working copy)
@@ -1082,9 +1082,6 @@  enum mips_code_readable_setting {
   (DEFAULT_SWITCH_TAKES_ARG (CHAR) || (CHAR) == 'G')
 
 #define CONDITIONAL_REGISTER_USAGE mips_conditional_register_usage ()
-
-/* Show we can debug even without a frame pointer.  */
-#define CAN_DEBUG_WITHOUT_FP
 
 /* Tell collect what flags to pass to nm.  */
 #ifndef NM_FLAGS
Index: gcc/config/v850/v850.c
===================================================================
--- gcc/config/v850/v850.c	(revision 165714)
+++ gcc/config/v850/v850.c	(working copy)
@@ -141,20 +141,20 @@  v850_handle_option (size_t code, const c
     }
 }
 
-/* Implement TARGET_OPTION_OPTIMIZATION.  */
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
 
-static void
-v850_option_optimization (int level, int size ATTRIBUTE_UNUSED)
-{
-  if (level)
+static const struct default_options v850_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
     /* Note - we no longer enable MASK_EP when optimizing.  This is
        because of a hardware bug which stops the SLD and SST instructions
        from correctly detecting some hazards.  If the user is sure that
        their hardware is fixed or that their program will not encounter
        the conditions that trigger the bug then they can enable -mep by
        hand.  */
-    target_flags |= MASK_PROLOG_FUNCTION;
-}
+    { OPT_LEVELS_1_PLUS, OPT_mprolog_function, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 /* Handle the TARGET_PASS_BY_REFERENCE target hook.
    Specify whether to pass the argument by reference.  */
@@ -3202,8 +3202,8 @@  static const struct attribute_spec v850_
 #undef  TARGET_STRICT_ARGUMENT_NAMING
 #define TARGET_STRICT_ARGUMENT_NAMING v850_strict_argument_naming
 
-#undef  TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION v850_option_optimization
+#undef  TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE v850_option_optimization_table
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
Index: gcc/config/v850/v850.h
===================================================================
--- gcc/config/v850/v850.h	(revision 165714)
+++ gcc/config/v850/v850.h	(working copy)
@@ -137,9 +137,6 @@  enum small_memory_type {
 };
 
 extern struct small_memory_info small_memory[(int)SMALL_MEMORY_max];
-
-/* Show we can debug even without a frame pointer.  */
-#define CAN_DEBUG_WITHOUT_FP
 
 /* Target machine storage layout */
 
Index: gcc/config/h8300/h8300.c
===================================================================
--- gcc/config/h8300/h8300.c	(revision 165714)
+++ gcc/config/h8300/h8300.c	(working copy)
@@ -303,17 +303,16 @@  enum h8_cpu
   H8_S
 };
 
-/* Implement TARGET_OPTION_OPTIMIZATION.  */
+/* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
 
-static void
-h8300_option_optimization (int level ATTRIBUTE_UNUSED,
-			   int size ATTRIBUTE_UNUSED)
-{
-  /* Basic block reordering is only beneficial on targets with cache
-     and/or variable-cycle branches where (cycle count taken != cycle
-     count not taken).  */
-  flag_reorder_blocks = 0;
-}
+static const struct default_options h8300_option_optimization_table[] =
+  {
+    /* Basic block reordering is only beneficial on targets with cache
+       and/or variable-cycle branches where (cycle count taken !=
+       cycle count not taken).  */
+    { OPT_LEVELS_ALL, OPT_freorder_blocks, NULL, 0 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
 
 /* Initialize various cpu specific globals at start up.  */
 
@@ -5937,7 +5936,7 @@  h8300_trampoline_init (rtx m_tramp, tree
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE h8300_option_override
 
-#undef TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION h8300_option_optimization
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE h8300_option_optimization_table
 
 struct gcc_target targetm = TARGET_INITIALIZER;
Index: gcc/config/h8300/h8300.h
===================================================================
--- gcc/config/h8300/h8300.h	(revision 165714)
+++ gcc/config/h8300/h8300.h	(working copy)
@@ -125,9 +125,6 @@  extern const char * const *h8_reg_names;
 #define TARGET_DEFAULT (MASK_QUICKCALL)
 #endif
 
-/* Show we can debug even without a frame pointer.  */
-/* #define CAN_DEBUG_WITHOUT_FP */
-
 /* We want dwarf2 info available to gdb...  */
 #define DWARF2_DEBUGGING_INFO        1
 /* ... but we don't actually support full dwarf2 EH.  */
Index: gcc/config/mmix/mmix.h
===================================================================
--- gcc/config/mmix/mmix.h	(revision 165714)
+++ gcc/config/mmix/mmix.h	(working copy)
@@ -147,10 +147,6 @@  struct GTY(()) machine_function
 #define TARGET_VERSION \
   fprintf (stderr, " (MMIX)")
 
-/* This one will have to wait a little bit; right now we can't debug
-   neither with or without a frame-pointer.  */
-/* #define CAN_DEBUG_WITHOUT_FP */
-
 
 /* Node: Per-Function Data */
 #define INIT_EXPANDERS mmix_init_expanders ()
Index: gcc/config/mmix/mmix.c
===================================================================
--- gcc/config/mmix/mmix.c	(revision 165714)
+++ gcc/config/mmix/mmix.c	(working copy)
@@ -114,7 +114,6 @@  rtx mmix_compare_op1;
 static int mmix_output_destination_register;
 
 static void mmix_option_override (void);
-static void mmix_option_optimization (int, int);
 static void mmix_asm_output_source_filename (FILE *, const char *);
 static void mmix_output_shiftvalue_op_from_str
   (FILE *, const char *, HOST_WIDEST_INT);
@@ -160,6 +159,15 @@  static bool mmix_frame_pointer_required 
 static void mmix_asm_trampoline_template (FILE *);
 static void mmix_trampoline_init (rtx, tree, rtx);
 
+/* TARGET_OPTION_OPTIMIZATION_TABLE.  */
+
+static const struct default_options mmix_option_optimization_table[] =
+  {
+    { OPT_LEVELS_1_PLUS, OPT_fregmove, NULL, 1 },
+    { OPT_LEVELS_2_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
+    { OPT_LEVELS_NONE, 0, NULL, 0 }
+  };
+
 /* Target structure macros.  Listed by node.  See `Using and Porting GCC'
    for a general description.  */
 
@@ -251,8 +259,8 @@  static void mmix_trampoline_init (rtx, t
 
 #undef TARGET_OPTION_OVERRIDE
 #define TARGET_OPTION_OVERRIDE mmix_option_override
-#undef TARGET_OPTION_OPTIMIZATION
-#define TARGET_OPTION_OPTIMIZATION mmix_option_optimization
+#undef TARGET_OPTION_OPTIMIZATION_TABLE
+#define TARGET_OPTION_OPTIMIZATION_TABLE mmix_option_optimization_table
 
 struct gcc_target targetm = TARGET_INITIALIZER;
 
@@ -276,18 +284,6 @@  mmix_option_override (void)
     }
 }
 
-/* TARGET_OPTION_OPTIMIZATION.  */
-
-static void
-mmix_option_optimization (int level, int size)
-{
-  if (level >= 1)
-    flag_regmove = 1;
-
-  if (size || level > 1)
-    flag_omit_frame_pointer = 1;
-}
-
 /* INIT_EXPANDERS.  */
 
 void