This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Using .opt files for target options


The aim of this patch is to extend the front- and middle-end
options-handling machinery so that it can be used for target
options as well.  In other words, it lets you specify target
options using target-specific .opt files.

The new code should work alongside TARGET_SWITCHES and TARGET_OPTIONS,
but in order to avoid one of those infamous "half transitions",
I suppose the long-term plan would be to move all ports over to the
new scheme.  I'll try to do that for the simpler, more obvious targets,
but I'll probably need help for some ports.  i386, rs6000 and sh look
especially hairy. ;)

.opt files and target_flags
===========================

The most obvious difference between the target-independent and
target-specific options is that the former generally use distinct
variables for each option (flag_fatal_errors, etc.)  whereas the latter
generally use target_flags.  The first question is therefore: should
target options start using separate variables or should the .opt
machinery support target_flags?

I personally have nothing against target_flags.  It does the job it's
supposed to, and it provides a convenient way of overriding the default
settings, either in config.gcc or in configuration-specific header files.
I also think it would be much easier to make mistakes if we tried to
change the option specification and state representation at the same time.
So I went for making the .opt machinery support target_flags.

Specifically, the patch replaces these three cl_option fields:

    int *flag_var;
    int has_set_value;
    int set_value;

with:

    int *flag_var;
    enum cl_var_cond var_cond;
    int var_value;

where cl_var_cond is defined as follows:

    /* Specifies how a switch's VAR_VALUE relates to its FLAG_VAR.  */
    enum cl_var_cond {
      /* The switch is enabled when FLAG_VAR is nonzero.  */
      CLVC_BOOLEAN,

      /* The switch is enabled when FLAG_VAR == VAR_VALUE.  */
      CLVC_EQUAL,

      /* The switch is enabled when VAR_VALUE is not set in FLAG_VAR.  */
      CLVC_BIT_CLEAR,

      /* The switch is enabled when VAR_VALUE is set in FLAG_VAR.  */
      CLVC_BIT_SET
    };

Then an option that sets MASK_FOO can be described as:

    &target_flags, CLVC_BIT_SET, MASK_FOO

and one that clears it as:

    &target_flags, CLVC_BIT_CLEAR, MASK_FOO

Also, the definitions of the various MASK_* and TARGET_* macros
tend to be very mechanical:

    #define MASK_FEATURE1 (1 << 0)
    #define MASK_FEATURE2 (1 << 1)
    ...
    #define TARGET_FEATURE1 ((target_flags & MASK_FEATURE1) != 0)
    #define TARGET_FEATURE2 ((target_flags & MASK_FEATURE2) != 0)
    ....

and I wanted to be able to generate them automatically from the
options definition.  The patch therefore adds two new .opt flags
that can be used in place of the current "Var(...)":

-------------------------------------------------------------------------
`Mask(NAME)'
     The option is associated with a bit in the `target_flags' variable
     (*note Run-time Target::) and is active when that bit is set.

     The options-processing script will automatically allocate a unique
     bit for the option and set the macro `MASK_NAME' to the
     appropriate bitmask.  It will also declare a `TARGET_NAME' macro
     that has the value 1 when the option is active and 0 otherwise.

`InverseMask(OTHERNAME)'
`InverseMask(OTHERNAME, THISNAME)'
     The option is the inverse of another option that has the
     `Mask(OTHERNAME)' property.  If THISNAME is given, the
     options-processing script will declare a `TARGET_THISNAME' macro
     that is 1 when the option is active and 0 otherwise.
-------------------------------------------------------------------------

Sometimes a TARGET_SWITCHES entry will set or clear more than one mask,
but I haven't added any .opt flags for that.  I think the current set-up
is mostly a result of the fact that, when using TARGET_SWITCHES, the
back-end will only get to see the final state of target_flags.  With the
new target hook (described below), the back-end will have a chance to
set and clear flags (and do other stuff) as each option is processed.

Initialising target_flags
=========================

The initial state of target_flags is currently set as follows:

    target_flags = 0;
    set_target_switch ("");

with the "cute" idiom that the "" entry in TARGET_SWITCHES specifies
the default flags.  Since the idea of this patch is to allow us to
move away from TARGET_SWITCHES, we need a new way of initialising
target_flags, so the patch adds a new targetm.default_target_flags
variable.  The variable's default setting is 0 and the code above
then becomes:

    target_flags = targetm.default_target_flags;
    set_target_switch ("");

Processing each option
======================

As mentioned earlier, the generic option-parsing code calls a hook to
process each option.  Language-specific options go through lang_hooks
and common options go through common_handle_option.  The patch adds a
new targetm hook in the same vein as the lang_hooks version.

Negative options
================

One awkwardness in the MIPS port is that some options include the
leading "-m" as part of the logical name of the option.  Thus we have
things like "-mips16", whose negative is "-mno-mips16" rather than
"-no-mips16" or "-mno-ips16".

I think the best way of coping with this sort of thing is to list the
unusual -mno-* options separately.  This will also tell the user that
the options don't follow the normal convention.

At the moment, the options parser looks for and removes "no-" prefixes
before looking up an option in the database.  The patch makes it look
up the original option first and only try removing "no-" if that first
look-up fails.

Including the option definitions
================================

One knock-on effect of using .opt files for target options is that the
masks and variables related to those options will now be declared in
options.h.  At present, this file is usually included indirectly via
flags.h, but some CUs that use the target headers don't include flags.h.

Also, some target headers use the MASK_* macros in preprocessor
conditions, so those macros will need to be defined before the
target headers are included.

The patch gets around both problems by adding options.h to the beginning
of the list of files that should be included in tm_p.h.  One drawback of
this is that a change to options definitions will cause more files to
rebuilt unnecessarily.  I've tried to reduce the impact of this by making
options.h depend on a stamp file, the idea being that some changes to
"optionlist" will only affect options.c, not options.h.

Picking up the option files
===========================

Targets can add new option files by listing them in the config.gcc
"extra_options" variable.  Any config/FOO/FOO.opt file will be picked
up automatically, but other OS-specific files could be added as well
(e.g. for cygwin and darwin).

Documentation
=============

The .opt format is currently documented in c.opt.  I wasn't comfortable
with describing Mask(...) and InverseMask(...) there, since they clearly
have nothing to do with C, so I went ahead and texinfo-ed it.  I hope
the new docs are OK.

Converting the MIPS port
========================

I've attached (separately) a patch that moves the MIPS TARGET_SWITCHES
options over to the new machinery.  In theory, it should have been possible
to just remove the MASK_*, TARGET_* and TARGET_SWITCHES macros and not
disturb the rest of the port, but one or two mechanical changes
had to be made:

  - Sometimes a "default on" switch would use MASK_NO_FOO and define
    TARGET_FOO as ((target_flags & MASK_NO_FOO) == 0).  The patch makes
    these switches use MASK_FOO instead and adds MASK_FOO to the default
    target_flags value.

  - Sometimes the MASK_* and TARGET_* macros used different suffixes,
    e,g, MASK_SPLIT_ADDRS vs. TARGET_SPLIT_ADDRESSES and MASK_PAIRED_SINGLE
    vs. TARGET_PAIRED_SINGLE_FLOAT.  The new automatic definitions require
    consistent names.

  - MASK_LONG64 cleared MASK_INT64.  I decided to handle this in
    override_options for now.  The -mint64 flag will be removed soon,
    but I didn't want to do that as part of this patch.

There were some cases where an option's MASK_FOO was only used by
TARGET_FOO and where the option's setting shouldn't affect PCH validity.
I've made this options use Var(TARGET_FOO) instead of Mask(FOO) in order
to reduce the pressure on target_flags bits.

I'd like to handle the MIPS TARGET_OPTIONS conversion as a follow-on patch.
The necessary changes are a bit more invasive.

Testing
=======

Bootstrapped & regression tested on mips-sgi-irix6.5 and i686-pc-linux-gnu.

OK to install?

Richard


	* config.gcc (extra_options): New variable for listing option files.
	Add ${cpu_type}/${cpu_type}.opt to it if that file exists.
	* configure.ac (extra_opt_files): New AC_SUBST variable.
	(tm_file_list, tm_include_list): Include options.h first.
	* configure: Regenerate.
	* Makefile.in (extra_opt_files, ALL_OPT_FILES): New variables.
	(s-options): Use $(ALL_OPT_FILES) instead of $(lang_opt_files)
	(s-options-h): New rule.
	(options.h): Depend on it.
	(TEXI_GCCINT_FILES): Add options.texi.
	* hooks.h (hook_bool_size_t_constcharptr_int_true): Declare.
	* hooks.c (hook_bool_size_t_constcharptr_int_true): New function.
	* target.h (gcc_target): Add default_target_flags and handle_option.
	* target-def.h (TARGET_DEFAULT_TARGET_FLAGS)
	(TARGET_HANDLE_OPTION): New macros.
	(TARGET_INITIALIZER): Include them.
	* opt-functions.awk (opt_args, nth_arg): New functions.
	(switch_flags): Handle the "Target" flag.
	(var_args): Delete.
	(var_name): Use opt_args and nth_arg.
	(var_set, var_ref): Likewise.  Handle "Mask" and "InverseMask".
	* opth-gen.awk: Declare target_flags.  Declare MASK_* and TARGET_*
	macros for the "Mask" and "InverseMask" options.
	* opts.h (cl_var_cond): New enum.
	(cl_option): Replace the "has_set_value" and "set_value" fields with 
	"var_cond" and "var_value".
	(CL_TARGET): New macro.
	(option_enabled, print_filtered_help): Declare.
	(decode_options): Move definition.
	* opts.c (handle_option): Search for the original option before
	removing any "no-" prefix.  Handle CL_TARGET.  Adjust for the new
	var_cond and var_value fields.  Use targetm.handle_option to handle
	target options.
	(decode_options): Set target_flags to targetm.default_target_flags.
	(print_filtered_help): Make global.  Handle CL_TARGET.
	(option_enabled): New function.
	* toplev.c (target_switches): Guard with #ifdef TARGET_SWITCHES.
	(display_target_options, set_target_switch, print_switch_values)
	(default_pch_valid_p): Guard uses of target_switches with
	#ifdef TARGET_SWITCHES.  Also...
	(display_target_options): Display the CL_TARGET entries in cl_options.
	(set_target_option): Don't complain about the "" option when
	TARGET_SWITCHES is undefined.
	(print_switch_values): Use option_enabled.
	(default_pch_valid_p): Check cl_options[] when looking for something
	that has changed the value of target_flags.
	* doc/gccint.texi: Add an "Options" chapter.  Include options.texi.
	* doc/sourecebuild.texi: Refer to the new options documentation
	instead of c.opt.  Document machine-specific .opt files.
	* doc/tm.texi (target_flags): Say that this variable is declared
	by options.h.
	(TARGET_DEFAULT_TARGET_FLAGS, TARGET_HANDLE_OPTION): Document.
	(TARGET_SWITCHES, TARGET_OPTIONS): Refer to the option files as
	an alternative.
	* doc/options.texi: New file.

Attachment: target-options.diff
Description: Text document

	* config.gcc (mips*-*-*): Rename MASK_SPLIT_ADDRS to
	MASK_SPLIT_ADDRESSES.
	* config/mips/mips.h (target_flags, mips_fix_vr4130_string): Delete.
	(MASK_INT64, MASK_LONG64, MASK_SPLIT_ADDR, MASK_NO_FUSED_MADD)
	(MASK_EXPLICIT_RELOCS, MASK_MEMCPY, MASK_SOFT_FLOAT)
	(MASK_FLOAT64, MASK_ABICALLS, MASK_XGOT, MASK_LONG_CALLS)
	(MASK_64BIT, MASK_EMBEDDED_DATA, MASK_BIG_ENDIAN)
	(MASK_SINGLE_FLOAT, MASK_MAD, MASK_4300_MUL_FIX, MASK_MIPS16)
	(MASK_NO_CHECK_ZERO_DIV, MASK_BRANCHLIKELY)
	(MASK_UNINIT_CONST_IN_RODATA, MASK_FIX_R4000, MASK_FIX_R4400)
	(MASK_FIX_SB1, MASK_FIX_VR4120, MASK_VR4130_ALIGN)
	(MASK_FP_EXCEPTIONS, MASK_DIVIDE_BREAKS, MASK_PAIRED_SINGLE)
	(MASK_MIPS3D, MASK_SYM32, MASK_DEBUG, MASK_DEBUG_D)
	(MASK_MIPS_TFILE, TARGET_INT64, TARGET_LONG64, TARGET_FLOAT64)
	(TARGET_64BIT, TARGET_SPLIT_ADDRESSES, TARGET_DEBUG_MODE)
	(TARGET_DEBUG_D_MODE, TARGET_MEMCPY, TARGET_ABICALLS)
	(TARGET_XGOT, TARGET_SOFT_FLOAT, TARGET_HARD_FLOAT)
	(TARGET_LONG_CALLS, TARGET_EMBEDDED_DATA)
	(TARGET_UNINIT_CONST_IN_RODATA, TARGET_BIG_ENDIAN)
	(TARGET_SINGLE_FLOAT, TARGET_DOUBLE_FLOAT, TARGET_MAD)
	(TARGET_FUSED_MADD, TARGET_4300_MUL_FIX, TARGET_CHECK_ZERO_DIV)
	(TARGET_DIVIDE_TRAPS, TARGET_BRANCHLIKELY, TARGET_FIX_SB1)
	(TARGET_FIX_R4000, TARGET_FIX_R4400, TARGET_FIX_VR4120)
	(TARGET_FIX_VR4130, TARGET_VR4130_ALIGN, TARGET_FP_EXCEPTIONS)
	(TARGET_PAIRED_SINGLE_FLOAT, TARGET_MIPS3D, TARGET_SYM32)
	(TARGET_EXPLICIT_RELOCS): Delete.
	(TARGET_SWITCHES, SUBTARGET_TARGET_SWITCHES): Delete.
	(TARGET_OPTIONS): Remove entry for -mfix-vr4130.
	* config/mips/mips.c (TARGET_DEFAULT_TARGET_FLAGS): Define.
	(override_options): Set MASK_LONG64 if -mint64 is given and no
	-mlongXX option is.  Complain about -mint64 -mlong32.
	(override_options, CMP_BUILTINS, mips_bdesc, sb1_desc): Rename
	MASK_PAIRED_SINGLE to MASK_PAIRED_SINGLE_FLOAT.
	* config/mips/mips.opt: New file.

Attachment: mips-options.diff
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]