2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
4 %************************************************************************
6 \section[SAT]{Static Argument Transformation pass}
8 %************************************************************************
10 May be seen as removing invariants from loops:
11 Arguments of recursive functions that do not change in recursive
12 calls are removed from the recursion, which is done locally
13 and only passes the arguments which effectively change.
16 map = /\ ab -> \f -> \xs -> case xs of
18 (a:b) -> f a : map f b
20 as map is recursively called with the same argument f (unmodified)
23 map = /\ ab -> \f -> \xs -> let map' ys = case ys of
28 Notice that for a compiler that uses lambda lifting this is
29 useless as map' will be transformed back to what map was.
31 We could possibly do the same for big lambdas, but we don't as
32 they will eventually be removed in later stages of the compiler,
33 therefore there is no penalty in keeping them.
35 Experimental Evidence: Heap: +/- 7%
36 Instrs: Always improves for 2 or more Static Args.
39 #include "HsVersions.h"
44 -- and to make the interface self-sufficient...
45 PlainCoreProgram(..), CoreExpr, CoreBinding, Id
49 import Maybes ( Maybe(..) )
57 doStaticArgs :: PlainCoreProgram -> SplitUniqSupply -> PlainCoreProgram
60 = initSAT (mapSAT sat_bind binds)
62 sat_bind (CoNonRec binder expr)
63 = emptyEnvSAT `thenSAT_`
64 satExpr expr `thenSAT` (\ expr' ->
65 returnSAT (CoNonRec binder expr') )
66 sat_bind (CoRec [(binder,rhs)])
67 = emptyEnvSAT `thenSAT_`
68 insSAEnv binder (getArgLists rhs) `thenSAT_`
69 satExpr rhs `thenSAT` (\ rhs' ->
70 saTransform binder rhs')
71 sat_bind (CoRec pairs)
72 = emptyEnvSAT `thenSAT_`
73 mapSAT satExpr rhss `thenSAT` \ rhss' ->
74 returnSAT (CoRec (binders `zip` rhss'))
76 (binders, rhss) = unzip pairs
81 = updSAEnv (Just (v,([],[]))) `thenSAT_`
84 satAtom _ = returnSAT ()
88 satExpr :: PlainCoreExpr -> SatM PlainCoreExpr
91 = updSAEnv (Just (v,([],[]))) `thenSAT_`
94 satExpr lit@(CoLit _) = returnSAT lit
96 satExpr e@(CoCon con types args)
97 = mapSAT satAtom args `thenSAT_`
100 satExpr e@(CoPrim prim ty args)
101 = mapSAT satAtom args `thenSAT_`
104 satExpr (CoLam binders body)
105 = satExpr body `thenSAT` \ body' ->
106 returnSAT (CoLam binders body')
108 satExpr (CoTyLam tyvar body)
109 = satExpr body `thenSAT` (\ body' ->
110 returnSAT (CoTyLam tyvar body') )
112 satExpr app@(CoApp _ _)
115 satExpr app@(CoTyApp _ _)
118 satExpr (CoCase expr alts)
119 = satExpr expr `thenSAT` \ expr' ->
120 sat_alts alts `thenSAT` \ alts' ->
121 returnSAT (CoCase expr' alts')
123 sat_alts (CoAlgAlts alts deflt)
124 = mapSAT satAlgAlt alts `thenSAT` \ alts' ->
125 sat_default deflt `thenSAT` \ deflt' ->
126 returnSAT (CoAlgAlts alts' deflt')
128 satAlgAlt (con, params, rhs)
129 = satExpr rhs `thenSAT` \ rhs' ->
130 returnSAT (con, params, rhs')
132 sat_alts (CoPrimAlts alts deflt)
133 = mapSAT satPrimAlt alts `thenSAT` \ alts' ->
134 sat_default deflt `thenSAT` \ deflt' ->
135 returnSAT (CoPrimAlts alts' deflt')
137 satPrimAlt (lit, rhs)
138 = satExpr rhs `thenSAT` \ rhs' ->
139 returnSAT (lit, rhs')
141 sat_default CoNoDefault
142 = returnSAT CoNoDefault
143 sat_default (CoBindDefault binder rhs)
144 = satExpr rhs `thenSAT` \ rhs' ->
145 returnSAT (CoBindDefault binder rhs')
147 satExpr (CoLet (CoNonRec binder rhs) body)
148 = satExpr body `thenSAT` \ body' ->
149 satExpr rhs `thenSAT` \ rhs' ->
150 returnSAT (CoLet (CoNonRec binder rhs') body')
152 satExpr (CoLet (CoRec [(binder,rhs)]) body)
153 = satExpr body `thenSAT` \ body' ->
154 insSAEnv binder (getArgLists rhs) `thenSAT_`
155 satExpr rhs `thenSAT` \ rhs' ->
156 saTransform binder rhs' `thenSAT` \ binding ->
157 returnSAT (CoLet binding body')
159 satExpr (CoLet (CoRec binds) body)
161 (binders, rhss) = unzip binds
163 satExpr body `thenSAT` \ body' ->
164 mapSAT satExpr rhss `thenSAT` \ rhss' ->
165 returnSAT (CoLet (CoRec (binders `zip` rhss')) body')
167 satExpr (CoSCC cc expr)
168 = satExpr expr `thenSAT` \ expr2 ->
169 returnSAT (CoSCC cc expr2)
175 getAppArgs :: PlainCoreExpr -> SatM PlainCoreExpr
178 = get app `thenSAT` \ (app',result) ->
179 updSAEnv result `thenSAT_`
183 -> SatM (PlainCoreExpr, Maybe (Id, SATInfo))
186 = get e `thenSAT` \ (e',result) ->
191 Just (v,(tv,lv)) -> Just (v,(tv++[Static ty],lv))
195 = get e `thenSAT` \ (e', result) ->
198 (CoVarAtom v) -> Static v
204 Just (v,(tv,lv)) -> Just (v,(tv,lv++[si]))
209 = returnSAT (var, Just (v,([],[])))
212 = satExpr e `thenSAT` \ e2 ->
213 returnSAT (e2, Nothing)