85581c9aad43d5627cb7a1eebfabd490d67a5ce3
[ghc-hetmet.git] / compiler / deSugar / DsBinds.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3 %
4 \section[DsBinds]{Pattern-matching bindings (HsBinds and MonoBinds)}
5
6 Handles @HsBinds@; those at the top level require different handling,
7 in that the @Rec@/@NonRec@/etc structure is thrown away (whereas at
8 lower levels it is preserved with @let@/@letrec@s).
9
10 \begin{code}
11 module DsBinds ( dsTopLHsBinds, dsLHsBinds, decomposeRuleLhs, 
12                  dsCoercion,
13                  AutoScc(..)
14   ) where
15
16 #include "HsVersions.h"
17
18
19 import {-# SOURCE #-}   DsExpr( dsLExpr, dsExpr )
20 import {-# SOURCE #-}   Match( matchWrapper )
21
22 import DsMonad
23 import DsGRHSs          ( dsGuarded )
24 import DsUtils
25
26 import HsSyn            -- lots of things
27 import CoreSyn          -- lots of things
28 import CoreUtils        ( exprType, mkInlineMe, mkSCC )
29
30 import OccurAnal        ( occurAnalyseExpr )
31 import CostCentre       ( mkAutoCC, IsCafCC(..) )
32 import Id               ( Id, DictId, idType, idName, mkLocalId, setInlinePragma )
33 import Rules            ( addIdSpecialisations, mkLocalRule )
34 import Var              ( TyVar, Var, isGlobalId, setIdNotExported )
35 import VarEnv
36 import Type             ( mkTyVarTy, substTyWith )
37 import TysWiredIn       ( voidTy )
38 import Module           ( Module )
39 import Outputable
40 import SrcLoc           ( Located(..) )
41 import Maybes           ( catMaybes, orElse )
42 import Bag              ( bagToList )
43 import BasicTypes       ( Activation(..), InlineSpec(..), isAlwaysActive )
44 import Monad            ( foldM )
45 import FastString       ( mkFastString )
46 import List             ( (\\) )
47 import Util             ( mapSnd )
48 \end{code}
49
50 %************************************************************************
51 %*                                                                      *
52 \subsection[dsMonoBinds]{Desugaring a @MonoBinds@}
53 %*                                                                      *
54 %************************************************************************
55
56 \begin{code}
57 dsTopLHsBinds :: AutoScc -> LHsBinds Id -> DsM [(Id,CoreExpr)]
58 dsTopLHsBinds auto_scc binds = ds_lhs_binds auto_scc binds
59
60 dsLHsBinds :: LHsBinds Id -> DsM [(Id,CoreExpr)]
61 dsLHsBinds binds = ds_lhs_binds NoSccs binds
62
63
64 ------------------------
65 ds_lhs_binds :: AutoScc -> LHsBinds Id -> DsM [(Id,CoreExpr)]
66          -- scc annotation policy (see below)
67 ds_lhs_binds auto_scc binds =  foldM (dsLHsBind auto_scc) [] (bagToList binds)
68
69 dsLHsBind :: AutoScc
70          -> [(Id,CoreExpr)]     -- Put this on the end (avoid quadratic append)
71          -> LHsBind Id
72          -> DsM [(Id,CoreExpr)] -- Result
73 dsLHsBind auto_scc rest (L loc bind)
74   = putSrcSpanDs loc $ dsHsBind auto_scc rest bind
75
76 dsHsBind :: AutoScc
77          -> [(Id,CoreExpr)]     -- Put this on the end (avoid quadratic append)
78          -> HsBind Id
79          -> DsM [(Id,CoreExpr)] -- Result
80
81 dsHsBind auto_scc rest (VarBind var expr)
82   = dsLExpr expr                `thenDs` \ core_expr ->
83
84         -- Dictionary bindings are always VarMonoBinds, so
85         -- we only need do this here
86     addDictScc var core_expr    `thenDs` \ core_expr' ->
87     returnDs ((var, core_expr') : rest)
88
89 dsHsBind auto_scc rest (FunBind { fun_id = L _ fun, fun_matches = matches, fun_co_fn = co_fn })
90   = matchWrapper (FunRhs (idName fun)) matches          `thenDs` \ (args, body) ->
91     dsCoercion co_fn (return (mkLams args body))        `thenDs` \ rhs ->
92     returnDs ((fun,rhs) : rest)
93
94 dsHsBind auto_scc rest (PatBind { pat_lhs = pat, pat_rhs = grhss, pat_rhs_ty = ty })
95   = dsGuarded grhss ty                          `thenDs` \ body_expr ->
96     mkSelectorBinds pat body_expr               `thenDs` \ sel_binds ->
97     returnDs (sel_binds ++ rest)
98
99 -- Note [Rules and inlining]
100 -- Common special case: no type or dictionary abstraction
101 -- This is a bit less trivial than you might suppose
102 -- The naive way woudl be to desguar to something like
103 --      f_lcl = ...f_lcl...     -- The "binds" from AbsBinds
104 --      M.f = f_lcl             -- Generated from "exports"
105 -- But we don't want that, because if M.f isn't exported,
106 -- it'll be inlined unconditionally at every call site (its rhs is 
107 -- trivial).  That would be ok unless it has RULES, which would 
108 -- thereby be completely lost.  Bad, bad, bad.
109 --
110 -- Instead we want to generate
111 --      M.f = ...f_lcl...
112 --      f_lcl = M.f
113 -- Now all is cool. The RULES are attached to M.f (by SimplCore), 
114 -- and f_lcl is rapidly inlined away.
115 --
116 -- This does not happen in the same way to polymorphic binds,
117 -- because they desugar to
118 --      M.f = /\a. let f_lcl = ...f_lcl... in f_lcl
119 -- Although I'm a bit worried about whether full laziness might
120 -- float the f_lcl binding out and then inline M.f at its call site
121
122 dsHsBind auto_scc rest (AbsBinds [] [] exports binds)
123   = do  { core_prs <- ds_lhs_binds NoSccs binds
124         ; let env = mkABEnv exports
125               do_one (lcl_id, rhs) | Just (gbl_id, prags) <- lookupVarEnv env lcl_id
126                                    = addInlinePrags prags gbl_id $
127                                      addAutoScc auto_scc gbl_id rhs
128                                    | otherwise = (lcl_id, rhs)
129               locals'  = [(lcl_id, Var gbl_id) | (_, gbl_id, lcl_id, _) <- exports]
130         ; return (map do_one core_prs ++ locals' ++ rest) }
131                 -- No Rec needed here (contrast the other AbsBinds cases)
132                 -- because we can rely on the enclosing dsBind to wrap in Rec
133
134         -- Another common case: one exported variable
135         -- Non-recursive bindings come through this way
136 dsHsBind auto_scc rest
137      (AbsBinds all_tyvars dicts exports@[(tyvars, global, local, prags)] binds)
138   = ASSERT( all (`elem` tyvars) all_tyvars )
139     ds_lhs_binds NoSccs binds   `thenDs` \ core_prs ->
140     let 
141         -- Always treat the binds as recursive, because the typechecker
142         -- makes rather mixed-up dictionary bindings
143         core_bind = Rec core_prs
144     in
145     mappM (dsSpec all_tyvars dicts tyvars global local core_bind) 
146           prags                         `thenDs` \ mb_specs ->
147     let
148         (spec_binds, rules) = unzip (catMaybes mb_specs)
149         global' = addIdSpecialisations global rules
150         rhs'    = mkLams tyvars $ mkLams dicts $ Let core_bind (Var local)
151         bind    = addInlinePrags prags global' $ addAutoScc auto_scc global' rhs'
152     in
153     returnDs (bind  : spec_binds ++ rest)
154
155 dsHsBind auto_scc rest (AbsBinds all_tyvars dicts exports binds)
156   = do  { core_prs <- ds_lhs_binds NoSccs binds
157         ; let env = mkABEnv exports
158               do_one (lcl_id,rhs) | Just (gbl_id, prags) <- lookupVarEnv env lcl_id
159                                   = addInlinePrags prags lcl_id $
160                                     addAutoScc auto_scc gbl_id rhs
161                                   | otherwise = (lcl_id,rhs)
162                
163                 -- Rec because of mixed-up dictionary bindings
164               core_bind = Rec (map do_one core_prs)
165
166               tup_expr      = mkTupleExpr locals
167               tup_ty        = exprType tup_expr
168               poly_tup_expr = mkLams all_tyvars $ mkLams dicts $
169                               Let core_bind tup_expr
170               locals        = [local | (_, _, local, _) <- exports]
171               local_tys     = map idType locals
172
173         ; poly_tup_id <- newSysLocalDs (exprType poly_tup_expr)
174
175         ; let dict_args = map Var dicts
176
177               mk_bind ((tyvars, global, local, prags), n)       -- locals !! n == local
178                 =       -- Need to make fresh locals to bind in the selector, because
179                         -- some of the tyvars will be bound to voidTy
180                   do { locals' <- newSysLocalsDs (map substitute local_tys)
181                      ; tup_id  <- newSysLocalDs  (substitute tup_ty)
182                      ; mb_specs <- mapM (dsSpec all_tyvars dicts tyvars global local core_bind) 
183                                          prags
184                      ; let (spec_binds, rules) = unzip (catMaybes mb_specs)
185                            global' = addIdSpecialisations global rules
186                            rhs = mkLams tyvars $ mkLams dicts $
187                                  mkTupleSelector locals' (locals' !! n) tup_id $
188                                  mkApps (mkTyApps (Var poly_tup_id) ty_args) dict_args
189                      ; returnDs ((global', rhs) : spec_binds) }
190                 where
191                   mk_ty_arg all_tyvar | all_tyvar `elem` tyvars = mkTyVarTy all_tyvar
192                                       | otherwise               = voidTy
193                   ty_args    = map mk_ty_arg all_tyvars
194                   substitute = substTyWith all_tyvars ty_args
195
196         ; export_binds_s <- mappM mk_bind (exports `zip` [0..])
197              -- don't scc (auto-)annotate the tuple itself.
198
199         ; returnDs ((poly_tup_id, poly_tup_expr) : 
200                     (concat export_binds_s ++ rest)) }
201
202 mkABEnv :: [([TyVar], Id, Id, [Prag])] -> VarEnv (Id, [Prag])
203 -- Takes the exports of a AbsBinds, and returns a mapping
204 --      lcl_id -> (gbl_id, prags)
205 mkABEnv exports = mkVarEnv [ (lcl_id, (gbl_id, prags)) 
206                            | (_, gbl_id, lcl_id, prags) <- exports]
207
208
209 dsSpec :: [TyVar] -> [DictId] -> [TyVar]
210        -> Id -> Id              -- Global, local
211        -> CoreBind -> Prag
212        -> DsM (Maybe ((Id,CoreExpr),    -- Binding for specialised Id
213                       CoreRule))        -- Rule for the Global Id
214
215 -- Example:
216 --      f :: (Eq a, Ix b) => a -> b -> b
217 --      {-# SPECIALISE f :: Ix b => Int -> b -> b #-}
218 --
219 --      AbsBinds [ab] [d1,d2] [([ab], f, f_mono, prags)] binds
220 -- 
221 --      SpecPrag (/\b.\(d:Ix b). f Int b dInt d) 
222 --               (forall b. Ix b => Int -> b -> b)
223 --
224 -- Rule:        forall b,(d:Ix b). f Int b dInt d = f_spec b d
225 --
226 -- Spec bind:   f_spec = Let f = /\ab \(d1:Eq a)(d2:Ix b). let binds in f_mono 
227 --                       /\b.\(d:Ix b). in f Int b dInt d
228 --              The idea is that f occurs just once, so it'll be 
229 --              inlined and specialised
230
231 dsSpec all_tvs dicts tvs poly_id mono_id mono_bind (InlinePrag {})
232   = return Nothing
233
234 dsSpec all_tvs dicts tvs poly_id mono_id mono_bind
235        (SpecPrag spec_expr spec_ty const_dicts inl)
236   = do  { let poly_name = idName poly_id
237         ; spec_name <- newLocalName poly_name
238         ; ds_spec_expr  <- dsExpr spec_expr
239         ; let (bndrs, body) = collectBinders ds_spec_expr
240               mb_lhs        = decomposeRuleLhs (bndrs ++ const_dicts) body
241
242         ; case mb_lhs of
243             Nothing -> do { warnDs msg; return Nothing }
244
245             Just (bndrs', var, args) -> return (Just (addInlineInfo inl spec_id spec_rhs, rule))
246                 where
247                   local_poly  = setIdNotExported poly_id
248                         -- Very important to make the 'f' non-exported,
249                         -- else it won't be inlined!
250                   spec_id     = mkLocalId spec_name spec_ty
251                   spec_rhs    = Let (NonRec local_poly poly_f_body) ds_spec_expr
252                   poly_f_body = mkLams (tvs ++ dicts) $
253                                 fix_up (Let mono_bind (Var mono_id))
254
255                         -- Quantify over constant dicts on the LHS, since
256                         -- their value depends only on their type
257                         -- The ones we are interested in may even be imported
258                         -- e.g. GHC.Base.dEqInt
259
260                   rule =  mkLocalRule (mkFastString ("SPEC " ++ showSDoc (ppr poly_name)))
261                                 AlwaysActive poly_name
262                                 bndrs'  -- Includes constant dicts
263                                 args
264                                 (mkVarApps (Var spec_id) bndrs)
265         }
266   where
267         -- Bind to voidTy any of all_ptvs that aren't 
268         -- relevant for this particular function 
269     fix_up body | null void_tvs = body
270                 | otherwise     = mkTyApps (mkLams void_tvs body) 
271                                            (map (const voidTy) void_tvs)
272     void_tvs = all_tvs \\ tvs
273
274     msg = hang (ptext SLIT("Specialisation too complicated to desugar; ignored"))
275              2 (ppr spec_expr)
276 \end{code}
277
278
279 %************************************************************************
280 %*                                                                      *
281 \subsection{Adding inline pragmas}
282 %*                                                                      *
283 %************************************************************************
284
285 \begin{code}
286 decomposeRuleLhs :: [Var] -> CoreExpr -> Maybe ([Var], Id, [CoreExpr])
287 -- Returns Nothing if the LHS isn't of the expected shape
288 -- The argument 'all_bndrs' includes the "constant dicts" of the LHS,
289 -- and they may be GlobalIds, which we can't forall-ify. 
290 -- So we substitute them out instead
291 decomposeRuleLhs all_bndrs lhs 
292   = go init_env (occurAnalyseExpr lhs)  -- Occurrence analysis sorts out the dict
293                                         -- bindings so we know if they are recursive
294   where
295
296         -- all_bndrs may include top-level imported dicts, 
297         -- imported things with a for-all.  
298         -- So we localise them and subtitute them out
299     bndr_prs =  [ (id, Var (localise id)) | id <- all_bndrs, isGlobalId id ]
300     localise d = mkLocalId (idName d) (idType d)
301
302     init_env = mkVarEnv bndr_prs
303     all_bndrs' = map subst_bndr all_bndrs
304     subst_bndr bndr = case lookupVarEnv init_env bndr of
305                         Just (Var bndr') -> bndr'
306                         Just other       -> panic "decomposeRuleLhs"
307                         Nothing          -> bndr
308
309         -- Substitute dicts in the LHS args, so that there 
310         -- aren't any lets getting in the way
311         -- Note that we substitute the function too; we might have this as
312         -- a LHS:       let f71 = M.f Int in f71
313     go env (Let (NonRec dict rhs) body) 
314         = go (extendVarEnv env dict (simpleSubst env rhs)) body
315     go env body 
316         = case collectArgs (simpleSubst env body) of
317             (Var fn, args) -> Just (all_bndrs', fn, args)
318             other          -> Nothing
319
320 simpleSubst :: IdEnv CoreExpr -> CoreExpr -> CoreExpr
321 -- Similar to CoreSubst.substExpr, except that 
322 -- (a) takes no account of capture; dictionary bindings use new names
323 -- (b) can have a GlobalId (imported) in its domain
324 -- (c) Ids only; no types are substituted
325
326 simpleSubst subst expr
327   = go expr
328   where
329     go (Var v)         = lookupVarEnv subst v `orElse` Var v
330     go (Cast e co)     = Cast (go e) co
331     go (Type ty)       = Type ty
332     go (Lit lit)       = Lit lit
333     go (App fun arg)   = App (go fun) (go arg)
334     go (Note note e)   = Note note (go e)
335     go (Lam bndr body) = Lam bndr (go body)
336     go (Let (NonRec bndr rhs) body) = Let (NonRec bndr (go rhs)) (go body)
337     go (Let (Rec pairs) body)       = Let (Rec (mapSnd go pairs)) (go body)
338     go (Case scrut bndr ty alts)    = Case (go scrut) bndr ty 
339                                            [(c,bs,go r) | (c,bs,r) <- alts]
340
341 addInlinePrags :: [Prag] -> Id -> CoreExpr -> (Id,CoreExpr)
342 addInlinePrags prags bndr rhs
343   = case [inl | InlinePrag inl <- prags] of
344         []      -> (bndr, rhs)
345         (inl:_) -> addInlineInfo inl bndr rhs
346
347 addInlineInfo :: InlineSpec -> Id -> CoreExpr -> (Id,CoreExpr)
348 addInlineInfo (Inline phase is_inline) bndr rhs
349   = (attach_phase bndr phase, wrap_inline is_inline rhs)
350   where
351     attach_phase bndr phase 
352         | isAlwaysActive phase = bndr   -- Default phase
353         | otherwise            = bndr `setInlinePragma` phase
354
355     wrap_inline True  body = mkInlineMe body
356     wrap_inline False body = body
357 \end{code}
358
359
360 %************************************************************************
361 %*                                                                      *
362 \subsection[addAutoScc]{Adding automatic sccs}
363 %*                                                                      *
364 %************************************************************************
365
366 \begin{code}
367 data AutoScc = NoSccs 
368              | AddSccs Module (Id -> Bool)
369 -- The (Id->Bool) says which Ids to add SCCs to 
370
371 addAutoScc :: AutoScc   
372            -> Id        -- Binder
373            -> CoreExpr  -- Rhs
374            -> CoreExpr  -- Scc'd Rhs
375
376 addAutoScc NoSccs _ rhs
377   = rhs
378 addAutoScc (AddSccs mod add_scc) id rhs
379   | add_scc id = mkSCC (mkAutoCC id mod NotCafCC) rhs
380   | otherwise  = rhs
381 \end{code}
382
383 If profiling and dealing with a dict binding,
384 wrap the dict in @_scc_ DICT <dict>@:
385
386 \begin{code}
387 addDictScc var rhs = returnDs rhs
388
389 {- DISABLED for now (need to somehow make up a name for the scc) -- SDM
390   | not ( opt_SccProfilingOn && opt_AutoSccsOnDicts)
391     || not (isDictId var)
392   = returnDs rhs                                -- That's easy: do nothing
393
394   | otherwise
395   = getModuleAndGroupDs         `thenDs` \ (mod, grp) ->
396         -- ToDo: do -dicts-all flag (mark dict things with individual CCs)
397     returnDs (Note (SCC (mkAllDictsCC mod grp False)) rhs)
398 -}
399 \end{code}
400
401
402 %************************************************************************
403 %*                                                                      *
404                 Desugaring coercions
405 %*                                                                      *
406 %************************************************************************
407
408
409 \begin{code}
410 dsCoercion :: HsWrapper -> DsM CoreExpr -> DsM CoreExpr
411 dsCoercion WpHole            thing_inside = thing_inside
412 dsCoercion (WpCompose c1 c2) thing_inside = dsCoercion c1 (dsCoercion c2 thing_inside)
413 dsCoercion (WpCo co)     thing_inside = do { expr <- thing_inside
414                                                ; return (Cast expr co) }
415 dsCoercion (WpLam id)        thing_inside = do { expr <- thing_inside
416                                                ; return (Lam id expr) }
417 dsCoercion (WpTyLam tv)      thing_inside = do { expr <- thing_inside
418                                                ; return (Lam tv expr) }
419 dsCoercion (WpApp id)        thing_inside = do { expr <- thing_inside
420                                                ; return (App expr (Var id)) }
421 dsCoercion (WpTyApp ty)      thing_inside = do { expr <- thing_inside
422                                                ; return (App expr (Type ty)) }
423 dsCoercion (WpLet bs)        thing_inside = do { prs <- dsLHsBinds bs
424                                                ; expr <- thing_inside
425                                                ; return (Let (Rec prs) expr) }
426 \end{code}