on master help sign in
Reorganize Optimize modules, making things a bit smaller
16c4b79Evan Czaplicki
elm-compiler.cabal+3−1
@@ -86,7 +86,9 @@ Library
86 Nitpick.PatternMatches,
86 Nitpick.PatternMatches,
87 Nitpick.TopLevelTypes,
87 Nitpick.TopLevelTypes,
88 Optimize,
88 Optimize,
89− Optimize.Cases,
89+ Optimize.Environment,
90+ Optimize.Patterns,
91+ Optimize.Patterns.DecisionTree,
90 Parse.Binop,
92 Parse.Binop,
91 Parse.Declaration,
93 Parse.Declaration,
92 Parse.Expression,
94 Parse.Expression,
src/AST/Expression/Optimized.hs+3−3
@@ -9,7 +9,7 @@ import qualified AST.Literal as Literal
9import qualified AST.Module.Name as ModuleName
9import qualified AST.Module.Name as ModuleName
10import qualified AST.Type as Type
10import qualified AST.Type as Type
11import qualified AST.Variable as Var
11import qualified AST.Variable as Var
12−import qualified Optimize.Cases as PM
12+import qualified Optimize.Patterns.DecisionTree as DT
13import qualified Reporting.Region as R
13import qualified Reporting.Region as R
14
14
15
15
@@ -40,7 +40,7 @@ data Expr
40 | TailCall String [String] [Expr]
40 | TailCall String [String] [Expr]
41 | If [(Expr, Expr)] Expr
41 | If [(Expr, Expr)] Expr
42 | Let [Def] Expr
42 | Let [Def] Expr
43− | Case Expr (PM.DecisionTree Jump) [(Int, Branch)]
43+ | Case Expr (DT.DecisionTree Jump) [(Int, Branch)]
44 | Data String [Expr]
44 | Data String [Expr]
45 | DataAccess Expr Int
45 | DataAccess Expr Int
46 | Access Expr String
46 | Access Expr String
@@ -57,6 +57,6 @@ data Jump
57
57
58
58
59data Branch = Branch
59data Branch = Branch
60− { _substitutions :: [(String, PM.Path)]
60+ { _substitutions :: [(String, DT.Path)]
61 , _branch :: Expr
61 , _branch :: Expr
62 }
62 }
src/Generate/JavaScript.hs+2−2
@@ -20,7 +20,7 @@ import qualified Generate.JavaScript.BuiltIn as BuiltIn
20import qualified Generate.JavaScript.Literal as Literal
20import qualified Generate.JavaScript.Literal as Literal
21import qualified Generate.JavaScript.Port as Port
21import qualified Generate.JavaScript.Port as Port
22import qualified Generate.JavaScript.Variable as Var
22import qualified Generate.JavaScript.Variable as Var
23−import qualified Optimize.Cases as PM
23+import qualified Optimize.Patterns.DecisionTree as DT
24
24
25
25
26generate :: Module.Optimized -> String
26generate :: Module.Optimized -> String
@@ -330,7 +330,7 @@ crushIfsHelp visitedBranches unvisitedBranches finally =
330
330
331generateCase
331generateCase
332 :: Opt.Expr
332 :: Opt.Expr
333− -> PM.DecisionTree Opt.Jump
333+ -> DT.DecisionTree Opt.Jump
334 -> [(Int, Opt.Branch)]
334 -> [(Int, Opt.Branch)]
335 -> State Int Code
335 -> State Int Code
336generateCase expr decisionTree branches =
336generateCase expr decisionTree branches =
src/Optimize.hs+31−169
@@ -1,12 +1,8 @@
1module Optimize (optimize) where
1module Optimize (optimize) where
2
2
3import Control.Applicative
3import Control.Applicative
4−import Control.Arrow (second)
5import qualified Control.Monad as M
4import qualified Control.Monad as M
6import qualified Control.Monad.State as State
5import qualified Control.Monad.State as State
7−import qualified Data.Map as Map
8−import Data.Map ((!))
9−import qualified Data.Maybe as Maybe
10import qualified Data.Traversable as T
6import qualified Data.Traversable as T
11
7
12import qualified AST.Expression.General as Expr
8import qualified AST.Expression.General as Expr
@@ -16,8 +12,8 @@ import qualified AST.Module as Module
16import qualified AST.Module.Name as ModuleName
12import qualified AST.Module.Name as ModuleName
17import qualified AST.Pattern as P
13import qualified AST.Pattern as P
18import qualified AST.Variable as Var
14import qualified AST.Variable as Var
19−import Elm.Utils ((|>))
15+import qualified Optimize.Environment as Env
20−import qualified Optimize.Cases as Cases
16+import qualified Optimize.Patterns as Patterns
21import qualified Reporting.Annotation as A
17import qualified Reporting.Annotation as A
22import qualified Reporting.Region as R
18import qualified Reporting.Region as R
23
19
@@ -35,7 +31,7 @@ optimize module_ =
35 in
31 in
36 State.evalState
32 State.evalState
37 (concat <$> mapM (optimizeDef (Just home)) defs)
33 (concat <$> mapM (optimizeDef (Just home)) defs)
38− (Env False 0)
34+ (Env.Env False 0)
39
35
40
36
41flattenLets :: [Can.Def] -> Can.Expr -> ([Can.Def], Can.Expr)
37flattenLets :: [Can.Def] -> Can.Expr -> ([Can.Def], Can.Expr)
@@ -48,32 +44,9 @@ flattenLets defs annExpr@(A.A _ expr) =
48 (defs, annExpr)
44 (defs, annExpr)
49
45
50
46
51−-- TRACKER TO THREAD FINDINGS THROUGH TRAVERSAL
52−
53−type Optimizer a =
54− State.State Env a
55−
56−
57−data Env = Env
58− { _hasTailCall :: Bool
59− , _uid :: Int
60− }
61−
62−
63−setTailCall :: Bool -> Optimizer ()
64−setTailCall bool =
65− do uid <- State.gets _uid
66− State.put (Env bool uid)
67−
68−
69−mapSnd :: M.Functor box => (a -> box b) -> (x, a) -> box (x, b)
70−mapSnd func (x, a) =
71− (,) x <$> func a
72−
73−
74-- CONVERT DEFINITIONS
47-- CONVERT DEFINITIONS
75
48
76−optimizeDef :: Maybe ModuleName.Canonical -> Can.Def -> Optimizer [Opt.Def]
49+optimizeDef :: Maybe ModuleName.Canonical -> Can.Def -> Env.Optimizer [Opt.Def]
77optimizeDef home (Can.Definition (Can.Facts deps) pattern@(A.A _ ptrn) expression _) =
50optimizeDef home (Can.Definition (Can.Facts deps) pattern@(A.A _ ptrn) expression _) =
78 let
51 let
79 (args, rawBody) =
52 (args, rawBody) =
@@ -82,13 +55,13 @@ optimizeDef home (Can.Definition (Can.Facts deps) pattern@(A.A _ ptrn) expressio
82 case (ptrn, args) of
55 case (ptrn, args) of
83 (P.Var name, _ : _) ->
56 (P.Var name, _ : _) ->
84
57
85− do (Env htc uid) <- State.get
58+ do (Env.Env htc uid) <- State.get
86− State.put (Env False uid)
59+ State.put (Env.Env False uid)
87
60
88 (args, body) <- optimizeFunction (Just name) args rawBody
61 (args, body) <- optimizeFunction (Just name) args rawBody
89
62
90− (Env isTailCall uid') <- State.get
63+ (Env.Env isTailCall uid') <- State.get
91− State.put (Env htc uid')
64+ State.put (Env.Env htc uid')
92
65
93 let facts = Opt.Facts home deps
66 let facts = Opt.Facts home deps
94
67
@@ -103,14 +76,14 @@ optimizeDef home (Can.Definition (Can.Facts deps) pattern@(A.A _ ptrn) expressio
103
76
104 (P.Var name, []) ->
77 (P.Var name, []) ->
105
78
106− do hasTailCall <- State.gets _hasTailCall
79+ do hasTailCall <- State.gets Env._hasTailCall
107 body <- optimizeExpr Nothing rawBody
80 body <- optimizeExpr Nothing rawBody
108− setTailCall hasTailCall
81+ Env.setTailCall hasTailCall
109 return [ Opt.Def (Opt.Facts home deps) name body ]
82 return [ Opt.Def (Opt.Facts home deps) name body ]
110
83
111 (_, []) ->
84 (_, []) ->
112
85
113− do name <- freshName
86+ do name <- Env.freshName
114 optBody <- optimizeExpr Nothing rawBody
87 optBody <- optimizeExpr Nothing rawBody
115 let optDef = Opt.Def (Opt.Facts home deps) name optBody
88 let optDef = Opt.Def (Opt.Facts home deps) name optBody
116 return (optDef : patternToDefs home name pattern)
89 return (optDef : patternToDefs home name pattern)
@@ -125,7 +98,7 @@ optimizeFunction
125 :: Maybe String
98 :: Maybe String
126 -> [P.CanonicalPattern]
99 -> [P.CanonicalPattern]
127 -> Can.Expr
100 -> Can.Expr
128− -> Optimizer ([String], Opt.Expr)
101+ -> Env.Optimizer ([String], Opt.Expr)
129optimizeFunction maybeName patterns givenBody =
102optimizeFunction maybeName patterns givenBody =
130 do (argNames, body) <- M.foldM depatternArgs ([], givenBody) (reverse patterns)
103 do (argNames, body) <- M.foldM depatternArgs ([], givenBody) (reverse patterns)
131 optBody <- optimizeExpr (makeContext argNames =<< maybeName) body
104 optBody <- optimizeExpr (makeContext argNames =<< maybeName) body
@@ -140,7 +113,7 @@ makeContext argNames name =
140depatternArgs
113depatternArgs
141 :: ([String], Can.Expr)
114 :: ([String], Can.Expr)
142 -> P.CanonicalPattern
115 -> P.CanonicalPattern
143− -> Optimizer ([String], Can.Expr)
116+ -> Env.Optimizer ([String], Can.Expr)
144depatternArgs (names, rawExpr) ptrn =
117depatternArgs (names, rawExpr) ptrn =
145 do (name, expr) <- depattern ptrn rawExpr
118 do (name, expr) <- depattern ptrn rawExpr
146 return (name : names, expr)
119 return (name : names, expr)
@@ -203,7 +176,7 @@ function arity, and list of argument names. If a tail call is possible, the
203`Context` will be filled in and we check any function we run into. If we go
176`Context` will be filled in and we check any function we run into. If we go
204down a route that cannot possibly have tail calls, we remove the context.
177down a route that cannot possibly have tail calls, we remove the context.
205-}
178-}
206−optimizeExpr :: Context -> Can.Expr -> Optimizer Opt.Expr
179+optimizeExpr :: Context -> Can.Expr -> Env.Optimizer Opt.Expr
207optimizeExpr context annExpr@(A.A region expression) =
180optimizeExpr context annExpr@(A.A region expression) =
208 let
181 let
209 keepLooking =
182 keepLooking =
@@ -250,17 +223,16 @@ optimizeExpr context annExpr@(A.A region expression) =
250 case isTailCall context func (length args) of
223 case isTailCall context func (length args) of
251 Just (name, argNames) ->
224 Just (name, argNames) ->
252 do optArgs <- T.traverse justConvert args
225 do optArgs <- T.traverse justConvert args
253− setTailCall True
226+ Env.setTailCall True
254 return (Opt.TailCall name argNames optArgs)
227 return (Opt.TailCall name argNames optArgs)
255
228
256 Nothing ->
229 Nothing ->
257− do hasTailCall <- State.gets _hasTailCall
230+ do hasTailCall <- State.gets Env._hasTailCall
258 optFunc <- justConvert func
231 optFunc <- justConvert func
259 optArgs <- T.traverse justConvert args
232 optArgs <- T.traverse justConvert args
260− setTailCall hasTailCall
233+ Env.setTailCall hasTailCall
261 return (Opt.Call optFunc optArgs)
234 return (Opt.Call optFunc optArgs)
262
235
263−
264 Expr.If branches finally ->
236 Expr.If branches finally ->
265 let
237 let
266 crawlBranch (cond,branch) =
238 crawlBranch (cond,branch) =
@@ -275,7 +247,9 @@ optimizeExpr context annExpr@(A.A region expression) =
275 Opt.Let optDefs <$> keepLooking body
247 Opt.Let optDefs <$> keepLooking body
276
248
277 Expr.Case expr branches ->
249 Expr.Case expr branches ->
278− optimizeCase context region expr branches
250+ do optExpr <- optimizeExpr Nothing expr
251+ optBranches <- T.traverse (mapSnd (optimizeExpr context)) branches
252+ Patterns.optimize region optExpr optBranches
279
253
280 Expr.Data name exprs ->
254 Expr.Data name exprs ->
281 Opt.Data name <$> T.traverse justConvert exprs
255 Opt.Data name <$> T.traverse justConvert exprs
@@ -310,6 +284,11 @@ optimizeExpr context annExpr@(A.A region expression) =
310 (\e -> Expr.Task name e tipe) <$> justConvert expr
284 (\e -> Expr.Task name e tipe) <$> justConvert expr
311
285
312
286
287+mapSnd :: M.Functor box => (a -> box b) -> (x, a) -> box (x, b)
288+mapSnd func (x, a) =
289+ (,) x <$> func a
290+
291+
313-- DETECT TAIL CALL
292-- DETECT TAIL CALL
314
293
315isTailCall :: Context -> Can.Expr -> Int -> Maybe (String, [String])
294isTailCall :: Context -> Can.Expr -> Int -> Maybe (String, [String])
@@ -327,13 +306,12 @@ isTailCall context (A.A _ function) arity =
327 Nothing
306 Nothing
328
307
329
308
330−
331-- DEPATTERN
309-- DEPATTERN
332-- given a pattern and an expression, push the actual pattern matching into the
310-- given a pattern and an expression, push the actual pattern matching into the
333-- expression as a case-expression if necessary. The pattern compiler will work
311-- expression as a case-expression if necessary. The pattern compiler will work
334-- it out from there
312-- it out from there
335
313
336−depattern :: P.CanonicalPattern -> Can.Expr -> Optimizer (String, Can.Expr)
314+depattern :: P.CanonicalPattern -> Can.Expr -> Env.Optimizer (String, Can.Expr)
337depattern canPattern@(A.A _ pattern) expr =
315depattern canPattern@(A.A _ pattern) expr =
338 let
316 let
339 ann =
317 ann =
@@ -346,7 +324,7 @@ depattern canPattern@(A.A _ pattern) expr =
346 ann (Expr.Var (Var.local name))
324 ann (Expr.Var (Var.local name))
347
325
348 caseify =
326 caseify =
349− do name <- freshName
327+ do name <- Env.freshName
350 return
328 return
351 ( name
329 ( name
352 , caseExpr (var name) [ (canPattern, expr) ]
330 , caseExpr (var name) [ (canPattern, expr) ]
@@ -363,7 +341,7 @@ depattern canPattern@(A.A _ pattern) expr =
363 caseify
341 caseify
364
342
365 P.Anything ->
343 P.Anything ->
366− do name <- freshName
344+ do name <- Env.freshName
367 return (name, expr)
345 return (name, expr)
368
346
369 P.Alias _ _ ->
347 P.Alias _ _ ->
@@ -373,122 +351,6 @@ depattern canPattern@(A.A _ pattern) expr =
373 caseify
351 caseify
374
352
375
353
376−freshName :: Optimizer String
377−freshName =
378− do (Env htc uid) <- State.get
379− State.put (Env htc (uid + 1))
380− return ("_p" ++ show uid)
381−
382−
383−-- OPTIMIZE CASES
384−
385−optimizeCase
386− :: Context
387− -> R.Region
388− -> Can.Expr
389− -> [(P.CanonicalPattern, Can.Expr)]
390− -> Optimizer Opt.Expr
391−optimizeCase context region expr rawBranches =
392− let
393− indexify index (pattern, branch) =
394− ( (pattern, index)
395− , (index, branch)
396− )
397− in
398− do optBranches <- T.traverse (mapSnd (optimizeExpr context)) rawBranches
399− crashBranches <-
400− case last optBranches of
401− (A.A ann P.Anything, Opt.Call (Opt.Crash _ _) [arg]) ->
402− do name <- freshName
403− let newPattern = A.A ann (P.Var name)
404− let newCall = Opt.Call (Opt.Crash region (Just name)) [arg]
405− return (init optBranches ++ [(newPattern, newCall)])
406−
407− _ ->
408− return optBranches
409−
410− let (patterns, indexedBranches) =
411− unzip (zipWith indexify [0..] crashBranches)
412−
413− let decisionTree =
414− Cases.compile (error "need a VariantDict") patterns
415−
416− optExpr <- optimizeExpr Nothing expr
417−
418− return (inlinedCase optExpr decisionTree indexedBranches)
419−
420−
421−inlinedCase
422− :: Opt.Expr
423− -> Cases.DecisionTree Cases.Jump
424− -> [(Int, Opt.Expr)]
425− -> Opt.Expr
426−inlinedCase expr decisionTree jumpTargets =
427− let
428− substitutionDict =
429− gatherSubstitutions decisionTree
430−
431− (jumps, sharedBranches) =
432− unzip (map (toJumps substitutionDict) jumpTargets)
433− in
434− Opt.Case
435− expr
436− (inlineJumps (Map.fromList jumps) decisionTree)
437− (Maybe.catMaybes sharedBranches)
438−
439−
440−gatherSubstitutions
441− :: Cases.DecisionTree Cases.Jump
442− -> Map.Map Int [[(String, Cases.Path)]]
443−gatherSubstitutions decisionTree =
444− case decisionTree of
445− Cases.Decision _ edges fallback ->
446− map snd edges
447− |> maybe id (:) fallback
448− |> map gatherSubstitutions
449− |> Map.unionsWith (++)
450−
451− Cases.Match (Cases.Jump target substitutions) ->
452− Map.singleton target [substitutions]
453−
454−
455−toJumps
456− :: Map.Map Int [[(String, Cases.Path)]]
457− -> (Int, Opt.Expr)
458− -> ( (Int, Opt.Jump), Maybe (Int, Opt.Branch) )
459−toJumps substitutionDict (target, branch) =
460− case substitutionDict ! target of
461− [substitutions] ->
462− ( (target, Opt.Inline (Opt.Branch substitutions branch))
463− , Nothing
464− )
465−
466− substitutions : _ ->
467− ( (target, Opt.Jump target)
468− , Just (target, Opt.Branch substitutions branch)
469− )
470−
471− _ ->
472− error "it is not possible for there to be no substitutions"
473−
474−
475−inlineJumps
476− :: Map.Map Int Opt.Jump
477− -> Cases.DecisionTree Cases.Jump
478− -> Cases.DecisionTree Opt.Jump
479−inlineJumps jumpDict decisionTree =
480− let
481− go =
482− inlineJumps jumpDict
483− in
484− case decisionTree of
485− Cases.Decision test edges fallback ->
486− Cases.Decision test (map (second go) edges) (fmap go fallback)
487−
488− Cases.Match (Cases.Jump target _) ->
489− Cases.Match (jumpDict ! target)
490−
491−
492-- OPTIMIZE BINOPS
354-- OPTIMIZE BINOPS
493
355
494optimizeBinop
356optimizeBinop
@@ -497,7 +359,7 @@ optimizeBinop
497 -> Var.Canonical
359 -> Var.Canonical
498 -> Can.Expr
360 -> Can.Expr
499 -> Can.Expr
361 -> Can.Expr
500− -> Optimizer Opt.Expr
362+ -> Env.Optimizer Opt.Expr
501optimizeBinop context region op leftExpr rightExpr =
363optimizeBinop context region op leftExpr rightExpr =
502 let
364 let
503 ann = A.A region
365 ann = A.A region
@@ -513,14 +375,14 @@ optimizeBinop context region op leftExpr rightExpr =
513
375
514 else if op == forwardCompose then
376 else if op == forwardCompose then
515
377
516− do var <- freshName
378+ do var <- Env.freshName
517 let makeRoot func = ann (Expr.App func (ann (Expr.Var (Var.local var))))
379 let makeRoot func = ann (Expr.App func (ann (Expr.Var (Var.local var))))
518 let body = collect makeRoot left forwardCompose binop
380 let body = collect makeRoot left forwardCompose binop
519 optimizeExpr context (ann (Expr.Lambda (ann (P.Var var)) body))
381 optimizeExpr context (ann (Expr.Lambda (ann (P.Var var)) body))
520
382
521 else if op == backwardCompose then
383 else if op == backwardCompose then
522
384
523− do var <- freshName
385+ do var <- Env.freshName
524 let makeRoot func = ann (Expr.App func (ann (Expr.Var (Var.local var))))
386 let makeRoot func = ann (Expr.App func (ann (Expr.Var (Var.local var))))
525 let body = collect makeRoot right backwardCompose binop
387 let body = collect makeRoot right backwardCompose binop
526 optimizeExpr context (ann (Expr.Lambda (ann (P.Var var)) body))
388 optimizeExpr context (ann (Expr.Lambda (ann (P.Var var)) body))
src/Optimize/Environment.hsnew file+26
@@ -0,0 +1,26 @@
1+module Optimize.Environment where
2+
3+import qualified Control.Monad.State as State
4+
5+
6+type Optimizer a =
7+ State.State Env a
8+
9+
10+data Env = Env
11+ { _hasTailCall :: Bool
12+ , _uid :: Int
13+ }
14+
15+
16+setTailCall :: Bool -> Optimizer ()
17+setTailCall bool =
18+ do uid <- State.gets _uid
19+ State.put (Env bool uid)
20+
21+
22+freshName :: Optimizer String
23+freshName =
24+ do (Env htc uid) <- State.get
25+ State.put (Env htc (uid + 1))
26+ return ("_p" ++ show uid)
src/Optimize/Patterns.hsnew file+125
@@ -0,0 +1,125 @@
1+{-# OPTIONS_GHC -Wall #-}
2+module Optimize.Patterns (optimize) where
3+
4+import Control.Applicative
5+import Control.Arrow (second)
6+import qualified Control.Monad as M
7+import qualified Control.Monad.State as State
8+import qualified Data.Map as Map
9+import Data.Map ((!))
10+import qualified Data.Maybe as Maybe
11+import qualified Data.Traversable as T
12+
13+import qualified AST.Expression.Optimized as Opt
14+import qualified AST.Module as Module
15+import qualified AST.Module.Name as ModuleName
16+import qualified AST.Pattern as P
17+import qualified AST.Variable as Var
18+import Elm.Utils ((|>))
19+import qualified Optimize.Environment as Env
20+import qualified Optimize.Patterns.DecisionTree as DT
21+import qualified Reporting.Annotation as A
22+import qualified Reporting.Region as R
23+
24+
25+optimize
26+ :: R.Region
27+ -> Opt.Expr
28+ -> [(P.CanonicalPattern, Opt.Expr)]
29+ -> Env.Optimizer Opt.Expr
30+optimize region optExpr optBranches =
31+ let
32+ indexify index (pattern, branch) =
33+ ( (pattern, index)
34+ , (index, branch)
35+ )
36+ in
37+ do crashBranches <-
38+ case last optBranches of
39+ (A.A ann P.Anything, Opt.Call (Opt.Crash _ _) [arg]) ->
40+ do name <- Env.freshName
41+ let newPattern = A.A ann (P.Var name)
42+ let newCall = Opt.Call (Opt.Crash region (Just name)) [arg]
43+ return (init optBranches ++ [(newPattern, newCall)])
44+
45+ _ ->
46+ return optBranches
47+
48+ let (patterns, indexedBranches) =
49+ unzip (zipWith indexify [0..] crashBranches)
50+
51+ let decisionTree =
52+ DT.compile (error "need a VariantDict") patterns
53+
54+ return (inlinedCase optExpr decisionTree indexedBranches)
55+
56+
57+inlinedCase
58+ :: Opt.Expr
59+ -> DT.DecisionTree DT.Jump
60+ -> [(Int, Opt.Expr)]
61+ -> Opt.Expr
62+inlinedCase expr decisionTree jumpTargets =
63+ let
64+ substitutionDict =
65+ gatherSubstitutions decisionTree
66+
67+ (jumps, sharedBranches) =
68+ unzip (map (toJumps substitutionDict) jumpTargets)
69+ in
70+ Opt.Case
71+ expr
72+ (inlineJumps (Map.fromList jumps) decisionTree)
73+ (Maybe.catMaybes sharedBranches)
74+
75+
76+gatherSubstitutions
77+ :: DT.DecisionTree DT.Jump
78+ -> Map.Map Int [[(String, DT.Path)]]
79+gatherSubstitutions decisionTree =
80+ case decisionTree of
81+ DT.Decision _ edges fallback ->
82+ map snd edges
83+ |> maybe id (:) fallback
84+ |> map gatherSubstitutions
85+ |> Map.unionsWith (++)
86+
87+ DT.Match (DT.Jump target substitutions) ->
88+ Map.singleton target [substitutions]
89+
90+
91+toJumps
92+ :: Map.Map Int [[(String, DT.Path)]]
93+ -> (Int, Opt.Expr)
94+ -> ( (Int, Opt.Jump), Maybe (Int, Opt.Branch) )
95+toJumps substitutionDict (target, branch) =
96+ case substitutionDict ! target of
97+ [substitutions] ->
98+ ( (target, Opt.Inline (Opt.Branch substitutions branch))
99+ , Nothing
100+ )
101+
102+ substitutions : _ ->
103+ ( (target, Opt.Jump target)
104+ , Just (target, Opt.Branch substitutions branch)
105+ )
106+
107+ _ ->
108+ error "it is not possible for there to be no substitutions"
109+
110+
111+inlineJumps
112+ :: Map.Map Int Opt.Jump
113+ -> DT.DecisionTree DT.Jump
114+ -> DT.DecisionTree Opt.Jump
115+inlineJumps jumpDict decisionTree =
116+ let
117+ go =
118+ inlineJumps jumpDict
119+ in
120+ case decisionTree of
121+ DT.Decision test edges fallback ->
122+ DT.Decision test (map (second go) edges) (fmap go fallback)
123+
124+ DT.Match (DT.Jump target _) ->
125+ DT.Match (jumpDict ! target)
src/Optimize/Cases.hs → src/Optimize/Patterns/DecisionTree.hsrenamed+1−1
@@ -1,5 +1,5 @@
1{-# OPTIONS_GHC -Wall #-}
1{-# OPTIONS_GHC -Wall #-}
2−module Optimize.Cases where
2+module Optimize.Patterns.DecisionTree where
3{- To learn more about how this works, definitely read through:
3{- To learn more about how this works, definitely read through:
4
4
5 "When Do Match-Compilation Heuristics Matter?"
5 "When Do Match-Compilation Heuristics Matter?"