The setup:
I have a function that uses SIMD intrinsics and would like to use it inside some constexpr functions.
For that, I need to make it constexpr. However, the SIMD intrinsics are not marked constexpr, and the constant evaluator of the compiler cannot handle them.
I tried replacing the SIMD intrinsics with a C++ constexpr implementation that does the same thing. The function became 3.5x slower at run-time, but I was able to use it at compile-time (yay?).
The problem:
How can I use this function inside constant expressions without slowing down my program at run-time?
Some ideas:
More pragmatic solutions would be to either:
Anyhow, I am open to any suggestion that solves my problem.
Hints:
__builtin_constant_p
to detect whether the function arguments are all constant expressions, in which case the compiler would hopefully be at least attempting to evaluate the function at compile-time.Failed attempts:
I would do it like this
constexpr int doit(int input, bool inconst = false) {
return inconst ? doitconsty(input) : doitfast(input);
}
If the call to doit
is inside of a constexpr
function that can be called to perform something either at runtime or at compile time, just forward the flag
constexpr int f(int n, bool inconst = false) {
/* ... */
int importantInt = doit(n / 42, inconst);
/* ... */
return magicResult;
}
Any constexpr
evaluation has something where it starts, if I'm not mistaken. Pass the inconst
there
enum foo { bar = f(256, true) }
If you are in the runtime world, just call f
like anything else
int main() { std::cout << "test-case: " << f(256); }
It should be noted that this does not work for operators, because you can't add the boolean parameter there. Instead, you could pass the value in some different way, if that's fine for you (for primitive values like int
and bool
, we could not overload the operator either).
template<typename T>
struct maybe_const_value {
T t;
bool isconst;
};
enum foo { bar = maybe_const_value{256, true} % magicTransform };
int main() { return maybe_const_value{265} % magicTransform; }
The operator function can then check input.isconst
and use input.t
as the actual value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With