Infrastructure for optimization level sensitive PARAM_ values

Message ID 20190611102222.7rupx3wicwt2mq6o@kam.mff.cuni.cz
State New
Headers show
Series
  • Infrastructure for optimization level sensitive PARAM_ values
Related show

Commit Message

Jan Hubicka June 11, 2019, 10:22 a.m.
Hi,
we plan to work on optimizing -O2 better for C++ code. This should
involve enabling some limited auto-inlining and possibly other opts.  To
not ruin code size we plan to tune down the newly introduced
optimizations as well as some of existing ones (shuch as complete loop
unrolling) to make more reasoable code size/performance tradeoffs.

Problem is that our passes are currently kind of binary (eiter enabled
or disabled) and when enabled they are usually tuned to highest value
needed for SPEC improvement and thus often bit extreme.

In opts.c we handle few PARAM values specially but this does not work
well with optimization attribute and LTO where parameters are not
done in funtion specific way.

This patch makes params optimization level sensitive.  This is done as
follows:

 1) parameters are now of two types - either global or optimization level
    specific. Some basic "type checking" is present since gloal parameter
    enum names are now GLOBAL_parname and they are defined by
    DEFPARAM_GLOBAL and used by PARAM_VALUE_GLOBAL
 2) opt specific parameter now have 6 values: for O1,O2,O3,Ofast, Os O1
    and Os O2+.
    This set is meant to be easily changed and basically I worked it
    out by looking at what we do currently with default parameters.
    I did not include Og and one combine flag.
    Generally I do not want to have too many parameters.
 3) For IPA passes there is now PARAM_VALUE_FOR_FN that can be used
    to obtain value depending on the setting of a given function.
 4) there is currently no way for user to specify differet values for different
    levels, but we can do that incrementally.

One ugly thing I needed to track is the fact that params.h is included
in contexts where tree.h is not present and thus DEF_PARAM can't be implemented
by means of inline function. (And I want to keep it inline since params might
be used in loops). This is done by simply passing down all necessary opt
settings from macro.

Bootstrapped/regtested x86_64-linux, seem reasonable?

2019-06-11  Jan Hubicka  <hubicka@ucw.cz>

	* cp/name-lookup.c (namespace_hints::namespace_hints): Use
	PARAM_VALUE_GLOBAL.

2019-06-11  Jan Hubicka  <hubicka@ucw.cz>

	* lto/lto-partition.c (lto_balanced_map): Use PARAM_VALUE_GLOBAL.
	* lto/lto.c (do_whole_program_analysis): Likewise.


ChangeLog:

2019-06-11  Jan Hubicka  <hubicka@ucw.cz>

	* params.def: Introduce DEFPARAM_GLOBAL, DEFPARAM_O2plus,
	DEFPARAM_Ofast, DEFPARAM_Os.
	* common.opt: param_values type is now struct param_vals.
	* opts.c (init_options_struct): Update allocation of param_values.
	(default_options_optimization): Move opt specific initialization of
	PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP, PARAM_MAX_DSE_ACTIVE_LOCAL_STORES,
	PARAM_ALLOW_STORE_DATA_RACES, PARAM_MIN_CROSSJUMP_INSNS to 
	params.def; use GLOBAL_PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE instead
	of PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE.
	(print_filtered_help): Update.
	(common_handle_option): Update handling of sanitize options.
	* params-enum.h (DEFPARAM): Update.
	(DEFPARAM_OPT, DEFPARAM_GLOBAL): New.
	* params-list.h: (DEFPARAM): Update.
	(DEFPARAM_OPT, DEFPARAM_GLOBAL): New.
	* params-options.h: (DEFPARAM): Update.
	(DEFPARAM_OPT, DEFPARAM_GLOBAL): New.
	* params.c (INIT_VALUES): New macro.
	(DEFPARAM): Update.
	(DEFPARAM_OPT, DEFPARAM_GLOBAL): New.
	(set_param_value_internal): Update.
	(set_param_value_internal_index): New.
	(validate_param): Update.
	(set_param_value): Update.
	(maybe_set_param_value): Update.
	(set_default_param_value): Update.
	(default_param_value): Update.
	* params.h (NUM_PARAM_SETTINGS): Set to 6.
	(struct param_vals): New structure.
	(struct param_info): Change type of default_value to param_vals.
	(param_value_index): Update prototype.
	(extern void init_param_values): Update prototype.
	(PARAM_VALUE_FOR_FN, PARAM_VALUE_SET_FOR_FN,
	PARAM_VALUE_SET, PARAM_VALUE_GLOBAL, PARAM_VALUE_GLOBAL_SET): New
	macros.
	(PARAM_VALUE): Implement using PARAM_VALUE_SET_FOR_FN.
	(param_value_index): New inline function.
	(MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS, MAX_INLINE_SLOPE,
	MIN_INLINE_INSNS, MAX_INLINE_INSNS_AUTO, MIN_VIRTUAL_MAPPINGS,
	VIRTUAL_MAPPINGS_TO_SYMS_RATIO): Remove; update uses
	by explicit PARAM_VALUE_FOR_FN.
	(INTEGER_SHARE_LIMIT, MAX_FIELDS_FOR_FIELD_SENSITIVE,
	USE_CANONICAL_TYPES, MIN_NONDEBUG_INSN_UID, ASAN_STACK,
	ASAN_PROTECT_ALLOCAS, ASAN_GLOBALS, ASAN_INSTRUMENT_READS,
	ASAN_INSTRUMENT_WRITES, ASAN_MEMINTRIN, ASAN_USE_AFTER_RETURN,
	ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD): Use
	PARAM_VALUE_GLOBAL.
	* predict.c (get_hot_bb_threshold): Use PARAM_VALUE_GLOBAL.
	(maybe_hot_count_p): Use PARAM_VALUE_GLOBAL.
	(probably_never_executed): Use PARAM_VALUE_GLOBAL.
	(predictable_edge_p): Use PARAM_VALUE_GLOBAL.
	(handle_missing_profiles): Use PARAM_VALUE_GLOBAL.
	* resource.c: Include tree.h.
	* sched-ebb.c: Include tree.h.
	* sched-rgn.c: Include tree.h.
	* targhooks.c (default_max_noce_ifcvt_seq_cost): Use
	PARAM_VALUE_SET.
	* toplev.c (print_version): Use PARAM_VALUE_GLOBAL.
	(process_options): Use PARAM_VALUE_GLOBAL.
	* tree-sra.c (analyze_all_variable_accesses): USE PARAM_VALUE_SET.
	(ipa_sra_preliminary_function_checks): Likewise.
	* tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise.
	* cgraph.c (cgraph_edge::maybe_hot_p): Likewise.
	* coverage.c (get_coverage_counts): Likewise.
	(coverage_compute_profile_id): Likewise.
	(coverage_begin_function): Likewise.
	(coverage_end_function): Likewise.
	* cprop.c: Include tree.h
	* fold-const.c (fold_range_test): Use PARAM_VALUE_GLOBAL.
	(fold_truth_andor): likewise.
	* ggc-page.c (ggc_collect): Use PARAM_VALUE_GLOBAL.
	* haifa-sched.c: Include tree.h.
	* hash-table.h: Use PARAM_VALUE_GLOBAL.
	* ipa-cp.c (ipcp_lattice::add_value): Use PARAM_VALUE_FOR_FN.
	(merge_agg_lats_step): Use PARAM_VALUE_GLOBAL.
	(devirtualization_time_bonus): Use PARAM_VALUE_FOR_FN.
	(hint_time_bonus): Use PARAM_VALUE_GLOBAL.
	(incorporate_penalties): Use PARAM_VALUE_GLOBAL.
	(good_cloning_opportunity_p): Use PARAM_VALUE_FOR_FN.
	(ipcp_propagate_stage): Use PARAM_VALUE_FOR_FN.
	* ipa-fnsummary.c (analyze_function_body): Use PARAM_VALUE_FOR_FN.
	(compute_fn_summary): Use PARAM_VALUE_FOR_FN.
	* ipa-inline-analysis.c (estimate_growth): Use PARAM_VALUE_FOR_FN.
	* ipa-inline.c (caller_growth_limits): Use PARAM_VALUE_FOR_FN.
	(can_inline_edge_by_limits_p): Use PARAM_VALUE_FOR_FN.
	(want_early_inline_function_p): Use PARAM_VALUE_FOR_FN.
	(big_speedup_p): Use PARAM_VALUE_FOR_FN.
	(want_inline_small_function_p): Use PARAM_VALUE_FOR_FN.
	(want_inline_self_recursive_call_p): Use PARAM_VALUE_FOR_FN.
	(edge_badness): Use PARAM_VALUE_FOR_FN.
	(recursive_inlining): Use PARAM_VALUE_FOR_FN.
	(compute_max_insns): Use PARAM_VALUE_GLOBAL.
	* ipa-profile.c (ipa_profile): Likewise.
	* ipa-prop.c: (determine_locally_known_aggregate_parts): Use
	PARAM_VALUE_GLOBAL
	* ipa-split.c (consider_split): Use PARAM_VALUE.
	* ira-build.c: Include tree.h
	* ira-conflicts.c: Include tree.h

config/ChangeLog:

2019-06-11  Jan Hubicka  <hubicka@ucw.cz>

	* i386/i386.c (ix86_max_noce_ifcvt_seq_cost): Use PARAM_VALUE_SET.

Comments

Richard Biener June 11, 2019, 1:29 p.m. | #1
On Tue, 11 Jun 2019, Jan Hubicka wrote:

> Hi,

> we plan to work on optimizing -O2 better for C++ code. This should

> involve enabling some limited auto-inlining and possibly other opts.  To

> not ruin code size we plan to tune down the newly introduced

> optimizations as well as some of existing ones (shuch as complete loop

> unrolling) to make more reasoable code size/performance tradeoffs.

> 

> Problem is that our passes are currently kind of binary (eiter enabled

> or disabled) and when enabled they are usually tuned to highest value

> needed for SPEC improvement and thus often bit extreme.

> 

> In opts.c we handle few PARAM values specially but this does not work

> well with optimization attribute and LTO where parameters are not

> done in funtion specific way.

> 

> This patch makes params optimization level sensitive.  This is done as

> follows:

> 

>  1) parameters are now of two types - either global or optimization level

>     specific. Some basic "type checking" is present since gloal parameter

>     enum names are now GLOBAL_parname and they are defined by

>     DEFPARAM_GLOBAL and used by PARAM_VALUE_GLOBAL

>  2) opt specific parameter now have 6 values: for O1,O2,O3,Ofast, Os O1

>     and Os O2+.

>     This set is meant to be easily changed and basically I worked it

>     out by looking at what we do currently with default parameters.

>     I did not include Og and one combine flag.

>     Generally I do not want to have too many parameters.

>  3) For IPA passes there is now PARAM_VALUE_FOR_FN that can be used

>     to obtain value depending on the setting of a given function.

>  4) there is currently no way for user to specify differet values for different

>     levels, but we can do that incrementally.

> 

> One ugly thing I needed to track is the fact that params.h is included

> in contexts where tree.h is not present and thus DEF_PARAM can't be implemented

> by means of inline function. (And I want to keep it inline since params might

> be used in loops). This is done by simply passing down all necessary opt

> settings from macro.

> 

> Bootstrapped/regtested x86_64-linux, seem reasonable?


Hmm, so looking at

+DEFPARAM_Ofast (PARAM_ALLOW_STORE_DATA_RACES,
          "allow-store-data-races",
          "Allow new data races on stores to be introduced.",
-         0, 0, 1)
+         0, 1, 0, 1)

once we want to have different defaults for -Os, -O2 and -Ofast
we need a new macro here and consumers need to deal with that.

I think we have a similar situation for regular options as well.
If we'd want different -finline-limit= dependent on optimization
setting there's no way to encode that in common.opt or in
default_options_table (maybe there by listing it multiple times
in the "correct" order).

You're not saving --params per function but instead key on
optimize[_{size,fast}].

I'm not sure why there is a distiction between DEFPARAM_*
and DEFPARAM_GLOBAL.  I'd have kept the existing DEFPARAM
syntax like

DEFPARAM (PARAM_ALLOW_STORE_DATA_RACES,
          "allow-store-data-races",
          "Allow new data races on stores to be introduced.",
          0, 0, 1)

which would set the default and then amend it with multiple

DEFPARAM_TUNING (PARAM_ALLOW_STORE_DATA_RACES, TUNE_Ofast, 1)

how does PARAM_VALUE_SET_FOR_FN work when a user cannot specify
param values per function?  Does it say "yes" in case the
function has 'optimize' attributes?

Does it ever make sense to use PARAM_VALUE_GLOBAL?  I think
we should always use PARAM_VALUE[_FOR_FN].

That said, the situation looks somewhat incomplete when
looking at the same issue in common.opt options?

I suppose the alternative was to embed (some) param values
into the opts structure as streamed.  Where I think we need
to go anyways with user supplied per CU --param specifications?
So the patch below walks in a non-extensible direction?

Thanks,
Richard.

> 2019-06-11  Jan Hubicka  <hubicka@ucw.cz>

> 

> 	* cp/name-lookup.c (namespace_hints::namespace_hints): Use

> 	PARAM_VALUE_GLOBAL.

> 

> 2019-06-11  Jan Hubicka  <hubicka@ucw.cz>

> 

> 	* lto/lto-partition.c (lto_balanced_map): Use PARAM_VALUE_GLOBAL.

> 	* lto/lto.c (do_whole_program_analysis): Likewise.

> 

> 

> ChangeLog:

> 

> 2019-06-11  Jan Hubicka  <hubicka@ucw.cz>

> 

> 	* params.def: Introduce DEFPARAM_GLOBAL, DEFPARAM_O2plus,

> 	DEFPARAM_Ofast, DEFPARAM_Os.

> 	* common.opt: param_values type is now struct param_vals.

> 	* opts.c (init_options_struct): Update allocation of param_values.

> 	(default_options_optimization): Move opt specific initialization of

> 	PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP, PARAM_MAX_DSE_ACTIVE_LOCAL_STORES,

> 	PARAM_ALLOW_STORE_DATA_RACES, PARAM_MIN_CROSSJUMP_INSNS to 

> 	params.def; use GLOBAL_PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE instead

> 	of PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE.

> 	(print_filtered_help): Update.

> 	(common_handle_option): Update handling of sanitize options.

> 	* params-enum.h (DEFPARAM): Update.

> 	(DEFPARAM_OPT, DEFPARAM_GLOBAL): New.

> 	* params-list.h: (DEFPARAM): Update.

> 	(DEFPARAM_OPT, DEFPARAM_GLOBAL): New.

> 	* params-options.h: (DEFPARAM): Update.

> 	(DEFPARAM_OPT, DEFPARAM_GLOBAL): New.

> 	* params.c (INIT_VALUES): New macro.

> 	(DEFPARAM): Update.

> 	(DEFPARAM_OPT, DEFPARAM_GLOBAL): New.

> 	(set_param_value_internal): Update.

> 	(set_param_value_internal_index): New.

> 	(validate_param): Update.

> 	(set_param_value): Update.

> 	(maybe_set_param_value): Update.

> 	(set_default_param_value): Update.

> 	(default_param_value): Update.

> 	* params.h (NUM_PARAM_SETTINGS): Set to 6.

> 	(struct param_vals): New structure.

> 	(struct param_info): Change type of default_value to param_vals.

> 	(param_value_index): Update prototype.

> 	(extern void init_param_values): Update prototype.

> 	(PARAM_VALUE_FOR_FN, PARAM_VALUE_SET_FOR_FN,

> 	PARAM_VALUE_SET, PARAM_VALUE_GLOBAL, PARAM_VALUE_GLOBAL_SET): New

> 	macros.

> 	(PARAM_VALUE): Implement using PARAM_VALUE_SET_FOR_FN.

> 	(param_value_index): New inline function.

> 	(MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS, MAX_INLINE_SLOPE,

> 	MIN_INLINE_INSNS, MAX_INLINE_INSNS_AUTO, MIN_VIRTUAL_MAPPINGS,

> 	VIRTUAL_MAPPINGS_TO_SYMS_RATIO): Remove; update uses

> 	by explicit PARAM_VALUE_FOR_FN.

> 	(INTEGER_SHARE_LIMIT, MAX_FIELDS_FOR_FIELD_SENSITIVE,

> 	USE_CANONICAL_TYPES, MIN_NONDEBUG_INSN_UID, ASAN_STACK,

> 	ASAN_PROTECT_ALLOCAS, ASAN_GLOBALS, ASAN_INSTRUMENT_READS,

> 	ASAN_INSTRUMENT_WRITES, ASAN_MEMINTRIN, ASAN_USE_AFTER_RETURN,

> 	ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD): Use

> 	PARAM_VALUE_GLOBAL.

> 	* predict.c (get_hot_bb_threshold): Use PARAM_VALUE_GLOBAL.

> 	(maybe_hot_count_p): Use PARAM_VALUE_GLOBAL.

> 	(probably_never_executed): Use PARAM_VALUE_GLOBAL.

> 	(predictable_edge_p): Use PARAM_VALUE_GLOBAL.

> 	(handle_missing_profiles): Use PARAM_VALUE_GLOBAL.

> 	* resource.c: Include tree.h.

> 	* sched-ebb.c: Include tree.h.

> 	* sched-rgn.c: Include tree.h.

> 	* targhooks.c (default_max_noce_ifcvt_seq_cost): Use

> 	PARAM_VALUE_SET.

> 	* toplev.c (print_version): Use PARAM_VALUE_GLOBAL.

> 	(process_options): Use PARAM_VALUE_GLOBAL.

> 	* tree-sra.c (analyze_all_variable_accesses): USE PARAM_VALUE_SET.

> 	(ipa_sra_preliminary_function_checks): Likewise.

> 	* tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise.

> 	* cgraph.c (cgraph_edge::maybe_hot_p): Likewise.

> 	* coverage.c (get_coverage_counts): Likewise.

> 	(coverage_compute_profile_id): Likewise.

> 	(coverage_begin_function): Likewise.

> 	(coverage_end_function): Likewise.

> 	* cprop.c: Include tree.h

> 	* fold-const.c (fold_range_test): Use PARAM_VALUE_GLOBAL.

> 	(fold_truth_andor): likewise.

> 	* ggc-page.c (ggc_collect): Use PARAM_VALUE_GLOBAL.

> 	* haifa-sched.c: Include tree.h.

> 	* hash-table.h: Use PARAM_VALUE_GLOBAL.

> 	* ipa-cp.c (ipcp_lattice::add_value): Use PARAM_VALUE_FOR_FN.

> 	(merge_agg_lats_step): Use PARAM_VALUE_GLOBAL.

> 	(devirtualization_time_bonus): Use PARAM_VALUE_FOR_FN.

> 	(hint_time_bonus): Use PARAM_VALUE_GLOBAL.

> 	(incorporate_penalties): Use PARAM_VALUE_GLOBAL.

> 	(good_cloning_opportunity_p): Use PARAM_VALUE_FOR_FN.

> 	(ipcp_propagate_stage): Use PARAM_VALUE_FOR_FN.

> 	* ipa-fnsummary.c (analyze_function_body): Use PARAM_VALUE_FOR_FN.

> 	(compute_fn_summary): Use PARAM_VALUE_FOR_FN.

> 	* ipa-inline-analysis.c (estimate_growth): Use PARAM_VALUE_FOR_FN.

> 	* ipa-inline.c (caller_growth_limits): Use PARAM_VALUE_FOR_FN.

> 	(can_inline_edge_by_limits_p): Use PARAM_VALUE_FOR_FN.

> 	(want_early_inline_function_p): Use PARAM_VALUE_FOR_FN.

> 	(big_speedup_p): Use PARAM_VALUE_FOR_FN.

> 	(want_inline_small_function_p): Use PARAM_VALUE_FOR_FN.

> 	(want_inline_self_recursive_call_p): Use PARAM_VALUE_FOR_FN.

> 	(edge_badness): Use PARAM_VALUE_FOR_FN.

> 	(recursive_inlining): Use PARAM_VALUE_FOR_FN.

> 	(compute_max_insns): Use PARAM_VALUE_GLOBAL.

> 	* ipa-profile.c (ipa_profile): Likewise.

> 	* ipa-prop.c: (determine_locally_known_aggregate_parts): Use

> 	PARAM_VALUE_GLOBAL

> 	* ipa-split.c (consider_split): Use PARAM_VALUE.

> 	* ira-build.c: Include tree.h

> 	* ira-conflicts.c: Include tree.h

> 

> config/ChangeLog:

> 

> 2019-06-11  Jan Hubicka  <hubicka@ucw.cz>

> 

> 	* i386/i386.c (ix86_max_noce_ifcvt_seq_cost): Use PARAM_VALUE_SET.

> 

> Index: params.def

> ===================================================================

> --- params.def	(revision 272142)

> +++ params.def	(working copy)

> @@ -19,7 +19,8 @@ along with GCC; see the file COPYING3.

>  <http://www.gnu.org/licenses/>.  */

>  

>  /* This file contains definitions for language-independent

> -   parameters.  The DEFPARAM macro takes 6 arguments:

> +   parameters.  Parameters that are independent of optimization level

> +   are set by the DEFPARAM_GLOBAL macro takes 6 arguments:

>  

>       - The enumeral corresponding to this parameter.

>  

> @@ -35,12 +36,34 @@ along with GCC; see the file COPYING3.

>       - The maximum acceptable value for the parameter (if greater than

>       the minimum).

>  

> +   The DEFPARAM is same except that it declares parameter that may have

> +   different values depends on optimization level.  Those are set by

> +   DEFPARAM_O2plus, DEFPARAM_Ofast and DEFPARAM_Os which additionally

> +   take extra argument specifying values for -O2+, -Ofast and -Os

> +   respectively.

> +

>     The DEFPARAMENUM<N> macro is similar, but instead of the minumum and maximum

>     arguments, it contains a list of <N> allowed strings, corresponding to

>     integer values 0..<N>-1.  Note that the default argument needs to be

>     specified as one of the allowed strings, rather than an integer value.

>  

> -   Be sure to add an entry to invoke.texi summarizing the parameter.  */

> +   Be sure to add an entry to invoke.texi summarizing the parameter.

> +

> +   Values declared by DEFPARAM_GLOBAL are used via PARAM_VALUE_GLOBAL macro

> +   whole other values are read by PARAM_VALUE.  */

> +

> +#define DEFPARAM(ENUM, OPTION, HELP, DEF, MIN, MAX) \

> +	DEFPARAM_OPT (ENUM, OPTION, HELP, DEF, DEF, DEF, DEF, DEF, DEF, \

> +		      MIN, MAX)

> +#define DEFPARAM_O2plus(ENUM, OPTION, HELP, DEF, DEFO2, MIN, MAX) \

> +	DEFPARAM_OPT (ENUM, OPTION, HELP, \

> +		      DEF, DEFO2, DEFO2, DEFO2, DEF, DEFO2, MIN, MAX)

> +#define DEFPARAM_Ofast(ENUM, OPTION, HELP, DEF, DEFOfast, MIN, MAX) \

> +	DEFPARAM_OPT (ENUM, OPTION, HELP, \

> +		      DEF, DEF, DEF, DEFOfast, DEF, DEF, MIN, MAX)

> +#define DEFPARAM_Os(ENUM, OPTION, HELP, DEF, DEFOs, MIN, MAX) \

> +	DEFPARAM_OPT (ENUM, OPTION, HELP, \

> +		      DEF, DEF, DEF, DEF, DEFOs, DEFOs, MIN, MAX)

>  

>  /* When branch is predicted to be taken with probability lower than this

>     threshold (in percent), then it is considered well predictable. */

> @@ -219,15 +242,15 @@ DEFPARAM(PARAM_LARGE_FUNCTION_GROWTH,

>  	 "large-function-growth",

>  	 "Maximal growth due to inlining of large function (in percent).",

>  	 100, 0, 0)

> -DEFPARAM(PARAM_LARGE_UNIT_INSNS,

> +DEFPARAM_GLOBAL(PARAM_LARGE_UNIT_INSNS,

>  	 "large-unit-insns",

>  	 "The size of translation unit to be considered large.",

>  	 10000, 0, 0)

> -DEFPARAM(PARAM_INLINE_UNIT_GROWTH,

> +DEFPARAM_GLOBAL(PARAM_INLINE_UNIT_GROWTH,

>  	 "inline-unit-growth",

>  	 "How much can given compilation unit grow because of the inlining (in percent).",

>  	 40, 0, 0)

> -DEFPARAM(PARAM_IPCP_UNIT_GROWTH,

> +DEFPARAM_GLOBAL(PARAM_IPCP_UNIT_GROWTH,

>  	 "ipcp-unit-growth",

>  	 "How much can given compilation unit grow because of the interprocedural constant propagation (in percent).",

>  	 10, 0, 0)

> @@ -425,12 +448,12 @@ DEFPARAM(PARAM_SMS_LOOP_AVERAGE_COUNT_TH

>  	 "A threshold on the average loop count considered by the swing modulo scheduler.",

>  	 0, 0, 0)

>  

> -DEFPARAM(HOT_BB_COUNT_FRACTION,

> +DEFPARAM_GLOBAL(HOT_BB_COUNT_FRACTION,

>  	 "hot-bb-count-fraction",

>  	 "Select fraction of the maximal count of repetitions of basic block in program given basic "

>  	 "block needs to have to be considered hot (used in non-LTO mode).",

>  	 10000, 0, 0)

> -DEFPARAM(HOT_BB_COUNT_WS_PERMILLE,

> +DEFPARAM_GLOBAL(HOT_BB_COUNT_WS_PERMILLE,

>  	 "hot-bb-count-ws-permille",

>           "A basic block profile count is considered hot if it contributes to "

>           "the given permillage of the entire profiled execution (used in LTO mode).",

> @@ -440,7 +463,7 @@ DEFPARAM(HOT_BB_FREQUENCY_FRACTION,

>  	 "Select fraction of the maximal frequency of executions of basic block in function given basic block needs to have to be considered hot.",

>  	 1000, 0, 0)

>  

> -DEFPARAM(UNLIKELY_BB_COUNT_FRACTION,

> +DEFPARAM_GLOBAL(UNLIKELY_BB_COUNT_FRACTION,

>  	 "unlikely-bb-count-fraction",

>           "The minimum fraction of profile runs a given basic block execution count must be not to be considered unlikely.",

>  	 20, 1, 10000)

> @@ -518,11 +541,12 @@ DEFPARAM(PARAM_MAX_CROSSJUMP_EDGES,

>  	 "The maximum number of incoming edges to consider for crossjumping.",

>  	 100, 0, 0)

>  

> -/* The minimum number of matching instructions to consider for crossjumping.  */

> -DEFPARAM(PARAM_MIN_CROSSJUMP_INSNS,

> +/* The minimum number of matching instructions to consider for crossjumping.

> +   At -Os we want to crossjump as much as possible*/

> +DEFPARAM_Os(PARAM_MIN_CROSSJUMP_INSNS,

>       "min-crossjump-insns",

>       "The minimum number of matching instructions to consider for crossjumping.",

> -     5, 1, 0)

> +     5, 1, 1, 0)

>  

>  /* The maximum number expansion factor when copying basic blocks.  */

>  DEFPARAM(PARAM_MAX_GROW_COPY_BB_INSNS,

> @@ -637,12 +661,12 @@ DEFPARAM(PARAM_MAX_CSELIB_MEMORY_LOCATIO

>  # define GGC_MIN_HEAPSIZE_DEFAULT 4096

>  #endif

>  

> -DEFPARAM(GGC_MIN_EXPAND,

> +DEFPARAM_GLOBAL(GGC_MIN_EXPAND,

>  	 "ggc-min-expand",

>  	 "Minimum heap expansion to trigger garbage collection, as a percentage of the total size of the heap.",

>  	 GGC_MIN_EXPAND_DEFAULT, 0, 0)

>  

> -DEFPARAM(GGC_MIN_HEAPSIZE,

> +DEFPARAM_GLOBAL(GGC_MIN_HEAPSIZE,

>  	 "ggc-min-heapsize",

>  	 "Minimum heap size before we start collecting garbage, in kilobytes.",

>  	 GGC_MIN_HEAPSIZE_DEFAULT, 0, 0)

> @@ -744,7 +768,7 @@ DEFPARAM(PARAM_MAX_COMBINE_INSNS,

>     {signed,unsigned} integral types.  This determines N.

>     Experimentation shows 251 to be a good value that generates the

>     least amount of garbage for allocating the TREE_VEC storage.  */

> -DEFPARAM (PARAM_INTEGER_SHARE_LIMIT,

> +DEFPARAM_GLOBAL (PARAM_INTEGER_SHARE_LIMIT,

>  	  "integer-share-limit",

>  	  "The upper bound for sharing integer constants.",

>  	  251, 2, 2)

> @@ -782,7 +806,7 @@ DEFPARAM (PARAM_MAX_JUMP_THREAD_DUPLICAT

>     will stop trying to treat it in a field-sensitive manner.

>     There are programs out there with thousands of fields per structure, and handling them

>     field-sensitively is not worth the cost.  */

> -DEFPARAM (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,

> +DEFPARAM_GLOBAL (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,

>            "max-fields-for-field-sensitive",

>  	  "Maximum number of fields in a structure before pointer analysis treats the structure as a single variable.",

>  	  0, 0, 0)

> @@ -793,10 +817,10 @@ DEFPARAM(PARAM_MAX_SCHED_READY_INSNS,

>  	 100, 1, 0)

>  

>  /* This is the maximum number of active local stores RTL DSE will consider.  */

> -DEFPARAM (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES,

> +DEFPARAM_O2plus (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES,

>  	  "max-dse-active-local-stores",

>  	  "Maximum number of active local stores in RTL dead store elimination.",

> -	  5000, 0, 0)

> +	  500, 5000, 0, 0)

>  

>  /* Prefetching and cache-optimizations related parameters.  Default values are

>     usually set by machine description.  */

> @@ -874,7 +898,7 @@ DEFPARAM (PARAM_LOOP_INTERCHANGE_STRIDE_

>     this value should only be set to zero to work around bugs in the

>     canonical type system by disabling it.  */

>  

> -DEFPARAM (PARAM_USE_CANONICAL_TYPES,

> +DEFPARAM_GLOBAL (PARAM_USE_CANONICAL_TYPES,

>  	  "use-canonical-types",

>  	  "Whether to use canonical types.",

>  	  1, 0, 1)

> @@ -979,15 +1003,15 @@ DEFPARAM (PARAM_LOOP_MAX_DATAREFS_FOR_DA

>  

>  /* Avoid doing loop invariant motion on very large loops.  */

>  

> -DEFPARAM (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,

> +DEFPARAM_O2plus (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,

>  	  "loop-invariant-max-bbs-in-loop",

>  	  "Max basic blocks number in loop for loop invariant motion.",

> -	  10000, 0, 0)

> +	  1000, 10000, 0, 0)

>  

>  /* When the parameter is 1, use the internal function id

>     to look up for profile data. Otherwise, use a more stable

>     external id based on assembler name and source location. */

> -DEFPARAM (PARAM_PROFILE_FUNC_INTERNAL_ID,

> +DEFPARAM_GLOBAL (PARAM_PROFILE_FUNC_INTERNAL_ID,

>  	  "profile-func-internal-id",

>  	  "Use internal function id in profile lookup.",

>  	  0, 0, 1)

> @@ -1043,7 +1067,7 @@ DEFPARAM (PARAM_MAX_DEBUG_MARKER_COUNT,

>  

>  /* Set minimum insn uid for non-debug insns.  */

>  

> -DEFPARAM (PARAM_MIN_NONDEBUG_INSN_UID,

> +DEFPARAM_GLOBAL (PARAM_MIN_NONDEBUG_INSN_UID,

>  	  "min-nondebug-insn-uid",

>  	  "The minimum UID to be used for a nondebug insn.",

>  	  0, 0, 0)

> @@ -1085,31 +1109,31 @@ DEFPARAM (PARAM_IPA_CP_EVAL_THRESHOLD,

>  	  "beneficial to clone.",

>  	  500, 0, 0)

>  

> -DEFPARAM (PARAM_IPA_CP_RECURSION_PENALTY,

> +DEFPARAM_GLOBAL (PARAM_IPA_CP_RECURSION_PENALTY,

>  	  "ipa-cp-recursion-penalty",

>  	  "Percentage penalty the recursive functions will receive when they "

>  	  "are evaluated for cloning.",

>  	  40, 0, 100)

>  

> -DEFPARAM (PARAM_IPA_CP_SINGLE_CALL_PENALTY,

> +DEFPARAM_GLOBAL (PARAM_IPA_CP_SINGLE_CALL_PENALTY,

>  	  "ipa-cp-single-call-penalty",

>  	  "Percentage penalty functions containing a single call to another "

>  	  "function will receive when they are evaluated for cloning.",

>  	  15, 0, 100)

>  

> -DEFPARAM (PARAM_IPA_MAX_AGG_ITEMS,

> +DEFPARAM_GLOBAL (PARAM_IPA_MAX_AGG_ITEMS,

>  	  "ipa-max-agg-items",

>  	  "Maximum number of aggregate content items for a parameter in "

>  	  "jump functions and lattices.",

>  	  16, 0, 0)

>  

> -DEFPARAM (PARAM_IPA_CP_LOOP_HINT_BONUS,

> +DEFPARAM_GLOBAL (PARAM_IPA_CP_LOOP_HINT_BONUS,

>  	  "ipa-cp-loop-hint-bonus",

>  	  "Compile-time bonus IPA-CP assigns to candidates which make loop "

>  	  "bounds or strides known.",

>  	  64, 0, 0)

>  

> -DEFPARAM (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS,

> +DEFPARAM_GLOBAL (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS,

>  	  "ipa-cp-array-index-hint-bonus",

>  	  "Compile-time bonus IPA-CP assigns to candidates which make an array "

>  	  "index known.",

> @@ -1123,29 +1147,29 @@ DEFPARAM (PARAM_IPA_MAX_AA_STEPS,

>  

>  /* WHOPR partitioning configuration.  */

>  

> -DEFPARAM (PARAM_LTO_PARTITIONS,

> +DEFPARAM_GLOBAL (PARAM_LTO_PARTITIONS,

>  	  "lto-partitions",

>  	  "Number of partitions the program should be split to.",

>  	  128, 1, 0)

>  

> -DEFPARAM (MIN_PARTITION_SIZE,

> +DEFPARAM_GLOBAL (MIN_PARTITION_SIZE,

>  	  "lto-min-partition",

>  	  "Minimal size of a partition for LTO (in estimated instructions).",

>  	  10000, 0, 0)

>  

> -DEFPARAM (MAX_PARTITION_SIZE,

> +DEFPARAM_GLOBAL (MAX_PARTITION_SIZE,

>  	  "lto-max-partition",

>  	  "Maximal size of a partition for LTO (in estimated instructions).",

>  	  1000000, 0, INT_MAX)

>  

> -DEFPARAM (PARAM_MAX_LTO_STREAMING_PARALLELISM,

> +DEFPARAM_GLOBAL (PARAM_MAX_LTO_STREAMING_PARALLELISM,

>  	  "lto-max-streaming-parallelism",

>  	  "maximal number of LTO partitions streamed in parallel.",

>  	  32, 1, 0)

>  

>  /* Diagnostic parameters.  */

>  

> -DEFPARAM (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP,

> +DEFPARAM_GLOBAL (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP,

>  	  "cxx-max-namespaces-for-diagnostic-help",

>  	  "Maximum number of namespaces to search for alternatives when "

>  	  "name lookup fails.",

> @@ -1181,11 +1205,12 @@ DEFPARAM (PARAM_JUMP_TABLE_MAX_GROWTH_RA

>  	  "optimizing for speed.",

>  	  800, 0, 0)

>  

> -/* Data race flags for C++0x memory model compliance.  */

> -DEFPARAM (PARAM_ALLOW_STORE_DATA_RACES,

> +/* Data race flags for C++0x memory model compliance.

> +   Allow them only for Ofast  */

> +DEFPARAM_Ofast (PARAM_ALLOW_STORE_DATA_RACES,

>  	  "allow-store-data-races",

>  	  "Allow new data races on stores to be introduced.",

> -	  0, 0, 1)

> +	  0, 1, 0, 1)

>  

>  /* Reassociation width to be used by tree reassoc optimization.  */

>  DEFPARAM (PARAM_TREE_REASSOC_WIDTH,

> @@ -1244,42 +1269,42 @@ DEFPARAM (PARAM_MAX_SLSR_CANDIDATE_SCAN,

>  

>  /* ASan stands for AddressSanitizer: https://github.com/google/sanitizers.  */

>  

> -DEFPARAM (PARAM_ASAN_STACK,

> +DEFPARAM_GLOBAL (PARAM_ASAN_STACK,

>           "asan-stack",

>           "Enable asan stack protection.",

>           1, 0, 1)

>  

> -DEFPARAM (PARAM_ASAN_PROTECT_ALLOCAS,

> +DEFPARAM_GLOBAL (PARAM_ASAN_PROTECT_ALLOCAS,

>  	"asan-instrument-allocas",

>  	"Enable asan allocas/VLAs protection.",

>  	1, 0, 1)

>  

> -DEFPARAM (PARAM_ASAN_GLOBALS,

> +DEFPARAM_GLOBAL (PARAM_ASAN_GLOBALS,

>           "asan-globals",

>           "Enable asan globals protection.",

>           1, 0, 1)

>  

> -DEFPARAM (PARAM_ASAN_INSTRUMENT_WRITES,

> +DEFPARAM_GLOBAL (PARAM_ASAN_INSTRUMENT_WRITES,

>           "asan-instrument-writes",

>           "Enable asan store operations protection.",

>           1, 0, 1)

>  

> -DEFPARAM (PARAM_ASAN_INSTRUMENT_READS,

> +DEFPARAM_GLOBAL (PARAM_ASAN_INSTRUMENT_READS,

>           "asan-instrument-reads",

>           "Enable asan load operations protection.",

>           1, 0, 1)

>  

> -DEFPARAM (PARAM_ASAN_MEMINTRIN,

> +DEFPARAM_GLOBAL (PARAM_ASAN_MEMINTRIN,

>           "asan-memintrin",

>           "Enable asan builtin functions protection.",

>           1, 0, 1)

>  

> -DEFPARAM (PARAM_ASAN_USE_AFTER_RETURN,

> +DEFPARAM_GLOBAL (PARAM_ASAN_USE_AFTER_RETURN,

>           "asan-use-after-return",

>           "Enable asan detection of use-after-return bugs.",

>           1, 0, 1)

>  

> -DEFPARAM (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,

> +DEFPARAM_GLOBAL (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,

>           "asan-instrumentation-with-call-threshold",

>           "Use callbacks instead of inline code if number of accesses "

>           "in function becomes greater or equal to this number.",

> @@ -1407,7 +1432,7 @@ DEFPARAM(PARAM_AVOID_FMA_MAX_BITS,

>  	 "Maximum number of bits for which we avoid creating FMAs.",

>  	 0, 0, 512)

>  

> -DEFPARAM(PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT,

> +DEFPARAM_GLOBAL(PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT,

>  	 "logical-op-non-short-circuit",

>  	 "True if a non-short-circuit operation is optimal.",

>  	 -1, -1, 1)

> @@ -1431,12 +1456,13 @@ DEFPARAM(PARAM_GIMPLE_FE_COMPUTED_HOT_BB

>  	 " The parameter is used only in GIMPLE FE.",

>  	 0, 0, 0)

>  

> -DEFPARAM(PARAM_HASH_TABLE_VERIFICATION_LIMIT,

> +DEFPARAM_GLOBAL(PARAM_HASH_TABLE_VERIFICATION_LIMIT,

>  	 "hash-table-verification-limit",

>  	 "The number of elements for which hash table verification is done for "

>  	 "each searched element.",

>  	 100, 0, 0)

>  

> +#undef DEFPARAM

>  /*

>  

>  Local variables:

> Index: common.opt

> ===================================================================

> --- common.opt	(revision 272142)

> +++ common.opt	(working copy)

> @@ -64,7 +64,7 @@ Variable

>  bool flag_warn_unused_result = false

>  

>  Variable

> -int *param_values

> +struct param_vals *param_values

>  

>  ; Nonzero if we should write GIMPLE bytecode for link-time optimization.

>  Variable

> Index: opts.c

> ===================================================================

> --- opts.c	(revision 272142)

> +++ opts.c	(working copy)

> @@ -292,10 +292,10 @@ init_options_struct (struct gcc_options

>    if (opts_set)

>      memset (opts_set, 0, sizeof (*opts_set));

>  

> -  opts->x_param_values = XNEWVEC (int, num_params);

> +  opts->x_param_values = XNEWVEC (struct param_vals, num_params);

>  

>    if (opts_set)

> -    opts_set->x_param_values = XCNEWVEC (int, num_params);

> +    opts_set->x_param_values = XCNEWVEC (struct param_vals, num_params);

>  

>    init_param_values (opts->x_param_values);

>  

> @@ -664,41 +664,10 @@ default_options_optimization (struct gcc

>  

>    /* Track fields in field-sensitive alias analysis.  */

>    maybe_set_param_value

> -    (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,

> -     opt2 ? 100 : default_param_value (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE),

> +    (GLOBAL_PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,

> +     opt2 ? 100 : default_param_value (GLOBAL_PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE),

>       opts->x_param_values, opts_set->x_param_values);

>  

> -  /* For -O1 only do loop invariant motion for very small loops.  */

> -  maybe_set_param_value

> -    (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,

> -     opt2 ? default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP)

> -     : default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) / 10,

> -     opts->x_param_values, opts_set->x_param_values);

> -

> -  /* For -O1 reduce the maximum number of active local stores for RTL DSE

> -     since this can consume huge amounts of memory (PR89115).  */

> -  maybe_set_param_value

> -    (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES,

> -     opt2 ? default_param_value (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES)

> -     : default_param_value (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES) / 10,

> -     opts->x_param_values, opts_set->x_param_values);

> -

> -  /* At -Ofast, allow store motion to introduce potential race conditions.  */

> -  maybe_set_param_value

> -    (PARAM_ALLOW_STORE_DATA_RACES,

> -     opts->x_optimize_fast ? 1

> -     : default_param_value (PARAM_ALLOW_STORE_DATA_RACES),

> -     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);

> -

>    /* Restrict the amount of work combine does at -Og while retaining

>       most of its useful transforms.  */

>    if (opts->x_optimize_debug)

> @@ -1330,7 +1299,7 @@ print_filtered_help (unsigned int includ

>  	    {

>  	      snprintf (new_help, sizeof (new_help),

>  			_("default %d minimum %d maximum %d"),

> -			compiler_params[i].default_value,

> +			compiler_params[i].default_value.val[0],

>  			compiler_params[i].min_value,

>  			compiler_params[i].max_value);

>  	      help = new_help;

> @@ -2273,17 +2242,19 @@ common_handle_option (struct gcc_options

>  	 all features.  */

>        if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)

>  	{

> -	  maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,

> +	  maybe_set_param_value (GLOBAL_PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,

>  				 0, opts->x_param_values,

>  				 opts_set->x_param_values);

> -	  maybe_set_param_value (PARAM_ASAN_GLOBALS, 0, opts->x_param_values,

> +	  maybe_set_param_value (GLOBAL_PARAM_ASAN_GLOBALS, 0,

> +				 opts->x_param_values,

>  				 opts_set->x_param_values);

> -	  maybe_set_param_value (PARAM_ASAN_STACK, 0, opts->x_param_values,

> +	  maybe_set_param_value (GLOBAL_PARAM_ASAN_STACK, 0,

> +				 opts->x_param_values,

>  				 opts_set->x_param_values);

> -	  maybe_set_param_value (PARAM_ASAN_PROTECT_ALLOCAS, 0,

> +	  maybe_set_param_value (GLOBAL_PARAM_ASAN_PROTECT_ALLOCAS, 0,

>  				 opts->x_param_values,

>  				 opts_set->x_param_values);

> -	  maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0,

> +	  maybe_set_param_value (GLOBAL_PARAM_ASAN_USE_AFTER_RETURN, 0,

>  				 opts->x_param_values,

>  				 opts_set->x_param_values);

>  	}

> Index: params-enum.h

> ===================================================================

> --- params-enum.h	(revision 272142)

> +++ params-enum.h	(working copy)

> @@ -17,7 +17,9 @@ You should have received a copy of the G

>  along with GCC; see the file COPYING3.  If not see

>  <http://www.gnu.org/licenses/>.  */

>  

> -#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)

> +#define DEFPARAM_OPT(ENUM, OPTION, HELP, DEFO1, DEFO2, DEFO3, DEFOfast,\

> +		     DEFOsO1, DEFOsO2, MIN, MAX)

> +#define DEFPARAM_GLOBAL(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)

>  #define DEFPARAMENUMNAME(ENUM) ENUM ## _KIND

>  #define DEFPARAMENUMVAL(ENUM, V) ENUM ## _KIND_ ## V

>  #define DEFPARAMENUMTERM(ENUM) ENUM ## _KIND_ ## LAST

> @@ -36,4 +38,5 @@ along with GCC; see the file COPYING3.

>  #undef DEFPARAMENUMTERM

>  #undef DEFPARAMENUMVAL

>  #undef DEFPARAMENUMNAME

> -#undef DEFPARAM

> +#undef DEFPARAM_OPT

> +#undef DEFPARAM_GLOBAL

> Index: params-list.h

> ===================================================================

> --- params-list.h	(revision 272142)

> +++ params-list.h	(working copy)

> @@ -17,10 +17,14 @@ You should have received a copy of the G

>  along with GCC; see the file COPYING3.  If not see

>  <http://www.gnu.org/licenses/>.  */

>  

> -#define DEFPARAM(enumerator, option, nocmsgid, default, min, max) \

> +#define DEFPARAM_OPT(enumerator, option, nocmsgid, DEFO1, DEFO2, DEFO3, \

> +		     DEFOfast, DEFOsO1, DEFOsO2, min, max) \

>    enumerator,

> +#define DEFPARAM_GLOBAL(enumerator, option, nocmsgid, default, min, max) \

> +  GLOBAL_##enumerator,

>  #define DEFPARAMENUM5(enumerator, option, nocmsgid, default, \

>  		      v0, v1, v2, v3, v4) enumerator,

>  #include "params.def"

> -#undef DEFPARAM

> +#undef DEFPARAM_OPT

> +#undef DEFPARAM_GLOBAL

>  #undef DEFPARAMENUM5

> Index: params-options.h

> ===================================================================

> --- params-options.h	(revision 272142)

> +++ params-options.h	(working copy)

> @@ -17,11 +17,13 @@ You should have received a copy of the G

>  along with GCC; see the file COPYING3.  If not see

>  <http://www.gnu.org/licenses/>.  */

>  

> -#define DEFPARAM(enumerator, option, nocmsgid, default, min, max) \

> +#define DEFPARAM(enumerator, option, nocmsgid, defO1, defO2, defO3, defOfast, \

> +		 defOs, defOsO1, min, max) \

>    option=default,min,max

>  #define DEFPARAMENUM5(enumerator, option, nocmsgid, default, \

>  		      v0, v1, v2, v3, v4) \

>    option=v0,v1,v2,v3,v4

>  #include "params.def"

> -#undef DEFPARAM

> +#undef DEFPARAM_OPT

> +#undef DEFPARAM_GLOBAL

>  #undef DEFPARAMENUM5

> Index: params.c

> ===================================================================

> --- params.c	(revision 272142)

> +++ params.c	(working copy)

> @@ -28,6 +28,8 @@ along with GCC; see the file COPYING3.

>  #include "diagnostic.h"

>  #include "spellcheck.h"

>  

> +#define INIT_VALUES(VAL) {{(VAL), (VAL), (VAL), (VAL), (VAL), (VAL)}}

> +

>  /* An array containing the compiler parameters and their current

>     values.  */

>  

> @@ -40,27 +42,36 @@ static size_t num_compiler_params;

>     default values determined.  */

>  static bool params_finished;

>  

> -#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)

> +#define DEFPARAM_OPT(ENUM, OPTION, HELP, DEFO1, DEFO2, DEFO3, DEFOfast, \

> +		     DEFOsO1, DEFOsO2, MIN, MAX)

> +#define DEFPARAM_GLOBAL(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)

>  #define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT, V0, V1, V2, V3, V4)	\

>    static const char *values_ ## ENUM [] = { #V0, #V1, #V2, #V3, #V4, NULL };

>  #include "params.def"

>  #undef DEFPARAMENUM5

> -#undef DEFPARAM

> +#undef DEFPARAM_OPT

> +#undef DEFPARAM_GLOBAL

>  

>  static const param_info lang_independent_params[] = {

> -#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX) \

> -  { OPTION, DEFAULT, MIN, MAX, HELP, NULL },

> +#define DEFPARAM_GLOBAL(ENUM, OPTION, HELP, DEFAULT, MIN, MAX) \

> +  { OPTION, {DEFAULT, DEFAULT, DEFAULT, DEFAULT}, MIN, MAX, HELP, NULL },

> +#define DEFPARAM_OPT(ENUM, OPTION, HELP, DEFO1, DEFO2, DEFO3, DEFOfast, \

> +		     DEFOsO1, DEFOsO2, MIN, MAX) \

> +  { OPTION, \

> +   {DEFO1, DEFO2, DEFO3, DEFOfast, DEFOsO1, DEFOsO2}, MIN, MAX, HELP, NULL },

>  #define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT,	     \

>  		      V0, V1, V2, V3, V4)		     \

> -  { OPTION, (int)ENUM ## _KIND_ ## DEFAULT, 0, 4, HELP, values_ ## ENUM },

> +  { OPTION, INIT_VALUES((int)ENUM ## _KIND_ ## DEFAULT),     \

> +    0, 4, HELP, values_ ## ENUM },

>  #include "params.def"

> -#undef DEFPARAM

> +#undef DEFPARAM_OPT

>  #undef DEFPARAMENUM5

> -  { NULL, 0, 0, 0, NULL, NULL }

> +  { NULL, INIT_VALUES (0), 0, 0, NULL, NULL }

>  };

>  

>  static bool

> -validate_param (const int value, const param_info param, const int index);

> +validate_param (const struct param_vals values,

> +		const param_info param, const int index);

>  

>  

>  /* Add the N PARAMS to the current list of compiler parameters.  */

> @@ -131,40 +142,66 @@ params_c_finalize (void)

>     otherwise it is being set implicitly by the compiler.  */

>  

>  static void

> -set_param_value_internal (compiler_param num, int value,

> -			  int *params, int *params_set,

> +set_param_value_internal (compiler_param num, struct param_vals value,

> +			  struct param_vals *params, 

> +			  struct param_vals *params_set,

>  			  bool explicit_p)

>  {

> +  param_vals true_vals = INIT_VALUES (true);

> +

>    size_t i = (size_t) num;

>  

>    gcc_assert (params_finished);

>  

>    params[i] = value;

>    if (explicit_p)

> -    params_set[i] = true;

> +    params_set[i] = true_vals;

> +}

> +

> +/* Same as set_param_value_inter but set only value for given INDEX.  */

> +

> +static void

> +set_param_value_internal_index (compiler_param num, int index,

> +				int value,

> +			        struct param_vals *params, 

> +			        struct param_vals *params_set,

> +				bool explicit_p)

> +{

> +  size_t i = (size_t) num;

> +

> +  gcc_assert (params_finished);

> +

> +  params[i].val[index] = value;

> +  if (explicit_p)

> +    params_set[i].val[index] = true;

>  }

>  

>  /* Validate PARAM and write an error if invalid.  */

>  

>  static bool

> -validate_param (const int value, const param_info param, const int index)

> +validate_param (const struct param_vals values,

> +	        const param_info param, const int index)

>  {

> -  /* These paremeters interpret bounds of 0 to be unbounded, as such don't

> -     perform any range validation on 0 parameters.  */

> -  if (value < param.min_value && param.min_value != 0)

> +  for (int i = 0; i < NUM_PARAM_SETTINGS; i++)

>      {

> -      error ("minimum value of parameter %qs is %u",

> -	     param.option, param.min_value);

> -      return false;

> -    }

> -  else if (param.max_value > param.min_value && value > param.max_value)

> -    {

> -      error ("maximum value of parameter %qs is %u",

> -	     param.option, param.max_value);

> -      return false;

> -    }

> -  else if (targetm_common.option_validate_param (value, index))

> -    return true;

> +      int value = values.val[i];

> +      /* These paremeters interpret bounds of 0 to be unbounded, as such don't

> +	 perform any range validation on 0 parameters.  */

> +      if (value < param.min_value && param.min_value != 0)

> +	{

> +	  error ("minimum value of parameter %qs is %u",

> +		 param.option, param.min_value);

> +	  return false;

> +	}

> +      else if (param.max_value > param.min_value && value > param.max_value)

> +	{

> +	  error ("maximum value of parameter %qs is %u",

> +		 param.option, param.max_value);

> +	  return false;

> +	}

> +      else if (targetm_common.option_validate_param (value, index))

> +	return true;

> +   }

>  

>    return false;

>  }

> @@ -226,9 +263,11 @@ param_string_value_p (enum compiler_para

>  

>  void

>  set_param_value (const char *name, int value,

> -		 int *params, int *params_set)

> +		 struct param_vals *params, 

> +		 struct param_vals *params_set)

>  {

>    size_t i;

> +  struct param_vals values = INIT_VALUES (value);

>  

>    /* Make sure nobody tries to set a parameter to an invalid value.  */

>    gcc_assert (value != INVALID_PARAM_VAL);

> @@ -242,8 +281,8 @@ set_param_value (const char *name, int v

>      }

>    i = (size_t)index;

>  

> -  if (validate_param (value, compiler_params[i], i))

> -    set_param_value_internal ((compiler_param) i, value,

> +  if (validate_param (values, compiler_params[i], i))

> +    set_param_value_internal ((compiler_param) i, values,

>  			      params, params_set, true);

>  }

>  

> @@ -253,10 +292,13 @@ set_param_value (const char *name, int v

>  

>  void

>  maybe_set_param_value (compiler_param num, int value,

> -		       int *params, int *params_set)

> +		       struct param_vals *params, 

> +		       struct param_vals *params_set)

>  {

> -  if (!params_set[(int) num])

> -    set_param_value_internal (num, value, params, params_set, false);

> +  for (int index = 0; index < NUM_PARAM_SETTINGS; index++)

> +    if (!params_set[(int) num].val[index])

> +      set_param_value_internal_index (num, index, value, params,

> +				      params_set, false);

>  }

>  

>  /* Set the default value of a parameter given by NUM to VALUE, before

> @@ -265,9 +307,10 @@ maybe_set_param_value (compiler_param nu

>  void

>  set_default_param_value (compiler_param num, int value)

>  {

> +  struct param_vals vals = INIT_VALUES (value);

>    gcc_assert (!params_finished);

>  

> -  compiler_params[(int) num].default_value = value;

> +  compiler_params[(int) num].default_value = vals;

>  }

>  

>  /* Return the default value of parameter NUM.  */

> @@ -275,14 +318,14 @@ set_default_param_value (compiler_param

>  int

>  default_param_value (compiler_param num)

>  {

> -  return compiler_params[(int) num].default_value;

> +  return compiler_params[(int) num].default_value.val[0];

>  }

>  

>  /* Initialize an array PARAMS with default values of the

>     parameters.  */

>  

>  void

> -init_param_values (int *params)

> +init_param_values (struct param_vals *params)

>  {

>    size_t i;

>  

> Index: params.h

> ===================================================================

> --- params.h	(revision 272142)

> +++ params.h	(working copy)

> @@ -32,10 +32,19 @@ along with GCC; see the file COPYING3.

>  #ifndef GCC_PARAMS_H

>  #define GCC_PARAMS_H

>  

> +#define NUM_PARAM_SETTINGS 6

> +

>  /* No parameter shall have this value.  */

>  

>  #define INVALID_PARAM_VAL (-1)

>  

> +/* Default values for given param.  */

> +

> +struct param_vals

> +{

> +  int val[NUM_PARAM_SETTINGS];

> +};

> +

>  /* The information associated with each parameter.  */

>  

>  struct param_info

> @@ -45,7 +54,7 @@ struct param_info

>    const char *option;

>  

>    /* The default value.  */

> -  int default_value;

> +  struct param_vals default_value;

>  

>    /* Minimum acceptable value.  */

>    int min_value;

> @@ -77,7 +86,8 @@ extern void add_params (const param_info

>     explicitly set.  */

>  

>  extern void set_param_value (const char *name, int value,

> -			     int *params, int *params_set);

> +			     struct param_vals *params,

> +			     struct param_vals *params_set);

>  

>  

>  /* The parameters in use by language-independent code.  */

> @@ -92,16 +102,56 @@ extern bool find_param (const char *, en

>  extern const char *find_param_fuzzy (const char *name);

>  extern bool param_string_value_p (enum compiler_param, const char *, int *);

>  

> -/* The value of the parameter given by ENUM.  Not an lvalue.  */

> -#define PARAM_VALUE(ENUM) \

> -  ((int) global_options.x_param_values[(int) ENUM])

> +/* Return index into param values for optimization setting of the function FUN:

> +   0 for -O0, -O1 and when optimization level is unknown.

> +   1 for -O2

> +   2 for -O3

> +   3 for -Ofast

> +   4 for -Os -O1. 

> +   5 for -Os -O2+.  */

> +inline int

> +param_value_index (bool opt_size, int opt_level, bool opt_fast)

> +{

> +  if (opt_size)

> +    return opt_level <= 1 ? 4 : 5;

> +  if (opt_fast)

> +    return 3;

> +  return MAX (MIN (opt_level-1, 2), 0);

> +}

> +

> +/* The value of the optimization level specific

> +   parameter given by ENUM.  Not an lvalue.  */

> +#define PARAM_VALUE_FOR_FN(FUN, ENUM)					     \

> +  ((int) global_options.x_param_values 					     \

> + 	 [(int) ENUM].val[param_value_index (opt_for_fn (FUN, optimize_size),\

> +					     opt_for_fn (FUN, optimize),     \

> +					     opt_for_fn (FUN, optimize_fast))])

> +/* True if optimization level specific parameter given by ENUM is set.  */

> +#define PARAM_VALUE_SET_FOR_FN(FUN, ENUM)				     \

> +  ((int) global_options_set.x_param_values 				     \

> + 	 [(int) ENUM].val[param_value_index (opt_for_fn (FUN, optimize_size),\

> +					     opt_for_fn (FUN, optimize),     \

> +					     opt_for_fn (FUN, optimize_fast))])

> +

> +/* The value of the optimization level specific

> +   parameter given by ENUM.  Not an lvalue.  */

> +#define PARAM_VALUE(ENUM) 						     \

> +  PARAM_VALUE_FOR_FN(current_function_decl, ENUM)

> +/* True if optimization level specific parameter given by ENUM is set.  */

> +#define PARAM_VALUE_SET(ENUM) 						     \

> +  PARAM_VALUE_SET_FOR_FN(current_function_decl, ENUM)

> +#define PARAM_VALUE_GLOBAL(ENUM) 					     \

> +  ((int) global_options.x_param_values [(int) GLOBAL_##ENUM].val[0])

> +#define PARAM_VALUE_GLOBAL_SET(ENUM) 						     \

> +  ((int) global_options_set.x_param_values [(int) GLOBAL_##ENUM].val[0])

>  

>  /* Set the value of the parameter given by NUM to VALUE, implicitly,

>     if it has not been set explicitly by the user, in the table PARAMS

>     using PARAMS_SET to indicate which have been explicitly set.  */

>  

>  extern void maybe_set_param_value (compiler_param num, int value,

> -				   int *params, int *params_set);

> +				   struct param_vals *params,

> +				   struct param_vals *params_set);

>  

>  /* Set the default value of a parameter given by NUM to VALUE, before

>     option processing.  */

> @@ -127,19 +177,9 @@ extern int default_param_value (compiler

>  

>  /* Initialize an array PARAMS with default values of the

>     parameters.  */

> -extern void init_param_values (int *params);

> +extern void init_param_values (struct param_vals *params);

>  

>  /* Macros for the various parameters.  */

> -#define MAX_INLINE_INSNS_SINGLE \

> -  PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE)

> -#define MAX_INLINE_INSNS \

> -  PARAM_VALUE (PARAM_MAX_INLINE_INSNS)

> -#define MAX_INLINE_SLOPE \

> -  PARAM_VALUE (PARAM_MAX_INLINE_SLOPE)

> -#define MIN_INLINE_INSNS \

> -  PARAM_VALUE (PARAM_MIN_INLINE_INSNS)

> -#define MAX_INLINE_INSNS_AUTO \

> -  PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO)

>  #define MAX_VARIABLE_EXPANSIONS \

>    PARAM_VALUE (PARAM_MAX_VARIABLE_EXPANSIONS)

>  #define MIN_VECT_LOOP_BOUND \

> @@ -175,15 +215,11 @@ extern void init_param_values (int *para

>  #define SMS_LOOP_AVERAGE_COUNT_THRESHOLD \

>    PARAM_VALUE (PARAM_SMS_LOOP_AVERAGE_COUNT_THRESHOLD)

>  #define INTEGER_SHARE_LIMIT \

> -  PARAM_VALUE (PARAM_INTEGER_SHARE_LIMIT)

> +  PARAM_VALUE_GLOBAL (PARAM_INTEGER_SHARE_LIMIT)

>  #define MAX_LAST_VALUE_RTL \

>    PARAM_VALUE (PARAM_MAX_LAST_VALUE_RTL)

> -#define MIN_VIRTUAL_MAPPINGS \

> -  PARAM_VALUE (PARAM_MIN_VIRTUAL_MAPPINGS)

> -#define VIRTUAL_MAPPINGS_TO_SYMS_RATIO \

> -  PARAM_VALUE (PARAM_VIRTUAL_MAPPINGS_TO_SYMS_RATIO)

>  #define MAX_FIELDS_FOR_FIELD_SENSITIVE \

> -  ((size_t) PARAM_VALUE (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE))

> +  ((size_t) PARAM_VALUE_GLOBAL (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE))

>  #define MAX_SCHED_READY_INSNS \

>    PARAM_VALUE (PARAM_MAX_SCHED_READY_INSNS)

>  #define PREFETCH_LATENCY \

> @@ -201,7 +237,7 @@ extern void init_param_values (int *para

>  #define PREFETCH_MINIMUM_STRIDE \

>    PARAM_VALUE (PARAM_PREFETCH_MINIMUM_STRIDE)

>  #define USE_CANONICAL_TYPES \

> -  PARAM_VALUE (PARAM_USE_CANONICAL_TYPES)

> +  PARAM_VALUE_GLOBAL (PARAM_USE_CANONICAL_TYPES)

>  #define IRA_MAX_LOOPS_NUM \

>    PARAM_VALUE (PARAM_IRA_MAX_LOOPS_NUM)

>  #define IRA_MAX_CONFLICT_TABLE_SIZE \

> @@ -223,7 +259,7 @@ extern void init_param_values (int *para

>  #define PREFETCH_MIN_INSN_TO_MEM_RATIO \

>    PARAM_VALUE (PARAM_PREFETCH_MIN_INSN_TO_MEM_RATIO)

>  #define MIN_NONDEBUG_INSN_UID \

> -  PARAM_VALUE (PARAM_MIN_NONDEBUG_INSN_UID)

> +  PARAM_VALUE_GLOBAL (PARAM_MIN_NONDEBUG_INSN_UID)

>  #define MAX_STORES_TO_SINK \

>    PARAM_VALUE (PARAM_MAX_STORES_TO_SINK)

>  #define ALLOW_LOAD_DATA_RACES \

> @@ -235,21 +271,21 @@ extern void init_param_values (int *para

>  #define ALLOW_PACKED_STORE_DATA_RACES \

>    PARAM_VALUE (PARAM_ALLOW_PACKED_STORE_DATA_RACES)

>  #define ASAN_STACK \

> -  PARAM_VALUE (PARAM_ASAN_STACK)

> +  PARAM_VALUE_GLOBAL (PARAM_ASAN_STACK)

>  #define ASAN_PROTECT_ALLOCAS \

> -  PARAM_VALUE (PARAM_ASAN_PROTECT_ALLOCAS)

> +  PARAM_VALUE_GLOBAL (PARAM_ASAN_PROTECT_ALLOCAS)

>  #define ASAN_GLOBALS \

> -  PARAM_VALUE (PARAM_ASAN_GLOBALS)

> +  PARAM_VALUE_GLOBAL (PARAM_ASAN_GLOBALS)

>  #define ASAN_INSTRUMENT_READS \

> -  PARAM_VALUE (PARAM_ASAN_INSTRUMENT_READS)

> +  PARAM_VALUE_GLOBAL (PARAM_ASAN_INSTRUMENT_READS)

>  #define ASAN_INSTRUMENT_WRITES \

> -  PARAM_VALUE (PARAM_ASAN_INSTRUMENT_WRITES)

> +  PARAM_VALUE_GLOBAL (PARAM_ASAN_INSTRUMENT_WRITES)

>  #define ASAN_MEMINTRIN \

> -  PARAM_VALUE (PARAM_ASAN_MEMINTRIN)

> +  PARAM_VALUE_GLOBAL (PARAM_ASAN_MEMINTRIN)

>  #define ASAN_USE_AFTER_RETURN \

> -  PARAM_VALUE (PARAM_ASAN_USE_AFTER_RETURN)

> +  PARAM_VALUE_GLOBAL (PARAM_ASAN_USE_AFTER_RETURN)

>  #define ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD \

> -  PARAM_VALUE (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD)

> +  PARAM_VALUE_GLOBAL (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD)

>  #define ASAN_PARAM_USE_AFTER_SCOPE_DIRECT_EMISSION_THRESHOLD \

>    ((unsigned) PARAM_VALUE (PARAM_USE_AFTER_SCOPE_DIRECT_EMISSION_THRESHOLD))

>  

> Index: predict.c

> ===================================================================

> --- predict.c	(revision 272142)

> +++ predict.c	(working copy)

> @@ -132,7 +132,8 @@ get_hot_bb_threshold ()

>  {

>    if (min_count == -1)

>      {

> -      gcov_type t = profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION);

> +      gcov_type t = profile_info->sum_max / PARAM_VALUE_GLOBAL

> +						 (HOT_BB_COUNT_FRACTION);

>        set_hot_bb_threshold (t);

>        if (dump_file)

>  	fprintf (dump_file, "Setting hotness threshold to %" PRId64 ".\n",

> @@ -173,9 +174,10 @@ maybe_hot_count_p (struct function *fun,

>        if (node->frequency == NODE_FREQUENCY_EXECUTED_ONCE

>  	  && count < (ENTRY_BLOCK_PTR_FOR_FN (fun)->count.apply_scale (2, 3)))

>  	return false;

> -      if (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) == 0)

> +      if (PARAM_VALUE_FOR_FN (node->decl, HOT_BB_FREQUENCY_FRACTION) == 0)

>  	return false;

> -      if (count.apply_scale (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION), 1)

> +      if (count.apply_scale (PARAM_VALUE_FOR_FN (node->decl,

> +						 HOT_BB_FREQUENCY_FRACTION), 1)

>  	  < ENTRY_BLOCK_PTR_FOR_FN (fun)->count)

>  	return false;

>        return true;

> @@ -222,7 +224,8 @@ probably_never_executed (struct function

>       desirable.  */

>    if (count.precise_p () && profile_status_for_fn (fun) == PROFILE_READ)

>      {

> -      int unlikely_count_fraction = PARAM_VALUE (UNLIKELY_BB_COUNT_FRACTION);

> +      int unlikely_count_fraction = PARAM_VALUE_GLOBAL

> +				      (UNLIKELY_BB_COUNT_FRACTION);

>        if (count.apply_scale (unlikely_count_fraction, 1) >= profile_info->runs)

>  	return false;

>        return true;

> @@ -413,9 +416,11 @@ predictable_edge_p (edge e)

>    if (!e->probability.initialized_p ())

>      return false;

>    if ((e->probability.to_reg_br_prob_base ()

> -       <= PARAM_VALUE (PARAM_PREDICTABLE_BRANCH_OUTCOME) * REG_BR_PROB_BASE / 100)

> +       <= PARAM_VALUE (PARAM_PREDICTABLE_BRANCH_OUTCOME)

> +			 * REG_BR_PROB_BASE / 100)

>        || (REG_BR_PROB_BASE - e->probability.to_reg_br_prob_base ()

> -          <= PARAM_VALUE (PARAM_PREDICTABLE_BRANCH_OUTCOME) * REG_BR_PROB_BASE / 100))

> +          <= PARAM_VALUE (PARAM_PREDICTABLE_BRANCH_OUTCOME)

> +				 * REG_BR_PROB_BASE / 100))

>      return true;

>    return false;

>  }

> @@ -3531,7 +3536,7 @@ void

>  handle_missing_profiles (void)

>  {

>    struct cgraph_node *node;

> -  int unlikely_count_fraction = PARAM_VALUE (UNLIKELY_BB_COUNT_FRACTION);

> +  int unlikely_count_fraction = PARAM_VALUE_GLOBAL (UNLIKELY_BB_COUNT_FRACTION);

>    auto_vec<struct cgraph_node *, 64> worklist;

>  

>    /* See if 0 count function has non-0 count callers.  In this case we

> Index: resource.c

> ===================================================================

> --- resource.c	(revision 272142)

> +++ resource.c	(working copy)

> @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.

>  #include "resource.h"

>  #include "insn-attr.h"

>  #include "params.h"

> +#include "tree.h"

>  

>  /* This structure is used to record liveness information at the targets or

>     fallthrough insns of branches.  We will most likely need the information

> Index: sched-ebb.c

> ===================================================================

> --- sched-ebb.c	(revision 272142)

> +++ sched-ebb.c	(working copy)

> @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.

>  #include "cfgrtl.h"

>  #include "cfgbuild.h"

>  #include "sched-int.h"

> +#include "tree.h"

>  

>  

>  #ifdef INSN_SCHEDULING

> Index: sched-rgn.c

> ===================================================================

> --- sched-rgn.c	(revision 272142)

> +++ sched-rgn.c	(working copy)

> @@ -66,6 +66,7 @@ along with GCC; see the file COPYING3.

>  #include "dbgcnt.h"

>  #include "pretty-print.h"

>  #include "print-rtl.h"

> +#include "tree.h"

>  

>  /* Disable warnings about quoting issues in the pp_xxx calls below

>     that (intentionally) don't follow GCC diagnostic conventions.  */

> Index: targhooks.c

> ===================================================================

> --- targhooks.c	(revision 272142)

> +++ targhooks.c	(working copy)

> @@ -2302,7 +2302,7 @@ default_max_noce_ifcvt_seq_cost (edge e)

>  

>    /* If we have a parameter set, use that, otherwise take a guess using

>       BRANCH_COST.  */

> -  if (global_options_set.x_param_values[param])

> +  if (PARAM_VALUE_SET (param))

>      return PARAM_VALUE (param);

>    else

>      return BRANCH_COST (true, predictable_p) * COSTS_N_INSNS (3);

> Index: toplev.c

> ===================================================================

> --- toplev.c	(revision 272142)

> +++ toplev.c	(working copy)

> @@ -697,7 +697,8 @@ print_version (FILE *file, const char *i

>        fprintf (file,

>  	       file == stderr ? _(fmt4) : fmt4,

>  	       indent, *indent != 0 ? " " : "",

> -	       PARAM_VALUE (GGC_MIN_EXPAND), PARAM_VALUE (GGC_MIN_HEAPSIZE));

> +	       PARAM_VALUE_GLOBAL (GGC_MIN_EXPAND),

> +	       PARAM_VALUE_GLOBAL (GGC_MIN_HEAPSIZE));

>  

>        print_plugins_versions (file, indent);

>      }

> @@ -1801,7 +1802,7 @@ process_options (void)

>  

>    if (flag_checking >= 2)

>      hash_table_sanitize_eq_limit

> -      = PARAM_VALUE (PARAM_HASH_TABLE_VERIFICATION_LIMIT);

> +      = PARAM_VALUE_GLOBAL (PARAM_HASH_TABLE_VERIFICATION_LIMIT);

>  

>    /* Please don't change global_options after this point, those changes won't

>       be reflected in optimization_{default,current}_node.  */

> Index: tree-sra.c

> ===================================================================

> --- tree-sra.c	(revision 272142)

> +++ tree-sra.c	(working copy)

> @@ -2977,7 +2977,7 @@ analyze_all_variable_accesses (void)

>    /* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>,

>       fall back to a target default.  */

>    unsigned HOST_WIDE_INT max_scalarization_size

> -    = global_options_set.x_param_values[param]

> +    = PARAM_VALUE_SET (param)

>        ? PARAM_VALUE (param)

>        : get_move_ratio (optimize_speed_p) * UNITS_PER_WORD;

>  

> @@ -5604,7 +5604,8 @@ ipa_sra_preliminary_function_checks (str

>  

>    if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl))

>        && ipa_fn_summaries->get (node)

> -      && ipa_fn_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO)

> +      && ipa_fn_summaries->get (node)->size >=

> +	   PARAM_VALUE_FOR_FN (node->decl, PARAM_MAX_INLINE_INSNS_AUTO))

>      {

>        if (dump_file)

>  	fprintf (dump_file, "Function too big to be made truly local.\n");

> Index: tree-ssa-ifcombine.c

> ===================================================================

> --- tree-ssa-ifcombine.c	(revision 272142)

> +++ tree-ssa-ifcombine.c	(working copy)

> @@ -565,9 +565,9 @@ ifcombine_ifandif (basic_block inner_con

>  	  tree t1, t2;

>  	  gimple_stmt_iterator gsi;

>  	  bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;

> -	  if (PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)

> +	  if (PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)

>  	    logical_op_non_short_circuit

> -	      = PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);

> +	      = PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);

>  	  if (!logical_op_non_short_circuit || flag_sanitize_coverage)

>  	    return false;

>  	  /* Only do this optimization if the inner bb contains only the conditional. */

> Index: cgraph.c

> ===================================================================

> --- cgraph.c	(revision 272142)

> +++ cgraph.c	(working copy)

> @@ -2783,8 +2783,10 @@ cgraph_edge::maybe_hot_p (void)

>    if (caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE

>        && sreal_frequency () * 2 < 3)

>      return false;

> -  if (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) == 0

> -      || sreal_frequency () * PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) <= 1)

> +  if (PARAM_VALUE_FOR_FN (caller->decl, HOT_BB_FREQUENCY_FRACTION) == 0

> +      || sreal_frequency () * PARAM_VALUE_FOR_FN

> +				 (caller->decl,

> +				  HOT_BB_FREQUENCY_FRACTION) <= 1)

>      return false;

>    return true;

>  }

> Index: config/i386/i386.c

> ===================================================================

> --- config/i386/i386.c	(revision 272142)

> +++ config/i386/i386.c	(working copy)

> @@ -21449,7 +21449,7 @@ ix86_max_noce_ifcvt_seq_cost (edge e)

>  

>    /* If we have a parameter set, use that, otherwise take a guess using

>       BRANCH_COST.  */

> -  if (global_options_set.x_param_values[param])

> +  if (PARAM_VALUE_SET (param))

>      return PARAM_VALUE (param);

>    else

>      return BRANCH_COST (true, predictable_p) * COSTS_N_INSNS (2);

> Index: coverage.c

> ===================================================================

> --- coverage.c	(revision 272142)

> +++ coverage.c	(working copy)

> @@ -324,7 +324,7 @@ get_coverage_counts (unsigned counter, u

>  	}

>        return NULL;

>      }

> -  if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))

> +  if (PARAM_VALUE_GLOBAL (PARAM_PROFILE_FUNC_INTERNAL_ID))

>      elt.ident = current_function_funcdef_no + 1;

>    else

>      {

> @@ -560,7 +560,8 @@ coverage_compute_profile_id (struct cgra

>      {

>        expanded_location xloc

>  	= expand_location (DECL_SOURCE_LOCATION (n->decl));

> -      bool use_name_only = (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID) == 0);

> +      bool use_name_only

> +		 = (PARAM_VALUE_GLOBAL (PARAM_PROFILE_FUNC_INTERNAL_ID) == 0);

>  

>        chksum = (use_name_only ? 0 : xloc.line);

>        if (xloc.file)

> @@ -628,7 +629,7 @@ coverage_begin_function (unsigned lineno

>  

>    /* Announce function */

>    offset = gcov_write_tag (GCOV_TAG_FUNCTION);

> -  if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))

> +  if (PARAM_VALUE_GLOBAL (PARAM_PROFILE_FUNC_INTERNAL_ID))

>      gcov_write_unsigned (current_function_funcdef_no + 1);

>    else

>      {

> @@ -682,7 +683,7 @@ coverage_end_function (unsigned lineno_c

>  

>        item = ggc_alloc<coverage_data> ();

>  

> -      if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))

> +      if (PARAM_VALUE_GLOBAL (PARAM_PROFILE_FUNC_INTERNAL_ID))

>  	item->ident = current_function_funcdef_no + 1;

>        else

>  	{

> Index: cp/name-lookup.c

> ===================================================================

> --- cp/name-lookup.c	(revision 272142)

> +++ cp/name-lookup.c	(working copy)

> @@ -5311,7 +5311,7 @@ namespace_hints::namespace_hints (locati

>  

>    m_candidates = vNULL;

>    m_limited = false;

> -  m_limit = PARAM_VALUE (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP);

> +  m_limit = PARAM_VALUE_GLOBAL (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP);

>  

>    /* Breadth-first search of namespaces.  Up to limit namespaces

>       searched (limit zero == unlimited).  */

> Index: cprop.c

> ===================================================================

> --- cprop.c	(revision 272142)

> +++ cprop.c	(working copy)

> @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.

>  #include "cfganal.h"

>  #include "lcm.h"

>  #include "cfgcleanup.h"

> +#include "tree.h"

>  #include "params.h"

>  #include "cselib.h"

>  #include "intl.h"

> Index: fold-const.c

> ===================================================================

> --- fold-const.c	(revision 272142)

> +++ fold-const.c	(working copy)

> @@ -5589,9 +5589,9 @@ fold_range_test (location_t loc, enum tr

>       short-circuited branch and the underlying object on both sides

>       is the same, make a non-short-circuit operation.  */

>    bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;

> -  if (PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)

> +  if (PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)

>      logical_op_non_short_circuit

> -      = PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);

> +      = PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);

>    if (logical_op_non_short_circuit

>        && !flag_sanitize_coverage

>        && lhs != 0 && rhs != 0

> @@ -8255,9 +8255,9 @@ fold_truth_andor (location_t loc, enum t

>      return tem;

>  

>    bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;

> -  if (PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)

> +  if (PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)

>      logical_op_non_short_circuit

> -      = PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);

> +      = PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);

>    if (logical_op_non_short_circuit

>        && !flag_sanitize_coverage

>        && (code == TRUTH_AND_EXPR

> Index: ggc-page.c

> ===================================================================

> --- ggc-page.c	(revision 272142)

> +++ ggc-page.c	(working copy)

> @@ -2171,9 +2171,11 @@ ggc_collect (void)

>       total allocations haven't expanded much since the last

>       collection.  */

>    float allocated_last_gc =

> -    MAX (G.allocated_last_gc, (size_t)PARAM_VALUE (GGC_MIN_HEAPSIZE) * 1024);

> +    MAX (G.allocated_last_gc,

> +	 (size_t)PARAM_VALUE_GLOBAL (GGC_MIN_HEAPSIZE) * 1024);

>  

> -  float min_expand = allocated_last_gc * PARAM_VALUE (GGC_MIN_EXPAND) / 100;

> +  float min_expand = allocated_last_gc

> +		     * PARAM_VALUE_GLOBAL (GGC_MIN_EXPAND) / 100;

>    if (G.allocated < allocated_last_gc + min_expand && !ggc_force_collect)

>      return;

>  

> Index: haifa-sched.c

> ===================================================================

> --- haifa-sched.c	(revision 272142)

> +++ haifa-sched.c	(working copy)

> @@ -146,6 +146,7 @@ along with GCC; see the file COPYING3.

>  #include "cfgloop.h"

>  #include "dumpfile.h"

>  #include "print-rtl.h"

> +#include "tree.h"

>  

>  #ifdef INSN_SCHEDULING

>  

> Index: hash-table.h

> ===================================================================

> --- hash-table.h	(revision 272142)

> +++ hash-table.h	(working copy)

> @@ -386,10 +386,10 @@ public:

>  

>    /* Create a hash_table in gc memory.  */

>    static hash_table *

> -  create_ggc (size_t n CXX_MEM_STAT_INFO)

> +  create_ggc (size_t n, bool sanitize_eq_and_hash = true CXX_MEM_STAT_INFO)

>    {

>      hash_table *table = ggc_alloc<hash_table> ();

> -    new (table) hash_table (n, true, true, GATHER_STATISTICS,

> +    new (table) hash_table (n, true, sanitize_eq_and_hash, GATHER_STATISTICS,

>  			    HASH_TABLE_ORIGIN PASS_MEM_STAT);

>      return table;

>    }

> Index: ipa-cp.c

> ===================================================================

> --- ipa-cp.c	(revision 272142)

> +++ ipa-cp.c	(working copy)

> @@ -1563,7 +1563,8 @@ ipcp_lattice<valtype>::add_value (valtyp

>  	return false;

>        }

>  

> -  if (values_count == PARAM_VALUE (PARAM_IPA_CP_VALUE_LIST_SIZE))

> +  if (values_count == PARAM_VALUE_FOR_FN (cs->caller->decl,

> +					  PARAM_IPA_CP_VALUE_LIST_SIZE))

>      {

>        /* We can only free sources, not the values themselves, because sources

>  	 of other values in this SCC might point to them.   */

> @@ -2043,7 +2044,7 @@ merge_agg_lats_step (struct ipcp_param_l

>  	  set_agg_lats_to_bottom (dest_plats);

>  	  return false;

>  	}

> -      if (dest_plats->aggs_count == PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS))

> +      if (dest_plats->aggs_count == PARAM_VALUE_GLOBAL (PARAM_IPA_MAX_AGG_ITEMS))

>  	return false;

>        dest_plats->aggs_count++;

>        new_al = ipcp_agg_lattice_pool.allocate ();

> @@ -2589,11 +2590,13 @@ devirtualization_time_bonus (struct cgra

>  

>        /* FIXME: The values below need re-considering and perhaps also

>  	 integrating into the cost metrics, at lest in some very basic way.  */

> -      if (isummary->size <= MAX_INLINE_INSNS_AUTO / 4)

> +      int max_inline_insns_auto = PARAM_VALUE_FOR_FN

> +			 (node->decl, PARAM_MAX_INLINE_INSNS_AUTO);

> +      if (isummary->size <= max_inline_insns_auto / 4)

>  	res += 31 / ((int)speculative + 1);

> -      else if (isummary->size <= MAX_INLINE_INSNS_AUTO / 2)

> +      else if (isummary->size <= max_inline_insns_auto / 2)

>  	res += 15 / ((int)speculative + 1);

> -      else if (isummary->size <= MAX_INLINE_INSNS_AUTO

> +      else if (isummary->size <= max_inline_insns_auto

>  	       || DECL_DECLARED_INLINE_P (callee->decl))

>  	res += 7 / ((int)speculative + 1);

>      }

> @@ -2608,9 +2611,9 @@ hint_time_bonus (ipa_hints hints)

>  {

>    int result = 0;

>    if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride))

> -    result += PARAM_VALUE (PARAM_IPA_CP_LOOP_HINT_BONUS);

> +    result += PARAM_VALUE_GLOBAL (PARAM_IPA_CP_LOOP_HINT_BONUS);

>    if (hints & INLINE_HINT_array_index)

> -    result += PARAM_VALUE (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS);

> +    result += PARAM_VALUE_GLOBAL (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS);

>    return result;

>  }

>  

> @@ -2622,11 +2625,13 @@ incorporate_penalties (ipa_node_params *

>  {

>    if (info->node_within_scc)

>      evaluation = (evaluation

> -		  * (100 - PARAM_VALUE (PARAM_IPA_CP_RECURSION_PENALTY))) / 100;

> +		  * (100 - PARAM_VALUE_GLOBAL

> +				 (PARAM_IPA_CP_RECURSION_PENALTY))) / 100;

>  

>    if (info->node_calling_single_call)

>      evaluation = (evaluation

> -		  * (100 - PARAM_VALUE (PARAM_IPA_CP_SINGLE_CALL_PENALTY)))

> +		  * (100 - PARAM_VALUE_GLOBAL

> +				 (PARAM_IPA_CP_SINGLE_CALL_PENALTY)))

>        / 100;

>  

>    return evaluation;

> @@ -2666,10 +2671,12 @@ good_cloning_opportunity_p (struct cgrap

>  		 ", threshold: %i\n",

>  		 info->node_within_scc ? ", scc" : "",

>  		 info->node_calling_single_call ? ", single_call" : "",

> -		 evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD));

> +		 evaluation, PARAM_VALUE_FOR_FN (node->decl,

> +						 PARAM_IPA_CP_EVAL_THRESHOLD));

>  	}

>  

> -      return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);

> +      return evaluation >= PARAM_VALUE_FOR_FN (node->decl,

> +					       PARAM_IPA_CP_EVAL_THRESHOLD);

>      }

>    else

>      {

> @@ -2684,9 +2691,11 @@ good_cloning_opportunity_p (struct cgrap

>  		 time_benefit, size_cost, freq_sum,

>  		 info->node_within_scc ? ", scc" : "",

>  		 info->node_calling_single_call ? ", single_call" : "",

> -		 evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD));

> +		 evaluation, PARAM_VALUE_FOR_FN (node->decl,

> +						 PARAM_IPA_CP_EVAL_THRESHOLD));

>  

> -      return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);

> +      return evaluation >= PARAM_VALUE_FOR_FN (node->decl,

> +					       PARAM_IPA_CP_EVAL_THRESHOLD);

>      }

>  }

>  

> @@ -3301,9 +3310,10 @@ ipcp_propagate_stage (struct ipa_topo_in

>    }

>  

>    max_new_size = overall_size;

> -  if (max_new_size < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS))

> -    max_new_size = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS);

> -  max_new_size += max_new_size * PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH) / 100 + 1;

> +  if (max_new_size < PARAM_VALUE_GLOBAL (PARAM_LARGE_UNIT_INSNS))

> +    max_new_size = PARAM_VALUE_GLOBAL (PARAM_LARGE_UNIT_INSNS);

> +  max_new_size += max_new_size

> +		  * PARAM_VALUE_GLOBAL (PARAM_IPCP_UNIT_GROWTH) / 100 + 1;

>  

>    if (dump_file)

>      fprintf (dump_file, "\noverall_size: %li, max_new_size: %li\n",

> Index: ipa-fnsummary.c

> ===================================================================

> --- ipa-fnsummary.c	(revision 272142)

> +++ ipa-fnsummary.c	(working copy)

> @@ -1987,9 +1987,9 @@ fp_expression_p (gimple *stmt)

>  static void

>  analyze_function_body (struct cgraph_node *node, bool early)

>  {

> -  sreal time = PARAM_VALUE (PARAM_UNINLINED_FUNCTION_TIME);

> +  sreal time = PARAM_VALUE_FOR_FN (node->decl, PARAM_UNINLINED_FUNCTION_TIME);

>    /* Estimate static overhead for function prologue/epilogue and alignment. */

> -  int size = PARAM_VALUE (PARAM_UNINLINED_FUNCTION_INSNS);

> +  int size = PARAM_VALUE_FOR_FN (node->decl, PARAM_UNINLINED_FUNCTION_INSNS);

>    /* Benefits are scaled by probability of elimination that is in range

>       <0,2>.  */

>    basic_block bb;

> @@ -2037,7 +2037,8 @@ analyze_function_body (struct cgraph_nod

>  	  fbi.bb_infos = vNULL;

>  	  fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));

>  	  fbi.param_count = count_formal_params (node->decl);

> -	  fbi.aa_walk_budget = PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS);

> +	  fbi.aa_walk_budget = PARAM_VALUE_FOR_FN (node->decl,

> +						   PARAM_IPA_MAX_AA_STEPS);

>  

>  	  nonconstant_names.safe_grow_cleared

>  	    (SSANAMES (my_function)->length ());

> @@ -2054,9 +2055,11 @@ analyze_function_body (struct cgraph_nod

>    info->account_size_time (0, 0, bb_predicate, bb_predicate);

>  

>    bb_predicate = predicate::not_inlined ();

> -  info->account_size_time (PARAM_VALUE (PARAM_UNINLINED_FUNCTION_INSNS)

> +  info->account_size_time (PARAM_VALUE_FOR_FN (node->decl,

> +					       PARAM_UNINLINED_FUNCTION_INSNS)

>  			   * ipa_fn_summary::size_scale,

> -			   PARAM_VALUE (PARAM_UNINLINED_FUNCTION_TIME),

> +			   PARAM_VALUE_FOR_FN (node->decl,

> +					       PARAM_UNINLINED_FUNCTION_TIME),

>  			   bb_predicate,

>  		           bb_predicate);

>  

> @@ -2441,10 +2444,12 @@ compute_fn_summary (struct cgraph_node *

>        es->call_stmt_size = eni_size_weights.call_cost;

>        es->call_stmt_time = eni_time_weights.call_cost;

>        info->account_size_time (ipa_fn_summary::size_scale

> -			       * PARAM_VALUE

> -				 (PARAM_UNINLINED_FUNCTION_THUNK_INSNS),

> -			       PARAM_VALUE

> -				 (PARAM_UNINLINED_FUNCTION_THUNK_TIME), t, t);

> +			       * PARAM_VALUE_FOR_FN

> +				 (node->decl,

> +				  PARAM_UNINLINED_FUNCTION_THUNK_INSNS),

> +			       PARAM_VALUE_FOR_FN

> +				 (node->decl,

> +				  PARAM_UNINLINED_FUNCTION_THUNK_TIME), t, t);

>        t = predicate::not_inlined ();

>        info->account_size_time (2 * ipa_fn_summary::size_scale, 0, t, t);

>        ipa_update_overall_fn_summary (node);

> Index: ipa-inline-analysis.c

> ===================================================================

> --- ipa-inline-analysis.c	(revision 272142)

> +++ ipa-inline-analysis.c	(working copy)

> @@ -343,7 +343,8 @@ estimate_growth (struct cgraph_node *nod

>        else if (DECL_COMDAT (node->decl)

>  	       && node->can_remove_if_no_direct_calls_p ())

>  	d.growth -= (info->size

> -		     * (100 - PARAM_VALUE (PARAM_COMDAT_SHARING_PROBABILITY))

> +		     * (100 - PARAM_VALUE_FOR_FN (node->decl,

> +						  PARAM_COMDAT_SHARING_PROBABILITY))

>  		     + 50) / 100;

>      }

>  

> Index: ipa-inline.c

> ===================================================================

> --- ipa-inline.c	(revision 272142)

> +++ ipa-inline.c	(working copy)

> @@ -179,13 +179,15 @@ caller_growth_limits (struct cgraph_edge

>    if (limit < what_info->self_size)

>      limit = what_info->self_size;

>  

> -  limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;

> +  limit += limit * PARAM_VALUE_FOR_FN (e->caller->decl,

> +				       PARAM_LARGE_FUNCTION_GROWTH) / 100;

>  

>    /* Check the size after inlining against the function limits.  But allow

>       the function to shrink if it went over the limits by forced inlining.  */

>    newsize = estimate_size_after_inlining (to, e);

>    if (newsize >= info->size

> -      && newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)

> +      && newsize > PARAM_VALUE_FOR_FN (e->caller->decl,

> +				       PARAM_LARGE_FUNCTION_INSNS)

>        && newsize > limit)

>      {

>        e->inline_failed = CIF_LARGE_FUNCTION_GROWTH_LIMIT;

> @@ -201,7 +203,8 @@ caller_growth_limits (struct cgraph_edge

>       on every invocation of the caller (i.e. its call statement dominates

>       exit block).  We do not track this information, yet.  */

>    stack_size_limit += ((gcov_type)stack_size_limit

> -		       * PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) / 100);

> +		       * PARAM_VALUE_FOR_FN (e->caller->decl,

> +					     PARAM_STACK_FRAME_GROWTH) / 100);

>  

>    inlined_stack = (outer_info->stack_frame_offset

>  		   + outer_info->estimated_self_stack_size

> @@ -214,7 +217,8 @@ caller_growth_limits (struct cgraph_edge

>  	 This bit overoptimistically assume that we are good at stack

>  	 packing.  */

>        && inlined_stack > info->estimated_stack_size

> -      && inlined_stack > PARAM_VALUE (PARAM_LARGE_STACK_FRAME))

> +      && inlined_stack > PARAM_VALUE_FOR_FN (e->caller->decl,

> +					     PARAM_LARGE_STACK_FRAME))

>      {

>        e->inline_failed = CIF_LARGE_STACK_FRAME_GROWTH_LIMIT;

>        return false;

> @@ -530,10 +534,15 @@ can_inline_edge_by_limits_p (struct cgra

>  	       > opt_for_fn (caller->decl, optimize_size))

>  	{

>  	  int growth = estimate_edge_growth (e);

> -	  if (growth > PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SIZE)

> +	  if (growth > PARAM_VALUE_FOR_FN (e->caller->decl,

> +					   PARAM_MAX_INLINE_INSNS_SIZE)

>  	      && (!DECL_DECLARED_INLINE_P (callee->decl)

> -		  && growth >= MAX (MAX_INLINE_INSNS_SINGLE,

> -				    MAX_INLINE_INSNS_AUTO)))

> +		  && growth >= MAX (PARAM_VALUE_FOR_FN

> +				      (e->caller->decl,

> +					PARAM_MAX_INLINE_INSNS_SINGLE),

> +				    PARAM_VALUE_FOR_FN

> +				      (e->caller->decl,

> +					PARAM_MAX_INLINE_INSNS_AUTO))))

>  	    {

>  	      e->inline_failed = CIF_OPTIMIZATION_MISMATCH;

>  	      inlinable = false;

> @@ -642,7 +651,8 @@ want_early_inline_function_p (struct cgr

>        int growth = estimate_edge_growth (e);

>        int n;

>  

> -      if (growth <= PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SIZE))

> +      if (growth <= PARAM_VALUE_FOR_FN (e->caller->decl,

> +					PARAM_MAX_INLINE_INSNS_SIZE))

>  	;

>        else if (!e->maybe_hot_p ())

>  	{

> @@ -654,7 +664,8 @@ want_early_inline_function_p (struct cgr

>  			     growth);

>  	  want_inline = false;

>  	}

> -      else if (growth > PARAM_VALUE (PARAM_EARLY_INLINING_INSNS))

> +      else if (growth > PARAM_VALUE_FOR_FN (e->caller->decl,

> +					    PARAM_EARLY_INLINING_INSNS))

>  	{

>  	  if (dump_enabled_p ())

>  	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,

> @@ -665,7 +676,9 @@ want_early_inline_function_p (struct cgr

>  	  want_inline = false;

>  	}

>        else if ((n = num_calls (callee)) != 0

> -	       && growth * (n + 1) > PARAM_VALUE (PARAM_EARLY_INLINING_INSNS))

> +	       && growth * (n + 1) > PARAM_VALUE_FOR_FN

> +					 (e->caller->decl,

> +					  PARAM_EARLY_INLINING_INSNS))

>  	{

>  	  if (dump_enabled_p ())

>  	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,

> @@ -741,7 +754,8 @@ big_speedup_p (struct cgraph_edge *e)

>    sreal inlined_time = compute_inlined_call_time (e, spec_time);

>  

>    if ((time - inlined_time) * 100

> -      > (sreal) (time * PARAM_VALUE (PARAM_INLINE_MIN_SPEEDUP)))

> +      > (sreal) (time * PARAM_VALUE_FOR_FN

> +			 (e->caller->decl, PARAM_INLINE_MIN_SPEEDUP)))

>      return true;

>    return false;

>  }

> @@ -775,7 +789,10 @@ want_inline_small_function_p (struct cgr

>  	   && (!e->count.ipa ().initialized_p () || !e->maybe_hot_p ()))

>  	   && ipa_fn_summaries->get (callee)->min_size

>  		- ipa_call_summaries->get (e)->call_stmt_size

> -	      > MAX (MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS_AUTO))

> +	      > MAX (PARAM_VALUE_FOR_FN (e->caller->decl,

> +					 PARAM_MAX_INLINE_INSNS_SINGLE),

> +		     PARAM_VALUE_FOR_FN (e->caller->decl,

> +					 PARAM_MAX_INLINE_INSNS_AUTO)))

>      {

>        e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;

>        want_inline = false;

> @@ -784,7 +801,8 @@ want_inline_small_function_p (struct cgr

>  	    || e->count.ipa ().nonzero_p ())

>  	   && ipa_fn_summaries->get (callee)->min_size

>  		- ipa_call_summaries->get (e)->call_stmt_size

> -	      > 16 * MAX_INLINE_INSNS_SINGLE)

> +	      > 16 * PARAM_VALUE_FOR_FN (e->caller->decl,

> +					 PARAM_MAX_INLINE_INSNS_SINGLE))

>      {

>        e->inline_failed = (DECL_DECLARED_INLINE_P (callee->decl)

>  			  ? CIF_MAX_INLINE_INSNS_SINGLE_LIMIT

> @@ -797,13 +815,16 @@ want_inline_small_function_p (struct cgr

>        ipa_hints hints = estimate_edge_hints (e);

>        int big_speedup = -1; /* compute this lazily */

>  

> -      if (growth <= PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SIZE))

> +      if (growth <= PARAM_VALUE_FOR_FN

> +			 (e->caller->decl, PARAM_MAX_INLINE_INSNS_SIZE))

>  	;

>        /* Apply MAX_INLINE_INSNS_SINGLE limit.  Do not do so when

>  	 hints suggests that inlining given function is very profitable.  */

>        else if (DECL_DECLARED_INLINE_P (callee->decl)

> -	       && growth >= MAX_INLINE_INSNS_SINGLE

> -	       && (growth >= MAX_INLINE_INSNS_SINGLE * 16

> +	       && growth >= PARAM_VALUE_FOR_FN (e->caller->decl,

> +						PARAM_MAX_INLINE_INSNS_SINGLE)

> +	       && (growth >= PARAM_VALUE_FOR_FN (e->caller->decl,

> +						 PARAM_MAX_INLINE_INSNS_SINGLE)

>  		   || (!(hints & (INLINE_HINT_indirect_call

>  				  | INLINE_HINT_known_hot

>  				  | INLINE_HINT_loop_iterations

> @@ -816,10 +837,12 @@ want_inline_small_function_p (struct cgr

>  	}

>        else if (!DECL_DECLARED_INLINE_P (callee->decl)

>  	       && !opt_for_fn (e->caller->decl, flag_inline_functions)

> -	       && growth >= PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SMALL))

> +	       && growth >= PARAM_VALUE_FOR_FN

> +				 (e->caller->decl, PARAM_MAX_INLINE_INSNS_SMALL))

>  	{

>  	  /* growth_likely_positive is expensive, always test it last.  */

> -          if (growth >= MAX_INLINE_INSNS_SINGLE

> +          if (growth >= PARAM_VALUE_FOR_FN (e->caller->decl,

> +					    PARAM_MAX_INLINE_INSNS_SINGLE)

>  	      || growth_likely_positive (callee, growth))

>  	    {

>                e->inline_failed = CIF_NOT_DECLARED_INLINED;

> @@ -835,13 +858,19 @@ want_inline_small_function_p (struct cgr

>  				       | INLINE_HINT_loop_iterations

>  			               | INLINE_HINT_array_index

>  				       | INLINE_HINT_loop_stride))

> -			     ? MAX (MAX_INLINE_INSNS_AUTO,

> -				    MAX_INLINE_INSNS_SINGLE)

> -			     : MAX_INLINE_INSNS_AUTO)

> +			     ? MAX (PARAM_VALUE_FOR_FN

> +					 (e->caller->decl,

> +					  PARAM_MAX_INLINE_INSNS_AUTO),

> +				    PARAM_VALUE_FOR_FN

> +					 (e->caller->decl,

> +					  PARAM_MAX_INLINE_INSNS_SINGLE))

> +			     : PARAM_VALUE_FOR_FN (e->caller->decl,

> +						   PARAM_MAX_INLINE_INSNS_AUTO))

>  	       && !(big_speedup == -1 ? big_speedup_p (e) : big_speedup))

>  	{

>  	  /* growth_likely_positive is expensive, always test it last.  */

> -          if (growth >= MAX_INLINE_INSNS_SINGLE

> +          if (growth >=	PARAM_VALUE_FOR_FN (e->caller->decl,

> +				     	    PARAM_MAX_INLINE_INSNS_SINGLE)

>  	      || growth_likely_positive (callee, growth))

>  	    {

>  	      e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;

> @@ -850,7 +879,8 @@ want_inline_small_function_p (struct cgr

>  	}

>        /* If call is cold, do not inline when function body would grow. */

>        else if (!e->maybe_hot_p ()

> -	       && (growth >= MAX_INLINE_INSNS_SINGLE

> +	       && (growth >= PARAM_VALUE_FOR_FN (e->caller->decl,

> +						 PARAM_MAX_INLINE_INSNS_SINGLE)

>  		   || growth_likely_positive (callee, growth)))

>  	{

>            e->inline_failed = CIF_UNLIKELY_CALL;

> @@ -882,10 +912,12 @@ want_inline_self_recursive_call_p (struc

>    char const *reason = NULL;

>    bool want_inline = true;

>    sreal caller_freq = 1;

> -  int max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO);

> +  int max_depth = PARAM_VALUE_FOR_FN (edge->caller->decl,

> +				      PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO);

>  

>    if (DECL_DECLARED_INLINE_P (edge->caller->decl))

> -    max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH);

> +    max_depth = PARAM_VALUE_FOR_FN (edge->caller->decl,

> +				    PARAM_MAX_INLINE_RECURSIVE_DEPTH);

>  

>    if (!edge->maybe_hot_p ())

>      {

> @@ -947,7 +979,8 @@ want_inline_self_recursive_call_p (struc

>      {

>        if (edge->sreal_frequency () * 100

>            <= caller_freq

> -	     * PARAM_VALUE (PARAM_MIN_INLINE_RECURSIVE_PROBABILITY))

> +	     * PARAM_VALUE_FOR_FN (edge->caller->decl,

> +			           PARAM_MIN_INLINE_RECURSIVE_PROBABILITY))

>  	{

>  	  reason = "frequency of recursive call is too small";

>  	  want_inline = false;

> @@ -1144,8 +1177,9 @@ edge_badness (struct cgraph_edge *edge,

>  		 frequency still indicates splitting is a win ... */

>  	      || (callee->split_part && !caller->split_part

>  		  && edge->sreal_frequency () * 100

> -		     < PARAM_VALUE

> -			  (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY)

> +		     < PARAM_VALUE_FOR_FN

> +			  (caller->decl,

> +			   PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY)

>  		  /* ... and do not overwrite user specified hints.   */

>  		  && (!DECL_DECLARED_INLINE_P (edge->callee->decl)

>  		      || DECL_DECLARED_INLINE_P (caller->decl)))))

> @@ -1158,8 +1192,10 @@ edge_badness (struct cgraph_edge *edge,

>  	  if (!caller_info->single_caller && overall_growth < caller_growth

>  	      && caller_info->inlinable

>  	      && caller_info->size

> -		 < (DECL_DECLARED_INLINE_P (caller->decl)

> -		    ? MAX_INLINE_INSNS_SINGLE : MAX_INLINE_INSNS_AUTO))

> +		 < PARAM_VALUE_FOR_FN (caller->decl,

> +			(DECL_DECLARED_INLINE_P (caller->decl)

> +			 ? PARAM_MAX_INLINE_INSNS_SINGLE

> +			 : PARAM_MAX_INLINE_INSNS_AUTO)))

>  	    {

>  	      if (dump)

>  		fprintf (dump_file,

> @@ -1473,7 +1509,8 @@ static bool

>  recursive_inlining (struct cgraph_edge *edge,

>  		    vec<cgraph_edge *> *new_edges)

>  {

> -  int limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO);

> +  int limit = PARAM_VALUE_FOR_FN (edge->caller->decl,

> +				  PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO);

>    edge_heap_t heap (sreal::min ());

>    struct cgraph_node *node;

>    struct cgraph_edge *e;

> @@ -1486,7 +1523,7 @@ recursive_inlining (struct cgraph_edge *

>      node = node->global.inlined_to;

>  

>    if (DECL_DECLARED_INLINE_P (node->decl))

> -    limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE);

> +    limit = PARAM_VALUE_FOR_FN (node->decl, PARAM_MAX_INLINE_INSNS_RECURSIVE);

>  

>    /* Make sure that function is small enough to be considered for inlining.  */

>    if (estimate_size_after_inlining (node, edge)  >= limit)

> @@ -1611,11 +1648,11 @@ static int

>  compute_max_insns (int insns)

>  {

>    int max_insns = insns;

> -  if (max_insns < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS))

> -    max_insns = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS);

> +  if (max_insns < PARAM_VALUE_GLOBAL (PARAM_LARGE_UNIT_INSNS))

> +    max_insns = PARAM_VALUE_GLOBAL (PARAM_LARGE_UNIT_INSNS);

>  

>    return ((int64_t) max_insns

> -	  * (100 + PARAM_VALUE (PARAM_INLINE_UNIT_GROWTH)) / 100);

> +	  * (100 + PARAM_VALUE_GLOBAL (PARAM_INLINE_UNIT_GROWTH)) / 100);

>  }

>  

>  

> Index: ipa-profile.c

> ===================================================================

> --- ipa-profile.c	(revision 272142)

> +++ ipa-profile.c	(working copy)

> @@ -506,7 +506,8 @@ ipa_profile (void)

>  

>        gcc_assert (overall_size);

>  

> -      cutoff = (overall_time * PARAM_VALUE (HOT_BB_COUNT_WS_PERMILLE) + 500) / 1000;

> +      cutoff = (overall_time * PARAM_VALUE_GLOBAL

> +			 (HOT_BB_COUNT_WS_PERMILLE) + 500) / 1000;

>        threshold = 0;

>        for (i = 0; cumulated < cutoff; i++)

>  	{

> Index: ipa-prop.c

> ===================================================================

> --- ipa-prop.c	(revision 272142)

> +++ ipa-prop.c	(working copy)

> @@ -1547,7 +1547,7 @@ determine_locally_known_aggregate_parts

>    bool check_ref, by_ref;

>    ao_ref r;

>  

> -  if (PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS) == 0)

> +  if (PARAM_VALUE_GLOBAL (PARAM_IPA_MAX_AGG_ITEMS) == 0)

>      return;

>  

>    /* The function operates in three stages.  First, we prepare check_ref, r,

> @@ -1675,8 +1675,8 @@ determine_locally_known_aggregate_parts

>        *p = n;

>  

>        item_count++;

> -      if (const_count == PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS)

> -	  || item_count == 2 * PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS))

> +      if (const_count == PARAM_VALUE_GLOBAL (PARAM_IPA_MAX_AGG_ITEMS)

> +	  || item_count == 2 * PARAM_VALUE_GLOBAL (PARAM_IPA_MAX_AGG_ITEMS))

>  	break;

>      }

>  

> Index: ipa-split.c

> ===================================================================

> --- ipa-split.c	(revision 272142)

> +++ ipa-split.c	(working copy)

> @@ -561,8 +561,8 @@ consider_split (struct split_point *curr

>       that.  Next stage1 we should try to be more meaningful here.  */

>    if (current->header_size + call_overhead

>        >= (unsigned int)(DECL_DECLARED_INLINE_P (current_function_decl)

> -			? MAX_INLINE_INSNS_SINGLE

> -			: MAX_INLINE_INSNS_AUTO) + 10)

> +			? PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE)

> +			: PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO)) + 10)

>      {

>        if (dump_file && (dump_flags & TDF_DETAILS))

>  	fprintf (dump_file,

> @@ -575,7 +575,8 @@ consider_split (struct split_point *curr

>       Limit this duplication.  This is consistent with limit in tree-sra.c  

>       FIXME: with LTO we ought to be able to do better!  */

>    if (DECL_ONE_ONLY (current_function_decl)

> -      && current->split_size >= (unsigned int) MAX_INLINE_INSNS_AUTO + 10)

> +      && current->split_size

> +	   >= (unsigned int) PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO) + 10)

>      {

>        if (dump_file && (dump_flags & TDF_DETAILS))

>  	fprintf (dump_file,

> Index: ira-build.c

> ===================================================================

> --- ira-build.c	(revision 272142)

> +++ ira-build.c	(working copy)

> @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.

>  #include "params.h"

>  #include "sparseset.h"

>  #include "cfgloop.h"

> +#include "tree.h"

>  

>  static ira_copy_t find_allocno_copy (ira_allocno_t, ira_allocno_t, rtx_insn *,

>  				     ira_loop_tree_node_t);

> Index: ira-conflicts.c

> ===================================================================

> --- ira-conflicts.c	(revision 272142)

> +++ ira-conflicts.c	(working copy)

> @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.

>  #include "params.h"

>  #include "sparseset.h"

>  #include "addresses.h"

> +#include "tree.h"

>  

>  /* This file contains code responsible for allocno conflict creation,

>     allocno copy creation and allocno info accumulation on upper level

> Index: lto/lto-partition.c

> ===================================================================

> --- lto/lto-partition.c	(revision 272142)

> +++ lto/lto-partition.c	(working copy)

> @@ -560,13 +560,13 @@ lto_balanced_map (int n_lto_partitions,

>    varpool_order.qsort (varpool_node_cmp);

>  

>    /* Compute partition size and create the first partition.  */

> -  if (PARAM_VALUE (MIN_PARTITION_SIZE) > max_partition_size)

> +  if (PARAM_VALUE_GLOBAL (MIN_PARTITION_SIZE) > max_partition_size)

>      fatal_error (input_location, "min partition size cannot be greater "

>  		 "than max partition size");

>  

>    partition_size = total_size / n_lto_partitions;

> -  if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE))

> -    partition_size = PARAM_VALUE (MIN_PARTITION_SIZE);

> +  if (partition_size < PARAM_VALUE_GLOBAL (MIN_PARTITION_SIZE))

> +    partition_size = PARAM_VALUE_GLOBAL (MIN_PARTITION_SIZE);

>    npartitions = 1;

>    partition = new_partition ("");

>    if (dump_file)

> @@ -816,8 +816,8 @@ lto_balanced_map (int n_lto_partitions,

>  	    fprintf (dump_file,

>  		     "Total size: %" PRId64 " partition_size: %" PRId64 "\n",

>  		     total_size, partition_size);

> -	  if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE))

> -	    partition_size = PARAM_VALUE (MIN_PARTITION_SIZE);

> +	  if (partition_size < PARAM_VALUE_GLOBAL (MIN_PARTITION_SIZE))

> +	    partition_size = PARAM_VALUE_GLOBAL (MIN_PARTITION_SIZE);

>  	  npartitions ++;

>  	}

>      }

> Index: lto/lto.c

> ===================================================================

> --- lto/lto.c	(revision 272142)

> +++ lto/lto.c	(working copy)

> @@ -420,14 +420,16 @@ do_whole_program_analysis (void)

>  

>    /* TODO: jobserver communication is not supported, yet.  */

>    if (!strcmp (flag_wpa, "jobserver"))

> -    lto_parallelism = PARAM_VALUE (PARAM_MAX_LTO_STREAMING_PARALLELISM);

> +    lto_parallelism = PARAM_VALUE_GLOBAL (PARAM_MAX_LTO_STREAMING_PARALLELISM);

>    else

>      {

>        lto_parallelism = atoi (flag_wpa);

>        if (lto_parallelism <= 0)

>  	lto_parallelism = 0;

> -      if (lto_parallelism >= PARAM_VALUE (PARAM_MAX_LTO_STREAMING_PARALLELISM))

> -	lto_parallelism = PARAM_VALUE (PARAM_MAX_LTO_STREAMING_PARALLELISM);

> +      if (lto_parallelism >= PARAM_VALUE_GLOBAL

> +				 (PARAM_MAX_LTO_STREAMING_PARALLELISM))

> +	lto_parallelism = PARAM_VALUE_GLOBAL

> +			     (PARAM_MAX_LTO_STREAMING_PARALLELISM);

>      }

>  

>    timevar_start (TV_PHASE_OPT_GEN);

> @@ -479,8 +481,8 @@ do_whole_program_analysis (void)

>    else if (flag_lto_partition == LTO_PARTITION_ONE)

>      lto_balanced_map (1, INT_MAX);

>    else if (flag_lto_partition == LTO_PARTITION_BALANCED)

> -    lto_balanced_map (PARAM_VALUE (PARAM_LTO_PARTITIONS),

> -		      PARAM_VALUE (MAX_PARTITION_SIZE));

> +    lto_balanced_map (PARAM_VALUE_GLOBAL (PARAM_LTO_PARTITIONS),

> +		      PARAM_VALUE_GLOBAL (MAX_PARTITION_SIZE));

>    else

>      gcc_unreachable ();

>  

> 


-- 
Richard Biener <rguenther@suse.de>
SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany;
GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG Nürnberg)
Jan Hubicka June 11, 2019, 1:54 p.m. | #2
> Hmm, so looking at

> 

> +DEFPARAM_Ofast (PARAM_ALLOW_STORE_DATA_RACES,

>           "allow-store-data-races",

>           "Allow new data races on stores to be introduced.",

> -         0, 0, 1)

> +         0, 1, 0, 1)

> 

> once we want to have different defaults for -Os, -O2 and -Ofast

> we need a new macro here and consumers need to deal with that.


Yes, my plan is to add DEFPARAM_O2_Ofast and similar variants if they
become necessary.  Consumers needs not be updated - it is
why I implemented those as wrappers to DEFPARAM and defined them in
params.def so it is not hard to add new ones wihout having to define
them multiple times.
> 

> I think we have a similar situation for regular options as well.

> If we'd want different -finline-limit= dependent on optimization

> setting there's no way to encode that in common.opt or in

> default_options_table (maybe there by listing it multiple times

> in the "correct" order).


-finline-limit is deprecated and translated to max-inline-insns-single
and max-inline-insns-auto

We have optimization attribute to handle command line options mismatches
and I think one should not need to make them optimization level
specific..

> 

> You're not saving --params per function but instead key on

> optimize[_{size,fast}].


Yep. We could also move all parameters to optimization attribute
and invent some tooling arond that, but we still want different
defaults for different optimization flags.
> 

> I'm not sure why there is a distiction between DEFPARAM_*

> and DEFPARAM_GLOBAL.  I'd have kept the existing DEFPARAM

> syntax like

> 

> DEFPARAM (PARAM_ALLOW_STORE_DATA_RACES,

>           "allow-store-data-races",

>           "Allow new data races on stores to be introduced.",

>           0, 0, 1)


I was concerned about definig different values based on optimization
level but then using PARAM_VALUE_GLOAL to retrieve the value
which would have unexpected effect.

We have parameters that are unavoidably global parameters of the
compiler, such as garbage collection parameters or things tied
to parsers that are not necessarily in known function level (yet).
> 

> which would set the default and then amend it with multiple

> 

> DEFPARAM_TUNING (PARAM_ALLOW_STORE_DATA_RACES, TUNE_Ofast, 1)

> 

> how does PARAM_VALUE_SET_FOR_FN work when a user cannot specify

> param values per function?  Does it say "yes" in case the

> function has 'optimize' attributes?


Parameters are saved in table depending on optimization levels and
function declaratoin provides its own settings of optimize,
optimize_size and optimize_Ofast.
> 

> Does it ever make sense to use PARAM_VALUE_GLOBAL?  I think

> we should always use PARAM_VALUE[_FOR_FN].


For example to set garbage collector parameters.

If you look into GLOBAL parameters in params.def there are some cases
where they can be turned to local if APIs are updated accordingly -
mostly in IPA area and I plan to work on that.  Also some of Asan stuff
probably.

There are also few things which affect compiler initialization
and should not if we want to make them per-function
(like alias oracle stuff).

I went with explicitly marking global parameter rather than
optimization level sensitive to make
> 

> That said, the situation looks somewhat incomplete when

> looking at the same issue in common.opt options?

> 

> I suppose the alternative was to embed (some) param values

> into the opts structure as streamed.  Where I think we need

> to go anyways with user supplied per CU --param specifications?

> So the patch below walks in a non-extensible direction?


If we want to drag parameters from translation time to link-time rather
then being able to fiddle with them at link time, then yes.
We would also need to specify what happens at the function boundary,
like during inlining.  We do have some semantics affecting parameters
like allow-store-data-races which would need to be matched.

Also unlike command line options, I think we have more global parameters
that definitly make sense to specify at link-time and should not be
carried over (like ggc paraters and probably also IPA optimization ones :)

At the moment parameters specified at compile time apply to all compile
process and at link-time to all stuff done at LTO. I see it is not
most transparent behaviour to users but the parameters are more or
less intended to tweak the compiler itself.

Honza
> 

> Thanks,

> Richard.

> 

> > 2019-06-11  Jan Hubicka  <hubicka@ucw.cz>

> > 

> > 	* cp/name-lookup.c (namespace_hints::namespace_hints): Use

> > 	PARAM_VALUE_GLOBAL.

> > 

> > 2019-06-11  Jan Hubicka  <hubicka@ucw.cz>

> > 

> > 	* lto/lto-partition.c (lto_balanced_map): Use PARAM_VALUE_GLOBAL.

> > 	* lto/lto.c (do_whole_program_analysis): Likewise.

> > 

> > 

> > ChangeLog:

> > 

> > 2019-06-11  Jan Hubicka  <hubicka@ucw.cz>

> > 

> > 	* params.def: Introduce DEFPARAM_GLOBAL, DEFPARAM_O2plus,

> > 	DEFPARAM_Ofast, DEFPARAM_Os.

> > 	* common.opt: param_values type is now struct param_vals.

> > 	* opts.c (init_options_struct): Update allocation of param_values.

> > 	(default_options_optimization): Move opt specific initialization of

> > 	PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP, PARAM_MAX_DSE_ACTIVE_LOCAL_STORES,

> > 	PARAM_ALLOW_STORE_DATA_RACES, PARAM_MIN_CROSSJUMP_INSNS to 

> > 	params.def; use GLOBAL_PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE instead

> > 	of PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE.

> > 	(print_filtered_help): Update.

> > 	(common_handle_option): Update handling of sanitize options.

> > 	* params-enum.h (DEFPARAM): Update.

> > 	(DEFPARAM_OPT, DEFPARAM_GLOBAL): New.

> > 	* params-list.h: (DEFPARAM): Update.

> > 	(DEFPARAM_OPT, DEFPARAM_GLOBAL): New.

> > 	* params-options.h: (DEFPARAM): Update.

> > 	(DEFPARAM_OPT, DEFPARAM_GLOBAL): New.

> > 	* params.c (INIT_VALUES): New macro.

> > 	(DEFPARAM): Update.

> > 	(DEFPARAM_OPT, DEFPARAM_GLOBAL): New.

> > 	(set_param_value_internal): Update.

> > 	(set_param_value_internal_index): New.

> > 	(validate_param): Update.

> > 	(set_param_value): Update.

> > 	(maybe_set_param_value): Update.

> > 	(set_default_param_value): Update.

> > 	(default_param_value): Update.

> > 	* params.h (NUM_PARAM_SETTINGS): Set to 6.

> > 	(struct param_vals): New structure.

> > 	(struct param_info): Change type of default_value to param_vals.

> > 	(param_value_index): Update prototype.

> > 	(extern void init_param_values): Update prototype.

> > 	(PARAM_VALUE_FOR_FN, PARAM_VALUE_SET_FOR_FN,

> > 	PARAM_VALUE_SET, PARAM_VALUE_GLOBAL, PARAM_VALUE_GLOBAL_SET): New

> > 	macros.

> > 	(PARAM_VALUE): Implement using PARAM_VALUE_SET_FOR_FN.

> > 	(param_value_index): New inline function.

> > 	(MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS, MAX_INLINE_SLOPE,

> > 	MIN_INLINE_INSNS, MAX_INLINE_INSNS_AUTO, MIN_VIRTUAL_MAPPINGS,

> > 	VIRTUAL_MAPPINGS_TO_SYMS_RATIO): Remove; update uses

> > 	by explicit PARAM_VALUE_FOR_FN.

> > 	(INTEGER_SHARE_LIMIT, MAX_FIELDS_FOR_FIELD_SENSITIVE,

> > 	USE_CANONICAL_TYPES, MIN_NONDEBUG_INSN_UID, ASAN_STACK,

> > 	ASAN_PROTECT_ALLOCAS, ASAN_GLOBALS, ASAN_INSTRUMENT_READS,

> > 	ASAN_INSTRUMENT_WRITES, ASAN_MEMINTRIN, ASAN_USE_AFTER_RETURN,

> > 	ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD): Use

> > 	PARAM_VALUE_GLOBAL.

> > 	* predict.c (get_hot_bb_threshold): Use PARAM_VALUE_GLOBAL.

> > 	(maybe_hot_count_p): Use PARAM_VALUE_GLOBAL.

> > 	(probably_never_executed): Use PARAM_VALUE_GLOBAL.

> > 	(predictable_edge_p): Use PARAM_VALUE_GLOBAL.

> > 	(handle_missing_profiles): Use PARAM_VALUE_GLOBAL.

> > 	* resource.c: Include tree.h.

> > 	* sched-ebb.c: Include tree.h.

> > 	* sched-rgn.c: Include tree.h.

> > 	* targhooks.c (default_max_noce_ifcvt_seq_cost): Use

> > 	PARAM_VALUE_SET.

> > 	* toplev.c (print_version): Use PARAM_VALUE_GLOBAL.

> > 	(process_options): Use PARAM_VALUE_GLOBAL.

> > 	* tree-sra.c (analyze_all_variable_accesses): USE PARAM_VALUE_SET.

> > 	(ipa_sra_preliminary_function_checks): Likewise.

> > 	* tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise.

> > 	* cgraph.c (cgraph_edge::maybe_hot_p): Likewise.

> > 	* coverage.c (get_coverage_counts): Likewise.

> > 	(coverage_compute_profile_id): Likewise.

> > 	(coverage_begin_function): Likewise.

> > 	(coverage_end_function): Likewise.

> > 	* cprop.c: Include tree.h

> > 	* fold-const.c (fold_range_test): Use PARAM_VALUE_GLOBAL.

> > 	(fold_truth_andor): likewise.

> > 	* ggc-page.c (ggc_collect): Use PARAM_VALUE_GLOBAL.

> > 	* haifa-sched.c: Include tree.h.

> > 	* hash-table.h: Use PARAM_VALUE_GLOBAL.

> > 	* ipa-cp.c (ipcp_lattice::add_value): Use PARAM_VALUE_FOR_FN.

> > 	(merge_agg_lats_step): Use PARAM_VALUE_GLOBAL.

> > 	(devirtualization_time_bonus): Use PARAM_VALUE_FOR_FN.

> > 	(hint_time_bonus): Use PARAM_VALUE_GLOBAL.

> > 	(incorporate_penalties): Use PARAM_VALUE_GLOBAL.

> > 	(good_cloning_opportunity_p): Use PARAM_VALUE_FOR_FN.

> > 	(ipcp_propagate_stage): Use PARAM_VALUE_FOR_FN.

> > 	* ipa-fnsummary.c (analyze_function_body): Use PARAM_VALUE_FOR_FN.

> > 	(compute_fn_summary): Use PARAM_VALUE_FOR_FN.

> > 	* ipa-inline-analysis.c (estimate_growth): Use PARAM_VALUE_FOR_FN.

> > 	* ipa-inline.c (caller_growth_limits): Use PARAM_VALUE_FOR_FN.

> > 	(can_inline_edge_by_limits_p): Use PARAM_VALUE_FOR_FN.

> > 	(want_early_inline_function_p): Use PARAM_VALUE_FOR_FN.

> > 	(big_speedup_p): Use PARAM_VALUE_FOR_FN.

> > 	(want_inline_small_function_p): Use PARAM_VALUE_FOR_FN.

> > 	(want_inline_self_recursive_call_p): Use PARAM_VALUE_FOR_FN.

> > 	(edge_badness): Use PARAM_VALUE_FOR_FN.

> > 	(recursive_inlining): Use PARAM_VALUE_FOR_FN.

> > 	(compute_max_insns): Use PARAM_VALUE_GLOBAL.

> > 	* ipa-profile.c (ipa_profile): Likewise.

> > 	* ipa-prop.c: (determine_locally_known_aggregate_parts): Use

> > 	PARAM_VALUE_GLOBAL

> > 	* ipa-split.c (consider_split): Use PARAM_VALUE.

> > 	* ira-build.c: Include tree.h

> > 	* ira-conflicts.c: Include tree.h

> > 

> > config/ChangeLog:

> > 

> > 2019-06-11  Jan Hubicka  <hubicka@ucw.cz>

> > 

> > 	* i386/i386.c (ix86_max_noce_ifcvt_seq_cost): Use PARAM_VALUE_SET.

> > 

> > Index: params.def

> > ===================================================================

> > --- params.def	(revision 272142)

> > +++ params.def	(working copy)

> > @@ -19,7 +19,8 @@ along with GCC; see the file COPYING3.

> >  <http://www.gnu.org/licenses/>.  */

> >  

> >  /* This file contains definitions for language-independent

> > -   parameters.  The DEFPARAM macro takes 6 arguments:

> > +   parameters.  Parameters that are independent of optimization level

> > +   are set by the DEFPARAM_GLOBAL macro takes 6 arguments:

> >  

> >       - The enumeral corresponding to this parameter.

> >  

> > @@ -35,12 +36,34 @@ along with GCC; see the file COPYING3.

> >       - The maximum acceptable value for the parameter (if greater than

> >       the minimum).

> >  

> > +   The DEFPARAM is same except that it declares parameter that may have

> > +   different values depends on optimization level.  Those are set by

> > +   DEFPARAM_O2plus, DEFPARAM_Ofast and DEFPARAM_Os which additionally

> > +   take extra argument specifying values for -O2+, -Ofast and -Os

> > +   respectively.

> > +

> >     The DEFPARAMENUM<N> macro is similar, but instead of the minumum and maximum

> >     arguments, it contains a list of <N> allowed strings, corresponding to

> >     integer values 0..<N>-1.  Note that the default argument needs to be

> >     specified as one of the allowed strings, rather than an integer value.

> >  

> > -   Be sure to add an entry to invoke.texi summarizing the parameter.  */

> > +   Be sure to add an entry to invoke.texi summarizing the parameter.

> > +

> > +   Values declared by DEFPARAM_GLOBAL are used via PARAM_VALUE_GLOBAL macro

> > +   whole other values are read by PARAM_VALUE.  */

> > +

> > +#define DEFPARAM(ENUM, OPTION, HELP, DEF, MIN, MAX) \

> > +	DEFPARAM_OPT (ENUM, OPTION, HELP, DEF, DEF, DEF, DEF, DEF, DEF, \

> > +		      MIN, MAX)

> > +#define DEFPARAM_O2plus(ENUM, OPTION, HELP, DEF, DEFO2, MIN, MAX) \

> > +	DEFPARAM_OPT (ENUM, OPTION, HELP, \

> > +		      DEF, DEFO2, DEFO2, DEFO2, DEF, DEFO2, MIN, MAX)

> > +#define DEFPARAM_Ofast(ENUM, OPTION, HELP, DEF, DEFOfast, MIN, MAX) \

> > +	DEFPARAM_OPT (ENUM, OPTION, HELP, \

> > +		      DEF, DEF, DEF, DEFOfast, DEF, DEF, MIN, MAX)

> > +#define DEFPARAM_Os(ENUM, OPTION, HELP, DEF, DEFOs, MIN, MAX) \

> > +	DEFPARAM_OPT (ENUM, OPTION, HELP, \

> > +		      DEF, DEF, DEF, DEF, DEFOs, DEFOs, MIN, MAX)

> >  

> >  /* When branch is predicted to be taken with probability lower than this

> >     threshold (in percent), then it is considered well predictable. */

> > @@ -219,15 +242,15 @@ DEFPARAM(PARAM_LARGE_FUNCTION_GROWTH,

> >  	 "large-function-growth",

> >  	 "Maximal growth due to inlining of large function (in percent).",

> >  	 100, 0, 0)

> > -DEFPARAM(PARAM_LARGE_UNIT_INSNS,

> > +DEFPARAM_GLOBAL(PARAM_LARGE_UNIT_INSNS,

> >  	 "large-unit-insns",

> >  	 "The size of translation unit to be considered large.",

> >  	 10000, 0, 0)

> > -DEFPARAM(PARAM_INLINE_UNIT_GROWTH,

> > +DEFPARAM_GLOBAL(PARAM_INLINE_UNIT_GROWTH,

> >  	 "inline-unit-growth",

> >  	 "How much can given compilation unit grow because of the inlining (in percent).",

> >  	 40, 0, 0)

> > -DEFPARAM(PARAM_IPCP_UNIT_GROWTH,

> > +DEFPARAM_GLOBAL(PARAM_IPCP_UNIT_GROWTH,

> >  	 "ipcp-unit-growth",

> >  	 "How much can given compilation unit grow because of the interprocedural constant propagation (in percent).",

> >  	 10, 0, 0)

> > @@ -425,12 +448,12 @@ DEFPARAM(PARAM_SMS_LOOP_AVERAGE_COUNT_TH

> >  	 "A threshold on the average loop count considered by the swing modulo scheduler.",

> >  	 0, 0, 0)

> >  

> > -DEFPARAM(HOT_BB_COUNT_FRACTION,

> > +DEFPARAM_GLOBAL(HOT_BB_COUNT_FRACTION,

> >  	 "hot-bb-count-fraction",

> >  	 "Select fraction of the maximal count of repetitions of basic block in program given basic "

> >  	 "block needs to have to be considered hot (used in non-LTO mode).",

> >  	 10000, 0, 0)

> > -DEFPARAM(HOT_BB_COUNT_WS_PERMILLE,

> > +DEFPARAM_GLOBAL(HOT_BB_COUNT_WS_PERMILLE,

> >  	 "hot-bb-count-ws-permille",

> >           "A basic block profile count is considered hot if it contributes to "

> >           "the given permillage of the entire profiled execution (used in LTO mode).",

> > @@ -440,7 +463,7 @@ DEFPARAM(HOT_BB_FREQUENCY_FRACTION,

> >  	 "Select fraction of the maximal frequency of executions of basic block in function given basic block needs to have to be considered hot.",

> >  	 1000, 0, 0)

> >  

> > -DEFPARAM(UNLIKELY_BB_COUNT_FRACTION,

> > +DEFPARAM_GLOBAL(UNLIKELY_BB_COUNT_FRACTION,

> >  	 "unlikely-bb-count-fraction",

> >           "The minimum fraction of profile runs a given basic block execution count must be not to be considered unlikely.",

> >  	 20, 1, 10000)

> > @@ -518,11 +541,12 @@ DEFPARAM(PARAM_MAX_CROSSJUMP_EDGES,

> >  	 "The maximum number of incoming edges to consider for crossjumping.",

> >  	 100, 0, 0)

> >  

> > -/* The minimum number of matching instructions to consider for crossjumping.  */

> > -DEFPARAM(PARAM_MIN_CROSSJUMP_INSNS,

> > +/* The minimum number of matching instructions to consider for crossjumping.

> > +   At -Os we want to crossjump as much as possible*/

> > +DEFPARAM_Os(PARAM_MIN_CROSSJUMP_INSNS,

> >       "min-crossjump-insns",

> >       "The minimum number of matching instructions to consider for crossjumping.",

> > -     5, 1, 0)

> > +     5, 1, 1, 0)

> >  

> >  /* The maximum number expansion factor when copying basic blocks.  */

> >  DEFPARAM(PARAM_MAX_GROW_COPY_BB_INSNS,

> > @@ -637,12 +661,12 @@ DEFPARAM(PARAM_MAX_CSELIB_MEMORY_LOCATIO

> >  # define GGC_MIN_HEAPSIZE_DEFAULT 4096

> >  #endif

> >  

> > -DEFPARAM(GGC_MIN_EXPAND,

> > +DEFPARAM_GLOBAL(GGC_MIN_EXPAND,

> >  	 "ggc-min-expand",

> >  	 "Minimum heap expansion to trigger garbage collection, as a percentage of the total size of the heap.",

> >  	 GGC_MIN_EXPAND_DEFAULT, 0, 0)

> >  

> > -DEFPARAM(GGC_MIN_HEAPSIZE,

> > +DEFPARAM_GLOBAL(GGC_MIN_HEAPSIZE,

> >  	 "ggc-min-heapsize",

> >  	 "Minimum heap size before we start collecting garbage, in kilobytes.",

> >  	 GGC_MIN_HEAPSIZE_DEFAULT, 0, 0)

> > @@ -744,7 +768,7 @@ DEFPARAM(PARAM_MAX_COMBINE_INSNS,

> >     {signed,unsigned} integral types.  This determines N.

> >     Experimentation shows 251 to be a good value that generates the

> >     least amount of garbage for allocating the TREE_VEC storage.  */

> > -DEFPARAM (PARAM_INTEGER_SHARE_LIMIT,

> > +DEFPARAM_GLOBAL (PARAM_INTEGER_SHARE_LIMIT,

> >  	  "integer-share-limit",

> >  	  "The upper bound for sharing integer constants.",

> >  	  251, 2, 2)

> > @@ -782,7 +806,7 @@ DEFPARAM (PARAM_MAX_JUMP_THREAD_DUPLICAT

> >     will stop trying to treat it in a field-sensitive manner.

> >     There are programs out there with thousands of fields per structure, and handling them

> >     field-sensitively is not worth the cost.  */

> > -DEFPARAM (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,

> > +DEFPARAM_GLOBAL (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,

> >            "max-fields-for-field-sensitive",

> >  	  "Maximum number of fields in a structure before pointer analysis treats the structure as a single variable.",

> >  	  0, 0, 0)

> > @@ -793,10 +817,10 @@ DEFPARAM(PARAM_MAX_SCHED_READY_INSNS,

> >  	 100, 1, 0)

> >  

> >  /* This is the maximum number of active local stores RTL DSE will consider.  */

> > -DEFPARAM (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES,

> > +DEFPARAM_O2plus (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES,

> >  	  "max-dse-active-local-stores",

> >  	  "Maximum number of active local stores in RTL dead store elimination.",

> > -	  5000, 0, 0)

> > +	  500, 5000, 0, 0)

> >  

> >  /* Prefetching and cache-optimizations related parameters.  Default values are

> >     usually set by machine description.  */

> > @@ -874,7 +898,7 @@ DEFPARAM (PARAM_LOOP_INTERCHANGE_STRIDE_

> >     this value should only be set to zero to work around bugs in the

> >     canonical type system by disabling it.  */

> >  

> > -DEFPARAM (PARAM_USE_CANONICAL_TYPES,

> > +DEFPARAM_GLOBAL (PARAM_USE_CANONICAL_TYPES,

> >  	  "use-canonical-types",

> >  	  "Whether to use canonical types.",

> >  	  1, 0, 1)

> > @@ -979,15 +1003,15 @@ DEFPARAM (PARAM_LOOP_MAX_DATAREFS_FOR_DA

> >  

> >  /* Avoid doing loop invariant motion on very large loops.  */

> >  

> > -DEFPARAM (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,

> > +DEFPARAM_O2plus (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,

> >  	  "loop-invariant-max-bbs-in-loop",

> >  	  "Max basic blocks number in loop for loop invariant motion.",

> > -	  10000, 0, 0)

> > +	  1000, 10000, 0, 0)

> >  

> >  /* When the parameter is 1, use the internal function id

> >     to look up for profile data. Otherwise, use a more stable

> >     external id based on assembler name and source location. */

> > -DEFPARAM (PARAM_PROFILE_FUNC_INTERNAL_ID,

> > +DEFPARAM_GLOBAL (PARAM_PROFILE_FUNC_INTERNAL_ID,

> >  	  "profile-func-internal-id",

> >  	  "Use internal function id in profile lookup.",

> >  	  0, 0, 1)

> > @@ -1043,7 +1067,7 @@ DEFPARAM (PARAM_MAX_DEBUG_MARKER_COUNT,

> >  

> >  /* Set minimum insn uid for non-debug insns.  */

> >  

> > -DEFPARAM (PARAM_MIN_NONDEBUG_INSN_UID,

> > +DEFPARAM_GLOBAL (PARAM_MIN_NONDEBUG_INSN_UID,

> >  	  "min-nondebug-insn-uid",

> >  	  "The minimum UID to be used for a nondebug insn.",

> >  	  0, 0, 0)

> > @@ -1085,31 +1109,31 @@ DEFPARAM (PARAM_IPA_CP_EVAL_THRESHOLD,

> >  	  "beneficial to clone.",

> >  	  500, 0, 0)

> >  

> > -DEFPARAM (PARAM_IPA_CP_RECURSION_PENALTY,

> > +DEFPARAM_GLOBAL (PARAM_IPA_CP_RECURSION_PENALTY,

> >  	  "ipa-cp-recursion-penalty",

> >  	  "Percentage penalty the recursive functions will receive when they "

> >  	  "are evaluated for cloning.",

> >  	  40, 0, 100)

> >  

> > -DEFPARAM (PARAM_IPA_CP_SINGLE_CALL_PENALTY,

> > +DEFPARAM_GLOBAL (PARAM_IPA_CP_SINGLE_CALL_PENALTY,

> >  	  "ipa-cp-single-call-penalty",

> >  	  "Percentage penalty functions containing a single call to another "

> >  	  "function will receive when they are evaluated for cloning.",

> >  	  15, 0, 100)

> >  

> > -DEFPARAM (PARAM_IPA_MAX_AGG_ITEMS,

> > +DEFPARAM_GLOBAL (PARAM_IPA_MAX_AGG_ITEMS,

> >  	  "ipa-max-agg-items",

> >  	  "Maximum number of aggregate content items for a parameter in "

> >  	  "jump functions and lattices.",

> >  	  16, 0, 0)

> >  

> > -DEFPARAM (PARAM_IPA_CP_LOOP_HINT_BONUS,

> > +DEFPARAM_GLOBAL (PARAM_IPA_CP_LOOP_HINT_BONUS,

> >  	  "ipa-cp-loop-hint-bonus",

> >  	  "Compile-time bonus IPA-CP assigns to candidates which make loop "

> >  	  "bounds or strides known.",

> >  	  64, 0, 0)

> >  

> > -DEFPARAM (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS,

> > +DEFPARAM_GLOBAL (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS,

> >  	  "ipa-cp-array-index-hint-bonus",

> >  	  "Compile-time bonus IPA-CP assigns to candidates which make an array "

> >  	  "index known.",

> > @@ -1123,29 +1147,29 @@ DEFPARAM (PARAM_IPA_MAX_AA_STEPS,

> >  

> >  /* WHOPR partitioning configuration.  */

> >  

> > -DEFPARAM (PARAM_LTO_PARTITIONS,

> > +DEFPARAM_GLOBAL (PARAM_LTO_PARTITIONS,

> >  	  "lto-partitions",

> >  	  "Number of partitions the program should be split to.",

> >  	  128, 1, 0)

> >  

> > -DEFPARAM (MIN_PARTITION_SIZE,

> > +DEFPARAM_GLOBAL (MIN_PARTITION_SIZE,

> >  	  "lto-min-partition",

> >  	  "Minimal size of a partition for LTO (in estimated instructions).",

> >  	  10000, 0, 0)

> >  

> > -DEFPARAM (MAX_PARTITION_SIZE,

> > +DEFPARAM_GLOBAL (MAX_PARTITION_SIZE,

> >  	  "lto-max-partition",

> >  	  "Maximal size of a partition for LTO (in estimated instructions).",

> >  	  1000000, 0, INT_MAX)

> >  

> > -DEFPARAM (PARAM_MAX_LTO_STREAMING_PARALLELISM,

> > +DEFPARAM_GLOBAL (PARAM_MAX_LTO_STREAMING_PARALLELISM,

> >  	  "lto-max-streaming-parallelism",

> >  	  "maximal number of LTO partitions streamed in parallel.",

> >  	  32, 1, 0)

> >  

> >  /* Diagnostic parameters.  */

> >  

> > -DEFPARAM (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP,

> > +DEFPARAM_GLOBAL (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP,

> >  	  "cxx-max-namespaces-for-diagnostic-help",

> >  	  "Maximum number of namespaces to search for alternatives when "

> >  	  "name lookup fails.",

> > @@ -1181,11 +1205,12 @@ DEFPARAM (PARAM_JUMP_TABLE_MAX_GROWTH_RA

> >  	  "optimizing for speed.",

> >  	  800, 0, 0)

> >  

> > -/* Data race flags for C++0x memory model compliance.  */

> > -DEFPARAM (PARAM_ALLOW_STORE_DATA_RACES,

> > +/* Data race flags for C++0x memory model compliance.

> > +   Allow them only for Ofast  */

> > +DEFPARAM_Ofast (PARAM_ALLOW_STORE_DATA_RACES,

> >  	  "allow-store-data-races",

> >  	  "Allow new data races on stores to be introduced.",

> > -	  0, 0, 1)

> > +	  0, 1, 0, 1)

> >  

> >  /* Reassociation width to be used by tree reassoc optimization.  */

> >  DEFPARAM (PARAM_TREE_REASSOC_WIDTH,

> > @@ -1244,42 +1269,42 @@ DEFPARAM (PARAM_MAX_SLSR_CANDIDATE_SCAN,

> >  

> >  /* ASan stands for AddressSanitizer: https://github.com/google/sanitizers.  */

> >  

> > -DEFPARAM (PARAM_ASAN_STACK,

> > +DEFPARAM_GLOBAL (PARAM_ASAN_STACK,

> >           "asan-stack",

> >           "Enable asan stack protection.",

> >           1, 0, 1)

> >  

> > -DEFPARAM (PARAM_ASAN_PROTECT_ALLOCAS,

> > +DEFPARAM_GLOBAL (PARAM_ASAN_PROTECT_ALLOCAS,

> >  	"asan-instrument-allocas",

> >  	"Enable asan allocas/VLAs protection.",

> >  	1, 0, 1)

> >  

> > -DEFPARAM (PARAM_ASAN_GLOBALS,

> > +DEFPARAM_GLOBAL (PARAM_ASAN_GLOBALS,

> >           "asan-globals",

> >           "Enable asan globals protection.",

> >           1, 0, 1)

> >  

> > -DEFPARAM (PARAM_ASAN_INSTRUMENT_WRITES,

> > +DEFPARAM_GLOBAL (PARAM_ASAN_INSTRUMENT_WRITES,

> >           "asan-instrument-writes",

> >           "Enable asan store operations protection.",

> >           1, 0, 1)

> >  

> > -DEFPARAM (PARAM_ASAN_INSTRUMENT_READS,

> > +DEFPARAM_GLOBAL (PARAM_ASAN_INSTRUMENT_READS,

> >           "asan-instrument-reads",

> >           "Enable asan load operations protection.",

> >           1, 0, 1)

> >  

> > -DEFPARAM (PARAM_ASAN_MEMINTRIN,

> > +DEFPARAM_GLOBAL (PARAM_ASAN_MEMINTRIN,

> >           "asan-memintrin",

> >           "Enable asan builtin functions protection.",

> >           1, 0, 1)

> >  

> > -DEFPARAM (PARAM_ASAN_USE_AFTER_RETURN,

> > +DEFPARAM_GLOBAL (PARAM_ASAN_USE_AFTER_RETURN,

> >           "asan-use-after-return",

> >           "Enable asan detection of use-after-return bugs.",

> >           1, 0, 1)

> >  

> > -DEFPARAM (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,

> > +DEFPARAM_GLOBAL (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,

> >           "asan-instrumentation-with-call-threshold",

> >           "Use callbacks instead of inline code if number of accesses "

> >           "in function becomes greater or equal to this number.",

> > @@ -1407,7 +1432,7 @@ DEFPARAM(PARAM_AVOID_FMA_MAX_BITS,

> >  	 "Maximum number of bits for which we avoid creating FMAs.",

> >  	 0, 0, 512)

> >  

> > -DEFPARAM(PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT,

> > +DEFPARAM_GLOBAL(PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT,

> >  	 "logical-op-non-short-circuit",

> >  	 "True if a non-short-circuit operation is optimal.",

> >  	 -1, -1, 1)

> > @@ -1431,12 +1456,13 @@ DEFPARAM(PARAM_GIMPLE_FE_COMPUTED_HOT_BB

> >  	 " The parameter is used only in GIMPLE FE.",

> >  	 0, 0, 0)

> >  

> > -DEFPARAM(PARAM_HASH_TABLE_VERIFICATION_LIMIT,

> > +DEFPARAM_GLOBAL(PARAM_HASH_TABLE_VERIFICATION_LIMIT,

> >  	 "hash-table-verification-limit",

> >  	 "The number of elements for which hash table verification is done for "

> >  	 "each searched element.",

> >  	 100, 0, 0)

> >  

> > +#undef DEFPARAM

> >  /*

> >  

> >  Local variables:

> > Index: common.opt

> > ===================================================================

> > --- common.opt	(revision 272142)

> > +++ common.opt	(working copy)

> > @@ -64,7 +64,7 @@ Variable

> >  bool flag_warn_unused_result = false

> >  

> >  Variable

> > -int *param_values

> > +struct param_vals *param_values

> >  

> >  ; Nonzero if we should write GIMPLE bytecode for link-time optimization.

> >  Variable

> > Index: opts.c

> > ===================================================================

> > --- opts.c	(revision 272142)

> > +++ opts.c	(working copy)

> > @@ -292,10 +292,10 @@ init_options_struct (struct gcc_options

> >    if (opts_set)

> >      memset (opts_set, 0, sizeof (*opts_set));

> >  

> > -  opts->x_param_values = XNEWVEC (int, num_params);

> > +  opts->x_param_values = XNEWVEC (struct param_vals, num_params);

> >  

> >    if (opts_set)

> > -    opts_set->x_param_values = XCNEWVEC (int, num_params);

> > +    opts_set->x_param_values = XCNEWVEC (struct param_vals, num_params);

> >  

> >    init_param_values (opts->x_param_values);

> >  

> > @@ -664,41 +664,10 @@ default_options_optimization (struct gcc

> >  

> >    /* Track fields in field-sensitive alias analysis.  */

> >    maybe_set_param_value

> > -    (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,

> > -     opt2 ? 100 : default_param_value (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE),

> > +    (GLOBAL_PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,

> > +     opt2 ? 100 : default_param_value (GLOBAL_PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE),

> >       opts->x_param_values, opts_set->x_param_values);

> >  

> > -  /* For -O1 only do loop invariant motion for very small loops.  */

> > -  maybe_set_param_value

> > -    (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,

> > -     opt2 ? default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP)

> > -     : default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) / 10,

> > -     opts->x_param_values, opts_set->x_param_values);

> > -

> > -  /* For -O1 reduce the maximum number of active local stores for RTL DSE

> > -     since this can consume huge amounts of memory (PR89115).  */

> > -  maybe_set_param_value

> > -    (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES,

> > -     opt2 ? default_param_value (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES)

> > -     : default_param_value (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES) / 10,

> > -     opts->x_param_values, opts_set->x_param_values);

> > -

> > -  /* At -Ofast, allow store motion to introduce potential race conditions.  */

> > -  maybe_set_param_value

> > -    (PARAM_ALLOW_STORE_DATA_RACES,

> > -     opts->x_optimize_fast ? 1

> > -     : default_param_value (PARAM_ALLOW_STORE_DATA_RACES),

> > -     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);

> > -

> >    /* Restrict the amount of work combine does at -Og while retaining

> >       most of its useful transforms.  */

> >    if (opts->x_optimize_debug)

> > @@ -1330,7 +1299,7 @@ print_filtered_help (unsigned int includ

> >  	    {

> >  	      snprintf (new_help, sizeof (new_help),

> >  			_("default %d minimum %d maximum %d"),

> > -			compiler_params[i].default_value,

> > +			compiler_params[i].default_value.val[0],

> >  			compiler_params[i].min_value,

> >  			compiler_params[i].max_value);

> >  	      help = new_help;

> > @@ -2273,17 +2242,19 @@ common_handle_option (struct gcc_options

> >  	 all features.  */

> >        if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)

> >  	{

> > -	  maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,

> > +	  maybe_set_param_value (GLOBAL_PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,

> >  				 0, opts->x_param_values,

> >  				 opts_set->x_param_values);

> > -	  maybe_set_param_value (PARAM_ASAN_GLOBALS, 0, opts->x_param_values,

> > +	  maybe_set_param_value (GLOBAL_PARAM_ASAN_GLOBALS, 0,

> > +				 opts->x_param_values,

> >  				 opts_set->x_param_values);

> > -	  maybe_set_param_value (PARAM_ASAN_STACK, 0, opts->x_param_values,

> > +	  maybe_set_param_value (GLOBAL_PARAM_ASAN_STACK, 0,

> > +				 opts->x_param_values,

> >  				 opts_set->x_param_values);

> > -	  maybe_set_param_value (PARAM_ASAN_PROTECT_ALLOCAS, 0,

> > +	  maybe_set_param_value (GLOBAL_PARAM_ASAN_PROTECT_ALLOCAS, 0,

> >  				 opts->x_param_values,

> >  				 opts_set->x_param_values);

> > -	  maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0,

> > +	  maybe_set_param_value (GLOBAL_PARAM_ASAN_USE_AFTER_RETURN, 0,

> >  				 opts->x_param_values,

> >  				 opts_set->x_param_values);

> >  	}

> > Index: params-enum.h

> > ===================================================================

> > --- params-enum.h	(revision 272142)

> > +++ params-enum.h	(working copy)

> > @@ -17,7 +17,9 @@ You should have received a copy of the G

> >  along with GCC; see the file COPYING3.  If not see

> >  <http://www.gnu.org/licenses/>.  */

> >  

> > -#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)

> > +#define DEFPARAM_OPT(ENUM, OPTION, HELP, DEFO1, DEFO2, DEFO3, DEFOfast,\

> > +		     DEFOsO1, DEFOsO2, MIN, MAX)

> > +#define DEFPARAM_GLOBAL(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)

> >  #define DEFPARAMENUMNAME(ENUM) ENUM ## _KIND

> >  #define DEFPARAMENUMVAL(ENUM, V) ENUM ## _KIND_ ## V

> >  #define DEFPARAMENUMTERM(ENUM) ENUM ## _KIND_ ## LAST

> > @@ -36,4 +38,5 @@ along with GCC; see the file COPYING3.

> >  #undef DEFPARAMENUMTERM

> >  #undef DEFPARAMENUMVAL

> >  #undef DEFPARAMENUMNAME

> > -#undef DEFPARAM

> > +#undef DEFPARAM_OPT

> > +#undef DEFPARAM_GLOBAL

> > Index: params-list.h

> > ===================================================================

> > --- params-list.h	(revision 272142)

> > +++ params-list.h	(working copy)

> > @@ -17,10 +17,14 @@ You should have received a copy of the G

> >  along with GCC; see the file COPYING3.  If not see

> >  <http://www.gnu.org/licenses/>.  */

> >  

> > -#define DEFPARAM(enumerator, option, nocmsgid, default, min, max) \

> > +#define DEFPARAM_OPT(enumerator, option, nocmsgid, DEFO1, DEFO2, DEFO3, \

> > +		     DEFOfast, DEFOsO1, DEFOsO2, min, max) \

> >    enumerator,

> > +#define DEFPARAM_GLOBAL(enumerator, option, nocmsgid, default, min, max) \

> > +  GLOBAL_##enumerator,

> >  #define DEFPARAMENUM5(enumerator, option, nocmsgid, default, \

> >  		      v0, v1, v2, v3, v4) enumerator,

> >  #include "params.def"

> > -#undef DEFPARAM

> > +#undef DEFPARAM_OPT

> > +#undef DEFPARAM_GLOBAL

> >  #undef DEFPARAMENUM5

> > Index: params-options.h

> > ===================================================================

> > --- params-options.h	(revision 272142)

> > +++ params-options.h	(working copy)

> > @@ -17,11 +17,13 @@ You should have received a copy of the G

> >  along with GCC; see the file COPYING3.  If not see

> >  <http://www.gnu.org/licenses/>.  */

> >  

> > -#define DEFPARAM(enumerator, option, nocmsgid, default, min, max) \

> > +#define DEFPARAM(enumerator, option, nocmsgid, defO1, defO2, defO3, defOfast, \

> > +		 defOs, defOsO1, min, max) \

> >    option=default,min,max

> >  #define DEFPARAMENUM5(enumerator, option, nocmsgid, default, \

> >  		      v0, v1, v2, v3, v4) \

> >    option=v0,v1,v2,v3,v4

> >  #include "params.def"

> > -#undef DEFPARAM

> > +#undef DEFPARAM_OPT

> > +#undef DEFPARAM_GLOBAL

> >  #undef DEFPARAMENUM5

> > Index: params.c

> > ===================================================================

> > --- params.c	(revision 272142)

> > +++ params.c	(working copy)

> > @@ -28,6 +28,8 @@ along with GCC; see the file COPYING3.

> >  #include "diagnostic.h"

> >  #include "spellcheck.h"

> >  

> > +#define INIT_VALUES(VAL) {{(VAL), (VAL), (VAL), (VAL), (VAL), (VAL)}}

> > +

> >  /* An array containing the compiler parameters and their current

> >     values.  */

> >  

> > @@ -40,27 +42,36 @@ static size_t num_compiler_params;

> >     default values determined.  */

> >  static bool params_finished;

> >  

> > -#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)

> > +#define DEFPARAM_OPT(ENUM, OPTION, HELP, DEFO1, DEFO2, DEFO3, DEFOfast, \

> > +		     DEFOsO1, DEFOsO2, MIN, MAX)

> > +#define DEFPARAM_GLOBAL(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)

> >  #define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT, V0, V1, V2, V3, V4)	\

> >    static const char *values_ ## ENUM [] = { #V0, #V1, #V2, #V3, #V4, NULL };

> >  #include "params.def"

> >  #undef DEFPARAMENUM5

> > -#undef DEFPARAM

> > +#undef DEFPARAM_OPT

> > +#undef DEFPARAM_GLOBAL

> >  

> >  static const param_info lang_independent_params[] = {

> > -#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX) \

> > -  { OPTION, DEFAULT, MIN, MAX, HELP, NULL },

> > +#define DEFPARAM_GLOBAL(ENUM, OPTION, HELP, DEFAULT, MIN, MAX) \

> > +  { OPTION, {DEFAULT, DEFAULT, DEFAULT, DEFAULT}, MIN, MAX, HELP, NULL },

> > +#define DEFPARAM_OPT(ENUM, OPTION, HELP, DEFO1, DEFO2, DEFO3, DEFOfast, \

> > +		     DEFOsO1, DEFOsO2, MIN, MAX) \

> > +  { OPTION, \

> > +   {DEFO1, DEFO2, DEFO3, DEFOfast, DEFOsO1, DEFOsO2}, MIN, MAX, HELP, NULL },

> >  #define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT,	     \

> >  		      V0, V1, V2, V3, V4)		     \

> > -  { OPTION, (int)ENUM ## _KIND_ ## DEFAULT, 0, 4, HELP, values_ ## ENUM },

> > +  { OPTION, INIT_VALUES((int)ENUM ## _KIND_ ## DEFAULT),     \

> > +    0, 4, HELP, values_ ## ENUM },

> >  #include "params.def"

> > -#undef DEFPARAM

> > +#undef DEFPARAM_OPT

> >  #undef DEFPARAMENUM5

> > -  { NULL, 0, 0, 0, NULL, NULL }

> > +  { NULL, INIT_VALUES (0), 0, 0, NULL, NULL }

> >  };

> >  

> >  static bool

> > -validate_param (const int value, const param_info param, const int index);

> > +validate_param (const struct param_vals values,

> > +		const param_info param, const int index);

> >  

> >  

> >  /* Add the N PARAMS to the current list of compiler parameters.  */

> > @@ -131,40 +142,66 @@ params_c_finalize (void)

> >     otherwise it is being set implicitly by the compiler.  */

> >  

> >  static void

> > -set_param_value_internal (compiler_param num, int value,

> > -			  int *params, int *params_set,

> > +set_param_value_internal (compiler_param num, struct param_vals value,

> > +			  struct param_vals *params, 

> > +			  struct param_vals *params_set,

> >  			  bool explicit_p)

> >  {

> > +  param_vals true_vals = INIT_VALUES (true);

> > +

> >    size_t i = (size_t) num;

> >  

> >    gcc_assert (params_finished);

> >  

> >    params[i] = value;

> >    if (explicit_p)

> > -    params_set[i] = true;

> > +    params_set[i] = true_vals;

> > +}

> > +

> > +/* Same as set_param_value_inter but set only value for given INDEX.  */

> > +

> > +static void

> > +set_param_value_internal_index (compiler_param num, int index,

> > +				int value,

> > +			        struct param_vals *params, 

> > +			        struct param_vals *params_set,

> > +				bool explicit_p)

> > +{

> > +  size_t i = (size_t) num;

> > +

> > +  gcc_assert (params_finished);

> > +

> > +  params[i].val[index] = value;

> > +  if (explicit_p)

> > +    params_set[i].val[index] = true;

> >  }

> >  

> >  /* Validate PARAM and write an error if invalid.  */

> >  

> >  static bool

> > -validate_param (const int value, const param_info param, const int index)

> > +validate_param (const struct param_vals values,

> > +	        const param_info param, const int index)

> >  {

> > -  /* These paremeters interpret bounds of 0 to be unbounded, as such don't

> > -     perform any range validation on 0 parameters.  */

> > -  if (value < param.min_value && param.min_value != 0)

> > +  for (int i = 0; i < NUM_PARAM_SETTINGS; i++)

> >      {

> > -      error ("minimum value of parameter %qs is %u",

> > -	     param.option, param.min_value);

> > -      return false;

> > -    }

> > -  else if (param.max_value > param.min_value && value > param.max_value)

> > -    {

> > -      error ("maximum value of parameter %qs is %u",

> > -	     param.option, param.max_value);

> > -      return false;

> > -    }

> > -  else if (targetm_common.option_validate_param (value, index))

> > -    return true;

> > +      int value = values.val[i];

> > +      /* These paremeters interpret bounds of 0 to be unbounded, as such don't

> > +	 perform any range validation on 0 parameters.  */

> > +      if (value < param.min_value && param.min_value != 0)

> > +	{

> > +	  error ("minimum value of parameter %qs is %u",

> > +		 param.option, param.min_value);

> > +	  return false;

> > +	}

> > +      else if (param.max_value > param.min_value && value > param.max_value)

> > +	{

> > +	  error ("maximum value of parameter %qs is %u",

> > +		 param.option, param.max_value);

> > +	  return false;

> > +	}

> > +      else if (targetm_common.option_validate_param (value, index))

> > +	return true;

> > +   }

> >  

> >    return false;

> >  }

> > @@ -226,9 +263,11 @@ param_string_value_p (enum compiler_para

> >  

> >  void

> >  set_param_value (const char *name, int value,

> > -		 int *params, int *params_set)

> > +		 struct param_vals *params, 

> > +		 struct param_vals *params_set)

> >  {

> >    size_t i;

> > +  struct param_vals values = INIT_VALUES (value);

> >  

> >    /* Make sure nobody tries to set a parameter to an invalid value.  */

> >    gcc_assert (value != INVALID_PARAM_VAL);

> > @@ -242,8 +281,8 @@ set_param_value (const char *name, int v

> >      }

> >    i = (size_t)index;

> >  

> > -  if (validate_param (value, compiler_params[i], i))

> > -    set_param_value_internal ((compiler_param) i, value,

> > +  if (validate_param (values, compiler_params[i], i))

> > +    set_param_value_internal ((compiler_param) i, values,

> >  			      params, params_set, true);

> >  }

> >  

> > @@ -253,10 +292,13 @@ set_param_value (const char *name, int v

> >  

> >  void

> >  maybe_set_param_value (compiler_param num, int value,

> > -		       int *params, int *params_set)

> > +		       struct param_vals *params, 

> > +		       struct param_vals *params_set)

> >  {

> > -  if (!params_set[(int) num])

> > -    set_param_value_internal (num, value, params, params_set, false);

> > +  for (int index = 0; index < NUM_PARAM_SETTINGS; index++)

> > +    if (!params_set[(int) num].val[index])

> > +      set_param_value_internal_index (num, index, value, params,

> > +				      params_set, false);

> >  }

> >  

> >  /* Set the default value of a parameter given by NUM to VALUE, before

> > @@ -265,9 +307,10 @@ maybe_set_param_value (compiler_param nu

> >  void

> >  set_default_param_value (compiler_param num, int value)

> >  {

> > +  struct param_vals vals = INIT_VALUES (value);

> >    gcc_assert (!params_finished);

> >  

> > -  compiler_params[(int) num].default_value = value;

> > +  compiler_params[(int) num].default_value = vals;

> >  }

> >  

> >  /* Return the default value of parameter NUM.  */

> > @@ -275,14 +318,14 @@ set_default_param_value (compiler_param

> >  int

> >  default_param_value (compiler_param num)

> >  {

> > -  return compiler_params[(int) num].default_value;

> > +  return compiler_params[(int) num].default_value.val[0];

> >  }

> >  

> >  /* Initialize an array PARAMS with default values of the

> >     parameters.  */

> >  

> >  void

> > -init_param_values (int *params)

> > +init_param_values (struct param_vals *params)

> >  {

> >    size_t i;

> >  

> > Index: params.h

> > ===================================================================

> > --- params.h	(revision 272142)

> > +++ params.h	(working copy)

> > @@ -32,10 +32,19 @@ along with GCC; see the file COPYING3.

> >  #ifndef GCC_PARAMS_H

> >  #define GCC_PARAMS_H

> >  

> > +#define NUM_PARAM_SETTINGS 6

> > +

> >  /* No parameter shall have this value.  */

> >  

> >  #define INVALID_PARAM_VAL (-1)

> >  

> > +/* Default values for given param.  */

> > +

> > +struct param_vals

> > +{

> > +  int val[NUM_PARAM_SETTINGS];

> > +};

> > +

> >  /* The information associated with each parameter.  */

> >  

> >  struct param_info

> > @@ -45,7 +54,7 @@ struct param_info

> >    const char *option;

> >  

> >    /* The default value.  */

> > -  int default_value;

> > +  struct param_vals default_value;

> >  

> >    /* Minimum acceptable value.  */

> >    int min_value;

> > @@ -77,7 +86,8 @@ extern void add_params (const param_info

> >     explicitly set.  */

> >  

> >  extern void set_param_value (const char *name, int value,

> > -			     int *params, int *params_set);

> > +			     struct param_vals *params,

> > +			     struct param_vals *params_set);

> >  

> >  

> >  /* The parameters in use by language-independent code.  */

> > @@ -92,16 +102,56 @@ extern bool find_param (const char *, en

> >  extern const char *find_param_fuzzy (const char *name);

> >  extern bool param_string_value_p (enum compiler_param, const char *, int *);

> >  

> > -/* The value of the parameter given by ENUM.  Not an lvalue.  */

> > -#define PARAM_VALUE(ENUM) \

> > -  ((int) global_options.x_param_values[(int) ENUM])

> > +/* Return index into param values for optimization setting of the function FUN:

> > +   0 for -O0, -O1 and when optimization level is unknown.

> > +   1 for -O2

> > +   2 for -O3

> > +   3 for -Ofast

> > +   4 for -Os -O1. 

> > +   5 for -Os -O2+.  */

> > +inline int

> > +param_value_index (bool opt_size, int opt_level, bool opt_fast)

> > +{

> > +  if (opt_size)

> > +    return opt_level <= 1 ? 4 : 5;

> > +  if (opt_fast)

> > +    return 3;

> > +  return MAX (MIN (opt_level-1, 2), 0);

> > +}

> > +

> > +/* The value of the optimization level specific

> > +   parameter given by ENUM.  Not an lvalue.  */

> > +#define PARAM_VALUE_FOR_FN(FUN, ENUM)					     \

> > +  ((int) global_options.x_param_values 					     \

> > + 	 [(int) ENUM].val[param_value_index (opt_for_fn (FUN, optimize_size),\

> > +					     opt_for_fn (FUN, optimize),     \

> > +					     opt_for_fn (FUN, optimize_fast))])

> > +/* True if optimization level specific parameter given by ENUM is set.  */

> > +#define PARAM_VALUE_SET_FOR_FN(FUN, ENUM)				     \

> > +  ((int) global_options_set.x_param_values 				     \

> > + 	 [(int) ENUM].val[param_value_index (opt_for_fn (FUN, optimize_size),\

> > +					     opt_for_fn (FUN, optimize),     \

> > +					     opt_for_fn (FUN, optimize_fast))])

> > +

> > +/* The value of the optimization level specific

> > +   parameter given by ENUM.  Not an lvalue.  */

> > +#define PARAM_VALUE(ENUM) 						     \

> > +  PARAM_VALUE_FOR_FN(current_function_decl, ENUM)

> > +/* True if optimization level specific parameter given by ENUM is set.  */

> > +#define PARAM_VALUE_SET(ENUM) 						     \

> > +  PARAM_VALUE_SET_FOR_FN(current_function_decl, ENUM)

> > +#define PARAM_VALUE_GLOBAL(ENUM) 					     \

> > +  ((int) global_options.x_param_values [(int) GLOBAL_##ENUM].val[0])

> > +#define PARAM_VALUE_GLOBAL_SET(ENUM) 						     \

> > +  ((int) global_options_set.x_param_values [(int) GLOBAL_##ENUM].val[0])

> >  

> >  /* Set the value of the parameter given by NUM to VALUE, implicitly,

> >     if it has not been set explicitly by the user, in the table PARAMS

> >     using PARAMS_SET to indicate which have been explicitly set.  */

> >  

> >  extern void maybe_set_param_value (compiler_param num, int value,

> > -				   int *params, int *params_set);

> > +				   struct param_vals *params,

> > +				   struct param_vals *params_set);

> >  

> >  /* Set the default value of a parameter given by NUM to VALUE, before

> >     option processing.  */

> > @@ -127,19 +177,9 @@ extern int default_param_value (compiler

> >  

> >  /* Initialize an array PARAMS with default values of the

> >     parameters.  */

> > -extern void init_param_values (int *params);

> > +extern void init_param_values (struct param_vals *params);

> >  

> >  /* Macros for the various parameters.  */

> > -#define MAX_INLINE_INSNS_SINGLE \

> > -  PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE)

> > -#define MAX_INLINE_INSNS \

> > -  PARAM_VALUE (PARAM_MAX_INLINE_INSNS)

> > -#define MAX_INLINE_SLOPE \

> > -  PARAM_VALUE (PARAM_MAX_INLINE_SLOPE)

> > -#define MIN_INLINE_INSNS \

> > -  PARAM_VALUE (PARAM_MIN_INLINE_INSNS)

> > -#define MAX_INLINE_INSNS_AUTO \

> > -  PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO)

> >  #define MAX_VARIABLE_EXPANSIONS \

> >    PARAM_VALUE (PARAM_MAX_VARIABLE_EXPANSIONS)

> >  #define MIN_VECT_LOOP_BOUND \

> > @@ -175,15 +215,11 @@ extern void init_param_values (int *para

> >  #define SMS_LOOP_AVERAGE_COUNT_THRESHOLD \

> >    PARAM_VALUE (PARAM_SMS_LOOP_AVERAGE_COUNT_THRESHOLD)

> >  #define INTEGER_SHARE_LIMIT \

> > -  PARAM_VALUE (PARAM_INTEGER_SHARE_LIMIT)

> > +  PARAM_VALUE_GLOBAL (PARAM_INTEGER_SHARE_LIMIT)

> >  #define MAX_LAST_VALUE_RTL \

> >    PARAM_VALUE (PARAM_MAX_LAST_VALUE_RTL)

> > -#define MIN_VIRTUAL_MAPPINGS \

> > -  PARAM_VALUE (PARAM_MIN_VIRTUAL_MAPPINGS)

> > -#define VIRTUAL_MAPPINGS_TO_SYMS_RATIO \

> > -  PARAM_VALUE (PARAM_VIRTUAL_MAPPINGS_TO_SYMS_RATIO)

> >  #define MAX_FIELDS_FOR_FIELD_SENSITIVE \

> > -  ((size_t) PARAM_VALUE (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE))

> > +  ((size_t) PARAM_VALUE_GLOBAL (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE))

> >  #define MAX_SCHED_READY_INSNS \

> >    PARAM_VALUE (PARAM_MAX_SCHED_READY_INSNS)

> >  #define PREFETCH_LATENCY \

> > @@ -201,7 +237,7 @@ extern void init_param_values (int *para

> >  #define PREFETCH_MINIMUM_STRIDE \

> >    PARAM_VALUE (PARAM_PREFETCH_MINIMUM_STRIDE)

> >  #define USE_CANONICAL_TYPES \

> > -  PARAM_VALUE (PARAM_USE_CANONICAL_TYPES)

> > +  PARAM_VALUE_GLOBAL (PARAM_USE_CANONICAL_TYPES)

> >  #define IRA_MAX_LOOPS_NUM \

> >    PARAM_VALUE (PARAM_IRA_MAX_LOOPS_NUM)

> >  #define IRA_MAX_CONFLICT_TABLE_SIZE \

> > @@ -223,7 +259,7 @@ extern void init_param_values (int *para

> >  #define PREFETCH_MIN_INSN_TO_MEM_RATIO \

> >    PARAM_VALUE (PARAM_PREFETCH_MIN_INSN_TO_MEM_RATIO)

> >  #define MIN_NONDEBUG_INSN_UID \

> > -  PARAM_VALUE (PARAM_MIN_NONDEBUG_INSN_UID)

> > +  PARAM_VALUE_GLOBAL (PARAM_MIN_NONDEBUG_INSN_UID)

> >  #define MAX_STORES_TO_SINK \

> >    PARAM_VALUE (PARAM_MAX_STORES_TO_SINK)

> >  #define ALLOW_LOAD_DATA_RACES \

> > @@ -235,21 +271,21 @@ extern void init_param_values (int *para

> >  #define ALLOW_PACKED_STORE_DATA_RACES \

> >    PARAM_VALUE (PARAM_ALLOW_PACKED_STORE_DATA_RACES)

> >  #define ASAN_STACK \

> > -  PARAM_VALUE (PARAM_ASAN_STACK)

> > +  PARAM_VALUE_GLOBAL (PARAM_ASAN_STACK)

> >  #define ASAN_PROTECT_ALLOCAS \

> > -  PARAM_VALUE (PARAM_ASAN_PROTECT_ALLOCAS)

> > +  PARAM_VALUE_GLOBAL (PARAM_ASAN_PROTECT_ALLOCAS)

> >  #define ASAN_GLOBALS \

> > -  PARAM_VALUE (PARAM_ASAN_GLOBALS)

> > +  PARAM_VALUE_GLOBAL (PARAM_ASAN_GLOBALS)

> >  #define ASAN_INSTRUMENT_READS \

> > -  PARAM_VALUE (PARAM_ASAN_INSTRUMENT_READS)

> > +  PARAM_VALUE_GLOBAL (PARAM_ASAN_INSTRUMENT_READS)

> >  #define ASAN_INSTRUMENT_WRITES \

> > -  PARAM_VALUE (PARAM_ASAN_INSTRUMENT_WRITES)

> > +  PARAM_VALUE_GLOBAL (PARAM_ASAN_INSTRUMENT_WRITES)

> >  #define ASAN_MEMINTRIN \

> > -  PARAM_VALUE (PARAM_ASAN_MEMINTRIN)

> > +  PARAM_VALUE_GLOBAL (PARAM_ASAN_MEMINTRIN)

> >  #define ASAN_USE_AFTER_RETURN \

> > -  PARAM_VALUE (PARAM_ASAN_USE_AFTER_RETURN)

> > +  PARAM_VALUE_GLOBAL (PARAM_ASAN_USE_AFTER_RETURN)

> >  #define ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD \

> > -  PARAM_VALUE (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD)

> > +  PARAM_VALUE_GLOBAL (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD)

> >  #define ASAN_PARAM_USE_AFTER_SCOPE_DIRECT_EMISSION_THRESHOLD \

> >    ((unsigned) PARAM_VALUE (PARAM_USE_AFTER_SCOPE_DIRECT_EMISSION_THRESHOLD))

> >  

> > Index: predict.c

> > ===================================================================

> > --- predict.c	(revision 272142)

> > +++ predict.c	(working copy)

> > @@ -132,7 +132,8 @@ get_hot_bb_threshold ()

> >  {

> >    if (min_count == -1)

> >      {

> > -      gcov_type t = profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION);

> > +      gcov_type t = profile_info->sum_max / PARAM_VALUE_GLOBAL

> > +						 (HOT_BB_COUNT_FRACTION);

> >        set_hot_bb_threshold (t);

> >        if (dump_file)

> >  	fprintf (dump_file, "Setting hotness threshold to %" PRId64 ".\n",

> > @@ -173,9 +174,10 @@ maybe_hot_count_p (struct function *fun,

> >        if (node->frequency == NODE_FREQUENCY_EXECUTED_ONCE

> >  	  && count < (ENTRY_BLOCK_PTR_FOR_FN (fun)->count.apply_scale (2, 3)))

> >  	return false;

> > -      if (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) == 0)

> > +      if (PARAM_VALUE_FOR_FN (node->decl, HOT_BB_FREQUENCY_FRACTION) == 0)

> >  	return false;

> > -      if (count.apply_scale (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION), 1)

> > +      if (count.apply_scale (PARAM_VALUE_FOR_FN (node->decl,

> > +						 HOT_BB_FREQUENCY_FRACTION), 1)

> >  	  < ENTRY_BLOCK_PTR_FOR_FN (fun)->count)

> >  	return false;

> >        return true;

> > @@ -222,7 +224,8 @@ probably_never_executed (struct function

> >       desirable.  */

> >    if (count.precise_p () && profile_status_for_fn (fun) == PROFILE_READ)

> >      {

> > -      int unlikely_count_fraction = PARAM_VALUE (UNLIKELY_BB_COUNT_FRACTION);

> > +      int unlikely_count_fraction = PARAM_VALUE_GLOBAL

> > +				      (UNLIKELY_BB_COUNT_FRACTION);

> >        if (count.apply_scale (unlikely_count_fraction, 1) >= profile_info->runs)

> >  	return false;

> >        return true;

> > @@ -413,9 +416,11 @@ predictable_edge_p (edge e)

> >    if (!e->probability.initialized_p ())

> >      return false;

> >    if ((e->probability.to_reg_br_prob_base ()

> > -       <= PARAM_VALUE (PARAM_PREDICTABLE_BRANCH_OUTCOME) * REG_BR_PROB_BASE / 100)

> > +       <= PARAM_VALUE (PARAM_PREDICTABLE_BRANCH_OUTCOME)

> > +			 * REG_BR_PROB_BASE / 100)

> >        || (REG_BR_PROB_BASE - e->probability.to_reg_br_prob_base ()

> > -          <= PARAM_VALUE (PARAM_PREDICTABLE_BRANCH_OUTCOME) * REG_BR_PROB_BASE / 100))

> > +          <= PARAM_VALUE (PARAM_PREDICTABLE_BRANCH_OUTCOME)

> > +				 * REG_BR_PROB_BASE / 100))

> >      return true;

> >    return false;

> >  }

> > @@ -3531,7 +3536,7 @@ void

> >  handle_missing_profiles (void)

> >  {

> >    struct cgraph_node *node;

> > -  int unlikely_count_fraction = PARAM_VALUE (UNLIKELY_BB_COUNT_FRACTION);

> > +  int unlikely_count_fraction = PARAM_VALUE_GLOBAL (UNLIKELY_BB_COUNT_FRACTION);

> >    auto_vec<struct cgraph_node *, 64> worklist;

> >  

> >    /* See if 0 count function has non-0 count callers.  In this case we

> > Index: resource.c

> > ===================================================================

> > --- resource.c	(revision 272142)

> > +++ resource.c	(working copy)

> > @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.

> >  #include "resource.h"

> >  #include "insn-attr.h"

> >  #include "params.h"

> > +#include "tree.h"

> >  

> >  /* This structure is used to record liveness information at the targets or

> >     fallthrough insns of branches.  We will most likely need the information

> > Index: sched-ebb.c

> > ===================================================================

> > --- sched-ebb.c	(revision 272142)

> > +++ sched-ebb.c	(working copy)

> > @@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.

> >  #include "cfgrtl.h"

> >  #include "cfgbuild.h"

> >  #include "sched-int.h"

> > +#include "tree.h"

> >  

> >  

> >  #ifdef INSN_SCHEDULING

> > Index: sched-rgn.c

> > ===================================================================

> > --- sched-rgn.c	(revision 272142)

> > +++ sched-rgn.c	(working copy)

> > @@ -66,6 +66,7 @@ along with GCC; see the file COPYING3.

> >  #include "dbgcnt.h"

> >  #include "pretty-print.h"

> >  #include "print-rtl.h"

> > +#include "tree.h"

> >  

> >  /* Disable warnings about quoting issues in the pp_xxx calls below

> >     that (intentionally) don't follow GCC diagnostic conventions.  */

> > Index: targhooks.c

> > ===================================================================

> > --- targhooks.c	(revision 272142)

> > +++ targhooks.c	(working copy)

> > @@ -2302,7 +2302,7 @@ default_max_noce_ifcvt_seq_cost (edge e)

> >  

> >    /* If we have a parameter set, use that, otherwise take a guess using

> >       BRANCH_COST.  */

> > -  if (global_options_set.x_param_values[param])

> > +  if (PARAM_VALUE_SET (param))

> >      return PARAM_VALUE (param);

> >    else

> >      return BRANCH_COST (true, predictable_p) * COSTS_N_INSNS (3);

> > Index: toplev.c

> > ===================================================================

> > --- toplev.c	(revision 272142)

> > +++ toplev.c	(working copy)

> > @@ -697,7 +697,8 @@ print_version (FILE *file, const char *i

> >        fprintf (file,

> >  	       file == stderr ? _(fmt4) : fmt4,

> >  	       indent, *indent != 0 ? " " : "",

> > -	       PARAM_VALUE (GGC_MIN_EXPAND), PARAM_VALUE (GGC_MIN_HEAPSIZE));

> > +	       PARAM_VALUE_GLOBAL (GGC_MIN_EXPAND),

> > +	       PARAM_VALUE_GLOBAL (GGC_MIN_HEAPSIZE));

> >  

> >        print_plugins_versions (file, indent);

> >      }

> > @@ -1801,7 +1802,7 @@ process_options (void)

> >  

> >    if (flag_checking >= 2)

> >      hash_table_sanitize_eq_limit

> > -      = PARAM_VALUE (PARAM_HASH_TABLE_VERIFICATION_LIMIT);

> > +      = PARAM_VALUE_GLOBAL (PARAM_HASH_TABLE_VERIFICATION_LIMIT);

> >  

> >    /* Please don't change global_options after this point, those changes won't

> >       be reflected in optimization_{default,current}_node.  */

> > Index: tree-sra.c

> > ===================================================================

> > --- tree-sra.c	(revision 272142)

> > +++ tree-sra.c	(working copy)

> > @@ -2977,7 +2977,7 @@ analyze_all_variable_accesses (void)

> >    /* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>,

> >       fall back to a target default.  */

> >    unsigned HOST_WIDE_INT max_scalarization_size

> > -    = global_options_set.x_param_values[param]

> > +    = PARAM_VALUE_SET (param)

> >        ? PARAM_VALUE (param)

> >        : get_move_ratio (optimize_speed_p) * UNITS_PER_WORD;

> >  

> > @@ -5604,7 +5604,8 @@ ipa_sra_preliminary_function_checks (str

> >  

> >    if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl))

> >        && ipa_fn_summaries->get (node)

> > -      && ipa_fn_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO)

> > +      && ipa_fn_summaries->get (node)->size >=

> > +	   PARAM_VALUE_FOR_FN (node->decl, PARAM_MAX_INLINE_INSNS_AUTO))

> >      {

> >        if (dump_file)

> >  	fprintf (dump_file, "Function too big to be made truly local.\n");

> > Index: tree-ssa-ifcombine.c

> > ===================================================================

> > --- tree-ssa-ifcombine.c	(revision 272142)

> > +++ tree-ssa-ifcombine.c	(working copy)

> > @@ -565,9 +565,9 @@ ifcombine_ifandif (basic_block inner_con

> >  	  tree t1, t2;

> >  	  gimple_stmt_iterator gsi;

> >  	  bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;

> > -	  if (PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)

> > +	  if (PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)

> >  	    logical_op_non_short_circuit

> > -	      = PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);

> > +	      = PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);

> >  	  if (!logical_op_non_short_circuit || flag_sanitize_coverage)

> >  	    return false;

> >  	  /* Only do this optimization if the inner bb contains only the conditional. */

> > Index: cgraph.c

> > ===================================================================

> > --- cgraph.c	(revision 272142)

> > +++ cgraph.c	(working copy)

> > @@ -2783,8 +2783,10 @@ cgraph_edge::maybe_hot_p (void)

> >    if (caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE

> >        && sreal_frequency () * 2 < 3)

> >      return false;

> > -  if (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) == 0

> > -      || sreal_frequency () * PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) <= 1)

> > +  if (PARAM_VALUE_FOR_FN (caller->decl, HOT_BB_FREQUENCY_FRACTION) == 0

> > +      || sreal_frequency () * PARAM_VALUE_FOR_FN

> > +				 (caller->decl,

> > +				  HOT_BB_FREQUENCY_FRACTION) <= 1)

> >      return false;

> >    return true;

> >  }

> > Index: config/i386/i386.c

> > ===================================================================

> > --- config/i386/i386.c	(revision 272142)

> > +++ config/i386/i386.c	(working copy)

> > @@ -21449,7 +21449,7 @@ ix86_max_noce_ifcvt_seq_cost (edge e)

> >  

> >    /* If we have a parameter set, use that, otherwise take a guess using

> >       BRANCH_COST.  */

> > -  if (global_options_set.x_param_values[param])

> > +  if (PARAM_VALUE_SET (param))

> >      return PARAM_VALUE (param);

> >    else

> >      return BRANCH_COST (true, predictable_p) * COSTS_N_INSNS (2);

> > Index: coverage.c

> > ===================================================================

> > --- coverage.c	(revision 272142)

> > +++ coverage.c	(working copy)

> > @@ -324,7 +324,7 @@ get_coverage_counts (unsigned counter, u

> >  	}

> >        return NULL;

> >      }

> > -  if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))

> > +  if (PARAM_VALUE_GLOBAL (PARAM_PROFILE_FUNC_INTERNAL_ID))

> >      elt.ident = current_function_funcdef_no + 1;

> >    else

> >      {

> > @@ -560,7 +560,8 @@ coverage_compute_profile_id (struct cgra

> >      {

> >        expanded_location xloc

> >  	= expand_location (DECL_SOURCE_LOCATION (n->decl));

> > -      bool use_name_only = (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID) == 0);

> > +      bool use_name_only

> > +		 = (PARAM_VALUE_GLOBAL (PARAM_PROFILE_FUNC_INTERNAL_ID) == 0);

> >  

> >        chksum = (use_name_only ? 0 : xloc.line);

> >        if (xloc.file)

> > @@ -628,7 +629,7 @@ coverage_begin_function (unsigned lineno

> >  

> >    /* Announce function */

> >    offset = gcov_write_tag (GCOV_TAG_FUNCTION);

> > -  if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))

> > +  if (PARAM_VALUE_GLOBAL (PARAM_PROFILE_FUNC_INTERNAL_ID))

> >      gcov_write_unsigned (current_function_funcdef_no + 1);

> >    else

> >      {

> > @@ -682,7 +683,7 @@ coverage_end_function (unsigned lineno_c

> >  

> >        item = ggc_alloc<coverage_data> ();

> >  

> > -      if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))

> > +      if (PARAM_VALUE_GLOBAL (PARAM_PROFILE_FUNC_INTERNAL_ID))

> >  	item->ident = current_function_funcdef_no + 1;

> >        else

> >  	{

> > Index: cp/name-lookup.c

> > ===================================================================

> > --- cp/name-lookup.c	(revision 272142)

> > +++ cp/name-lookup.c	(working copy)

> > @@ -5311,7 +5311,7 @@ namespace_hints::namespace_hints (locati

> >  

> >    m_candidates = vNULL;

> >    m_limited = false;

> > -  m_limit = PARAM_VALUE (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP);

> > +  m_limit = PARAM_VALUE_GLOBAL (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP);

> >  

> >    /* Breadth-first search of namespaces.  Up to limit namespaces

> >       searched (limit zero == unlimited).  */

> > Index: cprop.c

> > ===================================================================

> > --- cprop.c	(revision 272142)

> > +++ cprop.c	(working copy)

> > @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.

> >  #include "cfganal.h"

> >  #include "lcm.h"

> >  #include "cfgcleanup.h"

> > +#include "tree.h"

> >  #include "params.h"

> >  #include "cselib.h"

> >  #include "intl.h"

> > Index: fold-const.c

> > ===================================================================

> > --- fold-const.c	(revision 272142)

> > +++ fold-const.c	(working copy)

> > @@ -5589,9 +5589,9 @@ fold_range_test (location_t loc, enum tr

> >       short-circuited branch and the underlying object on both sides

> >       is the same, make a non-short-circuit operation.  */

> >    bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;

> > -  if (PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)

> > +  if (PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)

> >      logical_op_non_short_circuit

> > -      = PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);

> > +      = PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);

> >    if (logical_op_non_short_circuit

> >        && !flag_sanitize_coverage

> >        && lhs != 0 && rhs != 0

> > @@ -8255,9 +8255,9 @@ fold_truth_andor (location_t loc, enum t

> >      return tem;

> >  

> >    bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;

> > -  if (PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)

> > +  if (PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)

> >      logical_op_non_short_circuit

> > -      = PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);

> > +      = PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);

> >    if (logical_op_non_short_circuit

> >        && !flag_sanitize_coverage

> >        && (code == TRUTH_AND_EXPR

> > Index: ggc-page.c

> > ===================================================================

> > --- ggc-page.c	(revision 272142)

> > +++ ggc-page.c	(working copy)

> > @@ -2171,9 +2171,11 @@ ggc_collect (void)

> >       total allocations haven't expanded much since the last

> >       collection.  */

> >    float allocated_last_gc =

> > -    MAX (G.allocated_last_gc, (size_t)PARAM_VALUE (GGC_MIN_HEAPSIZE) * 1024);

> > +    MAX (G.allocated_last_gc,

> > +	 (size_t)PARAM_VALUE_GLOBAL (GGC_MIN_HEAPSIZE) * 1024);

> >  

> > -  float min_expand = allocated_last_gc * PARAM_VALUE (GGC_MIN_EXPAND) / 100;

> > +  float min_expand = allocated_last_gc

> > +		     * PARAM_VALUE_GLOBAL (GGC_MIN_EXPAND) / 100;

> >    if (G.allocated < allocated_last_gc + min_expand && !ggc_force_collect)

> >      return;

> >  

> > Index: haifa-sched.c

> > ===================================================================

> > --- haifa-sched.c	(revision 272142)

> > +++ haifa-sched.c	(working copy)

> > @@ -146,6 +146,7 @@ along with GCC; see the file COPYING3.

> >  #include "cfgloop.h"

> >  #include "dumpfile.h"

> >  #include "print-rtl.h"

> > +#include "tree.h"

> >  

> >  #ifdef INSN_SCHEDULING

> >  

> > Index: hash-table.h

> > ===================================================================

> > --- hash-table.h	(revision 272142)

> > +++ hash-table.h	(working copy)

> > @@ -386,10 +386,10 @@ public:

> >  

> >    /* Create a hash_table in gc memory.  */

> >    static hash_table *

> > -  create_ggc (size_t n CXX_MEM_STAT_INFO)

> > +  create_ggc (size_t n, bool sanitize_eq_and_hash = true CXX_MEM_STAT_INFO)

> >    {

> >      hash_table *table = ggc_alloc<hash_table> ();

> > -    new (table) hash_table (n, true, true, GATHER_STATISTICS,

> > +    new (table) hash_table (n, true, sanitize_eq_and_hash, GATHER_STATISTICS,

> >  			    HASH_TABLE_ORIGIN PASS_MEM_STAT);

> >      return table;

> >    }

> > Index: ipa-cp.c

> > ===================================================================

> > --- ipa-cp.c	(revision 272142)

> > +++ ipa-cp.c	(working copy)

> > @@ -1563,7 +1563,8 @@ ipcp_lattice<valtype>::add_value (valtyp

> >  	return false;

> >        }

> >  

> > -  if (values_count == PARAM_VALUE (PARAM_IPA_CP_VALUE_LIST_SIZE))

> > +  if (values_count == PARAM_VALUE_FOR_FN (cs->caller->decl,

> > +					  PARAM_IPA_CP_VALUE_LIST_SIZE))

> >      {

> >        /* We can only free sources, not the values themselves, because sources

> >  	 of other values in this SCC might point to them.   */

> > @@ -2043,7 +2044,7 @@ merge_agg_lats_step (struct ipcp_param_l

> >  	  set_agg_lats_to_bottom (dest_plats);

> >  	  return false;

> >  	}

> > -      if (dest_plats->aggs_count == PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS))

> > +      if (dest_plats->aggs_count == PARAM_VALUE_GLOBAL (PARAM_IPA_MAX_AGG_ITEMS))

> >  	return false;

> >        dest_plats->aggs_count++;

> >        new_al = ipcp_agg_lattice_pool.allocate ();

> > @@ -2589,11 +2590,13 @@ devirtualization_time_bonus (struct cgra

> >  

> >        /* FIXME: The values below need re-considering and perhaps also

> >  	 integrating into the cost metrics, at lest in some very basic way.  */

> > -      if (isummary->size <= MAX_INLINE_INSNS_AUTO / 4)

> > +      int max_inline_insns_auto = PARAM_VALUE_FOR_FN

> > +			 (node->decl, PARAM_MAX_INLINE_INSNS_AUTO);

> > +      if (isummary->size <= max_inline_insns_auto / 4)

> >  	res += 31 / ((int)speculative + 1);

> > -      else if (isummary->size <= MAX_INLINE_INSNS_AUTO / 2)

> > +      else if (isummary->size <= max_inline_insns_auto / 2)

> >  	res += 15 / ((int)speculative + 1);

> > -      else if (isummary->size <= MAX_INLINE_INSNS_AUTO

> > +      else if (isummary->size <= max_inline_insns_auto

> >  	       || DECL_DECLARED_INLINE_P (callee->decl))

> >  	res += 7 / ((int)speculative + 1);

> >      }

> > @@ -2608,9 +2611,9 @@ hint_time_bonus (ipa_hints hints)

> >  {

> >    int result = 0;

> >    if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride))

> > -    result += PARAM_VALUE (PARAM_IPA_CP_LOOP_HINT_BONUS);

> > +    result += PARAM_VALUE_GLOBAL (PARAM_IPA_CP_LOOP_HINT_BONUS);

> >    if (hints & INLINE_HINT_array_index)

> > -    result += PARAM_VALUE (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS);

> > +    result += PARAM_VALUE_GLOBAL (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS);

> >    return result;

> >  }

> >  

> > @@ -2622,11 +2625,13 @@ incorporate_penalties (ipa_node_params *

> >  {

> >    if (info->node_within_scc)

> >      evaluation = (evaluation

> > -		  * (100 - PARAM_VALUE (PARAM_IPA_CP_RECURSION_PENALTY))) / 100;

> > +		  * (100 - PARAM_VALUE_GLOBAL

> > +				 (PARAM_IPA_CP_RECURSION_PENALTY))) / 100;

> >  

> >    if (info->node_calling_single_call)

> >      evaluation = (evaluation

> > -		  * (100 - PARAM_VALUE (PARAM_IPA_CP_SINGLE_CALL_PENALTY)))

> > +		  * (100 - PARAM_VALUE_GLOBAL

> > +				 (PARAM_IPA_CP_SINGLE_CALL_PENALTY)))

> >        / 100;

> >  

> >    return evaluation;

> > @@ -2666,10 +2671,12 @@ good_cloning_opportunity_p (struct cgrap

> >  		 ", threshold: %i\n",

> >  		 info->node_within_scc ? ", scc" : "",

> >  		 info->node_calling_single_call ? ", single_call" : "",

> > -		 evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD));

> > +		 evaluation, PARAM_VALUE_FOR_FN (node->decl,

> > +						 PARAM_IPA_CP_EVAL_THRESHOLD));

> >  	}

> >  

> > -      return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);

> > +      return evaluation >= PARAM_VALUE_FOR_FN (node->decl,

> > +					       PARAM_IPA_CP_EVAL_THRESHOLD);

> >      }

> >    else

> >      {

> > @@ -2684,9 +2691,11 @@ good_cloning_opportunity_p (struct cgrap

> >  		 time_benefit, size_cost, freq_sum,

> >  		 info->node_within_scc ? ", scc" : "",

> >  		 info->node_calling_single_call ? ", single_call" : "",

> > -		 evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD));

> > +		 evaluation, PARAM_VALUE_FOR_FN (node->decl,

> > +						 PARAM_IPA_CP_EVAL_THRESHOLD));

> >  

> > -      return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);

> > +      return evaluation >= PARAM_VALUE_FOR_FN (node->decl,

> > +					       PARAM_IPA_CP_EVAL_THRESHOLD);

> >      }

> >  }

> >  

> > @@ -3301,9 +3310,10 @@ ipcp_propagate_stage (struct ipa_topo_in

> >    }

> >  

> >    max_new_size = overall_size;

> > -  if (max_new_size < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS))

> > -    max_new_size = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS);

> > -  max_new_size += max_new_size * PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH) / 100 + 1;

> > +  if (max_new_size < PARAM_VALUE_GLOBAL (PARAM_LARGE_UNIT_INSNS))

> > +    max_new_size = PARAM_VALUE_GLOBAL (PARAM_LARGE_UNIT_INSNS);

> > +  max_new_size += max_new_size

> > +		  * PARAM_VALUE_GLOBAL (PARAM_IPCP_UNIT_GROWTH) / 100 + 1;

> >  

> >    if (dump_file)

> >      fprintf (dump_file, "\noverall_size: %li, max_new_size: %li\n",

> > Index: ipa-fnsummary.c

> > ===================================================================

> > --- ipa-fnsummary.c	(revision 272142)

> > +++ ipa-fnsummary.c	(working copy)

> > @@ -1987,9 +1987,9 @@ fp_expression_p (gimple *stmt)

> >  static void

> >  analyze_function_body (struct cgraph_node *node, bool early)

> >  {

> > -  sreal time = PARAM_VALUE (PARAM_UNINLINED_FUNCTION_TIME);

> > +  sreal time = PARAM_VALUE_FOR_FN (node->decl, PARAM_UNINLINED_FUNCTION_TIME);

> >    /* Estimate static overhead for function prologue/epilogue and alignment. */

> > -  int size = PARAM_VALUE (PARAM_UNINLINED_FUNCTION_INSNS);

> > +  int size = PARAM_VALUE_FOR_FN (node->decl, PARAM_UNINLINED_FUNCTION_INSNS);

> >    /* Benefits are scaled by probability of elimination that is in range

> >       <0,2>.  */

> >    basic_block bb;

> > @@ -2037,7 +2037,8 @@ analyze_function_body (struct cgraph_nod

> >  	  fbi.bb_infos = vNULL;

> >  	  fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));

> >  	  fbi.param_count = count_formal_params (node->decl);

> > -	  fbi.aa_walk_budget = PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS);

> > +	  fbi.aa_walk_budget = PARAM_VALUE_FOR_FN (node->decl,

> > +						   PARAM_IPA_MAX_AA_STEPS);

> >  

> >  	  nonconstant_names.safe_grow_cleared

> >  	    (SSANAMES (my_function)->length ());

> > @@ -2054,9 +2055,11 @@ analyze_function_body (struct cgraph_nod

> >    info->account_size_time (0, 0, bb_predicate, bb_predicate);

> >  

> >    bb_predicate = predicate::not_inlined ();

> > -  info->account_size_time (PARAM_VALUE (PARAM_UNINLINED_FUNCTION_INSNS)

> > +  info->account_size_time (PARAM_VALUE_FOR_FN (node->decl,

> > +					       PARAM_UNINLINED_FUNCTION_INSNS)

> >  			   * ipa_fn_summary::size_scale,

> > -			   PARAM_VALUE (PARAM_UNINLINED_FUNCTION_TIME),

> > +			   PARAM_VALUE_FOR_FN (node->decl,

> > +					       PARAM_UNINLINED_FUNCTION_TIME),

> >  			   bb_predicate,

> >  		           bb_predicate);

> >  

> > @@ -2441,10 +2444,12 @@ compute_fn_summary (struct cgraph_node *

> >        es->call_stmt_size = eni_size_weights.call_cost;

> >        es->call_stmt_time = eni_time_weights.call_cost;

> >        info->account_size_time (ipa_fn_summary::size_scale

> > -			       * PARAM_VALUE

> > -				 (PARAM_UNINLINED_FUNCTION_THUNK_INSNS),

> > -			       PARAM_VALUE

> > -				 (PARAM_UNINLINED_FUNCTION_THUNK_TIME), t, t);

> > +			       * PARAM_VALUE_FOR_FN

> > +				 (node->decl,

> > +				  PARAM_UNINLINED_FUNCTION_THUNK_INSNS),

> > +			       PARAM_VALUE_FOR_FN

> > +				 (node->decl,

> > +				  PARAM_UNINLINED_FUNCTION_THUNK_TIME), t, t);

> >        t = predicate::not_inlined ();

> >        info->account_size_time (2 * ipa_fn_summary::size_scale, 0, t, t);

> >        ipa_update_overall_fn_summary (node);

> > Index: ipa-inline-analysis.c

> > ===================================================================

> > --- ipa-inline-analysis.c	(revision 272142)

> > +++ ipa-inline-analysis.c	(working copy)

> > @@ -343,7 +343,8 @@ estimate_growth (struct cgraph_node *nod

> >        else if (DECL_COMDAT (node->decl)

> >  	       && node->can_remove_if_no_direct_calls_p ())

> >  	d.growth -= (info->size

> > -		     * (100 - PARAM_VALUE (PARAM_COMDAT_SHARING_PROBABILITY))

> > +		     * (100 - PARAM_VALUE_FOR_FN (node->decl,

> > +						  PARAM_COMDAT_SHARING_PROBABILITY))

> >  		     + 50) / 100;

> >      }

> >  

> > Index: ipa-inline.c

> > ===================================================================

> > --- ipa-inline.c	(revision 272142)

> > +++ ipa-inline.c	(working copy)

> > @@ -179,13 +179,15 @@ caller_growth_limits (struct cgraph_edge

> >    if (limit < what_info->self_size)

> >      limit = what_info->self_size;

> >  

> > -  limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;

> > +  limit += limit * PARAM_VALUE_FOR_FN (e->caller->decl,

> > +				       PARAM_LARGE_FUNCTION_GROWTH) / 100;

> >  

> >    /* Check the size after inlining against the function limits.  But allow

> >       the function to shrink if it went over the limits by forced inlining.  */

> >    newsize = estimate_size_after_inlining (to, e);

> >    if (newsize >= info->size

> > -      && newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)

> > +      && newsize > PARAM_VALUE_FOR_FN (e->caller->decl,

> > +				       PARAM_LARGE_FUNCTION_INSNS)

> >        && newsize > limit)

> >      {

> >        e->inline_failed = CIF_LARGE_FUNCTION_GROWTH_LIMIT;

> > @@ -201,7 +203,8 @@ caller_growth_limits (struct cgraph_edge

> >       on every invocation of the caller (i.e. its call statement dominates

> >       exit block).  We do not track this information, yet.  */

> >    stack_size_limit += ((gcov_type)stack_size_limit

> > -		       * PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) / 100);

> > +		       * PARAM_VALUE_FOR_FN (e->caller->decl,

> > +					     PARAM_STACK_FRAME_GROWTH) / 100);

> >  

> >    inlined_stack = (outer_info->stack_frame_offset

> >  		   + outer_info->estimated_self_stack_size

> > @@ -214,7 +217,8 @@ caller_growth_limits (struct cgraph_edge

> >  	 This bit overoptimistically assume that we are good at stack

> >  	 packing.  */

> >        && inlined_stack > info->estimated_stack_size

> > -      && inlined_stack > PARAM_VALUE (PARAM_LARGE_STACK_FRAME))

> > +      && inlined_stack > PARAM_VALUE_FOR_FN (e->caller->decl,

> > +					     PARAM_LARGE_STACK_FRAME))

> >      {

> >        e->inline_failed = CIF_LARGE_STACK_FRAME_GROWTH_LIMIT;

> >        return false;

> > @@ -530,10 +534,15 @@ can_inline_edge_by_limits_p (struct cgra

> >  	       > opt_for_fn (caller->decl, optimize_size))

> >  	{

> >  	  int growth = estimate_edge_growth (e);

> > -	  if (growth > PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SIZE)

> > +	  if (growth > PARAM_VALUE_FOR_FN (e->caller->decl,

> > +					   PARAM_MAX_INLINE_INSNS_SIZE)

> >  	      && (!DECL_DECLARED_INLINE_P (callee->decl)

> > -		  && growth >= MAX (MAX_INLINE_INSNS_SINGLE,

> > -				    MAX_INLINE_INSNS_AUTO)))

> > +		  && growth >= MAX (PARAM_VALUE_FOR_FN

> > +				      (e->caller->decl,

> > +					PARAM_MAX_INLINE_INSNS_SINGLE),

> > +				    PARAM_VALUE_FOR_FN

> > +				      (e->caller->decl,

> > +					PARAM_MAX_INLINE_INSNS_AUTO))))

> >  	    {

> >  	      e->inline_failed = CIF_OPTIMIZATION_MISMATCH;

> >  	      inlinable = false;

> > @@ -642,7 +651,8 @@ want_early_inline_function_p (struct cgr

> >        int growth = estimate_edge_growth (e);

> >        int n;

> >  

> > -      if (growth <= PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SIZE))

> > +      if (growth <= PARAM_VALUE_FOR_FN (e->caller->decl,

> > +					PARAM_MAX_INLINE_INSNS_SIZE))

> >  	;

> >        else if (!e->maybe_hot_p ())

> >  	{

> > @@ -654,7 +664,8 @@ want_early_inline_function_p (struct cgr

> >  			     growth);

> >  	  want_inline = false;

> >  	}

> > -      else if (growth > PARAM_VALUE (PARAM_EARLY_INLINING_INSNS))

> > +      else if (growth > PARAM_VALUE_FOR_FN (e->caller->decl,

> > +					    PARAM_EARLY_INLINING_INSNS))

> >  	{

> >  	  if (dump_enabled_p ())

> >  	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,

> > @@ -665,7 +676,9 @@ want_early_inline_function_p (struct cgr

> >  	  want_inline = false;

> >  	}

> >        else if ((n = num_calls (callee)) != 0

> > -	       && growth * (n + 1) > PARAM_VALUE (PARAM_EARLY_INLINING_INSNS))

> > +	       && growth * (n + 1) > PARAM_VALUE_FOR_FN

> > +					 (e->caller->decl,

> > +					  PARAM_EARLY_INLINING_INSNS))

> >  	{

> >  	  if (dump_enabled_p ())

> >  	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,

> > @@ -741,7 +754,8 @@ big_speedup_p (struct cgraph_edge *e)

> >    sreal inlined_time = compute_inlined_call_time (e, spec_time);

> >  

> >    if ((time - inlined_time) * 100

> > -      > (sreal) (time * PARAM_VALUE (PARAM_INLINE_MIN_SPEEDUP)))

> > +      > (sreal) (time * PARAM_VALUE_FOR_FN

> > +			 (e->caller->decl, PARAM_INLINE_MIN_SPEEDUP)))

> >      return true;

> >    return false;

> >  }

> > @@ -775,7 +789,10 @@ want_inline_small_function_p (struct cgr

> >  	   && (!e->count.ipa ().initialized_p () || !e->maybe_hot_p ()))

> >  	   && ipa_fn_summaries->get (callee)->min_size

> >  		- ipa_call_summaries->get (e)->call_stmt_size

> > -	      > MAX (MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS_AUTO))

> > +	      > MAX (PARAM_VALUE_FOR_FN (e->caller->decl,

> > +					 PARAM_MAX_INLINE_INSNS_SINGLE),

> > +		     PARAM_VALUE_FOR_FN (e->caller->decl,

> > +					 PARAM_MAX_INLINE_INSNS_AUTO)))

> >      {

> >        e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;

> >        want_inline = false;

> > @@ -784,7 +801,8 @@ want_inline_small_function_p (struct cgr

> >  	    || e->count.ipa ().nonzero_p ())

> >  	   && ipa_fn_summaries->get (callee)->min_size

> >  		- ipa_call_summaries->get (e)->call_stmt_size

> > -	      > 16 * MAX_INLINE_INSNS_SINGLE)

> > +	      > 16 * PARAM_VALUE_FOR_FN (e->caller->decl,

> > +					 PARAM_MAX_INLINE_INSNS_SINGLE))

> >      {

> >        e->inline_failed = (DECL_DECLARED_INLINE_P (callee->decl)

> >  			  ? CIF_MAX_INLINE_INSNS_SINGLE_LIMIT

> > @@ -797,13 +815,16 @@ want_inline_small_function_p (struct cgr

> >        ipa_hints hints = estimate_edge_hints (e);

> >        int big_speedup = -1; /* compute this lazily */

> >  

> > -      if (growth <= PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SIZE))

> > +      if (growth <= PARAM_VALUE_FOR_FN

> > +			 (e->caller->decl, PARAM_MAX_INLINE_INSNS_SIZE))

> >  	;

> >        /* Apply MAX_INLINE_INSNS_SINGLE limit.  Do not do so when

> >  	 hints suggests that inlining given function is very profitable.  */

> >        else if (DECL_DECLARED_INLINE_P (callee->decl)

> > -	       && growth >= MAX_INLINE_INSNS_SINGLE

> > -	       && (growth >= MAX_INLINE_INSNS_SINGLE * 16

> > +	       && growth >= PARAM_VALUE_FOR_FN (e->caller->decl,

> > +						PARAM_MAX_INLINE_INSNS_SINGLE)

> > +	       && (growth >= PARAM_VALUE_FOR_FN (e->caller->decl,

> > +						 PARAM_MAX_INLINE_INSNS_SINGLE)

> >  		   || (!(hints & (INLINE_HINT_indirect_call

> >  				  | INLINE_HINT_known_hot

> >  				  | INLINE_HINT_loop_iterations

> > @@ -816,10 +837,12 @@ want_inline_small_function_p (struct cgr

> >  	}

> >        else if (!DECL_DECLARED_INLINE_P (callee->decl)

> >  	       && !opt_for_fn (e->caller->decl, flag_inline_functions)

> > -	       && growth >= PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SMALL))

> > +	       && growth >= PARAM_VALUE_FOR_FN

> > +				 (e->caller->decl, PARAM_MAX_INLINE_INSNS_SMALL))

> >  	{

> >  	  /* growth_likely_positive is expensive, always test it last.  */

> > -          if (growth >= MAX_INLINE_INSNS_SINGLE

> > +          if (growth >= PARAM_VALUE_FOR_FN (e->caller->decl,

> > +					    PARAM_MAX_INLINE_INSNS_SINGLE)

> >  	      || growth_likely_positive (callee, growth))

> >  	    {

> >                e->inline_failed = CIF_NOT_DECLARED_INLINED;

> > @@ -835,13 +858,19 @@ want_inline_small_function_p (struct cgr

> >  				       | INLINE_HINT_loop_iterations

> >  			               | INLINE_HINT_array_index

> >  				       | INLINE_HINT_loop_stride))

> > -			     ? MAX (MAX_INLINE_INSNS_AUTO,

> > -				    MAX_INLINE_INSNS_SINGLE)

> > -			     : MAX_INLINE_INSNS_AUTO)

> > +			     ? MAX (PARAM_VALUE_FOR_FN

> > +					 (e->caller->decl,

> > +					  PARAM_MAX_INLINE_INSNS_AUTO),

> > +				    PARAM_VALUE_FOR_FN

> > +					 (e->caller->decl,

> > +					  PARAM_MAX_INLINE_INSNS_SINGLE))

> > +			     : PARAM_VALUE_FOR_FN (e->caller->decl,

> > +						   PARAM_MAX_INLINE_INSNS_AUTO))

> >  	       && !(big_speedup == -1 ? big_speedup_p (e) : big_speedup))

> >  	{

> >  	  /* growth_likely_positive is expensive, always test it last.  */

> > -          if (growth >= MAX_INLINE_INSNS_SINGLE

> > +          if (growth >=	PARAM_VALUE_FOR_FN (e->caller->decl,

> > +				     	    PARAM_MAX_INLINE_INSNS_SINGLE)

> >  	      || growth_likely_positive (callee, growth))

> >  	    {

> >  	      e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;

> > @@ -850,7 +879,8 @@ want_inline_small_function_p (struct cgr

> >  	}

> >        /* If call is cold, do not inline when function body would grow. */

> >        else if (!e->maybe_hot_p ()

> > -	       && (growth >= MAX_INLINE_INSNS_SINGLE

> > +	       && (growth >= PARAM_VALUE_FOR_FN (e->caller->decl,

> > +						 PARAM_MAX_INLINE_INSNS_SINGLE)

> >  		   || growth_likely_positive (callee, growth)))

> >  	{

> >            e->inline_failed = CIF_UNLIKELY_CALL;

> > @@ -882,10 +912,12 @@ want_inline_self_recursive_call_p (struc

> >    char const *reason = NULL;

> >    bool want_inline = true;

> >    sreal caller_freq = 1;

> > -  int max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO);

> > +  int max_depth = PARAM_VALUE_FOR_FN (edge->caller->decl,

> > +				      PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO);

> >  

> >    if (DECL_DECLARED_INLINE_P (edge->caller->decl))

> > -    max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH);

> > +    max_depth = PARAM_VALUE_FOR_FN (edge->caller->decl,

> > +				    PARAM_MAX_INLINE_RECURSIVE_DEPTH);

> >  

> >    if (!edge->maybe_hot_p ())

> >      {

> > @@ -947,7 +979,8 @@ want_inline_self_recursive_call_p (struc

> >      {

> >        if (edge->sreal_frequency () * 100

> >            <= caller_freq

> > -	     * PARAM_VALUE (PARAM_MIN_INLINE_RECURSIVE_PROBABILITY))

> > +	     * PARAM_VALUE_FOR_FN (edge->caller->decl,

> > +			           PARAM_MIN_INLINE_RECURSIVE_PROBABILITY))

> >  	{

> >  	  reason = "frequency of recursive call is too small";

> >  	  want_inline = false;

> > @@ -1144,8 +1177,9 @@ edge_badness (struct cgraph_edge *edge,

> >  		 frequency still indicates splitting is a win ... */

> >  	      || (callee->split_part && !caller->split_part

> >  		  && edge->sreal_frequency () * 100

> > -		     < PARAM_VALUE

> > -			  (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY)

> > +		     < PARAM_VALUE_FOR_FN

> > +			  (caller->decl,

> > +			   PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY)

> >  		  /* ... and do not overwrite user specified hints.   */

> >  		  && (!DECL_DECLARED_INLINE_P (edge->callee->decl)

> >  		      || DECL_DECLARED_INLINE_P (caller->decl)))))

> > @@ -1158,8 +1192,10 @@ edge_badness (struct cgraph_edge *edge,

> >  	  if (!caller_info->single_caller && overall_growth < caller_growth

> >  	      && caller_info->inlinable

> >  	      && caller_info->size

> > -		 < (DECL_DECLARED_INLINE_P (caller->decl)

> > -		    ? MAX_INLINE_INSNS_SINGLE : MAX_INLINE_INSNS_AUTO))

> > +		 < PARAM_VALUE_FOR_FN (caller->decl,

> > +			(DECL_DECLARED_INLINE_P (caller->decl)

> > +			 ? PARAM_MAX_INLINE_INSNS_SINGLE

> > +			 : PARAM_MAX_INLINE_INSNS_AUTO)))

> >  	    {

> >  	      if (dump)

> >  		fprintf (dump_file,

> > @@ -1473,7 +1509,8 @@ static bool

> >  recursive_inlining (struct cgraph_edge *edge,

> >  		    vec<cgraph_edge *> *new_edges)

> >  {

> > -  int limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO);

> > +  int limit = PARAM_VALUE_FOR_FN (edge->caller->decl,

> > +				  PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO);

> >    edge_heap_t heap (sreal::min ());

> >    struct cgraph_node *node;

> >    struct cgraph_edge *e;

> > @@ -1486,7 +1523,7 @@ recursive_inlining (struct cgraph_edge *

> >      node = node->global.inlined_to;

> >  

> >    if (DECL_DECLARED_INLINE_P (node->decl))

> > -    limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE);

> > +    limit = PARAM_VALUE_FOR_FN (node->decl, PARAM_MAX_INLINE_INSNS_RECURSIVE);

> >  

> >    /* Make sure that function is small enough to be considered for inlining.  */

> >    if (estimate_size_after_inlining (node, edge)  >= limit)

> > @@ -1611,11 +1648,11 @@ static int

> >  compute_max_insns (int insns)

> >  {

> >    int max_insns = insns;

> > -  if (max_insns < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS))

> > -    max_insns = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS);

> > +  if (max_insns < PARAM_VALUE_GLOBAL (PARAM_LARGE_UNIT_INSNS))

> > +    max_insns = PARAM_VALUE_GLOBAL (PARAM_LARGE_UNIT_INSNS);

> >  

> >    return ((int64_t) max_insns

> > -	  * (100 + PARAM_VALUE (PARAM_INLINE_UNIT_GROWTH)) / 100);

> > +	  * (100 + PARAM_VALUE_GLOBAL (PARAM_INLINE_UNIT_GROWTH)) / 100);

> >  }

> >  

> >  

> > Index: ipa-profile.c

> > ===================================================================

> > --- ipa-profile.c	(revision 272142)

> > +++ ipa-profile.c	(working copy)

> > @@ -506,7 +506,8 @@ ipa_profile (void)

> >  

> >        gcc_assert (overall_size);

> >  

> > -      cutoff = (overall_time * PARAM_VALUE (HOT_BB_COUNT_WS_PERMILLE) + 500) / 1000;

> > +      cutoff = (overall_time * PARAM_VALUE_GLOBAL

> > +			 (HOT_BB_COUNT_WS_PERMILLE) + 500) / 1000;

> >        threshold = 0;

> >        for (i = 0; cumulated < cutoff; i++)

> >  	{

> > Index: ipa-prop.c

> > ===================================================================

> > --- ipa-prop.c	(revision 272142)

> > +++ ipa-prop.c	(working copy)

> > @@ -1547,7 +1547,7 @@ determine_locally_known_aggregate_parts

> >    bool check_ref, by_ref;

> >    ao_ref r;

> >  

> > -  if (PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS) == 0)

> > +  if (PARAM_VALUE_GLOBAL (PARAM_IPA_MAX_AGG_ITEMS) == 0)

> >      return;

> >  

> >    /* The function operates in three stages.  First, we prepare check_ref, r,

> > @@ -1675,8 +1675,8 @@ determine_locally_known_aggregate_parts

> >        *p = n;

> >  

> >        item_count++;

> > -      if (const_count == PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS)

> > -	  || item_count == 2 * PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS))

> > +      if (const_count == PARAM_VALUE_GLOBAL (PARAM_IPA_MAX_AGG_ITEMS)

> > +	  || item_count == 2 * PARAM_VALUE_GLOBAL (PARAM_IPA_MAX_AGG_ITEMS))

> >  	break;

> >      }

> >  

> > Index: ipa-split.c

> > ===================================================================

> > --- ipa-split.c	(revision 272142)

> > +++ ipa-split.c	(working copy)

> > @@ -561,8 +561,8 @@ consider_split (struct split_point *curr

> >       that.  Next stage1 we should try to be more meaningful here.  */

> >    if (current->header_size + call_overhead

> >        >= (unsigned int)(DECL_DECLARED_INLINE_P (current_function_decl)

> > -			? MAX_INLINE_INSNS_SINGLE

> > -			: MAX_INLINE_INSNS_AUTO) + 10)

> > +			? PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE)

> > +			: PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO)) + 10)

> >      {

> >        if (dump_file && (dump_flags & TDF_DETAILS))

> >  	fprintf (dump_file,

> > @@ -575,7 +575,8 @@ consider_split (struct split_point *curr

> >       Limit this duplication.  This is consistent with limit in tree-sra.c  

> >       FIXME: with LTO we ought to be able to do better!  */

> >    if (DECL_ONE_ONLY (current_function_decl)

> > -      && current->split_size >= (unsigned int) MAX_INLINE_INSNS_AUTO + 10)

> > +      && current->split_size

> > +	   >= (unsigned int) PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO) + 10)

> >      {

> >        if (dump_file && (dump_flags & TDF_DETAILS))

> >  	fprintf (dump_file,

> > Index: ira-build.c

> > ===================================================================

> > --- ira-build.c	(revision 272142)

> > +++ ira-build.c	(working copy)

> > @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.

> >  #include "params.h"

> >  #include "sparseset.h"

> >  #include "cfgloop.h"

> > +#include "tree.h"

> >  

> >  static ira_copy_t find_allocno_copy (ira_allocno_t, ira_allocno_t, rtx_insn *,

> >  				     ira_loop_tree_node_t);

> > Index: ira-conflicts.c

> > ===================================================================

> > --- ira-conflicts.c	(revision 272142)

> > +++ ira-conflicts.c	(working copy)

> > @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.

> >  #include "params.h"

> >  #include "sparseset.h"

> >  #include "addresses.h"

> > +#include "tree.h"

> >  

> >  /* This file contains code responsible for allocno conflict creation,

> >     allocno copy creation and allocno info accumulation on upper level

> > Index: lto/lto-partition.c

> > ===================================================================

> > --- lto/lto-partition.c	(revision 272142)

> > +++ lto/lto-partition.c	(working copy)

> > @@ -560,13 +560,13 @@ lto_balanced_map (int n_lto_partitions,

> >    varpool_order.qsort (varpool_node_cmp);

> >  

> >    /* Compute partition size and create the first partition.  */

> > -  if (PARAM_VALUE (MIN_PARTITION_SIZE) > max_partition_size)

> > +  if (PARAM_VALUE_GLOBAL (MIN_PARTITION_SIZE) > max_partition_size)

> >      fatal_error (input_location, "min partition size cannot be greater "

> >  		 "than max partition size");

> >  

> >    partition_size = total_size / n_lto_partitions;

> > -  if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE))

> > -    partition_size = PARAM_VALUE (MIN_PARTITION_SIZE);

> > +  if (partition_size < PARAM_VALUE_GLOBAL (MIN_PARTITION_SIZE))

> > +    partition_size = PARAM_VALUE_GLOBAL (MIN_PARTITION_SIZE);

> >    npartitions = 1;

> >    partition = new_partition ("");

> >    if (dump_file)

> > @@ -816,8 +816,8 @@ lto_balanced_map (int n_lto_partitions,

> >  	    fprintf (dump_file,

> >  		     "Total size: %" PRId64 " partition_size: %" PRId64 "\n",

> >  		     total_size, partition_size);

> > -	  if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE))

> > -	    partition_size = PARAM_VALUE (MIN_PARTITION_SIZE);

> > +	  if (partition_size < PARAM_VALUE_GLOBAL (MIN_PARTITION_SIZE))

> > +	    partition_size = PARAM_VALUE_GLOBAL (MIN_PARTITION_SIZE);

> >  	  npartitions ++;

> >  	}

> >      }

> > Index: lto/lto.c

> > ===================================================================

> > --- lto/lto.c	(revision 272142)

> > +++ lto/lto.c	(working copy)

> > @@ -420,14 +420,16 @@ do_whole_program_analysis (void)

> >  

> >    /* TODO: jobserver communication is not supported, yet.  */

> >    if (!strcmp (flag_wpa, "jobserver"))

> > -    lto_parallelism = PARAM_VALUE (PARAM_MAX_LTO_STREAMING_PARALLELISM);

> > +    lto_parallelism = PARAM_VALUE_GLOBAL (PARAM_MAX_LTO_STREAMING_PARALLELISM);

> >    else

> >      {

> >        lto_parallelism = atoi (flag_wpa);

> >        if (lto_parallelism <= 0)

> >  	lto_parallelism = 0;

> > -      if (lto_parallelism >= PARAM_VALUE (PARAM_MAX_LTO_STREAMING_PARALLELISM))

> > -	lto_parallelism = PARAM_VALUE (PARAM_MAX_LTO_STREAMING_PARALLELISM);

> > +      if (lto_parallelism >= PARAM_VALUE_GLOBAL

> > +				 (PARAM_MAX_LTO_STREAMING_PARALLELISM))

> > +	lto_parallelism = PARAM_VALUE_GLOBAL

> > +			     (PARAM_MAX_LTO_STREAMING_PARALLELISM);

> >      }

> >  

> >    timevar_start (TV_PHASE_OPT_GEN);

> > @@ -479,8 +481,8 @@ do_whole_program_analysis (void)

> >    else if (flag_lto_partition == LTO_PARTITION_ONE)

> >      lto_balanced_map (1, INT_MAX);

> >    else if (flag_lto_partition == LTO_PARTITION_BALANCED)

> > -    lto_balanced_map (PARAM_VALUE (PARAM_LTO_PARTITIONS),

> > -		      PARAM_VALUE (MAX_PARTITION_SIZE));

> > +    lto_balanced_map (PARAM_VALUE_GLOBAL (PARAM_LTO_PARTITIONS),

> > +		      PARAM_VALUE_GLOBAL (MAX_PARTITION_SIZE));

> >    else

> >      gcc_unreachable ();

> >  

> > 

> 

> -- 

> Richard Biener <rguenther@suse.de>

> SUSE Linux GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany;

> GF: Felix Imendörffer, Mary Higgins, Sri Rasiah; HRB 21284 (AG Nürnberg)

Patch

Index: params.def
===================================================================
--- params.def	(revision 272142)
+++ params.def	(working copy)
@@ -19,7 +19,8 @@  along with GCC; see the file COPYING3.
 <http://www.gnu.org/licenses/>.  */
 
 /* This file contains definitions for language-independent
-   parameters.  The DEFPARAM macro takes 6 arguments:
+   parameters.  Parameters that are independent of optimization level
+   are set by the DEFPARAM_GLOBAL macro takes 6 arguments:
 
      - The enumeral corresponding to this parameter.
 
@@ -35,12 +36,34 @@  along with GCC; see the file COPYING3.
      - The maximum acceptable value for the parameter (if greater than
      the minimum).
 
+   The DEFPARAM is same except that it declares parameter that may have
+   different values depends on optimization level.  Those are set by
+   DEFPARAM_O2plus, DEFPARAM_Ofast and DEFPARAM_Os which additionally
+   take extra argument specifying values for -O2+, -Ofast and -Os
+   respectively.
+
    The DEFPARAMENUM<N> macro is similar, but instead of the minumum and maximum
    arguments, it contains a list of <N> allowed strings, corresponding to
    integer values 0..<N>-1.  Note that the default argument needs to be
    specified as one of the allowed strings, rather than an integer value.
 
-   Be sure to add an entry to invoke.texi summarizing the parameter.  */
+   Be sure to add an entry to invoke.texi summarizing the parameter.
+
+   Values declared by DEFPARAM_GLOBAL are used via PARAM_VALUE_GLOBAL macro
+   whole other values are read by PARAM_VALUE.  */
+
+#define DEFPARAM(ENUM, OPTION, HELP, DEF, MIN, MAX) \
+	DEFPARAM_OPT (ENUM, OPTION, HELP, DEF, DEF, DEF, DEF, DEF, DEF, \
+		      MIN, MAX)
+#define DEFPARAM_O2plus(ENUM, OPTION, HELP, DEF, DEFO2, MIN, MAX) \
+	DEFPARAM_OPT (ENUM, OPTION, HELP, \
+		      DEF, DEFO2, DEFO2, DEFO2, DEF, DEFO2, MIN, MAX)
+#define DEFPARAM_Ofast(ENUM, OPTION, HELP, DEF, DEFOfast, MIN, MAX) \
+	DEFPARAM_OPT (ENUM, OPTION, HELP, \
+		      DEF, DEF, DEF, DEFOfast, DEF, DEF, MIN, MAX)
+#define DEFPARAM_Os(ENUM, OPTION, HELP, DEF, DEFOs, MIN, MAX) \
+	DEFPARAM_OPT (ENUM, OPTION, HELP, \
+		      DEF, DEF, DEF, DEF, DEFOs, DEFOs, MIN, MAX)
 
 /* When branch is predicted to be taken with probability lower than this
    threshold (in percent), then it is considered well predictable. */
@@ -219,15 +242,15 @@  DEFPARAM(PARAM_LARGE_FUNCTION_GROWTH,
 	 "large-function-growth",
 	 "Maximal growth due to inlining of large function (in percent).",
 	 100, 0, 0)
-DEFPARAM(PARAM_LARGE_UNIT_INSNS,
+DEFPARAM_GLOBAL(PARAM_LARGE_UNIT_INSNS,
 	 "large-unit-insns",
 	 "The size of translation unit to be considered large.",
 	 10000, 0, 0)
-DEFPARAM(PARAM_INLINE_UNIT_GROWTH,
+DEFPARAM_GLOBAL(PARAM_INLINE_UNIT_GROWTH,
 	 "inline-unit-growth",
 	 "How much can given compilation unit grow because of the inlining (in percent).",
 	 40, 0, 0)
-DEFPARAM(PARAM_IPCP_UNIT_GROWTH,
+DEFPARAM_GLOBAL(PARAM_IPCP_UNIT_GROWTH,
 	 "ipcp-unit-growth",
 	 "How much can given compilation unit grow because of the interprocedural constant propagation (in percent).",
 	 10, 0, 0)
@@ -425,12 +448,12 @@  DEFPARAM(PARAM_SMS_LOOP_AVERAGE_COUNT_TH
 	 "A threshold on the average loop count considered by the swing modulo scheduler.",
 	 0, 0, 0)
 
-DEFPARAM(HOT_BB_COUNT_FRACTION,
+DEFPARAM_GLOBAL(HOT_BB_COUNT_FRACTION,
 	 "hot-bb-count-fraction",
 	 "Select fraction of the maximal count of repetitions of basic block in program given basic "
 	 "block needs to have to be considered hot (used in non-LTO mode).",
 	 10000, 0, 0)
-DEFPARAM(HOT_BB_COUNT_WS_PERMILLE,
+DEFPARAM_GLOBAL(HOT_BB_COUNT_WS_PERMILLE,
 	 "hot-bb-count-ws-permille",
          "A basic block profile count is considered hot if it contributes to "
          "the given permillage of the entire profiled execution (used in LTO mode).",
@@ -440,7 +463,7 @@  DEFPARAM(HOT_BB_FREQUENCY_FRACTION,
 	 "Select fraction of the maximal frequency of executions of basic block in function given basic block needs to have to be considered hot.",
 	 1000, 0, 0)
 
-DEFPARAM(UNLIKELY_BB_COUNT_FRACTION,
+DEFPARAM_GLOBAL(UNLIKELY_BB_COUNT_FRACTION,
 	 "unlikely-bb-count-fraction",
          "The minimum fraction of profile runs a given basic block execution count must be not to be considered unlikely.",
 	 20, 1, 10000)
@@ -518,11 +541,12 @@  DEFPARAM(PARAM_MAX_CROSSJUMP_EDGES,
 	 "The maximum number of incoming edges to consider for crossjumping.",
 	 100, 0, 0)
 
-/* The minimum number of matching instructions to consider for crossjumping.  */
-DEFPARAM(PARAM_MIN_CROSSJUMP_INSNS,
+/* The minimum number of matching instructions to consider for crossjumping.
+   At -Os we want to crossjump as much as possible*/
+DEFPARAM_Os(PARAM_MIN_CROSSJUMP_INSNS,
      "min-crossjump-insns",
      "The minimum number of matching instructions to consider for crossjumping.",
-     5, 1, 0)
+     5, 1, 1, 0)
 
 /* The maximum number expansion factor when copying basic blocks.  */
 DEFPARAM(PARAM_MAX_GROW_COPY_BB_INSNS,
@@ -637,12 +661,12 @@  DEFPARAM(PARAM_MAX_CSELIB_MEMORY_LOCATIO
 # define GGC_MIN_HEAPSIZE_DEFAULT 4096
 #endif
 
-DEFPARAM(GGC_MIN_EXPAND,
+DEFPARAM_GLOBAL(GGC_MIN_EXPAND,
 	 "ggc-min-expand",
 	 "Minimum heap expansion to trigger garbage collection, as a percentage of the total size of the heap.",
 	 GGC_MIN_EXPAND_DEFAULT, 0, 0)
 
-DEFPARAM(GGC_MIN_HEAPSIZE,
+DEFPARAM_GLOBAL(GGC_MIN_HEAPSIZE,
 	 "ggc-min-heapsize",
 	 "Minimum heap size before we start collecting garbage, in kilobytes.",
 	 GGC_MIN_HEAPSIZE_DEFAULT, 0, 0)
@@ -744,7 +768,7 @@  DEFPARAM(PARAM_MAX_COMBINE_INSNS,
    {signed,unsigned} integral types.  This determines N.
    Experimentation shows 251 to be a good value that generates the
    least amount of garbage for allocating the TREE_VEC storage.  */
-DEFPARAM (PARAM_INTEGER_SHARE_LIMIT,
+DEFPARAM_GLOBAL (PARAM_INTEGER_SHARE_LIMIT,
 	  "integer-share-limit",
 	  "The upper bound for sharing integer constants.",
 	  251, 2, 2)
@@ -782,7 +806,7 @@  DEFPARAM (PARAM_MAX_JUMP_THREAD_DUPLICAT
    will stop trying to treat it in a field-sensitive manner.
    There are programs out there with thousands of fields per structure, and handling them
    field-sensitively is not worth the cost.  */
-DEFPARAM (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,
+DEFPARAM_GLOBAL (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,
           "max-fields-for-field-sensitive",
 	  "Maximum number of fields in a structure before pointer analysis treats the structure as a single variable.",
 	  0, 0, 0)
@@ -793,10 +817,10 @@  DEFPARAM(PARAM_MAX_SCHED_READY_INSNS,
 	 100, 1, 0)
 
 /* This is the maximum number of active local stores RTL DSE will consider.  */
-DEFPARAM (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES,
+DEFPARAM_O2plus (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES,
 	  "max-dse-active-local-stores",
 	  "Maximum number of active local stores in RTL dead store elimination.",
-	  5000, 0, 0)
+	  500, 5000, 0, 0)
 
 /* Prefetching and cache-optimizations related parameters.  Default values are
    usually set by machine description.  */
@@ -874,7 +898,7 @@  DEFPARAM (PARAM_LOOP_INTERCHANGE_STRIDE_
    this value should only be set to zero to work around bugs in the
    canonical type system by disabling it.  */
 
-DEFPARAM (PARAM_USE_CANONICAL_TYPES,
+DEFPARAM_GLOBAL (PARAM_USE_CANONICAL_TYPES,
 	  "use-canonical-types",
 	  "Whether to use canonical types.",
 	  1, 0, 1)
@@ -979,15 +1003,15 @@  DEFPARAM (PARAM_LOOP_MAX_DATAREFS_FOR_DA
 
 /* Avoid doing loop invariant motion on very large loops.  */
 
-DEFPARAM (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,
+DEFPARAM_O2plus (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,
 	  "loop-invariant-max-bbs-in-loop",
 	  "Max basic blocks number in loop for loop invariant motion.",
-	  10000, 0, 0)
+	  1000, 10000, 0, 0)
 
 /* When the parameter is 1, use the internal function id
    to look up for profile data. Otherwise, use a more stable
    external id based on assembler name and source location. */
-DEFPARAM (PARAM_PROFILE_FUNC_INTERNAL_ID,
+DEFPARAM_GLOBAL (PARAM_PROFILE_FUNC_INTERNAL_ID,
 	  "profile-func-internal-id",
 	  "Use internal function id in profile lookup.",
 	  0, 0, 1)
@@ -1043,7 +1067,7 @@  DEFPARAM (PARAM_MAX_DEBUG_MARKER_COUNT,
 
 /* Set minimum insn uid for non-debug insns.  */
 
-DEFPARAM (PARAM_MIN_NONDEBUG_INSN_UID,
+DEFPARAM_GLOBAL (PARAM_MIN_NONDEBUG_INSN_UID,
 	  "min-nondebug-insn-uid",
 	  "The minimum UID to be used for a nondebug insn.",
 	  0, 0, 0)
@@ -1085,31 +1109,31 @@  DEFPARAM (PARAM_IPA_CP_EVAL_THRESHOLD,
 	  "beneficial to clone.",
 	  500, 0, 0)
 
-DEFPARAM (PARAM_IPA_CP_RECURSION_PENALTY,
+DEFPARAM_GLOBAL (PARAM_IPA_CP_RECURSION_PENALTY,
 	  "ipa-cp-recursion-penalty",
 	  "Percentage penalty the recursive functions will receive when they "
 	  "are evaluated for cloning.",
 	  40, 0, 100)
 
-DEFPARAM (PARAM_IPA_CP_SINGLE_CALL_PENALTY,
+DEFPARAM_GLOBAL (PARAM_IPA_CP_SINGLE_CALL_PENALTY,
 	  "ipa-cp-single-call-penalty",
 	  "Percentage penalty functions containing a single call to another "
 	  "function will receive when they are evaluated for cloning.",
 	  15, 0, 100)
 
-DEFPARAM (PARAM_IPA_MAX_AGG_ITEMS,
+DEFPARAM_GLOBAL (PARAM_IPA_MAX_AGG_ITEMS,
 	  "ipa-max-agg-items",
 	  "Maximum number of aggregate content items for a parameter in "
 	  "jump functions and lattices.",
 	  16, 0, 0)
 
-DEFPARAM (PARAM_IPA_CP_LOOP_HINT_BONUS,
+DEFPARAM_GLOBAL (PARAM_IPA_CP_LOOP_HINT_BONUS,
 	  "ipa-cp-loop-hint-bonus",
 	  "Compile-time bonus IPA-CP assigns to candidates which make loop "
 	  "bounds or strides known.",
 	  64, 0, 0)
 
-DEFPARAM (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS,
+DEFPARAM_GLOBAL (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS,
 	  "ipa-cp-array-index-hint-bonus",
 	  "Compile-time bonus IPA-CP assigns to candidates which make an array "
 	  "index known.",
@@ -1123,29 +1147,29 @@  DEFPARAM (PARAM_IPA_MAX_AA_STEPS,
 
 /* WHOPR partitioning configuration.  */
 
-DEFPARAM (PARAM_LTO_PARTITIONS,
+DEFPARAM_GLOBAL (PARAM_LTO_PARTITIONS,
 	  "lto-partitions",
 	  "Number of partitions the program should be split to.",
 	  128, 1, 0)
 
-DEFPARAM (MIN_PARTITION_SIZE,
+DEFPARAM_GLOBAL (MIN_PARTITION_SIZE,
 	  "lto-min-partition",
 	  "Minimal size of a partition for LTO (in estimated instructions).",
 	  10000, 0, 0)
 
-DEFPARAM (MAX_PARTITION_SIZE,
+DEFPARAM_GLOBAL (MAX_PARTITION_SIZE,
 	  "lto-max-partition",
 	  "Maximal size of a partition for LTO (in estimated instructions).",
 	  1000000, 0, INT_MAX)
 
-DEFPARAM (PARAM_MAX_LTO_STREAMING_PARALLELISM,
+DEFPARAM_GLOBAL (PARAM_MAX_LTO_STREAMING_PARALLELISM,
 	  "lto-max-streaming-parallelism",
 	  "maximal number of LTO partitions streamed in parallel.",
 	  32, 1, 0)
 
 /* Diagnostic parameters.  */
 
-DEFPARAM (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP,
+DEFPARAM_GLOBAL (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP,
 	  "cxx-max-namespaces-for-diagnostic-help",
 	  "Maximum number of namespaces to search for alternatives when "
 	  "name lookup fails.",
@@ -1181,11 +1205,12 @@  DEFPARAM (PARAM_JUMP_TABLE_MAX_GROWTH_RA
 	  "optimizing for speed.",
 	  800, 0, 0)
 
-/* Data race flags for C++0x memory model compliance.  */
-DEFPARAM (PARAM_ALLOW_STORE_DATA_RACES,
+/* Data race flags for C++0x memory model compliance.
+   Allow them only for Ofast  */
+DEFPARAM_Ofast (PARAM_ALLOW_STORE_DATA_RACES,
 	  "allow-store-data-races",
 	  "Allow new data races on stores to be introduced.",
-	  0, 0, 1)
+	  0, 1, 0, 1)
 
 /* Reassociation width to be used by tree reassoc optimization.  */
 DEFPARAM (PARAM_TREE_REASSOC_WIDTH,
@@ -1244,42 +1269,42 @@  DEFPARAM (PARAM_MAX_SLSR_CANDIDATE_SCAN,
 
 /* ASan stands for AddressSanitizer: https://github.com/google/sanitizers.  */
 
-DEFPARAM (PARAM_ASAN_STACK,
+DEFPARAM_GLOBAL (PARAM_ASAN_STACK,
          "asan-stack",
          "Enable asan stack protection.",
          1, 0, 1)
 
-DEFPARAM (PARAM_ASAN_PROTECT_ALLOCAS,
+DEFPARAM_GLOBAL (PARAM_ASAN_PROTECT_ALLOCAS,
 	"asan-instrument-allocas",
 	"Enable asan allocas/VLAs protection.",
 	1, 0, 1)
 
-DEFPARAM (PARAM_ASAN_GLOBALS,
+DEFPARAM_GLOBAL (PARAM_ASAN_GLOBALS,
          "asan-globals",
          "Enable asan globals protection.",
          1, 0, 1)
 
-DEFPARAM (PARAM_ASAN_INSTRUMENT_WRITES,
+DEFPARAM_GLOBAL (PARAM_ASAN_INSTRUMENT_WRITES,
          "asan-instrument-writes",
          "Enable asan store operations protection.",
          1, 0, 1)
 
-DEFPARAM (PARAM_ASAN_INSTRUMENT_READS,
+DEFPARAM_GLOBAL (PARAM_ASAN_INSTRUMENT_READS,
          "asan-instrument-reads",
          "Enable asan load operations protection.",
          1, 0, 1)
 
-DEFPARAM (PARAM_ASAN_MEMINTRIN,
+DEFPARAM_GLOBAL (PARAM_ASAN_MEMINTRIN,
          "asan-memintrin",
          "Enable asan builtin functions protection.",
          1, 0, 1)
 
-DEFPARAM (PARAM_ASAN_USE_AFTER_RETURN,
+DEFPARAM_GLOBAL (PARAM_ASAN_USE_AFTER_RETURN,
          "asan-use-after-return",
          "Enable asan detection of use-after-return bugs.",
          1, 0, 1)
 
-DEFPARAM (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
+DEFPARAM_GLOBAL (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
          "asan-instrumentation-with-call-threshold",
          "Use callbacks instead of inline code if number of accesses "
          "in function becomes greater or equal to this number.",
@@ -1407,7 +1432,7 @@  DEFPARAM(PARAM_AVOID_FMA_MAX_BITS,
 	 "Maximum number of bits for which we avoid creating FMAs.",
 	 0, 0, 512)
 
-DEFPARAM(PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT,
+DEFPARAM_GLOBAL(PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT,
 	 "logical-op-non-short-circuit",
 	 "True if a non-short-circuit operation is optimal.",
 	 -1, -1, 1)
@@ -1431,12 +1456,13 @@  DEFPARAM(PARAM_GIMPLE_FE_COMPUTED_HOT_BB
 	 " The parameter is used only in GIMPLE FE.",
 	 0, 0, 0)
 
-DEFPARAM(PARAM_HASH_TABLE_VERIFICATION_LIMIT,
+DEFPARAM_GLOBAL(PARAM_HASH_TABLE_VERIFICATION_LIMIT,
 	 "hash-table-verification-limit",
 	 "The number of elements for which hash table verification is done for "
 	 "each searched element.",
 	 100, 0, 0)
 
+#undef DEFPARAM
 /*
 
 Local variables:
Index: common.opt
===================================================================
--- common.opt	(revision 272142)
+++ common.opt	(working copy)
@@ -64,7 +64,7 @@  Variable
 bool flag_warn_unused_result = false
 
 Variable
-int *param_values
+struct param_vals *param_values
 
 ; Nonzero if we should write GIMPLE bytecode for link-time optimization.
 Variable
Index: opts.c
===================================================================
--- opts.c	(revision 272142)
+++ opts.c	(working copy)
@@ -292,10 +292,10 @@  init_options_struct (struct gcc_options
   if (opts_set)
     memset (opts_set, 0, sizeof (*opts_set));
 
-  opts->x_param_values = XNEWVEC (int, num_params);
+  opts->x_param_values = XNEWVEC (struct param_vals, num_params);
 
   if (opts_set)
-    opts_set->x_param_values = XCNEWVEC (int, num_params);
+    opts_set->x_param_values = XCNEWVEC (struct param_vals, num_params);
 
   init_param_values (opts->x_param_values);
 
@@ -664,41 +664,10 @@  default_options_optimization (struct gcc
 
   /* Track fields in field-sensitive alias analysis.  */
   maybe_set_param_value
-    (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,
-     opt2 ? 100 : default_param_value (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE),
+    (GLOBAL_PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,
+     opt2 ? 100 : default_param_value (GLOBAL_PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE),
      opts->x_param_values, opts_set->x_param_values);
 
-  /* For -O1 only do loop invariant motion for very small loops.  */
-  maybe_set_param_value
-    (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,
-     opt2 ? default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP)
-     : default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) / 10,
-     opts->x_param_values, opts_set->x_param_values);
-
-  /* For -O1 reduce the maximum number of active local stores for RTL DSE
-     since this can consume huge amounts of memory (PR89115).  */
-  maybe_set_param_value
-    (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES,
-     opt2 ? default_param_value (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES)
-     : default_param_value (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES) / 10,
-     opts->x_param_values, opts_set->x_param_values);
-
-  /* At -Ofast, allow store motion to introduce potential race conditions.  */
-  maybe_set_param_value
-    (PARAM_ALLOW_STORE_DATA_RACES,
-     opts->x_optimize_fast ? 1
-     : default_param_value (PARAM_ALLOW_STORE_DATA_RACES),
-     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);
-
   /* Restrict the amount of work combine does at -Og while retaining
      most of its useful transforms.  */
   if (opts->x_optimize_debug)
@@ -1330,7 +1299,7 @@  print_filtered_help (unsigned int includ
 	    {
 	      snprintf (new_help, sizeof (new_help),
 			_("default %d minimum %d maximum %d"),
-			compiler_params[i].default_value,
+			compiler_params[i].default_value.val[0],
 			compiler_params[i].min_value,
 			compiler_params[i].max_value);
 	      help = new_help;
@@ -2273,17 +2242,19 @@  common_handle_option (struct gcc_options
 	 all features.  */
       if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
 	{
-	  maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
+	  maybe_set_param_value (GLOBAL_PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
 				 0, opts->x_param_values,
 				 opts_set->x_param_values);
-	  maybe_set_param_value (PARAM_ASAN_GLOBALS, 0, opts->x_param_values,
+	  maybe_set_param_value (GLOBAL_PARAM_ASAN_GLOBALS, 0,
+				 opts->x_param_values,
 				 opts_set->x_param_values);
-	  maybe_set_param_value (PARAM_ASAN_STACK, 0, opts->x_param_values,
+	  maybe_set_param_value (GLOBAL_PARAM_ASAN_STACK, 0,
+				 opts->x_param_values,
 				 opts_set->x_param_values);
-	  maybe_set_param_value (PARAM_ASAN_PROTECT_ALLOCAS, 0,
+	  maybe_set_param_value (GLOBAL_PARAM_ASAN_PROTECT_ALLOCAS, 0,
 				 opts->x_param_values,
 				 opts_set->x_param_values);
-	  maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0,
+	  maybe_set_param_value (GLOBAL_PARAM_ASAN_USE_AFTER_RETURN, 0,
 				 opts->x_param_values,
 				 opts_set->x_param_values);
 	}
Index: params-enum.h
===================================================================
--- params-enum.h	(revision 272142)
+++ params-enum.h	(working copy)
@@ -17,7 +17,9 @@  You should have received a copy of the G
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)
+#define DEFPARAM_OPT(ENUM, OPTION, HELP, DEFO1, DEFO2, DEFO3, DEFOfast,\
+		     DEFOsO1, DEFOsO2, MIN, MAX)
+#define DEFPARAM_GLOBAL(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)
 #define DEFPARAMENUMNAME(ENUM) ENUM ## _KIND
 #define DEFPARAMENUMVAL(ENUM, V) ENUM ## _KIND_ ## V
 #define DEFPARAMENUMTERM(ENUM) ENUM ## _KIND_ ## LAST
@@ -36,4 +38,5 @@  along with GCC; see the file COPYING3.
 #undef DEFPARAMENUMTERM
 #undef DEFPARAMENUMVAL
 #undef DEFPARAMENUMNAME
-#undef DEFPARAM
+#undef DEFPARAM_OPT
+#undef DEFPARAM_GLOBAL
Index: params-list.h
===================================================================
--- params-list.h	(revision 272142)
+++ params-list.h	(working copy)
@@ -17,10 +17,14 @@  You should have received a copy of the G
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-#define DEFPARAM(enumerator, option, nocmsgid, default, min, max) \
+#define DEFPARAM_OPT(enumerator, option, nocmsgid, DEFO1, DEFO2, DEFO3, \
+		     DEFOfast, DEFOsO1, DEFOsO2, min, max) \
   enumerator,
+#define DEFPARAM_GLOBAL(enumerator, option, nocmsgid, default, min, max) \
+  GLOBAL_##enumerator,
 #define DEFPARAMENUM5(enumerator, option, nocmsgid, default, \
 		      v0, v1, v2, v3, v4) enumerator,
 #include "params.def"
-#undef DEFPARAM
+#undef DEFPARAM_OPT
+#undef DEFPARAM_GLOBAL
 #undef DEFPARAMENUM5
Index: params-options.h
===================================================================
--- params-options.h	(revision 272142)
+++ params-options.h	(working copy)
@@ -17,11 +17,13 @@  You should have received a copy of the G
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
-#define DEFPARAM(enumerator, option, nocmsgid, default, min, max) \
+#define DEFPARAM(enumerator, option, nocmsgid, defO1, defO2, defO3, defOfast, \
+		 defOs, defOsO1, min, max) \
   option=default,min,max
 #define DEFPARAMENUM5(enumerator, option, nocmsgid, default, \
 		      v0, v1, v2, v3, v4) \
   option=v0,v1,v2,v3,v4
 #include "params.def"
-#undef DEFPARAM
+#undef DEFPARAM_OPT
+#undef DEFPARAM_GLOBAL
 #undef DEFPARAMENUM5
Index: params.c
===================================================================
--- params.c	(revision 272142)
+++ params.c	(working copy)
@@ -28,6 +28,8 @@  along with GCC; see the file COPYING3.
 #include "diagnostic.h"
 #include "spellcheck.h"
 
+#define INIT_VALUES(VAL) {{(VAL), (VAL), (VAL), (VAL), (VAL), (VAL)}}
+
 /* An array containing the compiler parameters and their current
    values.  */
 
@@ -40,27 +42,36 @@  static size_t num_compiler_params;
    default values determined.  */
 static bool params_finished;
 
-#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)
+#define DEFPARAM_OPT(ENUM, OPTION, HELP, DEFO1, DEFO2, DEFO3, DEFOfast, \
+		     DEFOsO1, DEFOsO2, MIN, MAX)
+#define DEFPARAM_GLOBAL(ENUM, OPTION, HELP, DEFAULT, MIN, MAX)
 #define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT, V0, V1, V2, V3, V4)	\
   static const char *values_ ## ENUM [] = { #V0, #V1, #V2, #V3, #V4, NULL };
 #include "params.def"
 #undef DEFPARAMENUM5
-#undef DEFPARAM
+#undef DEFPARAM_OPT
+#undef DEFPARAM_GLOBAL
 
 static const param_info lang_independent_params[] = {
-#define DEFPARAM(ENUM, OPTION, HELP, DEFAULT, MIN, MAX) \
-  { OPTION, DEFAULT, MIN, MAX, HELP, NULL },
+#define DEFPARAM_GLOBAL(ENUM, OPTION, HELP, DEFAULT, MIN, MAX) \
+  { OPTION, {DEFAULT, DEFAULT, DEFAULT, DEFAULT}, MIN, MAX, HELP, NULL },
+#define DEFPARAM_OPT(ENUM, OPTION, HELP, DEFO1, DEFO2, DEFO3, DEFOfast, \
+		     DEFOsO1, DEFOsO2, MIN, MAX) \
+  { OPTION, \
+   {DEFO1, DEFO2, DEFO3, DEFOfast, DEFOsO1, DEFOsO2}, MIN, MAX, HELP, NULL },
 #define DEFPARAMENUM5(ENUM, OPTION, HELP, DEFAULT,	     \
 		      V0, V1, V2, V3, V4)		     \
-  { OPTION, (int)ENUM ## _KIND_ ## DEFAULT, 0, 4, HELP, values_ ## ENUM },
+  { OPTION, INIT_VALUES((int)ENUM ## _KIND_ ## DEFAULT),     \
+    0, 4, HELP, values_ ## ENUM },
 #include "params.def"
-#undef DEFPARAM
+#undef DEFPARAM_OPT
 #undef DEFPARAMENUM5
-  { NULL, 0, 0, 0, NULL, NULL }
+  { NULL, INIT_VALUES (0), 0, 0, NULL, NULL }
 };
 
 static bool
-validate_param (const int value, const param_info param, const int index);
+validate_param (const struct param_vals values,
+		const param_info param, const int index);
 
 
 /* Add the N PARAMS to the current list of compiler parameters.  */
@@ -131,40 +142,66 @@  params_c_finalize (void)
    otherwise it is being set implicitly by the compiler.  */
 
 static void
-set_param_value_internal (compiler_param num, int value,
-			  int *params, int *params_set,
+set_param_value_internal (compiler_param num, struct param_vals value,
+			  struct param_vals *params, 
+			  struct param_vals *params_set,
 			  bool explicit_p)
 {
+  param_vals true_vals = INIT_VALUES (true);
+
   size_t i = (size_t) num;
 
   gcc_assert (params_finished);
 
   params[i] = value;
   if (explicit_p)
-    params_set[i] = true;
+    params_set[i] = true_vals;
+}
+
+/* Same as set_param_value_inter but set only value for given INDEX.  */
+
+static void
+set_param_value_internal_index (compiler_param num, int index,
+				int value,
+			        struct param_vals *params, 
+			        struct param_vals *params_set,
+				bool explicit_p)
+{
+  size_t i = (size_t) num;
+
+  gcc_assert (params_finished);
+
+  params[i].val[index] = value;
+  if (explicit_p)
+    params_set[i].val[index] = true;
 }
 
 /* Validate PARAM and write an error if invalid.  */
 
 static bool
-validate_param (const int value, const param_info param, const int index)
+validate_param (const struct param_vals values,
+	        const param_info param, const int index)
 {
-  /* These paremeters interpret bounds of 0 to be unbounded, as such don't
-     perform any range validation on 0 parameters.  */
-  if (value < param.min_value && param.min_value != 0)
+  for (int i = 0; i < NUM_PARAM_SETTINGS; i++)
     {
-      error ("minimum value of parameter %qs is %u",
-	     param.option, param.min_value);
-      return false;
-    }
-  else if (param.max_value > param.min_value && value > param.max_value)
-    {
-      error ("maximum value of parameter %qs is %u",
-	     param.option, param.max_value);
-      return false;
-    }
-  else if (targetm_common.option_validate_param (value, index))
-    return true;
+      int value = values.val[i];
+      /* These paremeters interpret bounds of 0 to be unbounded, as such don't
+	 perform any range validation on 0 parameters.  */
+      if (value < param.min_value && param.min_value != 0)
+	{
+	  error ("minimum value of parameter %qs is %u",
+		 param.option, param.min_value);
+	  return false;
+	}
+      else if (param.max_value > param.min_value && value > param.max_value)
+	{
+	  error ("maximum value of parameter %qs is %u",
+		 param.option, param.max_value);
+	  return false;
+	}
+      else if (targetm_common.option_validate_param (value, index))
+	return true;
+   }
 
   return false;
 }
@@ -226,9 +263,11 @@  param_string_value_p (enum compiler_para
 
 void
 set_param_value (const char *name, int value,
-		 int *params, int *params_set)
+		 struct param_vals *params, 
+		 struct param_vals *params_set)
 {
   size_t i;
+  struct param_vals values = INIT_VALUES (value);
 
   /* Make sure nobody tries to set a parameter to an invalid value.  */
   gcc_assert (value != INVALID_PARAM_VAL);
@@ -242,8 +281,8 @@  set_param_value (const char *name, int v
     }
   i = (size_t)index;
 
-  if (validate_param (value, compiler_params[i], i))
-    set_param_value_internal ((compiler_param) i, value,
+  if (validate_param (values, compiler_params[i], i))
+    set_param_value_internal ((compiler_param) i, values,
 			      params, params_set, true);
 }
 
@@ -253,10 +292,13 @@  set_param_value (const char *name, int v
 
 void
 maybe_set_param_value (compiler_param num, int value,
-		       int *params, int *params_set)
+		       struct param_vals *params, 
+		       struct param_vals *params_set)
 {
-  if (!params_set[(int) num])
-    set_param_value_internal (num, value, params, params_set, false);
+  for (int index = 0; index < NUM_PARAM_SETTINGS; index++)
+    if (!params_set[(int) num].val[index])
+      set_param_value_internal_index (num, index, value, params,
+				      params_set, false);
 }
 
 /* Set the default value of a parameter given by NUM to VALUE, before
@@ -265,9 +307,10 @@  maybe_set_param_value (compiler_param nu
 void
 set_default_param_value (compiler_param num, int value)
 {
+  struct param_vals vals = INIT_VALUES (value);
   gcc_assert (!params_finished);
 
-  compiler_params[(int) num].default_value = value;
+  compiler_params[(int) num].default_value = vals;
 }
 
 /* Return the default value of parameter NUM.  */
@@ -275,14 +318,14 @@  set_default_param_value (compiler_param
 int
 default_param_value (compiler_param num)
 {
-  return compiler_params[(int) num].default_value;
+  return compiler_params[(int) num].default_value.val[0];
 }
 
 /* Initialize an array PARAMS with default values of the
    parameters.  */
 
 void
-init_param_values (int *params)
+init_param_values (struct param_vals *params)
 {
   size_t i;
 
Index: params.h
===================================================================
--- params.h	(revision 272142)
+++ params.h	(working copy)
@@ -32,10 +32,19 @@  along with GCC; see the file COPYING3.
 #ifndef GCC_PARAMS_H
 #define GCC_PARAMS_H
 
+#define NUM_PARAM_SETTINGS 6
+
 /* No parameter shall have this value.  */
 
 #define INVALID_PARAM_VAL (-1)
 
+/* Default values for given param.  */
+
+struct param_vals
+{
+  int val[NUM_PARAM_SETTINGS];
+};
+
 /* The information associated with each parameter.  */
 
 struct param_info
@@ -45,7 +54,7 @@  struct param_info
   const char *option;
 
   /* The default value.  */
-  int default_value;
+  struct param_vals default_value;
 
   /* Minimum acceptable value.  */
   int min_value;
@@ -77,7 +86,8 @@  extern void add_params (const param_info
    explicitly set.  */
 
 extern void set_param_value (const char *name, int value,
-			     int *params, int *params_set);
+			     struct param_vals *params,
+			     struct param_vals *params_set);
 
 
 /* The parameters in use by language-independent code.  */
@@ -92,16 +102,56 @@  extern bool find_param (const char *, en
 extern const char *find_param_fuzzy (const char *name);
 extern bool param_string_value_p (enum compiler_param, const char *, int *);
 
-/* The value of the parameter given by ENUM.  Not an lvalue.  */
-#define PARAM_VALUE(ENUM) \
-  ((int) global_options.x_param_values[(int) ENUM])
+/* Return index into param values for optimization setting of the function FUN:
+   0 for -O0, -O1 and when optimization level is unknown.
+   1 for -O2
+   2 for -O3
+   3 for -Ofast
+   4 for -Os -O1. 
+   5 for -Os -O2+.  */
+inline int
+param_value_index (bool opt_size, int opt_level, bool opt_fast)
+{
+  if (opt_size)
+    return opt_level <= 1 ? 4 : 5;
+  if (opt_fast)
+    return 3;
+  return MAX (MIN (opt_level-1, 2), 0);
+}
+
+/* The value of the optimization level specific
+   parameter given by ENUM.  Not an lvalue.  */
+#define PARAM_VALUE_FOR_FN(FUN, ENUM)					     \
+  ((int) global_options.x_param_values 					     \
+ 	 [(int) ENUM].val[param_value_index (opt_for_fn (FUN, optimize_size),\
+					     opt_for_fn (FUN, optimize),     \
+					     opt_for_fn (FUN, optimize_fast))])
+/* True if optimization level specific parameter given by ENUM is set.  */
+#define PARAM_VALUE_SET_FOR_FN(FUN, ENUM)				     \
+  ((int) global_options_set.x_param_values 				     \
+ 	 [(int) ENUM].val[param_value_index (opt_for_fn (FUN, optimize_size),\
+					     opt_for_fn (FUN, optimize),     \
+					     opt_for_fn (FUN, optimize_fast))])
+
+/* The value of the optimization level specific
+   parameter given by ENUM.  Not an lvalue.  */
+#define PARAM_VALUE(ENUM) 						     \
+  PARAM_VALUE_FOR_FN(current_function_decl, ENUM)
+/* True if optimization level specific parameter given by ENUM is set.  */
+#define PARAM_VALUE_SET(ENUM) 						     \
+  PARAM_VALUE_SET_FOR_FN(current_function_decl, ENUM)
+#define PARAM_VALUE_GLOBAL(ENUM) 					     \
+  ((int) global_options.x_param_values [(int) GLOBAL_##ENUM].val[0])
+#define PARAM_VALUE_GLOBAL_SET(ENUM) 						     \
+  ((int) global_options_set.x_param_values [(int) GLOBAL_##ENUM].val[0])
 
 /* Set the value of the parameter given by NUM to VALUE, implicitly,
    if it has not been set explicitly by the user, in the table PARAMS
    using PARAMS_SET to indicate which have been explicitly set.  */
 
 extern void maybe_set_param_value (compiler_param num, int value,
-				   int *params, int *params_set);
+				   struct param_vals *params,
+				   struct param_vals *params_set);
 
 /* Set the default value of a parameter given by NUM to VALUE, before
    option processing.  */
@@ -127,19 +177,9 @@  extern int default_param_value (compiler
 
 /* Initialize an array PARAMS with default values of the
    parameters.  */
-extern void init_param_values (int *params);
+extern void init_param_values (struct param_vals *params);
 
 /* Macros for the various parameters.  */
-#define MAX_INLINE_INSNS_SINGLE \
-  PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE)
-#define MAX_INLINE_INSNS \
-  PARAM_VALUE (PARAM_MAX_INLINE_INSNS)
-#define MAX_INLINE_SLOPE \
-  PARAM_VALUE (PARAM_MAX_INLINE_SLOPE)
-#define MIN_INLINE_INSNS \
-  PARAM_VALUE (PARAM_MIN_INLINE_INSNS)
-#define MAX_INLINE_INSNS_AUTO \
-  PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO)
 #define MAX_VARIABLE_EXPANSIONS \
   PARAM_VALUE (PARAM_MAX_VARIABLE_EXPANSIONS)
 #define MIN_VECT_LOOP_BOUND \
@@ -175,15 +215,11 @@  extern void init_param_values (int *para
 #define SMS_LOOP_AVERAGE_COUNT_THRESHOLD \
   PARAM_VALUE (PARAM_SMS_LOOP_AVERAGE_COUNT_THRESHOLD)
 #define INTEGER_SHARE_LIMIT \
-  PARAM_VALUE (PARAM_INTEGER_SHARE_LIMIT)
+  PARAM_VALUE_GLOBAL (PARAM_INTEGER_SHARE_LIMIT)
 #define MAX_LAST_VALUE_RTL \
   PARAM_VALUE (PARAM_MAX_LAST_VALUE_RTL)
-#define MIN_VIRTUAL_MAPPINGS \
-  PARAM_VALUE (PARAM_MIN_VIRTUAL_MAPPINGS)
-#define VIRTUAL_MAPPINGS_TO_SYMS_RATIO \
-  PARAM_VALUE (PARAM_VIRTUAL_MAPPINGS_TO_SYMS_RATIO)
 #define MAX_FIELDS_FOR_FIELD_SENSITIVE \
-  ((size_t) PARAM_VALUE (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE))
+  ((size_t) PARAM_VALUE_GLOBAL (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE))
 #define MAX_SCHED_READY_INSNS \
   PARAM_VALUE (PARAM_MAX_SCHED_READY_INSNS)
 #define PREFETCH_LATENCY \
@@ -201,7 +237,7 @@  extern void init_param_values (int *para
 #define PREFETCH_MINIMUM_STRIDE \
   PARAM_VALUE (PARAM_PREFETCH_MINIMUM_STRIDE)
 #define USE_CANONICAL_TYPES \
-  PARAM_VALUE (PARAM_USE_CANONICAL_TYPES)
+  PARAM_VALUE_GLOBAL (PARAM_USE_CANONICAL_TYPES)
 #define IRA_MAX_LOOPS_NUM \
   PARAM_VALUE (PARAM_IRA_MAX_LOOPS_NUM)
 #define IRA_MAX_CONFLICT_TABLE_SIZE \
@@ -223,7 +259,7 @@  extern void init_param_values (int *para
 #define PREFETCH_MIN_INSN_TO_MEM_RATIO \
   PARAM_VALUE (PARAM_PREFETCH_MIN_INSN_TO_MEM_RATIO)
 #define MIN_NONDEBUG_INSN_UID \
-  PARAM_VALUE (PARAM_MIN_NONDEBUG_INSN_UID)
+  PARAM_VALUE_GLOBAL (PARAM_MIN_NONDEBUG_INSN_UID)
 #define MAX_STORES_TO_SINK \
   PARAM_VALUE (PARAM_MAX_STORES_TO_SINK)
 #define ALLOW_LOAD_DATA_RACES \
@@ -235,21 +271,21 @@  extern void init_param_values (int *para
 #define ALLOW_PACKED_STORE_DATA_RACES \
   PARAM_VALUE (PARAM_ALLOW_PACKED_STORE_DATA_RACES)
 #define ASAN_STACK \
-  PARAM_VALUE (PARAM_ASAN_STACK)
+  PARAM_VALUE_GLOBAL (PARAM_ASAN_STACK)
 #define ASAN_PROTECT_ALLOCAS \
-  PARAM_VALUE (PARAM_ASAN_PROTECT_ALLOCAS)
+  PARAM_VALUE_GLOBAL (PARAM_ASAN_PROTECT_ALLOCAS)
 #define ASAN_GLOBALS \
-  PARAM_VALUE (PARAM_ASAN_GLOBALS)
+  PARAM_VALUE_GLOBAL (PARAM_ASAN_GLOBALS)
 #define ASAN_INSTRUMENT_READS \
-  PARAM_VALUE (PARAM_ASAN_INSTRUMENT_READS)
+  PARAM_VALUE_GLOBAL (PARAM_ASAN_INSTRUMENT_READS)
 #define ASAN_INSTRUMENT_WRITES \
-  PARAM_VALUE (PARAM_ASAN_INSTRUMENT_WRITES)
+  PARAM_VALUE_GLOBAL (PARAM_ASAN_INSTRUMENT_WRITES)
 #define ASAN_MEMINTRIN \
-  PARAM_VALUE (PARAM_ASAN_MEMINTRIN)
+  PARAM_VALUE_GLOBAL (PARAM_ASAN_MEMINTRIN)
 #define ASAN_USE_AFTER_RETURN \
-  PARAM_VALUE (PARAM_ASAN_USE_AFTER_RETURN)
+  PARAM_VALUE_GLOBAL (PARAM_ASAN_USE_AFTER_RETURN)
 #define ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD \
-  PARAM_VALUE (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD)
+  PARAM_VALUE_GLOBAL (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD)
 #define ASAN_PARAM_USE_AFTER_SCOPE_DIRECT_EMISSION_THRESHOLD \
   ((unsigned) PARAM_VALUE (PARAM_USE_AFTER_SCOPE_DIRECT_EMISSION_THRESHOLD))
 
Index: predict.c
===================================================================
--- predict.c	(revision 272142)
+++ predict.c	(working copy)
@@ -132,7 +132,8 @@  get_hot_bb_threshold ()
 {
   if (min_count == -1)
     {
-      gcov_type t = profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION);
+      gcov_type t = profile_info->sum_max / PARAM_VALUE_GLOBAL
+						 (HOT_BB_COUNT_FRACTION);
       set_hot_bb_threshold (t);
       if (dump_file)
 	fprintf (dump_file, "Setting hotness threshold to %" PRId64 ".\n",
@@ -173,9 +174,10 @@  maybe_hot_count_p (struct function *fun,
       if (node->frequency == NODE_FREQUENCY_EXECUTED_ONCE
 	  && count < (ENTRY_BLOCK_PTR_FOR_FN (fun)->count.apply_scale (2, 3)))
 	return false;
-      if (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) == 0)
+      if (PARAM_VALUE_FOR_FN (node->decl, HOT_BB_FREQUENCY_FRACTION) == 0)
 	return false;
-      if (count.apply_scale (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION), 1)
+      if (count.apply_scale (PARAM_VALUE_FOR_FN (node->decl,
+						 HOT_BB_FREQUENCY_FRACTION), 1)
 	  < ENTRY_BLOCK_PTR_FOR_FN (fun)->count)
 	return false;
       return true;
@@ -222,7 +224,8 @@  probably_never_executed (struct function
      desirable.  */
   if (count.precise_p () && profile_status_for_fn (fun) == PROFILE_READ)
     {
-      int unlikely_count_fraction = PARAM_VALUE (UNLIKELY_BB_COUNT_FRACTION);
+      int unlikely_count_fraction = PARAM_VALUE_GLOBAL
+				      (UNLIKELY_BB_COUNT_FRACTION);
       if (count.apply_scale (unlikely_count_fraction, 1) >= profile_info->runs)
 	return false;
       return true;
@@ -413,9 +416,11 @@  predictable_edge_p (edge e)
   if (!e->probability.initialized_p ())
     return false;
   if ((e->probability.to_reg_br_prob_base ()
-       <= PARAM_VALUE (PARAM_PREDICTABLE_BRANCH_OUTCOME) * REG_BR_PROB_BASE / 100)
+       <= PARAM_VALUE (PARAM_PREDICTABLE_BRANCH_OUTCOME)
+			 * REG_BR_PROB_BASE / 100)
       || (REG_BR_PROB_BASE - e->probability.to_reg_br_prob_base ()
-          <= PARAM_VALUE (PARAM_PREDICTABLE_BRANCH_OUTCOME) * REG_BR_PROB_BASE / 100))
+          <= PARAM_VALUE (PARAM_PREDICTABLE_BRANCH_OUTCOME)
+				 * REG_BR_PROB_BASE / 100))
     return true;
   return false;
 }
@@ -3531,7 +3536,7 @@  void
 handle_missing_profiles (void)
 {
   struct cgraph_node *node;
-  int unlikely_count_fraction = PARAM_VALUE (UNLIKELY_BB_COUNT_FRACTION);
+  int unlikely_count_fraction = PARAM_VALUE_GLOBAL (UNLIKELY_BB_COUNT_FRACTION);
   auto_vec<struct cgraph_node *, 64> worklist;
 
   /* See if 0 count function has non-0 count callers.  In this case we
Index: resource.c
===================================================================
--- resource.c	(revision 272142)
+++ resource.c	(working copy)
@@ -30,6 +30,7 @@  along with GCC; see the file COPYING3.
 #include "resource.h"
 #include "insn-attr.h"
 #include "params.h"
+#include "tree.h"
 
 /* This structure is used to record liveness information at the targets or
    fallthrough insns of branches.  We will most likely need the information
Index: sched-ebb.c
===================================================================
--- sched-ebb.c	(revision 272142)
+++ sched-ebb.c	(working copy)
@@ -33,6 +33,7 @@  along with GCC; see the file COPYING3.
 #include "cfgrtl.h"
 #include "cfgbuild.h"
 #include "sched-int.h"
+#include "tree.h"
 
 
 #ifdef INSN_SCHEDULING
Index: sched-rgn.c
===================================================================
--- sched-rgn.c	(revision 272142)
+++ sched-rgn.c	(working copy)
@@ -66,6 +66,7 @@  along with GCC; see the file COPYING3.
 #include "dbgcnt.h"
 #include "pretty-print.h"
 #include "print-rtl.h"
+#include "tree.h"
 
 /* Disable warnings about quoting issues in the pp_xxx calls below
    that (intentionally) don't follow GCC diagnostic conventions.  */
Index: targhooks.c
===================================================================
--- targhooks.c	(revision 272142)
+++ targhooks.c	(working copy)
@@ -2302,7 +2302,7 @@  default_max_noce_ifcvt_seq_cost (edge e)
 
   /* If we have a parameter set, use that, otherwise take a guess using
      BRANCH_COST.  */
-  if (global_options_set.x_param_values[param])
+  if (PARAM_VALUE_SET (param))
     return PARAM_VALUE (param);
   else
     return BRANCH_COST (true, predictable_p) * COSTS_N_INSNS (3);
Index: toplev.c
===================================================================
--- toplev.c	(revision 272142)
+++ toplev.c	(working copy)
@@ -697,7 +697,8 @@  print_version (FILE *file, const char *i
       fprintf (file,
 	       file == stderr ? _(fmt4) : fmt4,
 	       indent, *indent != 0 ? " " : "",
-	       PARAM_VALUE (GGC_MIN_EXPAND), PARAM_VALUE (GGC_MIN_HEAPSIZE));
+	       PARAM_VALUE_GLOBAL (GGC_MIN_EXPAND),
+	       PARAM_VALUE_GLOBAL (GGC_MIN_HEAPSIZE));
 
       print_plugins_versions (file, indent);
     }
@@ -1801,7 +1802,7 @@  process_options (void)
 
   if (flag_checking >= 2)
     hash_table_sanitize_eq_limit
-      = PARAM_VALUE (PARAM_HASH_TABLE_VERIFICATION_LIMIT);
+      = PARAM_VALUE_GLOBAL (PARAM_HASH_TABLE_VERIFICATION_LIMIT);
 
   /* Please don't change global_options after this point, those changes won't
      be reflected in optimization_{default,current}_node.  */
Index: tree-sra.c
===================================================================
--- tree-sra.c	(revision 272142)
+++ tree-sra.c	(working copy)
@@ -2977,7 +2977,7 @@  analyze_all_variable_accesses (void)
   /* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>,
      fall back to a target default.  */
   unsigned HOST_WIDE_INT max_scalarization_size
-    = global_options_set.x_param_values[param]
+    = PARAM_VALUE_SET (param)
       ? PARAM_VALUE (param)
       : get_move_ratio (optimize_speed_p) * UNITS_PER_WORD;
 
@@ -5604,7 +5604,8 @@  ipa_sra_preliminary_function_checks (str
 
   if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl))
       && ipa_fn_summaries->get (node)
-      && ipa_fn_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO)
+      && ipa_fn_summaries->get (node)->size >=
+	   PARAM_VALUE_FOR_FN (node->decl, PARAM_MAX_INLINE_INSNS_AUTO))
     {
       if (dump_file)
 	fprintf (dump_file, "Function too big to be made truly local.\n");
Index: tree-ssa-ifcombine.c
===================================================================
--- tree-ssa-ifcombine.c	(revision 272142)
+++ tree-ssa-ifcombine.c	(working copy)
@@ -565,9 +565,9 @@  ifcombine_ifandif (basic_block inner_con
 	  tree t1, t2;
 	  gimple_stmt_iterator gsi;
 	  bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;
-	  if (PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)
+	  if (PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)
 	    logical_op_non_short_circuit
-	      = PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);
+	      = PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);
 	  if (!logical_op_non_short_circuit || flag_sanitize_coverage)
 	    return false;
 	  /* Only do this optimization if the inner bb contains only the conditional. */
Index: cgraph.c
===================================================================
--- cgraph.c	(revision 272142)
+++ cgraph.c	(working copy)
@@ -2783,8 +2783,10 @@  cgraph_edge::maybe_hot_p (void)
   if (caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE
       && sreal_frequency () * 2 < 3)
     return false;
-  if (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) == 0
-      || sreal_frequency () * PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) <= 1)
+  if (PARAM_VALUE_FOR_FN (caller->decl, HOT_BB_FREQUENCY_FRACTION) == 0
+      || sreal_frequency () * PARAM_VALUE_FOR_FN
+				 (caller->decl,
+				  HOT_BB_FREQUENCY_FRACTION) <= 1)
     return false;
   return true;
 }
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 272142)
+++ config/i386/i386.c	(working copy)
@@ -21449,7 +21449,7 @@  ix86_max_noce_ifcvt_seq_cost (edge e)
 
   /* If we have a parameter set, use that, otherwise take a guess using
      BRANCH_COST.  */
-  if (global_options_set.x_param_values[param])
+  if (PARAM_VALUE_SET (param))
     return PARAM_VALUE (param);
   else
     return BRANCH_COST (true, predictable_p) * COSTS_N_INSNS (2);
Index: coverage.c
===================================================================
--- coverage.c	(revision 272142)
+++ coverage.c	(working copy)
@@ -324,7 +324,7 @@  get_coverage_counts (unsigned counter, u
 	}
       return NULL;
     }
-  if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))
+  if (PARAM_VALUE_GLOBAL (PARAM_PROFILE_FUNC_INTERNAL_ID))
     elt.ident = current_function_funcdef_no + 1;
   else
     {
@@ -560,7 +560,8 @@  coverage_compute_profile_id (struct cgra
     {
       expanded_location xloc
 	= expand_location (DECL_SOURCE_LOCATION (n->decl));
-      bool use_name_only = (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID) == 0);
+      bool use_name_only
+		 = (PARAM_VALUE_GLOBAL (PARAM_PROFILE_FUNC_INTERNAL_ID) == 0);
 
       chksum = (use_name_only ? 0 : xloc.line);
       if (xloc.file)
@@ -628,7 +629,7 @@  coverage_begin_function (unsigned lineno
 
   /* Announce function */
   offset = gcov_write_tag (GCOV_TAG_FUNCTION);
-  if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))
+  if (PARAM_VALUE_GLOBAL (PARAM_PROFILE_FUNC_INTERNAL_ID))
     gcov_write_unsigned (current_function_funcdef_no + 1);
   else
     {
@@ -682,7 +683,7 @@  coverage_end_function (unsigned lineno_c
 
       item = ggc_alloc<coverage_data> ();
 
-      if (PARAM_VALUE (PARAM_PROFILE_FUNC_INTERNAL_ID))
+      if (PARAM_VALUE_GLOBAL (PARAM_PROFILE_FUNC_INTERNAL_ID))
 	item->ident = current_function_funcdef_no + 1;
       else
 	{
Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c	(revision 272142)
+++ cp/name-lookup.c	(working copy)
@@ -5311,7 +5311,7 @@  namespace_hints::namespace_hints (locati
 
   m_candidates = vNULL;
   m_limited = false;
-  m_limit = PARAM_VALUE (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP);
+  m_limit = PARAM_VALUE_GLOBAL (CXX_MAX_NAMESPACES_FOR_DIAGNOSTIC_HELP);
 
   /* Breadth-first search of namespaces.  Up to limit namespaces
      searched (limit zero == unlimited).  */
Index: cprop.c
===================================================================
--- cprop.c	(revision 272142)
+++ cprop.c	(working copy)
@@ -34,6 +34,7 @@  along with GCC; see the file COPYING3.
 #include "cfganal.h"
 #include "lcm.h"
 #include "cfgcleanup.h"
+#include "tree.h"
 #include "params.h"
 #include "cselib.h"
 #include "intl.h"
Index: fold-const.c
===================================================================
--- fold-const.c	(revision 272142)
+++ fold-const.c	(working copy)
@@ -5589,9 +5589,9 @@  fold_range_test (location_t loc, enum tr
      short-circuited branch and the underlying object on both sides
      is the same, make a non-short-circuit operation.  */
   bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;
-  if (PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)
+  if (PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)
     logical_op_non_short_circuit
-      = PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);
+      = PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);
   if (logical_op_non_short_circuit
       && !flag_sanitize_coverage
       && lhs != 0 && rhs != 0
@@ -8255,9 +8255,9 @@  fold_truth_andor (location_t loc, enum t
     return tem;
 
   bool logical_op_non_short_circuit = LOGICAL_OP_NON_SHORT_CIRCUIT;
-  if (PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)
+  if (PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT) != -1)
     logical_op_non_short_circuit
-      = PARAM_VALUE (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);
+      = PARAM_VALUE_GLOBAL (PARAM_LOGICAL_OP_NON_SHORT_CIRCUIT);
   if (logical_op_non_short_circuit
       && !flag_sanitize_coverage
       && (code == TRUTH_AND_EXPR
Index: ggc-page.c
===================================================================
--- ggc-page.c	(revision 272142)
+++ ggc-page.c	(working copy)
@@ -2171,9 +2171,11 @@  ggc_collect (void)
      total allocations haven't expanded much since the last
      collection.  */
   float allocated_last_gc =
-    MAX (G.allocated_last_gc, (size_t)PARAM_VALUE (GGC_MIN_HEAPSIZE) * 1024);
+    MAX (G.allocated_last_gc,
+	 (size_t)PARAM_VALUE_GLOBAL (GGC_MIN_HEAPSIZE) * 1024);
 
-  float min_expand = allocated_last_gc * PARAM_VALUE (GGC_MIN_EXPAND) / 100;
+  float min_expand = allocated_last_gc
+		     * PARAM_VALUE_GLOBAL (GGC_MIN_EXPAND) / 100;
   if (G.allocated < allocated_last_gc + min_expand && !ggc_force_collect)
     return;
 
Index: haifa-sched.c
===================================================================
--- haifa-sched.c	(revision 272142)
+++ haifa-sched.c	(working copy)
@@ -146,6 +146,7 @@  along with GCC; see the file COPYING3.
 #include "cfgloop.h"
 #include "dumpfile.h"
 #include "print-rtl.h"
+#include "tree.h"
 
 #ifdef INSN_SCHEDULING
 
Index: hash-table.h
===================================================================
--- hash-table.h	(revision 272142)
+++ hash-table.h	(working copy)
@@ -386,10 +386,10 @@  public:
 
   /* Create a hash_table in gc memory.  */
   static hash_table *
-  create_ggc (size_t n CXX_MEM_STAT_INFO)
+  create_ggc (size_t n, bool sanitize_eq_and_hash = true CXX_MEM_STAT_INFO)
   {
     hash_table *table = ggc_alloc<hash_table> ();
-    new (table) hash_table (n, true, true, GATHER_STATISTICS,
+    new (table) hash_table (n, true, sanitize_eq_and_hash, GATHER_STATISTICS,
 			    HASH_TABLE_ORIGIN PASS_MEM_STAT);
     return table;
   }
Index: ipa-cp.c
===================================================================
--- ipa-cp.c	(revision 272142)
+++ ipa-cp.c	(working copy)
@@ -1563,7 +1563,8 @@  ipcp_lattice<valtype>::add_value (valtyp
 	return false;
       }
 
-  if (values_count == PARAM_VALUE (PARAM_IPA_CP_VALUE_LIST_SIZE))
+  if (values_count == PARAM_VALUE_FOR_FN (cs->caller->decl,
+					  PARAM_IPA_CP_VALUE_LIST_SIZE))
     {
       /* We can only free sources, not the values themselves, because sources
 	 of other values in this SCC might point to them.   */
@@ -2043,7 +2044,7 @@  merge_agg_lats_step (struct ipcp_param_l
 	  set_agg_lats_to_bottom (dest_plats);
 	  return false;
 	}
-      if (dest_plats->aggs_count == PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS))
+      if (dest_plats->aggs_count == PARAM_VALUE_GLOBAL (PARAM_IPA_MAX_AGG_ITEMS))
 	return false;
       dest_plats->aggs_count++;
       new_al = ipcp_agg_lattice_pool.allocate ();
@@ -2589,11 +2590,13 @@  devirtualization_time_bonus (struct cgra
 
       /* FIXME: The values below need re-considering and perhaps also
 	 integrating into the cost metrics, at lest in some very basic way.  */
-      if (isummary->size <= MAX_INLINE_INSNS_AUTO / 4)
+      int max_inline_insns_auto = PARAM_VALUE_FOR_FN
+			 (node->decl, PARAM_MAX_INLINE_INSNS_AUTO);
+      if (isummary->size <= max_inline_insns_auto / 4)
 	res += 31 / ((int)speculative + 1);
-      else if (isummary->size <= MAX_INLINE_INSNS_AUTO / 2)
+      else if (isummary->size <= max_inline_insns_auto / 2)
 	res += 15 / ((int)speculative + 1);
-      else if (isummary->size <= MAX_INLINE_INSNS_AUTO
+      else if (isummary->size <= max_inline_insns_auto
 	       || DECL_DECLARED_INLINE_P (callee->decl))
 	res += 7 / ((int)speculative + 1);
     }
@@ -2608,9 +2611,9 @@  hint_time_bonus (ipa_hints hints)
 {
   int result = 0;
   if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride))
-    result += PARAM_VALUE (PARAM_IPA_CP_LOOP_HINT_BONUS);
+    result += PARAM_VALUE_GLOBAL (PARAM_IPA_CP_LOOP_HINT_BONUS);
   if (hints & INLINE_HINT_array_index)
-    result += PARAM_VALUE (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS);
+    result += PARAM_VALUE_GLOBAL (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS);
   return result;
 }
 
@@ -2622,11 +2625,13 @@  incorporate_penalties (ipa_node_params *
 {
   if (info->node_within_scc)
     evaluation = (evaluation
-		  * (100 - PARAM_VALUE (PARAM_IPA_CP_RECURSION_PENALTY))) / 100;
+		  * (100 - PARAM_VALUE_GLOBAL
+				 (PARAM_IPA_CP_RECURSION_PENALTY))) / 100;
 
   if (info->node_calling_single_call)
     evaluation = (evaluation
-		  * (100 - PARAM_VALUE (PARAM_IPA_CP_SINGLE_CALL_PENALTY)))
+		  * (100 - PARAM_VALUE_GLOBAL
+				 (PARAM_IPA_CP_SINGLE_CALL_PENALTY)))
       / 100;
 
   return evaluation;
@@ -2666,10 +2671,12 @@  good_cloning_opportunity_p (struct cgrap
 		 ", threshold: %i\n",
 		 info->node_within_scc ? ", scc" : "",
 		 info->node_calling_single_call ? ", single_call" : "",
-		 evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD));
+		 evaluation, PARAM_VALUE_FOR_FN (node->decl,
+						 PARAM_IPA_CP_EVAL_THRESHOLD));
 	}
 
-      return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);
+      return evaluation >= PARAM_VALUE_FOR_FN (node->decl,
+					       PARAM_IPA_CP_EVAL_THRESHOLD);
     }
   else
     {
@@ -2684,9 +2691,11 @@  good_cloning_opportunity_p (struct cgrap
 		 time_benefit, size_cost, freq_sum,
 		 info->node_within_scc ? ", scc" : "",
 		 info->node_calling_single_call ? ", single_call" : "",
-		 evaluation, PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD));
+		 evaluation, PARAM_VALUE_FOR_FN (node->decl,
+						 PARAM_IPA_CP_EVAL_THRESHOLD));
 
-      return evaluation >= PARAM_VALUE (PARAM_IPA_CP_EVAL_THRESHOLD);
+      return evaluation >= PARAM_VALUE_FOR_FN (node->decl,
+					       PARAM_IPA_CP_EVAL_THRESHOLD);
     }
 }
 
@@ -3301,9 +3310,10 @@  ipcp_propagate_stage (struct ipa_topo_in
   }
 
   max_new_size = overall_size;
-  if (max_new_size < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS))
-    max_new_size = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS);
-  max_new_size += max_new_size * PARAM_VALUE (PARAM_IPCP_UNIT_GROWTH) / 100 + 1;
+  if (max_new_size < PARAM_VALUE_GLOBAL (PARAM_LARGE_UNIT_INSNS))
+    max_new_size = PARAM_VALUE_GLOBAL (PARAM_LARGE_UNIT_INSNS);
+  max_new_size += max_new_size
+		  * PARAM_VALUE_GLOBAL (PARAM_IPCP_UNIT_GROWTH) / 100 + 1;
 
   if (dump_file)
     fprintf (dump_file, "\noverall_size: %li, max_new_size: %li\n",
Index: ipa-fnsummary.c
===================================================================
--- ipa-fnsummary.c	(revision 272142)
+++ ipa-fnsummary.c	(working copy)
@@ -1987,9 +1987,9 @@  fp_expression_p (gimple *stmt)
 static void
 analyze_function_body (struct cgraph_node *node, bool early)
 {
-  sreal time = PARAM_VALUE (PARAM_UNINLINED_FUNCTION_TIME);
+  sreal time = PARAM_VALUE_FOR_FN (node->decl, PARAM_UNINLINED_FUNCTION_TIME);
   /* Estimate static overhead for function prologue/epilogue and alignment. */
-  int size = PARAM_VALUE (PARAM_UNINLINED_FUNCTION_INSNS);
+  int size = PARAM_VALUE_FOR_FN (node->decl, PARAM_UNINLINED_FUNCTION_INSNS);
   /* Benefits are scaled by probability of elimination that is in range
      <0,2>.  */
   basic_block bb;
@@ -2037,7 +2037,8 @@  analyze_function_body (struct cgraph_nod
 	  fbi.bb_infos = vNULL;
 	  fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun));
 	  fbi.param_count = count_formal_params (node->decl);
-	  fbi.aa_walk_budget = PARAM_VALUE (PARAM_IPA_MAX_AA_STEPS);
+	  fbi.aa_walk_budget = PARAM_VALUE_FOR_FN (node->decl,
+						   PARAM_IPA_MAX_AA_STEPS);
 
 	  nonconstant_names.safe_grow_cleared
 	    (SSANAMES (my_function)->length ());
@@ -2054,9 +2055,11 @@  analyze_function_body (struct cgraph_nod
   info->account_size_time (0, 0, bb_predicate, bb_predicate);
 
   bb_predicate = predicate::not_inlined ();
-  info->account_size_time (PARAM_VALUE (PARAM_UNINLINED_FUNCTION_INSNS)
+  info->account_size_time (PARAM_VALUE_FOR_FN (node->decl,
+					       PARAM_UNINLINED_FUNCTION_INSNS)
 			   * ipa_fn_summary::size_scale,
-			   PARAM_VALUE (PARAM_UNINLINED_FUNCTION_TIME),
+			   PARAM_VALUE_FOR_FN (node->decl,
+					       PARAM_UNINLINED_FUNCTION_TIME),
 			   bb_predicate,
 		           bb_predicate);
 
@@ -2441,10 +2444,12 @@  compute_fn_summary (struct cgraph_node *
       es->call_stmt_size = eni_size_weights.call_cost;
       es->call_stmt_time = eni_time_weights.call_cost;
       info->account_size_time (ipa_fn_summary::size_scale
-			       * PARAM_VALUE
-				 (PARAM_UNINLINED_FUNCTION_THUNK_INSNS),
-			       PARAM_VALUE
-				 (PARAM_UNINLINED_FUNCTION_THUNK_TIME), t, t);
+			       * PARAM_VALUE_FOR_FN
+				 (node->decl,
+				  PARAM_UNINLINED_FUNCTION_THUNK_INSNS),
+			       PARAM_VALUE_FOR_FN
+				 (node->decl,
+				  PARAM_UNINLINED_FUNCTION_THUNK_TIME), t, t);
       t = predicate::not_inlined ();
       info->account_size_time (2 * ipa_fn_summary::size_scale, 0, t, t);
       ipa_update_overall_fn_summary (node);
Index: ipa-inline-analysis.c
===================================================================
--- ipa-inline-analysis.c	(revision 272142)
+++ ipa-inline-analysis.c	(working copy)
@@ -343,7 +343,8 @@  estimate_growth (struct cgraph_node *nod
       else if (DECL_COMDAT (node->decl)
 	       && node->can_remove_if_no_direct_calls_p ())
 	d.growth -= (info->size
-		     * (100 - PARAM_VALUE (PARAM_COMDAT_SHARING_PROBABILITY))
+		     * (100 - PARAM_VALUE_FOR_FN (node->decl,
+						  PARAM_COMDAT_SHARING_PROBABILITY))
 		     + 50) / 100;
     }
 
Index: ipa-inline.c
===================================================================
--- ipa-inline.c	(revision 272142)
+++ ipa-inline.c	(working copy)
@@ -179,13 +179,15 @@  caller_growth_limits (struct cgraph_edge
   if (limit < what_info->self_size)
     limit = what_info->self_size;
 
-  limit += limit * PARAM_VALUE (PARAM_LARGE_FUNCTION_GROWTH) / 100;
+  limit += limit * PARAM_VALUE_FOR_FN (e->caller->decl,
+				       PARAM_LARGE_FUNCTION_GROWTH) / 100;
 
   /* Check the size after inlining against the function limits.  But allow
      the function to shrink if it went over the limits by forced inlining.  */
   newsize = estimate_size_after_inlining (to, e);
   if (newsize >= info->size
-      && newsize > PARAM_VALUE (PARAM_LARGE_FUNCTION_INSNS)
+      && newsize > PARAM_VALUE_FOR_FN (e->caller->decl,
+				       PARAM_LARGE_FUNCTION_INSNS)
       && newsize > limit)
     {
       e->inline_failed = CIF_LARGE_FUNCTION_GROWTH_LIMIT;
@@ -201,7 +203,8 @@  caller_growth_limits (struct cgraph_edge
      on every invocation of the caller (i.e. its call statement dominates
      exit block).  We do not track this information, yet.  */
   stack_size_limit += ((gcov_type)stack_size_limit
-		       * PARAM_VALUE (PARAM_STACK_FRAME_GROWTH) / 100);
+		       * PARAM_VALUE_FOR_FN (e->caller->decl,
+					     PARAM_STACK_FRAME_GROWTH) / 100);
 
   inlined_stack = (outer_info->stack_frame_offset
 		   + outer_info->estimated_self_stack_size
@@ -214,7 +217,8 @@  caller_growth_limits (struct cgraph_edge
 	 This bit overoptimistically assume that we are good at stack
 	 packing.  */
       && inlined_stack > info->estimated_stack_size
-      && inlined_stack > PARAM_VALUE (PARAM_LARGE_STACK_FRAME))
+      && inlined_stack > PARAM_VALUE_FOR_FN (e->caller->decl,
+					     PARAM_LARGE_STACK_FRAME))
     {
       e->inline_failed = CIF_LARGE_STACK_FRAME_GROWTH_LIMIT;
       return false;
@@ -530,10 +534,15 @@  can_inline_edge_by_limits_p (struct cgra
 	       > opt_for_fn (caller->decl, optimize_size))
 	{
 	  int growth = estimate_edge_growth (e);
-	  if (growth > PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SIZE)
+	  if (growth > PARAM_VALUE_FOR_FN (e->caller->decl,
+					   PARAM_MAX_INLINE_INSNS_SIZE)
 	      && (!DECL_DECLARED_INLINE_P (callee->decl)
-		  && growth >= MAX (MAX_INLINE_INSNS_SINGLE,
-				    MAX_INLINE_INSNS_AUTO)))
+		  && growth >= MAX (PARAM_VALUE_FOR_FN
+				      (e->caller->decl,
+					PARAM_MAX_INLINE_INSNS_SINGLE),
+				    PARAM_VALUE_FOR_FN
+				      (e->caller->decl,
+					PARAM_MAX_INLINE_INSNS_AUTO))))
 	    {
 	      e->inline_failed = CIF_OPTIMIZATION_MISMATCH;
 	      inlinable = false;
@@ -642,7 +651,8 @@  want_early_inline_function_p (struct cgr
       int growth = estimate_edge_growth (e);
       int n;
 
-      if (growth <= PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SIZE))
+      if (growth <= PARAM_VALUE_FOR_FN (e->caller->decl,
+					PARAM_MAX_INLINE_INSNS_SIZE))
 	;
       else if (!e->maybe_hot_p ())
 	{
@@ -654,7 +664,8 @@  want_early_inline_function_p (struct cgr
 			     growth);
 	  want_inline = false;
 	}
-      else if (growth > PARAM_VALUE (PARAM_EARLY_INLINING_INSNS))
+      else if (growth > PARAM_VALUE_FOR_FN (e->caller->decl,
+					    PARAM_EARLY_INLINING_INSNS))
 	{
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
@@ -665,7 +676,9 @@  want_early_inline_function_p (struct cgr
 	  want_inline = false;
 	}
       else if ((n = num_calls (callee)) != 0
-	       && growth * (n + 1) > PARAM_VALUE (PARAM_EARLY_INLINING_INSNS))
+	       && growth * (n + 1) > PARAM_VALUE_FOR_FN
+					 (e->caller->decl,
+					  PARAM_EARLY_INLINING_INSNS))
 	{
 	  if (dump_enabled_p ())
 	    dump_printf_loc (MSG_MISSED_OPTIMIZATION, e->call_stmt,
@@ -741,7 +754,8 @@  big_speedup_p (struct cgraph_edge *e)
   sreal inlined_time = compute_inlined_call_time (e, spec_time);
 
   if ((time - inlined_time) * 100
-      > (sreal) (time * PARAM_VALUE (PARAM_INLINE_MIN_SPEEDUP)))
+      > (sreal) (time * PARAM_VALUE_FOR_FN
+			 (e->caller->decl, PARAM_INLINE_MIN_SPEEDUP)))
     return true;
   return false;
 }
@@ -775,7 +789,10 @@  want_inline_small_function_p (struct cgr
 	   && (!e->count.ipa ().initialized_p () || !e->maybe_hot_p ()))
 	   && ipa_fn_summaries->get (callee)->min_size
 		- ipa_call_summaries->get (e)->call_stmt_size
-	      > MAX (MAX_INLINE_INSNS_SINGLE, MAX_INLINE_INSNS_AUTO))
+	      > MAX (PARAM_VALUE_FOR_FN (e->caller->decl,
+					 PARAM_MAX_INLINE_INSNS_SINGLE),
+		     PARAM_VALUE_FOR_FN (e->caller->decl,
+					 PARAM_MAX_INLINE_INSNS_AUTO)))
     {
       e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
       want_inline = false;
@@ -784,7 +801,8 @@  want_inline_small_function_p (struct cgr
 	    || e->count.ipa ().nonzero_p ())
 	   && ipa_fn_summaries->get (callee)->min_size
 		- ipa_call_summaries->get (e)->call_stmt_size
-	      > 16 * MAX_INLINE_INSNS_SINGLE)
+	      > 16 * PARAM_VALUE_FOR_FN (e->caller->decl,
+					 PARAM_MAX_INLINE_INSNS_SINGLE))
     {
       e->inline_failed = (DECL_DECLARED_INLINE_P (callee->decl)
 			  ? CIF_MAX_INLINE_INSNS_SINGLE_LIMIT
@@ -797,13 +815,16 @@  want_inline_small_function_p (struct cgr
       ipa_hints hints = estimate_edge_hints (e);
       int big_speedup = -1; /* compute this lazily */
 
-      if (growth <= PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SIZE))
+      if (growth <= PARAM_VALUE_FOR_FN
+			 (e->caller->decl, PARAM_MAX_INLINE_INSNS_SIZE))
 	;
       /* Apply MAX_INLINE_INSNS_SINGLE limit.  Do not do so when
 	 hints suggests that inlining given function is very profitable.  */
       else if (DECL_DECLARED_INLINE_P (callee->decl)
-	       && growth >= MAX_INLINE_INSNS_SINGLE
-	       && (growth >= MAX_INLINE_INSNS_SINGLE * 16
+	       && growth >= PARAM_VALUE_FOR_FN (e->caller->decl,
+						PARAM_MAX_INLINE_INSNS_SINGLE)
+	       && (growth >= PARAM_VALUE_FOR_FN (e->caller->decl,
+						 PARAM_MAX_INLINE_INSNS_SINGLE)
 		   || (!(hints & (INLINE_HINT_indirect_call
 				  | INLINE_HINT_known_hot
 				  | INLINE_HINT_loop_iterations
@@ -816,10 +837,12 @@  want_inline_small_function_p (struct cgr
 	}
       else if (!DECL_DECLARED_INLINE_P (callee->decl)
 	       && !opt_for_fn (e->caller->decl, flag_inline_functions)
-	       && growth >= PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SMALL))
+	       && growth >= PARAM_VALUE_FOR_FN
+				 (e->caller->decl, PARAM_MAX_INLINE_INSNS_SMALL))
 	{
 	  /* growth_likely_positive is expensive, always test it last.  */
-          if (growth >= MAX_INLINE_INSNS_SINGLE
+          if (growth >= PARAM_VALUE_FOR_FN (e->caller->decl,
+					    PARAM_MAX_INLINE_INSNS_SINGLE)
 	      || growth_likely_positive (callee, growth))
 	    {
               e->inline_failed = CIF_NOT_DECLARED_INLINED;
@@ -835,13 +858,19 @@  want_inline_small_function_p (struct cgr
 				       | INLINE_HINT_loop_iterations
 			               | INLINE_HINT_array_index
 				       | INLINE_HINT_loop_stride))
-			     ? MAX (MAX_INLINE_INSNS_AUTO,
-				    MAX_INLINE_INSNS_SINGLE)
-			     : MAX_INLINE_INSNS_AUTO)
+			     ? MAX (PARAM_VALUE_FOR_FN
+					 (e->caller->decl,
+					  PARAM_MAX_INLINE_INSNS_AUTO),
+				    PARAM_VALUE_FOR_FN
+					 (e->caller->decl,
+					  PARAM_MAX_INLINE_INSNS_SINGLE))
+			     : PARAM_VALUE_FOR_FN (e->caller->decl,
+						   PARAM_MAX_INLINE_INSNS_AUTO))
 	       && !(big_speedup == -1 ? big_speedup_p (e) : big_speedup))
 	{
 	  /* growth_likely_positive is expensive, always test it last.  */
-          if (growth >= MAX_INLINE_INSNS_SINGLE
+          if (growth >=	PARAM_VALUE_FOR_FN (e->caller->decl,
+				     	    PARAM_MAX_INLINE_INSNS_SINGLE)
 	      || growth_likely_positive (callee, growth))
 	    {
 	      e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
@@ -850,7 +879,8 @@  want_inline_small_function_p (struct cgr
 	}
       /* If call is cold, do not inline when function body would grow. */
       else if (!e->maybe_hot_p ()
-	       && (growth >= MAX_INLINE_INSNS_SINGLE
+	       && (growth >= PARAM_VALUE_FOR_FN (e->caller->decl,
+						 PARAM_MAX_INLINE_INSNS_SINGLE)
 		   || growth_likely_positive (callee, growth)))
 	{
           e->inline_failed = CIF_UNLIKELY_CALL;
@@ -882,10 +912,12 @@  want_inline_self_recursive_call_p (struc
   char const *reason = NULL;
   bool want_inline = true;
   sreal caller_freq = 1;
-  int max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO);
+  int max_depth = PARAM_VALUE_FOR_FN (edge->caller->decl,
+				      PARAM_MAX_INLINE_RECURSIVE_DEPTH_AUTO);
 
   if (DECL_DECLARED_INLINE_P (edge->caller->decl))
-    max_depth = PARAM_VALUE (PARAM_MAX_INLINE_RECURSIVE_DEPTH);
+    max_depth = PARAM_VALUE_FOR_FN (edge->caller->decl,
+				    PARAM_MAX_INLINE_RECURSIVE_DEPTH);
 
   if (!edge->maybe_hot_p ())
     {
@@ -947,7 +979,8 @@  want_inline_self_recursive_call_p (struc
     {
       if (edge->sreal_frequency () * 100
           <= caller_freq
-	     * PARAM_VALUE (PARAM_MIN_INLINE_RECURSIVE_PROBABILITY))
+	     * PARAM_VALUE_FOR_FN (edge->caller->decl,
+			           PARAM_MIN_INLINE_RECURSIVE_PROBABILITY))
 	{
 	  reason = "frequency of recursive call is too small";
 	  want_inline = false;
@@ -1144,8 +1177,9 @@  edge_badness (struct cgraph_edge *edge,
 		 frequency still indicates splitting is a win ... */
 	      || (callee->split_part && !caller->split_part
 		  && edge->sreal_frequency () * 100
-		     < PARAM_VALUE
-			  (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY)
+		     < PARAM_VALUE_FOR_FN
+			  (caller->decl,
+			   PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY)
 		  /* ... and do not overwrite user specified hints.   */
 		  && (!DECL_DECLARED_INLINE_P (edge->callee->decl)
 		      || DECL_DECLARED_INLINE_P (caller->decl)))))
@@ -1158,8 +1192,10 @@  edge_badness (struct cgraph_edge *edge,
 	  if (!caller_info->single_caller && overall_growth < caller_growth
 	      && caller_info->inlinable
 	      && caller_info->size
-		 < (DECL_DECLARED_INLINE_P (caller->decl)
-		    ? MAX_INLINE_INSNS_SINGLE : MAX_INLINE_INSNS_AUTO))
+		 < PARAM_VALUE_FOR_FN (caller->decl,
+			(DECL_DECLARED_INLINE_P (caller->decl)
+			 ? PARAM_MAX_INLINE_INSNS_SINGLE
+			 : PARAM_MAX_INLINE_INSNS_AUTO)))
 	    {
 	      if (dump)
 		fprintf (dump_file,
@@ -1473,7 +1509,8 @@  static bool
 recursive_inlining (struct cgraph_edge *edge,
 		    vec<cgraph_edge *> *new_edges)
 {
-  int limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO);
+  int limit = PARAM_VALUE_FOR_FN (edge->caller->decl,
+				  PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO);
   edge_heap_t heap (sreal::min ());
   struct cgraph_node *node;
   struct cgraph_edge *e;
@@ -1486,7 +1523,7 @@  recursive_inlining (struct cgraph_edge *
     node = node->global.inlined_to;
 
   if (DECL_DECLARED_INLINE_P (node->decl))
-    limit = PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RECURSIVE);
+    limit = PARAM_VALUE_FOR_FN (node->decl, PARAM_MAX_INLINE_INSNS_RECURSIVE);
 
   /* Make sure that function is small enough to be considered for inlining.  */
   if (estimate_size_after_inlining (node, edge)  >= limit)
@@ -1611,11 +1648,11 @@  static int
 compute_max_insns (int insns)
 {
   int max_insns = insns;
-  if (max_insns < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS))
-    max_insns = PARAM_VALUE (PARAM_LARGE_UNIT_INSNS);
+  if (max_insns < PARAM_VALUE_GLOBAL (PARAM_LARGE_UNIT_INSNS))
+    max_insns = PARAM_VALUE_GLOBAL (PARAM_LARGE_UNIT_INSNS);
 
   return ((int64_t) max_insns
-	  * (100 + PARAM_VALUE (PARAM_INLINE_UNIT_GROWTH)) / 100);
+	  * (100 + PARAM_VALUE_GLOBAL (PARAM_INLINE_UNIT_GROWTH)) / 100);
 }
 
 
Index: ipa-profile.c
===================================================================
--- ipa-profile.c	(revision 272142)
+++ ipa-profile.c	(working copy)
@@ -506,7 +506,8 @@  ipa_profile (void)
 
       gcc_assert (overall_size);
 
-      cutoff = (overall_time * PARAM_VALUE (HOT_BB_COUNT_WS_PERMILLE) + 500) / 1000;
+      cutoff = (overall_time * PARAM_VALUE_GLOBAL
+			 (HOT_BB_COUNT_WS_PERMILLE) + 500) / 1000;
       threshold = 0;
       for (i = 0; cumulated < cutoff; i++)
 	{
Index: ipa-prop.c
===================================================================
--- ipa-prop.c	(revision 272142)
+++ ipa-prop.c	(working copy)
@@ -1547,7 +1547,7 @@  determine_locally_known_aggregate_parts
   bool check_ref, by_ref;
   ao_ref r;
 
-  if (PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS) == 0)
+  if (PARAM_VALUE_GLOBAL (PARAM_IPA_MAX_AGG_ITEMS) == 0)
     return;
 
   /* The function operates in three stages.  First, we prepare check_ref, r,
@@ -1675,8 +1675,8 @@  determine_locally_known_aggregate_parts
       *p = n;
 
       item_count++;
-      if (const_count == PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS)
-	  || item_count == 2 * PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS))
+      if (const_count == PARAM_VALUE_GLOBAL (PARAM_IPA_MAX_AGG_ITEMS)
+	  || item_count == 2 * PARAM_VALUE_GLOBAL (PARAM_IPA_MAX_AGG_ITEMS))
 	break;
     }
 
Index: ipa-split.c
===================================================================
--- ipa-split.c	(revision 272142)
+++ ipa-split.c	(working copy)
@@ -561,8 +561,8 @@  consider_split (struct split_point *curr
      that.  Next stage1 we should try to be more meaningful here.  */
   if (current->header_size + call_overhead
       >= (unsigned int)(DECL_DECLARED_INLINE_P (current_function_decl)
-			? MAX_INLINE_INSNS_SINGLE
-			: MAX_INLINE_INSNS_AUTO) + 10)
+			? PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE)
+			: PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO)) + 10)
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
 	fprintf (dump_file,
@@ -575,7 +575,8 @@  consider_split (struct split_point *curr
      Limit this duplication.  This is consistent with limit in tree-sra.c  
      FIXME: with LTO we ought to be able to do better!  */
   if (DECL_ONE_ONLY (current_function_decl)
-      && current->split_size >= (unsigned int) MAX_INLINE_INSNS_AUTO + 10)
+      && current->split_size
+	   >= (unsigned int) PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO) + 10)
     {
       if (dump_file && (dump_flags & TDF_DETAILS))
 	fprintf (dump_file,
Index: ira-build.c
===================================================================
--- ira-build.c	(revision 272142)
+++ ira-build.c	(working copy)
@@ -34,6 +34,7 @@  along with GCC; see the file COPYING3.
 #include "params.h"
 #include "sparseset.h"
 #include "cfgloop.h"
+#include "tree.h"
 
 static ira_copy_t find_allocno_copy (ira_allocno_t, ira_allocno_t, rtx_insn *,
 				     ira_loop_tree_node_t);
Index: ira-conflicts.c
===================================================================
--- ira-conflicts.c	(revision 272142)
+++ ira-conflicts.c	(working copy)
@@ -34,6 +34,7 @@  along with GCC; see the file COPYING3.
 #include "params.h"
 #include "sparseset.h"
 #include "addresses.h"
+#include "tree.h"
 
 /* This file contains code responsible for allocno conflict creation,
    allocno copy creation and allocno info accumulation on upper level
Index: lto/lto-partition.c
===================================================================
--- lto/lto-partition.c	(revision 272142)
+++ lto/lto-partition.c	(working copy)
@@ -560,13 +560,13 @@  lto_balanced_map (int n_lto_partitions,
   varpool_order.qsort (varpool_node_cmp);
 
   /* Compute partition size and create the first partition.  */
-  if (PARAM_VALUE (MIN_PARTITION_SIZE) > max_partition_size)
+  if (PARAM_VALUE_GLOBAL (MIN_PARTITION_SIZE) > max_partition_size)
     fatal_error (input_location, "min partition size cannot be greater "
 		 "than max partition size");
 
   partition_size = total_size / n_lto_partitions;
-  if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE))
-    partition_size = PARAM_VALUE (MIN_PARTITION_SIZE);
+  if (partition_size < PARAM_VALUE_GLOBAL (MIN_PARTITION_SIZE))
+    partition_size = PARAM_VALUE_GLOBAL (MIN_PARTITION_SIZE);
   npartitions = 1;
   partition = new_partition ("");
   if (dump_file)
@@ -816,8 +816,8 @@  lto_balanced_map (int n_lto_partitions,
 	    fprintf (dump_file,
 		     "Total size: %" PRId64 " partition_size: %" PRId64 "\n",
 		     total_size, partition_size);
-	  if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE))
-	    partition_size = PARAM_VALUE (MIN_PARTITION_SIZE);
+	  if (partition_size < PARAM_VALUE_GLOBAL (MIN_PARTITION_SIZE))
+	    partition_size = PARAM_VALUE_GLOBAL (MIN_PARTITION_SIZE);
 	  npartitions ++;
 	}
     }
Index: lto/lto.c
===================================================================
--- lto/lto.c	(revision 272142)
+++ lto/lto.c	(working copy)
@@ -420,14 +420,16 @@  do_whole_program_analysis (void)
 
   /* TODO: jobserver communication is not supported, yet.  */
   if (!strcmp (flag_wpa, "jobserver"))
-    lto_parallelism = PARAM_VALUE (PARAM_MAX_LTO_STREAMING_PARALLELISM);
+    lto_parallelism = PARAM_VALUE_GLOBAL (PARAM_MAX_LTO_STREAMING_PARALLELISM);
   else
     {
       lto_parallelism = atoi (flag_wpa);
       if (lto_parallelism <= 0)
 	lto_parallelism = 0;
-      if (lto_parallelism >= PARAM_VALUE (PARAM_MAX_LTO_STREAMING_PARALLELISM))
-	lto_parallelism = PARAM_VALUE (PARAM_MAX_LTO_STREAMING_PARALLELISM);
+      if (lto_parallelism >= PARAM_VALUE_GLOBAL
+				 (PARAM_MAX_LTO_STREAMING_PARALLELISM))
+	lto_parallelism = PARAM_VALUE_GLOBAL
+			     (PARAM_MAX_LTO_STREAMING_PARALLELISM);
     }
 
   timevar_start (TV_PHASE_OPT_GEN);
@@ -479,8 +481,8 @@  do_whole_program_analysis (void)
   else if (flag_lto_partition == LTO_PARTITION_ONE)
     lto_balanced_map (1, INT_MAX);
   else if (flag_lto_partition == LTO_PARTITION_BALANCED)
-    lto_balanced_map (PARAM_VALUE (PARAM_LTO_PARTITIONS),
-		      PARAM_VALUE (MAX_PARTITION_SIZE));
+    lto_balanced_map (PARAM_VALUE_GLOBAL (PARAM_LTO_PARTITIONS),
+		      PARAM_VALUE_GLOBAL (MAX_PARTITION_SIZE));
   else
     gcc_unreachable ();