Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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)
11 changes: 9 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
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
4 changes: 4 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,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
member _.fsiMultiAssemblyEmit = data.fsiMultiAssemblyEmit
member _.FxResolver = data.FxResolver
member _.strictIndentation = data.strictIndentation
member _.inlineNamedFunctions = data.inlineNamedFunctions
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 option

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
7 changes: 7 additions & 0 deletions src/Compiler/Driver/OptimizeInputs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -327,13 +327,17 @@ let ApplyAllOptimizations
// Only do abstractBigTargets in the first phase, and only when TLR is on.
abstractBigTargets = tcConfig.doTLR
reportingPhase = true
inlineNamedFunctions =
tcConfig.inlineNamedFunctions
|> Option.defaultValue (not tcConfig.debuginfo || tcConfig.optSettings.LocalOptimizationsEnabled)
}

// Only do these two steps in the first phase.
let extraAndFinalLoopSettings =
{ firstLoopSettings with
abstractBigTargets = false
reportingPhase = false
inlineNamedFunctions = false
}

let addPhaseDiagnostics (f: PhaseFunc) (info: Phase) =
Expand Down Expand Up @@ -578,6 +582,9 @@ let GenerateIlxCode
isInteractiveItExpr = isInteractiveItExpr
alwaysCallVirt = tcConfig.alwaysCallVirt
parallelIlxGenEnabled = tcConfig.parallelIlxGen
inlineNamedFunctions =
tcConfig.inlineNamedFunctions
|> Option.defaultValue (not tcConfig.debuginfo || tcConfig.optSettings.LocalOptimizationsEnabled)
}

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