@@ -467,18 +467,20 @@ let rec BindValsInModuleOrNamespace cenv (mval:LazyModuleInfo) env =
467467 let env = ( env, mval.ValInfos.Entries) ||> Seq.fold ( fun env ( v : ValRef , vval ) -> BindExternalLocalVal cenv v.Deref vval env)
468468 env
469469
470- let BindInternalValToUnknown cenv v env =
470+ let inline BindInternalValToUnknown cenv v env =
471471#if CHECKED
472472 BindInternalLocalVal cenv v UnknownValue env
473473#else
474- ignore ( cenv, v)
474+ ignore cenv
475+ ignore v
475476 env
476477#endif
477- let BindInternalValsToUnknown cenv vs env =
478+ let inline BindInternalValsToUnknown cenv vs env =
478479#if CHECKED
479480 List.foldBack ( BindInternalValToUnknown cenv) vs env
480481#else
481- ignore ( cenv, vs)
482+ ignore cenv
483+ ignore vs
482484 env
483485#endif
484486
@@ -568,9 +570,11 @@ let GetInfoForNonLocalVal cenv env (vref:ValRef) =
568570
569571let GetInfoForVal cenv env m ( vref : ValRef ) =
570572 let res =
571- match vref.IsLocalRef with
572- | true -> GetInfoForLocalValue cenv env vref.binding m
573- | false -> GetInfoForNonLocalVal cenv env vref
573+ if vref.IsLocalRef then
574+ GetInfoForLocalValue cenv env vref.binding m
575+ else
576+ GetInfoForNonLocalVal cenv env vref
577+
574578 check (* "its stored value was incomplete" m *) vref res |> ignore
575579 res
576580
@@ -2032,16 +2036,15 @@ and OptimizeFastIntegerForLoop cenv env (spStart,v,e1,dir,e2,e3,m) =
20322036//-------------------------------------------------------------------------
20332037
20342038and OptimizeLetRec cenv env ( binds , bodyExpr , m ) =
2035- let vs = binds |> FlatList.map ( fun v -> v.Var) in
2039+ let vs = binds |> FlatList.map ( fun v -> v.Var)
20362040 let env = BindInternalValsToUnknown cenv vs env
20372041 let binds ' , env = OptimizeBindings cenv true env binds
20382042 let bodyExpr ' , einfo = OptimizeExpr cenv env bodyExpr
20392043 // REVIEW: graph analysis to determine which items are unused
20402044 // Eliminate any unused bindings, as in let case
20412045 let binds '' , bindinfos =
20422046 let fvs0 = freeInExpr CollectLocals bodyExpr'
2043- let fvsN = FlatList.map ( fst >> freeInBindingRhs CollectLocals) binds'
2044- let fvs = FlatList.fold unionFreeVars fvs0 fvsN
2047+ let fvs = FlatList.fold ( fun acc x -> unionFreeVars acc ( fst x |> freeInBindingRhs CollectLocals)) fvs0 binds'
20452048 SplitValuesByIsUsedOrHasEffect cenv ( fun () -> fvs.FreeLocals) binds'
20462049 // Trim out any optimization info that involves escaping values
20472050 let evalue ' = AbstractExprInfoByVars ( FlatList.toList vs,[]) einfo.Info
@@ -2206,7 +2209,7 @@ and TryOptimizeVal cenv env (mustInline,valInfoForVal,m) =
22062209 | SizeValue (_, detail) -> TryOptimizeVal cenv env ( mustInline, detail, m)
22072210 | ValValue ( v', detail) ->
22082211 // Inline values bound to other values immediately
2209- match TryOptimizeVal cenv env ( mustInline, detail, m) with
2212+ match TryOptimizeVal cenv env ( mustInline, detail, m) with
22102213 // Prefer to inline using the more specific info if possible
22112214 | Some e -> Some e
22122215 //If the more specific info didn't reveal an inline then use the value
@@ -2300,9 +2303,9 @@ and TakeAddressOfStructArgumentIfNeeded cenv (vref:ValRef) ty args m =
23002303 wrap, ( objArgAddress:: rest)
23012304 | _ ->
23022305 // no wrapper, args stay the same
2303- ( fun x -> x ) , args
2306+ id , args
23042307 else
2305- ( fun x -> x ) , args
2308+ id , args
23062309
23072310and DevirtualizeApplication cenv env ( vref : ValRef ) ty tyargs args m =
23082311 let wrap , args = TakeAddressOfStructArgumentIfNeeded cenv vref ty args m
@@ -2579,50 +2582,51 @@ and TryInlineApplication cenv env (_f0',finfo) (tyargs: TType list,args: Expr li
25792582//-------------------------------------------------------------------------
25802583
25812584and OptimizeApplication cenv env ( f0 , f0ty , tyargs , args , m ) =
2582- let f0 ' , finfo = OptimizeExpr cenv env f0
25832585 // trying to devirtualize
25842586 match TryDevirtualizeApplication cenv env ( f0, tyargs, args, m) with
25852587 | Some res ->
25862588 // devirtualized
25872589 res
25882590 | None ->
2589-
2590- match TryInlineApplication cenv env ( f0' , finfo) ( tyargs, args, m) with
2591+ let newf0 , finfo = OptimizeExpr cenv env f0
2592+ match TryInlineApplication cenv env ( newf0 , finfo) ( tyargs, args, m) with
25912593 | Some res ->
25922594 // inlined
25932595 res
25942596 | None ->
25952597
25962598 let shapes =
2597- match f0' with
2598- | Expr.Val( vref,_,_) when Option.isSome vref.ValReprInfo ->
2599- let ( ValReprInfo ( _kinds , detupArgsL , _ )) = Option.get vref.ValReprInfo
2600- let nargs = ( args.Length)
2601- let nDetupArgsL = detupArgsL.Length
2602- let nShapes = min nargs nDetupArgsL
2603- let detupArgsShapesL =
2604- List.take nShapes detupArgsL |> List.map ( fun detupArgs ->
2605- match detupArgs with
2606- | [] | [_] -> UnknownValue
2607- | _ -> TupleValue( Array.ofList ( List.map ( fun _ -> UnknownValue) detupArgs)))
2608- detupArgsShapesL @ List.replicate ( nargs - nShapes) UnknownValue
2609-
2610- | _ -> args |> List.map ( fun _ -> UnknownValue)
2611-
2612- let args ' , arginfos = OptimizeExprsThenReshapeAndConsiderSplits cenv env ( List.zip shapes args)
2599+ match newf0 with
2600+ | Expr.Val( vref,_,_) ->
2601+ match vref.ValReprInfo with
2602+ | Some( ValReprInfo(_, detupArgsL,_)) ->
2603+ let nargs = args.Length
2604+ let nDetupArgsL = detupArgsL.Length
2605+ let nShapes = min nargs nDetupArgsL
2606+ let detupArgsShapesL =
2607+ List.take nShapes detupArgsL
2608+ |> List.map ( fun detupArgs ->
2609+ match detupArgs with
2610+ | [] | [_] -> UnknownValue
2611+ | _ -> TupleValue( Array.ofList ( List.map ( fun _ -> UnknownValue) detupArgs)))
2612+ List.zip ( detupArgsShapesL @ List.replicate ( nargs - nShapes) UnknownValue) args
2613+ | _ -> args |> List.map ( fun arg -> UnknownValue, arg)
2614+ | _ -> args |> List.map ( fun arg -> UnknownValue, arg)
2615+
2616+ let newArgs , arginfos = OptimizeExprsThenReshapeAndConsiderSplits cenv env shapes
26132617 // beta reducing
2614- let expr ' = MakeApplicationAndBetaReduce cenv.g ( f0' , f0ty, [ tyargs], args' , m)
2618+ let newExpr = MakeApplicationAndBetaReduce cenv.g ( newf0 , f0ty, [ tyargs], newArgs , m)
26152619
2616- match f0' , expr' with
2620+ match newf0 , newExpr with
26172621 | ( Expr.Lambda _ | Expr.TyLambda _), Expr.Let _ ->
26182622 // we beta-reduced, hence reoptimize
2619- OptimizeExpr cenv env expr'
2623+ OptimizeExpr cenv env newExpr
26202624 | _ ->
26212625 // regular
26222626
26232627 // Determine if this application is a critical tailcall
26242628 let mayBeCriticalTailcall =
2625- match f0' with
2629+ match newf0 with
26262630 | KnownValApp( vref,_ typeArgs, otherArgs) ->
26272631
26282632 // Check if this is a call to a function of known arity that has been inferred to not be a critical tailcall when used as a direct call
@@ -2633,25 +2637,25 @@ and OptimizeApplication cenv env (f0,f0ty,tyargs,args,m) =
26332637 ( let valInfoForVal = GetInfoForVal cenv env m vref in valInfoForVal.ValMakesNoCriticalTailcalls) ||
26342638 ( match env.functionVal with | None -> false | Some ( v,_) -> valEq vref.Deref v)
26352639 if doesNotMakeCriticalTailcall then
2636- let numArgs = otherArgs.Length + args' .Length
2640+ let numArgs = otherArgs.Length + newArgs .Length
26372641 match vref.ValReprInfo with
26382642 | Some i -> numArgs > i.NumCurriedArgs
26392643 | None ->
26402644 match env.functionVal with
26412645 | Some (_ v, i) -> numArgs > i.NumCurriedArgs
2642- | None -> true // over-applicaiton of a known function, which presumably returns a function. This counts as an indirect call
2646+ | None -> true // over-application of a known function, which presumably returns a function. This counts as an indirect call
26432647 else
26442648 true // application of a function that may make a critical tailcall
26452649
26462650 | _ ->
26472651 // All indirect calls (calls to unknown functions) are assumed to be critical tailcalls
26482652 true
26492653
2650- expr' , { TotalSize= finfo.TotalSize + AddTotalSizes arginfos
2651- FunctionSize= finfo.FunctionSize + AddFunctionSizes arginfos
2652- HasEffect= true
2653- MightMakeCriticalTailcall = mayBeCriticalTailcall
2654- Info= ValueOfExpr expr' }
2654+ newExpr , { TotalSize= finfo.TotalSize + AddTotalSizes arginfos
2655+ FunctionSize= finfo.FunctionSize + AddFunctionSizes arginfos
2656+ HasEffect= true
2657+ MightMakeCriticalTailcall = mayBeCriticalTailcall
2658+ Info= ValueOfExpr newExpr }
26552659
26562660//-------------------------------------------------------------------------
26572661// Optimize/analyze a lambda expression
@@ -2661,7 +2665,6 @@ and OptimizeLambdas (vspec: Val option) cenv env topValInfo e ety =
26612665 match e with
26622666 | Expr.Lambda ( lambdaId,_,_,_,_, m,_)
26632667 | Expr.TyLambda( lambdaId,_,_, m,_) ->
2664- let isTopLevel = Option.isSome vspec && vspec.Value.IsCompiledAsTopLevel
26652668 let tps , ctorThisValOpt , baseValOpt , vsl , body , bodyty = IteratedAdjustArityOfLambda cenv.g cenv.amap topValInfo e
26662669 let env = { env with functionVal = ( match vspec with None -> None | Some v -> Some ( v, topValInfo)) }
26672670 let env = Option.foldBack ( BindInternalValToUnknown cenv) ctorThisValOpt env
@@ -2709,13 +2712,18 @@ and OptimizeLambdas (vspec: Val option) cenv env topValInfo e ety =
27092712 | Some baseVal ->
27102713 let fvs = freeInExpr CollectLocals body'
27112714 if fvs.UsesMethodLocalConstructs || fvs.FreeLocals.Contains baseVal then
2712- UnknownValue
2715+ UnknownValue
27132716 else
27142717 let expr2 = mkMemberLambdas m tps ctorThisValOpt None vsl ( body', bodyty)
27152718 CurriedLambdaValue ( lambdaId, arities, bsize, expr2, ety)
27162719
27172720
2718- expr', { TotalSize= bsize + ( if isTopLevel then methodDefnTotalSize else closureTotalSize) (* estimate size of new syntactic closure - expensive, in contrast to a method *)
2721+ let estimatedSize =
2722+ match vspec with
2723+ | Some v when v.IsCompiledAsTopLevel -> methodDefnTotalSize
2724+ | _ -> closureTotalSize
2725+
2726+ expr', { TotalSize= bsize + estimatedSize (* estimate size of new syntactic closure - expensive, in contrast to a method *)
27192727 FunctionSize= 1
27202728 HasEffect= false
27212729 MightMakeCriticalTailcall = false
@@ -2739,9 +2747,10 @@ and OptimizeExprsThenConsiderSplits cenv env exprs =
27392747 | [] -> NoExprs
27402748 | _ -> OptimizeList ( OptimizeExprThenConsiderSplit cenv env) exprs
27412749
2742- and OptimizeFlatExprsThenConsiderSplits cenv env ( exprs : FlatExprs ) =
2743- if FlatList.isEmpty exprs then NoFlatExprs
2744- else OptimizeFlatList ( OptimizeExprThenConsiderSplit cenv env) exprs
2750+ and OptimizeFlatExprsThenConsiderSplits cenv env exprs =
2751+ match exprs with
2752+ | [] -> NoFlatExprs
2753+ | _ -> OptimizeFlatList ( OptimizeExprThenConsiderSplit cenv env) exprs
27452754
27462755and OptimizeExprThenReshapeAndConsiderSplit cenv env ( shape , e ) =
27472756 OptimizeExprThenConsiderSplit cenv env ( ReshapeExpr cenv ( shape, e))
@@ -2753,7 +2762,8 @@ and ReshapeExpr cenv (shape,e) =
27532762 match shape, e with
27542763 | TupleValue( subshapes), Expr.Val(_ vref,_ vFlags, m) ->
27552764 let tinst = destRefTupleTy cenv.g ( tyOfExpr cenv.g e)
2756- mkRefTupled cenv.g m ( List.mapi ( fun i subshape -> ReshapeExpr cenv ( subshape, mkTupleFieldGet cenv.g ( tupInfoRef, e, tinst, i, m))) ( Array.toList subshapes)) tinst
2765+ let subshapes = Array.toList subshapes
2766+ mkRefTupled cenv.g m ( List.mapi ( fun i subshape -> ReshapeExpr cenv ( subshape, mkTupleFieldGet cenv.g ( tupInfoRef, e, tinst, i, m))) subshapes) tinst
27572767 | _ ->
27582768 e
27592769
@@ -2868,8 +2878,7 @@ and OptimizeDecisionTree cenv env m x =
28682878 let info = CombineValueInfosUnknown [ rinfo; binfo]
28692879 // try to fold the let-binding into a single result expression
28702880 match rest with
2871- | TDSuccess( es, n) when es.Length = 1 ->
2872- let e = es.[ 0 ]
2881+ | TDSuccess([ e], n) ->
28732882 let e , _adjust = TryEliminateLet cenv env bind e m
28742883 TDSuccess( FlatList.one e, n), info
28752884 | _ ->
@@ -3072,7 +3081,7 @@ and OptimizeModuleExpr cenv env x =
30723081 new ModuleOrNamespaceType( kind= mtyp.ModuleOrNamespaceKind,
30733082 vals= ( mtyp.AllValsAndMembers |> QueueList.filter ( Zset.memberOf deadSet >> not )),
30743083 entities= mtyp.AllEntities)
3075- mtyp.ModuleAndNamespaceDefinitions |> List.iter ( fun mspec -> elimModSpec mspec )
3084+ mtyp.ModuleAndNamespaceDefinitions |> List.iter elimModSpec
30763085 mty
30773086 and elimModSpec ( mspec : ModuleOrNamespace ) =
30783087 let mtyp = elimModTy mspec.ModuleOrNamespaceType
@@ -3116,13 +3125,12 @@ and OptimizeModuleDef cenv (env,bindInfosColl) x =
31163125 let binds = minfos |> List.choose ( function Choice1Of2 ( x,_) -> Some x | _ -> None)
31173126 let binfos = minfos |> List.choose ( function Choice1Of2 (_, x) -> Some x | _ -> None)
31183127 let minfos = minfos |> List.choose ( function Choice2Of2 x -> Some x | _ -> None)
3119-
31203128
3121- (* REVIEW: Eliminate let bindings on the way back up *)
3129+ (* REVIEW: Eliminate let bindings on the way back up *)
31223130 ( TMDefRec( isRec, tycons, mbinds, m),
3123- notlazy { ValInfos= ValInfos( FlatList.map2 ( fun bind binfo -> mkValBind bind ( mkValInfo binfo bind.Var)) binds binfos)
3131+ notlazy { ValInfos = ValInfos( FlatList.map2 ( fun bind binfo -> mkValBind bind ( mkValInfo binfo bind.Var)) binds binfos)
31243132 ModuleOrNamespaceInfos = NameMap.ofList minfos}),
3125- ( env, bindInfosColl)
3133+ ( env, bindInfosColl)
31263134 | TMAbstract( mexpr) ->
31273135 let mexpr , info = OptimizeModuleExpr cenv env mexpr
31283136 let env = BindValsInModuleOrNamespace cenv info env
@@ -3132,7 +3140,7 @@ and OptimizeModuleDef cenv (env,bindInfosColl) x =
31323140 (* REVIEW: Eliminate unused let bindings from modules *)
31333141 ( TMDefLet( bind', m),
31343142 notlazy { ValInfos= ValInfos [ mkValBind bind ( mkValInfo binfo bind.Var)]
3135- ModuleOrNamespaceInfos = NameMap.ofList [] }),
3143+ ModuleOrNamespaceInfos = NameMap.empty }),
31363144 ( env ,([ bindInfo]:: bindInfosColl))
31373145
31383146 | TMDefDo( e, m) ->
0 commit comments