[cfe-dev] Constexpr evaluation speed

David Rector via cfe-dev cfe-dev at lists.llvm.org
Fri Mar 5 10:41:16 PST 2021



> On Mar 5, 2021, at 1:13 PM, David Rector <davrecthreads at gmail.com> wrote:
> 
> 
> 
>> On Mar 5, 2021, at 12:00 PM, paul.robinson at sony.com <mailto:paul.robinson at sony.com> wrote:
>> 
>> 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
>>  
>> One can easily imagine (say) Apple building an X86-hosted Clang that includes only ARM targets for building code to run on mobile devices; it would not have a native target, so building “for the current machine” would be infeasible.  Building natively for the host can only be an optimization, it can’t be the general solution.
> 
> I suppose what I mean is that it would be up to the user to build and link the desired constexpr/"meta" libraries on their own via a prior build step, with a different compiler if necessary (as it would be in the case you describe); then pass those the locations of those libraries to the current compiler via some independent flag ("—meta-library-directory" or something).  

One last insight - it occurs to me that just requiring the user to *always* build a separate meta library, i.e. one that is only ever passed as a —meta-library-directory and never as a --library-directory, *even when building for the host*, might solve the issue Balazs raised previously: sanitizers etc. could be added only to functions in the meta library, as necessary to match needed constexpr semantics; the semantics of/pessimizations in the "constexpr binaries" need not ever intrude on the ordinary non-constexpr binaries.

To be sure though - there is enough complexity here, and not yet sufficient need, that all this is just food for thought.

> But these matters are already well beyond my breadth/depth, so I am sure I am missing still further complexities, and this certainly would be one important consideration among many.
> 
>> --paulr
>>  
>> From: cfe-dev <cfe-dev-bounces at lists.llvm.org <mailto:cfe-dev-bounces at lists.llvm.org>> On Behalf Of David Rector via cfe-dev
>> Sent: Friday, March 5, 2021 11:53 AM
>> To: Arthur O'Dwyer <arthur.j.odwyer at gmail.com <mailto:arthur.j.odwyer at gmail.com>>
>> Cc: clang developer list <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>>
>> Subject: Re: [cfe-dev] Constexpr evaluation speed
>>  
>>  
>> 
>> 
>> On Mar 4, 2021, at 5:34 PM, Arthur O'Dwyer <arthur.j.odwyer at gmail.com <mailto: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 theusual 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,
>>  
>> Dave
> 

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


More information about the cfe-dev mailing list