[cfe-dev] Potential missed optimization - unnecessary reload of vtable ptr inside loop body

Alex Wang via cfe-dev cfe-dev at lists.llvm.org
Wed Mar 7 10:41:29 PST 2018


Hello all!

I posted a question about a potential missed optimization to llvm-dev, but was
directed here since it concerned more C++-specific bits of code. Previous
conversion can be found at [0] and [1].

The code in question is here: https://godbolt.org/g/ec5cP7

My main question here is about assembly lines 24 and 46, where I think the
vtable pointer for the Rect object is being reloaded every iteration of the
loop. nbjoerg on #llvm said that's due to the possibility of placement new being
used somewhere inside the called function, but I'm not entirely sure that
placement new can change what vtable the vtable pointer points to.

(I'm new to this language lawyering stuff, so please let me know what I mess up)

As far as I understand, paragraph 8 of 6.6.3 [basic.life] in the most recent
draft of the standard says that references or names of an object that has been
"replaced" by placement new are only "redirected" to the new object if the new
object is the same type and no other class derives from that type; otherwise,
the reference/name refers to an object whose lifetime has ended. Thus, any uses
of the "this" pointer after a member function is called are only valid if the
placement new'd object is the same type, and so has the same vtable, which means
the vtable pointer does not have to be reloaded.

The example for point 6.5 of paragraph 6 of 6.6.3 sort of supports this
interpretation, since calling B::mutate() changes the type of *this, which
causes pb to point to an object whose lifetime has ended, and further method
calls through pb result in undefined behavior.

Is this reasoning correct? ICC 18, Clang trunk, Clang 5.0, GCC 7.3, GCC trunk,
and MSVC 19 all perform the reload, so I'm guessing I'm wrong, but I'm not sure
how.

If the vtable pointer reload is required, is there a way to indicate to Clang
that such a reload will not be necessary, even though the compiler can't verify
that (sort of like __restrict)? I tried adding [[gnu::pure]] to the function
declarations and definitions, but the vtable pointer reload remained. Does Clang
take [[gnu::pure]]/[[gnu::const]] into account for code generation/optimization?

Thanks for the help!

Alex

    [0]: http://lists.llvm.org/pipermail/llvm-dev/2018-February/121439.html
    [1]: http://lists.llvm.org/pipermail/llvm-dev/2018-March/121486.html


More information about the cfe-dev mailing list