53188bac738dbc4c252a86fe4040d1b8fe8dab5d
[ghc-hetmet.git] / ghc / compiler / simplCore / FloatIn.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 %************************************************************************
5 %*                                                                      *
6 \section[FloatIn]{Floating Inwards pass}
7 %*                                                                      *
8 %************************************************************************
9
10 The main purpose of @floatInwards@ is floating into branches of a
11 case, so that we don't allocate things, save them on the stack, and
12 then discover that they aren't needed in the chosen branch.
13
14 \begin{code}
15 module FloatIn ( floatInwards ) where
16
17 #include "HsVersions.h"
18
19 import CmdLineOpts      ( opt_D_verbose_core2core )
20 import CoreSyn
21 import CoreLint         ( beginPass, endPass )
22 import Const            ( isDataCon )
23 import CoreFVs          ( CoreExprWithFVs, freeVars, freeVarsOf )
24 import Id               ( isOneShotLambda )
25 import Var              ( Id, idType, isTyVar )
26 import Type             ( isUnLiftedType )
27 import VarSet
28 import Util             ( zipEqual )
29 import Outputable
30 \end{code}
31
32 Top-level interface function, @floatInwards@.  Note that we do not
33 actually float any bindings downwards from the top-level.
34
35 \begin{code}
36 floatInwards :: [CoreBind] -> IO [CoreBind]
37
38 floatInwards binds
39   = do {
40         beginPass "Float inwards";
41         let { binds' = map fi_top_bind binds };
42         endPass "Float inwards" 
43                 opt_D_verbose_core2core         {- no specific flag for dumping float-in -} 
44                 binds'  
45     }
46                           
47   where
48     fi_top_bind (NonRec binder rhs)
49       = NonRec binder (fiExpr [] (freeVars rhs))
50     fi_top_bind (Rec pairs)
51       = Rec [ (b, fiExpr [] (freeVars rhs)) | (b, rhs) <- pairs ]
52 \end{code}
53
54 %************************************************************************
55 %*                                                                      *
56 \subsection{Mail from Andr\'e [edited]}
57 %*                                                                      *
58 %************************************************************************
59
60 {\em Will wrote: What??? I thought the idea was to float as far
61 inwards as possible, no matter what.  This is dropping all bindings
62 every time it sees a lambda of any kind.  Help! }
63
64 You are assuming we DO DO full laziness AFTER floating inwards!  We
65 have to [not float inside lambdas] if we don't.
66
67 If we indeed do full laziness after the floating inwards (we could
68 check the compilation flags for that) then I agree we could be more
69 aggressive and do float inwards past lambdas.
70
71 Actually we are not doing a proper full laziness (see below), which
72 was another reason for not floating inwards past a lambda.
73
74 This can easily be fixed.  The problem is that we float lets outwards,
75 but there are a few expressions which are not let bound, like case
76 scrutinees and case alternatives.  After floating inwards the
77 simplifier could decide to inline the let and the laziness would be
78 lost, e.g.
79
80 \begin{verbatim}
81 let a = expensive             ==> \b -> case expensive of ...
82 in \ b -> case a of ...
83 \end{verbatim}
84 The fix is
85 \begin{enumerate}
86 \item
87 to let bind the algebraic case scrutinees (done, I think) and
88 the case alternatives (except the ones with an
89 unboxed type)(not done, I think). This is best done in the
90 SetLevels.lhs module, which tags things with their level numbers.
91 \item
92 do the full laziness pass (floating lets outwards).
93 \item
94 simplify. The simplifier inlines the (trivial) lets that were
95  created but were not floated outwards.
96 \end{enumerate}
97
98 With the fix I think Will's suggestion that we can gain even more from
99 strictness by floating inwards past lambdas makes sense.
100
101 We still gain even without going past lambdas, as things may be
102 strict in the (new) context of a branch (where it was floated to) or
103 of a let rhs, e.g.
104 \begin{verbatim}
105 let a = something            case x of
106 in case x of                   alt1 -> case something of a -> a + a
107      alt1 -> a + a      ==>    alt2 -> b
108      alt2 -> b
109
110 let a = something           let b = case something of a -> a + a
111 in let b = a + a        ==> in (b,b)
112 in (b,b)
113 \end{verbatim}
114 Also, even if a is not found to be strict in the new context and is
115 still left as a let, if the branch is not taken (or b is not entered)
116 the closure for a is not built.
117
118 %************************************************************************
119 %*                                                                      *
120 \subsection{Main floating-inwards code}
121 %*                                                                      *
122 %************************************************************************
123
124 \begin{code}
125 type FreeVarsSet   = IdSet
126
127 type FloatingBinds = [(CoreBind, FreeVarsSet)]
128         -- In reverse dependency order (innermost bindiner first)
129
130         -- The FreeVarsSet is the free variables of the binding.  In the case
131         -- of recursive bindings, the set doesn't include the bound
132         -- variables.
133
134 fiExpr :: FloatingBinds         -- Binds we're trying to drop
135                                 -- as far "inwards" as possible
136        -> CoreExprWithFVs       -- Input expr
137        -> CoreExpr              -- Result
138
139 fiExpr to_drop (_, AnnVar v) = mkCoLets' to_drop (Var v)
140
141 fiExpr to_drop (_, AnnType ty) = ASSERT( null to_drop )
142                                  Type ty
143
144 fiExpr to_drop (_, AnnCon c args)
145    = mkCoLets' drop_here (Con c args')
146    where
147      (drop_here : arg_drops) = sepBindsByDropPoint (map freeVarsOf args) to_drop
148      args'                   = zipWith fiExpr arg_drops args
149 \end{code}
150
151 Applications: we do float inside applications, mainly because we
152 need to get at all the arguments.  The next simplifier run will
153 pull out any silly ones.
154
155 \begin{code}
156 fiExpr to_drop (_,AnnApp fun arg)
157   = mkCoLets' drop_here (App (fiExpr fun_drop fun) (fiExpr arg_drop arg))
158   where
159     [drop_here, fun_drop, arg_drop] = sepBindsByDropPoint [freeVarsOf fun, freeVarsOf arg] to_drop
160 \end{code}
161
162 We are careful about lambdas: 
163
164 * We must be careful about floating inside inside a value lambda.  
165   That risks losing laziness.
166   The float-out pass might rescue us, but then again it might not.
167
168 * We must be careful about type lambdas too.  At one time we did, and
169   there is no risk of duplicating work thereby, but we do need to be
170   careful.  In particular, here is a bad case (it happened in the
171   cichelli benchmark:
172         let v = ...
173         in let f = /\t -> \a -> ...
174            ==>
175         let f = /\t -> let v = ... in \a -> ...
176   This is bad as now f is an updatable closure (update PAP)
177   and has arity 0.
178
179 So we treat lambda in groups, using the following rule:
180
181         Float inside a group of lambdas only if
182         they are all either type lambdas or one-shot lambdas.
183
184         Otherwise drop all the bindings outside the group.
185
186 \begin{code}
187 fiExpr to_drop (_, AnnLam b body)
188   = case collect [b] body of
189       (bndrs, real_body)
190         | all is_ok bndrs -> mkLams bndrs (fiExpr to_drop real_body)
191         | otherwise       -> mkCoLets' to_drop (mkLams bndrs (fiExpr [] real_body))
192   where
193     collect bs (_, AnnLam b body) = collect (b:bs) body
194     collect bs body               = (reverse bs, body)
195
196     is_ok bndr = isTyVar bndr || isOneShotLambda bndr
197 \end{code}
198
199 We don't float lets inwards past an SCC.
200         ToDo: keep info on current cc, and when passing
201         one, if it is not the same, annotate all lets in binds with current
202         cc, change current cc to the new one and float binds into expr.
203
204 \begin{code}
205 fiExpr to_drop (_, AnnNote note@(SCC cc) expr)
206   =     -- Wimp out for now
207     mkCoLets' to_drop (Note note (fiExpr [] expr))
208
209 fiExpr to_drop (_, AnnNote InlineCall expr)
210   =     -- Wimp out for InlineCall; keep it close
211         -- the the call it annotates
212     mkCoLets' to_drop (Note InlineCall (fiExpr [] expr))
213
214 fiExpr to_drop (_, AnnNote InlineMe expr)
215   =     -- Ditto... don't float anything into an INLINE expression
216     mkCoLets' to_drop (Note InlineMe (fiExpr [] expr))
217
218 fiExpr to_drop (_, AnnNote note@(Coerce _ _) expr)
219   =     -- Just float in past coercion
220     Note note (fiExpr to_drop expr)
221
222 fiExpr to_drop (_, AnnNote note@(TermUsg _) expr)
223   =     -- Float in past term usage annotation
224         -- (for now; not sure if this is correct: KSW 1999-05)
225     Note note (fiExpr to_drop expr)
226 \end{code}
227
228 For @Lets@, the possible ``drop points'' for the \tr{to_drop}
229 bindings are: (a)~in the body, (b1)~in the RHS of a NonRec binding,
230 or~(b2), in each of the RHSs of the pairs of a @Rec@.
231
232 Note that we do {\em weird things} with this let's binding.  Consider:
233 \begin{verbatim}
234 let
235     w = ...
236 in {
237     let v = ... w ...
238     in ... v .. w ...
239 }
240 \end{verbatim}
241 Look at the inner \tr{let}.  As \tr{w} is used in both the bind and
242 body of the inner let, we could panic and leave \tr{w}'s binding where
243 it is.  But \tr{v} is floatable further into the body of the inner let, and
244 {\em then} \tr{w} will also be only in the body of that inner let.
245
246 So: rather than drop \tr{w}'s binding here, we add it onto the list of
247 things to drop in the outer let's body, and let nature take its
248 course.
249
250 \begin{code}
251 fiExpr to_drop (_,AnnLet (AnnNonRec id rhs@(rhs_fvs, ann_rhs)) body)
252   = fiExpr new_to_drop body
253   where
254     body_fvs = freeVarsOf body
255
256     final_body_fvs | noFloatIntoRhs ann_rhs
257                    || isUnLiftedType (idType id) = body_fvs `unionVarSet` rhs_fvs
258                    | otherwise                   = body_fvs
259         -- See commments with letrec below
260         -- No point in floating in only to float straight out again
261         -- Ditto ok-for-speculation unlifted RHSs
262
263     [shared_binds, rhs_binds, body_binds] = sepBindsByDropPoint [rhs_fvs, final_body_fvs] to_drop
264
265     new_to_drop = body_binds ++                         -- the bindings used only in the body
266                   [(NonRec id rhs', rhs_fvs')] ++       -- the new binding itself
267                   shared_binds                          -- the bindings used both in rhs and body
268
269         -- Push rhs_binds into the right hand side of the binding
270     rhs'     = fiExpr rhs_binds rhs
271     rhs_fvs' = rhs_fvs `unionVarSet` floatedBindsFVs rhs_binds
272
273 fiExpr to_drop (_,AnnLet (AnnRec bindings) body)
274   = fiExpr new_to_drop body
275   where
276     (binders, rhss) = unzip bindings
277
278     rhss_fvs = map freeVarsOf rhss
279     body_fvs = freeVarsOf body
280
281         -- Add to body_fvs the free vars of any RHS that has
282         -- a lambda at the top.  This has the effect of making it seem
283         -- that such things are used in the body as well, and hence prevents
284         -- them getting floated in.  The big idea is to avoid turning:
285         --      let x# = y# +# 1#
286         --      in
287         --      letrec f = \z. ...x#...f...
288         --      in ...
289         -- into
290         --      letrec f = let x# = y# +# 1# in \z. ...x#...f... in ...
291         -- 
292         -- Because now we can't float the let out again, because a letrec
293         -- can't have unboxed bindings.
294
295     final_body_fvs = foldr (unionVarSet . get_extras) body_fvs rhss
296     get_extras (rhs_fvs, rhs) | noFloatIntoRhs rhs = rhs_fvs
297                               | otherwise          = emptyVarSet
298
299     (shared_binds:body_binds:rhss_binds) = sepBindsByDropPoint (final_body_fvs:rhss_fvs) to_drop
300
301     new_to_drop = -- the bindings used only in the body
302                   body_binds ++
303                   -- the new binding itself
304                   [(Rec (fi_bind rhss_binds bindings), rhs_fvs')] ++
305                   -- the bindings used both in rhs and body or in more than one rhs
306                   shared_binds
307
308     rhs_fvs' = unionVarSet (unionVarSets rhss_fvs)
309                            (unionVarSets (map floatedBindsFVs rhss_binds))
310
311     -- Push rhs_binds into the right hand side of the binding
312     fi_bind :: [FloatingBinds]      -- one per "drop pt" conjured w/ fvs_of_rhss
313             -> [(Id, CoreExprWithFVs)]
314             -> [(Id, CoreExpr)]
315
316     fi_bind to_drops pairs
317       = [ (binder, fiExpr to_drop rhs) 
318         | ((binder, rhs), to_drop) <- zipEqual "fi_bind" pairs to_drops ]
319 \end{code}
320
321 For @Case@, the possible ``drop points'' for the \tr{to_drop}
322 bindings are: (a)~inside the scrutinee, (b)~inside one of the
323 alternatives/default [default FVs always {\em first}!].
324
325 \begin{code}
326 fiExpr to_drop (_, AnnCase scrut case_bndr alts)
327   = mkCoLets' drop_here (Case (fiExpr scrut_drops scrut) case_bndr
328                               (zipWith fi_alt alts_drops alts))
329   where
330     (drop_here : scrut_drops : alts_drops) = sepBindsByDropPoint (scrut_fvs : alts_fvs) to_drop
331     scrut_fvs = freeVarsOf scrut
332     alts_fvs  = map alt_fvs alts
333     alt_fvs (con, args, rhs) = foldl delVarSet (freeVarsOf rhs) (case_bndr:args)
334                                 -- Delete case_bndr and args from free vars of rhs 
335                                 -- to get free vars of alt
336
337     fi_alt to_drop (con, args, rhs) = (con, args, fiExpr to_drop rhs)
338
339 noFloatIntoRhs (AnnNote InlineMe _) = True
340 noFloatIntoRhs (AnnLam _ _)         = True
341 noFloatIntoRhs (AnnCon con _)       = isDataCon con
342 noFloatIntoRhs other                = False
343 \end{code}
344
345
346 %************************************************************************
347 %*                                                                      *
348 \subsection{@sepBindsByDropPoint@}
349 %*                                                                      *
350 %************************************************************************
351
352 This is the crucial function.  The idea is: We have a wad of bindings
353 that we'd like to distribute inside a collection of {\em drop points};
354 insides the alternatives of a \tr{case} would be one example of some
355 drop points; the RHS and body of a non-recursive \tr{let} binding
356 would be another (2-element) collection.
357
358 So: We're given a list of sets-of-free-variables, one per drop point,
359 and a list of floating-inwards bindings.  If a binding can go into
360 only one drop point (without suddenly making something out-of-scope),
361 in it goes.  If a binding is used inside {\em multiple} drop points,
362 then it has to go in a you-must-drop-it-above-all-these-drop-points
363 point.
364
365 We have to maintain the order on these drop-point-related lists.
366
367 \begin{code}
368 sepBindsByDropPoint
369     :: [FreeVarsSet]        -- One set of FVs per drop point
370     -> FloatingBinds        -- Candidate floaters
371     -> [FloatingBinds]      -- FIRST one is bindings which must not be floated
372                             -- inside any drop point; the rest correspond
373                             -- one-to-one with the input list of FV sets
374
375 -- Every input floater is returned somewhere in the result;
376 -- none are dropped, not even ones which don't seem to be
377 -- free in *any* of the drop-point fvs.  Why?  Because, for example,
378 -- a binding (let x = E in B) might have a specialised version of
379 -- x (say x') stored inside x, but x' isn't free in E or B.
380
381 sepBindsByDropPoint drop_pts []
382   = [] : [[] | p <- drop_pts]   -- cut to the chase scene; it happens
383
384 sepBindsByDropPoint drop_pts floaters
385   = go floaters (map (\fvs -> (fvs, [])) (emptyVarSet : drop_pts))
386   where
387     go :: FloatingBinds -> [(FreeVarsSet, FloatingBinds)] -> [FloatingBinds]
388         -- The *first* one in the argument list is the drop_here set
389         -- The FloatingBinds in the lists are in the reverse of
390         -- the normal FloatingBinds order; that is, they are the right way round!
391
392     go [] drop_boxes = map (reverse . snd) drop_boxes
393
394     go (bind_w_fvs@(bind, bind_fvs) : binds) drop_boxes
395         = go binds (insert drop_boxes (drop_here : used_in_flags))
396                 -- insert puts the find in box whose True flag comes first
397         where
398           (used_here : used_in_flags) = [ any (`elemVarSet` fvs) (bindersOf bind)
399                                         | (fvs, drops) <- drop_boxes]
400
401           drop_here = used_here || not (exactlyOneTrue used_in_flags)
402
403           insert ((fvs,drops) : drop_boxes) (True : _)
404                 = ((fvs `unionVarSet` bind_fvs, bind_w_fvs:drops) : drop_boxes)
405           insert (drop_box : drop_boxes) (False : others)
406                 = drop_box : insert drop_boxes others
407           insert _ _ = panic "sepBindsByDropPoint"      -- Should never happen
408
409 exactlyOneTrue :: [Bool] -> Bool
410 exactlyOneTrue flags = case [() | True <- flags] of
411                         [_]   -> True
412                         other -> False
413
414 floatedBindsFVs :: FloatingBinds -> FreeVarsSet
415 floatedBindsFVs binds = unionVarSets (map snd binds)
416
417 mkCoLets' :: FloatingBinds -> CoreExpr -> CoreExpr
418 mkCoLets' to_drop e = foldl (flip (Let . fst)) e to_drop
419         -- Remember to_drop is in *reverse* dependency order
420 \end{code}