Skip to content

Commit 97c7b9a

Browse files
authored
Parallel project analysis behind a feature flag (#13521)
* Allow parallel project analysis with an environment variable * reformat CompilerImports.fs * Wire in the flag from top-level, add an internal option to the FSC, add a constructor arg to the FSharpChecker. * Fantomas formatting * Update surface baseline * Cleanup * Dummy commit to trigger PR checks * Update surface baseline after merge * Empty commit to trigger PR check rerun * Empty commit to trigger PR check rerun * Restore tests/fsharp/regression/13219/test.fsx
1 parent bdde70d commit 97c7b9a

File tree

13 files changed

+104
-12
lines changed

13 files changed

+104
-12
lines changed

src/Compiler/Driver/CompilerConfig.fs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,11 @@ type MetadataAssemblyGeneration =
388388
| ReferenceOut of outputPath: string
389389
| ReferenceOnly
390390

391+
[<RequireQualifiedAccess>]
392+
type ParallelReferenceResolution =
393+
| On
394+
| Off
395+
391396
[<NoEquality; NoComparison>]
392397
type TcConfigBuilder =
393398
{
@@ -580,6 +585,8 @@ type TcConfigBuilder =
580585
mutable xmlDocInfoLoader: IXmlDocumentationInfoLoader option
581586

582587
mutable exiter: Exiter
588+
589+
mutable parallelReferenceResolution: ParallelReferenceResolution
583590
}
584591

585592
// Directories to start probing in
@@ -767,6 +774,7 @@ type TcConfigBuilder =
767774
sdkDirOverride = sdkDirOverride
768775
xmlDocInfoLoader = None
769776
exiter = QuitProcessExiter
777+
parallelReferenceResolution = ParallelReferenceResolution.Off
770778
}
771779

772780
member tcConfigB.FxResolver =
@@ -1310,6 +1318,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) =
13101318
member _.applyLineDirectives = data.applyLineDirectives
13111319
member _.xmlDocInfoLoader = data.xmlDocInfoLoader
13121320
member _.exiter = data.exiter
1321+
member _.parallelReferenceResolution = data.parallelReferenceResolution
13131322

13141323
static member Create(builder, validate) =
13151324
use _ = UseBuildPhase BuildPhase.Parameter

src/Compiler/Driver/CompilerConfig.fsi

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,11 @@ type MetadataAssemblyGeneration =
198198
/// Only emits the assembly as a reference assembly.
199199
| ReferenceOnly
200200

201+
[<RequireQualifiedAccess>]
202+
type ParallelReferenceResolution =
203+
| On
204+
| Off
205+
201206
[<NoEquality; NoComparison>]
202207
type TcConfigBuilder =
203208
{
@@ -482,6 +487,8 @@ type TcConfigBuilder =
482487
mutable xmlDocInfoLoader: IXmlDocumentationInfoLoader option
483488

484489
mutable exiter: Exiter
490+
491+
mutable parallelReferenceResolution: ParallelReferenceResolution
485492
}
486493

487494
static member CreateNew:
@@ -845,6 +852,8 @@ type TcConfig =
845852

846853
member exiter: Exiter
847854

855+
member parallelReferenceResolution: ParallelReferenceResolution
856+
848857
/// Represents a computation to return a TcConfig. Normally this is just a constant immutable TcConfig,
849858
/// but for F# Interactive it may be based on an underlying mutable TcConfigBuilder.
850859
[<Sealed>]

src/Compiler/Driver/CompilerImports.fs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2141,6 +2141,12 @@ and [<Sealed>] TcImports
21412141
node {
21422142
CheckDisposed()
21432143

2144+
let tcConfig = tcConfigP.Get ctok
2145+
let runMethod =
2146+
match tcConfig.parallelReferenceResolution with
2147+
| ParallelReferenceResolution.On -> NodeCode.Parallel
2148+
| ParallelReferenceResolution.Off -> NodeCode.Sequential
2149+
21442150
let! results =
21452151
nms
21462152
|> List.map (fun nm ->
@@ -2151,7 +2157,7 @@ and [<Sealed>] TcImports
21512157
errorR (Error(FSComp.SR.buildProblemReadingAssembly (nm.resolvedPath, e.Message), nm.originalReference.Range))
21522158
return None
21532159
})
2154-
|> NodeCode.Sequential
2160+
|> runMethod
21552161

21562162
let dllinfos, phase2s = results |> Array.choose id |> List.ofArray |> List.unzip
21572163
fixupOrphanCcus ()

src/Compiler/Driver/CompilerOptions.fs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,6 +1680,14 @@ let internalFlags (tcConfigB: TcConfigBuilder) =
16801680
None
16811681
)
16821682

1683+
CompilerOption(
1684+
"parallelreferenceresolution",
1685+
tagNone,
1686+
OptionUnit(fun () -> tcConfigB.parallelReferenceResolution <- ParallelReferenceResolution.On),
1687+
Some(InternalCommandLineOption("--parallelreferenceresolution", rangeCmdArgs)),
1688+
None
1689+
)
1690+
16831691
testFlag tcConfigB
16841692
]
16851693
@

src/Compiler/Driver/fsc.fs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,18 @@ let TryFindVersionAttribute g attrib attribName attribs deterministic =
446446
[<NoEquality; NoComparison>]
447447
type Args<'T> = Args of 'T
448448

449+
let getParallelReferenceResolutionFromEnvironment () =
450+
Environment.GetEnvironmentVariable("FCS_ParallelReferenceResolution")
451+
|> Option.ofObj
452+
|> Option.bind (fun flag ->
453+
match bool.TryParse flag with
454+
| true, runInParallel ->
455+
if runInParallel then
456+
Some ParallelReferenceResolution.On
457+
else
458+
Some ParallelReferenceResolution.Off
459+
| false, _ -> None)
460+
449461
/// First phase of compilation.
450462
/// - Set up console encoding and code page settings
451463
/// - Process command line, flags and collect filenames
@@ -533,6 +545,11 @@ let main1
533545

534546
tcConfigB.conditionalDefines <- "COMPILED" :: tcConfigB.conditionalDefines
535547

548+
// Override ParallelReferenceResolution set on the CLI with an environment setting if present.
549+
match getParallelReferenceResolutionFromEnvironment () with
550+
| Some parallelReferenceResolution -> tcConfigB.parallelReferenceResolution <- parallelReferenceResolution
551+
| None -> ()
552+
536553
// Display the banner text, if necessary
537554
if not bannerAlreadyPrinted then
538555
Console.Write(GetBannerText tcConfigB)

src/Compiler/Driver/fsc.fsi

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,6 @@ val CompileFromCommandLineArguments:
5555
tcImportsCapture: (TcImports -> unit) option *
5656
dynamicAssemblyCreator: (TcConfig * TcGlobals * string * ILModuleDef -> unit) option ->
5757
unit
58+
59+
/// Read the parallelReferenceResolution flag from environment variables
60+
val internal getParallelReferenceResolutionFromEnvironment: unit -> ParallelReferenceResolution option

src/Compiler/Facilities/BuildGraph.fs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,12 @@ type NodeCode private () =
182182

183183
return results.ToArray()
184184
}
185+
186+
static member Parallel (computations: NodeCode<'T> seq) =
187+
computations
188+
|> Seq.map (fun (Node x) -> x)
189+
|> Async.Parallel
190+
|> Node
185191

186192
type private AgentMessage<'T> = GetValue of AsyncReplyChannel<Result<'T, Exception>> * callerCancellationToken: CancellationToken
187193

@@ -331,7 +337,7 @@ type GraphNode<'T>(retryCompute: bool, computation: NodeCode<'T>) =
331337
// occur, making sure we are under the protection of the 'try'.
332338
// For example, NodeCode's 'try/finally' (TryFinally) uses async.TryFinally which does
333339
// implicit cancellation checks even before the try is entered, as do the
334-
// de-sugaring of 'do!' and other CodeCode constructs.
340+
// de-sugaring of 'do!' and other NodeCode constructs.
335341
let mutable taken = false
336342

337343
try

src/Compiler/Facilities/BuildGraph.fsi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ type NodeCode =
6565

6666
static member Sequential: computations: NodeCode<'T> seq -> NodeCode<'T[]>
6767

68+
static member Parallel: computations: (NodeCode<'T> seq) -> NodeCode<'T[]>
69+
6870
/// Execute the cancellable computation synchronously using the ambient cancellation token of
6971
/// the NodeCode.
7072
static member FromCancellable: computation: Cancellable<'T> -> NodeCode<'T>

src/Compiler/Service/IncrementalBuild.fs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1432,7 +1432,8 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc
14321432
enableBackgroundItemKeyStoreAndSemanticClassification,
14331433
enablePartialTypeChecking: bool,
14341434
enableParallelCheckingWithSignatureFiles: bool,
1435-
dependencyProvider
1435+
dependencyProvider,
1436+
parallelReferenceResolution
14361437
) =
14371438

14381439
let useSimpleResolutionSwitch = "--simpleresolution"
@@ -1514,6 +1515,7 @@ type IncrementalBuilder(initialState: IncrementalBuilderInitialState, state: Inc
15141515
|> Some
15151516

15161517
tcConfigB.parallelCheckingWithSignatureFiles <- enableParallelCheckingWithSignatureFiles
1518+
tcConfigB.parallelReferenceResolution <- parallelReferenceResolution
15171519

15181520
tcConfigB, sourceFilesNew
15191521

src/Compiler/Service/IncrementalBuild.fsi

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,8 @@ type internal IncrementalBuilder =
264264
enableBackgroundItemKeyStoreAndSemanticClassification: bool *
265265
enablePartialTypeChecking: bool *
266266
enableParallelCheckingWithSignatureFiles: bool *
267-
dependencyProvider: DependencyProvider option ->
267+
dependencyProvider: DependencyProvider option *
268+
parallelReferenceResolution: ParallelReferenceResolution ->
268269
NodeCode<IncrementalBuilder option * FSharpDiagnostic[]>
269270

270271
/// Generalized Incremental Builder. This is exposed only for unit testing purposes.

0 commit comments

Comments
 (0)