Manually set sret parameter
Andrew Pinski
pinskia@gmail.com
Mon Jun 30 14:51:00 GMT 2025
On Mon, Jun 30, 2025 at 7:25 AM Antoni Boucher <bouanto@zoho.com> wrote:
>
>
>
> Le 2025-06-29 à 19 h 42, Andrew Pinski a écrit :
> >
> >
> > On Sun, Jun 29, 2025, 4:36 PM Antoni Boucher <bouanto@zoho.com
> > <mailto:bouanto@zoho.com>> wrote:
> >
> >
> >
> > Le 2025-06-29 à 10 h 46, Andrew Pinski a écrit :
> > >
> > >
> > > On Sun, Jun 29, 2025, 7:43 AM Andrew Pinski <pinskia@gmail.com
> > <mailto:pinskia@gmail.com>
> > > <mailto:pinskia@gmail.com <mailto:pinskia@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.
> > >
> >
>
More information about the Gcc
mailing list