July 17, 2010
I remember Don saying something about this some time ago, but I don't remember what he said and what the conclusion was.

This is a small D2 program that contains the initialization of a small fixed-size array allocated on the stack:


import std.c.stdio: printf;
import std.c.stdlib: atof;
void main() {
    double x = atof("1.0");
    double y = atof("2.0");
    double[2] arr = [x, y];
    printf("%f\n", arr[1]);
}


The asm generated by dmd in an optimized build shows two calls to initialize the array. Can such calls be removed in this simple situation?

------------

DMD:
__Dmain comdat
        sub ESP,04Ch
        mov EAX,offset FLAT:_DATA
        push    EBX
        push    ESI
        push    EAX
        call    near ptr _atof
        mov ECX,offset FLAT:_DATA[4]
        fstp    qword ptr 010h[ESP]
        push    010h
        push    ECX
        call    near ptr _atof
        add ESP,0FFFFFFFCh
        mov EDX,offset FLAT:_D12TypeInfo_xAd6__initZ
        fstp    qword ptr [ESP]
        push    dword ptr 020h[ESP]
        push    dword ptr 020h[ESP]
        push    2
        push    EDX
>       call    near ptr __d_arrayliteralT
        add ESP,018h
        push    EAX
        lea EBX,028h[ESP]
        push    EBX
>       call    near ptr _memcpy
        mov ESI,offset FLAT:_DATA[8]
        push    dword ptr 038h[ESP]
        push    dword ptr 038h[ESP]
        push    ESI
        call    near ptr _printf
        add ESP,01Ch
        xor EAX,EAX
        pop ESI
        pop EBX
        add ESP,04Ch
        ret

------------

LDC:
_Dmain:
    subl    $52, %esp
    movl    $.str, (%esp)
    call    atof
    fstpt   28(%esp)
    movl    $.str1, (%esp)
    call    atof
    fstpt   16(%esp)
    movl    $2, 4(%esp)
    movl    $_D11TypeInfo_Ad6__initZ, (%esp)
>   call    _d_newarrayvT
    fldt    28(%esp)
    fstpl   (%eax)
    fldt    16(%esp)
    fstpl   40(%esp)
    movsd   40(%esp), %xmm0
    movsd   %xmm0, 8(%eax)
    movsd   %xmm0, 4(%esp)
    movl    $.str2, (%esp)
    call    printf
    xorl    %eax, %eax
    addl    $52, %esp
    ret $8

------------

Bye,
bearophile
July 19, 2010
On Sat, 17 Jul 2010 13:15:18 -0400, bearophile <bearophileHUGS@lycos.com> wrote:

> I remember Don saying something about this some time ago, but I don't remember what he said and what the conclusion was.
>
> This is a small D2 program that contains the initialization of a small fixed-size array allocated on the stack:
>
>
> import std.c.stdio: printf;
> import std.c.stdlib: atof;
> void main() {
>     double x = atof("1.0");
>     double y = atof("2.0");
>     double[2] arr = [x, y];
>     printf("%f\n", arr[1]);
> }
>
>
> The asm generated by dmd in an optimized build shows two calls to initialize the array. Can such calls be removed in this simple situation?

The first call builds a dynamic array on the heap.

The second call copies the array from the heap to the stack.

The bug should be that it's using the heap at all.

-Steve