Open e0e1e613-dccb-47a5-85db-3dc989429265 opened 7 years ago
Oh, I see.
So, essentially, in c++17 compiler is mandated to compute everything in compile time. In c++14 however, it's not and the optimizer cannot see through enough layers to optimize it all away.
Would be nice, if the optimizer could see all of that though.
Can you elaborate - why non-constexpr lambdas matter in this case? I mean - they are still only called in runtime.
In C++17, the initializer of the 'vtable' variable is a constant expression: both the evaluation of the lambda expression itself (creating an object of the closure type) and the conversion to a function pointer are constexpr operations. So the 'vtable' variable's initializer will be emitted as a compile-time constant.
In C++14, neither the lambda expression itself nor the conversion to a function pointer are permitted in constant expressions (and neither Clang's nor LLVM's optimizations for static initializers are able to completely fold the initializer to a constant). So we emit code that initializes the value of the 'vtable' variable at runtime instead.
@Richard Smith
You are right in a sense that if I use constexpr function instead of a lambda function, codegen becomes identical.
Can you elaborate - why non-constexpr lambdas matter in this case? I mean - they are still only called in runtime.
In C++17 onwards, lambdas can appear in constant expressions. This change seems like an expected consequence of that to me.
Extended Description
Hi.
I was playing with variant implementation and found out that c++1z option produces a better code than with c++14. Might be worth looking into.
Unfortunately, links to goldbolt currently do not work, so I attach code as file.
It's not exactly an easy read so quick idea: for each possible combination of parameters, I instantiate a function. All of this functions are written in one n-dimentional array, where each dimension corresponds to an element. So sum of two variants should be equivalent to:
Compiling with c++1z generates 2 times less instructions than with c++14. This does not seem right.
Compilation options:
-Werror -Wall --std=c++1z -O3 -fno-exceptions -DNDEBUG