Skip to content

Conversation

@dsyme
Copy link
Contributor

@dsyme dsyme commented Nov 18, 2021

#12322 is a related to processing very large expressions recursively, where these expressions are not already recognised as "linear".

Normally when processing F# expressions the depth is small, e.g. 10, though for some known "linear" sequences such as long lists of let bindings, the depth may be arbitrarily large. We already code the compiler to handle these.

However some potentially-linearizable expressions are not detected and it's really hard to detect and handle them properly systematically. Some examples include

  • Very long pipelines A |> A |> A ...
  • Very long computation expressions thing { 1;2;3;4;.. .}
  • Very deep hand-written expressions M(M(M(M(M....)

We can at least guard against this kind of problem by jumping to a new thread stack when non-linear processing of deeply recursive is detected. This isn't ideal but it works.

Overall this protects us against the real problem of #12322 which is that stack depth varies on the six configurations of running our compiler

  • 32-bit .NET Framework fsc.exe
  • 64-bit .NET Framework fscAnyCpu.exe/devenv.exe
  • 64-bit .NET 6 fsc.dll

It does this by making much more of our deep-stack processing independent of actual available stack size.

Testing:

Manual testing notes for the whole matrix (except Windows v. Linux v. macOS)

# Debug compiler, release codegen, no debug 
del test.exe && artifacts\bin\fscAnyCpu\Debug\net472\fscAnyCpu.exe tests/fsharp/regression/12322/test.fsx  && dir test.exe
del test.exe && artifacts\bin\fsc\Debug\net472\fsc.exe tests/fsharp/regression/12322/test.fsx  && dir test.exe
del test.exe && dotnet artifacts\bin\fsc\Debug\net5.0\fsc.dll tests/fsharp/regression/12322/test.fsx  && dir test.exe

# Debug compiler, debug codegen, debug full
del test.exe && artifacts\bin\fscAnyCpu\Debug\net472\fscAnyCpu.exe --optimize- --debug:full --tailcalls- tests/fsharp/regression/12322/test.fsx  && dir test.exe
del test.exe && artifacts\bin\fsc\Debug\net472\fsc.exe --optimize- --debug:full --tailcalls- tests/fsharp/regression/12322/test.fsx  && dir test.exe
del test.exe && dotnet artifacts\bin\fsc\Debug\net5.0\fsc.dll --optimize- --debug:full --tailcalls- tests/fsharp/regression/12322/test.fsx  && dir test.exe

# Debug compiler, debug codegen, debug portable
del test.exe && artifacts\bin\fscAnyCpu\Debug\net472\fscAnyCpu.exe --optimize- --debug:portable --tailcalls- --define:PORTABLE_PDB tests/fsharp/regression/12322/test.fsx  && dir test.exe
del test.exe && artifacts\bin\fsc\Debug\net472\fsc.exe --optimize- --debug:portable --tailcalls- --define:PORTABLE_PDB tests/fsharp/regression/12322/test.fsx  && dir test.exe
del test.exe && dotnet artifacts\bin\fsc\Debug\net5.0\fsc.dll --optimize- --debug:portable --tailcalls- --define:PORTABLE_PDB tests/fsharp/regression/12322/test.fsx  && dir test.exe

# Debug fsi, normal codegen
artifacts\bin\fsi\Debug\net472\fsi.exe tests/fsharp/regression/12322/test.fsx  
artifacts\bin\fsiAnyCpu\Debug\net472\fsiAnyCpu.exe tests/fsharp/regression/12322/test.fsx  
dotnet artifacts\bin\fsi\Debug\net5.0\fsi.dll tests/fsharp/regression/12322/test.fsx  

# Release compiler, release codegen, no debug 
del test.exe && artifacts\bin\fscAnyCpu\Release\net472\fscAnyCpu.exe tests/fsharp/regression/12322/test.fsx  && dir test.exe
del test.exe && artifacts\bin\fsc\Release\net472\fsc.exe tests/fsharp/regression/12322/test.fsx  && dir test.exe
del test.exe && dotnet artifacts\bin\fsc\Release\net5.0\fsc.dll tests/fsharp/regression/12322/test.fsx  && dir test.exe

# Release compiler, debug codegen, debug full
del test.exe && artifacts\bin\fscAnyCpu\Release\net472\fscAnyCpu.exe --optimize- --debug:full --tailcalls- tests/fsharp/regression/12322/test.fsx  && dir test.exe
del test.exe && artifacts\bin\fsc\Release\net472\fsc.exe --optimize- --debug:full --tailcalls- tests/fsharp/regression/12322/test.fsx  && dir test.exe
del test.exe && dotnet artifacts\bin\fsc\Release\net5.0\fsc.dll --optimize- --debug:full --tailcalls- tests/fsharp/regression/12322/test.fsx  && dir test.exe

# Release compiler, debug codegen, debug portable
del test.exe && artifacts\bin\fscAnyCpu\Release\net472\fscAnyCpu.exe --optimize- --debug:portable --tailcalls- --define:PORTABLE_PDB tests/fsharp/regression/12322/test.fsx  && dir test.exe
del test.exe && artifacts\bin\fsc\Release\net472\fsc.exe --optimize- --debug:portable --tailcalls- --define:PORTABLE_PDB tests/fsharp/regression/12322/test.fsx  && dir test.exe
del test.exe && dotnet artifacts\bin\fsc\Release\net5.0\fsc.dll --optimize- --debug:portable --tailcalls- --define:PORTABLE_PDB tests/fsharp/regression/12322/test.fsx  && dir test.exe

# Release fsi, normal codegen
artifacts\bin\fsi\Release\net472\fsi.exe tests/fsharp/regression/12322/test.fsx
artifacts\bin\fsiAnyCpu\Release\net472\fsiAnyCpu.exe tests/fsharp/regression/12322/test.fsx
dotnet artifacts\bin\fsi\Release\net5.0\fsi.dll tests/fsharp/regression/12322/test.fsx

@dsyme dsyme changed the title Enable deep recursive expression processing Fix deep recursive expression processing Nov 18, 2021
@dsyme
Copy link
Contributor Author

dsyme commented Nov 19, 2021

OK, this is ready, subject to being green. There is the automated test matrix in the PR (see tests.fs) and I've been through the same manual steps up above

@dsyme dsyme requested review from TIHan and vzarytovskii and removed request for TIHan November 19, 2021 01:30
@dsyme
Copy link
Contributor Author

dsyme commented Nov 19, 2021

I took the opportunity to cleanup the test configuration matrix used in test\fsharp\tests.fs

@dsyme dsyme changed the title Fix deep recursive expression processing 12322: Fix deep recursive expression processing Nov 20, 2021
@vzarytovskii vzarytovskii merged commit edd4c3b into dotnet:main Nov 23, 2021
@kentcb
Copy link

kentcb commented Jan 6, 2022

Curious that the latest preview (17.1.0 Preview 2) doesn't seem to contain this fix. Is that expected?

@baronfel
Copy link
Member

baronfel commented Jan 7, 2022

@kentcb you'll want to check what version of the SDK is bundled with 17.1.0 Preview 2. I tested this manually with the 6.0.2xx nightly previews (which you can download from the table at the dotnet/installer repo, and the sample code in the linked issue #12322 compiled successfully for me. I don't believe this fix made it into 'servicing' for the 6.0.1xx series of SDKs, but others may have more insight there.

@kentcb
Copy link

kentcb commented Jan 16, 2022

Sorry to ping you @baronfel, but do you know who I should be bugging about this? I believe this to be a fundamental flaw that needs to be patched - I am blocked from using my project on VS22 as a result.

@vzarytovskii
Copy link
Member

It should be in 6.0.200, an probably next dev17 preview. @brettfo do you know if it made it there?

@kentcb
Copy link

kentcb commented Jan 16, 2022

Hmm, I can successfully build my repro project from the CLI with 6.0.200-preview.21617.4, but building from within VS2022 still reproduces the issue. From what I can tell, VS should be using the same SDK as when building from CLI so I'm very confused.

@dsyme
Copy link
Contributor Author

dsyme commented Jan 21, 2022

@kentcb By default VS uses the .NET Framework compiler. There's a way to adjust your project to use the .NET SDK compiler, (@KevinRansom can give the details or search this repo)

@mattiasw2
Copy link

Is this problem solved? I get

MSB6006 "fscAnyCpu.exe" exited with code -1073741571.

with no reference to which file the compilation fails. I am using VS2022 17.1.1

The workaround is to continue to use VS2019. Also, my command line compilations continue to work.

It is a big F# project, used to be Ocaml when created 20 years ago. Some files are very big switch statements or big functions with internal functions.

@mattiasw2
Copy link

Still not working in VS2022 17.3, solved it by adding the folloiwing to the project file for the problematic project. The source is most like a very big "switch" statement

<FSharpPreferNetFrameworkTools>true</FSharpPreferNetFrameworkTools>
<FSharpPrefer64BitTools>false</FSharpPrefer64BitTools>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants