Skip to content

Commit bb07495

Browse files
authored
Merge pull request #3 from fable-compiler/resizelist
[WIP] More optimization attempts
2 parents 2877fcd + 0e12796 commit bb07495

File tree

5 files changed

+313
-170
lines changed

5 files changed

+313
-170
lines changed

build.fsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,21 @@ let buildLibrary() =
106106

107107
let watchLibrary() =
108108
let libDir = "src/fable-library"
109+
let buildDir = fullPath "build/fable-library"
109110
printfn "Watching %s..." libDir
110111
chokidar
111112
.watch(libDir)
112113
.on("change", fun _ -> buildLibrary())
113114
|> ignore
114115

116+
// runFableWithArgs ("watch " + libDir) [
117+
// "--outDir " + buildDir
118+
// "--fableLib " + buildDir
119+
// "--exclude Fable.Core"
120+
// "--define FX_NO_BIGINT"
121+
// "--define FABLE_LIBRARY"
122+
// ]
123+
115124
let buildLibraryTs() =
116125
let projectDir = "src/fable-library"
117126
let buildDirTs = "build/fable-library-ts"
@@ -160,6 +169,7 @@ let testJsFast() =
160169
]
161170

162171
runFableWithArgs "src/fable-compiler-js/src" [
172+
"--forcePkgs"
163173
"--exclude Fable.Core"
164174
"--define LOCAL_TEST"
165175
]

src/Fable.Transforms/Fable2Babel.fs

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -835,9 +835,7 @@ module Util =
835835
let rec checkCrossRefs tempVars allArgs = function
836836
| [] -> tempVars
837837
| (argId, _arg)::rest ->
838-
let found = allArgs |> List.exists (FableTransforms.deepExists (function
839-
| Fable.IdentExpr i -> argId = i.Name
840-
| _ -> false))
838+
let found = allArgs |> List.exists (FableTransforms.isIdentUsed argId)
841839
let tempVars =
842840
if found then
843841
let tempVarName = getUniqueNameInDeclarationScope ctx (argId + "_tmp")
@@ -907,36 +905,24 @@ module Util =
907905
// | Fable.NewList (headAndTail, _) when List.contains "FABLE_LIBRARY" com.Options.Define ->
908906
// makeList com ctx r headAndTail
909907
// Optimization for bundle size: compile list literals as List.ofArray
910-
| Replacements.ListLiteral(exprs, t) ->
911-
[|List.rev exprs |> makeArray com ctx|]
912-
|> libCall com ctx r "List" "newList"
913-
// match exprs with
914-
// | [] -> libCall com ctx r "List" "empty" [||]
915-
// | [TransformExpr com ctx expr] -> libCall com ctx r "List" "singleton" [|expr|]
916-
// | exprs -> [|makeArray com ctx exprs|] |> libCall com ctx r "List" "ofArray"
917908
| Fable.NewList (headAndTail, _) ->
918-
match headAndTail with
919-
| None -> libCall com ctx r "List" "empty" [||]
920-
| Some(TransformExpr com ctx head, TransformExpr com ctx tail) ->
909+
let rec getItems acc = function
910+
| None -> List.rev acc, None
911+
| Some(head, Fable.Value(Fable.NewList(tail, _),_)) -> getItems (head::acc) tail
912+
| Some(head, tail) -> List.rev (head::acc), Some tail
913+
match getItems [] headAndTail with
914+
| [], None ->
915+
libCall com ctx r "List" "empty" [||]
916+
| [TransformExpr com ctx expr], None ->
917+
libCall com ctx r "List" "singleton" [|expr|]
918+
| exprs, None ->
919+
[|List.rev exprs |> makeArray com ctx|]
920+
|> libCall com ctx r "List" "newList"
921+
| [TransformExpr com ctx head], Some(TransformExpr com ctx tail) ->
921922
libCall com ctx r "List" "cons" [|head; tail|]
922-
923-
// let rec getItems acc = function
924-
// | None -> List.rev acc, None
925-
// | Some(head, Fable.Value(Fable.NewList(tail, _),_)) -> getItems (head::acc) tail
926-
// | Some(head, tail) -> List.rev (head::acc), Some tail
927-
// match getItems [] headAndTail with
928-
// | [], None ->
929-
// libCall com ctx r "List" "empty" [||]
930-
// | [TransformExpr com ctx expr], None ->
931-
// libCall com ctx r "List" "singleton" [|expr|]
932-
// | exprs, None ->
933-
// [|makeArray com ctx exprs|]
934-
// |> libCall com ctx r "List" "ofArray"
935-
// | [TransformExpr com ctx head], Some(TransformExpr com ctx tail) ->
936-
// libCall com ctx r "List" "cons" [|head; tail|]
937-
// | exprs, Some(TransformExpr com ctx tail) ->
938-
// [|makeArray com ctx exprs; tail|]
939-
// |> libCall com ctx r "List" "ofArrayWithTail"
923+
| exprs, Some(TransformExpr com ctx tail) ->
924+
[|List.rev exprs |> makeArray com ctx; tail|]
925+
|> libCall com ctx r "List" "newListWithTail"
940926
| Fable.NewOption (value, t) ->
941927
match value with
942928
| Some (TransformExpr com ctx e) ->
@@ -1191,11 +1177,11 @@ module Util =
11911177

11921178
| Fable.ListHead ->
11931179
// get range (com.TransformAsExpr(ctx, fableExpr)) "head"
1194-
libCall com ctx range "List" "head" [|com.TransformAsExpr(ctx, fableExpr)|]
1180+
libCall com ctx range "List" "head_" [|com.TransformAsExpr(ctx, fableExpr)|]
11951181

11961182
| Fable.ListTail ->
11971183
// get range (com.TransformAsExpr(ctx, fableExpr)) "tail"
1198-
libCall com ctx range "List" "tail" [|com.TransformAsExpr(ctx, fableExpr)|]
1184+
libCall com ctx range "List" "tail_" [|com.TransformAsExpr(ctx, fableExpr)|]
11991185

12001186
| Fable.TupleIndex index ->
12011187
match fableExpr with

src/Fable.Transforms/FableTransforms.fs

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -149,23 +149,31 @@ let getSubExpressions = function
149149
| DecisionTree(expr, targets) -> expr::(List.map snd targets)
150150
| DecisionTreeSuccess(_, boundValues, _) -> boundValues
151151

152-
let deepExists (f: Expr -> bool) expr =
153-
let rec deepExistsInner (exprs: ResizeArray<Expr>) =
154-
let mutable found = false
155-
let subExprs = ResizeArray()
156-
for e in exprs do
157-
if not found then
158-
subExprs.AddRange(getSubExpressions e)
159-
found <- f e
160-
if found then true
161-
elif subExprs.Count > 0 then deepExistsInner subExprs
162-
else false
163-
ResizeArray [|expr|] |> deepExistsInner
152+
let deepExists arg (f: 'arg -> Expr -> bool * 'arg) expr =
153+
let rec deepExistsInner arg = function
154+
| [] -> false
155+
| e::rest ->
156+
let found, subarg = f arg e
157+
if found then true
158+
else
159+
let subexprs = getSubExpressions e
160+
let found = deepExistsInner subarg subexprs
161+
if found then true
162+
else deepExistsInner arg rest
163+
deepExistsInner arg [expr]
164164

165165
let isIdentUsed identName expr =
166-
expr |> deepExists (function
167-
| IdentExpr i -> i.Name = identName
168-
| _ -> false)
166+
expr |> deepExists () (fun _ e ->
167+
match e with
168+
| IdentExpr i -> i.Name = identName, ()
169+
| _ -> false, ())
170+
171+
let isIdentCaptured identName expr =
172+
expr |> deepExists false (fun isClosure e ->
173+
match e with
174+
| Lambda _ | Delegate _ | ObjectExpr _ -> false, true
175+
| IdentExpr i -> isClosure && i.Name = identName, isClosure
176+
| _ -> false, isClosure)
169177

170178
let replaceValues replacements expr =
171179
if Map.isEmpty replacements
@@ -189,16 +197,20 @@ let replaceNames replacements expr =
189197

190198
let countReferences limit identName body =
191199
let mutable count = 0
192-
body |> deepExists (function
200+
body |> deepExists () (fun _ e ->
201+
match e with
193202
| IdentExpr id2 when id2.Name = identName ->
194203
count <- count + 1
195-
count > limit
196-
| _ -> false) |> ignore
204+
count > limit, ()
205+
| _ -> false, ()) |> ignore
197206
count
198207

199208
let canInlineArg identName value body =
200-
not(canHaveSideEffects value)
201-
&& countReferences 1 identName body <= 1
209+
match value with
210+
| IdentExpr i -> not i.IsMutable
211+
| _ ->
212+
not(canHaveSideEffects value)
213+
&& countReferences 1 identName body <= 1
202214

203215
module private Transforms =
204216
let (|LambdaOrDelegate|_|) = function
@@ -237,7 +249,9 @@ module private Transforms =
237249
| [] -> replaceValues replacements body
238250
| bindings -> Let(List.rev bindings, replaceValues replacements body)
239251
match e with
240-
// TODO: Other binary operations and numeric types, also recursive?
252+
| IfThenElse(IfThenElse(condition1, condition2, Value(BoolConstant false, _), _), thenExpr, elseExpr, r) ->
253+
IfThenElse(Operation(Logical(AST.LogicalAnd, condition1, condition2), Boolean, None), thenExpr, elseExpr, r)
254+
// TODO: Other binary operations and numeric types
241255
| Operation(Binary(AST.BinaryPlus, Value(StringConstant str1, r1), Value(StringConstant str2, r2)),_,_) ->
242256
Value(StringConstant(str1 + str2), addRanges [r1; r2])
243257
| Call(Delegate(args, body, _), info, _, _) when List.sameLength args info.Args ->

0 commit comments

Comments
 (0)