On Tue, 10 Dec 2024, Jan Hubicka wrote:

> Hi,
> int:
> struct foo
> {
>   int a;
>   void bar() const;
>   ~foo()
>   {
>     if (a != 42)
>       __builtin_abort ();
>   }
> };
> __attribute__ ((noinline))
> void test(const struct foo a)
> {
>         int b = a.a;
>         a.bar();
>         if (a.a != b)
>           __builtin_printf ("optimize me away");
> }
> struct foo is passed by invisible reference. As discussed in the PR,
> since it is declared const, it can not change before function test
> returns.  This makes it possible to optimize out the conditional.

Doesn't this break the case where 'a' is declared mutable?

Richard.

> We already support this for fnspec "r" attribute. This patch simply adds
> same logic for const parameters passed by invisible reference.
> To simplify the implementation I also extended attr-fnspec to allow
> NULL in the constructor, so we can use same loop no matter when fnspec
> is present.
> 
> Bootstrapped/regtested x86_64-linux, OK?
> 
> gcc/ChangeLog:
> 
>       PR tree-optimization/103827
>       * attr-fnspec.h (attr_fnspec constructor): Allow NULL_TREE.
>       * tree-into-ssa.cc (pass_build_ssa::execute): Also set
>       SSA_NAME_POINTS_TO_READONLY_MEMORY for parameters passed by
>       invisible reference and declared const.
> 
> gcc/testsuite/ChangeLog:
> 
>       * g++.dg/tree-ssa/pr103827.C: New test.
> 
> 
> diff --git a/gcc/attr-fnspec.h b/gcc/attr-fnspec.h
> index aef4701e6d1..76053d88b09 100644
> --- a/gcc/attr-fnspec.h
> +++ b/gcc/attr-fnspec.h
> @@ -93,8 +97,8 @@ public:
>        verify ();
>    }
>    attr_fnspec (const_tree identifier)
> -  : str (TREE_STRING_POINTER (identifier)),
> -    len (TREE_STRING_LENGTH (identifier))
> +  : str (identifier ? TREE_STRING_POINTER (identifier) : NULL),
> +    len (identifier ? TREE_STRING_LENGTH (identifier) : 0)
>    {
>      if (flag_checking)
>        verify ();
> diff --git a/gcc/tree-into-ssa.cc b/gcc/tree-into-ssa.cc
> index df1fb186962..0267a86f1cc 100644
> --- a/gcc/tree-into-ssa.cc
> +++ b/gcc/tree-into-ssa.cc
> @@ -2555,25 +2556,23 @@ pass_build_ssa::execute (function *fun)
>       SET_SSA_NAME_VAR_OR_IDENTIFIER (name, DECL_NAME (decl));
>      }
>  
> -  /* Initialize SSA_NAME_POINTS_TO_READONLY_MEMORY.  */
> +  /* Initialize SSA_NAME_POINTS_TO_READONLY_MEMORY using fnspec or for
> +     values passed by invisible reference declared const.  */
>    tree fnspec_tree
>        = lookup_attribute ("fn spec",
>                            TYPE_ATTRIBUTES (TREE_TYPE (fun->decl)));
> -  if (fnspec_tree)
> -    {
> -      attr_fnspec fnspec (TREE_VALUE (TREE_VALUE (fnspec_tree)));
> -      unsigned i = 0;
> -      for (tree arg = DECL_ARGUMENTS (cfun->decl);
> -        arg; arg = DECL_CHAIN (arg), ++i)
> +  attr_fnspec fnspec (fnspec_tree ? TREE_VALUE (TREE_VALUE (fnspec_tree)) : 
> NULL);
> +  i = 0;
> +  for (tree arg = DECL_ARGUMENTS (cfun->decl);
> +       arg; arg = DECL_CHAIN (arg), ++i)
> +    {
> +      if ((fnspec.arg_specified_p (i) && fnspec.arg_readonly_p (i))
> +       || (DECL_BY_REFERENCE (arg)
> +           && TYPE_READONLY (TREE_TYPE (TREE_TYPE (arg)))))
>       {
> -       if (!fnspec.arg_specified_p (i))
> -        break;
> -       if (fnspec.arg_readonly_p (i))
> -         {
> -           tree name = ssa_default_def (fun, arg);
> -           if (name)
> -             SSA_NAME_POINTS_TO_READONLY_MEMORY (name) = 1;
> -         }
> +       tree name = ssa_default_def (fun, arg);
> +       if (name)
> +         SSA_NAME_POINTS_TO_READONLY_MEMORY (name) = 1;
>       }
>      }
> diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr103827.C 
> b/gcc/testsuite/g++.dg/tree-ssa/pr103827.C
> new file mode 100644
> index 00000000000..6059fe514b1
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/tree-ssa/pr103827.C
> @@ -0,0 +1,22 @@
> +// { dg-do compile }
> +// { dg-options "-O1 -fdump-tree-optimized" }
> +struct foo
> +{
> +  int a;
> +  void bar() const;
> +  ~foo()
> +  {
> +    if (a != 42)
> +      __builtin_abort ();
> +  }
> +};
> +__attribute__ ((noinline))
> +void test(const struct foo a)
> +{
> +        int b = a.a;
> +        a.bar();
> +        if (a.a != b)
> +          __builtin_printf ("optimize me away");
> +}
> +
> +/* { dg-final { scan-tree-dump-not "optimize me away" "optimized" } } */
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to