[clang-tidy] Determining constexpr evaluation time

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[clang-tidy] Determining constexpr evaluation time

Hubert Tong via cfe-dev
Hello all,

Is it possible to determine if a CallExpr will be evaluated
at compile time from clang-tidy? I notice some references to
InConstantContext in the EvaluateAs* functions in ExprConstant.cpp,
but I'm not sure if that is applicable/usable from clang-tidy.

Thanks,
Connor Davis





_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [clang-tidy] Determining constexpr evaluation time

Hubert Tong via cfe-dev
There is `Expr::isCXX11ConstantExpr(const ASTContext &C, …)`, which returns e.g.:

```
constexpr int f(int i) {
  return i + 42;
}

int g(int i) {
  return
      f(i); // 
isCXX11ConstantExpr = false
}

int main() {
  int j =
      g(3); // 
isCXX11ConstantExpr = false

  int k =
      f(g(3)); // 
isCXX11ConstantExpr = false (both CallExprs)

  int l =
      f(3); // 
isCXX11ConstantExpr = true
}
```

It is defined in terms of `EvaluateAsRValue` FWIW.  Note that all the `EvaluateAs*` methods refer to evaluating at compile time, regardless of the `InConstantContext` argument, and (I think) all will return false whenever the expression cannot fully "fold" (i.e. if there will necessarily be run-time dependencies remaining in the expression, or there was an error during evaluation).

Hope that helps,

Dave

On Aug 30, 2020, at 7:15 PM, Connor Davis via cfe-dev <[hidden email]> wrote:

Hello all,

Is it possible to determine if a CallExpr will be evaluated
at compile time from clang-tidy? I notice some references to
InConstantContext in the EvaluateAs* functions in ExprConstant.cpp,
but I'm not sure if that is applicable/usable from clang-tidy.

Thanks,
Connor Davis





_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [clang-tidy] Determining constexpr evaluation time

Hubert Tong via cfe-dev
Hi Dave,

That makes sense, however I'm looking for a way to determine if an actual
call instruction will be emitted. Using your example in godbolt (using x86-64
trunk with -std=c++17) there are four call instructions in main. But using
```constexpr int l = f(3);``` results in only three calls in main. And passing
-O2 removes all of them. Is there some way to statically determine that the
call instruction will be omitted?

For context, I have a patch for misc-no-recursion that does not warn when an
SCC is found in the call graph where each node is marked consteval, and I thought
that the "every node is constexpr but evaluated at compile time" is another case
where recursion would be OK. Although now that I type it out it's really "every
node is inlined".

Thanks,
Connor

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Monday, August 31, 2020 5:17 PM, David Rector <[hidden email]> wrote:

> There is `Expr::isCXX11ConstantExpr(const ASTContext &C, …)`, which returns e.g.:
>
> ```
> constexpr int f(int i) {
>   return i + 42;
> }
> int g(int i) {
>   return
>       f(i); // isCXX11ConstantExpr = false
> }
> int main() {
>   int j =
>       g(3); // isCXX11ConstantExpr = false
>   int k =
>       f(g(3)); // isCXX11ConstantExpr = false (both CallExprs)
>   int l =
>       f(3); // isCXX11ConstantExpr = true
> }```
>
> It is defined in terms of `EvaluateAsRValue` FWIW.  Note that all the `EvaluateAs*` methods refer to evaluating at compile time, regardless of the `InConstantContext` argument, and (I think) all will return false whenever the expression cannot fully "fold" (i.e. if there will necessarily be run-time dependencies remaining in the expression, or there was an error during evaluation).
>
> Hope that helps,
>
> Dave
>
> > On Aug 30, 2020, at 7:15 PM, Connor Davis via cfe-dev <[hidden email]> wrote:
> >
> > Hello all,
> >
> > Is it possible to determine if a CallExpr will be evaluated
> > at compile time from clang-tidy? I notice some references to
> > InConstantContext in the EvaluateAs* functions in ExprConstant.cpp,
> > but I'm not sure if that is applicable/usable from clang-tidy.
> >
> > Thanks,
> > Connor Davis
> >
> > _______________________________________________
> > cfe-dev mailing list
> > [hidden email]
> > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev


_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [clang-tidy] Determining constexpr evaluation time

Hubert Tong via cfe-dev
I’m stumped — I am kind of surprised that `f(3)` is not always evaluated away before CodeGen, but even disregarding that, I am not sure how to determine which CallExprs are ultimately emitted as calls given the possibility of additional optimizations.

Does anyone else have insight?

Dave

> On Sep 1, 2020, at 12:48 AM, Connor Davis <[hidden email]> wrote:
>
> Hi Dave,
>
> That makes sense, however I'm looking for a way to determine if an actual
> call instruction will be emitted. Using your example in godbolt (using x86-64
> trunk with -std=c++17) there are four call instructions in main. But using
> ```constexpr int l = f(3);``` results in only three calls in main. And passing
> -O2 removes all of them. Is there some way to statically determine that the
> call instruction will be omitted?
>
> For context, I have a patch for misc-no-recursion that does not warn when an
> SCC is found in the call graph where each node is marked consteval, and I thought
> that the "every node is constexpr but evaluated at compile time" is another case
> where recursion would be OK. Although now that I type it out it's really "every
> node is inlined".
>
> Thanks,
> Connor
>
> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
> On Monday, August 31, 2020 5:17 PM, David Rector <[hidden email]> wrote:
>
>> There is `Expr::isCXX11ConstantExpr(const ASTContext &C, …)`, which returns e.g.:
>>
>> ```
>> constexpr int f(int i) {
>>   return i + 42;
>> }
>> int g(int i) {
>>   return
>>       f(i); // isCXX11ConstantExpr = false
>> }
>> int main() {
>>   int j =
>>       g(3); // isCXX11ConstantExpr = false
>>   int k =
>>       f(g(3)); // isCXX11ConstantExpr = false (both CallExprs)
>>   int l =
>>       f(3); // isCXX11ConstantExpr = true
>> }```
>>
>> It is defined in terms of `EvaluateAsRValue` FWIW.  Note that all the `EvaluateAs*` methods refer to evaluating at compile time, regardless of the `InConstantContext` argument, and (I think) all will return false whenever the expression cannot fully "fold" (i.e. if there will necessarily be run-time dependencies remaining in the expression, or there was an error during evaluation).
>>
>> Hope that helps,
>>
>> Dave
>>
>>> On Aug 30, 2020, at 7:15 PM, Connor Davis via cfe-dev <[hidden email]> wrote:
>>>
>>> Hello all,
>>>
>>> Is it possible to determine if a CallExpr will be evaluated
>>> at compile time from clang-tidy? I notice some references to
>>> InConstantContext in the EvaluateAs* functions in ExprConstant.cpp,
>>> but I'm not sure if that is applicable/usable from clang-tidy.
>>>
>>> Thanks,
>>> Connor Davis
>>>
>>> _______________________________________________
>>> cfe-dev mailing list
>>> [hidden email]
>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
>

_______________________________________________
cfe-dev mailing list
[hidden email]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev