Skip to content

[MicroPerf] Fuse the optimizer inlining copy + type-instantiation passes - #20363

Open
T-Gro wants to merge 1 commit into
dotnet:mainfrom
T-Gro:t-gro-remark-fuse-spike
Open

[MicroPerf] Fuse the optimizer inlining copy + type-instantiation passes#20363
T-Gro wants to merge 1 commit into
dotnet:mainfrom
T-Gro:t-gro-remark-fuse-spike

Conversation

@T-Gro

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

Copy link
Copy Markdown
Member

Inlining a generic function saturated by its type arguments cloned the body twice: copyExpr (clone + fresh vals), then a second full traversal inside MakeApplicationAndBetaReduce to substitute the type arguments. remapExpr already applies a type instantiation at every type position, so the generic-inline site now carries the instantiation via mkInstRemap in the same copy pass — one traversal, one val-clone.

Allocation

Release net11.0, 65,880-LOC project, GC.GetTotalAllocatedBytes(true), 3 runs × 4 iters:

build MB / compile
base 10,662
this PR 10,105
delta −557 (−5.2%)

Diff

One hunk in Optimizer.fs (+11 / −4). TypedTreeOps.Remapping.* untouched; no new ValCopyFlag case.

match f2 with
| Expr.TyLambda(_, tyvs, body, _, bodyTy) when tyvs.Length = tyargs.Length ->
    let tpinst = bindTypars tyvs tyargs emptyTyparInst
    let bodyR = remapExpr g CloneAllAndMarkExprValsAsCompilerGenerated (mkInstRemap tpinst) body |> remarkExpr m
    MakeApplicationAndBetaReduce g (bodyR, instType tpinst bodyTy, [], argsR, m)
| _ -> // non-TyLambda: unchanged original path

Verification

check result
EmittedIL + Optimizations suites (net11.0) 671 pass, 0 regressions (6 pre-existing PrintFunction env failures — identical on base)
Differential batteries (generic inline / match / try / for / while / closures / InlineIfLambda / struct / byref / SRTP / GenericZero), --optimize+ and --optimize- --debug:portable byte-identical IL + PDB vs base
[<ReflectedDefinition>] assembly reflected-definitions resource-name tag shifts by the newUnique delta (one clone instead of two); pickled-payload hash unchanged, name is prefix-consumed — cosmetic only

Branch fires ~6.2k times per compile of the workload, so the fused path is exercised (not dead).

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

❗ Release notes required

You can open this PR in browser to add release notes: open in github.dev


✅ Found changes and release notes in following paths:

Change path Release notes path Description
`src/Compiler` docs/release-notes/.FSharp.Compiler.Service/11.0.100.md

@T-Gro
T-Gro force-pushed the t-gro-remark-fuse-spike branch from 5eb52d1 to ed67aaf Compare August 26, 2026 14:29
@github-actions github-actions Bot added the ⚠️ Affects-Compiler-Output Tooling check: PR touches IL emission or codegen label Aug 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Tooling Safety Check — Affects-Compiler-Output
Affects-Compiler-Output: modifies Optimizer.fs and TypedTreeOps.Remapping

Generated by PR Tooling Safety Check · opus46 4M ·

When inlining a generic function saturated by its type arguments, the optimizer
cloned the whole body twice: copyExpr (clone + fresh vals), then a separate
type-application beta reduction to substitute the type args. remapExpr already
applies a type instantiation at every type position, so the generic-inline site
now carries the instantiation via mkInstRemap in the same copy pass - one
traversal, one val-clone - and applies the (already type-instantiated) body with
an empty tyarg list. The range-remark stays a separate pass, unchanged.

Non-generic inline sites are untouched, and TypedTreeOps.Remapping is unchanged.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 69e8646f-b2d9-4852-af5c-5f96dc2d36a3
@T-Gro
T-Gro force-pushed the t-gro-remark-fuse-spike branch from ed67aaf to 7679c37 Compare August 26, 2026 17:40
@T-Gro T-Gro changed the title Fuse the optimizer inlining copy/remark/instantiate passes Fuse the optimizer inlining copy + type-instantiation passes Aug 26, 2026
@T-Gro T-Gro changed the title Fuse the optimizer inlining copy + type-instantiation passes [MicroPerf] Fuse the optimizer inlining copy + type-instantiation passes Aug 27, 2026
@T-Gro
T-Gro requested a review from abonie August 27, 2026 08:17
@T-Gro
T-Gro enabled auto-merge (squash) August 27, 2026 08:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚠️ Affects-Compiler-Output Tooling check: PR touches IL emission or codegen Theme-Performance

Projects

Status: New

Development

Successfully merging this pull request may close these issues.

1 participant