Skip to content

Conversation

jtschuster
Copy link
Member

Fixes #118121

With large block counts, the CFG convergence takes a long time and performs a lot of Meets, allocating a new Dictionary for each Value in each block. This adds up to gigabytes of allocations in the process.

Ideally we would fix the performance issue with some optimization, but I'm still working on a proper solution. To fix the issue for .NET 10 in the meantime, we can add a limit to the number of iterations to bail out if we reach an excessively large number of iterations. The largest number of iterations in the runtime build is 2600, so 10,000 seems fairly reasonable to me. The build time of the project in #118121 is around ~20 seconds with 10,000 iterations and ~70 seconds with 20,000.

@jtschuster jtschuster added this to the 10.0.0 milestone Aug 15, 2025
@jtschuster jtschuster requested review from agocke and sbomer August 15, 2025 06:10
@jtschuster jtschuster self-assigned this Aug 15, 2025
@jtschuster jtschuster added the area-Tools-ILLink .NET linker development as well as trimming analyzers label Aug 15, 2025
@Copilot Copilot AI review requested due to automatic review settings August 15, 2025 06:10
@dotnet-policy-service dotnet-policy-service bot added the linkable-framework Issues associated with delivering a linker friendly framework label Aug 15, 2025
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds a configurable limit on control flow graph (CFG) convergence iterations in the trim analyzer to prevent excessive memory allocation and build time issues. The change addresses a performance problem where large block counts cause the CFG convergence algorithm to perform millions of iterations, each allocating new dictionaries and consuming gigabytes of memory.

Key Changes:

  • Introduces a maximum iteration limit of 10,000 for CFG convergence
  • Adds early termination logic to prevent runaway iteration scenarios
  • Provides a temporary fix while a more comprehensive performance solution is developed

Copy link
Contributor

Tagging subscribers to this area: @dotnet/illink
See info in area-owners.md if you want to be subscribed.

Copy link
Member

@sbomer sbomer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM as a way to prevent the hang. I think it would be worth adding a warning if we couldn't complete analysis of a method, would you mind adding that?

@jtschuster
Copy link
Member Author

LGTM as a way to prevent the hang. I think it would be worth adding a warning if we couldn't complete analysis of a method, would you mind adding that?

Added an Info diagnostic, but happy to make it a warning if we think it's warranted.

@sbomer
Copy link
Member

sbomer commented Aug 15, 2025

My vote is to make it a warning, since it's possible that it hides a real trimming issue.

Copy link
Member

@sbomer sbomer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM if we make it a warning. Thank you!

@jtschuster jtschuster enabled auto-merge (squash) August 15, 2025 21:02
@jtschuster jtschuster merged commit c270c9e into dotnet:main Aug 16, 2025
76 checks passed
@github-project-automation github-project-automation bot moved this to Done in AppModel Aug 16, 2025
@vcsjones
Copy link
Member

@jtschuster I see you have the milestone set as 10.0, but it looks like this PR missed the release/10.0 snap.

@jtschuster
Copy link
Member Author

/backport to release/10.0-rc1

Copy link
Contributor

Started backporting to release/10.0-rc1: https://github.com/dotnet/runtime/actions/runs/17046124731

Copy link
Contributor

@jtschuster backporting to "release/10.0-rc1" failed, the patch most likely resulted in conflicts:

$ git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch

Applying: Add limit on CFG convergence iterations
Using index info to reconstruct a base tree...
M	src/tools/illink/src/ILLink.Shared/DataFlow/ForwardDataFlowAnalysis.cs
Falling back to patching base and 3-way merge...
Auto-merging src/tools/illink/src/ILLink.Shared/DataFlow/ForwardDataFlowAnalysis.cs
No changes -- Patch already applied.
Applying: Add warning for CFG convergence bailout
Using index info to reconstruct a base tree...
M	src/tools/illink/src/ILLink.RoslynAnalyzer/DataFlow/LocalDataFlowAnalysis.cs
M	src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs
M	src/tools/illink/src/ILLink.Shared/DataFlow/ForwardDataFlowAnalysis.cs
M	src/tools/illink/src/ILLink.Shared/DiagnosticId.cs
M	src/tools/illink/src/ILLink.Shared/SharedStrings.resx
Falling back to patching base and 3-way merge...
Auto-merging src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs
CONFLICT (content): Merge conflict in src/tools/illink/src/ILLink.RoslynAnalyzer/DynamicallyAccessedMembersAnalyzer.cs
error: Failed to merge in the changes.
hint: Use 'git am --show-current-patch=diff' to see the failed patch
hint: When you have resolved this problem, run "git am --continue".
hint: If you prefer to skip this patch, run "git am --skip" instead.
hint: To restore the original branch and stop patching, run "git am --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Patch failed at 0002 Add warning for CFG convergence bailout
Error: The process '/usr/bin/git' failed with exit code 128

Please backport manually!

@jtschuster
Copy link
Member Author

Looks like it made it in with #118812

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-Tools-ILLink .NET linker development as well as trimming analyzers linkable-framework Issues associated with delivering a linker friendly framework
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Excessive CPU and memory usage (70+ GB) when running analyzers
4 participants