Message ID | Pine.LNX.4.64.1011170917350.27921@digraph.polyomino.org.uk |
---|---|
State | New |
Headers | show |
On Wed, Nov 17, 2010 at 10:18 AM, Joseph S. Myers <joseph@codesourcery.com> wrote: > This patch implements a general system for command-line options to be > deferred for handling after the main sequence of calls to option > handlers. > > The purpose of this is to separate those parts of option > handling/initialization that are best kept out of the driver > (involving RTL, registers, etc.) from those that can be shared with > the driver. > > The deferred handling goes in a new file opts-global.c. The intended > division is: opts-common.c for general option-handling code not > involving global data or the details of individual options, opts.c for > code relating to details of individual options but not involving > global data or state not readily available in the driver, > opts-global.c for code depending on global state or state not > available in the driver in ways that are hard to remove. There are > still plenty of cases of options in opts.c using global data that will > need addressing in one way or another; the ones moved in this patch > are the ones for which it seems clearest that moving them is the right > approach. > > Right now the deferred handling of common options is called from > toplev.c immediately after decode_options. (None of the options in > question is an optimization option so we don't need to worry about > handling them in other calls to decode_options.) This may move > elsewhere as the option initialization in toplev.c:process_options > gets better integrated with that in opts.c:finish_options. > > Deferred handling is already used by at least C-family and Fortran > front ends for some preprocessor options; this patch doesn't do > anything with that although it would probably make sense to move it to > the new mechanism. > > The deferred options are stored in a VEC; where multiple sets of > deferred options are useful, different options can specify different > Var settings along with Defer in the .opt file. However, the > gcc_options field is declared as void *. This is because declaring > VEC types also defines inline functions, which need symbols from > vec.c, and options.h is included in tm.h which is included in target > code and miscellaneous host programs such as gcov which don't use > vec.c. If uses of tm.h in code built for the target are eliminated, > it may then make sense to revisit this, add vec.o and ggc-none.o to > all miscellaneous host programs not using them (it seems reasonable to > consider VECs generic infrastructure it's OK to link into all > programs), and give the fields their proper VEC types. > > Bootstrapped with no regressions on x86_64-unknown-linux-gnu. OK to > commit? Ok. Thanks, Richard. > 2010-11-17 Joseph Myers <joseph@codesourcery.com> > > * doc/options.texi (Var): Document effects of Defer. > (Defer): Document. > * opt-functions.awk (var_type, var_set): Handle deferred options. > * opts-common.c (set_option): Handle CLVC_DEFER. > * common.opt (fcall-saved-, fcall-used-, fdump-, ffixed-, > fplugin=, fplugin-arg-, fstack-limit, fstack-limit-register=, > fstack-limit-symbol=): Mark as deferred. > * opts.c: Don't include rtl.h, ggc.h, output.h, tree-pass.h or > plugin.h. > (print_filtered_help): Don't report state of CLVC_DEFER options. > (common_handle_option): Move code for OPT_fcall_used_, > OPT_fcall_saved_, OPT_fdump_, OPT_ffixed_, OPT_fplugin_, > OPT_fplugin_arg_, OPT_fstack_limit, OPT_fstack_limit_register_ and > OPT_fstack_limit_symbol_ to opts-global.c. > (option_enabled, get_option_state): Hanle CLVC_DEFER. > * opts.h: Include vec.h. > (enum cl_var_type): Add CLVC_DEFER. > (cl_deferred_option): Define type and vectors. > (handle_common_deferred_options): Declare. > * opts-global.c: New. > * toplev.c (toplev_main): Call handle_common_deferred_options > * Makefile.in (OPTS_H): Include $(VEC_H). > (OBJS-common): Include opts-global.o. > (opts.o): Update dependencies. > (opts-global.o): Add dependencies. > > Index: gcc/doc/options.texi > =================================================================== > --- gcc/doc/options.texi (revision 166795) > +++ gcc/doc/options.texi (working copy) > @@ -201,6 +201,12 @@ If the option takes an argument and has > @var{var} is an integer variable that stores the value of the argument. > > @item > +If the option has the @code{Defer} property, @var{var} is a pointer to > +a @code{VEC(cl_deferred_option,heap)} that stores the option for later > +processing. (@var{var} is declared with type @code{void *} and needs > +to be cast to @code{VEC(cl_deferred_option,heap)} before use.) > + > +@item > Otherwise, if the option takes an argument, @var{var} is a pointer to > the argument string. The pointer will be null if the argument is optional > and wasn't given. > @@ -255,6 +261,10 @@ The main purpose of this property is to > The first option should use @samp{Mask(@var{name})} and the others > should use @samp{Mask(@var{name}) MaskExists}. > > +@item Defer > +The option should be stored in a vector, specified with @code{Var}, > +for later processing. > + > @item Alias(@var{opt}) > @itemx Alias(@var{opt}, @var{arg}) > @itemx Alias(@var{opt}, @var{posarg}, @var{negarg}) > Index: gcc/opts-common.c > =================================================================== > --- gcc/opts-common.c (revision 166795) > +++ gcc/opts-common.c (working copy) > @@ -958,6 +958,22 @@ set_option (struct gcc_options *opts, st > if (set_flag_var) > *(const char **) set_flag_var = ""; > break; > + > + case CLVC_DEFER: > + { > + VEC(cl_deferred_option,heap) *vec > + = (VEC(cl_deferred_option,heap) *) *(void **) flag_var; > + cl_deferred_option *p; > + > + p = VEC_safe_push (cl_deferred_option, heap, vec, NULL); > + p->opt_index = opt_index; > + p->arg = arg; > + p->value = value; > + *(void **) flag_var = vec; > + if (set_flag_var) > + *(void **) set_flag_var = vec; > + } > + break; > } > > if ((diagnostic_t) kind != DK_UNSPECIFIED > Index: gcc/toplev.c > =================================================================== > --- gcc/toplev.c (revision 166795) > +++ gcc/toplev.c (working copy) > @@ -2365,6 +2365,8 @@ toplev_main (int argc, char **argv) > save_decoded_options, save_decoded_options_count, > UNKNOWN_LOCATION, global_dc); > > + handle_common_deferred_options (); > + > init_local_tick (); > > initialize_plugins (); > Index: gcc/opts.c > =================================================================== > --- gcc/opts.c (revision 166795) > +++ gcc/opts.c (working copy) > @@ -25,10 +25,7 @@ along with GCC; see the file COPYING3. > #include "coretypes.h" > #include "tm.h" > #include "tree.h" > -#include "rtl.h" > #include "expr.h" > -#include "ggc.h" > -#include "output.h" > #include "langhooks.h" > #include "opts.h" > #include "options.h" > @@ -39,10 +36,8 @@ along with GCC; see the file COPYING3. > #include "opts-diagnostic.h" > #include "insn-attr.h" /* For INSN_SCHEDULING. */ > #include "target.h" > -#include "tree-pass.h" > #include "dbgcnt.h" > #include "debug.h" > -#include "plugin.h" > #include "except.h" > #include "lto-streamer.h" > > @@ -1440,7 +1435,8 @@ print_filtered_help (unsigned int includ > else > strcpy (new_help, "\t"); > > - if (flag_var != NULL) > + if (flag_var != NULL > + && option->var_type != CLVC_DEFER) > { > if (option->flags & CL_JOINED) > { > @@ -1839,11 +1835,8 @@ common_handle_option (struct gcc_options > break; > > case OPT_fcall_used_: > - fix_register (arg, 0, 1); > - break; > - > case OPT_fcall_saved_: > - fix_register (arg, 0, 0); > + /* Deferred. */ > break; > > case OPT_fcompare_debug_second: > @@ -1877,8 +1870,7 @@ common_handle_option (struct gcc_options > break; > > case OPT_fdump_: > - if (!dump_switch_p (arg)) > - return false; > + /* Deferred. */ > break; > > case OPT_ffp_contract_: > @@ -1911,7 +1903,7 @@ common_handle_option (struct gcc_options > break; > > case OPT_ffixed_: > - fix_register (arg, 1, 1); > + /* Deferred. */ > break; > > case OPT_finline_limit_: > @@ -1946,19 +1938,8 @@ common_handle_option (struct gcc_options > break; > > case OPT_fplugin_: > -#ifdef ENABLE_PLUGIN > - add_new_plugin (arg); > -#else > - error ("plugin support is disabled; configure with --enable-plugin"); > -#endif > - break; > - > case OPT_fplugin_arg_: > -#ifdef ENABLE_PLUGIN > - parse_plugin_arg_opt (arg); > -#else > - error ("plugin support is disabled; configure with --enable-plugin"); > -#endif > + /* Deferred. */ > break; > > case OPT_fprofile_dir_: > @@ -2084,21 +2065,12 @@ common_handle_option (struct gcc_options > /* The real switch is -fno-stack-limit. */ > if (value) > return false; > - stack_limit_rtx = NULL_RTX; > + /* Deferred. */ > break; > > case OPT_fstack_limit_register_: > - { > - int reg = decode_reg_name (arg); > - if (reg < 0) > - error ("unrecognized register name \"%s\"", arg); > - else > - stack_limit_rtx = gen_rtx_REG (Pmode, reg); > - } > - break; > - > case OPT_fstack_limit_symbol_: > - stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (arg)); > + /* Deferred. */ > break; > > case OPT_ftree_vectorizer_verbose_: > @@ -2380,6 +2352,7 @@ option_enabled (int opt_idx, void *opts) > return (*(int *) flag_var & option->var_value) != 0; > > case CLVC_STRING: > + case CLVC_DEFER: > break; > } > return -1; > @@ -2418,6 +2391,9 @@ get_option_state (struct gcc_options *op > state->data = ""; > state->size = strlen ((const char *) state->data) + 1; > break; > + > + case CLVC_DEFER: > + return false; > } > return true; > } > Index: gcc/opts.h > =================================================================== > --- gcc/opts.h (revision 166795) > +++ gcc/opts.h (working copy) > @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. > #define GCC_OPTS_H > > #include "input.h" > +#include "vec.h" > > /* Specifies how a switch's VAR_VALUE relates to its FLAG_VAR. */ > enum cl_var_type { > @@ -39,7 +40,11 @@ enum cl_var_type { > > /* The switch takes a string argument and FLAG_VAR points to that > argument. */ > - CLVC_STRING > + CLVC_STRING, > + > + /* The switch should be stored in the VEC pointed to by FLAG_VAR for > + later processing. */ > + CLVC_DEFER > }; > > struct cl_option > @@ -158,6 +163,20 @@ struct cl_decoded_option > int errors; > }; > > +/* Structure describing an option deferred for handling after the main > + option handlers. */ > + > +typedef struct > +{ > + /* Elements from struct cl_decoded_option used for deferred > + options. */ > + size_t opt_index; > + const char *arg; > + int value; > +} cl_deferred_option; > +DEF_VEC_O(cl_deferred_option); > +DEF_VEC_ALLOC_O(cl_deferred_option,heap); > + > /* Structure describing a single option-handling callback. */ > > struct cl_option_handler_func > @@ -264,4 +283,5 @@ extern void control_warning_option (unsi > struct gcc_options *opts_set, > diagnostic_context *dc); > extern void print_ignored_options (void); > +extern void handle_common_deferred_options (void); > #endif > Index: gcc/common.opt > =================================================================== > --- gcc/common.opt (revision 166795) > +++ gcc/common.opt (working copy) > @@ -710,11 +710,11 @@ Common Report Var(flag_btr_bb_exclusive) > Restrict target load migration not to re-use registers in any basic block > > fcall-saved- > -Common Joined RejectNegative > +Common Joined RejectNegative Var(common_deferred_options) Defer > -fcall-saved-<register> Mark <register> as being preserved across functions > > fcall-used- > -Common Joined RejectNegative > +Common Joined RejectNegative Var(common_deferred_options) Defer > -fcall-used-<register> Mark <register> as being corrupted by function calls > > ; Nonzero for -fcaller-saves: allocate values in regs that need to > @@ -815,7 +815,7 @@ Common Var(flag_diagnostics_show_option) > Amend appropriate diagnostic messages with the command line option that controls them > > fdump- > -Common Joined RejectNegative > +Common Joined RejectNegative Var(common_deferred_options) Defer > -fdump-<type> Dump various compiler internals to a file > > fdump-final-insns > @@ -893,7 +893,7 @@ Common Report Var(flag_finite_math_only) > Assume no NaNs or infinities are generated > > ffixed- > -Common Joined RejectNegative > +Common Joined RejectNegative Var(common_deferred_options) Defer > -ffixed-<register> Mark <register> as being unavailable to the compiler > > ffloat-store > @@ -1306,11 +1306,11 @@ Common Report Var(flag_pie,1) > Generate position-independent code for executables if possible (small mode) > > fplugin= > -Common Joined RejectNegative > +Common Joined RejectNegative Var(common_deferred_options) Defer > Specify a plugin to load > > fplugin-arg- > -Common Joined RejectNegative > +Common Joined RejectNegative Var(common_deferred_options) Defer > -fplugin-arg-<name>-<key>[=<value>] Specify argument <key>=<value> for plugin <name> > > fpredictive-commoning > @@ -1573,14 +1573,14 @@ Common Alias(fstack-check=, specific, no > Insert stack checking code into the program. Same as -fstack-check=specific > > fstack-limit > -Common > +Common Var(common_deferred_options) Defer > > fstack-limit-register= > -Common RejectNegative Joined > +Common RejectNegative Joined Var(common_deferred_options) Defer > -fstack-limit-register=<register> Trap if the stack goes past <register> > > fstack-limit-symbol= > -Common RejectNegative Joined > +Common RejectNegative Joined Var(common_deferred_options) Defer > -fstack-limit-symbol=<name> Trap if the stack goes past symbol <name> > > fstack-protector > Index: gcc/opt-functions.awk > =================================================================== > --- gcc/opt-functions.awk (revision 166795) > +++ gcc/opt-functions.awk (working copy) > @@ -148,7 +148,9 @@ function static_var(name, flags) > # Return the type of variable that should be associated with the given flags. > function var_type(flags) > { > - if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) > + if (flag_set_p("Defer", flags)) > + return "void *" > + else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) > return "int " > else if (flag_set_p("UInteger", flags)) > return "int " > @@ -177,6 +179,8 @@ function var_type_struct(flags) > # "var_cond" and "var_value" fields of its cl_options[] entry. > function var_set(flags) > { > + if (flag_set_p("Defer", flags)) > + return "CLVC_DEFER, 0" > s = nth_arg(1, opt_args("Var", flags)) > if (s != "") > return "CLVC_EQUAL, " s > Index: gcc/opts-global.c > =================================================================== > --- gcc/opts-global.c (revision 0) > +++ gcc/opts-global.c (revision 0) > @@ -0,0 +1,105 @@ > +/* Command line option handling. Code involving global state that > + should not be shared with the driver. > + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 > + Free Software Foundation, Inc. > + > +This file is part of GCC. > + > +GCC is free software; you can redistribute it and/or modify it under > +the terms of the GNU General Public License as published by the Free > +Software Foundation; either version 3, or (at your option) any later > +version. > + > +GCC is distributed in the hope that it will be useful, but WITHOUT ANY > +WARRANTY; without even the implied warranty of MERCHANTABILITY or > +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License > +for more details. > + > +You should have received a copy of the GNU General Public License > +along with GCC; see the file COPYING3. If not see > +<http://www.gnu.org/licenses/>. */ > + > +#include "config.h" > +#include "system.h" > +#include "coretypes.h" > +#include "diagnostic-core.h" > +#include "opts.h" > +#include "flags.h" > +#include "ggc.h" > +#include "tm.h" /* Required by rtl.h. */ > +#include "rtl.h" > +#include "output.h" > +#include "plugin.h" > +#include "tree-pass.h" > + > +void > +handle_common_deferred_options (void) > +{ > + unsigned int i; > + cl_deferred_option *opt; > + VEC(cl_deferred_option,heap) *vec > + = (VEC(cl_deferred_option,heap) *) common_deferred_options; > + > + FOR_EACH_VEC_ELT (cl_deferred_option, vec, i, opt) > + { > + switch (opt->opt_index) > + { > + case OPT_fcall_used_: > + fix_register (opt->arg, 0, 1); > + break; > + > + case OPT_fcall_saved_: > + fix_register (opt->arg, 0, 0); > + break; > + > + case OPT_fdump_: > + if (!dump_switch_p (opt->arg)) > + error ("unrecognized command line option %<-fdump-%s%>", opt->arg); > + break; > + > + case OPT_ffixed_: > + /* Deferred. */ > + fix_register (opt->arg, 1, 1); > + break; > + > + case OPT_fplugin_: > +#ifdef ENABLE_PLUGIN > + add_new_plugin (opt->arg); > +#else > + error ("plugin support is disabled; configure with --enable-plugin"); > +#endif > + break; > + > + case OPT_fplugin_arg_: > +#ifdef ENABLE_PLUGIN > + parse_plugin_arg_opt (opt->arg); > +#else > + error ("plugin support is disabled; configure with --enable-plugin"); > +#endif > + break; > + > + case OPT_fstack_limit: > + /* The real switch is -fno-stack-limit. */ > + gcc_assert (!opt->value); > + stack_limit_rtx = NULL_RTX; > + break; > + > + case OPT_fstack_limit_register_: > + { > + int reg = decode_reg_name (opt->arg); > + if (reg < 0) > + error ("unrecognized register name %qs", opt->arg); > + else > + stack_limit_rtx = gen_rtx_REG (Pmode, reg); > + } > + break; > + > + case OPT_fstack_limit_symbol_: > + stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt->arg)); > + break; > + > + default: > + gcc_unreachable (); > + } > + } > +} > Index: gcc/Makefile.in > =================================================================== > --- gcc/Makefile.in (revision 166795) > +++ gcc/Makefile.in (working copy) > @@ -932,7 +932,7 @@ PREDICT_H = predict.h predict.def > CPPLIB_H = $(srcdir)/../libcpp/include/line-map.h \ > $(srcdir)/../libcpp/include/cpplib.h > INPUT_H = $(srcdir)/../libcpp/include/line-map.h input.h > -OPTS_H = $(INPUT_H) opts.h > +OPTS_H = $(INPUT_H) $(VEC_H) opts.h > DECNUM_H = $(DECNUM)/decContext.h $(DECNUM)/decDPD.h $(DECNUM)/decNumber.h \ > $(DECNUMFMT)/decimal32.h $(DECNUMFMT)/decimal64.h \ > $(DECNUMFMT)/decimal128.h $(DECNUMFMT)/decimal128Local.h > @@ -1295,6 +1295,7 @@ OBJS-common = \ > optabs.o \ > options.o \ > opts-common.o \ > + opts-global.o \ > opts.o \ > params.o \ > passes.o \ > @@ -2810,10 +2811,13 @@ fold-const.o : fold-const.c $(CONFIG_H) > diagnostic.o : diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ > version.h $(INPUT_H) intl.h $(DIAGNOSTIC_H) diagnostic.def > opts.o : opts.c $(OPTS_H) $(OPTIONS_H) $(TOPLEV_H) $(DIAGNOSTIC_CORE_H) $(CONFIG_H) $(SYSTEM_H) \ > - coretypes.h $(TREE_H) $(TM_H) langhooks.h $(GGC_H) $(EXPR_H) $(RTL_H) \ > - output.h $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \ > - $(FLAGS_H) $(PARAMS_H) $(TREE_PASS_H) $(DBGCNT_H) debug.h \ > - $(PLUGIN_H) $(EXCEPT_H) $(LTO_STREAMER_H) opts-diagnostic.h > + coretypes.h $(TREE_H) $(TM_H) langhooks.h $(EXPR_H) \ > + $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \ > + $(FLAGS_H) $(PARAMS_H) $(DBGCNT_H) debug.h \ > + $(EXCEPT_H) $(LTO_STREAMER_H) opts-diagnostic.h > +opts-global.o : opts-global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ > + $(DIAGNOSTIC_CORE_H) $(OPTS_H) $(FLAGS_H) $(GGC_H) $(TM_H) $(RTL_H) \ > + output.h $(PLUGIN_H) $(TREE_PASS_H) > opts-common.o : opts-common.c $(OPTS_H) $(FLAGS_H) $(CONFIG_H) $(SYSTEM_H) \ > coretypes.h intl.h $(DIAGNOSTIC_H) $(TM_H) > targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ > > -- > Joseph S. Myers > joseph@codesourcery.com >
Index: gcc/doc/options.texi =================================================================== --- gcc/doc/options.texi (revision 166795) +++ gcc/doc/options.texi (working copy) @@ -201,6 +201,12 @@ If the option takes an argument and has @var{var} is an integer variable that stores the value of the argument. @item +If the option has the @code{Defer} property, @var{var} is a pointer to +a @code{VEC(cl_deferred_option,heap)} that stores the option for later +processing. (@var{var} is declared with type @code{void *} and needs +to be cast to @code{VEC(cl_deferred_option,heap)} before use.) + +@item Otherwise, if the option takes an argument, @var{var} is a pointer to the argument string. The pointer will be null if the argument is optional and wasn't given. @@ -255,6 +261,10 @@ The main purpose of this property is to The first option should use @samp{Mask(@var{name})} and the others should use @samp{Mask(@var{name}) MaskExists}. +@item Defer +The option should be stored in a vector, specified with @code{Var}, +for later processing. + @item Alias(@var{opt}) @itemx Alias(@var{opt}, @var{arg}) @itemx Alias(@var{opt}, @var{posarg}, @var{negarg}) Index: gcc/opts-common.c =================================================================== --- gcc/opts-common.c (revision 166795) +++ gcc/opts-common.c (working copy) @@ -958,6 +958,22 @@ set_option (struct gcc_options *opts, st if (set_flag_var) *(const char **) set_flag_var = ""; break; + + case CLVC_DEFER: + { + VEC(cl_deferred_option,heap) *vec + = (VEC(cl_deferred_option,heap) *) *(void **) flag_var; + cl_deferred_option *p; + + p = VEC_safe_push (cl_deferred_option, heap, vec, NULL); + p->opt_index = opt_index; + p->arg = arg; + p->value = value; + *(void **) flag_var = vec; + if (set_flag_var) + *(void **) set_flag_var = vec; + } + break; } if ((diagnostic_t) kind != DK_UNSPECIFIED Index: gcc/toplev.c =================================================================== --- gcc/toplev.c (revision 166795) +++ gcc/toplev.c (working copy) @@ -2365,6 +2365,8 @@ toplev_main (int argc, char **argv) save_decoded_options, save_decoded_options_count, UNKNOWN_LOCATION, global_dc); + handle_common_deferred_options (); + init_local_tick (); initialize_plugins (); Index: gcc/opts.c =================================================================== --- gcc/opts.c (revision 166795) +++ gcc/opts.c (working copy) @@ -25,10 +25,7 @@ along with GCC; see the file COPYING3. #include "coretypes.h" #include "tm.h" #include "tree.h" -#include "rtl.h" #include "expr.h" -#include "ggc.h" -#include "output.h" #include "langhooks.h" #include "opts.h" #include "options.h" @@ -39,10 +36,8 @@ along with GCC; see the file COPYING3. #include "opts-diagnostic.h" #include "insn-attr.h" /* For INSN_SCHEDULING. */ #include "target.h" -#include "tree-pass.h" #include "dbgcnt.h" #include "debug.h" -#include "plugin.h" #include "except.h" #include "lto-streamer.h" @@ -1440,7 +1435,8 @@ print_filtered_help (unsigned int includ else strcpy (new_help, "\t"); - if (flag_var != NULL) + if (flag_var != NULL + && option->var_type != CLVC_DEFER) { if (option->flags & CL_JOINED) { @@ -1839,11 +1835,8 @@ common_handle_option (struct gcc_options break; case OPT_fcall_used_: - fix_register (arg, 0, 1); - break; - case OPT_fcall_saved_: - fix_register (arg, 0, 0); + /* Deferred. */ break; case OPT_fcompare_debug_second: @@ -1877,8 +1870,7 @@ common_handle_option (struct gcc_options break; case OPT_fdump_: - if (!dump_switch_p (arg)) - return false; + /* Deferred. */ break; case OPT_ffp_contract_: @@ -1911,7 +1903,7 @@ common_handle_option (struct gcc_options break; case OPT_ffixed_: - fix_register (arg, 1, 1); + /* Deferred. */ break; case OPT_finline_limit_: @@ -1946,19 +1938,8 @@ common_handle_option (struct gcc_options break; case OPT_fplugin_: -#ifdef ENABLE_PLUGIN - add_new_plugin (arg); -#else - error ("plugin support is disabled; configure with --enable-plugin"); -#endif - break; - case OPT_fplugin_arg_: -#ifdef ENABLE_PLUGIN - parse_plugin_arg_opt (arg); -#else - error ("plugin support is disabled; configure with --enable-plugin"); -#endif + /* Deferred. */ break; case OPT_fprofile_dir_: @@ -2084,21 +2065,12 @@ common_handle_option (struct gcc_options /* The real switch is -fno-stack-limit. */ if (value) return false; - stack_limit_rtx = NULL_RTX; + /* Deferred. */ break; case OPT_fstack_limit_register_: - { - int reg = decode_reg_name (arg); - if (reg < 0) - error ("unrecognized register name \"%s\"", arg); - else - stack_limit_rtx = gen_rtx_REG (Pmode, reg); - } - break; - case OPT_fstack_limit_symbol_: - stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (arg)); + /* Deferred. */ break; case OPT_ftree_vectorizer_verbose_: @@ -2380,6 +2352,7 @@ option_enabled (int opt_idx, void *opts) return (*(int *) flag_var & option->var_value) != 0; case CLVC_STRING: + case CLVC_DEFER: break; } return -1; @@ -2418,6 +2391,9 @@ get_option_state (struct gcc_options *op state->data = ""; state->size = strlen ((const char *) state->data) + 1; break; + + case CLVC_DEFER: + return false; } return true; } Index: gcc/opts.h =================================================================== --- gcc/opts.h (revision 166795) +++ gcc/opts.h (working copy) @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. #define GCC_OPTS_H #include "input.h" +#include "vec.h" /* Specifies how a switch's VAR_VALUE relates to its FLAG_VAR. */ enum cl_var_type { @@ -39,7 +40,11 @@ enum cl_var_type { /* The switch takes a string argument and FLAG_VAR points to that argument. */ - CLVC_STRING + CLVC_STRING, + + /* The switch should be stored in the VEC pointed to by FLAG_VAR for + later processing. */ + CLVC_DEFER }; struct cl_option @@ -158,6 +163,20 @@ struct cl_decoded_option int errors; }; +/* Structure describing an option deferred for handling after the main + option handlers. */ + +typedef struct +{ + /* Elements from struct cl_decoded_option used for deferred + options. */ + size_t opt_index; + const char *arg; + int value; +} cl_deferred_option; +DEF_VEC_O(cl_deferred_option); +DEF_VEC_ALLOC_O(cl_deferred_option,heap); + /* Structure describing a single option-handling callback. */ struct cl_option_handler_func @@ -264,4 +283,5 @@ extern void control_warning_option (unsi struct gcc_options *opts_set, diagnostic_context *dc); extern void print_ignored_options (void); +extern void handle_common_deferred_options (void); #endif Index: gcc/common.opt =================================================================== --- gcc/common.opt (revision 166795) +++ gcc/common.opt (working copy) @@ -710,11 +710,11 @@ Common Report Var(flag_btr_bb_exclusive) Restrict target load migration not to re-use registers in any basic block fcall-saved- -Common Joined RejectNegative +Common Joined RejectNegative Var(common_deferred_options) Defer -fcall-saved-<register> Mark <register> as being preserved across functions fcall-used- -Common Joined RejectNegative +Common Joined RejectNegative Var(common_deferred_options) Defer -fcall-used-<register> Mark <register> as being corrupted by function calls ; Nonzero for -fcaller-saves: allocate values in regs that need to @@ -815,7 +815,7 @@ Common Var(flag_diagnostics_show_option) Amend appropriate diagnostic messages with the command line option that controls them fdump- -Common Joined RejectNegative +Common Joined RejectNegative Var(common_deferred_options) Defer -fdump-<type> Dump various compiler internals to a file fdump-final-insns @@ -893,7 +893,7 @@ Common Report Var(flag_finite_math_only) Assume no NaNs or infinities are generated ffixed- -Common Joined RejectNegative +Common Joined RejectNegative Var(common_deferred_options) Defer -ffixed-<register> Mark <register> as being unavailable to the compiler ffloat-store @@ -1306,11 +1306,11 @@ Common Report Var(flag_pie,1) Generate position-independent code for executables if possible (small mode) fplugin= -Common Joined RejectNegative +Common Joined RejectNegative Var(common_deferred_options) Defer Specify a plugin to load fplugin-arg- -Common Joined RejectNegative +Common Joined RejectNegative Var(common_deferred_options) Defer -fplugin-arg-<name>-<key>[=<value>] Specify argument <key>=<value> for plugin <name> fpredictive-commoning @@ -1573,14 +1573,14 @@ Common Alias(fstack-check=, specific, no Insert stack checking code into the program. Same as -fstack-check=specific fstack-limit -Common +Common Var(common_deferred_options) Defer fstack-limit-register= -Common RejectNegative Joined +Common RejectNegative Joined Var(common_deferred_options) Defer -fstack-limit-register=<register> Trap if the stack goes past <register> fstack-limit-symbol= -Common RejectNegative Joined +Common RejectNegative Joined Var(common_deferred_options) Defer -fstack-limit-symbol=<name> Trap if the stack goes past symbol <name> fstack-protector Index: gcc/opt-functions.awk =================================================================== --- gcc/opt-functions.awk (revision 166795) +++ gcc/opt-functions.awk (working copy) @@ -148,7 +148,9 @@ function static_var(name, flags) # Return the type of variable that should be associated with the given flags. function var_type(flags) { - if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) + if (flag_set_p("Defer", flags)) + return "void *" + else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) return "int " else if (flag_set_p("UInteger", flags)) return "int " @@ -177,6 +179,8 @@ function var_type_struct(flags) # "var_cond" and "var_value" fields of its cl_options[] entry. function var_set(flags) { + if (flag_set_p("Defer", flags)) + return "CLVC_DEFER, 0" s = nth_arg(1, opt_args("Var", flags)) if (s != "") return "CLVC_EQUAL, " s Index: gcc/opts-global.c =================================================================== --- gcc/opts-global.c (revision 0) +++ gcc/opts-global.c (revision 0) @@ -0,0 +1,105 @@ +/* Command line option handling. Code involving global state that + should not be shared with the driver. + Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 + Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "diagnostic-core.h" +#include "opts.h" +#include "flags.h" +#include "ggc.h" +#include "tm.h" /* Required by rtl.h. */ +#include "rtl.h" +#include "output.h" +#include "plugin.h" +#include "tree-pass.h" + +void +handle_common_deferred_options (void) +{ + unsigned int i; + cl_deferred_option *opt; + VEC(cl_deferred_option,heap) *vec + = (VEC(cl_deferred_option,heap) *) common_deferred_options; + + FOR_EACH_VEC_ELT (cl_deferred_option, vec, i, opt) + { + switch (opt->opt_index) + { + case OPT_fcall_used_: + fix_register (opt->arg, 0, 1); + break; + + case OPT_fcall_saved_: + fix_register (opt->arg, 0, 0); + break; + + case OPT_fdump_: + if (!dump_switch_p (opt->arg)) + error ("unrecognized command line option %<-fdump-%s%>", opt->arg); + break; + + case OPT_ffixed_: + /* Deferred. */ + fix_register (opt->arg, 1, 1); + break; + + case OPT_fplugin_: +#ifdef ENABLE_PLUGIN + add_new_plugin (opt->arg); +#else + error ("plugin support is disabled; configure with --enable-plugin"); +#endif + break; + + case OPT_fplugin_arg_: +#ifdef ENABLE_PLUGIN + parse_plugin_arg_opt (opt->arg); +#else + error ("plugin support is disabled; configure with --enable-plugin"); +#endif + break; + + case OPT_fstack_limit: + /* The real switch is -fno-stack-limit. */ + gcc_assert (!opt->value); + stack_limit_rtx = NULL_RTX; + break; + + case OPT_fstack_limit_register_: + { + int reg = decode_reg_name (opt->arg); + if (reg < 0) + error ("unrecognized register name %qs", opt->arg); + else + stack_limit_rtx = gen_rtx_REG (Pmode, reg); + } + break; + + case OPT_fstack_limit_symbol_: + stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt->arg)); + break; + + default: + gcc_unreachable (); + } + } +} Index: gcc/Makefile.in =================================================================== --- gcc/Makefile.in (revision 166795) +++ gcc/Makefile.in (working copy) @@ -932,7 +932,7 @@ PREDICT_H = predict.h predict.def CPPLIB_H = $(srcdir)/../libcpp/include/line-map.h \ $(srcdir)/../libcpp/include/cpplib.h INPUT_H = $(srcdir)/../libcpp/include/line-map.h input.h -OPTS_H = $(INPUT_H) opts.h +OPTS_H = $(INPUT_H) $(VEC_H) opts.h DECNUM_H = $(DECNUM)/decContext.h $(DECNUM)/decDPD.h $(DECNUM)/decNumber.h \ $(DECNUMFMT)/decimal32.h $(DECNUMFMT)/decimal64.h \ $(DECNUMFMT)/decimal128.h $(DECNUMFMT)/decimal128Local.h @@ -1295,6 +1295,7 @@ OBJS-common = \ optabs.o \ options.o \ opts-common.o \ + opts-global.o \ opts.o \ params.o \ passes.o \ @@ -2810,10 +2811,13 @@ fold-const.o : fold-const.c $(CONFIG_H) diagnostic.o : diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ version.h $(INPUT_H) intl.h $(DIAGNOSTIC_H) diagnostic.def opts.o : opts.c $(OPTS_H) $(OPTIONS_H) $(TOPLEV_H) $(DIAGNOSTIC_CORE_H) $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(TREE_H) $(TM_H) langhooks.h $(GGC_H) $(EXPR_H) $(RTL_H) \ - output.h $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \ - $(FLAGS_H) $(PARAMS_H) $(TREE_PASS_H) $(DBGCNT_H) debug.h \ - $(PLUGIN_H) $(EXCEPT_H) $(LTO_STREAMER_H) opts-diagnostic.h + coretypes.h $(TREE_H) $(TM_H) langhooks.h $(EXPR_H) \ + $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \ + $(FLAGS_H) $(PARAMS_H) $(DBGCNT_H) debug.h \ + $(EXCEPT_H) $(LTO_STREAMER_H) opts-diagnostic.h +opts-global.o : opts-global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(DIAGNOSTIC_CORE_H) $(OPTS_H) $(FLAGS_H) $(GGC_H) $(TM_H) $(RTL_H) \ + output.h $(PLUGIN_H) $(TREE_PASS_H) opts-common.o : opts-common.c $(OPTS_H) $(FLAGS_H) $(CONFIG_H) $(SYSTEM_H) \ coretypes.h intl.h $(DIAGNOSTIC_H) $(TM_H) targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \