[project @ 1998-01-08 18:03:08 by simonm]
[ghc-hetmet.git] / ghc / compiler / coreSyn / FreeVars.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 Taken quite directly from the Peyton Jones/Lester paper.
5
6 \begin{code}
7 module FreeVars (
8         freeVars,
9
10         -- cheap and cheerful variant...
11         addTopBindsFVs, addExprFVs,
12
13         freeVarsOf, freeTyVarsOf,
14         FVCoreExpr, FVCoreBinding,
15
16         CoreExprWithFVs,                -- For the above functions
17         AnnCoreExpr,            -- Dito
18         FVInfo(..), LeakInfo(..)
19     ) where
20
21 #include "HsVersions.h"
22
23 import AnnCoreSyn       -- output
24
25 import CoreSyn
26 import Id               ( idType, getIdArity, isBottomingId,
27                           emptyIdSet, unitIdSet, mkIdSet,
28                           elementOfIdSet, minusIdSet, unionManyIdSets,
29                           IdSet, Id
30                         )
31 import IdInfo           ( ArityInfo(..) )
32 import PrimOp           ( PrimOp(..) )
33 import Type             ( tyVarsOfType, Type )
34 import TyVar            ( emptyTyVarSet, unitTyVarSet, minusTyVarSet,
35                           intersectTyVarSets,
36                           TyVarSet, TyVar
37                         )
38 import BasicTypes       ( Unused )
39 import UniqSet          ( unionUniqSets )
40 import Util             ( panic, assertPanic )
41 \end{code}
42
43 %************************************************************************
44 %*                                                                      *
45 \section[freevars-everywhere]{Attaching free variables to every sub-expression
46 %*                                                                      *
47 %************************************************************************
48
49 The free variable pass annotates every node in the expression with its
50 NON-GLOBAL free variables and type variables.
51
52 The ``free type variables'' are defined to be those which are mentioned
53 in type applications, {\em not} ones which lie buried in the types of Ids.
54
55 *** ALAS: we *do* need to collect tyvars from lambda-bound ids. ***
56 I've half-convinced myself we don't for case- and letrec bound ids
57 but I might be wrong. (SLPJ, date unknown)
58
59 \begin{code}
60 type CoreExprWithFVs =  AnnCoreExpr Id Id Unused FVInfo
61
62 type TyVarCands = TyVarSet  -- for when we carry around lists of
63 type IdCands    = IdSet     -- "candidate" TyVars/Ids.
64 noTyVarCands    = emptyTyVarSet
65 noIdCands       = emptyIdSet
66
67 data FVInfo
68   = FVInfo  IdSet       -- Free ids
69             TyVarSet    -- Free tyvars
70             LeakInfo
71
72 noFreeIds      = emptyIdSet
73 noFreeTyVars   = emptyTyVarSet
74 noFreeAnything = (noFreeIds, noFreeTyVars)
75 aFreeId i      = unitIdSet i
76 aFreeTyVar t   = unitTyVarSet t
77 is_among       = elementOfIdSet
78 munge_id_ty  i = tyVarsOfType (idType i)
79 combine        = unionUniqSets -- used both for {Id,TyVar}Sets
80
81 combineFVInfo (FVInfo fvs1 tfvs1 leak1) (FVInfo fvs2 tfvs2 leak2)
82   = FVInfo (fvs1  `combine` fvs2)
83            (tfvs1 `combine` tfvs2)
84            (leak1 `orLeak`  leak2)
85 \end{code}
86
87 Leak-free-ness is based only on the value, not the type.  In
88 particular, nested collections of constructors are guaranteed leak
89 free.  Function applications are not, except for PAPs.
90
91 Applications of error gets (LeakFree bigArity) -- a hack!
92
93 \begin{code}
94 data LeakInfo
95   = MightLeak
96   | LeakFree Int    -- Leak free, and guarantees to absorb this # of
97                     -- args before becoming leaky.
98
99 lEAK_FREE_0   = LeakFree 0
100 lEAK_FREE_BIG = LeakFree bigArity
101               where
102                 bigArity = 1000::Int    -- NB: arbitrary
103
104 orLeak :: LeakInfo -> LeakInfo -> LeakInfo
105 orLeak MightLeak     _           = MightLeak
106 orLeak _             MightLeak   = MightLeak
107 orLeak (LeakFree n) (LeakFree m) = LeakFree (n `min` m)
108 \end{code}
109
110 Main public interface:
111 \begin{code}
112 freeVars :: CoreExpr -> CoreExprWithFVs
113
114 freeVars expr = fvExpr noIdCands noTyVarCands expr
115 \end{code}
116
117 %************************************************************************
118 %*                                                                      *
119 \subsection{Free variables (and types)}
120 %*                                                                      *
121 %************************************************************************
122
123 We do the free-variable stuff by passing around ``candidates lists''
124 of @Ids@ and @TyVars@ that may be considered free.  This is useful,
125 e.g., to avoid considering top-level binders as free variables---don't
126 put them on the candidates list.
127
128 \begin{code}
129
130 fvExpr :: IdCands           -- In-scope Ids
131        -> TyVarCands        -- In-scope tyvars
132        -> CoreExpr
133        -> CoreExprWithFVs
134
135 fvExpr id_cands tyvar_cands (Var v)
136   = (FVInfo (if (v `is_among` id_cands)
137              then aFreeId v
138              else noFreeIds)
139             noFreeTyVars
140             leakiness,
141      AnnVar v)
142   where
143     leakiness
144       | isBottomingId v = lEAK_FREE_BIG -- Hack
145       | otherwise       = case getIdArity v of
146                             UnknownArity       -> lEAK_FREE_0
147                             ArityAtLeast arity -> LeakFree arity
148                             ArityExactly arity -> LeakFree arity
149
150 fvExpr id_cands tyvar_cands (Lit k)
151   = (FVInfo noFreeIds noFreeTyVars lEAK_FREE_0, AnnLit k)
152
153 fvExpr id_cands tyvar_cands (Con c args)
154   = (FVInfo args_fvs tfvs lEAK_FREE_0, AnnCon c args)
155   where
156     (args_fvs, tfvs) = freeArgs id_cands tyvar_cands args
157
158 fvExpr id_cands tyvar_cands (Prim op args)
159   = (FVInfo args_fvs tfvs lEAK_FREE_0, AnnPrim op args)
160   where
161     (args_fvs, tfvs) = freeArgs id_cands tyvar_cands args_to_use{-NB-}
162     args_to_use
163       = case op of
164           CCallOp _ _ _ _ res_ty -> TyArg res_ty : args
165           _                      -> args
166
167 -- this Lam stuff could probably be improved by rewriting (WDP 96/03)
168
169 fvExpr id_cands tyvar_cands (Lam b@(ValBinder binder) body)
170   = (FVInfo (freeVarsOf body2   `minusIdSet` unitIdSet binder)
171             (freeTyVarsOf body2 `combine`    munge_id_ty binder)
172             leakiness,
173      AnnLam b body2)
174   where
175         -- We need to collect free tyvars from the binders
176     body2 = fvExpr (unitIdSet binder `combine` id_cands) tyvar_cands body
177
178     leakiness = case leakinessOf body2 of
179                   MightLeak  -> LeakFree 1
180                   LeakFree n -> LeakFree (n + 1)
181
182 fvExpr id_cands tyvar_cands (Lam b@(TyBinder tyvar) body)
183   = (FVInfo (freeVarsOf body2)
184             (freeTyVarsOf body2 `minusTyVarSet` aFreeTyVar tyvar)
185             (leakinessOf body2),
186      AnnLam b body2)
187   where
188     body2 = fvExpr id_cands (aFreeTyVar tyvar `combine` tyvar_cands) body
189
190 -- ditto on rewriting this App stuff (WDP 96/03)
191
192 fvExpr id_cands tyvar_cands (App fun arg)
193   = (FVInfo (freeVarsOf fun2   `combine` fvs_arg)
194             (freeTyVarsOf fun2 `combine` tfvs_arg)
195             leakiness,
196      AnnApp fun2 arg)
197   where
198     fun2 = fvExpr id_cands tyvar_cands fun
199     fun2_leakiness = leakinessOf fun2
200
201     (fvs_arg, tfvs_arg) = freeArgs id_cands tyvar_cands [arg]
202
203     leakiness = if (notValArg arg) then
204                     fun2_leakiness
205                 else
206                     case fun2_leakiness of
207                        LeakFree n | n>1 -> LeakFree (n-1) -- Note > not >=
208                        other            -> MightLeak
209
210 fvExpr id_cands tyvar_cands (Case expr alts)
211   = (combineFVInfo expr_fvinfo alts_fvinfo,
212      AnnCase expr2 alts')
213   where
214     expr2@(expr_fvinfo,_) = fvExpr id_cands tyvar_cands expr
215     (alts_fvinfo, alts') = annotate_alts alts
216
217     annotate_alts (AlgAlts alts deflt)
218       = (fvinfo, AnnAlgAlts alts' deflt')
219       where
220         (alts_fvinfo_s, alts') = unzip (map ann_boxed_alt alts)
221         (deflt_fvinfo, deflt') = annotate_default deflt
222         fvinfo = foldr combineFVInfo deflt_fvinfo alts_fvinfo_s
223
224         ann_boxed_alt (con, params, rhs)
225           = (FVInfo (freeVarsOf rhs' `minusIdSet` mkIdSet params)
226                     (freeTyVarsOf rhs' `combine` param_ftvs)
227                     (leakinessOf rhs'),
228              (con, params, rhs'))
229           where
230             rhs' = fvExpr (mkIdSet params `combine` id_cands) tyvar_cands rhs
231             param_ftvs = foldr (combine . munge_id_ty) noFreeTyVars params
232                 -- We need to collect free tyvars from the binders
233
234     annotate_alts (PrimAlts alts deflt)
235       = (fvinfo, AnnPrimAlts alts' deflt')
236       where
237         (alts_fvinfo_s, alts') = unzip (map ann_unboxed_alt alts)
238         (deflt_fvinfo, deflt') = annotate_default deflt
239         fvinfo  = foldr combineFVInfo deflt_fvinfo alts_fvinfo_s
240
241         ann_unboxed_alt (lit, rhs) = (rhs_info, (lit, rhs'))
242           where
243             rhs'@(rhs_info,_) = fvExpr id_cands tyvar_cands rhs
244
245     annotate_default NoDefault = (FVInfo noFreeIds noFreeTyVars lEAK_FREE_BIG,
246                                     AnnNoDefault)
247
248     annotate_default (BindDefault binder rhs)
249       = (FVInfo (freeVarsOf   rhs' `minusIdSet` aFreeId binder)
250                 (freeTyVarsOf rhs' `combine` binder_ftvs)
251                 (leakinessOf rhs'),
252          AnnBindDefault binder rhs')
253       where
254         rhs' = fvExpr (aFreeId binder `combine` id_cands) tyvar_cands rhs
255         binder_ftvs = munge_id_ty binder
256             -- We need to collect free tyvars from the binder
257
258 fvExpr id_cands tyvar_cands (Let (NonRec binder rhs) body)
259   = (FVInfo (freeVarsOf rhs'   `combine` body_fvs)
260             (freeTyVarsOf rhs' `combine` freeTyVarsOf body2 `combine` binder_ftvs)
261             (leakinessOf rhs' `orLeak` leakinessOf body2),
262      AnnLet (AnnNonRec binder rhs') body2)
263   where
264     rhs'        = fvExpr id_cands tyvar_cands rhs
265     body2       = fvExpr (aFreeId binder `combine` id_cands) tyvar_cands body
266     body_fvs    = freeVarsOf body2 `minusIdSet` aFreeId binder
267     binder_ftvs = munge_id_ty binder
268         -- We need to collect free tyvars from the binder
269
270 fvExpr id_cands tyvar_cands (Let (Rec binds) body)
271   = (FVInfo (binds_fvs `combine` body_fvs)
272             (rhss_tfvs `combine` freeTyVarsOf body2 `combine` binders_ftvs)
273             (leakiness_of_rhss `orLeak` leakinessOf body2),
274      AnnLet (AnnRec (binders `zip` rhss')) body2)
275   where
276     (binders, rhss)   = unzip binds
277     new_id_cands      = binders_set `combine` id_cands
278     binders_set       = mkIdSet binders
279     rhss'             = map (fvExpr new_id_cands tyvar_cands) rhss
280
281     FVInfo rhss_fvs rhss_tfvs leakiness_of_rhss
282         = foldr1 combineFVInfo [info | (info,_) <- rhss']
283
284     binds_fvs         = rhss_fvs `minusIdSet` binders_set
285     body2             = fvExpr new_id_cands tyvar_cands body
286     body_fvs          = freeVarsOf body2 `minusIdSet` binders_set
287     binders_ftvs      = foldr (combine . munge_id_ty) noFreeTyVars binders
288         -- We need to collect free tyvars from the binders
289
290 fvExpr id_cands tyvar_cands (SCC label expr)
291   = (fvinfo, AnnSCC label expr2)
292   where
293     expr2@(fvinfo,_) = fvExpr id_cands tyvar_cands expr
294
295 fvExpr id_cands tyvar_cands (Coerce c ty expr)
296   = (FVInfo (freeVarsOf   expr2)
297             (freeTyVarsOf expr2 `combine` tfvs)
298             (leakinessOf  expr2),
299      AnnCoerce c ty expr2)
300   where
301     expr2 = fvExpr id_cands tyvar_cands expr
302     tfvs  = freeTy tyvar_cands ty
303 \end{code}
304
305 \begin{code}
306 freeArgs :: IdCands -> TyVarCands
307          -> [CoreArg]
308          -> (IdSet, TyVarSet)
309
310 freeArgs icands tcands [] = noFreeAnything
311 freeArgs icands tcands (arg:args)
312   -- this code is written this funny way only for "efficiency" purposes
313   = let
314         free_first_arg@(arg_fvs, tfvs) = free_arg arg
315     in
316     if (null args) then
317         free_first_arg
318     else
319         case (freeArgs icands tcands args) of { (irest, trest) ->
320         (arg_fvs `combine` irest, tfvs `combine` trest) }
321   where
322     free_arg (LitArg   _) = noFreeAnything
323     free_arg (TyArg   ty) = (noFreeIds, freeTy tcands ty)
324     free_arg (VarArg   v)
325       | v `is_among` icands = (aFreeId v, noFreeTyVars)
326       | otherwise           = noFreeAnything
327
328 ---------
329 freeTy :: TyVarCands -> Type -> TyVarSet
330
331 freeTy cands ty = tyVarsOfType ty `intersectTyVarSets` cands
332
333 freeVarsOf :: CoreExprWithFVs -> IdSet
334 freeVarsOf (FVInfo free_vars _ _, _) = free_vars
335
336 freeTyVarsOf :: CoreExprWithFVs -> TyVarSet
337 freeTyVarsOf (FVInfo _ free_tyvars _, _) = free_tyvars
338
339 leakinessOf :: CoreExprWithFVs -> LeakInfo
340 leakinessOf (FVInfo _ _ leakiness, _) = leakiness
341 \end{code}
342
343
344 %************************************************************************
345 %*                                                                      *
346 \section[freevars-binders]{Attaching free variables to binders
347 %*                                                                      *
348 %************************************************************************
349
350
351 Here's an variant of the free-variable pass, which pins free-variable
352 information on {\em binders} rather than every single jolly
353 expression!
354 \begin{itemize}
355 \item
356   The free vars attached to a lambda binder are the free vars of the
357   whole lambda abstraction.  If there are multiple binders, they are
358   each given the same free-var set.
359 \item
360   The free vars attached to a let(rec) binder are the free vars of the
361   rhs of the binding.  In the case of letrecs, this set excludes the
362   binders themselves.
363 \item
364   The free vars attached to a case alternative binder are the free
365   vars of the alternative, excluding the alternative's binders.
366 \end{itemize}
367
368 There's a predicate carried in which tells what is a free-var
369 candidate. It is passed the Id and a set of in-scope Ids.
370
371 (Global) constructors used on the rhs in a Con are also treated as
372 potential free-var candidates (though they will not be recorded in the
373 in-scope set). The predicate must decide if they are to be recorded as
374 free-vars.
375
376 As it happens this is only ever used by the Specialiser!
377
378 \begin{code}
379 type FVCoreBinder  = (Id, IdSet)
380 type FVCoreExpr    = GenCoreExpr    FVCoreBinder Id Unused
381 type FVCoreBinding = GenCoreBinding FVCoreBinder Id Unused
382
383 type InterestingIdFun
384   =  IdSet      -- Non-top-level in-scope variables
385   -> Id         -- The Id being looked at
386   -> Bool       -- True <=> interesting
387 \end{code}
388
389 \begin{code}
390 addExprFVs :: InterestingIdFun  -- "Interesting id" predicate
391            -> IdSet             -- In scope ids
392            -> CoreExpr
393            -> (FVCoreExpr, IdSet)
394
395 addExprFVs fv_cand in_scope (Var v)
396   = (Var v, if fv_cand in_scope v
397               then aFreeId v
398               else noFreeIds)
399
400 addExprFVs fv_cand in_scope (Lit lit) = (Lit lit, noFreeIds)
401
402 addExprFVs fv_cand in_scope (Con con args)
403   = (Con con args,
404      if fv_cand in_scope con
405      then aFreeId con
406      else noFreeIds `combine` fvsOfArgs fv_cand in_scope args)
407
408 addExprFVs fv_cand in_scope (Prim op args)
409   = (Prim op args, fvsOfArgs fv_cand in_scope args)
410
411 addExprFVs fv_cand in_scope (Lam binder body)
412   = (Lam new_binder new_body, lam_fvs)
413   where
414     (new_binder, binder_set)
415       = case binder of
416           TyBinder    t -> (TyBinder t, emptyIdSet)
417           ValBinder   b -> (ValBinder (b, lam_fvs),
418                             unitIdSet b)
419
420     new_in_scope         = in_scope `combine` binder_set
421     (new_body, body_fvs) = addExprFVs fv_cand new_in_scope body
422     lam_fvs              = body_fvs `minusIdSet` binder_set
423
424 addExprFVs fv_cand in_scope (App fun arg)
425   = (App fun2 arg, fun_fvs `combine` fvsOfArgs fv_cand in_scope [arg])
426   where
427     (fun2, fun_fvs) = addExprFVs fv_cand in_scope fun
428
429 addExprFVs fv_cand in_scope (Case scrut alts)
430   = (Case scrut' alts', scrut_fvs `combine` alts_fvs)
431   where
432     (scrut', scrut_fvs) = addExprFVs fv_cand in_scope scrut
433
434     (alts', alts_fvs)
435       = case alts of
436           AlgAlts alg_alts deflt -> (AlgAlts alg_alts' deflt', fvs)
437             where
438               (alg_alts', alt_fvs) = unzip (map do_alg_alt alg_alts)
439               (deflt', deflt_fvs) = do_deflt deflt
440               fvs = unionManyIdSets (deflt_fvs : alt_fvs)
441
442           PrimAlts prim_alts deflt -> (PrimAlts prim_alts' deflt', fvs)
443             where
444               (prim_alts', alt_fvs) = unzip (map do_prim_alt prim_alts)
445               (deflt', deflt_fvs) = do_deflt deflt
446               fvs = unionManyIdSets (deflt_fvs : alt_fvs)
447
448     do_alg_alt :: (Id, [Id], CoreExpr)
449                -> ((Id, [FVCoreBinder], FVCoreExpr), IdSet)
450
451     do_alg_alt (con, args, rhs) = ((con, args `zip` (repeat fvs), rhs'), fvs)
452       where
453         new_in_scope = in_scope `combine` arg_set
454         (rhs', rhs_fvs) = addExprFVs fv_cand new_in_scope rhs
455         fvs = rhs_fvs `minusIdSet` arg_set
456         arg_set = mkIdSet args
457
458     do_prim_alt (lit, rhs) = ((lit, rhs'), rhs_fvs)
459       where
460         (rhs', rhs_fvs) = addExprFVs fv_cand in_scope rhs
461
462     do_deflt NoDefault = (NoDefault, noFreeIds)
463     do_deflt (BindDefault var rhs)
464       = (BindDefault (var,fvs) rhs', fvs)
465       where
466         new_in_scope = in_scope `combine` var_set
467         (rhs', rhs_fvs) = addExprFVs fv_cand new_in_scope rhs
468         fvs = rhs_fvs `minusIdSet` var_set
469         var_set = aFreeId var
470
471 addExprFVs fv_cand in_scope (Let binds body)
472   = (Let binds' body2, fvs_binds `combine` (fvs_body `minusIdSet` binder_set))
473   where
474     (binds', fvs_binds, new_in_scope, binder_set)
475       = addBindingFVs fv_cand in_scope binds
476
477     (body2, fvs_body)  = addExprFVs fv_cand new_in_scope body
478
479 addExprFVs fv_cand in_scope (SCC label expr)
480   = (SCC label expr2, expr_fvs)
481   where
482     (expr2, expr_fvs) = addExprFVs fv_cand in_scope expr
483
484 addExprFVs fv_cand in_scope (Coerce c ty expr)
485   = (Coerce c ty expr2, expr_fvs)
486   where
487     (expr2, expr_fvs) = addExprFVs fv_cand in_scope expr
488 \end{code}
489
490 \begin{code}
491 addBindingFVs
492             :: InterestingIdFun -- "Interesting id" predicate
493             -> IdSet            -- In scope ids
494             -> CoreBinding
495             -> (FVCoreBinding,
496                 IdSet,          -- Free vars of binding group
497                 IdSet,          -- Augmented in-scope Ids
498                 IdSet)          -- Set of Ids bound by this binding
499
500 addBindingFVs fv_cand in_scope (NonRec binder rhs)
501   = (NonRec binder' rhs', fvs, new_in_scope, binder_set)
502   where
503     ((binder', rhs'), fvs) = do_pair fv_cand in_scope binder_set (binder, rhs)
504     new_in_scope = in_scope `combine` binder_set
505     binder_set = aFreeId binder
506
507 addBindingFVs fv_cand in_scope (Rec pairs)
508   = (Rec pairs', unionManyIdSets fvs_s, new_in_scope, binder_set)
509   where
510     binders = [binder | (binder,_) <- pairs]
511     binder_set = mkIdSet binders
512     new_in_scope = in_scope `combine` binder_set
513     (pairs', fvs_s) = unzip (map (do_pair fv_cand new_in_scope binder_set) pairs)
514 \end{code}
515
516 \begin{code}
517 addTopBindsFVs
518             :: InterestingIdFun -- "Interesting id" predicate
519             -> [CoreBinding]
520             -> ([FVCoreBinding],
521                 IdSet)
522
523 addTopBindsFVs fv_cand [] = ([], noFreeIds)
524 addTopBindsFVs fv_cand (b:bs)
525   = let
526       (b',  fvs_b, _, _) = addBindingFVs fv_cand noFreeIds b
527       (bs', fvs_bs)      = addTopBindsFVs fv_cand bs
528     in
529     (b' : bs', fvs_b `combine` fvs_bs)
530 \end{code}
531
532 \begin{code}
533 fvsOfArgs   :: InterestingIdFun -- "Interesting id" predicate
534             -> IdSet            -- In scope ids
535             -> [CoreArg]
536             -> IdSet
537
538 fvsOfArgs _ _ [] = noFreeIds
539
540 fvsOfArgs fv_cand in_scope [VarArg v] -- this is only a short-cut...
541   = if (fv_cand in_scope v) then aFreeId v else noFreeIds
542 fvsOfArgs _       _        [ _ ] = noFreeIds
543
544 fvsOfArgs fv_cand in_scope args
545   = mkIdSet [ v | (VarArg v) <- args, fv_cand in_scope v ]
546     -- all other types of args are uninteresting here...
547
548 ----------
549 do_pair :: InterestingIdFun -- "Interesting id" predicate
550         -> IdSet            -- In scope ids
551         -> IdSet
552         -> (Id, CoreExpr)
553         -> ((FVCoreBinder, FVCoreExpr), IdSet)
554
555 do_pair fv_cand in_scope binder_set (binder,rhs)
556  = (((binder, fvs), rhs'), fvs)
557  where
558    (rhs', rhs_fvs) = addExprFVs fv_cand in_scope rhs
559    fvs = rhs_fvs `minusIdSet` binder_set
560 \end{code}