On Mon, Jun 30, 2025 at 7:25 AM Antoni Boucher <boua...@zoho.com> wrote:
>
>
>
> Le 2025-06-29 à 19 h 42, Andrew Pinski a écrit :
> >
> >
> > On Sun, Jun 29, 2025, 4:36 PM Antoni Boucher <boua...@zoho.com
> > <mailto:boua...@zoho.com>> wrote:
> >
> >
> >
> >     Le 2025-06-29 à 10 h 46, Andrew Pinski a écrit :
> >      >
> >      >
> >      > On Sun, Jun 29, 2025, 7:43 AM Andrew Pinski <pins...@gmail.com
> >     <mailto:pins...@gmail.com>
> >      > <mailto:pins...@gmail.com <mailto:pins...@gmail.com>>> wrote:
> >      >
> >      >     On Sun, Jun 29, 2025, 7:36 AM Antoni Boucher via Gcc
> >      >     <gcc@gcc.gnu.org <mailto:gcc@gcc.gnu.org>
> >     <mailto:gcc@gcc.gnu.org <mailto:gcc@gcc.gnu.org>>> wrote:
> >      >
> >      >         Hi.
> >      >         Is there a way in GENERIC to specify that a parameter will be
> >      >         passed in
> >      >         "sret", or is this solely controlled by the hook
> >     struct_value_rtx?
> >      >
> >      >
> >      >     It is only controlled by the hook.
> >      >     What exactly are trying to do?
> >      >     You could set the return slot optimization bit on the call
> >      >     expression if you want the lhs of a call not to be copied and
> >     just
> >      >     passed as the address via sret.
> >
> >     I'm trying to follow the Rust ABI for rustc_codegen_gcc: they manually
> >     specify whether a param is "sret".
> >
> >
> > Not all ABI/targets have a sret specific register. So this is even more
> > confusing.
> >
> >
> >
> >      >
> >      >     That is if you have:
> >      >     StructVar = func(...);
> >      >
> >      >     You set the return slot optimization bit on the call expr in
> >     generic
> >      >     and which will copy that bit to the gimple GIMPLE_CALL and then
> >      >     during expand will again copy it back to the generic
> >     call_expr and
> >      >     expand will use the target for the address.
> >      >
> >      >
> >      > CALL_EXPR_RETURN_SLOT_OPT is the macro.
> >
> >     Is this a guaranteed optimization? I'm asking because this is for ABI
> >     correctness and I need a solution that will always work.
> >     If not, would there be another way to do this?
> >     Thanks.
> >
> >
> > Yes it is guaranteed that if the return type is returned via memory
> > reference to the other function it will use that memory location.
>
> How does this work on the side of the function declaration? Do we need
> to set something so that it follows the correct convention?

So there are 2 separate things here.
First there is an ABI of having struct return in memory.
Note if TREE_ADDRESSABLE is set on a struct type, then return value is
always through memory:
```
   In ..._TYPE nodes, it means that objects of this type must be fully
   addressable.  This means that pieces of this object cannot go into
   register parameters, for example.  If this a function type, this
   means that the value must be returned in memory.
```
The ABI part is independent of the CALL_EXPR and dependent on the
FUNCTION_TYPE that is being used and the target.

Second is specifying if you can reuse the memory of the lhs of a
modify_expr with a call_expr when the ABI says the memory is return in
memory.
This is specified via CALL_EXPR_RETURN_SLOT_OPT on the CALL_EXPR.

I am trying to understand how the rustc front-end sets up this. Does
it implement the ABI of each target as that is needed for LLVM?
This is the major difference here as GCC's front-ends normally don't
care much about the ABI except in specific cases (e.g. returns this
and a few others). GCC's front-end don't handle the call argument ABI
at all; rather it is more like you build call_expr which act like
function calls in C (well with the addition of reference types but
those are really just pointers at that point). And the middle-end
(with help from the backend) which implements the full ABI.

The reason why this is done this way is an abstraction layer and
allows new front-ends for backends that are known to it at the time
without additional work (e.g. gfortran adding support for riscv or
aarch64; no changes to  the front-end were made). This seems like the
opposite of LLVM where there is no tight coupling of the 2 and there
is no abstraction for most of the ABI call work and each front-end
needs to implement that again.

Hope this helps explain GCC front-end interactions with the GCC's
middle-end better.

>
> Thanks a lot for your help.
>
> >
> > Even for things like a->b = func(...)[RSO].  It is even used by the c++
> > frontend that way.
> >
> >
> >
> >      >
> >      >
> >      >
> >      >     Is that what you are looking for?
> >      >
> >      >
> >      >     Thanks,
> >      >     Andrew
> >      >
> >      >         Thanks.
> >      >
> >
>

Reply via email to