Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang-tidy] misc-const-correctness is compared to other checks very slow (16/17) #71786

Closed
Viatorus opened this issue Nov 9, 2023 · 1 comment · Fixed by #72705
Closed
Assignees
Labels
clang-tidy confirmed Verified by a second party performance

Comments

@Viatorus
Copy link

Viatorus commented Nov 9, 2023

E.g. on a file with 1000 lines of unit tests, the following execution time has been measured:

===-------------------------------------------------------------------------===
                          clang-tidy checks profiling
===-------------------------------------------------------------------------===
  Total Execution Time: 49.6135 seconds (49.6176 wall clock)

   ---User Time---   --System Time--   --User+System--   ---Wall Time---  --- Name ---
  25.6283 ( 58.7%)   0.1126 (  1.9%)  25.7409 ( 51.9%)  25.7429 ( 51.9%)  misc-const-correctness
   0.6483 (  1.5%)   0.2052 (  3.4%)   0.8535 (  1.7%)   0.8526 (  1.7%)  bugprone-use-after-move
   0.6351 (  1.5%)   0.2162 (  3.6%)   0.8512 (  1.7%)   0.8514 (  1.7%)  bugprone-stringview-nullptr
   0.6075 (  1.4%)   0.2073 (  3.5%)   0.8148 (  1.6%)   0.8149 (  1.6%)  modernize-type-traits
   0.6096 (  1.4%)   0.1944 (  3.3%)   0.8040 (  1.6%)   0.8033 (  1.6%)  bugprone-standalone-empty
   0.5329 (  1.2%)   0.1910 (  3.2%)   0.7239 (  1.5%)   0.7236 (  1.5%)  misc-unused-using-decls
   0.4504 (  1.0%)   0.1156 (  1.9%)   0.5660 (  1.1%)   0.5661 (  1.1%)  bugprone-infinite-loop
   0.4220 (  1.0%)   0.1425 (  2.4%)   0.5645 (  1.1%)   0.5641 (  1.1%)  cppcoreguidelines-owning-memory
   0.4418 (  1.0%)   0.0943 (  1.6%)   0.5361 (  1.1%)   0.5362 (  1.1%)  modernize-macro-to-enum
   0.3688 (  0.8%)   0.1195 (  2.0%)   0.4883 (  1.0%)   0.4891 (  1.0%)  readability-non-const-parameter
   0.3745 (  0.9%)   0.1123 (  1.9%)   0.4868 (  1.0%)   0.4868 (  1.0%)  readability-container-size-empty
   0.3656 (  0.8%)   0.1147 (  1.9%)   0.4803 (  1.0%)   0.4807 (  1.0%)  readability-uppercase-literal-suffix
   0.3534 (  0.8%)   0.1127 (  1.9%)   0.4660 (  0.9%)   0.4662 (  0.9%)  bugprone-unused-return-value
   0.3396 (  0.8%)   0.1242 (  2.1%)   0.4639 (  0.9%)   0.4640 (  0.9%)  modernize-use-transparent-functors
   0.3372 (  0.8%)   0.1086 (  1.8%)   0.4458 (  0.9%)   0.4461 (  0.9%)  bugprone-suspicious-string-compare
   0.3153 (  0.7%)   0.1140 (  1.9%)   0.4292 (  0.9%)   0.4295 (  0.9%)  cppcoreguidelines-avoid-c-arrays
   0.3024 (  0.7%)   0.0982 (  1.6%)   0.4006 (  0.8%)   0.4007 (  0.8%)  readability-redundant-control-flow
   0.2930 (  0.7%)   0.1062 (  1.8%)   0.3992 (  0.8%)   0.3990 (  0.8%)  modernize-deprecated-ios-base-aliases
   // ...
@PiotrZSL PiotrZSL added the confirmed Verified by a second party label Nov 12, 2023
@PiotrZSL PiotrZSL self-assigned this Nov 12, 2023
@PiotrZSL
Copy link
Member

PiotrZSL commented Nov 12, 2023

Problem is actually in ExprMutationAnalyzer. I tested this check on llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp file, it takes 156 seconds for me , so that's good benchmark. Both callgrind and perf suggest that problem is with many matchers that are short lived, specially those in canResolveToExpr matcher.
I didn't quick proof of concept with merging multiple IgnoreDerivedToBase into one with anyOf, and that bring time down to 122 seconds. Now I'm experimenting with replacing some of those matchers with plain old good code.

Edit: Not using matchers in canResolveToExpr at all, brings time down to 47 seconds.

PiotrZSL added a commit that referenced this issue Jan 9, 2024
Replaced certain AST matchers in ExprMutationAnalyzer with a more direct
utilization of AST classes. The primary bottleneck was identified in the
canResolveToExpr AST matcher. Since this matcher was employed multiple
times and used recursively, each invocation led to the constant creation
and destruction of other matchers within it. Additionally, the continual
comparison of DynTypedNode resulted in significant performance
degradation.

The optimization was tested on the TargetLowering.cpp file. Originally,
the check took 156 seconds on that file, but after implementing this
enhancement, it now takes approximately 40 seconds, making it nearly
four times faster.

Despite this improvement, there are still numerous issues in this file.
To further reduce the computational cost of this class, it is advisable
to consider removing the remaining matchers and exploring alternatives
such as leveraging RecursiveASTVisitor and increasing the direct use of
AST classes.

Closes #71786
justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this issue Jan 28, 2024
Replaced certain AST matchers in ExprMutationAnalyzer with a more direct
utilization of AST classes. The primary bottleneck was identified in the
canResolveToExpr AST matcher. Since this matcher was employed multiple
times and used recursively, each invocation led to the constant creation
and destruction of other matchers within it. Additionally, the continual
comparison of DynTypedNode resulted in significant performance
degradation.

The optimization was tested on the TargetLowering.cpp file. Originally,
the check took 156 seconds on that file, but after implementing this
enhancement, it now takes approximately 40 seconds, making it nearly
four times faster.

Despite this improvement, there are still numerous issues in this file.
To further reduce the computational cost of this class, it is advisable
to consider removing the remaining matchers and exploring alternatives
such as leveraging RecursiveASTVisitor and increasing the direct use of
AST classes.

Closes llvm#71786
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment