|
|
size_t
for indexing to be safe in both 32 and 64 bit builds.
i
in the first loop should be std::vector<T>::size_type
or at least std::size_t
|
|
# second loop (with .end()) ..B1.3: movq %r12, %rdi call Bar::Foo() ..B1.4: addq $8, %r12 cmpq 8+vector(%rip), %r12 jne ..B1.3 |
In the following example, vector implementation stores the end pointer as a member of std::vector, while size has to be calculated as end minus begin, and the compiler couldn't determine that it was a loop invariant... |
jb
(less than) vs jne
(not equal), while gcc kept subtracting, for shame.
|
|
second loop, using .end() .L900000205: call Bar::Foo() add %i2,1,%i2 ld [%i3],%i4 cmp %i2,%i4 bne,pt %icc,.L900000205 or %g0,%i2,%o0 |
|
|
# second loop, using .end() __L180: bl Bar::Foo() oril r0,r0,0x0000 l r3,64(SP) l r0,8(r31) st r0,68(SP) cal r3,1(r3) st r3,64(SP) cmpl 0,r3,r0 bc BO_IF_NOT,CR0_EQ,__L180 |
|
|
# second loop, using .end() ..L5: add r37 = 0, r36 add r36 = 1, r36 br.call.sptk.many rp = Bar::Foo() ld4 r8 = [r35] add gp = 0, r32 cmp4.ne.unc p6, p0 = r36, r8 br.dptk.many ..L5 |
|
|
return _size;
in the implementation. Seems like a prime candidate for inlining/optimizing.
To be fair, the compiler will never optimize that ::size() call away on a non-const container |
std::for_each(myvec.begin(), myvec.end(), CallFoo());
|
|
..B1.3: movl $_2__STRING.0, %edi call puts ..B1.4: incq %r13 cmpq %r12, %r13 jb ..B1.3 |