Memory Allocation Optimized away with new by not with ::operator new

Hi,

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?

François

Hi,

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.

Is it expected or a bug from LLVM?

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

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.

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
http://reviews.llvm.org/rL210211

or is it now in c++14 explicitly allowed?

Hi,

I have checked and N3664 only talks about new/delete but not about operator
new/delete. Do you know the rationale behind this choice?

Hi,

I have checked and N3664 only talks about new/delete but not about operator
new/delete. Do you know the rationale behind this choice?

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.

That makes sense.

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.