@@ -19,8 +19,10 @@ import qualified Reporting.Annotation as A
19import qualified Reporting.Region as R
19import qualified Reporting.Region as R
22-- OPTIMIZE
23-- OPTIMIZE
24optimize :: DT.VariantDict -> Module.CanonicalModule -> Module.Optimized
26optimize :: DT.VariantDict -> Module.CanonicalModule -> Module.Optimized
25optimize variantDict module_@(Module.Module home _ _ _ _ body) =
27optimize variantDict module_@(Module.Module home _ _ _ _ body) =
@@ -28,7 +30,7 @@ optimize variantDict module_@(Module.Module home _ _ _ _ body) =
28 flattenLets [] (Module.program body)
30 flattenLets [] (Module.program body)
31− Env.run variantDict (concat <$> mapM (optimizeDef (Just home)) defs)
33+ Env.run variantDict home (concat <$> mapM (optimizeDef True) defs)
33 module_ { Module.body = body { Module.program = optDefs } }
35 module_ { Module.body = body { Module.program = optDefs } }
@@ -43,56 +45,77 @@ flattenLets defs annExpr@(A.A _ expr) =
43 (defs, annExpr)
45 (defs, annExpr)
46-- CONVERT DEFINITIONS
49-- CONVERT DEFINITIONS
48−optimizeDef :: Maybe ModuleName.Canonical -> Can.Def -> Env.Optimizer [Opt.Def]
52+optimizeDef :: Bool -> Can.Def -> Env.Optimizer [Opt.Def]
49−optimizeDef home (Can.Definition (Can.Facts deps) pattern@(A.A _ ptrn) expression _) =
53+optimizeDef isRoot (Can.Definition (Can.Facts deps) pattern expression _) =
51− (args, rawBody) =
55+ (args, canBody) =
52 Expr.collectLambdas expression
56 Expr.collectLambdas expression
54− case (ptrn, args) of
58+ do home <-
55− (P.Var name, _ : _) ->
59+ if isRoot then
57− do htc <- Env.getTailCall
64+ optimizeDefHelp home deps pattern args canBody
58− Env.setTailCall False
60− (args, body) <- optimizeFunction (Just name) args rawBody
62− isTailCall <- Env.getTailCall
67+optimizeDefHelp
63− Env.setTailCall htc
68+ :: Maybe ModuleName.Canonical
70+ -> P.CanonicalPattern
71+ -> [P.CanonicalPattern]
73+ -> Env.Optimizer [Opt.Def]
74+optimizeDefHelp home deps pattern@(A.A _ ptrn) args rawBody =
80+ (P.Var name, _ : _) ->
65− let facts = Opt.Facts home deps
82+ do htc <- Env.getTailCall
83+ Env.setTailCall False
67− return $
85+ (args, body) <- optimizeFunction (Just name) args rawBody
70− [ Opt.TailDef facts name args body ]
87+ isTailCall <- Env.getTailCall
92+ [ Opt.TailDef facts name args body ]
74 [ Opt.Def facts name (Opt.Function args body) ]
95 [ Opt.Def facts name (Opt.Function args body) ]
76− (P.Var name, []) ->
97+ (P.Var name, []) ->
78− do hasTailCall <- Env.getTailCall
99+ do hasTailCall <- Env.getTailCall
79− body <- optimizeExpr Nothing rawBody
100+ body <- optimizeExpr Nothing rawBody
80− Env.setTailCall hasTailCall
101+ Env.setTailCall hasTailCall
81− return [ Opt.Def (Opt.Facts home deps) name body ]
102+ return [ Opt.Def facts name body ]
83− (_, []) ->
104+ (_, []) ->
85− do name <- Env.freshName
106+ do name <- Env.freshName
86− optBody <- optimizeExpr Nothing rawBody
107+ optBody <- optimizeExpr Nothing rawBody
87− let optDef = Opt.Def (Opt.Facts home deps) name optBody
108+ let optDef = Opt.Def facts name optBody
88− return (optDef : patternToDefs home name pattern)
109+ return (optDef : patternToDefs home name pattern)
112+ error "there should never be a function where the name is not a P.Var"
91− error "there should never be a function where the name is not a P.Var"
94-- OPTIMIZE FUNCTION
116-- OPTIMIZE FUNCTION
96optimizeFunction
119optimizeFunction
97 :: Maybe String
120 :: Maybe String
98 -> [P.CanonicalPattern]
121 -> [P.CanonicalPattern]
@@ -196,7 +219,8 @@ optimizeExpr context annExpr@(A.A region expression) =
197 Expr.Var name ->
220 Expr.Var name ->
198 if name == Var.inCore ["Debug"] "crash" then
221 if name == Var.inCore ["Debug"] "crash" then
222+ do home <- Env.getHome
199− pure (Opt.Crash region Nothing)
223+ pure (Opt.Crash home region Nothing)
202 pure (Opt.Var name)
226 pure (Opt.Var name)
@@ -248,7 +272,7 @@ optimizeExpr context annExpr@(A.A region expression) =
248 <*> keepLooking finally
272 <*> keepLooking finally
250 Expr.Let defs body ->
274 Expr.Let defs body ->
251− do optDefs <- concat <$> T.traverse (optimizeDef Nothing) defs
275+ do optDefs <- concat <$> T.traverse (optimizeDef False) defs
252 Opt.Let optDefs <$> keepLooking body
276 Opt.Let optDefs <$> keepLooking body
254 Expr.Case expr branches ->
278 Expr.Case expr branches ->
@@ -256,8 +280,8 @@ optimizeExpr context annExpr@(A.A region expression) =
256 variantDict <- Env.getVariantDict
280 variantDict <- Env.getVariantDict
258 name <- Env.freshName
282 name <- Env.freshName
259− optBranches <- T.traverse (optimizeBranch context name) branches
283+ optBranches <- T.traverse (optimizeBranch context region name) branches
260− optCase <- Case.optimize variantDict region name optBranches
284+ let optCase = Case.optimize variantDict name optBranches
261 return $ Opt.Let [ Opt.Def Opt.dummyFacts name optExpr ] optCase
285 return $ Opt.Let [ Opt.Def Opt.dummyFacts name optExpr ] optCase
263 Expr.Data name exprs ->
287 Expr.Data name exprs ->
@@ -302,19 +326,40 @@ mapSnd func (x, a) =
303optimizeBranch
327optimizeBranch
304 :: Context
328 :: Context
305 -> String
330 -> String
306 -> (P.CanonicalPattern, Can.Expr)
331 -> (P.CanonicalPattern, Can.Expr)
307 -> Env.Optimizer (P.CanonicalPattern, Opt.Expr)
332 -> Env.Optimizer (P.CanonicalPattern, Opt.Expr)
308−optimizeBranch context exprName (pattern, canonicalExpr) =
333+optimizeBranch context region exprName (rawPattern, canBranch) =
311 Opt.Var (Var.Canonical Var.Local exprName)
336 Opt.Var (Var.Canonical Var.Local exprName)
314− Map.fromList (patternToSubstitutions root pattern)
316− do optExpr <- optimizeExpr context canonicalExpr
338+ do optBranch <- optimizeExpr context canBranch
339+ (pattern, branch) <- tagCrashBranch region rawPattern optBranch
342+ Map.fromList (patternToSubstitutions root pattern)
317− (,) pattern <$> Inline.inline substitutions optExpr
344+ (,) pattern <$> Inline.inline substitutions branch
349+ -> P.CanonicalPattern
351+ -> Env.Optimizer (P.CanonicalPattern, Opt.Expr)
352+tagCrashBranch region pattern@(A.A pr _) expr =
354+ Opt.Call (Opt.Crash home _ _) [arg] ->
355+ do name <- Env.freshName
357+ ( A.A pr (P.Alias name pattern)
358+ , Opt.Call (Opt.Crash home region (Just (Opt.Var (Var.local name)))) [arg]
362+ return (pattern, expr)
320-- DETECT TAIL CALL
365-- DETECT TAIL CALL