f84a64ee7931a030c749228742f235084cf2ad35
[ghc-hetmet.git] / 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 DynFlags ( DynFlags, DynFlag(..) )
20 import CoreSyn
21 import CoreUtils        ( exprIsHNF, exprIsDupable )
22 import CoreLint         ( showPass, endPass )
23 import CoreFVs          ( CoreExprWithFVs, freeVars, freeVarsOf, idRuleVars )
24 import Id               ( isOneShotBndr )
25 import Var              ( Id, idType )
26 import Type             ( isUnLiftedType )
27 import VarSet
28 import Util             ( zipEqual, zipWithEqual, count )
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 :: DynFlags -> [CoreBind] -> IO [CoreBind]
37
38 floatInwards dflags binds
39   = do {
40         showPass dflags "Float inwards";
41         let { binds' = map fi_top_bind binds };
42         endPass dflags "Float inwards" Opt_D_verbose_core2core binds'   
43                                 {- no specific flag for dumping float-in -} 
44     }
45                           
46   where
47     fi_top_bind (NonRec binder rhs)
48       = NonRec binder (fiExpr [] (freeVars rhs))
49     fi_top_bind (Rec pairs)
50       = Rec [ (b, fiExpr [] (freeVars rhs)) | (b, rhs) <- pairs ]
51 \end{code}
52
53 %************************************************************************
54 %*                                                                      *
55 \subsection{Mail from Andr\'e [edited]}
56 %*                                                                      *
57 %************************************************************************
58
59 {\em Will wrote: What??? I thought the idea was to float as far
60 inwards as possible, no matter what.  This is dropping all bindings
61 every time it sees a lambda of any kind.  Help! }
62
63 You are assuming we DO DO full laziness AFTER floating inwards!  We
64 have to [not float inside lambdas] if we don't.
65
66 If we indeed do full laziness after the floating inwards (we could
67 check the compilation flags for that) then I agree we could be more
68 aggressive and do float inwards past lambdas.
69
70 Actually we are not doing a proper full laziness (see below), which
71 was another reason for not floating inwards past a lambda.
72
73 This can easily be fixed.  The problem is that we float lets outwards,
74 but there are a few expressions which are not let bound, like case
75 scrutinees and case alternatives.  After floating inwards the
76 simplifier could decide to inline the let and the laziness would be
77 lost, e.g.
78
79 \begin{verbatim}
80 let a = expensive             ==> \b -> case expensive of ...
81 in \ b -> case a of ...
82 \end{verbatim}
83 The fix is
84 \begin{enumerate}
85 \item
86 to let bind the algebraic case scrutinees (done, I think) and
87 the case alternatives (except the ones with an
88 unboxed type)(not done, I think). This is best done in the
89 SetLevels.lhs module, which tags things with their level numbers.
90 \item
91 do the full laziness pass (floating lets outwards).
92 \item
93 simplify. The simplifier inlines the (trivial) lets that were
94  created but were not floated outwards.
95 \end{enumerate}
96
97 With the fix I think Will's suggestion that we can gain even more from
98 strictness by floating inwards past lambdas makes sense.
99
100 We still gain even without going past lambdas, as things may be
101 strict in the (new) context of a branch (where it was floated to) or
102 of a let rhs, e.g.
103 \begin{verbatim}
104 let a = something            case x of
105 in case x of                   alt1 -> case something of a -> a + a
106      alt1 -> a + a      ==>    alt2 -> b
107      alt2 -> b
108
109 let a = something           let b = case something of a -> a + a
110 in let b = a + a        ==> in (b,b)
111 in (b,b)
112 \end{verbatim}
113 Also, even if a is not found to be strict in the new context and is
114 still left as a let, if the branch is not taken (or b is not entered)
115 the closure for a is not built.
116
117 %************************************************************************
118 %*                                                                      *
119 \subsection{Main floating-inwards code}
120 %*                                                                      *
121 %************************************************************************
122
123 \begin{code}
124 type FreeVarsSet   = IdSet
125
126 type FloatingBinds = [(CoreBind, FreeVarsSet)]
127         -- In reverse dependency order (innermost binder first)
128
129         -- The FreeVarsSet is the free variables of the binding.  In the case
130         -- of recursive bindings, the set doesn't include the bound
131         -- variables.
132
133 fiExpr :: FloatingBinds         -- Binds we're trying to drop
134                                 -- as far "inwards" as possible
135        -> CoreExprWithFVs       -- Input expr
136        -> CoreExpr              -- Result
137
138 fiExpr to_drop (_, AnnVar v) = mkCoLets' to_drop (Var v)
139
140 fiExpr to_drop (_, AnnType ty) = ASSERT( null to_drop )
141                                  Type ty
142 fiExpr to_drop (_, AnnCast expr co)
143   = Cast (fiExpr to_drop expr) co       -- Just float in past coercion
144
145 fiExpr to_drop (_, AnnLit lit) = Lit lit
146 \end{code}
147
148 Applications: we do float inside applications, mainly because we
149 need to get at all the arguments.  The next simplifier run will
150 pull out any silly ones.
151
152 \begin{code}
153 fiExpr to_drop (_,AnnApp fun arg)
154   = mkCoLets' drop_here (App (fiExpr fun_drop fun) (fiExpr arg_drop arg))
155   where
156     [drop_here, fun_drop, arg_drop] = sepBindsByDropPoint False [freeVarsOf fun, freeVarsOf arg] to_drop
157 \end{code}
158
159 We are careful about lambdas: 
160
161 * We must be careful about floating inside inside a value lambda.  
162   That risks losing laziness.
163   The float-out pass might rescue us, but then again it might not.
164
165 * We must be careful about type lambdas too.  At one time we did, and
166   there is no risk of duplicating work thereby, but we do need to be
167   careful.  In particular, here is a bad case (it happened in the
168   cichelli benchmark:
169         let v = ...
170         in let f = /\t -> \a -> ...
171            ==>
172         let f = /\t -> let v = ... in \a -> ...
173   This is bad as now f is an updatable closure (update PAP)
174   and has arity 0.
175
176 So we treat lambda in groups, using the following rule:
177
178         Float inside a group of lambdas only if
179         they are all either type lambdas or one-shot lambdas.
180
181         Otherwise drop all the bindings outside the group.
182
183 \begin{code}
184         -- Hack alert!  We only float in through one-shot lambdas, 
185         -- not (as you might guess) through big lambdas.  
186         -- Reason: we float *out* past big lambdas (see the test in the Lam
187         -- case of FloatOut.floatExpr) and we don't want to float straight
188         -- back in again.
189         --
190         -- It *is* important to float into one-shot lambdas, however;
191         -- see the remarks with noFloatIntoRhs.
192 fiExpr to_drop lam@(_, AnnLam _ _)
193   | all is_one_shot bndrs       -- Float in
194   = mkLams bndrs (fiExpr to_drop body)
195
196   | otherwise           -- Dump it all here
197   = mkCoLets' to_drop (mkLams bndrs (fiExpr [] body))
198
199   where
200     (bndrs, body) = collectAnnBndrs lam
201 \end{code}
202
203 We don't float lets inwards past an SCC.
204         ToDo: keep info on current cc, and when passing
205         one, if it is not the same, annotate all lets in binds with current
206         cc, change current cc to the new one and float binds into expr.
207
208 \begin{code}
209 fiExpr to_drop (_, AnnNote note@(SCC cc) expr)
210   =     -- Wimp out for now
211     mkCoLets' to_drop (Note note (fiExpr [] expr))
212
213 fiExpr to_drop (_, AnnNote InlineMe expr)
214   =     -- Ditto... don't float anything into an INLINE expression
215     mkCoLets' to_drop (Note InlineMe (fiExpr [] expr))
216
217 fiExpr to_drop (_, AnnNote note@(CoreNote _) expr)
218   = Note note (fiExpr to_drop expr)
219 \end{code}
220
221 For @Lets@, the possible ``drop points'' for the \tr{to_drop}
222 bindings are: (a)~in the body, (b1)~in the RHS of a NonRec binding,
223 or~(b2), in each of the RHSs of the pairs of a @Rec@.
224
225 Note that we do {\em weird things} with this let's binding.  Consider:
226 \begin{verbatim}
227 let
228     w = ...
229 in {
230     let v = ... w ...
231     in ... v .. w ...
232 }
233 \end{verbatim}
234 Look at the inner \tr{let}.  As \tr{w} is used in both the bind and
235 body of the inner let, we could panic and leave \tr{w}'s binding where
236 it is.  But \tr{v} is floatable further into the body of the inner let, and
237 {\em then} \tr{w} will also be only in the body of that inner let.
238
239 So: rather than drop \tr{w}'s binding here, we add it onto the list of
240 things to drop in the outer let's body, and let nature take its
241 course.
242
243 Note [extra_fvs (1): avoid floating into RHS]
244 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
245 Consdider let x=\y....t... in body.  We do not necessarily want to float 
246 a binding for t into the RHS, because it'll immediately be floated out
247 again.  (It won't go inside the lambda else we risk losing work.)
248 In letrec, we need to be more careful still. We don't want to transform
249         let x# = y# +# 1#
250         in
251         letrec f = \z. ...x#...f...
252         in ...
253 into
254         letrec f = let x# = y# +# 1# in \z. ...x#...f... in ...
255 because now we can't float the let out again, because a letrec
256 can't have unboxed bindings.
257
258 So we make "extra_fvs" which is the rhs_fvs of such bindings, and
259 arrange to dump bindings that bind extra_fvs before the entire let.
260
261 Note [extra_fvs (s): free variables of rules]
262 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
263 Consider let x{rule mentioning y} = rhs in body
264 Here y is not free in rhs or body; but we still want to dump bindings
265 that bind y outside the let.  So we augment extra_fvs with the
266 idRuleVars of x.
267
268
269 \begin{code}
270 fiExpr to_drop (_,AnnLet (AnnNonRec id rhs@(rhs_fvs, ann_rhs)) body)
271   = fiExpr new_to_drop body
272   where
273     body_fvs = freeVarsOf body
274
275     rule_fvs = idRuleVars id    -- See Note [extra_fvs (2): free variables of rules]
276     extra_fvs | noFloatIntoRhs ann_rhs
277               || isUnLiftedType (idType id) = rule_fvs `unionVarSet` rhs_fvs
278               | otherwise                   = rule_fvs
279         -- See Note [extra_fvs (2): avoid floating into RHS]
280         -- No point in floating in only to float straight out again
281         -- Ditto ok-for-speculation unlifted RHSs
282
283     [shared_binds, extra_binds, rhs_binds, body_binds] 
284         = sepBindsByDropPoint False [extra_fvs, rhs_fvs, body_fvs] to_drop
285
286     new_to_drop = body_binds ++                         -- the bindings used only in the body
287                   [(NonRec id rhs', rhs_fvs')] ++       -- the new binding itself
288                   extra_binds ++                        -- bindings from extra_fvs
289                   shared_binds                          -- the bindings used both in rhs and body
290
291         -- Push rhs_binds into the right hand side of the binding
292     rhs'     = fiExpr rhs_binds rhs
293     rhs_fvs' = rhs_fvs `unionVarSet` floatedBindsFVs rhs_binds
294
295 fiExpr to_drop (_,AnnLet (AnnRec bindings) body)
296   = fiExpr new_to_drop body
297   where
298     rhss = map snd bindings
299
300     rhss_fvs = map freeVarsOf rhss
301     body_fvs = freeVarsOf body
302
303         -- See Note [extra_fvs (1,2)]
304     extra_fvs = foldr (unionVarSet . get_extras) emptyVarSet bindings
305     get_extras (id, (rhs_fvs, rhs)) 
306         | noFloatIntoRhs rhs = idRuleVars id `unionVarSet` rhs_fvs
307         | otherwise          = idRuleVars id
308
309     (shared_binds:extra_binds:body_binds:rhss_binds) 
310         = sepBindsByDropPoint False (extra_fvs:body_fvs:rhss_fvs) to_drop
311
312     new_to_drop = body_binds ++         -- the bindings used only in the body
313                   [(Rec (fi_bind rhss_binds bindings), rhs_fvs')] ++
314                                         -- The new binding itself
315                   extra_binds ++        -- Note [extra_fvs (1,2)]
316                   shared_binds          -- Used in more than one place
317
318     rhs_fvs' = unionVarSet (unionVarSets rhss_fvs)
319                            (unionVarSets (map floatedBindsFVs rhss_binds))
320
321     -- Push rhs_binds into the right hand side of the binding
322     fi_bind :: [FloatingBinds]      -- one per "drop pt" conjured w/ fvs_of_rhss
323             -> [(Id, CoreExprWithFVs)]
324             -> [(Id, CoreExpr)]
325
326     fi_bind to_drops pairs
327       = [ (binder, fiExpr to_drop rhs) 
328         | ((binder, rhs), to_drop) <- zipEqual "fi_bind" pairs to_drops ]
329 \end{code}
330
331 For @Case@, the possible ``drop points'' for the \tr{to_drop}
332 bindings are: (a)~inside the scrutinee, (b)~inside one of the
333 alternatives/default [default FVs always {\em first}!].
334
335 \begin{code}
336 fiExpr to_drop (_, AnnCase scrut case_bndr ty alts)
337   = mkCoLets' drop_here1 $
338     mkCoLets' drop_here2 $
339     Case (fiExpr scrut_drops scrut) case_bndr ty
340          (zipWith fi_alt alts_drops_s alts)
341   where
342         -- Float into the scrut and alts-considered-together just like App
343     [drop_here1, scrut_drops, alts_drops] = sepBindsByDropPoint False [scrut_fvs, all_alts_fvs] to_drop
344
345         -- Float into the alts with the is_case flag set
346     (drop_here2 : alts_drops_s)           = sepBindsByDropPoint True alts_fvs alts_drops
347
348     scrut_fvs    = freeVarsOf scrut
349     alts_fvs     = map alt_fvs alts
350     all_alts_fvs = unionVarSets alts_fvs
351     alt_fvs (con, args, rhs) = foldl delVarSet (freeVarsOf rhs) (case_bndr:args)
352                                 -- Delete case_bndr and args from free vars of rhs 
353                                 -- to get free vars of alt
354
355     fi_alt to_drop (con, args, rhs) = (con, args, fiExpr to_drop rhs)
356
357 noFloatIntoRhs (AnnNote InlineMe _) = True
358 noFloatIntoRhs (AnnLam b _)         = not (is_one_shot b)
359         -- IMPORTANT: don't say 'True' for a RHS with a one-shot lambda at the top.
360         -- This makes a big difference for things like
361         --      f x# = let x = I# x#
362         --             in let j = \() -> ...x...
363         --                in if <condition> then normal-path else j ()
364         -- If x is used only in the error case join point, j, we must float the
365         -- boxing constructor into it, else we box it every time which is very bad
366         -- news indeed.
367
368 noFloatIntoRhs rhs = exprIsHNF (deAnnotate' rhs)        -- We'd just float right back out again...
369
370 is_one_shot b = isId b && isOneShotBndr b
371 \end{code}
372
373
374 %************************************************************************
375 %*                                                                      *
376 \subsection{@sepBindsByDropPoint@}
377 %*                                                                      *
378 %************************************************************************
379
380 This is the crucial function.  The idea is: We have a wad of bindings
381 that we'd like to distribute inside a collection of {\em drop points};
382 insides the alternatives of a \tr{case} would be one example of some
383 drop points; the RHS and body of a non-recursive \tr{let} binding
384 would be another (2-element) collection.
385
386 So: We're given a list of sets-of-free-variables, one per drop point,
387 and a list of floating-inwards bindings.  If a binding can go into
388 only one drop point (without suddenly making something out-of-scope),
389 in it goes.  If a binding is used inside {\em multiple} drop points,
390 then it has to go in a you-must-drop-it-above-all-these-drop-points
391 point.
392
393 We have to maintain the order on these drop-point-related lists.
394
395 \begin{code}
396 sepBindsByDropPoint
397     :: Bool                 -- True <=> is case expression
398     -> [FreeVarsSet]        -- One set of FVs per drop point
399     -> FloatingBinds        -- Candidate floaters
400     -> [FloatingBinds]      -- FIRST one is bindings which must not be floated
401                             -- inside any drop point; the rest correspond
402                             -- one-to-one with the input list of FV sets
403
404 -- Every input floater is returned somewhere in the result;
405 -- none are dropped, not even ones which don't seem to be
406 -- free in *any* of the drop-point fvs.  Why?  Because, for example,
407 -- a binding (let x = E in B) might have a specialised version of
408 -- x (say x') stored inside x, but x' isn't free in E or B.
409
410 type DropBox = (FreeVarsSet, FloatingBinds)
411
412 sepBindsByDropPoint is_case drop_pts []
413   = [] : [[] | p <- drop_pts]   -- cut to the chase scene; it happens
414
415 sepBindsByDropPoint is_case drop_pts floaters
416   = go floaters (map (\fvs -> (fvs, [])) (emptyVarSet : drop_pts))
417   where
418     go :: FloatingBinds -> [DropBox] -> [FloatingBinds]
419         -- The *first* one in the argument list is the drop_here set
420         -- The FloatingBinds in the lists are in the reverse of
421         -- the normal FloatingBinds order; that is, they are the right way round!
422
423     go [] drop_boxes = map (reverse . snd) drop_boxes
424
425     go (bind_w_fvs@(bind, bind_fvs) : binds) drop_boxes@(here_box : fork_boxes)
426         = go binds new_boxes
427         where
428           -- "here" means the group of bindings dropped at the top of the fork
429
430           (used_here : used_in_flags) = [ any (`elemVarSet` fvs) (bindersOf bind)
431                                         | (fvs, drops) <- drop_boxes]
432
433           drop_here = used_here || not can_push
434
435                 -- For case expressions we duplicate the binding if it is
436                 -- reasonably small, and if it is not used in all the RHSs
437                 -- This is good for situations like
438                 --      let x = I# y in
439                 --      case e of
440                 --        C -> error x
441                 --        D -> error x
442                 --        E -> ...not mentioning x...
443
444           n_alts      = length used_in_flags
445           n_used_alts = count id used_in_flags -- returns number of Trues in list.
446
447           can_push = n_used_alts == 1           -- Used in just one branch
448                    || (is_case &&               -- We are looking at case alternatives
449                        n_used_alts > 1 &&       -- It's used in more than one
450                        n_used_alts < n_alts &&  -- ...but not all
451                        bindIsDupable bind)      -- and we can duplicate the binding
452
453           new_boxes | drop_here = (insert here_box : fork_boxes)
454                     | otherwise = (here_box : new_fork_boxes)
455
456           new_fork_boxes = zipWithEqual "FloatIn.sepBinds" insert_maybe fork_boxes used_in_flags
457
458           insert :: DropBox -> DropBox
459           insert (fvs,drops) = (fvs `unionVarSet` bind_fvs, bind_w_fvs:drops)
460
461           insert_maybe box True  = insert box
462           insert_maybe box False = box
463
464
465 floatedBindsFVs :: FloatingBinds -> FreeVarsSet
466 floatedBindsFVs binds = unionVarSets (map snd binds)
467
468 mkCoLets' :: FloatingBinds -> CoreExpr -> CoreExpr
469 mkCoLets' to_drop e = foldl (flip (Let . fst)) e to_drop
470         -- Remember to_drop is in *reverse* dependency order
471
472 bindIsDupable (Rec prs)    = all (exprIsDupable . snd) prs
473 bindIsDupable (NonRec b r) = exprIsDupable r
474 \end{code}