Thread overview
Returning fixed size arrays
Jun 25, 2014
bearophile
Jun 25, 2014
bearophile
Jun 25, 2014
John Colvin
Jun 26, 2014
bearophile
Jun 26, 2014
John Colvin
Jun 26, 2014
bearophile
Jun 25, 2014
Tobias Pankrath
Jun 25, 2014
bearophile
June 25, 2014
Is it possible and a good idea to change the D ABI to make code like this avoid an array copy in 100% of the cases (without inlining)?


ubyte[1000] foo() nothrow @safe {
    typeof(return) data;
    // some code here.
    return data;
}
void main() nothrow {
    immutable data = foo();
}


Bye,
bearophile
June 25, 2014
> Is it possible and a good idea to change the D ABI to make code like this avoid an array copy in 100% of the cases (without inlining)?

I meant, letting the compiler rewrite that code like this:


void foo(ref ubyte[1000] __data) nothrow @safe {
    __data[] = 0;
    // some code here.
}
void main() nothrow {
    ubyte[1000] __data = void;
    foo(__data);
    immutable data = cast(immutable ubyte[1000])__data;
}


Bye,
bearophile
June 25, 2014
On Wednesday, 25 June 2014 at 20:55:47 UTC, bearophile wrote:
> Is it possible and a good idea to change the D ABI to make code like this avoid an array copy in 100% of the cases (without inlining)?
>
>
> ubyte[1000] foo() nothrow @safe {
>     typeof(return) data;
>     // some code here.
>     return data;
> }
> void main() nothrow {
>     immutable data = foo();
> }
>
>
> Bye,
> bearophile

Isn't this a case for Named Return Value Optimization?

June 25, 2014
Tobias Pankrath:

> Isn't this a case for Named Return Value Optimization?

Perhaps, but then why aren't dmd/ldc doing it? And the question was if that's possible in the ABI, so it always happens (unless the array is very small).

Bye,
bearophile
June 25, 2014
On Wednesday, 25 June 2014 at 20:59:29 UTC, bearophile wrote:
>> Is it possible and a good idea to change the D ABI to make code like this avoid an array copy in 100% of the cases (without inlining)?
>
> I meant, letting the compiler rewrite that code like this:
>
>
> void foo(ref ubyte[1000] __data) nothrow @safe {
>     __data[] = 0;
>     // some code here.
> }
> void main() nothrow {
>     ubyte[1000] __data = void;
>     foo(__data);
>     immutable data = cast(immutable ubyte[1000])__data;
> }
>
>
> Bye,
> bearophile

perhaps i'm misunderstanding things, but isn't this exactly what the System V ABI specifies anyway? Large aggregate returns are allocated on the calling stack, passed by hidden pointer.
June 26, 2014
John Colvin:

> isn't this exactly what the System V ABI specifies anyway? Large aggregate returns are allocated on the calling stack, passed by hidden pointer.

So do you know why D is not using that design?

Bye,
bearophile
June 26, 2014
On Thursday, 26 June 2014 at 12:06:34 UTC, bearophile wrote:
> John Colvin:
>
>> isn't this exactly what the System V ABI specifies anyway? Large aggregate returns are allocated on the calling stack, passed by hidden pointer.
>
> So do you know why D is not using that design?
>
> Bye,
> bearophile

It is, but a copy is made after the function returns anyway, for reasons unknown to me. For some reason the optimizer can't elide it (ldc2 -O5 -release, with a pragma(LDC_never_inline); inside foo).
June 26, 2014
John Colvin:

> It is,

As far as I know, D is using that as an optimization, not as an ABI default that must happen at all optimization levels.


> but a copy is made after the function returns anyway, for reasons unknown to me. For some reason the optimizer can't elide it (ldc2 -O5 -release, with a pragma(LDC_never_inline); inside foo).

Right. perhaps I'll have to ask this again in the main D newsgroup (but perhaps better to do it Monday).

Bye,
bearophile