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 AST.Variable as Var
14import qualified Optimize.Environment as Env
18inline :: Map.Map Text Opt.Expr -> Opt.Expr -> Env.Optimizer Opt.Expr
19inline rawSubs expression =
25 Map.toList (Map.intersectionWith (,) counts rawSubs)
27 do (Subs subs defs) <- foldM processSubs (Subs Map.empty []) annotatedSubs
28 let inlinedExpr = replace subs expression
34 Let (map (\(name, expr) -> Opt.Def Opt.dummyFacts name expr) 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.Var (Var.local 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
64getDefName :: Opt.Def -> Text
70 Opt.TailDef _ name _ _ ->
75-- COUNT VARIABLE APPEARANCES
78count :: Opt.Expr -> Map.Map Text Int
82 Map.unionWith (+) (count a) (count b)
85 Map.unionsWith (+) (map count xs)
91 Var (Var.Canonical home name) ->
108 Binop _op left right ->
111 Function args body ->
112 deleteBatch args (count body)
115 Map.unionWith (+) (count func) (countMany args)
117 TailCall _name _argNames args ->
120 If branches finally ->
121 Map.unionsWith (+) (count finally : map (uncurry count2) branches)
127 Opt.Def _ name body ->
128 Map.delete name (count body)
130 Opt.TailDef _ name argNames body ->
131 deleteBatch (name:argNames) (count body)
134 deleteBatch (map getDefName defs) (count expr)
136 Map.unionsWith (+) (exprCount : map countDef defs)
138 Case _ decider jumps ->
142 Leaf (Inline expr) ->
148 Chain _ success failure ->
149 Map.unionWith (+) (countDecider success) (countDecider failure)
151 FanOut _path tests fallback ->
152 Map.unionsWith (+) (map countDecider (fallback : map snd tests))
154 Map.unionsWith (+) (countDecider decider : map (count . snd) jumps)
159 CtorAccess root _index ->
162 Access record _field ->
165 Update record fields ->
166 Map.unionWith (+) (count record) (countMany (map snd fields))
169 countMany (map snd fields)
189 Crash _ _ maybeBranchProblem ->
190 maybe Map.empty count maybeBranchProblem
197replace :: Map.Map Text Opt.Expr -> Opt.Expr -> Opt.Expr
198replace substitutions expression =
200 go = replace substitutions
206 Var (Var.Canonical Var.Local name) ->
207 maybe expression id (Map.lookup name substitutions)
215 Binop op left right ->
216 Binop op (go left) (go right)
218 Function args body ->
219 Function args (replace (deleteBatch args substitutions) body)
222 Call (go func) (map go args)
224 TailCall name argNames args ->
225 TailCall name argNames (map go args)
227 If branches finally ->
228 If (map (go *** go) branches) (go finally)
234 Opt.Def facts name body ->
236 (replace (Map.delete name substitutions) body)
238 Opt.TailDef facts name argNames body ->
239 Opt.TailDef facts name argNames
240 (replace (deleteBatch (name:argNames) substitutions) body)
246 (map replaceDef defs)
247 (replace (deleteBatch boundNames substitutions) expr)
249 Case exprName decider jumps ->
253 Leaf (Inline expr) ->
254 Leaf (Inline (go expr))
256 Leaf (Jump _target) ->
259 Chain chain success failure ->
260 Chain chain (goDecider success) (goDecider failure)
262 FanOut path tests fallback ->
263 FanOut path (map (second goDecider) tests) (goDecider fallback)
265 Case exprName (goDecider decider) (map (second go) jumps)
268 Ctor tag (map go values)
270 CtorAccess root index ->
271 CtorAccess (go root) index
273 Access record field ->
274 Access (go record) field
276 Update record fields ->
277 Update (go record) (map (second go) fields)
280 Record (map (second go) fields)
295 Program kind (go expr)
300 Crash home region maybeBranchProblem ->
301 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