Skip to content
Closed
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
10 changes: 5 additions & 5 deletions azure-pipelines-PR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ stages:
helixRepo: dotnet/fsharp
jobs:
# Determinism, we want to run it only in PR builds
- job: Determinism_Debug
- job: Determinism_Release
condition: eq(variables['Build.Reason'], 'PullRequest')
variables:
- name: _SignType
Expand Down Expand Up @@ -129,15 +129,15 @@ stages:
workingDirectory: $(Build.SourcesDirectory)
installationPath: $(Build.SourcesDirectory)/.dotnet
- script: .\eng\common\dotnet.cmd
- script: .\eng\test-determinism.cmd -configuration Debug
- script: .\eng\test-determinism.cmd -configuration Release
env:
FSHARP_EXPERIMENTAL_FEATURES: $(_experimental_flag)
displayName: Determinism tests with Debug configuration
displayName: Determinism tests with Release configuration
- task: PublishPipelineArtifact@1
displayName: Publish Determinism Logs
inputs:
targetPath: '$(Build.SourcesDirectory)/artifacts/log/Debug'
artifactName: 'Determinism_Debug Attempt $(System.JobAttempt) Logs'
targetPath: '$(Build.SourcesDirectory)/artifacts/log/Release'
artifactName: 'Determinism_Release Attempt $(System.JobAttempt) Logs'
continueOnError: true
condition: not(succeeded())

Expand Down
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
@@ -1,5 +1,6 @@
### Fixed

* Improve determinism under parallel optimization: `Optimize/DetupleArgs` and `Optimize/InnerLambdasToTopLevelFuncs` now walk their `Val` sets in stable source-position order before calling into `NiceNameGenerator`, so compiler-generated names no longer vary across builds due to `Val.Stamp` assignment races during parallel type-check. ([Issue #19732](https://github.com/dotnet/fsharp/issues/19732), [PR #19810](https://github.com/dotnet/fsharp/pull/19810))
* Honor `--nowarn` and `--warnaserror` for warnings emitted during command-line option parsing ([Issue #19576](https://github.com/dotnet/fsharp/issues/19576), [PR #19776](https://github.com/dotnet/fsharp/pull/19776))
* Fix `[<return: X>]` prefix attributes being silently dropped on class members, and fix false-positive `AllowMultiple=false` errors when `[<X>]` and `[<return: X>]` are applied to the same binding. ([Issue #17904](https://github.com/dotnet/fsharp/issues/17904), [Issue #19020](https://github.com/dotnet/fsharp/issues/19020), [PR #19738](https://github.com/dotnet/fsharp/pull/19738))
* Fix attributes on return type of unparenthesized tuple methods being silently dropped from IL. ([Issue #462](https://github.com/dotnet/fsharp/issues/462), [PR #19714](https://github.com/dotnet/fsharp/pull/19714))
Expand Down
6 changes: 5 additions & 1 deletion src/Compiler/Driver/OptimizeInputs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -511,8 +511,12 @@ let ApplyAllOptimizations

let results, optEnvFirstLoop =
match tcConfig.optSettings.processingMode with
// Parallel optimization breaks determinism - turn it off in deterministic builds.
| Optimizer.OptimizationProcessingMode.Parallel ->
// Determinism under Parallel mode relies on the per-pass sorts in
// DetupleArgs.determineTransforms and InnerLambdasToTopLevelFuncs.CreateNewValuesForTLR
// (via valSourceOrderKey). Any new pass calling NiceNameGenerator from a
// parallel optimizer phase must sort its Val collection the same way.
// See https://github.com/dotnet/fsharp/issues/19732.
let results, optEnvFirstPhase =
ParallelOptimization.optimizeFilesInParallel optEnv phases implFiles

Expand Down
3 changes: 2 additions & 1 deletion src/Compiler/Optimize/DetupleArgs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,8 @@ let determineTransforms g (z: Results) =
let callPatterns = sitesCPs sites // callPatterns from sites
decideTransform g z f callPatterns (m, tps, vss, retTy) // make transform (if required)

let vtransforms = Zmap.chooseL selectTransform z.Uses
let vtransforms =
Zmap.chooseL selectTransform z.Uses
let vtransforms = Zmap.ofList valOrder vtransforms
vtransforms

Expand Down
9 changes: 9 additions & 0 deletions src/Compiler/TypedTree/TypedTreeOps.ExprConstruction.fs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ module internal ExprConstruction =
member _.Compare(v1, v2) = compareBy v1 v2 _.Stamp
}

// Source-position-derived order key for Vals. Used to walk Val collections
// in a stable, build-independent order before calling NiceNameGenerator
// from parallel optimizer passes. Stamp is the final tiebreaker for
// synthetic Vals at the same location; stamps are fixed within a single
// process so the order is total. See https://github.com/dotnet/fsharp/issues/19732.
let valSourceOrderKey (v: Val) =
let r = v.Range
struct (r.FileIndex, r.StartLine, r.StartColumn, v.LogicalName, v.Stamp)

let tyconOrder =
{ new IComparer<Tycon> with
member _.Compare(tycon1, tycon2) = compareBy tycon1 tycon2 _.Stamp
Expand Down
6 changes: 6 additions & 0 deletions src/Compiler/TypedTree/TypedTreeOps.ExprConstruction.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ module internal ExprConstruction =
/// An ordering for value definitions, based on stamp
val valOrder: IComparer<Val>

/// Stable, source-position-derived key for ordering Vals.
/// Use this before calling NiceNameGenerator from parallel optimizer passes
/// so the generated names do not depend on Val.Stamp assignment race.
/// See https://github.com/dotnet/fsharp/issues/19732.
val valSourceOrderKey: Val -> struct (int * int * int * string * int64)

/// An ordering for type definitions, based on stamp
val tyconOrder: IComparer<Tycon>

Expand Down
Loading