diff mbox

IPA ICF: add no_icf attribute for a function

Message ID 54B9287B.7060705@suse.cz
State New
Headers show

Commit Message

Martin Liška Jan. 16, 2015, 3:04 p.m. UTC
Hello.

This patch adds support for __attribute__((no_icf)) that prevents a function
being merged with a different one.

Tested on x86_64-linux-pc.

Ready for trunk?
Thanks,
Martin

Comments

Jeff Law Jan. 16, 2015, 4:30 p.m. UTC | #1
On 01/16/15 08:04, Martin Liška wrote:
> Hello.
>
> This patch adds support for __attribute__((no_icf)) that prevents a
> function
> being merged with a different one.
>
> Tested on x86_64-linux-pc.
>
> Ready for trunk?
> Thanks,
> Martin
>
> 0001-IPA-ICF-add-no_icf-attribute.patch
>
>
>  From 234fc8018f9810e2adf6d975d6d0051631ef8c02 Mon Sep 17 00:00:00 2001
> From: mliska<mliska@suse.cz>
> Date: Fri, 16 Jan 2015 14:35:23 +0100
> Subject: [PATCH] IPA ICF: add no_icf attribute.
>
> gcc/c-family/ChangeLog:
>
> 2015-01-16  Martin Liska<mliska@suse.cz>
>
> 	* c-common.c (handle_noicf_attribute): New function.
>
> gcc/ChangeLog:
>
> 2015-01-16  Martin Liska<mliska@suse.cz>
>
> 	* doc/extend.texi (no_icf): Add new attribute description.
> 	* ipa-icf.c (sem_item_optimizer::merge_classes): Handle cases
> 	where the pass attempts to merge a function with no_icf attribute.
>
> gcc/testsuite/ChangeLog:
>
> 2015-01-16  Martin Liska<mliska@suse.cz>
>
> 	* gcc.dg/ipa/ipa-icf-33.c: New test.
OK.
jeff
Jan Hubicka Jan. 16, 2015, 4:50 p.m. UTC | #2
> >gcc/c-family/ChangeLog:
> >
> >2015-01-16  Martin Liska<mliska@suse.cz>
> >
> >	* c-common.c (handle_noicf_attribute): New function.
> >
> >gcc/ChangeLog:
> >
> >2015-01-16  Martin Liska<mliska@suse.cz>
> >
> >	* doc/extend.texi (no_icf): Add new attribute description.
> >	* ipa-icf.c (sem_item_optimizer::merge_classes): Handle cases
> >	where the pass attempts to merge a function with no_icf attribute.
> >
> >gcc/testsuite/ChangeLog:
> >
> >2015-01-16  Martin Liska<mliska@suse.cz>
> >
> >	* gcc.dg/ipa/ipa-icf-33.c: New test.
> OK.
I think you want to check at same places opt_for_fn (fndecl, flag_icf) too
to support optimization attribute and LTO merging.

Honza
> jeff
Marek Polacek Jan. 18, 2015, 12:15 p.m. UTC | #3
On Fri, Jan 16, 2015 at 04:04:27PM +0100, Martin Liška wrote:
> Hello.
> 
> This patch adds support for __attribute__((no_icf)) that prevents a function
> being merged with a different one.
> 
> Tested on x86_64-linux-pc.
> 
> Ready for trunk?
> Thanks,
> Martin

> From 234fc8018f9810e2adf6d975d6d0051631ef8c02 Mon Sep 17 00:00:00 2001
> From: mliska <mliska@suse.cz>
> Date: Fri, 16 Jan 2015 14:35:23 +0100
> Subject: [PATCH] IPA ICF: add no_icf attribute.
> 
> gcc/c-family/ChangeLog:
> 
> 2015-01-16  Martin Liska  <mliska@suse.cz>
> 
> 	* c-common.c (handle_noicf_attribute): New function.
> 
> gcc/ChangeLog:
> 
> 2015-01-16  Martin Liska  <mliska@suse.cz>
> 
> 	* doc/extend.texi (no_icf): Add new attribute description.
> 	* ipa-icf.c (sem_item_optimizer::merge_classes): Handle cases
> 	where the pass attempts to merge a function with no_icf attribute.
> 
> gcc/testsuite/ChangeLog:
> 
> 2015-01-16  Martin Liska  <mliska@suse.cz>
> 
> 	* gcc.dg/ipa/ipa-icf-33.c: New test.
> ---
>  gcc/c-family/c-common.c               | 21 +++++++++++++++++++++
>  gcc/doc/extend.texi                   |  6 ++++++
>  gcc/ipa-icf.c                         |  8 ++++++++
>  gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c | 27 +++++++++++++++++++++++++++
>  4 files changed, 62 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c
> 
> diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
> index eb132c5..3c18d1c 100644
> --- a/gcc/c-family/c-common.c
> +++ b/gcc/c-family/c-common.c
> @@ -330,6 +330,7 @@ static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int,
>  static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *);
>  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_leaf_attribute (tree *, tree, tree, int, bool *);
>  static tree handle_always_inline_attribute (tree *, tree, tree, int,
>  					    bool *);
> @@ -664,6 +665,8 @@ const struct attribute_spec c_common_attribute_table[] =
>  			      handle_noinline_attribute, false },
>    { "noclone",                0, 0, true,  false, false,
>  			      handle_noclone_attribute, false },
> +  { "no_icf",                 0, 0, true,  false, false,
> +			      handle_noicf_attribute, false },
>    { "leaf",                   0, 0, true,  false, false,
>  			      handle_leaf_attribute, false },
>    { "always_inline",          0, 0, true,  false, false,
> @@ -6853,6 +6856,24 @@ handle_noclone_attribute (tree *node, tree name,
>    return NULL_TREE;
>  }
>  
> +/* Handle a "no_icf" attribute; arguments as in
> +   struct attribute_spec.handler.  */
> +
> +static tree
> +handle_noicf_attribute (tree *node, tree name,
> +			tree ARG_UNUSED (args),
> +			int ARG_UNUSED (flags), bool *no_add_attrs)
> +{
> +  if (TREE_CODE (*node) != FUNCTION_DECL)
> +    {
> +      warning (OPT_Wattributes, "%qE attribute ignored", name);
> +      *no_add_attrs = true;
> +    }
> +
> +  return NULL_TREE;
> +}
> +
> +
>  /* Handle a "always_inline" attribute; arguments as in
>     struct attribute_spec.handler.  */
>  
> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> index bf6d710..ba921e9 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -2195,6 +2195,7 @@ attribute specification inside double parentheses.  The following
>  attributes are currently defined for functions on all targets:
>  @code{aligned}, @code{alloc_size}, @code{alloc_align}, @code{assume_aligned},
>  @code{noreturn}, @code{returns_twice}, @code{noinline}, @code{noclone},
> +@code{no_icf},
>  @code{always_inline}, @code{flatten}, @code{pure}, @code{const},
>  @code{nothrow}, @code{sentinel}, @code{format}, @code{format_arg},
>  @code{no_instrument_function}, @code{no_split_stack},
> @@ -3475,6 +3476,11 @@ cloning---a mechanism that produces specialized copies of functions
>  and which is (currently) performed by interprocedural constant
>  propagation.
>  
> +@item no_icf
> +@cindex @code{no_icf} function attribute
> +This function attribute prevents a functions from being merged with another

s/functions/function/

> +semantically equivalent function.
> +
>  @item nonnull (@var{arg-index}, @dots{})
>  @cindex @code{nonnull} function attribute
>  The @code{nonnull} attribute specifies that some function parameters should
> diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
> index bbd5724..4b70900 100644
> --- a/gcc/ipa-icf.c
> +++ b/gcc/ipa-icf.c
> @@ -2372,6 +2372,14 @@ sem_item_optimizer::merge_classes (unsigned int prev_class_count)
>  			 source->asm_name (), alias->asm_name ());
>  	      }
>  
> +	    if (lookup_attribute ("no_icf", DECL_ATTRIBUTES (alias->decl)))
> +	      {
> +	        if (dump_file)
> +		  fprintf (dump_file, "Merge operation is skipped due to no_icf attribute.\n\n");

Note that this line is too long.

> +		continue;
> +	      }
> +
>  	    if (dump_file && (dump_flags & TDF_DETAILS))
>  	      {
>  		source->dump_to_file (dump_file);
> diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c
> new file mode 100644
> index 0000000..d7e814d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c
> @@ -0,0 +1,27 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O0 -fipa-icf -fdump-ipa-icf"  } */
> +
> +#include <stdio.h>
> +
> +static int
> +__attribute__ ((no_icf))
> +foo()
> +{
> +  return 2;
> +}
> +
> +static int
> +__attribute__ ((no_icf))
> +bar()
> +{
> +  return 2;
> +}
> +
> +int main()
> +{
> +  return foo() - bar();
> +}
> +
> +/* { dg-final { scan-ipa-dump "Equal symbols: 1" "icf"  } } */
> +/* { dg-final { scan-ipa-dump "Equal symbols: 1" "icf"  } } */
> +/* { dg-final { cleanup-ipa-dump "icf" } } */
> -- 
> 2.1.2
> 


	Marek
diff mbox

Patch

From 234fc8018f9810e2adf6d975d6d0051631ef8c02 Mon Sep 17 00:00:00 2001
From: mliska <mliska@suse.cz>
Date: Fri, 16 Jan 2015 14:35:23 +0100
Subject: [PATCH] IPA ICF: add no_icf attribute.

gcc/c-family/ChangeLog:

2015-01-16  Martin Liska  <mliska@suse.cz>

	* c-common.c (handle_noicf_attribute): New function.

gcc/ChangeLog:

2015-01-16  Martin Liska  <mliska@suse.cz>

	* doc/extend.texi (no_icf): Add new attribute description.
	* ipa-icf.c (sem_item_optimizer::merge_classes): Handle cases
	where the pass attempts to merge a function with no_icf attribute.

gcc/testsuite/ChangeLog:

2015-01-16  Martin Liska  <mliska@suse.cz>

	* gcc.dg/ipa/ipa-icf-33.c: New test.
---
 gcc/c-family/c-common.c               | 21 +++++++++++++++++++++
 gcc/doc/extend.texi                   |  6 ++++++
 gcc/ipa-icf.c                         |  8 ++++++++
 gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c | 27 +++++++++++++++++++++++++++
 4 files changed, 62 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index eb132c5..3c18d1c 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -330,6 +330,7 @@  static tree handle_no_sanitize_undefined_attribute (tree *, tree, tree, int,
 static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *);
 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_leaf_attribute (tree *, tree, tree, int, bool *);
 static tree handle_always_inline_attribute (tree *, tree, tree, int,
 					    bool *);
@@ -664,6 +665,8 @@  const struct attribute_spec c_common_attribute_table[] =
 			      handle_noinline_attribute, false },
   { "noclone",                0, 0, true,  false, false,
 			      handle_noclone_attribute, false },
+  { "no_icf",                 0, 0, true,  false, false,
+			      handle_noicf_attribute, false },
   { "leaf",                   0, 0, true,  false, false,
 			      handle_leaf_attribute, false },
   { "always_inline",          0, 0, true,  false, false,
@@ -6853,6 +6856,24 @@  handle_noclone_attribute (tree *node, tree name,
   return NULL_TREE;
 }
 
+/* Handle a "no_icf" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_noicf_attribute (tree *node, tree name,
+			tree ARG_UNUSED (args),
+			int ARG_UNUSED (flags), bool *no_add_attrs)
+{
+  if (TREE_CODE (*node) != FUNCTION_DECL)
+    {
+      warning (OPT_Wattributes, "%qE attribute ignored", name);
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
+
 /* Handle a "always_inline" attribute; arguments as in
    struct attribute_spec.handler.  */
 
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index bf6d710..ba921e9 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -2195,6 +2195,7 @@  attribute specification inside double parentheses.  The following
 attributes are currently defined for functions on all targets:
 @code{aligned}, @code{alloc_size}, @code{alloc_align}, @code{assume_aligned},
 @code{noreturn}, @code{returns_twice}, @code{noinline}, @code{noclone},
+@code{no_icf},
 @code{always_inline}, @code{flatten}, @code{pure}, @code{const},
 @code{nothrow}, @code{sentinel}, @code{format}, @code{format_arg},
 @code{no_instrument_function}, @code{no_split_stack},
@@ -3475,6 +3476,11 @@  cloning---a mechanism that produces specialized copies of functions
 and which is (currently) performed by interprocedural constant
 propagation.
 
+@item no_icf
+@cindex @code{no_icf} function attribute
+This function attribute prevents a functions from being merged with another
+semantically equivalent function.
+
 @item nonnull (@var{arg-index}, @dots{})
 @cindex @code{nonnull} function attribute
 The @code{nonnull} attribute specifies that some function parameters should
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index bbd5724..4b70900 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -2372,6 +2372,14 @@  sem_item_optimizer::merge_classes (unsigned int prev_class_count)
 			 source->asm_name (), alias->asm_name ());
 	      }
 
+	    if (lookup_attribute ("no_icf", DECL_ATTRIBUTES (alias->decl)))
+	      {
+	        if (dump_file)
+		  fprintf (dump_file, "Merge operation is skipped due to no_icf attribute.\n\n");
+
+		continue;
+	      }
+
 	    if (dump_file && (dump_flags & TDF_DETAILS))
 	      {
 		source->dump_to_file (dump_file);
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c
new file mode 100644
index 0000000..d7e814d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c
@@ -0,0 +1,27 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O0 -fipa-icf -fdump-ipa-icf"  } */
+
+#include <stdio.h>
+
+static int
+__attribute__ ((no_icf))
+foo()
+{
+  return 2;
+}
+
+static int
+__attribute__ ((no_icf))
+bar()
+{
+  return 2;
+}
+
+int main()
+{
+  return foo() - bar();
+}
+
+/* { dg-final { scan-ipa-dump "Equal symbols: 1" "icf"  } } */
+/* { dg-final { scan-ipa-dump "Equal symbols: 1" "icf"  } } */
+/* { dg-final { cleanup-ipa-dump "icf" } } */
-- 
2.1.2