[RFC] noipa attribute (was Re: How to avoid constant propagation into functions?)
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? 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 * 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.jj2016-10-31 13:28:05.0 +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.0 +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.0 +0100 +++ gcc/cgraph.c2016-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.0 +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.0 +0100 +++ gcc/c-family/c-attribs.c2016-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 ha
Re: [RFC] noipa attribute (was Re: How to avoid constant propagation into functions?)
On Thu, 15 Dec 2016, Jakub Jelinek wrote: > 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'd like to suggest some additions to the extend.texi entry: > --- gcc/doc/extend.texi.jj2016-12-15 11:26:07.0 +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. 1. I believe the last sentence should call out that the effect of this attribute is not reducible to just the existing attributes, because suppression of IPA-RA and pure/const discovery is not expressible that way, and that is actually intended. Can this be added to clarify the intent: However, this attribute is not equivalent to a combination of other attributes, because its purpose is to suppress existing and future optimizations employing interprocedural analysis, including those that do not have an attribute suitable for disabling them individually. (and perhaps remove ' ... and in the future might imply ...' from the quoted snippet, because the clarification makes it partially redundant) 2. Can we gently suggest to readers of documentation that this was invented for use in the GCC testsuite, and encourage them to seek proper alternatives, e.g.: This attribute is exposed for the purpose of testing the compiler. In general it should be preferable to properly constrain code generation using the language facilities: for example, using separate compilation or calling through a volatile pointer achieves a similar effect in a portable way [ except in case of a sufficiently advanced compiler indistinguishable from an adversary ;) ] Thanks. Alexander
Re: [RFC] noipa attribute (was Re: How to avoid constant propagation into functions?)
* Jakub Jelinek: > + if (lookup_attribute ("used", attributes) == NULL) > + attributes = tree_cons (get_identifier ("used"), NULL, attributes); Attribute “used” seems different to me from the rest. Based on the documentation, I wouldn't expect it to have any action-at-a-distance effect, just that an out-of-line copy is always emitted. It will disable unused-function warnings, too, I think.
Re: [RFC] noipa attribute (was Re: How to avoid constant propagation into functions?)
On Thu, Dec 15, 2016 at 07:11:09PM +0100, Florian Weimer wrote: > * Jakub Jelinek: > > > + if (lookup_attribute ("used", attributes) == NULL) > > + attributes = tree_cons (get_identifier ("used"), NULL, attributes); > > Attribute “used” seems different to me from the rest. Based on the > documentation, I wouldn't expect it to have any action-at-a-distance > effect, just that an out-of-line copy is always emitted. It will > disable unused-function warnings, too, I think. "used" means the function may be used behind compiler's back in some other ways, so it sets DECL_PRESERVE_P which causes it not to be removed as unused, but also affects various other properties we want from the noipa functions. I'll have to test whether it e.g. disables the changing of argument/return value passing (e.g. on i686 we sometimes decide to use regparm convention, that is keyed on the can_change_signature flag, I'd have to figure out if DECL_PRESERVE_P actually disables that, but if not, that would be a bug). Jakub
Re: [RFC] noipa attribute (was Re: How to avoid constant propagation into functions?)
* Jakub Jelinek: > On Thu, Dec 15, 2016 at 07:11:09PM +0100, Florian Weimer wrote: >> * Jakub Jelinek: >> >> > + if (lookup_attribute ("used", attributes) == NULL) >> > + attributes = tree_cons (get_identifier ("used"), NULL, attributes); >> >> Attribute “used” seems different to me from the rest. Based on the >> documentation, I wouldn't expect it to have any action-at-a-distance >> effect, just that an out-of-line copy is always emitted. It will >> disable unused-function warnings, too, I think. > > "used" means the function may be used behind compiler's back in some other > ways, so it sets DECL_PRESERVE_P which causes it not to be removed as > unused, but also affects various other properties we want from the noipa > functions. Interesting. And other aspects of the noipa attribute will not have this effect already? I still wish there was a way to achieve this, without affecting the decision whether the function is emitted and disabling the unused warning.
Re: [RFC] noipa attribute (was Re: How to avoid constant propagation into functions?)
> 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 > > * 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.0 +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.jj2016-11-25 09:49:47.0 +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.0 +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.jj2016-12-15 11:26:07.0 +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_i
Re: [RFC] noipa attribute (was Re: How to avoid constant propagation into functions?)
* Alexander Monakov: > 2. Can we gently suggest to readers of documentation that this was > invented for use in the GCC testsuite, and encourage them to seek > proper alternatives, e.g.: > > This attribute is exposed for the purpose of testing the compiler. > In general it should be preferable to properly constrain code > generation using the language facilities: for example, using > separate compilation or calling through a volatile pointer > achieves a similar effect in a portable way Separate compilation has caveats with LTO, and I don't think the claim is true for volatile function pointers, as I've already explained.
Re: [RFC] noipa attribute (was Re: How to avoid constant propagation into functions?)
On Thu, Dec 15, 2016 at 10:10:31PM +0100, Jan Hubicka wrote: > > 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. ipa-split should be turned off by noinline, ipa-sra by noclone, shouldn't it? I'll need to write testcases anyway and want to go through my as well as your list (perhaps find testcases we have for the various optimizations and make sure that with noipa they don't apply). > 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. The intent has been that the optimization boundary would be just on the edge between callers and callee where callee has noipa attribute, so it is fine to inline anything into the noipa function etc.; if one wants to avoid that, he would declare those other functions noipa as well. Otherwise the attribute would be less useful for the GCC testsuite - in many cases we have static inline ... fn1 (...) { ... } __attribute__((noinline, noclone)) ... fn2 (...) { ... fn1 (...); ... } int main () { ... fn2 (...); ... } and we rely on the inlining into fn2, but don't want it inlined into main nor all the other ipa opts. Jakub
gcc-6-20161215 is now available
Snapshot gcc-6-20161215 is now available on ftp://gcc.gnu.org/pub/gcc/snapshots/6-20161215/ and on various mirrors, see http://gcc.gnu.org/mirrors.html for details. This snapshot has been generated from the GCC 6 SVN branch with the following options: svn://gcc.gnu.org/svn/gcc/branches/gcc-6-branch revision 243727 You'll find: gcc-6-20161215.tar.bz2 Complete GCC MD5=d2c0c2b6b157d3fc3967169b8c354728 SHA1=d4baa9275bda1cb01339f48acc934b5e6594b277 Diffs from 6-20161208 are available in the diffs/ subdirectory. When a particular snapshot is ready for public consumption the LATEST-6 link is updated and a message is sent to the gcc list. Please do not use a snapshot before it has been announced that way.
Do we really need a CPP manual?
I've had an item on my todo list for a while to try to update the CPP manual, mainly because I've been aware that it has duplicate entries for several of the same command-line options that appear in invoke.texi that have gotten bit-rotten or otherwise out of sync with respect to the GCC manual and/or the implementation. There are also a lot of references to really old versions of GCC and pre-ANSI/ISO C, and compatibility with really old versions of CPP (2.95 and before?). Looking at the structure of the whole manual, though, I see that most of it is in fact a tutorial on how to use the preprocessor language, like you would find in a C programming book. Is this a useful thing for us to be providing? Offhand I am not sure how up-to-date this material is or how much of a maintenance burden it is, but it seems peculiar to be providing such extensive introductory material on the preprocessor when we don't do that for the C or C++ languages; we assume that people already know how to program. I'm wondering if it would be better to toss the tutorial and merge the remaining useful/non-duplicate information about the preprocessor into the main GCC manual. I think the key things to cover are: * Any GNU extensions to the preprocessor language * Predefined macros * Any pragmas not already documented in the GCC manual * Any command-line options not already documented in the GCC manual * Any implementation-defined behavior or implementation limits not already documented in the GCC manual On a related topic do we really need to retain implementations of -traditional-cpp and the documented "obsolete features" (assertions)? It seems especially weird to retain support for -traditional-cpp given that support for pre-ANSI C was removed from the compiler proper at least a dozen years ago. Comments? Suggestions? -Sandra