public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Sandiford <richard.sandiford@arm.com>
To: Andrew Carlotti <andrew.carlotti@arm.com>
Cc: gcc-patches@gcc.gnu.org,  ebotcazou@libertysurf.fr,
	 poulhies@adacore.com,  ibuclaw@gdcproject.org,
	 jason@redhat.com,  nathan@acm.org,  rguenther@suse.de,
	 richard.earnshaw@arm.com
Subject: Re: [PATCH v2 4/5] Add support for target_version attribute
Date: Wed, 29 Nov 2023 17:53:56 +0000	[thread overview]
Message-ID: <mptfs0oh2dn.fsf@arm.com> (raw)
In-Reply-To: <372e1dfb-af4f-e92b-09aa-952b7b52f195@e124511.cambridge.arm.com> (Andrew Carlotti's message of "Fri, 17 Nov 2023 02:55:02 +0000")

Andrew Carlotti <andrew.carlotti@arm.com> writes:
> This patch adds support for the "target_version" attribute to the middle
> end and the C++ frontend, which will be used to implement function
> multiversioning in the aarch64 backend.
>
> On targets that don't use the "target" attribute for multiversioning,
> there is no conflict between the "target" and "target_clones"
> attributes.  This patch therefore makes the mutual exclusion in
> C-family, D and Ada conditonal upon the value of the
> expanded_clones_attribute target hook.
>
> The "target_version" attribute is only added to C++ in this patch,
> because this is currently the only frontend which supports
> multiversioning using the "target" attribute.  Support for the
> "target_version" attribute will be extended to C at a later date.
>
> Targets that currently use the "target" attribute for function
> multiversioning (i.e. i386 and rs6000) are not affected by this patch.
>
> Ok for master?
>
> gcc/ChangeLog:
>
> 	* attribs.cc (decl_attributes): Pass attribute name to target.
> 	(is_function_default_version): Update comment to specify
> 	incompatibility with target_version attributes.
> 	* cgraphclones.cc (cgraph_node::create_version_clone_with_body):
> 	Call valid_version_attribute_p for target_version attributes.
> 	* target.def (valid_version_attribute_p): New hook.
> 	(expanded_clones_attribute): New hook.
> 	* doc/tm.texi.in: Add new hooks.
> 	* doc/tm.texi: Regenerate.
> 	* multiple_target.cc (create_dispatcher_calls): Remove redundant
> 	is_function_default_version check.
> 	(expand_target_clones): Use target hook for attribute name.
> 	* targhooks.cc (default_target_option_valid_version_attribute_p):
> 	New.
> 	* targhooks.h (default_target_option_valid_version_attribute_p):
> 	New.
> 	* tree.h (DECL_FUNCTION_VERSIONED): Update comment to include
> 	target_version attributes.
>
> gcc/c-family/ChangeLog:
>
> 	* c-attribs.cc (CLONES_USES_TARGET): New macro.
> 	(attr_target_exclusions): Use new macro.
> 	(attr_target_clones_exclusions): Ditto, and add target_version.
> 	(attr_target_version_exclusions): New.
> 	(c_common_attribute_table): Add target_version.
> 	(handle_target_version_attribute): New.
>
> gcc/ada/ChangeLog:
>
> 	* gcc-interface/utils.cc (CLONES_USES_TARGET): New macro.
> 	(attr_target_exclusions): Use new macro.
> 	(attr_target_clones_exclusions): Ditto.
>
> gcc/d/ChangeLog:
>
> 	* d-attribs.cc (CLONES_USES_TARGET): New macro.
> 	(attr_target_exclusions): Use new macro.
> 	(attr_target_clones_exclusions): Ditto.
>
> gcc/cp/ChangeLog:
>
> 	* decl2.cc (check_classfn): Update comment to include
> 	target_version attributes.
>
>
> diff --git a/gcc/ada/gcc-interface/utils.cc b/gcc/ada/gcc-interface/utils.cc
> index e33a63948cebdeafc3abcdd539a35141969ad978..8850943cb3326568b4679a73405f50487aa1b7c6 100644
> --- a/gcc/ada/gcc-interface/utils.cc
> +++ b/gcc/ada/gcc-interface/utils.cc
> @@ -143,16 +143,21 @@ static const struct attribute_spec::exclusions attr_noinline_exclusions[] =
>    { NULL, false, false, false },
>  };
>  
> +#define CLONES_USES_TARGET \
> +  (strcmp (targetm.target_option.expanded_clones_attribute, \
> +	   "target") == 0)
> +

Sorry for the slower review on this part.  I was hoping inspiration
would strike for a way to resolve this, but it hasn't, so:

The codebase usually avoids static variables that need dynamic
initialisation.  So although macros are not the preferred way of
doing things, I think one is probably appropriate here.  How about:

  TARGET_HAS_FMV_TARGET_ATTRIBUTE

with the default being true, and with AArch64 defining it to false?

This would replace the expanded_clones_attribute hook, with:

  const char *new_attr_name = targetm.target_option.expanded_clones_attribute;

becoming:

  const char *new_attr_name = (TARGET_HAS_FMV_TARGET_ATTRIBUTE
			       ? "target" : "target_version");

I realise this is anything but elegant, but I think it's probably
the least worst option, given where we are.

>  static const struct attribute_spec::exclusions attr_target_exclusions[] =
>  {
> -  { "target_clones", true, true, true },
> +  { "target_clones", CLONES_USES_TARGET, CLONES_USES_TARGET,
> +    CLONES_USES_TARGET },
>    { NULL, false, false, false },
>  };
>  
>  static const struct attribute_spec::exclusions attr_target_clones_exclusions[] =
>  {
>    { "always_inline", true, true, true },
> -  { "target", true, true, true },
> +  { "target", CLONES_USES_TARGET, CLONES_USES_TARGET, CLONES_USES_TARGET },
>    { NULL, false, false, false },
>  };
>  
> diff --git a/gcc/attribs.cc b/gcc/attribs.cc
> index f9fd258598914ce2112ecaaeaad6c63cd69a44e2..27533023ef5c481ba085c2f0c605dfb992987b3e 100644
> --- a/gcc/attribs.cc
> +++ b/gcc/attribs.cc
> @@ -657,7 +657,8 @@ decl_attributes (tree *node, tree attributes, int flags,
>       options to the attribute((target(...))) list.  */
>    if (TREE_CODE (*node) == FUNCTION_DECL
>        && current_target_pragma
> -      && targetm.target_option.valid_attribute_p (*node, NULL_TREE,
> +      && targetm.target_option.valid_attribute_p (*node,
> +						  get_identifier("target"),

Formatting nit: should be a space before ("target")

>  						  current_target_pragma, 0))
>      {
>        tree cur_attr = lookup_attribute ("target", attributes);
> @@ -1241,8 +1242,9 @@ make_dispatcher_decl (const tree decl)
>    return func_decl;  
>  }
>  
> -/* Returns true if decl is multi-versioned and DECL is the default function,
> -   that is it is not tagged with target specific optimization.  */
> +/* Returns true if DECL is multi-versioned using the target attribute, and this
> +   is the default version.  This function can only be used for targets that do
> +   not support the "target_version" attribute.  */
>  
>  bool
>  is_function_default_version (const tree decl)
> diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
> index b3b41ef123a0f171f57acb1b7f7fdde716428c00..8e33b7c3f4a9e7dcaa299eeff0eea92240f7ef0a 100644
> --- a/gcc/c-family/c-attribs.cc
> +++ b/gcc/c-family/c-attribs.cc
> @@ -149,6 +149,7 @@ static tree handle_alloc_align_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_assume_aligned_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_assume_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_target_attribute (tree *, tree, tree, int, bool *);
> +static tree handle_target_version_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_target_clones_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_optimize_attribute (tree *, tree, tree, int, bool *);
>  static tree ignore_attribute (tree *, tree, tree, int, bool *);
> @@ -228,16 +229,29 @@ static const struct attribute_spec::exclusions attr_noinline_exclusions[] =
>    ATTR_EXCL (NULL, false, false, false),
>  };
>  
> +#define CLONES_USES_TARGET \
> +  (strcmp (targetm.target_option.expanded_clones_attribute, \
> +	   "target") == 0)
> +
>  static const struct attribute_spec::exclusions attr_target_exclusions[] =
>  {
> -  ATTR_EXCL ("target_clones", true, true, true),
> +  ATTR_EXCL ("target_clones", CLONES_USES_TARGET, CLONES_USES_TARGET,
> +	     CLONES_USES_TARGET),
>    ATTR_EXCL (NULL, false, false, false),
>  };
>  
>  static const struct attribute_spec::exclusions attr_target_clones_exclusions[] =
>  {
>    ATTR_EXCL ("always_inline", true, true, true),
> -  ATTR_EXCL ("target", true, true, true),
> +  ATTR_EXCL ("target", CLONES_USES_TARGET, CLONES_USES_TARGET,
> +	     CLONES_USES_TARGET),
> +  ATTR_EXCL ("target_version", true, true, true),
> +  ATTR_EXCL (NULL, false, false, false),
> +};
> +
> +static const struct attribute_spec::exclusions attr_target_version_exclusions[] =
> +{
> +  ATTR_EXCL ("target_clones", true, true, true),

Just FTR: I suppose this should also include "target" if there is ever
a port that uses "target" and "target_version" for the same thing, but
there's no need to predict that case.

>    ATTR_EXCL (NULL, false, false, false),
>  };
>  
> @@ -505,6 +519,9 @@ const struct attribute_spec c_common_attribute_table[] =
>    { "target",                 1, -1, true, false, false, false,
>  			      handle_target_attribute,
>  			      attr_target_exclusions },
> +  { "target_version",         1, 1, true, false, false, false,
> +			      handle_target_version_attribute,
> +			      attr_target_version_exclusions },
>    { "target_clones",          1, -1, true, false, false, false,
>  			      handle_target_clones_attribute,
>  			      attr_target_clones_exclusions },
> @@ -5670,6 +5687,25 @@ handle_target_attribute (tree *node, tree name, tree args, int flags,
>    return NULL_TREE;
>  }
>  
> +/* Handle a "target_version" attribute.  */
> +
> +static tree
> +handle_target_version_attribute (tree *node, tree name, tree args, int flags,
> +				  bool *no_add_attrs)
> +{
> +  /* Ensure we have a function type.  */
> +  if (TREE_CODE (*node) != FUNCTION_DECL)
> +    {
> +      warning (OPT_Wattributes, "%qE attribute ignored", name);
> +      *no_add_attrs = true;
> +    }
> +  else if (!targetm.target_option.valid_version_attribute_p (*node, name, args,
> +							     flags))
> +    *no_add_attrs = true;
> +
> +  return NULL_TREE;
> +}
> +
>  /* Handle a "target_clones" attribute.  */
>  
>  static tree
> diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc
> index 29d28ef895a73a223695cbb86aafbc845bbe7688..8af6b23d8c0306920e0fdcb3559ef047a16689f4 100644
> --- a/gcc/cgraphclones.cc
> +++ b/gcc/cgraphclones.cc
> @@ -78,6 +78,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "tree-eh.h"
>  #include "tree-cfg.h"
>  #include "tree-inline.h"
> +#include "attribs.h"
>  #include "dumpfile.h"
>  #include "gimple-pretty-print.h"
>  #include "alloc-pool.h"
> @@ -1048,7 +1049,17 @@ cgraph_node::create_version_clone_with_body
>        location_t saved_loc = input_location;
>        tree v = TREE_VALUE (target_attributes);
>        input_location = DECL_SOURCE_LOCATION (new_decl);
> -      bool r = targetm.target_option.valid_attribute_p (new_decl, NULL, v, 1);
> +      bool r;
> +      tree name_id = get_attribute_name (target_attributes);
> +      const char* name_str = IDENTIFIER_POINTER (name_id);

Formatting nit, sorry, but: "const char* name_str".

> +      if (strcmp (name_str, "target") == 0)
> +	r = targetm.target_option.valid_attribute_p (new_decl, name_id, v, 1);
> +      else if (strcmp (name_str, "target_version") == 0)
> +	r = targetm.target_option.valid_version_attribute_p (new_decl, name_id,
> +							     v, 1);
> +      else
> +	gcc_assert(false);

gcc_unreachable ();

LGTM otherwise, thanks.

Richard

> +
>        input_location = saved_loc;
>        if (!r)
>  	return NULL;
> diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
> index 9e666e5eecee07ae7c742c3a2b27e85899945c4e..e607aa14d284d545d122e04b0eae1247fd301882 100644
> --- a/gcc/cp/decl2.cc
> +++ b/gcc/cp/decl2.cc
> @@ -832,8 +832,8 @@ check_classfn (tree ctype, tree function, tree template_parms)
>        tree c2 = get_constraints (fndecl);
>  
>        /* While finding a match, same types and params are not enough
> -	 if the function is versioned.  Also check version ("target")
> -	 attributes.  */
> +	 if the function is versioned.  Also check for different target
> +	 specific attributes.  */
>        if (same_type_p (TREE_TYPE (TREE_TYPE (function)),
>  		       TREE_TYPE (TREE_TYPE (fndecl)))
>  	  && compparms (p1, p2)
> diff --git a/gcc/d/d-attribs.cc b/gcc/d/d-attribs.cc
> index c0dc0e24ded871c136e54e5527e901d16cfa5ceb..7fe68565e70dd1124aac63601416dad68600a34e 100644
> --- a/gcc/d/d-attribs.cc
> +++ b/gcc/d/d-attribs.cc
> @@ -126,16 +126,22 @@ static const struct attribute_spec::exclusions attr_noinline_exclusions[] =
>    ATTR_EXCL (NULL, false, false, false),
>  };
>  
> +#define CLONES_USES_TARGET \
> +  (strcmp (targetm.target_option.expanded_clones_attribute, \
> +	   "target") == 0)
> +
>  static const struct attribute_spec::exclusions attr_target_exclusions[] =
>  {
> -  ATTR_EXCL ("target_clones", true, true, true),
> +  ATTR_EXCL ("target_clones", CLONES_USES_TARGET, CLONES_USES_TARGET,
> +	     CLONES_USES_TARGET),
>    ATTR_EXCL (NULL, false, false, false),
>  };
>  
>  static const struct attribute_spec::exclusions attr_target_clones_exclusions[] =
>  {
>    ATTR_EXCL ("always_inline", true, true, true),
> -  ATTR_EXCL ("target", true, true, true),
> +  ATTR_EXCL ("target", CLONES_USES_TARGET, CLONES_USES_TARGET,
> +	     CLONES_USES_TARGET),
>    ATTR_EXCL (NULL, false, false, false),
>  };
>  
> diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
> index d83ca73b1aff90d3c181436afedc162b977a4158..6f6b133803f4574fcf0112b1385eec861112ddd5 100644
> --- a/gcc/doc/tm.texi
> +++ b/gcc/doc/tm.texi
> @@ -10644,6 +10644,23 @@ the function declaration to hold a pointer to a target-specific
>  @code{struct cl_target_option} structure.
>  @end deftypefn
>  
> +@deftypefn {Target Hook} bool TARGET_OPTION_VALID_VERSION_ATTRIBUTE_P (tree @var{fndecl}, tree @var{name}, tree @var{args}, int @var{flags})
> +This hook is called to parse @code{attribute(target_version("..."))},
> +which allows setting target-specific options on individual function versions.
> +These function-specific options may differ
> +from the options specified on the command line.  The hook should return
> +@code{true} if the options are valid.
> +
> +The hook should set the @code{DECL_FUNCTION_SPECIFIC_TARGET} field in
> +the function declaration to hold a pointer to a target-specific
> +@code{struct cl_target_option} structure.
> +@end deftypefn
> +
> +@deftypevr {Target Hook} {const char *} TARGET_OPTION_EXPANDED_CLONES_ATTRIBUTE
> +Contains the name of the attribute used for the version description string
> +when expanding clones for a function with the target_clones attribute.
> +@end deftypevr
> +
>  @deftypefn {Target Hook} void TARGET_OPTION_SAVE (struct cl_target_option *@var{ptr}, struct gcc_options *@var{opts}, struct gcc_options *@var{opts_set})
>  This hook is called to save any additional target-specific information
>  in the @code{struct cl_target_option} structure for function-specific
> diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
> index 3d3ae12cc2ff62025b1138430de501a33961fd90..149c88f627be20a9a35ead2eaebdb704e51927fa 100644
> --- a/gcc/doc/tm.texi.in
> +++ b/gcc/doc/tm.texi.in
> @@ -7028,6 +7028,10 @@ on this implementation detail.
>  
>  @hook TARGET_OPTION_VALID_ATTRIBUTE_P
>  
> +@hook TARGET_OPTION_VALID_VERSION_ATTRIBUTE_P
> +
> +@hook TARGET_OPTION_EXPANDED_CLONES_ATTRIBUTE
> +
>  @hook TARGET_OPTION_SAVE
>  
>  @hook TARGET_OPTION_RESTORE
> diff --git a/gcc/multiple_target.cc b/gcc/multiple_target.cc
> index a2ed048d7dd28ec470953fcd8a0dc86817e4b7dc..3db57c2b13d612a37240d9dcf58ad21b2286633c 100644
> --- a/gcc/multiple_target.cc
> +++ b/gcc/multiple_target.cc
> @@ -66,10 +66,6 @@ create_dispatcher_calls (struct cgraph_node *node)
>  {
>    ipa_ref *ref;
>  
> -  if (!DECL_FUNCTION_VERSIONED (node->decl)
> -      || !is_function_default_version (node->decl))
> -    return;
> -
>    if (!targetm.has_ifunc_p ())
>      {
>        error_at (DECL_SOURCE_LOCATION (node->decl),
> @@ -377,6 +373,7 @@ expand_target_clones (struct cgraph_node *node, bool definition)
>        return false;
>      }
>  
> +  const char *new_attr_name = targetm.target_option.expanded_clones_attribute;
>    cgraph_function_version_info *decl1_v = NULL;
>    cgraph_function_version_info *decl2_v = NULL;
>    cgraph_function_version_info *before = NULL;
> @@ -392,7 +389,7 @@ expand_target_clones (struct cgraph_node *node, bool definition)
>        char *attr = attrs[i];
>  
>        /* Create new target clone.  */
> -      tree attributes = make_attribute ("target", attr,
> +      tree attributes = make_attribute (new_attr_name, attr,
>  					DECL_ATTRIBUTES (node->decl));
>  
>        char *suffix = XNEWVEC (char, strlen (attr) + 1);
> @@ -430,7 +427,7 @@ expand_target_clones (struct cgraph_node *node, bool definition)
>    XDELETEVEC (attr_str);
>  
>    /* Setting new attribute to initial function.  */
> -  tree attributes = make_attribute ("target", "default",
> +  tree attributes = make_attribute (new_attr_name, "default",
>  				    DECL_ATTRIBUTES (node->decl));
>    DECL_ATTRIBUTES (node->decl) = attributes;
>    node->local = false;
> diff --git a/gcc/target.def b/gcc/target.def
> index 0996da0f71a85f8217a41ceb08de8b21087e4ed9..1d2e0d8bf03a8b949ec636e6a78a111308d3dd71 100644
> --- a/gcc/target.def
> +++ b/gcc/target.def
> @@ -6533,6 +6533,31 @@ the function declaration to hold a pointer to a target-specific\n\
>   bool, (tree fndecl, tree name, tree args, int flags),
>   default_target_option_valid_attribute_p)
>  
> +/* Function to validate the attribute((target_version(...))) strings.  If
> +   the option is validated, the hook should also fill in
> +   DECL_FUNCTION_SPECIFIC_TARGET in the function decl node.  */
> +DEFHOOK
> +(valid_version_attribute_p,
> + "This hook is called to parse @code{attribute(target_version(\"...\"))},\n\
> +which allows setting target-specific options on individual function versions.\n\
> +These function-specific options may differ\n\
> +from the options specified on the command line.  The hook should return\n\
> +@code{true} if the options are valid.\n\
> +\n\
> +The hook should set the @code{DECL_FUNCTION_SPECIFIC_TARGET} field in\n\
> +the function declaration to hold a pointer to a target-specific\n\
> +@code{struct cl_target_option} structure.",
> + bool, (tree fndecl, tree name, tree args, int flags),
> + default_target_option_valid_version_attribute_p)
> +
> +/* Attribute to be used when expanding clones for functions with
> +   target_clones attribute.  */
> +DEFHOOKPOD
> +(expanded_clones_attribute,
> + "Contains the name of the attribute used for the version description string\n\
> +when expanding clones for a function with the target_clones attribute.",
> + const char *, "target")
> +
>  /* Function to save any extra target state in the target options structure.  */
>  DEFHOOK
>  (save,
> diff --git a/gcc/targhooks.h b/gcc/targhooks.h
> index 189549cb1c742c37c17623141989b492a7c2b2f8..ff2957fd9fd8389e23992281b35e8e5467072f7d 100644
> --- a/gcc/targhooks.h
> +++ b/gcc/targhooks.h
> @@ -192,6 +192,7 @@ extern bool default_hard_regno_scratch_ok (unsigned int);
>  extern bool default_mode_dependent_address_p (const_rtx, addr_space_t);
>  extern bool default_new_address_profitable_p (rtx, rtx_insn *, rtx);
>  extern bool default_target_option_valid_attribute_p (tree, tree, tree, int);
> +extern bool default_target_option_valid_version_attribute_p (tree, tree, tree, int);
>  extern bool default_target_option_pragma_parse (tree, tree);
>  extern bool default_target_can_inline_p (tree, tree);
>  extern bool default_update_ipa_fn_target_info (unsigned int &, const gimple *);
> diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
> index 4f5b240f8d65eeeaf73418c9f1e2c2684b257cfa..b693352d7eae555912477b6e431dd9c016105007 100644
> --- a/gcc/targhooks.cc
> +++ b/gcc/targhooks.cc
> @@ -1789,7 +1789,19 @@ default_target_option_valid_attribute_p (tree ARG_UNUSED (fndecl),
>  					 int ARG_UNUSED (flags))
>  {
>    warning (OPT_Wattributes,
> -	   "target attribute is not supported on this machine");
> +	   "%<target%> attribute is not supported on this machine");
> +
> +  return false;
> +}
> +
> +bool
> +default_target_option_valid_version_attribute_p (tree ARG_UNUSED (fndecl),
> +						 tree ARG_UNUSED (name),
> +						 tree ARG_UNUSED (args),
> +						 int ARG_UNUSED (flags))
> +{
> +  warning (OPT_Wattributes,
> +	   "%<target_version%> attribute is not supported on this machine");
>  
>    return false;
>  }
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 086b55f0375435d53a1604b6659da4f19fce3d17..d7841af19b20b0dc0ae28b433d5150e9c4763eff 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -3500,8 +3500,8 @@ extern vec<tree, va_gc> **decl_debug_args_insert (tree);
>     (FUNCTION_DECL_CHECK (NODE)->function_decl.function_specific_optimization)
>  
>  /* In FUNCTION_DECL, this is set if this function has other versions generated
> -   using "target" attributes.  The default version is the one which does not
> -   have any "target" attribute set. */
> +   to support different architecture feature sets, e.g. using "target" or
> +   "target_version" attributes.  */
>  #define DECL_FUNCTION_VERSIONED(NODE)\
>     (FUNCTION_DECL_CHECK (NODE)->function_decl.versioned_function)
>  

  reply	other threads:[~2023-11-29 17:53 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-17  2:49 [PATCH v2 0/5] target_version and aarch64 function multiversioning Andrew Carlotti
2023-11-17  2:51 ` [PATCH v2[1/5] aarch64: Add cpu feature detection to libgcc Andrew Carlotti
2023-11-20 15:46   ` Richard Sandiford
2023-12-04 10:31     ` Andrew Carlotti
2023-11-17  2:53 ` [PATCH v2 2/5] c-family: Simplify attribute exclusion handling Andrew Carlotti
2023-11-19 21:45   ` Jeff Law
2023-11-17  2:54 ` [PATCH v2 3/5] ada: Improve " Andrew Carlotti
2023-11-17 10:45   ` Marc Poulhiès
2023-11-17 11:15     ` Andrew Carlotti
2023-11-20  8:26       ` Marc Poulhiès
2023-11-17  2:55 ` [PATCH v2 4/5] Add support for target_version attribute Andrew Carlotti
2023-11-29 17:53   ` Richard Sandiford [this message]
2023-12-04 11:14     ` Andrew Carlotti
2023-11-17  2:56 ` [PATCH v2 5/5] aarch64: Add function multiversioning support Andrew Carlotti
2023-11-24 16:22   ` Richard Sandiford
2023-12-04 13:23     ` Andrew Carlotti

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=mptfs0oh2dn.fsf@arm.com \
    --to=richard.sandiford@arm.com \
    --cc=andrew.carlotti@arm.com \
    --cc=ebotcazou@libertysurf.fr \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=ibuclaw@gdcproject.org \
    --cc=jason@redhat.com \
    --cc=nathan@acm.org \
    --cc=poulhies@adacore.com \
    --cc=rguenther@suse.de \
    --cc=richard.earnshaw@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).