Skip to content

[MicroPerf] Fuse copyExpr and remarkExpr into one pass when inlining - #20352

Closed
T-Gro wants to merge 1 commit into
mainfrom
t-gro-remarkexpr-perf-spike
Closed

T-Gro wants to merge 1 commit into
mainfrom
t-gro-remarkexpr-perf-spike

Conversation

@T-Gro

@T-Gro T-Gro commented Aug 25, 2026

Copy link
Copy Markdown
Member

The optimizer's two inlining paths ran copyExpr (a full tree rebuild that clones locals) then remarkExpr (a second full rebuild that only stamps every node's range with the call site), discarding the first tree — so the second rebuild was pure allocation. remapExprImpl now takes an optional target range and re-marks in the same traversal it already does for copying, reproducing remarkExpr exactly (range rewrite, debug-point erasure on loop/try ops, NoneAtInvisible matches, NoneAtSticky binds, DebugPoint stripping, and keeping introduced temporaries' original ranges).

Emitted IL and PDBs are byte-for-byte unchanged on every workload checked. A 65,880-LOC / 120-file compile allocates ~321 MB less per compile (10,673 → 10,352 MB/iter, --optimize+).

The two inlining hot paths in the optimizer ran copyExpr (a full tree
rebuild that clones locals) and then remarkExpr (a second full tree
rebuild that only rewrites every node's range to the call site). The
first tree is discarded immediately, so the second rebuild is pure waste.

remapExprImpl now carries an optional target range; when set it re-marks
every constructed node in the same traversal it already does for copying,
reproducing remarkExpr's behaviour exactly (range rewrite, debug-point
erasure on loop/try TOps, NoneAtInvisible matches, NoneAtSticky binds,
DebugPoint wrapper stripping, and preserving introduced temporaries'
original ranges). CopyExprForInlining and the ConstExprValue path use the
new copyAndRemarkExpr entry point instead of copyExpr |> remarkExpr.

Output is byte-for-byte identical (IL and PDB) to before on every workload
checked, and a 65,880-LOC / 120-file compile drops ~321 MB of allocation
per compile (10,673 MB -> 10,352 MB/iter, --optimize+).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@T-Gro
T-Gro requested a review from a team as a code owner August 25, 2026 15:33
@T-Gro T-Gro added NO_RELEASE_NOTES Label for pull requests which signals, that user opted-out of providing release notes AI-Tooling-Check-Bypassed Tooling check: non-fork PR, not diff-analyzed labels Aug 25, 2026
@github-actions

github-actions Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

⚠️ Release notes required, but author opted out

Warning

Author opted out of release notes, check is disabled for this pull request.
cc @dotnet/fsharp-team-msft

@T-Gro

T-Gro commented Aug 26, 2026

Copy link
Copy Markdown
Member Author

Closing — change is too bloated for the win; reworking toward a minimal diff.

@T-Gro T-Gro closed this Aug 26, 2026
@T-Gro T-Gro changed the title Fuse copyExpr and remarkExpr into one pass when inlining [MicroPerf] Fuse copyExpr and remarkExpr into one pass when inlining Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI-Tooling-Check-Bypassed Tooling check: non-fork PR, not diff-analyzed NO_RELEASE_NOTES Label for pull requests which signals, that user opted-out of providing release notes Theme-Performance

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

1 participant