Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
6a04e7b
Optimizer: don't inline named functions in debug builds
auduchinok Apr 3, 2026
0054ff1
Xlf
auduchinok Apr 7, 2026
257c702
Release notes
auduchinok Apr 7, 2026
193c36c
Don't specialize local functions
auduchinok Apr 7, 2026
d229804
Remove specialized values caching
auduchinok Apr 7, 2026
a8491d1
Fix witness passing
auduchinok Apr 8, 2026
23d09eb
Inline NoDynamicInvocation and some builtin functions
auduchinok Apr 9, 2026
b550111
Add more tests
auduchinok Apr 9, 2026
d729149
Update compiler options test baseline
auduchinok Apr 9, 2026
be87db7
More witness fixes
auduchinok Apr 11, 2026
bdfc882
Don't check accessibility for non-inlined functions
auduchinok Apr 10, 2026
66e2f26
Fix
auduchinok Apr 12, 2026
7d922d9
Fix same line name
auduchinok Apr 12, 2026
af085c2
More SRTP
auduchinok Apr 12, 2026
3a857f5
Accessibility
auduchinok Apr 13, 2026
4b2880b
Fantomas
auduchinok Apr 13, 2026
67bbcf4
Inline when extra optimization loops
auduchinok Apr 13, 2026
777423f
Specialize signature-hidden values
auduchinok Apr 13, 2026
0ab3245
Byref
auduchinok Apr 14, 2026
ddc38be
More verify in tests
auduchinok Apr 14, 2026
3aaead6
Resumable tests
auduchinok Apr 14, 2026
79412f1
Another accessibility attempt
auduchinok Apr 15, 2026
43ce57a
Fix inlined definition check
auduchinok Apr 15, 2026
2dc1443
Optimized to debug
auduchinok Apr 15, 2026
07adb24
Update baseline
auduchinok Apr 15, 2026
87e6132
Fix Optimize flag in mass-converted tuple tests
auduchinok Apr 15, 2026
3b27d90
Async baselines
auduchinok Apr 15, 2026
11f5c62
Nested inline with different type args
auduchinok Apr 15, 2026
09d1f9c
Update test
auduchinok Apr 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/release-notes/.FSharp.Compiler.Service/11.0.100.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@

* Added warning FS3884 when a function or delegate value is used as an interpolated string argument. ([PR #19289](https://github.com/dotnet/fsharp/pull/19289))
* Add `#version;;` directive to F# Interactive to display version and environment information. ([Issue #13307](https://github.com/dotnet/fsharp/issues/13307), [PR #19332](https://github.com/dotnet/fsharp/pull/19332))
* Optimizer: don't inline named functions in debug builds ([PR #19548](https://github.com/dotnet/fsharp/pull/19548)
26 changes: 24 additions & 2 deletions src/Compiler/CodeGen/IlxGen.fs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,8 @@ type IlxGenOptions =

/// When set to true, the IlxGen will delay generation of method bodies and generated them later in parallel (parallelized across files)
parallelIlxGenEnabled: bool

inlineNamedFunctions: bool
}

/// Compilation environment for compiling a fragment of an assembly
Expand Down Expand Up @@ -5586,8 +5588,13 @@ and GenTraitCall (cenv: cenv) cgbuf eenv (traitInfo: TraitConstraintInfo, argExp

| None ->

// If witnesses are available, we should now always find trait witnesses in scope
assert not generateWitnesses
// When inlineNamedFunctions is true, all trait calls should be resolved via witnesses in scope.
// When inlineNamedFunctions is false, inline functions are kept as calls rather than inlined.
// Their witness arguments may contain TraitCall operations for constraints that were resolved
// without a witness (e.g., when the constraint is satisfied by a known concrete type).
// In such cases, generateWitnesses can be true (because other witnesses are in scope) but
// the specific trait's witness is not found. Fall through to the constraint solver to resolve it.
assert (not generateWitnesses || not cenv.options.inlineNamedFunctions)

let exprOpt =
CommitOperationResult(ConstraintSolver.CodegenWitnessExprForTraitConstraint cenv.tcVal g cenv.amap m traitInfo argExprs)
Expand Down Expand Up @@ -7073,6 +7080,21 @@ and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenv takenNames

let cloFreeTyvars = cloFreeTyvars.FreeTypars |> Zset.elements

// When generating witnesses, witness types may reference type variables that appear
// only in SRTP constraints of the captured type variables (e.g. 'b in 'a : (member M: unit -> 'b)).
// Include those so they are available when generating witness field types.
let cloFreeTyvars =
if ComputeGenerateWitnesses g eenv then
let extra =
GetTraitWitnessInfosOfTypars g 0 cloFreeTyvars
|> List.collect (fun w ->
(freeInType CollectTyparsNoCaching (GenWitnessTy g w)).FreeTypars
|> Zset.elements)

(cloFreeTyvars @ extra) |> List.distinctBy (fun tp -> tp.Stamp)
else
cloFreeTyvars

let eenvinner = eenv |> EnvForTypars cloFreeTyvars

let ilCloTyInner =
Expand Down
3 changes: 3 additions & 0 deletions src/Compiler/CodeGen/IlxGen.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ type internal IlxGenOptions =

/// When set to true, the IlxGen will delay generation of method bodies and generate them later in parallel (parallelized across files)
parallelIlxGenEnabled: bool

/// Indicates if inline named functions are being inlined or emitted as calls
inlineNamedFunctions: bool
}

/// The results of the ILX compilation of one fragment of an assembly
Expand Down
12 changes: 12 additions & 0 deletions src/Compiler/Driver/CompilerConfig.fs
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,8 @@ type TcConfigBuilder =

mutable strictIndentation: bool option

mutable inlineNamedFunctions: bool option

mutable exename: string option

// If true - the compiler will copy FSharp.Core.dll along the produced binaries
Expand Down Expand Up @@ -853,6 +855,7 @@ type TcConfigBuilder =
dumpSignatureData = false
realsig = false
strictIndentation = None
inlineNamedFunctions = None
compilationMode = TcGlobals.CompilationMode.Unset
}

Expand Down Expand Up @@ -1253,6 +1256,15 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
member _.fsiMultiAssemblyEmit = data.fsiMultiAssemblyEmit
member _.FxResolver = data.FxResolver
member _.strictIndentation = data.strictIndentation

member _.inlineNamedFunctions =
data.inlineNamedFunctions
|> Option.defaultValue (
not data.debuginfo
|| data.optSettings.LocalOptimizationsEnabled
|| data.extraOptimizationIterations > 0
)

member _.primaryAssembly = data.primaryAssembly
member _.noFeedback = data.noFeedback
member _.stackReserveSize = data.stackReserveSize
Expand Down
4 changes: 4 additions & 0 deletions src/Compiler/Driver/CompilerConfig.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,8 @@ type TcConfigBuilder =

mutable strictIndentation: bool option

mutable inlineNamedFunctions: bool option

mutable exename: string option

mutable copyFSharpCore: CopyFSharpCoreFlag
Expand Down Expand Up @@ -814,6 +816,8 @@ type TcConfig =

member strictIndentation: bool option

member inlineNamedFunctions: bool

member GetTargetFrameworkDirectories: unit -> string list

/// Get the loaded sources that exist and issue a warning for the ones that don't
Expand Down
8 changes: 8 additions & 0 deletions src/Compiler/Driver/CompilerOptions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,14 @@ let languageFlags tcConfigB =
None,
Some(FSComp.SR.optsStrictIndentation (formatOptionSwitch (Option.defaultValue false tcConfigB.strictIndentation)))
)

CompilerOption(
"inline-named-functions",
tagNone,
OptionSwitch(fun switch -> tcConfigB.inlineNamedFunctions <- Some(switch = OptionSwitch.On)),
None,
Some(FSComp.SR.optsInlineNamedFunctions ())
)
]

// OptionBlock: Advanced user options
Expand Down
2 changes: 2 additions & 0 deletions src/Compiler/Driver/OptimizeInputs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ let ApplyAllOptimizations
// Only do abstractBigTargets in the first phase, and only when TLR is on.
abstractBigTargets = tcConfig.doTLR
reportingPhase = true
inlineNamedFunctions = tcConfig.inlineNamedFunctions
}

// Only do these two steps in the first phase.
Expand Down Expand Up @@ -578,6 +579,7 @@ let GenerateIlxCode
isInteractiveItExpr = isInteractiveItExpr
alwaysCallVirt = tcConfig.alwaysCallVirt
parallelIlxGenEnabled = tcConfig.parallelIlxGen
inlineNamedFunctions = tcConfig.inlineNamedFunctions
}

ilxGenerator.GenerateCode(ilxGenOpts, optimizedImpls, topAttrs.assemblyAttrs, topAttrs.netModuleAttrs)
Expand Down
1 change: 1 addition & 0 deletions src/Compiler/FSComp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1560,6 +1560,7 @@ optsSetLangVersion,"Specify language version such as 'latest' or 'preview'."
optsDisableLanguageFeature,"Disable a specific language feature by name."
optsSupportedLangVersions,"Supported language versions:"
optsStrictIndentation,"Override indentation rules implied by the language version (%s by default)"
optsInlineNamedFunctions,"Inline named 'inline' functions"
nativeResourceFormatError,"Stream does not begin with a null resource and is not in '.RES' format."
nativeResourceHeaderMalformed,"Resource header beginning at offset %s is malformed."
formatDashItem," - %s"
Expand Down
Loading
Loading