<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, May 30, 2014 at 1:50 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">On Wed, May 28, 2014 at 4:35 AM, dennis luehring <span dir="ltr"><<a href="mailto:dl.soluz@gmx.net" target="_blank">dl.soluz@gmx.net</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">i've rechecked against<br>
<br>
gcc.<a href="http://gcc.godbolt.org/" target="_blank">http://gcc.godbolt.org/</a><br>
*clang version 3.4.1<br>
*gcc 4.9 20130909<br>
with -O3 -std=c++11<br>
<br>
gcc does not optimize down to result 160 and does not remove the new/deletes<br>
<br>
main:<br>
<div>        pushq   %rbx<br>
        movl    $12, %edi<br>
</div>        call    operator new(unsigned long)<br>
        movq    ._41(%rip), %rdx<br>
        movq    %rax, %rdi<br>
        movq    %rdx, %rsi<br>
        movq    %rdx, (%rax)<br>
        movl    ._41+8(%rip), %eax<br>
        shrq    $32, %rsi<br>
        leal    100(%rsi,%rdx), %ebx<br>
        movl    %eax, 8(%rdi)<br>
        addl    %eax, %ebx<br>
        testq   %rdi, %rdi<br>
<div>        je      .L2<br>
        call    operator delete(void*)<br>
.L2:<br>
</div><div>        movl    %ebx, %eax<br>
        popq    %rbx<br>
        ret<br>
</div>._41:<br>
<div>        .long   10<br>
        .long   20<br>
        .long   30<br>
<br>
</div>clang does optimize down to result 160 but still not remove the new/deletes<br>
<br>
main:                                   # @main<br>
        pushq   %rax<br>
<div>        movl    $12, %edi<br>
        callq   operator new(unsigned long)<br>
</div>        testq   %rax, %rax<br>
<div>        movabsq $85899345930, %rcx      # imm = 0x140000000A<br>
        movq    %rcx, (%rax)<br>
</div>        movl    $30, 8(%rax)<br>
        je      .LBB0_2<br>
<div>        movq    %rax, %rdi<br>
        callq   operator delete(void*)<br>
</div>.LBB0_2:                                # %_ZNSt6vectorIiSaIiEED2Ev.exit<br>
        movl    $160, %eax<br>
        popq    %rdx<br>
        ret<br>
<br>
so Bens "Sadly, removing the allocation is harder." seems to be still hard</blockquote><div><br></div></div></div><div>This is close to the best result that a conforming compiler can give (for the standard library implementation you're using). We're not *permitted* to remove those operator new/operator delete calls by the standard, because operator new and operator delete can be overridden by the user.</div>

<div><br></div><div>The standard (as of only a few months ago) allows operator new/operator delete calls such as the above to be removed, but *only* if they came from new-expressions and delete-expressions. Under the covers, std::vector uses direct calls to ::operator new and ::operator delete, so these provisions do not apply.</div>

<div><br></div><div>So... we should add some way for std::allocator to say "allocate/deallocate memory like a new-expression", and use it in libc++. I think we should add</div><div><br></div><div>  void *__builtin_operator_new(size_t)</div>

<div>  void __builtin_operator_delete(void*)</div><div><br></div><div>for this.</div></div></div></div>
</blockquote></div><br></div><div class="gmail_extra">Clang now supports these, and I have a patch out for review to make libc++ use them. With the patch applied, clang+libc++ optimizes your code down to just 'return 160' for both the std::array and std::vector cases.</div>
</div>