Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 22037

Why do gcc and clang generate so much code for std::find?

$
0
0

I entered the following code into godbolt.org, and compiled it with gcc 10.1 and clang 10:

#include <algorithm>#include <vector>typedef std::vector<int> V;template<class InputIt, class T>InputIt myfind(InputIt first, InputIt last, const T& value) {    for (; first != last; ++first) {        if (*first == value) {            return first;        }    }    return last;}V::iterator my_find_int(V& v, int i) {    return myfind(v.begin(), v.end(), i);}V::iterator std_find_int(V& v, int i) {    return std::find(v.begin(), v.end(), i);}

With either -O3 or with -Os, both compilers generate about what I would expect for my_find_int (gcc 10.1, -Os):

my_find_int(std::vector<int, std::allocator<int> >&, int):        mov     rdx, QWORD PTR [rdi+8]        mov     rax, QWORD PTR [rdi].L3:        mov     r8, rax        cmp     rdx, rax        je      .L2        add     rax, 4        cmp     DWORD PTR [rax-4], esi        jne     .L3.L2:        mov     rax, r8        ret

However, for std_find_int, with either -O3 or -Os, they both generate several dozen instructions (gcc 10.1, -Os):

std_find_int(std::vector<int, std::allocator<int> >&, int):        mov     rax, rdi        mov     rdi, QWORD PTR [rdi+8]        mov     rdx, QWORD PTR [rax]        mov     rcx, rdi        sub     rcx, rdx        sar     rcx, 4.L12:        mov     rax, rdx        test    rcx, rcx        jle     .L7        cmp     DWORD PTR [rdx], esi        je      .L8        cmp     DWORD PTR [rdx+4], esi        jne     .L9        add     rax, 4        ret.L9:        cmp     DWORD PTR [rdx+8], esi        jne     .L10        add     rax, 8        ret.L10:        lea     rdx, [rdx+16]        cmp     DWORD PTR [rax+12], esi        jne     .L11        add     rax, 12        ret.L11:        dec     rcx        jmp     .L12.L7:        mov     rdx, rdi        sub     rdx, rax        cmp     rdx, 8        je      .L13        cmp     rdx, 12        je      .L14        cmp     rdx, 4        jne     .L23        jmp     .L15.L14:        cmp     esi, DWORD PTR [rax]        je      .L8        add     rax, 4.L13:        cmp     esi, DWORD PTR [rax]        je      .L8        add     rax, 4.L15:        cmp     esi, DWORD PTR [rax]        je      .L8.L23:        mov     rax, rdi.L8:        ret

According to cppreference.com, myfind is a valid implementation of std::find (they describe it as a "possible implementation" of std::find).

The behavior does not seem to be version-specific; the output of every major version of gcc going back to at least 4.9 looks similar.

It seems like my_find_int and std_find_int should be functionally identical, so why do both compilers generate so much more code when std::find is used?


Viewing all articles
Browse latest Browse all 22037

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>