> 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