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

Richard Smith richard at metafoo.co.uk
Fri May 30 13:50:18 PDT 2014


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


More information about the cfe-dev mailing list