Memory Allocation Optimized away with new by not with ::operator new
Francois_Fayard1 May 4, 2015, 10:37am #1
I've made my own version of std::vector which is called il::Vector. Due to http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3664.html, LLVM can optimise away memory allocation. Therefore, the following code optimise away all memory allocation for w resulting in a single allocation during the whole program (for v).
When using my own vector implementation, I realised that the allocation were not optimized away because I was using ::operator new. When I've switched back to new, the optimisation came back.
Is it expected or a bug from LLVM?
d0k May 4, 2015, 11:45am #2
I've made my own version of std::vector which is called il::Vector. Due to
Clarifying Memory Allocation, LLVM can
optimise away memory allocation. Therefore, the following code optimise away
all memory allocation for w resulting in a single allocation during the
whole program (for v).
When using my own vector implementation, I realised that the allocation were
not optimized away because I was using ::operator new. When I've switched
back to new, the optimisation came back.
Sadly this is a feature. The C++ standard has been unclear
historically about whether removing pairs of new/delete. The problem
is that the user may override them so this is an observable change,
but some compilers (LLVM) removed them anyways. As you said C++14
changed the wording so removing new/delete expression pairs is now
explicitly legal. Calls to ::operator new and delete aren't new/delete
expressions though, so it should behave as expected when overridden.
It looks like a glitch in the standard, but if I remember correctly it
was done intentionally.
- Ben
mats_petersson1 May 4, 2015, 11:50am #3
If the compiler can't say for sure that your operator new is identical (has no side-effects beyond allocating memory), it would be correct for the compiler to NOT optimise it out - as it can't determine that it has no other effect that your program rely on in some way.
Dennis_Luehring May 4, 2015, 11:57am #4
look at the "newly" added __builtin_operator_new/delete (by Richard Smith)
discussed missing heap optimization for vector and std::string
http://clang-developers.42468.n3.nabble.com/missing-optimization-opportunity-for-const-std-vector-compared-to-std-array-td4034587.html#none
resulting patches to clang/libc++ to use the optimization
http://reviews.llvm.org/rL210137
or is it now in c++14 explicitly allowed?
Francois_Fayard1 May 4, 2015, 1:27pm #5
I have checked and N3664 only talks about new/delete but not about operator
new/delete. Do you know the rationale behind this choice?
dblaikie May 4, 2015, 3:47pm #6
I believe the notion was to provide a syntax for /actually/ calling those
functions that the compiler couldn't optimize away, in case you wanted them
for their side effects, etc.
By the way, does anybody know an example where LLVM can fuse 2 memory allocation into one? In N3664, it is explicitly said that the compiler is allowed to do that.