[cfe-dev] missing optimization opportunity for const std::vector compared to std::array

Richard Smith richard at metafoo.co.uk
Tue Jun 3 15:16:46 PDT 2014


On Fri, May 30, 2014 at 1:50 PM, Richard Smith <richard at metafoo.co.uk>
wrote:

> On Wed, May 28, 2014 at 4:35 AM, dennis luehring <dl.soluz at gmx.net> wrote:
>
>> i've rechecked against
>>
>> gcc.http://gcc.godbolt.org/
>> *clang version 3.4.1
>> *gcc 4.9 20130909
>> with -O3 -std=c++11
>>
>> gcc does not optimize down to result 160 and does not remove the
>> new/deletes
>>
>> main:
>>         pushq   %rbx
>>         movl    $12, %edi
>>         call    operator new(unsigned long)
>>         movq    ._41(%rip), %rdx
>>         movq    %rax, %rdi
>>         movq    %rdx, %rsi
>>         movq    %rdx, (%rax)
>>         movl    ._41+8(%rip), %eax
>>         shrq    $32, %rsi
>>         leal    100(%rsi,%rdx), %ebx
>>         movl    %eax, 8(%rdi)
>>         addl    %eax, %ebx
>>         testq   %rdi, %rdi
>>         je      .L2
>>         call    operator delete(void*)
>> .L2:
>>         movl    %ebx, %eax
>>         popq    %rbx
>>         ret
>> ._41:
>>         .long   10
>>         .long   20
>>         .long   30
>>
>> clang does optimize down to result 160 but still not remove the
>> new/deletes
>>
>> main:                                   # @main
>>         pushq   %rax
>>         movl    $12, %edi
>>         callq   operator new(unsigned long)
>>         testq   %rax, %rax
>>         movabsq $85899345930, %rcx      # imm = 0x140000000A
>>         movq    %rcx, (%rax)
>>         movl    $30, 8(%rax)
>>         je      .LBB0_2
>>         movq    %rax, %rdi
>>         callq   operator delete(void*)
>> .LBB0_2:                                # %_ZNSt6vectorIiSaIiEED2Ev.exit
>>         movl    $160, %eax
>>         popq    %rdx
>>         ret
>>
>> so Bens "Sadly, removing the allocation is harder." seems to be still hard
>
>
> 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.
>
> 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.
>
> 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
>
>   void *__builtin_operator_new(size_t)
>   void __builtin_operator_delete(void*)
>
> for this.
>

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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140603/de81ed5b/attachment.html>


More information about the cfe-dev mailing list