gcc-patches@gcc.gnu.org
[Top] [All Lists]

Re: [PATCH] Attribute noclone

Subject: Re: [PATCH] Attribute noclone
From: Martin Jambor
Date: Fri, 17 Jul 2009 21:54:44 +0200
On Fri, Jul 17, 2009 at 09:40:35PM +0200, Richard Guenther wrote:
> 2009/7/17 Martin Jambor <mjambor@xxxxxxx>:
> > Hi,
> >
> > since the  attribute noinline does not prevent  ipa-cp cloning from
> > taking place, there  has been a need to provide  a new attribute to
> > do just that.   The following patch introduces it,  adds a testcase
> > to verify  it works, amends  a testcase which  will need it  in the
> > future and documents it.
> >
> > Bootstrapped and tested on x86_64-linux and with make pdf.
> >
> > OK for trunk?
> 
> Hm.  Why not simply make the noinline attribute prevent cloning as well?
> I think that is what code using the noinline attribute would expect
> (the body shouldn't be duplicated).
> 

It was that way until
http://gcc.gnu.org/ml/gcc-patches/2009-06/msg02049.html

Reading that mail again, I should probably move the attribute check
from ipa-cp.c somewhere to tree-inline.c... let's see if I can find
the correct spot.

As it is now, the rest of the patch would probably stay the same.

Thanks,

Martin


> Thanks,
> Richard.
> 
> > Thanks,
> >
> > Martin
> >
> > 2009-07-17  Martin Jambor  <mjambor@xxxxxxx>
> >
> >        * c-common.c (c_common_attribute_table): New element for noclone.
> >        (handle_noclone_attribute): New function. Forward-declare.
> >        * ipa-cp.c (ipcp_initialize_node_lattices): Query for noclone 
> > attribute.
> >        * doc/extend.texi (Labels as Values): Document need for noclone.
> >        (Function Attributes): Document noclone attribute.
> >        (Return Address): Mention potential need for the caller a function
> >        using __builtin_return_address to have noinline and noclone
> >        attributes.
> >
> >        * testsuite/gcc.c-torture/execute/pr17377.c: Add noclone attribute to
> >        function y.
> >        * testsuite/gcc.dg/ipa/noclone-1.c: New test.
> >
> >
> > Index: icln/gcc/c-common.c
> > ===================================================================
> > --- icln.orig/gcc/c-common.c
> > +++ icln/gcc/c-common.c
> > @@ -482,6 +482,7 @@ static tree handle_noreturn_attribute (t
> >  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 *);
> > @@ -731,6 +732,8 @@ const struct attribute_spec c_common_att
> >                              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,
> > @@ -5903,6 +5906,23 @@ handle_noinline_attribute (tree *node, t
> >     {
> >       warning (OPT_Wattributes, "%qE attribute ignored", name);
> >       *no_add_attrs = true;
> > +    }
> > +
> > +  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;
> > Index: icln/gcc/ipa-cp.c
> > ===================================================================
> > --- icln.orig/gcc/ipa-cp.c
> > +++ icln/gcc/ipa-cp.c
> > @@ -495,7 +495,8 @@ ipcp_initialize_node_lattices (struct cg
> >   struct ipa_node_params *info = IPA_NODE_REF (node);
> >   enum ipa_lattice_type type;
> >
> > -  if (ipa_is_called_with_var_arguments (info))
> > +  if (ipa_is_called_with_var_arguments (info)
> > +      || lookup_attribute ("noclone", DECL_ATTRIBUTES (node->decl)))
> >     type = IPA_BOTTOM;
> >   else if (!node->needed)
> >     type = IPA_TOP;
> > Index: icln/gcc/doc/extend.texi
> > ===================================================================
> > --- icln.orig/gcc/doc/extend.texi
> > +++ icln/gcc/doc/extend.texi
> > @@ -372,11 +372,12 @@ This is more friendly to code living in
> >  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
> > @@ -1882,19 +1883,18 @@ attributes when making a declaration.  T
> >  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
> > @@ -2719,6 +2719,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
> > @@ -5799,14 +5806,18 @@ These functions may be used to get infor
> >  function.
> >
> >  @deftypefn {Built-in Function} {void *} __builtin_return_address (unsigned 
> > int @var{level})
> > -This function returns the return address of the current function, or of
> > -one of its callers.  The @var{level} argument is number of frames to
> > -scan up the call stack.  A value of @code{0} yields the return address
> > -of the current function, a value of @code{1} yields the return address
> > -of the caller of the current function, and so forth.  When inlining
> > -the expected behavior is that the function will return the address of
> > -the function that will be returned to.  To work around this behavior use
> > -the @code{noinline} function attribute.
> > +This function returns the return address of the current function, or
> > +of one of its callers.  The @var{level} argument is number of frames
> > +to scan up the call stack.  A value of @code{0} yields the return
> > +address of the current function, a value of @code{1} yields the return
> > +address of the caller of the current function, and so forth.  When
> > +inlining the expected behavior is that the function will return the
> > +address of the function that will be returned to.  To work around this
> > +behavior use the @code{noinline} function attribute.  When a caller of
> > +a function calling this built-in has been inlined or cloned, the
> > +address might differ even when this is not apprent from the source
> > +code.  To prevent this from happening, use both the @code{noinline}
> > +and @code{noclone} function attributes on the caller.
> >
> >  The @var{level} argument must be a constant integer.
> >
> > Index: icln/gcc/testsuite/gcc.c-torture/execute/pr17377.c
> > ===================================================================
> > --- icln.orig/gcc/testsuite/gcc.c-torture/execute/pr17377.c
> > +++ icln/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)
> >  {
> > Index: icln/gcc/testsuite/gcc.dg/ipa/noclone-1.c
> > ===================================================================
> > --- /dev/null
> > +++ icln/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" } } */
> >
> >

<Prev in Thread] Current Thread [Next in Thread>