Date: Tue, 29 Apr 2025 13:49:30 +0200
I've floated a similar idea a while ago, which is to make an "if provable"
statement like
if provable (x == 0)
Such a statement would not be evaluated at runtime, and only be true when
the compiler knows that x == 0 is true, similar to [[assume]]. In clang,
this can be emulated already like
if (__builtin_constant_p(x == 0) && x == 0)
The problem here is x == 0 is not a constant expression, and it cannot be.
The idea of "if provable" or your equivalent is to leverage optimizer
knowledge, or knowledge during constant evaluation, but this cannot
translate back into the type system so that you could use x as an array
size or something.
My idea also received some negative feedback due to ODR concerns. Another
approach would be to have "constexpr parameters", which I'm pretty sure has
been proposed before, like
void f(constexpr int x);
This would implicitly turn f into a function template. However, this
solution is still kinda bad because it can only make use of x being a true
constant expression; it doesn't benefit from the optimizer figuring out the
value of x after optimization passes. The mylog example should still be
optimized even if the base is not a constant expression, but it's revealed
after optimization passes that the base is known to the optimizer.
Unfortunately, it is incredibly difficult to approach this design space. I
think constexpr function parameters would be a good start, but ideally, you
would have some way to write "optimizer scripts" to make this feature much
more powerful.
statement like
if provable (x == 0)
Such a statement would not be evaluated at runtime, and only be true when
the compiler knows that x == 0 is true, similar to [[assume]]. In clang,
this can be emulated already like
if (__builtin_constant_p(x == 0) && x == 0)
The problem here is x == 0 is not a constant expression, and it cannot be.
The idea of "if provable" or your equivalent is to leverage optimizer
knowledge, or knowledge during constant evaluation, but this cannot
translate back into the type system so that you could use x as an array
size or something.
My idea also received some negative feedback due to ODR concerns. Another
approach would be to have "constexpr parameters", which I'm pretty sure has
been proposed before, like
void f(constexpr int x);
This would implicitly turn f into a function template. However, this
solution is still kinda bad because it can only make use of x being a true
constant expression; it doesn't benefit from the optimizer figuring out the
value of x after optimization passes. The mylog example should still be
optimized even if the base is not a constant expression, but it's revealed
after optimization passes that the base is known to the optimizer.
Unfortunately, it is incredibly difficult to approach this design space. I
think constexpr function parameters would be a good start, but ideally, you
would have some way to write "optimizer scripts" to make this feature much
more powerful.
Received on 2025-04-29 11:49:49