mirror of git://gcc.gnu.org/git/gcc.git
extend.texi (Labels as Values): Document need for noclone.
2009-07-25 Martin Jambor <mjambor@suse.cz> * doc/extend.texi (Labels as Values): Document need for noclone. (Function Attributes): Document noclone attribute. * c-common.c (c_common_attribute_table): New element for noclone. (handle_noclone_attribute): New function. Forward-declare. * tree-inline.c (tree_versionable_function_p): Check for noclone attribute. * testsuite/gcc.c-torture/execute/pr17377.c: Add noclone attribute to function y. * testsuite/gcc.dg/ipa/noclone-1.c: New test. From-SVN: r150086
This commit is contained in:
parent
2a9de34938
commit
86631ea3dd
|
|
@ -1,3 +1,12 @@
|
||||||
|
2009-07-25 Martin Jambor <mjambor@suse.cz>
|
||||||
|
|
||||||
|
* c-common.c (c_common_attribute_table): New element for noclone.
|
||||||
|
(handle_noclone_attribute): New function. Forward-declare.
|
||||||
|
* tree-inline.c (tree_versionable_function_p): Check for noclone
|
||||||
|
attribute.
|
||||||
|
* doc/extend.texi (Labels as Values): Document need for noclone.
|
||||||
|
(Function Attributes): Document noclone attribute.
|
||||||
|
|
||||||
2009-07-25 Jakub Jelinek <jakub@redhat.com>
|
2009-07-25 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
PR rtl-optimization/34999
|
PR rtl-optimization/34999
|
||||||
|
|
|
||||||
|
|
@ -482,6 +482,7 @@ static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
|
||||||
static tree handle_hot_attribute (tree *, tree, tree, int, bool *);
|
static tree handle_hot_attribute (tree *, tree, tree, int, bool *);
|
||||||
static tree handle_cold_attribute (tree *, tree, tree, int, bool *);
|
static tree handle_cold_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_always_inline_attribute (tree *, tree, tree, int,
|
static tree handle_always_inline_attribute (tree *, tree, tree, int,
|
||||||
bool *);
|
bool *);
|
||||||
static tree handle_gnu_inline_attribute (tree *, tree, tree, int, bool *);
|
static tree handle_gnu_inline_attribute (tree *, tree, tree, int, bool *);
|
||||||
|
|
@ -733,6 +734,8 @@ const struct attribute_spec c_common_attribute_table[] =
|
||||||
handle_noreturn_attribute },
|
handle_noreturn_attribute },
|
||||||
{ "noinline", 0, 0, true, false, false,
|
{ "noinline", 0, 0, true, false, false,
|
||||||
handle_noinline_attribute },
|
handle_noinline_attribute },
|
||||||
|
{ "noclone", 0, 0, true, false, false,
|
||||||
|
handle_noclone_attribute },
|
||||||
{ "always_inline", 0, 0, true, false, false,
|
{ "always_inline", 0, 0, true, false, false,
|
||||||
handle_always_inline_attribute },
|
handle_always_inline_attribute },
|
||||||
{ "gnu_inline", 0, 0, true, false, false,
|
{ "gnu_inline", 0, 0, true, false, false,
|
||||||
|
|
@ -5913,6 +5916,23 @@ handle_noinline_attribute (tree *node, tree name,
|
||||||
return NULL_TREE;
|
return NULL_TREE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle a "noclone" attribute; arguments as in
|
||||||
|
struct attribute_spec.handler. */
|
||||||
|
|
||||||
|
static tree
|
||||||
|
handle_noclone_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. */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -372,11 +372,12 @@ This is more friendly to code living in shared libraries, as it reduces
|
||||||
the number of dynamic relocations that are needed, and by consequence,
|
the number of dynamic relocations that are needed, and by consequence,
|
||||||
allows the data to be read-only.
|
allows the data to be read-only.
|
||||||
|
|
||||||
The @code{&&foo} expressions for the same label might have different values
|
The @code{&&foo} expressions for the same label might have different
|
||||||
if the containing function is inlined or cloned. If a program relies on
|
values if the containing function is inlined or cloned. If a program
|
||||||
them being always the same, @code{__attribute__((__noinline__))} should
|
relies on them being always the same,
|
||||||
be used to prevent inlining. If @code{&&foo} is used
|
@code{__attribute__((__noinline__,__noclone__))} should be used to
|
||||||
in a static variable initializer, inlining is forbidden.
|
prevent inlining and cloning. If @code{&&foo} is used in a static
|
||||||
|
variable initializer, inlining and cloning is forbidden.
|
||||||
|
|
||||||
@node Nested Functions
|
@node Nested Functions
|
||||||
@section Nested Functions
|
@section Nested Functions
|
||||||
|
|
@ -1881,19 +1882,18 @@ attributes when making a declaration. This keyword is followed by an
|
||||||
attribute specification inside double parentheses. The following
|
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{noreturn},
|
@code{aligned}, @code{alloc_size}, @code{noreturn},
|
||||||
@code{returns_twice}, @code{noinline}, @code{always_inline},
|
@code{returns_twice}, @code{noinline}, @code{noclone},
|
||||||
@code{flatten}, @code{pure}, @code{const}, @code{nothrow},
|
@code{always_inline}, @code{flatten}, @code{pure}, @code{const},
|
||||||
@code{sentinel}, @code{format}, @code{format_arg},
|
@code{nothrow}, @code{sentinel}, @code{format}, @code{format_arg},
|
||||||
@code{no_instrument_function}, @code{section}, @code{constructor},
|
@code{no_instrument_function}, @code{section}, @code{constructor},
|
||||||
@code{destructor}, @code{used}, @code{unused}, @code{deprecated},
|
@code{destructor}, @code{used}, @code{unused}, @code{deprecated},
|
||||||
@code{weak}, @code{malloc}, @code{alias}, @code{warn_unused_result},
|
@code{weak}, @code{malloc}, @code{alias}, @code{warn_unused_result},
|
||||||
@code{nonnull}, @code{gnu_inline}, @code{externally_visible},
|
@code{nonnull}, @code{gnu_inline}, @code{externally_visible},
|
||||||
@code{hot}, @code{cold}, @code{artificial}, @code{error}
|
@code{hot}, @code{cold}, @code{artificial}, @code{error} and
|
||||||
and @code{warning}.
|
@code{warning}. Several other attributes are defined for functions on
|
||||||
Several other attributes are defined for functions on particular
|
particular target systems. Other attributes, including @code{section}
|
||||||
target systems. Other attributes, including @code{section} are
|
are supported for variables declarations (@pxref{Variable Attributes})
|
||||||
supported for variables declarations (@pxref{Variable Attributes}) and
|
and for types (@pxref{Type Attributes}).
|
||||||
for types (@pxref{Type Attributes}).
|
|
||||||
|
|
||||||
You may also specify attributes with @samp{__} preceding and following
|
You may also specify attributes with @samp{__} preceding and following
|
||||||
each keyword. This allows you to use them in header files without
|
each keyword. This allows you to use them in header files without
|
||||||
|
|
@ -2718,6 +2718,13 @@ asm ("");
|
||||||
(@pxref{Extended Asm}) in the called function, to serve as a special
|
(@pxref{Extended Asm}) in the called function, to serve as a special
|
||||||
side-effect.
|
side-effect.
|
||||||
|
|
||||||
|
@item noclone
|
||||||
|
@cindex @code{noclone} function attribute
|
||||||
|
This function attribute prevents a function from being considered for
|
||||||
|
cloning - a mechanism which produces specialized copies of functions
|
||||||
|
and which is (currently) performed by interprocedural constant
|
||||||
|
propagation.
|
||||||
|
|
||||||
@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
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
2009-07-25 Martin Jambor <mjambor@suse.cz>
|
||||||
|
|
||||||
|
* gcc.c-torture/execute/pr17377.c: Add noclone attribute to function y.
|
||||||
|
* gcc.dg/ipa/noclone-1.c: New test.
|
||||||
|
|
||||||
2009-07-25 Uros Bizjak <ubizjak@gmail.com>
|
2009-07-25 Uros Bizjak <ubizjak@gmail.com>
|
||||||
|
|
||||||
* lib/target-supports.exp (check_effective_target_static): New
|
* lib/target-supports.exp (check_effective_target_static): New
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ f (int i)
|
||||||
|
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
void *y (int i) __attribute__ ((__noinline__));
|
void *y (int i) __attribute__ ((__noinline__,__noclone__));
|
||||||
void *
|
void *
|
||||||
y (int i)
|
y (int i)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-ipa-cp -fno-early-inlining" } */
|
||||||
|
|
||||||
|
int global_1, global_2;
|
||||||
|
|
||||||
|
__attribute__((__noclone__)) int g (int b, int c)
|
||||||
|
{
|
||||||
|
global_1 = b;
|
||||||
|
global_2 = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((__noclone__)) int f (int a)
|
||||||
|
{
|
||||||
|
/* Second parameter of g gets different values. */
|
||||||
|
if (a > 0)
|
||||||
|
g (a, 3);
|
||||||
|
else
|
||||||
|
g (a, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main ()
|
||||||
|
{
|
||||||
|
f (7);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* { dg-final { scan-ipa-dump-times "versioned function" 0 "cp" } } */
|
||||||
|
/* { dg-final { cleanup-ipa-dump "cp" } } */
|
||||||
|
|
@ -4349,7 +4349,8 @@ copy_static_chain (tree static_chain, copy_body_data * id)
|
||||||
bool
|
bool
|
||||||
tree_versionable_function_p (tree fndecl)
|
tree_versionable_function_p (tree fndecl)
|
||||||
{
|
{
|
||||||
return copy_forbidden (DECL_STRUCT_FUNCTION (fndecl), fndecl) == NULL;
|
return (!lookup_attribute ("noclone", DECL_ATTRIBUTES (fndecl))
|
||||||
|
&& copy_forbidden (DECL_STRUCT_FUNCTION (fndecl), fndecl) == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete all unreachable basic blocks and update callgraph.
|
/* Delete all unreachable basic blocks and update callgraph.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue