aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2009-07-25 20:09:42 +0200
committerMartin Jambor <jamborm@gcc.gnu.org>2009-07-25 20:09:42 +0200
commit86631ea3dd78a0077a6f96061affe89d5e38220f (patch)
tree3c96ae42a6ff9f1334a7b02a1bd9e7eff55129ad
parent2a9de349388c25eb2d8df725d5eace68c6c2c81d (diff)
downloadgcc-86631ea3dd78a0077a6f96061affe89d5e38220f.zip
gcc-86631ea3dd78a0077a6f96061affe89d5e38220f.tar.gz
gcc-86631ea3dd78a0077a6f96061affe89d5e38220f.tar.bz2
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
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/c-common.c20
-rw-r--r--gcc/doc/extend.texi35
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr17377.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/noclone-1.c29
-rw-r--r--gcc/tree-inline.c3
7 files changed, 87 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2039153..e223f44 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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>
PR rtl-optimization/34999
diff --git a/gcc/c-common.c b/gcc/c-common.c
index aaa6435..0ebb9f1 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -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_cold_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,
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 },
{ "noinline", 0, 0, true, false, false,
handle_noinline_attribute },
+ { "noclone", 0, 0, true, false, false,
+ handle_noclone_attribute },
{ "always_inline", 0, 0, true, false, false,
handle_always_inline_attribute },
{ "gnu_inline", 0, 0, true, false, false,
@@ -5913,6 +5916,23 @@ handle_noinline_attribute (tree *node, tree name,
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
struct attribute_spec.handler. */
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 2453bd8..37c5089 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -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,
allows the data to be read-only.
-The @code{&&foo} expressions for the same label might have different values
-if the containing function is inlined or cloned. If a program relies on
-them being always the same, @code{__attribute__((__noinline__))} should
-be used to prevent inlining. If @code{&&foo} is used
-in a static variable initializer, inlining is forbidden.
+The @code{&&foo} expressions for the same label might have different
+values if the containing function is inlined or cloned. If a program
+relies on them being always the same,
+@code{__attribute__((__noinline__,__noclone__))} should be used to
+prevent inlining and cloning. If @code{&&foo} is used in a static
+variable initializer, inlining and cloning is forbidden.
@node 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
attributes are currently defined for functions on all targets:
@code{aligned}, @code{alloc_size}, @code{noreturn},
-@code{returns_twice}, @code{noinline}, @code{always_inline},
-@code{flatten}, @code{pure}, @code{const}, @code{nothrow},
-@code{sentinel}, @code{format}, @code{format_arg},
+@code{returns_twice}, @code{noinline}, @code{noclone},
+@code{always_inline}, @code{flatten}, @code{pure}, @code{const},
+@code{nothrow}, @code{sentinel}, @code{format}, @code{format_arg},
@code{no_instrument_function}, @code{section}, @code{constructor},
@code{destructor}, @code{used}, @code{unused}, @code{deprecated},
@code{weak}, @code{malloc}, @code{alias}, @code{warn_unused_result},
@code{nonnull}, @code{gnu_inline}, @code{externally_visible},
-@code{hot}, @code{cold}, @code{artificial}, @code{error}
-and @code{warning}.
-Several other attributes are defined for functions on particular
-target systems. Other attributes, including @code{section} are
-supported for variables declarations (@pxref{Variable Attributes}) and
-for types (@pxref{Type Attributes}).
+@code{hot}, @code{cold}, @code{artificial}, @code{error} and
+@code{warning}. Several other attributes are defined for functions on
+particular target systems. Other attributes, including @code{section}
+are supported for variables declarations (@pxref{Variable Attributes})
+and for types (@pxref{Type Attributes}).
You may also specify attributes with @samp{__} preceding and following
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
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{})
@cindex @code{nonnull} function attribute
The @code{nonnull} attribute specifies that some function parameters should
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b70c78f..9651ed2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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>
* lib/target-supports.exp (check_effective_target_static): New
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr17377.c b/gcc/testsuite/gcc.c-torture/execute/pr17377.c
index 0be6f0a..87d23c5 100644
--- a/gcc/testsuite/gcc.c-torture/execute/pr17377.c
+++ b/gcc/testsuite/gcc.c-torture/execute/pr17377.c
@@ -26,7 +26,7 @@ f (int i)
int x;
-void *y (int i) __attribute__ ((__noinline__));
+void *y (int i) __attribute__ ((__noinline__,__noclone__));
void *
y (int i)
{
diff --git a/gcc/testsuite/gcc.dg/ipa/noclone-1.c b/gcc/testsuite/gcc.dg/ipa/noclone-1.c
new file mode 100644
index 0000000..118df3a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/noclone-1.c
@@ -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" } } */
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 3b7b666..605f91e 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -4349,7 +4349,8 @@ copy_static_chain (tree static_chain, copy_body_data * id)
bool
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.