This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
[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 <jakub@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