[r2r] Enable generic cycles detection by default#128957
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates crossgen2 ReadyToRun (R2R) compilation to enable generic-cycle detection by default and to proactively avoid GVM dependency expansion for methods/types that are flagged as potentially participating in generic cycles. The goal is to prevent explosive graph growth during dependency analysis that can lead to compiler overflows/timeouts (as seen in R2R compilation of System.Linq.Parallel.Tests).
Changes:
- Enable generic-cycle detection by default for R2R by setting the builder’s generic cycle cutoffs to
ReadyToRunCompilerContextdefaults. - Extend the generic cycle detection infrastructure with a “could be in a cycle” query and plumb it through the R2R
NodeFactory(CanBeInGenericCycle). - Make
NodeFactory.GVMDependencies(...)returnnullfor potentially-cyclic entities and update GVM dependency consumers to tolerate and skip these dependencies; remove the older GVM-node-local generic cycle check.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/tools/Common/Compiler/GenericCycleDetection/ModuleCycleInfo.cs | Adds a CanBeInCycle query on GenericCycleDetector for fast cycle-membership checks. |
| src/coreclr/tools/Common/Compiler/DependencyAnalysis/GVMDependenciesNode.cs | Updates dynamic dependency discovery to handle GVMDependencies(...) returning null; removes per-node generic-cycle try/catch in R2R path. |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilationBuilder.cs | Enables generic-cycle detection by default by initializing cutoffs to ReadyToRunCompilerContext defaults. |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs | Adds CanBeInGenericCycle and skips creating GVM dependency nodes for potentially-cyclic definitions (returns null). |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/MethodFixupSignature.cs | Avoids adding a virtual dispatch GVM dependency when GVMDependencies(...) returns null. |
|
/azp run runtime-coreclr crossgen2 outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Following the addition of GVM handling in r2r via dynamic dependencies, System.Linq.Parallel.Tests fails to compile, by overflow due to excessive compilation. Enabling the scanning for generic cycles alone doesn't fix this (--enable-generic-cycle-detection). This testsuite also fails to compile on NativeAot where it is disabled. It seems like, despite having generic cycle checks inside the GVM expansion, the amount of nodes still grows at an excessive rate, breaking the compilation. As a fix, we ensure that we have the `_genericCycleDetector` initialized by default on r2r and use it to query for types/methods that could be part of generic cycles (from the computed `ModuleCycleInfo` information). We conservatively avoid any GVM scan for these entities, to avoid excessive compilation and potential size increases, since we have the flexibility to fallback to jit/interpreter at runtime. As a side effect, this enables the generic cycle checks for other areas of R2R, but, given we will start compiling more methods with generics, it might be a good thing to have it enabled anyway.
4bd014c to
8875f9e
Compare
|
/azp run runtime-coreclr crossgen2 outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
fecdc14 to
74f7257
Compare
74f7257 to
df3bc5a
Compare
|
Disabled the test in the same way as the others in this Negative set. Removed the option to enable the cycle detection. Note it could still be disabled by setting both remaining knobs to -1. |
|
/azp run runtime-coreclr crossgen2 outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run runtime-coreclr crossgen2 outerloop |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Following the addition of GVM handling in r2r via dynamic dependencies, System.Linq.Parallel.Tests fails to compile, by overflow due to excessive compilation. Enabling the scanning for generic cycles alone doesn't fix this (--enable-generic-cycle-detection). This testsuite also fails to compile on NativeAot where it is disabled. It seems like, despite having generic cycle checks inside the GVM expansion, the amount of nodes still grows at an excessive rate, breaking the compilation.
As a fix, we ensure that we have the
_genericCycleDetectorinitialized by default on r2r and use it to query for types/methods that could be part of generic cycles (from the computedModuleCycleInfoinformation). We conservatively avoid any GVM scan for these entities, to avoid excessive compilation and potential size increases, since we have the flexibility to fallback to jit/interpreter at runtime.As a side effect, this enables the generic cycle checks for other areas of R2R, but, given we will start compiling more methods with generics, it might be a good thing to have it enabled anyway.
Also removes the previous generic cycles check from GVMDependenciesNode which no longer seem necessary.
Fixes #128694