@@ -18,7 +18,7 @@ import qualified Reporting.Annotation as A
18import qualified Reporting.Region as R
18import qualified Reporting.Region as R
21−-- OPTIMIZE FOR TAIL CALLS
21+-- OPTIMIZE - turn a canonical module into a list of optimized defs
23optimize :: Module.CanonicalModule -> Module.Optimized
23optimize :: Module.CanonicalModule -> Module.Optimized
24optimize module_ =
24optimize module_ =
@@ -30,7 +30,7 @@ optimize module_ =
30 flattenLets [] (Module.program (Module.body module_))
30 flattenLets [] (Module.program (Module.body module_))
32 State.evalState
32 State.evalState
33− (concat <$> mapM (definition (Just home)) defs)
33+ (concat <$> mapM (optimizeDef (Just home)) defs)
34 (Env False 0)
34 (Env False 0)
@@ -69,8 +69,8 @@ mapSnd func (x, a) =
70-- CONVERT DEFINITIONS
70-- CONVERT DEFINITIONS
72−definition :: Maybe ModuleName.Canonical -> Can.Def -> Optimizer [Opt.Def]
72+optimizeDef :: Maybe ModuleName.Canonical -> Can.Def -> Optimizer [Opt.Def]
73−definition home (Can.Definition (Can.Facts deps) pattern@(A.A _ ptrn) expression _) =
73+optimizeDef home (Can.Definition (Can.Facts deps) pattern@(A.A _ ptrn) expression _) =
75 (args, rawBody) =
75 (args, rawBody) =
76 Expr.collectLambdas expression
76 Expr.collectLambdas expression
@@ -100,14 +100,14 @@ definition home (Can.Definition (Can.Facts deps) pattern@(A.A _ ptrn) expression
100 (P.Var name, []) ->
100 (P.Var name, []) ->
102 do hasTailCall <- State.gets _hasTailCall
102 do hasTailCall <- State.gets _hasTailCall
103− body <- findTailCalls Nothing rawBody
103+ body <- optimizeExpr Nothing rawBody
104 setTailCall hasTailCall
104 setTailCall hasTailCall
105 return [ Opt.Def (Opt.Facts home deps) name body ]
105 return [ Opt.Def (Opt.Facts home deps) name body ]
107 (_, []) ->
107 (_, []) ->
109 do name <- freshName
109 do name <- freshName
110− optBody <- findTailCalls Nothing rawBody
110+ optBody <- optimizeExpr Nothing rawBody
111 let optDef = Opt.Def (Opt.Facts home deps) name optBody
111 let optDef = Opt.Def (Opt.Facts home deps) name optBody
112 return (optDef : patternToDefs home name pattern)
112 return (optDef : patternToDefs home name pattern)
@@ -124,7 +124,7 @@ optimizeFunction
124 -> Optimizer ([String], Opt.Expr)
124 -> Optimizer ([String], Opt.Expr)
125optimizeFunction maybeName patterns givenBody =
125optimizeFunction maybeName patterns givenBody =
126 do (argNames, body) <- M.foldM depatternArgs ([], givenBody) (reverse patterns)
126 do (argNames, body) <- M.foldM depatternArgs ([], givenBody) (reverse patterns)
127− optBody <- findTailCalls (makeContext argNames =<< maybeName) body
127+ optBody <- optimizeExpr (makeContext argNames =<< maybeName) body
128 return (argNames, optBody)
128 return (argNames, optBody)
@@ -189,21 +189,26 @@ substitutions expr (A.A _ pattern) =
189 concat (zipWith (substitutions . Opt.DataAccess expr) [0..] patterns)
189 concat (zipWith (substitutions . Opt.DataAccess expr) [0..] patterns)
192−-- CONVERT EXPRESSIONS
192+-- OPTIMIZE EXPRESSIONS
194type Context = Maybe (String, Int, [String])
194type Context = Maybe (String, Int, [String])
197+{-| This optimizer detects tail calls. The `Context` holds a function name,
198+function arity, and list of argument names. If a tail call is possible, the
199+`Context` will be filled in and we check any function we run into. If we go
200+down a route that cannot possibly have tail calls, we remove the context.
197−findTailCalls :: Context -> Can.Expr -> Optimizer Opt.Expr
202+optimizeExpr :: Context -> Can.Expr -> Optimizer Opt.Expr
198−findTailCalls context annExpr@(A.A region expression) =
203+optimizeExpr context annExpr@(A.A region expression) =
200 keepLooking =
205 keepLooking =
201− findTailCalls context
206+ optimizeExpr context
202 -- this *might* find a tail call, use this when something is a potential
207 -- this *might* find a tail call, use this when something is a potential
203 -- tail call
208 -- tail call
205 justConvert =
210 justConvert =
206− findTailCalls Nothing
211+ optimizeExpr Nothing
207 -- this will never find tail calls, use this when you are working with
212 -- this will never find tail calls, use this when you are working with
208 -- expressions that cannot be turned into tail calls
213 -- expressions that cannot be turned into tail calls
@@ -262,7 +267,7 @@ findTailCalls context annExpr@(A.A region expression) =
262 <*> keepLooking finally
267 <*> keepLooking finally
264 Expr.Let defs body ->
269 Expr.Let defs body ->
265− do optDefs <- concat <$> T.traverse (definition Nothing) defs
270+ do optDefs <- concat <$> T.traverse (optimizeDef Nothing) defs
266 Opt.Let optDefs <$> keepLooking body
271 Opt.Let optDefs <$> keepLooking body
268 Expr.Case expr rawBranches ->
273 Expr.Case expr rawBranches ->
@@ -405,35 +410,35 @@ optimizeBinop context region op leftExpr rightExpr =
406 if op == forwardApply then
411 if op == forwardApply then
408− findTailCalls context (collect id left forwardApply binop)
413+ optimizeExpr context (collect id left forwardApply binop)
410 else if op == backwardApply then
415 else if op == backwardApply then
412− findTailCalls context (collect id right backwardApply binop)
417+ optimizeExpr context (collect id right backwardApply binop)
414 else if op == forwardCompose then
419 else if op == forwardCompose then
416 do var <- freshName
421 do var <- freshName
417 let makeRoot func = ann (Expr.App func (ann (Expr.Var (Var.local var))))
422 let makeRoot func = ann (Expr.App func (ann (Expr.Var (Var.local var))))
418 let body = collect makeRoot left forwardCompose binop
423 let body = collect makeRoot left forwardCompose binop
419− findTailCalls context (ann (Expr.Lambda (ann (P.Var var)) body))
424+ optimizeExpr context (ann (Expr.Lambda (ann (P.Var var)) body))
421 else if op == backwardCompose then
426 else if op == backwardCompose then
423 do var <- freshName
428 do var <- freshName
424 let makeRoot func = ann (Expr.App func (ann (Expr.Var (Var.local var))))
429 let makeRoot func = ann (Expr.App func (ann (Expr.Var (Var.local var))))
425 let body = collect makeRoot right backwardCompose binop
430 let body = collect makeRoot right backwardCompose binop
426− findTailCalls context (ann (Expr.Lambda (ann (P.Var var)) body))
431+ optimizeExpr context (ann (Expr.Lambda (ann (P.Var var)) body))
428 else if op == Var.Canonical Var.BuiltIn "::" then
433 else if op == Var.Canonical Var.BuiltIn "::" then
430− findTailCalls context (ann (Expr.Data "::" [ leftExpr, rightExpr ]))
435+ optimizeExpr context (ann (Expr.Data "::" [ leftExpr, rightExpr ]))
434 Opt.Binop op
439 Opt.Binop op
435− <$> findTailCalls Nothing leftExpr
440+ <$> optimizeExpr Nothing leftExpr
436− <*> findTailCalls Nothing rightExpr
441+ <*> optimizeExpr Nothing rightExpr
439-- left-associative ((x |> f) |> g)
444-- left-associative ((x |> f) |> g)