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:
parent
b24671f781
commit
185c9e5621
@ -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
|
||||||
|
@ -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>
|
||||||
|
@ -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. */
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
27
gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c
Normal file
27
gcc/testsuite/gcc.dg/ipa/ipa-icf-33.c
Normal 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" } } */
|
Loading…
Reference in New Issue
Block a user