Jump to page: 1 2
Thread overview
[Issue 13381] One case of array literal that can be stack-allocated
Aug 31, 2014
yebblies
Aug 31, 2014
yebblies
Aug 31, 2014
yebblies
Aug 31, 2014
yebblies
Aug 31, 2014
yebblies
Aug 31, 2014
yebblies
[Issue 13381] Two cases of array literal that can be stack-allocated
Sep 14
Dennis
August 31, 2014
https://issues.dlang.org/show_bug.cgi?id=13381

yebblies <yebblies@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |yebblies@gmail.com
           Hardware|x86                         |All
                 OS|Windows                     |All

--- Comment #1 from yebblies <yebblies@gmail.com> ---
I agree.

--
August 31, 2014
https://issues.dlang.org/show_bug.cgi?id=13381

--- Comment #2 from bearophile_hugs@eml.cc ---
Given this code:

void foo(uint[] a) @nogc {
    if (a == [1, 2]) {}
}


One way to rewrite it is (the immutable can't be always used):


void foo(uint[] a) @nogc {
    immutable static uint[2] __foo_aux0 == [1, 2];
    if (a == __foo_aux0) {}
}


Or more efficient:

void foo(uint[] a) @nogc {
    if (a.length == 2 && a[0] == 1 && a[1] == 2) {}
}

--
August 31, 2014
https://issues.dlang.org/show_bug.cgi?id=13381

--- Comment #3 from yebblies <yebblies@gmail.com> ---
(In reply to bearophile_hugs from comment #2)
> 
> One way to rewrite it is (the immutable can't be always used):
> 

While re-writes are certainly the simplest way to explain it, using them in the compiler often leads to complications, especially with error messages referring to the re-written code instead of the original.

For this case, and similar cases, the compiler can simply type the array literal as a static array, because it knows that == can't escape any references.  It already does something like this for indexing array literals.

--
August 31, 2014
https://issues.dlang.org/show_bug.cgi?id=13381

--- Comment #4 from bearophile_hugs@eml.cc ---
(In reply to yebblies from comment #3)

> For this case, and similar cases, the compiler can simply type the array literal as a static array, because it knows that == can't escape any references.  It already does something like this for indexing array literals.

I see. I have suggested a rewrite like this:

if (a.length == 2 && a[0] == 1 && a[1] == 2) {}

Because most array literals used for equality or comparison are short or very short, so calling == or < on few single items is much more efficient than calling a runtime function that works on whole arrays.

--
August 31, 2014
https://issues.dlang.org/show_bug.cgi?id=13381

--- Comment #5 from yebblies <yebblies@gmail.com> ---
(In reply to bearophile_hugs from comment #4)
> (In reply to yebblies from comment #3)
> 
> > For this case, and similar cases, the compiler can simply type the array literal as a static array, because it knows that == can't escape any references.  It already does something like this for indexing array literals.
> 
> I see. I have suggested a rewrite like this:
> 
> if (a.length == 2 && a[0] == 1 && a[1] == 2) {}
> 
> Because most array literals used for equality or comparison are short or very short, so calling == or < on few single items is much more efficient than calling a runtime function that works on whole arrays.

Ideally the optimizer would do this by itself, once the literal is stack-allocated.  I suspect it already does in some cases for gdc/ldc.

--
August 31, 2014
https://issues.dlang.org/show_bug.cgi?id=13381

--- Comment #6 from bearophile_hugs@eml.cc ---
(In reply to yebblies from comment #5)

> Ideally the optimizer would do this by itself, once the literal is stack-allocated.  I suspect it already does in some cases for gdc/ldc.

If I compile this program:


bool foo(in int[] a) {
    return a == [1, 2, 3];
}
void main() {}


With the latest ldc2 with:

ldmd2 -O -release -inline -noboundscheck -output-s test.d


The asm of foo is:

__D4test3fooFxAiZb:
    subl    $20, %esp
    movl    $3, 4(%esp)
    movl    $__D12TypeInfo_xAi6__initZ, (%esp)
    calll   __d_newarrayvT
    movl    $3, 8(%edx)
    movl    $2, 4(%edx)
    movl    $1, (%edx)
    movl    %edx, 12(%esp)
    movl    %eax, 8(%esp)
    movl    28(%esp), %eax
    movl    %eax, 4(%esp)
    movl    24(%esp), %eax
    movl    %eax, (%esp)
    movl    $__D12TypeInfo_Axi6__initZ, 16(%esp)
    calll   __adEq2
    testl   %eax, %eax
    setne   %al
    addl    $20, %esp
    ret $8

--
August 31, 2014
https://issues.dlang.org/show_bug.cgi?id=13381

--- Comment #7 from yebblies <yebblies@gmail.com> ---
(In reply to bearophile_hugs from comment #6)
> (In reply to yebblies from comment #5)
> 
> > Ideally the optimizer would do this by itself, once the literal is stack-allocated.  I suspect it already does in some cases for gdc/ldc.
> 
> If I compile this program:
> 

Like I said, once the literal is stack-allocated it's more likely to work.

--
August 31, 2014
https://issues.dlang.org/show_bug.cgi?id=13381

--- Comment #8 from bearophile_hugs@eml.cc ---
(In reply to yebblies from comment #7)

> Like I said, once the literal is stack-allocated it's more likely to work.

OK, another experiment:


bool foo(in int[] a) {
    immutable static int[3] aux = [1, 2, 3];
    return a == aux;
}
void main() {}


__D4test3fooFxAiZb:
    subl    $20, %esp
    movl    28(%esp), %eax
    movl    %eax, 4(%esp)
    movl    24(%esp), %eax
    movl    %eax, (%esp)
    movl    $__D12TypeInfo_Axi6__initZ, 16(%esp)
    movl    $__D4test3fooFxAiZb3auxyG3i, 12(%esp)
    movl    $3, 8(%esp)
    calll   __adEq2
    testl   %eax, %eax
    setne   %al
    addl    $20, %esp
    ret $8

--
August 31, 2014
https://issues.dlang.org/show_bug.cgi?id=13381

--- Comment #9 from yebblies <yebblies@gmail.com> ---
(In reply to bearophile_hugs from comment #8)
> (In reply to yebblies from comment #7)
> 
> > Like I said, once the literal is stack-allocated it's more likely to work.
> 
> OK, another experiment:
> 
> 
> bool foo(in int[] a) {
>     immutable static int[3] aux = [1, 2, 3];
>     return a == aux;
> }
> void main() {}
> 
> 
> __D4test3fooFxAiZb:
>     subl    $20, %esp
>     movl    28(%esp), %eax
>     movl    %eax, 4(%esp)
>     movl    24(%esp), %eax
>     movl    %eax, (%esp)
>     movl    $__D12TypeInfo_Axi6__initZ, 16(%esp)
>     movl    $__D4test3fooFxAiZb3auxyG3i, 12(%esp)
>     movl    $3, 8(%esp)
>     calll   __adEq2
>     testl   %eax, %eax
>     setne   %al
>     addl    $20, %esp
>     ret $8

Which compiler?  I'd say it's worth filing an optimizer enhancement.

--
August 31, 2014
https://issues.dlang.org/show_bug.cgi?id=13381

--- Comment #10 from bearophile_hugs@eml.cc ---
(In reply to yebblies from comment #9)

> Which compiler?

The latest ldc2, version   0.14.0 (DMD v2.065, LLVM 3.4.2).

dmd is not doing better.
I don't know what gdc does in this case.


> I'd say it's worth filing an optimizer enhancement.

I don't know.

--
« First   ‹ Prev
1 2