Skip to content

Commit 2167ecd

Browse files
authored
Merge pull request #1321 from dsyme/fix-116
fix 116 - no method splitting in loops
2 parents 29440cf + 57df8c2 commit 2167ecd

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

src/fsharp/Optimizer.fs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,9 @@ type IncrementalOptimizationEnv =
330330
// Recursively bound vars. If an sub-expression that is a candidate for method splitting
331331
// contains any of these variables then don't split it, for fear of mucking up tailcalls.
332332
// See FSharp 1.0 bug 2892
333-
dontSplitVars: ValMap<unit>
333+
dontSplitVars: ValMap<unit>
334+
// Disable method splitting in loops
335+
inLoop: bool
334336
/// The Val for the function binding being generated, if any.
335337
functionVal: (Val * Tast.ValReprInfo) option
336338
typarInfos: (Typar * TypeValueInfo) list
@@ -343,6 +345,7 @@ type IncrementalOptimizationEnv =
343345
typarInfos = []
344346
functionVal = None
345347
dontSplitVars = ValMap.Empty
348+
inLoop = false
346349
localExternalVals = LayeredMap.Empty
347350
globalModuleInfos = LayeredMap.Empty }
348351

@@ -1825,8 +1828,8 @@ and OptimizeExprOp cenv env (op,tyargs,args,m) =
18251828
MightMakeCriticalTailcall = false
18261829
Info = UnknownValue }
18271830
(* Handle these as special cases since mutables are allowed inside their bodies *)
1828-
| TOp.While (spWhile,marker),_,[Expr.Lambda(_,_,_,[_],e1,_,_);Expr.Lambda(_,_,_,[_],e2,_,_)] -> OptimizeWhileLoop cenv env (spWhile,marker,e1,e2,m)
1829-
| TOp.For(spStart,dir),_,[Expr.Lambda(_,_,_,[_],e1,_,_);Expr.Lambda(_,_,_,[_],e2,_,_);Expr.Lambda(_,_,_,[v],e3,_,_)] -> OptimizeFastIntegerForLoop cenv env (spStart,v,e1,dir,e2,e3,m)
1831+
| TOp.While (spWhile,marker),_,[Expr.Lambda(_,_,_,[_],e1,_,_);Expr.Lambda(_,_,_,[_],e2,_,_)] -> OptimizeWhileLoop cenv { env with inLoop=true } (spWhile,marker,e1,e2,m)
1832+
| TOp.For(spStart,dir),_,[Expr.Lambda(_,_,_,[_],e1,_,_);Expr.Lambda(_,_,_,[_],e2,_,_);Expr.Lambda(_,_,_,[v],e3,_,_)] -> OptimizeFastIntegerForLoop cenv { env with inLoop=true } (spStart,v,e1,dir,e2,e3,m)
18301833
| TOp.TryFinally(spTry,spFinally),[resty],[Expr.Lambda(_,_,_,[_],e1,_,_); Expr.Lambda(_,_,_,[_],e2,_,_)] -> OptimizeTryFinally cenv env (spTry,spFinally,e1,e2,m,resty)
18311834
| TOp.TryCatch(spTry,spWith),[resty],[Expr.Lambda(_,_,_,[_],e1,_,_); Expr.Lambda(_,_,_,[vf],ef,_,_); Expr.Lambda(_,_,_,[vh],eh,_,_)] -> OptimizeTryCatch cenv env (e1,vf,ef,vh,eh,m,resty,spTry,spWith)
18321835
| TOp.TraitCall(traitInfo),[],args -> OptimizeTraitCall cenv env (traitInfo, args, m)
@@ -2770,6 +2773,7 @@ and ComputeSplitToMethodCondition flag threshold cenv env (e,einfo) =
27702773
// REVIEW: This should only apply to methods that actually make self-tailcalls (tested further below).
27712774
// Old comment "don't mess with taking guaranteed tailcalls if used with --no-tailcalls!"
27722775
cenv.emitTailcalls &&
2776+
not env.inLoop &&
27732777
einfo.FunctionSize >= threshold &&
27742778

27752779
// We can only split an expression out as a method if certain conditions are met.

0 commit comments

Comments
 (0)