IPA ICF: add no_icf attribute.

* c-common.c (handle_noicf_attribute): New function.
	* 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.dg/ipa/ipa-icf-33.c: New test.

From-SVN: r219848
This commit is contained in:
Martin Liska 2015-01-19 16:20:16 +01:00 committed by Martin Liska
parent b24671f781
commit 185c9e5621
7 changed files with 78 additions and 0 deletions

View File

@ -1,3 +1,9 @@
2015-01-19 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.
2015-01-19 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com> 2015-01-19 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
PR target/64532 PR target/64532

View File

@ -1,3 +1,7 @@
2015-01-19 Martin Liska <mliska@suse.cz>
* c-common.c (handle_noicf_attribute): New function.
2015-01-15 Thomas Schwinge <thomas@codesourcery.com> 2015-01-15 Thomas Schwinge <thomas@codesourcery.com>
Bernd Schmidt <bernds@codesourcery.com> Bernd Schmidt <bernds@codesourcery.com>
James Norris <jnorris@codesourcery.com> James Norris <jnorris@codesourcery.com>

View File

@ -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_stack_protect_attribute (tree *, tree, tree, int, bool *);
static tree handle_noinline_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_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_leaf_attribute (tree *, tree, tree, int, bool *);
static tree handle_always_inline_attribute (tree *, tree, tree, int, static tree handle_always_inline_attribute (tree *, tree, tree, int,
bool *); bool *);
@ -664,6 +665,8 @@ const struct attribute_spec c_common_attribute_table[] =
handle_noinline_attribute, false }, handle_noinline_attribute, false },
{ "noclone", 0, 0, true, false, false, { "noclone", 0, 0, true, false, false,
handle_noclone_attribute, false }, handle_noclone_attribute, false },
{ "no_icf", 0, 0, true, false, false,
handle_noicf_attribute, false },
{ "leaf", 0, 0, true, false, false, { "leaf", 0, 0, true, false, false,
handle_leaf_attribute, false }, handle_leaf_attribute, false },
{ "always_inline", 0, 0, true, false, false, { "always_inline", 0, 0, true, false, false,
@ -6853,6 +6856,24 @@ handle_noclone_attribute (tree *node, tree name,
return NULL_TREE; 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 /* Handle a "always_inline" attribute; arguments as in
struct attribute_spec.handler. */ struct attribute_spec.handler. */

View File

@ -2195,6 +2195,7 @@ attribute specification inside double parentheses. The following
attributes are currently defined for functions on all targets: attributes are currently defined for functions on all targets:
@code{aligned}, @code{alloc_size}, @code{alloc_align}, @code{assume_aligned}, @code{aligned}, @code{alloc_size}, @code{alloc_align}, @code{assume_aligned},
@code{noreturn}, @code{returns_twice}, @code{noinline}, @code{noclone}, @code{noreturn}, @code{returns_twice}, @code{noinline}, @code{noclone},
@code{no_icf},
@code{always_inline}, @code{flatten}, @code{pure}, @code{const}, @code{always_inline}, @code{flatten}, @code{pure}, @code{const},
@code{nothrow}, @code{sentinel}, @code{format}, @code{format_arg}, @code{nothrow}, @code{sentinel}, @code{format}, @code{format_arg},
@code{no_instrument_function}, @code{no_split_stack}, @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 and which is (currently) performed by interprocedural constant
propagation. 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{}) @item nonnull (@var{arg-index}, @dots{})
@cindex @code{nonnull} function attribute @cindex @code{nonnull} function attribute
The @code{nonnull} attribute specifies that some function parameters should The @code{nonnull} attribute specifies that some function parameters should

View File

@ -2373,6 +2373,16 @@ sem_item_optimizer::merge_classes (unsigned int prev_class_count)
source->asm_name (), alias->asm_name ()); 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)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
source->dump_to_file (dump_file); source->dump_to_file (dump_file);

View File

@ -1,3 +1,7 @@
2015-01-19 Martin Liska <mliska@suse.cz>
* gcc.dg/ipa/ipa-icf-33.c: New test.
2015-01-19 Felix Yang <felix.yang@huawei.com> 2015-01-19 Felix Yang <felix.yang@huawei.com>
Haijian Zhang <z.zhanghaijian@huawei.com> Haijian Zhang <z.zhanghaijian@huawei.com>

View File

@ -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" } } */