[RFC] noipa attribute (was Re: How to avoid constant propagation into functions?)

2016-12-15 Thread Jakub Jelinek
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?)

2016-12-15 Thread Alexander Monakov
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?)

2016-12-15 Thread Florian Weimer
* 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?)

2016-12-15 Thread 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.  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?)

2016-12-15 Thread Florian Weimer
* 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?)

2016-12-15 Thread Jan Hubicka
> 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?)

2016-12-15 Thread Florian Weimer
* 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?)

2016-12-15 Thread Jakub Jelinek
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

2016-12-15 Thread gccadmin
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?

2016-12-15 Thread Sandra Loosemore
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