https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90501

--- Comment #13 from rguenther at suse dot de <rguenther at suse dot de> ---
On Thu, 16 May 2019, ibuclaw at gdcproject dot org wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90501
> 
> --- Comment #11 from Iain Buclaw <ibuclaw at gdcproject dot org> ---
> (In reply to Jakub Jelinek from comment #8)
> > So the first question would be why D passes the return value as
> > DECL_BY_REFERENCE if it doesn't have TREE_ADDRESSABLE type.
> 
> Looking at the places where DECL_BY_REFERENCE is set, this mismatch could
> happen when the result should be returned using NRVO.
> 
> To memory, using a mixture of DECL_BY_REFERENCE and CALL_EXPR_RETURN_SLOT_OPT
> gives a desired behaviour of eliding a copy.
> 
> Two things come to mind as alternatives:
> 
> 1. Currently for NRVO, the DECL_RESULT is explicitly set as not addressable.
> 
>   TREE_TYPE (resdecl) = build_reference_type (TREE_TYPE (resdecl));
>   DECL_BY_REFERENCE (resdecl) = 1;
>   TREE_ADDRESSABLE (resdecl) = 0;
> 
> Is it allowed for the decl to be both DECL_BY_REFERENCE and TREE_ADDRESSABLE 
> at
> the same time?  Or will that just confuse things further.

I think that's independent - iff DECL_BY_REFERENCE then resdecl
is the pointer to the decl, so whether the pointer has its address
taken isn't known here yet.

>   TREE_TYPE (resdecl) = build_reference_type (TREE_TYPE (resdecl));
>   DECL_BY_REFERENCE (resdecl) = 1;
> - TREE_ADDRESSABLE (resdecl) = 0;
> + if (TREE_ADDRESSABLE (TREE_TYPE (resdecl))
> +   TREE_ADDRESSABLE (resdecl) = 0;
> 
> 
> 2. Redo handling of NRVO in the D front-end, to enforce a specific semantic 
> for
> trivial types that we want to elide a copy for.
> 
> i.e: Given,
> ---
> S foo()
> {
>     S result;
>     result.a = 3;
>     return result;
> }
> 
> void test()
> {
>     S s = foo();
> }
> ---
> 
> Generate this explicitly as:
> ---
> S* foo(S* hidden)
> {
>     S result;
>     result.a = 3;
>     *hidden = result;
>     return hidden;
> }
> 
> void test()
> {
>     S tmp;
>     S s = *foo(&tmp);
> }
> ---
> 
> Obviously, that change would be a bit more involved on my side.

I don't think this would be FE friendly design of the middle-end.
Thus my question would be why we do have the special-casing
of TREE_ADDRESSABLE (TREE_TYPE (..)) on DECL_BY_REFERENCE decls.

That is, why's

Index: gcc/gimple-walk.c
===================================================================
--- gcc/gimple-walk.c   (revision 271394)
+++ gcc/gimple-walk.c   (working copy)
@@ -829,8 +829,7 @@ walk_stmt_load_store_addr_ops (gimple *s
                           gimple_call_chain (call_stmt), data);
       if (visit_addr
          && gimple_call_return_slot_opt_p (call_stmt)
-         && gimple_call_lhs (call_stmt) != NULL_TREE
-         && TREE_ADDRESSABLE (TREE_TYPE (gimple_call_lhs (call_stmt))))
+         && gimple_call_lhs (call_stmt) != NULL_TREE)
        ret |= visit_addr (stmt, gimple_call_lhs (call_stmt),
                           gimple_call_lhs (call_stmt), data);
     }

not correct?  Do we really force a new temporary to be used?
We'd need to be consistent here for inlining as well then.

Reply via email to