1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
3module Optimize.Inline (inline) where
5import Control.Arrow (second, (***))
6import Control.Monad (foldM)
7import qualified Data.List as List
8import qualified Data.Map as Map
11import AST.Expression.Optimized (Expr(..), Decider(..), Choice(..))
12import qualified AST.Expression.Optimized as Opt
13import qualified Optimize.Environment as Env
17inline :: Map.Map Text Opt.Expr -> Opt.Expr -> Env.Optimizer Opt.Expr
18inline rawSubs expression =
24 Map.toList (Map.intersectionWith (,) counts rawSubs)
26 do (Subs subs defs) <- foldM processSubs (Subs Map.empty []) annotatedSubs
27 let inlinedExpr = replace subs expression
33 Let (map (second Opt.Def) defs) inlinedExpr
38 { _substitutions :: Map.Map Text Opt.Expr
39 , _definitions :: [(Text, Opt.Expr)]
43processSubs :: Subs -> (Text, (Int, Opt.Expr)) -> Env.Optimizer Subs
44processSubs (Subs subs defs) (name, (n, expr)) =
46 return $ Subs (Map.insert name expr subs) defs
49 do uniqueName <- Env.freshName
51 (Map.insert name (Opt.VarLocal uniqueName) subs)
52 ((uniqueName, expr) : defs)
59deleteBatch :: [Text] -> Map.Map Text a -> Map.Map Text a
60deleteBatch names dict =
61 List.foldl' (flip Map.delete) dict names
65-- COUNT VARIABLE APPEARANCES
68count :: Opt.Expr -> Map.Map Text Int
72 Map.unionWith (+) (count a) (count b)
75 Map.unionsWith (+) (map count xs)
94 deleteBatch args (count body)
97 Map.unionWith (+) (count func) (countMany args)
99 TailCall _name _argNames args ->
102 If branches finally ->
103 Map.unionsWith (+) (count finally : map (uncurry count2) branches)
107 countDef (name, def) =
110 Map.delete name (count body)
112 Opt.TailDef argNames body ->
113 deleteBatch (name:argNames) (count body)
116 deleteBatch (map fst defs) (count expr)
118 Map.unionsWith (+) (exprCount : map countDef defs)
120 Case _ decider jumps ->
124 Leaf (Inline expr) ->
130 Chain _ success failure ->
131 Map.unionWith (+) (countDecider success) (countDecider failure)
133 FanOut _path tests fallback ->
134 Map.unionsWith (+) (map countDecider (fallback : map snd tests))
136 Map.unionsWith (+) (countDecider decider : map (count . snd) jumps)
141 CtorAccess root _index ->
144 Access record _field ->
147 Update record fields ->
148 Map.unionWith (+) (count record) (countMany (map snd fields))
151 countMany (map snd fields)
171 Crash _ _ maybeBranchProblem ->
172 maybe Map.empty count maybeBranchProblem
179replace :: Map.Map Text Opt.Expr -> Opt.Expr -> Opt.Expr
180replace substitutions expression =
182 go = replace substitutions
189 maybe expression id (Map.lookup name substitutions)
197 Binop op left right ->
198 Binop op (go left) (go right)
200 Function args body ->
201 Function args (replace (deleteBatch args substitutions) body)
204 Call (go func) (map go args)
206 TailCall name argNames args ->
207 TailCall name argNames (map go args)
209 If branches finally ->
210 If (map (go *** go) branches) (go finally)
214 replaceDef (name, def) =
218 replace (Map.delete name substitutions) body
220 Opt.TailDef argNames body ->
221 (,) name $ Opt.TailDef argNames $
222 replace (deleteBatch (name:argNames) substitutions) body
228 (map replaceDef defs)
229 (replace (deleteBatch boundNames substitutions) expr)
231 Case exprName decider jumps ->
235 Leaf (Inline expr) ->
236 Leaf (Inline (go expr))
238 Leaf (Jump _target) ->
241 Chain chain success failure ->
242 Chain chain (goDecider success) (goDecider failure)
244 FanOut path tests fallback ->
245 FanOut path (map (second goDecider) tests) (goDecider fallback)
247 Case exprName (goDecider decider) (map (second go) jumps)
250 Ctor tag (map go values)
252 CtorAccess root index ->
253 CtorAccess (go root) index
255 Access record field ->
256 Access (go record) field
258 Update record fields ->
259 Update (go record) (map (second go) fields)
262 Record (map (second go) fields)
277 Program kind (go expr)
282 Crash home region maybeBranchProblem ->
283 Crash home region (fmap go maybeBranchProblem)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list