Skip to content

Commit f68d7b6

Browse files
authored
Don't split resumable code (#17076)
1 parent 89e6411 commit f68d7b6

File tree

3 files changed

+68
-2
lines changed

3 files changed

+68
-2
lines changed

docs/release-notes/.FSharp.Compiler.Service/8.0.400.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@
88
* Files passed with -embed:relative/path/to/file are not embedded. ([Issue #16768](https://github.com/dotnet/fsharp/pull/17068))
99
* Fix bug in optimization of for-loops over integral ranges with steps and units of measure. ([Issue #17025](https://github.com/dotnet/fsharp/issues/17025), [PR #17040](https://github.com/dotnet/fsharp/pull/17040), [PR #17048](https://github.com/dotnet/fsharp/pull/17048))
1010
* Fix calling an overridden virtual static method via the interface ([PR #17013](https://github.com/dotnet/fsharp/pull/17013))
11-
11+
* Fix state machines compilation, when big decision trees are involved, by removing code split when resumable code is detected ([PR #17076](https://github.com/dotnet/fsharp/pull/17076))

src/Compiler/Optimize/Optimizer.fs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2314,7 +2314,7 @@ let IsILMethodRefSystemStringConcatArray (mref: ILMethodRef) =
23142314
ilTy.IsNominal &&
23152315
ilTy.TypeRef.Name = "System.String" -> true
23162316
| _ -> false))
2317-
2317+
23182318
let rec IsDebugPipeRightExpr cenv expr =
23192319
let g = cenv.g
23202320
match expr with
@@ -2329,6 +2329,13 @@ let rec IsDebugPipeRightExpr cenv expr =
23292329
else false
23302330
| _ -> false
23312331

2332+
let inline IsStateMachineExpr g overallExpr =
2333+
//printfn "%s" (DebugPrint.showExpr overallExpr)
2334+
match overallExpr with
2335+
| Expr.App(funcExpr = Expr.Val(valRef = valRef)) ->
2336+
isReturnsResumableCodeTy g valRef.TauType
2337+
| _ -> false
2338+
23322339
/// Optimize/analyze an expression
23332340
let rec OptimizeExpr cenv (env: IncrementalOptimizationEnv) expr =
23342341
cenv.stackGuard.Guard <| fun () ->
@@ -2343,6 +2350,10 @@ let rec OptimizeExpr cenv (env: IncrementalOptimizationEnv) expr =
23432350

23442351
if IsDebugPipeRightExpr cenv expr then OptimizeDebugPipeRights cenv env expr else
23452352

2353+
let isStateMachineE = IsStateMachineExpr g expr
2354+
2355+
let env = { env with disableMethodSplitting = env.disableMethodSplitting || isStateMachineE }
2356+
23462357
match expr with
23472358
// treat the common linear cases to avoid stack overflows, using an explicit continuation
23482359
| LinearOpExpr _

tests/FSharp.Compiler.ComponentTests/Language/StateMachineTests.fs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,61 @@ let compute () =
103103
for i in 1 .. 100 do
104104
compute().Wait ()
105105
"""
106+
|> withOptimize
107+
|> compileExeAndRun
108+
|> shouldSucceed
109+
110+
[<Fact>] // https://github.com/dotnet/fsharp/issues/16068
111+
let ``Decision tree with 32+ binds with nested expression is not getting splitted and state machine is successfully statically compiles``() =
112+
FSharp """
113+
module Testing
114+
115+
let test () =
116+
task {
117+
if true then
118+
let c = failwith ""
119+
let c = failwith ""
120+
let c = failwith ""
121+
let c = failwith ""
122+
let c = failwith ""
123+
let c = failwith ""
124+
let c = failwith ""
125+
let c = failwith ""
126+
let c = failwith ""
127+
let c = failwith ""
128+
let c = failwith ""
129+
let c = failwith ""
130+
let c = failwith ""
131+
let c = failwith ""
132+
let c = failwith ""
133+
let c = failwith ""
134+
let c = failwith ""
135+
let c = failwith ""
136+
let c = failwith ""
137+
let c = failwith ""
138+
let c = failwith ""
139+
let c = failwith ""
140+
let c = failwith ""
141+
let c = failwith ""
142+
let c = failwith ""
143+
let c = failwith ""
144+
let c = failwith ""
145+
let c = failwith ""
146+
let c = failwith ""
147+
let c = failwith ""
148+
let c = failwith ""
149+
let c = failwith ""
150+
let c = failwith ""
151+
()
152+
}
153+
154+
[<EntryPoint>]
155+
let main _ =
156+
test () |> ignore
157+
printfn "Hello, World!"
158+
0
159+
"""
160+
|> ignoreWarnings
106161
|> withOptimize
107162
|> compileExeAndRun
108163
|> shouldSucceed

0 commit comments

Comments
 (0)