> From: Sergei Trofimovich <siarh...@google.com>
> 
> Before the change RVO gimple statements were treated as local
> stores by modres analysis. But in practice RVO escapes target.
> 
> 2021-01-30  Sergei Trofimovich  <siarh...@google.com>
> 
> gcc/ChangeLog:
> 
>       PR tree-optimization/98499
>       * ipa-modref.c: treat RVO conservatively and assume
>       all possible side-effects.
> 
> gcc/testsuite/ChangeLog:
> 
>       PR tree-optimization/98499
>       * g++.dg/pr98499.C: new test.

This is OK.  Thanks a lot for debugging this.
> +       /* Return slot optiomization would require bit of propagation;
> +          give up for now.  */
> +       if (gimple_call_return_slot_opt_p (call)
> +           && gimple_call_lhs (call) != NULL_TREE
> +           && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (call))))
> +         {
> +           if (dump_file)
> +             fprintf (dump_file, "%*s  Unhandled return slot opt\n",
> +                      depth * 4, "");
> +           lattice[index].merge (0);

Here we are really missing a way to track that argument is "write only".
We could probably still set EAF_DIRECT, but it is useless withtout
noescape anyway, so 0 is OK.

I implemented tracking of noescape here but only at local modref, since
for global modref we are missing jump functions tracking the fact that
the return value is passed to another function, so probably someting for
next stage1 (I am gathering some stats now though)

Honza
> +         }
>         /* Recursion would require bit of propagation; give up for now.  */
> -       if (callee && !ipa && recursive_call_p (current_function_decl,
> +       else if (callee && !ipa && recursive_call_p (current_function_decl,
>                                                 callee))
>           lattice[index].merge (0);
>         else
> diff --git a/gcc/testsuite/g++.dg/pr98499.C b/gcc/testsuite/g++.dg/pr98499.C
> new file mode 100644
> index 00000000000..ace088aeed9
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/pr98499.C
> @@ -0,0 +1,31 @@
> +/* PR tree-optimization/98499.  */
> +/* { dg-do run } */
> +/* { dg-options "-O2" } */
> +
> +struct string {
> +  // pointer to local store
> +  char * _M_buf;
> +  // local store
> +  char _M_local_buf[16];
> +
> +  __attribute__((noinline)) string() : _M_buf(_M_local_buf) {}
> +
> +  ~string() {
> +    if (_M_buf != _M_local_buf)
> +      __builtin_trap();
> +  }
> +
> +  string(const string &__str); // no copies
> +};
> +
> +__attribute__((noinline)) static string dir_name() { return string(); }
> +class Importer {
> +  string base_path;
> +
> +public:
> +  __attribute__((noinline)) Importer() : base_path (dir_name()) {}
> +};
> +
> +int main() {
> +  Importer imp;
> +}
> -- 
> 2.30.0
> 

Reply via email to