[crossgen2] Add --strip-il-bodies option for composite R2R#125647
[crossgen2] Add --strip-il-bodies option for composite R2R#125647kotlarmilos wants to merge 4 commits intodotnet:mainfrom
Conversation
Add a --strip-il-bodies crossgen2 option that replaces IL method bodies of successfully R2R-compiled methods with minimal stubs (ret) in the composite output assemblies. This reduces assembly size for scenarios where the IL interpreter fallback is not needed, such as full R2R on iOS/MacCatalyst. Methods that were not compiled by crossgen2 retain their original IL bodies. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a --strip-il-bodies crossgen2 option for composite R2R that replaces IL method bodies of successfully compiled methods with minimal ret stubs, reducing output size for scenarios like full R2R on iOS/MacCatalyst.
Changes:
- New
--strip-il-bodiesCLI option and correspondingNodeFactoryOptimizationFlagsfields - Builds a set of compiled method definitions and passes it to component file rewriting
- In
CopiedMethodILNode, replaces IL bodies of non-generic compiled methods with a minimal 2-byte stub
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| Crossgen2RootCommand.cs | Declares the --strip-il-bodies CLI option |
| Program.cs | Wires the option value into nodeFactoryFlags.StripILBodies |
| ReadyToRunCodegenNodeFactory.cs | Adds StripILBodies/CompiledMethodDefs fields and BuildCompiledMethodDefsSet() |
| ReadyToRunCodegenCompilation.cs | Builds the compiled methods set and passes it through to RewriteComponentFile |
| CopiedMethodILNode.cs | Implements IL body stripping with a minimal ret stub for compiled non-generic methods |
You can also share your feedback on Copilot code review. Take the survey.
| public class CopiedMethodILNode : ObjectNode, ISymbolDefinitionNode | ||
| { | ||
| // Minimal IL method body: tiny header (0x02 flags | 0x01 size << 2 = 0x06) + ret opcode (0x2A). | ||
| private static readonly byte[] s_minimalILBody = new byte[] { 0x06, 0x2A }; |
There was a problem hiding this comment.
| private static readonly byte[] s_minimalILBody = new byte[] { 0x06, 0x2A }; | |
| private static readonly byte[] s_minimalILBody = [0x06, 0x2A]; |
Will this stub method body be emitted once per method definition, or once and shared across all method definitions?
There was a problem hiding this comment.
I think it is emitted once per method definition, but could be shared.
There was a problem hiding this comment.
Looks like we do not de-dup IL method bodies in general. That's sounds like a bug that you may want to look into fixing as part of your binary size work. (I believe IL linker does that.)
...tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedMethodILNode.cs
Outdated
Show resolved
Hide resolved
...tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedMethodILNode.cs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Pull request overview
Adds a new crossgen2 switch to reduce composite R2R deployment size by stripping IL bodies from rewritten component assemblies when the method was successfully compiled into the composite image.
Changes:
- Add
--strip-il-bodiesoption wiring from crossgen2 CLI intoNodeFactoryOptimizationFlags. - Track the set of methods compiled into the composite image and pass it into component-module rewriting.
- When rewriting component assemblies, replace eligible compiled methods’ IL bodies with a minimal stub body.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/tools/aot/crossgen2/Program.cs | Wires the new CLI option into NodeFactoryOptimizationFlags. |
| src/coreclr/tools/aot/crossgen2/Crossgen2RootCommand.cs | Introduces and registers the --strip-il-bodies command-line option. |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCodegenCompilation.cs | Builds the compiled-method set for composite builds and passes it into component rewriting. |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRunCodegenNodeFactory.cs | Extends optimization flags and adds helper to compute the compiled method definition set. |
| src/coreclr/tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedMethodILNode.cs | Implements IL-body replacement for eligible methods during component rewrite. |
You can also share your feedback on Copilot code review. Take the survey.
...tools/aot/ILCompiler.ReadyToRun/Compiler/DependencyAnalysis/ReadyToRun/CopiedMethodILNode.cs
Show resolved
Hide resolved
| public Option<bool> StripILBodies { get; } = | ||
| new("--strip-il-bodies") { Description = "Replace IL method bodies of compiled methods with a throwing stub in the output image" }; |
Description
Add a
--strip-il-bodiescrossgen2 option that replaces IL method bodies of successfully R2R-compiled methods with minimal stubs (ret) in composite output assemblies. This reduces assembly size for scenarios where IL interpreter fallback is not needed, such as full R2R on iOS/MacCatalyst.Fixes #124860