From patchwork Wed Nov 17 09:18:34 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 71532 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id A872DB7188 for ; Wed, 17 Nov 2010 20:18:49 +1100 (EST) Received: (qmail 32766 invoked by alias); 17 Nov 2010 09:18:47 -0000 Received: (qmail 32750 invoked by uid 22791); 17 Nov 2010 09:18:44 -0000 X-SWARE-Spam-Status: No, hits=-0.8 required=5.0 tests=AWL, BAYES_40, TW_CP, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 17 Nov 2010 09:18:38 +0000 Received: (qmail 28907 invoked from network); 17 Nov 2010 09:18:36 -0000 Received: from unknown (HELO digraph.polyomino.org.uk) (joseph@127.0.0.2) by mail.codesourcery.com with ESMTPA; 17 Nov 2010 09:18:36 -0000 Received: from jsm28 (helo=localhost) by digraph.polyomino.org.uk with local-esmtp (Exim 4.72) (envelope-from ) id 1PIe9y-0007Pc-H0 for gcc-patches@gcc.gnu.org; Wed, 17 Nov 2010 09:18:34 +0000 Date: Wed, 17 Nov 2010 09:18:34 +0000 (UTC) From: "Joseph S. Myers" To: gcc-patches@gcc.gnu.org Subject: Deferring command-line options Message-ID: MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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? 2010-11-17 Joseph Myers * 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- Mark as being preserved across functions fcall-used- -Common Joined RejectNegative +Common Joined RejectNegative Var(common_deferred_options) Defer -fcall-used- Mark 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- 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- Mark 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--[=] Specify argument = for plugin 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= Trap if the stack goes past fstack-limit-symbol= -Common RejectNegative Joined +Common RejectNegative Joined Var(common_deferred_options) Defer -fstack-limit-symbol= Trap if the stack goes past symbol 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 +. */ + +#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) \