[cfe-dev] Constexpr evaluation speed

David Rector via cfe-dev cfe-dev at lists.llvm.org
Fri Mar 5 08:52:52 PST 2021

> On Mar 4, 2021, at 5:34 PM, Arthur O'Dwyer <arthur.j.odwyer at gmail.com> wrote:
> On Thu, Mar 4, 2021 at 3:25 PM David Rector via cfe-dev <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>> wrote:
>> On Mar 4, 2021, at 2:26 PM, Balázs Benics <benicsbalazs at gmail.com <mailto:benicsbalazs at gmail.com>> wrote:
>> I don't think you can easily substitute constexpr evaluation with simply calling a compiled counterpart. [...]
> Thanks for this input, you’re right — e.g. `constexpr void f(A *a)` might or might not be able to handle `f(nullptr)`; it would require proof, and there things probably get too complex.  
> The other thing you have to keep in mind is cross-compilers. JIT interpreters do not have to deal with cross-compilation.
> Clang could certainly invest in JIT-compiled codepaths for its constexpr evaluation, and that might make the usual desktop-compilation path blazing fast... but then you'd be in this weird situation where Boost-or-whatever compiled in a reasonable amount of time for x86-64, but building an ARM binary would take days. (Until you bought an M1 Mac, I guess, and then the situation would flip-flop.)
> my $.02,
> Arthur

Yes, cross-compiling would be another complexity of such an approach; I suppose you would probably need to separately build your "constexpr binaries" for the current machine in addition to whatever building you do for the target platform

Even with these complexities, I can’t quite let the possibility go.  A user might run a single expensive constexpr metafunction might be run millions or billions of times on different inputs.  If we could analyze it just a single time, and guarantee it safely handles its inputs, or some subset of possible inputs that could be encoded along with it, it is tantalizing to consider how fast builds could get if we could call the binary version of it, bypassing all those expensive checks and the interpreter infrastructure during those calls.  

Whether these static analysis challenges are surmountable is of course well beyond my depth.

And there are other problems with the approach; e.g. anything absolutely requiring constant evaluation, e.g. reflected meta::infos, or injection statements, could not directly be compiled to binary, or at least would require a lot of additional thought.  

And, perhaps a JIT approach would not be far off in performance anyway.  Perhaps the interpreter alone will ultimately prove sufficient.  

Concluding thought:

C++ allows lightning fast run time performance…at the expense of expertise, labor, and maintenance.

Reflection + injection can solve these issues, allowing the user to delegate that expertise, labor, and maintenance to metafunctions/metaclasses…but at the expense of increases in build time due the challenges of constexpr evaluation.

This last issue may require additional focus in the medium/long term.

Thanks all,

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20210305/de62215a/attachment-0001.html>

More information about the cfe-dev mailing list