> Hi!
> 
> So here is a proof of concept of an attribute that disables inlining,
> cloning, ICF, IPA VRP, IPA bit CCP, IPA RA, pure/const/throw discovery.
> Does it look reasonable?  Anything still missing?

I think you also want to disable optimizations we do about local functions
(stack alignment propagation, calling convention changes), IPA-SRA, IPA-PTA and
possibly ipa-split.

If you want it to be bi-directional it is also necessary to prevent inlining
into the function with attribute and similarly avoiding other results of IPA
analysis.

Honza

> No testsuite coverage yet, I bet we'd want to check for all those opts and
> see that they aren't happening if the attribute is present.
> 
> 2016-12-15  Jakub Jelinek  <ja...@redhat.com>
> 
>       * attribs.c (decl_attributes): Imply noinline, noclone, no_icf and
>       used attributes for noipa attribute.  For naked attribute use
>       lookup_attribute first before lookup_attribute_spec.
>       * final.c (rest_of_handle_final): Disable IPA RA for functions with
>       noipa attribute.
>       * cgraph.c (cgraph_node::get_availability): Return AVAIL_INTERPOSABLE
>       for functions with noipa attribute.
>       * doc/extend.texi: Document noipa function attribute.
> c-family/
>       * c-attribs.c (c_common_attribute_table): Add noipa attribute.
>       (handle_noipa_attribute): New function.
> 
> --- gcc/attribs.c.jj  2016-10-31 13:28:05.000000000 +0100
> +++ gcc/attribs.c     2016-12-15 10:50:54.809973594 +0100
> @@ -404,8 +404,8 @@ decl_attributes (tree *node, tree attrib
>       those targets that support it.  */
>    if (TREE_CODE (*node) == FUNCTION_DECL
>        && attributes
> -      && lookup_attribute_spec (get_identifier ("naked"))
> -      && lookup_attribute ("naked", attributes) != NULL)
> +      && lookup_attribute ("naked", attributes) != NULL
> +      && lookup_attribute_spec (get_identifier ("naked")))
>      {
>        if (lookup_attribute ("noinline", attributes) == NULL)
>       attributes = tree_cons (get_identifier ("noinline"), NULL, attributes);
> @@ -414,6 +414,26 @@ decl_attributes (tree *node, tree attrib
>       attributes = tree_cons (get_identifier ("noclone"),  NULL, attributes);
>      }
>  
> +  /* A "noipa" function attribute implies "noinline", "noclone", "no_icf" and
> +     "used" for those targets that support it.  */
> +  if (TREE_CODE (*node) == FUNCTION_DECL
> +      && attributes
> +      && lookup_attribute ("noipa", attributes) != NULL
> +      && lookup_attribute_spec (get_identifier ("noipa")))
> +    {
> +      if (lookup_attribute ("noinline", attributes) == NULL)
> +     attributes = tree_cons (get_identifier ("noinline"), NULL, attributes);
> +
> +      if (lookup_attribute ("noclone", attributes) == NULL)
> +     attributes = tree_cons (get_identifier ("noclone"),  NULL, attributes);
> +
> +      if (lookup_attribute ("no_icf", attributes) == NULL)
> +     attributes = tree_cons (get_identifier ("no_icf"),  NULL, attributes);
> +
> +      if (lookup_attribute ("used", attributes) == NULL)
> +     attributes = tree_cons (get_identifier ("used"),  NULL, attributes);
> +    }
> +
>    targetm.insert_attributes (*node, &attributes);
>  
>    for (a = attributes; a; a = TREE_CHAIN (a))
> --- gcc/final.c.jj    2016-11-25 09:49:47.000000000 +0100
> +++ gcc/final.c       2016-12-15 11:38:10.660080949 +0100
> @@ -4473,7 +4473,8 @@ rest_of_handle_final (void)
>    assemble_start_function (current_function_decl, fnname);
>    final_start_function (get_insns (), asm_out_file, optimize);
>    final (get_insns (), asm_out_file, optimize);
> -  if (flag_ipa_ra)
> +  if (flag_ipa_ra
> +      && !lookup_attribute ("noipa", DECL_ATTRIBUTES 
> (current_function_decl)))
>      collect_fn_hard_reg_usage ();
>    final_end_function ();
>  
> --- gcc/cgraph.c.jj   2016-12-07 20:10:16.000000000 +0100
> +++ gcc/cgraph.c      2016-12-15 12:20:11.449481168 +0100
> @@ -2255,7 +2255,8 @@ cgraph_node::get_availability (symtab_no
>      avail = AVAIL_AVAILABLE;
>    else if (transparent_alias)
>      ultimate_alias_target (&avail, ref);
> -  else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
> +  else if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl))
> +        || lookup_attribute ("noipa", DECL_ATTRIBUTES (decl)))
>      avail = AVAIL_INTERPOSABLE;
>    else if (!externally_visible)
>      avail = AVAIL_AVAILABLE;
> --- gcc/doc/extend.texi.jj    2016-12-15 11:26:07.000000000 +0100
> +++ gcc/doc/extend.texi       2016-12-15 12:19:32.738996533 +0100
> @@ -2955,6 +2955,15 @@ asm ("");
>  (@pxref{Extended Asm}) in the called function, to serve as a special
>  side-effect.
>  
> +@item noipa
> +@cindex @code{noipa} function attribute
> +Disable interprocedural optimizations between the function with this
> +attribute and its callers, as if the body of the function is not available
> +when optimizing callers and the callers are unavailable when optimizing
> +the body.  This attribute implies @code{noinline}, @code{noclone},
> +@code{no_icf} and @code{used} attributes and in the future might
> +imply further newly added attributes.
> +
>  @item nonnull (@var{arg-index}, @dots{})
>  @cindex @code{nonnull} function attribute
>  @cindex functions with non-null pointer arguments
> --- gcc/c-family/c-attribs.c.jj       2016-12-02 09:37:19.000000000 +0100
> +++ gcc/c-family/c-attribs.c  2016-12-15 10:48:43.743724788 +0100
> @@ -63,6 +63,7 @@ static tree handle_stack_protect_attribu
>  static tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_noclone_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_noicf_attribute (tree *, tree, tree, int, bool *);
> +static tree handle_noipa_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_leaf_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_always_inline_attribute (tree *, tree, tree, int,
>                                           bool *);
> @@ -173,6 +174,8 @@ const struct attribute_spec c_common_att
>                             handle_noclone_attribute, false },
>    { "no_icf",                 0, 0, true,  false, false,
>                             handle_noicf_attribute, false },
> +  { "noipa",               0, 0, true,  false, false,
> +                           handle_noipa_attribute, false },
>    { "leaf",                   0, 0, true,  false, false,
>                             handle_leaf_attribute, false },
>    { "always_inline",          0, 0, true,  false, false,
> @@ -680,6 +683,22 @@ handle_noicf_attribute (tree *node, tree
>  {
>    if (TREE_CODE (*node) != FUNCTION_DECL)
>      {
> +      warning (OPT_Wattributes, "%qE attribute ignored", name);
> +      *no_add_attrs = true;
> +    }
> +
> +  return NULL_TREE;
> +}
> +
> +/* Handle a "noipa" attribute; arguments as in
> +   struct attribute_spec.handler.  */
> +
> +static tree
> +handle_noipa_attribute (tree *node, tree name, tree args,
> +                     int flags, bool *no_add_attrs)
> +{
> +  if (TREE_CODE (*node) != FUNCTION_DECL)
> +    {
>        warning (OPT_Wattributes, "%qE attribute ignored", name);
>        *no_add_attrs = true;
>      }
> 
>       Jakub

Reply via email to