www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.ldc - Another interesting difference

reply "bearophile" <bearophileHUGS lycos.com> writes:
I am trying the following program with both the latest dmd 
2.065alpha and ldc2 2.063.2, with no optimizations:


int fun(int[3] a) {
     return a[0]+ a[1] + a[2];
}
int main() {
     int total = 0;
     foreach (immutable _; 0 .. 100_000_000)
         total += fun([1, 2, 3]);
     return total;
}


The results, both in run-time and x86 asm:

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

dmd test2.d
runtime: 0.81

_D5test23funFG3iZi  comdat
         mov EAX,4[ESP]
         add EAX,8[ESP]
         add EAX,0Ch[ESP]
         ret 0Ch

__Dmain comdat
L0:     enter   014h,0
         push    EBX
         xor EAX,EAX
         mov -014h[EBP],EAX
         mov -010h[EBP],EAX
LD:     cmp dword ptr -010h[EBP],05F5E100h
         jge L47
         mov ECX,-010h[EBP]
         mov EDX,1
         mov -0Ch[EBP],EDX
         mov dword ptr -8[EBP],2
         mov dword ptr -4[EBP],3
         lea EBX,-0Ch[EBP]
         push    dword ptr 8[EBX]
         push    dword ptr 4[EBX]
         push    dword ptr [EBX]
         call    near ptr _D5test23funFG3iZi
         add -014h[EBP],EAX
         inc dword ptr -010h[EBP]
         jmp short   LD
L47:        mov EAX,-014h[EBP]
         pop EBX
         leave
         ret

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

ldmd2 test2.d
runtime: 1.94


ldmd2 -output-s test2.d

__D5test23funFG3iZi:
     subl    $28, %esp
     leal    32(%esp), %eax
     movb    $1, %cl
     testb   $1, %cl
     movl    %eax, 24(%esp)
     jne LBB0_2
     jmp LBB0_1
LBB0_1:
     leal    __D5test212__ModuleInfoZ, %eax
     movl    $2, %ecx
     movl    %eax, (%esp)
     movl    $2, 4(%esp)
     movl    %ecx, 20(%esp)
     calll   __d_array_bounds
LBB0_2:
     movb    $1, %al
     testb   $1, %al
     jne LBB0_4
     leal    __D5test212__ModuleInfoZ, %eax
     movl    $2, %ecx
     movl    %eax, (%esp)
     movl    $2, 4(%esp)
     movl    %ecx, 16(%esp)
     calll   __d_array_bounds
LBB0_4:
     movb    $1, %al
     movl    24(%esp), %ecx
     movl    (%ecx), %edx
     addl    4(%ecx), %edx
     testb   $1, %al
     movl    %edx, 12(%esp)
     jne LBB0_6
     leal    __D5test212__ModuleInfoZ, %eax
     movl    $2, %ecx
     movl    %eax, (%esp)
     movl    $2, 4(%esp)
     movl    %ecx, 8(%esp)
     calll   __d_array_bounds
LBB0_6:
     movl    24(%esp), %eax
     movl    8(%eax), %ecx
     movl    12(%esp), %edx
     addl    %ecx, %edx
     movl    %edx, %eax
     addl    $28, %esp
     ret $12

__Dmain:
     subl    $40, %esp
     movl    $0, 36(%esp)
     movl    $0, 32(%esp)
     movl    $100000000, 28(%esp)
LBB1_1:
     cmpl    $100000000, 32(%esp)
     jge LBB1_4
     movl    32(%esp), %eax
     movl    %eax, 24(%esp)
     movl    $3, 20(%esp)
     movl    $2, 16(%esp)
     movl    $1, 12(%esp)
     movl    20(%esp), %eax
     movl    %esp, %ecx
     movl    %eax, 8(%ecx)
     movsd   12(%esp), %xmm0
     movsd   %xmm0, (%ecx)
     calll   __D5test23funFG3iZi
     subl    $12, %esp
     movl    36(%esp), %ecx
     addl    %eax, %ecx
     movl    %ecx, 36(%esp)
     movl    32(%esp), %eax
     addl    $1, %eax
     movl    %eax, 32(%esp)
     jmp LBB1_1
LBB1_4:
     movl    36(%esp), %eax
     addl    $40, %esp
     ret

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

Do you know why ldc2 puts array bound tests inside fun()? The 
array 'a' inside fun() is a fixed size array, so there is no need 
to verify at run-time that 0 1 2 are within the array bounds.

Bye,
bearophile
Dec 12 2013
next sibling parent reply "David Nadlinger" <code klickverbot.at> writes:
On 12 Dec 2013, at 10:00, bearophile wrote:
 Do you know why ldc2 puts array bound tests inside fun()? The array 
 'a' inside fun() is a fixed size array, so there is no need to verify 
 at run-time that 0 1 2 are within the array bounds.
I don't know why we are, but we shouldn't: https://github.com/ldc-developers/ldc/issues/553 David
Dec 12 2013
parent "Kai Nacke" <kai redstar.de> writes:
On Thursday, 12 December 2013 at 09:37:36 UTC, David Nadlinger 
wrote:
 On 12 Dec 2013, at 10:00, bearophile wrote:
 Do you know why ldc2 puts array bound tests inside fun()? The 
 array 'a' inside fun() is a fixed size array, so there is no 
 need to verify at run-time that 0 1 2 are within the array 
 bounds.
I don't know why we are, but we shouldn't: https://github.com/ldc-developers/ldc/issues/553 David
This is the solution: https://github.com/ldc-developers/ldc/pull/554 Regards, Kai
Dec 12 2013
prev sibling parent "Kai Nacke" <kai redstar.de> writes:
On Thursday, 12 December 2013 at 09:00:08 UTC, bearophile wrote:
 I am trying the following program with both the latest dmd 
 2.065alpha and ldc2 2.063.2, with no optimizations:
[..snip..]
 Do you know why ldc2 puts array bound tests inside fun()?
Yes! There was no check for this situation in ldc2. Bounds checking code was emitted for all array references. dmd 2.064 omits the bounds checking code if the access can be checked at compile time. Therefore you see the difference. I fixed this in the master and the merge-2.064 branch. The next release will include the fix. Regards, Kai
Dec 16 2013