16ab5e5feae9207a08ef2c68b7c487e6bb3e48b7
[ghc-hetmet.git] / ghc / compiler / stgSyn / CoreToStg.lhs
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
3 %
4 %************************************************************************
5 %*                                                                      *
6 \section[CoreToStg]{Converting core syntax to STG syntax}
7 %*                                                                      *
8 %************************************************************************
9
10 Convert a @CoreSyntax@ program to a @StgSyntax@ program.
11
12 \begin{code}
13 #include "HsVersions.h"
14
15 module CoreToStg ( topCoreBindsToStg ) where
16
17 IMP_Ubiq(){-uitous-}
18 IMPORT_1_3(Ratio(numerator,denominator))
19
20 import CoreSyn          -- input
21 import StgSyn           -- output
22
23 import Bag              ( emptyBag, unitBag, unionBags, unionManyBags, bagToList )
24 import CoreUtils        ( coreExprType )
25 import CostCentre       ( noCostCentre )
26 import Id               ( mkSysLocal, idType, isBottomingId,
27                           externallyVisibleId,
28
29                           nullIdEnv, addOneToIdEnv, lookupIdEnv, growIdEnvList,
30                           SYN_IE(IdEnv), GenId{-instance NamedThing-}, SYN_IE(Id)
31                         )
32 import Literal          ( mkMachInt, Literal(..) )
33 import PrelVals         ( unpackCStringId, unpackCString2Id,
34                           integerZeroId, integerPlusOneId,
35                           integerPlusTwoId, integerMinusOneId
36                         )
37 import PrimOp           ( PrimOp(..) )
38 import SpecUtils        ( mkSpecialisedCon )
39 import SrcLoc           ( noSrcLoc )
40 import TyCon            ( TyCon{-instance Uniquable-} )
41 import Type             ( getAppDataTyConExpandingDicts, SYN_IE(Type) )
42 import TysWiredIn       ( stringTy )
43 import Unique           ( integerTyConKey, ratioTyConKey, Unique{-instance Eq-} )
44 import UniqSupply       -- all of it, really
45 import Util             ( zipLazy, panic, assertPanic, pprTrace {-TEMP-} )
46 import Pretty
47 import Outputable
48
49 isLeakFreeType x y = False -- safe option; ToDo
50 \end{code}
51
52
53         ***************  OVERVIEW   *********************
54
55
56 The business of this pass is to convert Core to Stg.  On the way:
57
58 * We discard type lambdas and applications. In so doing we discard
59   "trivial" bindings such as
60         x = y t1 t2
61   where t1, t2 are types
62
63 * We don't pin on correct arities any more, because they can be mucked up
64   by the lambda lifter.  In particular, the lambda lifter can take a local
65   letrec-bound variable and make it a lambda argument, which shouldn't have
66   an arity.  So SetStgVarInfo sets arities now.
67
68 * We do *not* pin on the correct free/live var info; that's done later.
69   Instead we use bOGUS_LVS and _FVS as a placeholder.
70
71 [Quite a bit of stuff that used to be here has moved 
72  to tidyCorePgm (SimplCore.lhs) SLPJ Nov 96]
73
74
75 %************************************************************************
76 %*                                                                      *
77 \subsection[coreToStg-programs]{Converting a core program and core bindings}
78 %*                                                                      *
79 %************************************************************************
80
81 Because we're going to come across ``boring'' bindings like
82 \tr{let x = /\ tyvars -> y in ...}, we want to keep a small
83 environment, so we can just replace all occurrences of \tr{x}
84 with \tr{y}.
85
86 \begin{code}
87 type StgEnv = IdEnv StgArg
88 \end{code}
89
90 No free/live variable information is pinned on in this pass; it's added
91 later.  For this pass
92 we use @bOGUS_LVs@ and @bOGUS_FVs@ as placeholders.
93
94 \begin{code}
95 bOGUS_LVs :: StgLiveVars
96 bOGUS_LVs = panic "bOGUS_LVs" -- emptyUniqSet (used when pprTracing)
97
98 bOGUS_FVs :: [Id]
99 bOGUS_FVs = panic "bOGUS_FVs" -- [] (ditto)
100 \end{code}
101
102 \begin{code}
103 topCoreBindsToStg :: UniqSupply -- name supply
104                   -> [CoreBinding]      -- input
105                   -> [StgBinding]       -- output
106
107 topCoreBindsToStg us core_binds
108   = initUs us (coreBindsToStg nullIdEnv core_binds)
109   where
110     coreBindsToStg :: StgEnv -> [CoreBinding] -> UniqSM [StgBinding]
111
112     coreBindsToStg env [] = returnUs []
113     coreBindsToStg env (b:bs)
114       = coreBindToStg  env b            `thenUs` \ (new_b, new_env) ->
115         coreBindsToStg new_env bs       `thenUs` \ new_bs ->
116         returnUs (new_b ++ new_bs)
117 \end{code}
118
119 %************************************************************************
120 %*                                                                      *
121 \subsection[coreToStg-binds]{Converting bindings}
122 %*                                                                      *
123 %************************************************************************
124
125 \begin{code}
126 coreBindToStg :: StgEnv
127               -> CoreBinding
128               -> UniqSM ([StgBinding],  -- Empty or singleton
129                          StgEnv)        -- Floats
130
131 coreBindToStg env (NonRec binder rhs)
132   = coreRhsToStg env rhs        `thenUs` \ stg_rhs ->
133     let
134         -- Binds to return if RHS is trivial
135         triv_binds | externallyVisibleId binder = [StgNonRec binder stg_rhs]    -- Retain it
136                    | otherwise                  = []                            -- Discard it
137     in
138     case stg_rhs of
139       StgRhsClosure cc bi fvs upd [] (StgApp atom [] lvs) ->
140                 -- Trivial RHS, so augment envt, and ditch the binding
141                 returnUs (triv_binds, new_env)
142            where
143                 new_env = addOneToIdEnv env binder atom
144
145       StgRhsCon cc con_id [] ->
146                 -- Trivial RHS, so augment envt, and ditch the binding
147                 returnUs (triv_binds, new_env)
148            where
149                 new_env = addOneToIdEnv env binder (StgConArg con_id)
150
151       other ->  -- Non-trivial RHS, so don't augment envt
152                 returnUs ([StgNonRec binder stg_rhs], env)
153
154 coreBindToStg env (Rec pairs)
155   = -- NB: *** WE DO NOT CHECK FOR TRIV_BINDS in REC BIND ****
156     -- (possibly ToDo)
157     let
158         (binders, rhss) = unzip pairs
159     in
160     mapUs (coreRhsToStg env) rhss `thenUs` \ stg_rhss ->
161     returnUs ([StgRec (binders `zip` stg_rhss)], env)
162 \end{code}
163
164
165 %************************************************************************
166 %*                                                                      *
167 \subsection[coreToStg-rhss]{Converting right hand sides}
168 %*                                                                      *
169 %************************************************************************
170
171 \begin{code}
172 coreRhsToStg :: StgEnv -> CoreExpr -> UniqSM StgRhs
173
174 coreRhsToStg env core_rhs
175   = coreExprToStg env core_rhs  `thenUs` \ stg_expr ->
176
177     let stg_rhs = case stg_expr of
178                     StgLet (StgNonRec var1 rhs) (StgApp (StgVarArg var2) [] _)
179                         | var1 == var2 -> rhs
180                         -- This curious stuff is to unravel what a lambda turns into
181                         -- We have to do it this way, rather than spot a lambda in the
182                         -- incoming rhs.  Why?  Because trivial bindings might conceal
183                         -- what the rhs is actually like.
184
185                     StgCon con args _ -> StgRhsCon noCostCentre con args
186
187                     other -> StgRhsClosure noCostCentre -- No cost centre (ToDo?)
188                                            stgArgOcc    -- safe
189                                            bOGUS_FVs
190                                            Updatable    -- Be pessimistic
191                                            []
192                                            stg_expr
193     in
194     returnUs stg_rhs
195 \end{code}
196
197
198 %************************************************************************
199 %*                                                                      *
200 \subsection[coreToStg-atoms{Converting atoms}
201 %*                                                                      *
202 %************************************************************************
203
204 \begin{code}
205 coreArgsToStg :: StgEnv -> [CoreArg] -> ([Type], [StgArg])
206
207 coreArgsToStg env [] = ([], [])
208 coreArgsToStg env (a:as)
209   = case a of
210         TyArg    t -> (t:trest, vrest)
211         UsageArg u -> (trest,   vrest)
212         VarArg   v -> (trest,   stgLookup env v : vrest)
213         LitArg   l -> (trest,   StgLitArg l     : vrest)
214   where
215     (trest,vrest) = coreArgsToStg env as
216 \end{code}
217
218
219 %************************************************************************
220 %*                                                                      *
221 \subsection[coreToStg-exprs]{Converting core expressions}
222 %*                                                                      *
223 %************************************************************************
224
225 \begin{code}
226 coreExprToStg :: StgEnv -> CoreExpr -> UniqSM StgExpr
227
228 coreExprToStg env (Lit lit)
229   = returnUs (StgApp (StgLitArg lit) [] bOGUS_LVs)
230
231 coreExprToStg env (Var var)
232   = returnUs (mk_app (stgLookup env var) [])
233
234 coreExprToStg env (Con con args)
235   = let
236         (types, stg_atoms) = coreArgsToStg env args
237         spec_con = mkSpecialisedCon con types
238     in
239     returnUs (StgCon spec_con stg_atoms bOGUS_LVs)
240
241 coreExprToStg env (Prim op args)
242   = let
243         (types, stg_atoms) = coreArgsToStg env args
244     in
245     returnUs (StgPrim op stg_atoms bOGUS_LVs)
246 \end{code}
247
248 %************************************************************************
249 %*                                                                      *
250 \subsubsection[coreToStg-lambdas]{Lambda abstractions}
251 %*                                                                      *
252 %************************************************************************
253
254 \begin{code}
255 coreExprToStg env expr@(Lam _ _)
256   = let
257         (_,_, binders, body) = collectBinders expr
258     in
259     coreExprToStg env body              `thenUs` \ stg_body ->
260
261     if null binders then -- it was all type/usage binders; tossed
262         returnUs stg_body
263     else
264         newStgVar (coreExprType expr)   `thenUs` \ var ->
265         returnUs
266           (StgLet (StgNonRec var
267                                   (StgRhsClosure noCostCentre
268                                   stgArgOcc
269                                   bOGUS_FVs
270                                   ReEntrant     -- binders is non-empty
271                                   binders
272                                   stg_body))
273            (StgApp (StgVarArg var) [] bOGUS_LVs))
274 \end{code}
275
276 %************************************************************************
277 %*                                                                      *
278 \subsubsection[coreToStg-applications]{Applications}
279 %*                                                                      *
280 %************************************************************************
281
282 \begin{code}
283 coreExprToStg env expr@(App _ _)
284   = let
285         (fun,args)    = collect_args expr []
286         (_, stg_args) = coreArgsToStg env args
287     in
288         -- Now deal with the function
289     case (fun, args) of
290       (Var fun_id, _) ->        -- A function Id, so do an StgApp; it's ok if
291                                 -- there are no arguments.
292                             returnUs (mk_app (stgLookup env fun_id) stg_args)
293
294       (non_var_fun, []) ->      -- No value args, so recurse into the function
295                             coreExprToStg env non_var_fun
296
297       other ->  -- A non-variable applied to things; better let-bind it.
298                 newStgVar (coreExprType fun)    `thenUs` \ fun_id ->
299                 coreExprToStg env fun           `thenUs` \ (stg_fun) ->
300                 let
301                    fun_rhs = StgRhsClosure noCostCentre -- No cost centre (ToDo?)
302                                            stgArgOcc
303                                            bOGUS_FVs
304                                            SingleEntry  -- Only entered once
305                                            []
306                                            stg_fun
307                 in
308                 returnUs (StgLet (StgNonRec fun_id fun_rhs)
309                                  (StgApp (StgVarArg fun_id) stg_args bOGUS_LVs))
310   where
311         -- Collect arguments, discarding type/usage applications
312     collect_args (App e   (TyArg _))    args = collect_args e   args
313     collect_args (App e   (UsageArg _)) args = collect_args e   args
314     collect_args (App fun arg)          args = collect_args fun (arg:args)
315     collect_args (Coerce _ _ expr)      args = collect_args expr args
316     collect_args fun                    args = (fun, args)
317 \end{code}
318
319 %************************************************************************
320 %*                                                                      *
321 \subsubsection[coreToStg-cases]{Case expressions}
322 %*                                                                      *
323 %************************************************************************
324
325 \begin{code}
326 coreExprToStg env (Case discrim alts)
327   = coreExprToStg env discrim           `thenUs` \ stg_discrim ->
328     alts_to_stg discrim alts            `thenUs` \ stg_alts ->
329     getUnique                           `thenUs` \ uniq ->
330     returnUs (
331         StgCase stg_discrim
332                 bOGUS_LVs
333                 bOGUS_LVs
334                 uniq
335                 stg_alts
336     )
337   where
338     discrim_ty              = coreExprType discrim
339     (_, discrim_ty_args, _) = getAppDataTyConExpandingDicts discrim_ty
340
341     alts_to_stg discrim (AlgAlts alts deflt)
342       = default_to_stg discrim deflt            `thenUs` \ stg_deflt ->
343         mapUs boxed_alt_to_stg alts             `thenUs` \ stg_alts  ->
344         returnUs (StgAlgAlts discrim_ty stg_alts stg_deflt)
345       where
346         boxed_alt_to_stg (con, bs, rhs)
347           = coreExprToStg env rhs    `thenUs` \ stg_rhs ->
348             returnUs (spec_con, bs, [ True | b <- bs ]{-bogus use mask-}, stg_rhs)
349           where
350             spec_con = mkSpecialisedCon con discrim_ty_args
351
352     alts_to_stg discrim (PrimAlts alts deflt)
353       = default_to_stg discrim deflt            `thenUs` \ stg_deflt ->
354         mapUs unboxed_alt_to_stg alts           `thenUs` \ stg_alts  ->
355         returnUs (StgPrimAlts discrim_ty stg_alts stg_deflt)
356       where
357         unboxed_alt_to_stg (lit, rhs)
358           = coreExprToStg env rhs    `thenUs` \ stg_rhs ->
359             returnUs (lit, stg_rhs)
360
361     default_to_stg discrim NoDefault
362       = returnUs StgNoDefault
363
364     default_to_stg discrim (BindDefault binder rhs)
365       = coreExprToStg env rhs    `thenUs` \ stg_rhs ->
366         returnUs (StgBindDefault binder True{-used? no it is lying-} stg_rhs)
367 \end{code}
368
369 %************************************************************************
370 %*                                                                      *
371 \subsubsection[coreToStg-let(rec)]{Let and letrec expressions}
372 %*                                                                      *
373 %************************************************************************
374
375 \begin{code}
376 coreExprToStg env (Let bind body)
377   = coreBindToStg env     bind   `thenUs` \ (stg_binds, new_env) ->
378     coreExprToStg new_env body   `thenUs` \ stg_body ->
379     returnUs (mkStgLets stg_binds stg_body)
380 \end{code}
381
382
383 %************************************************************************
384 %*                                                                      *
385 \subsubsection[coreToStg-scc]{SCC expressions}
386 %*                                                                      *
387 %************************************************************************
388
389 Covert core @scc@ expression directly to STG @scc@ expression.
390 \begin{code}
391 coreExprToStg env (SCC cc expr)
392   = coreExprToStg env expr   `thenUs` \ stg_expr ->
393     returnUs (StgSCC (coreExprType expr) cc stg_expr)
394 \end{code}
395
396 \begin{code}
397 coreExprToStg env (Coerce c ty expr) = coreExprToStg env expr
398 \end{code}
399
400
401 %************************************************************************
402 %*                                                                      *
403 \subsection[coreToStg-misc]{Miscellaneous helping functions}
404 %*                                                                      *
405 %************************************************************************
406
407 There's not anything interesting we can ASSERT about \tr{var} if it
408 isn't in the StgEnv. (WDP 94/06)
409
410 \begin{code}
411 stgLookup :: StgEnv -> Id -> StgArg
412 stgLookup env var = case (lookupIdEnv env var) of
413                       Nothing   -> StgVarArg var
414                       Just atom -> atom
415 \end{code}
416
417 Invent a fresh @Id@:
418 \begin{code}
419 newStgVar :: Type -> UniqSM Id
420 newStgVar ty
421  = getUnique                    `thenUs` \ uniq ->
422    returnUs (mkSysLocal SLIT("stg") uniq ty noSrcLoc)
423 \end{code}
424
425 \begin{code}
426 mkStgLets ::   [StgBinding]
427             -> StgExpr  -- body of let
428             -> StgExpr
429
430 mkStgLets binds body = foldr StgLet body binds
431
432 -- mk_app spots an StgCon in a function position, 
433 -- and turns it into an StgCon. See notes with
434 -- getArgAmode in CgBindery.
435 mk_app (StgConArg con) args = StgCon con       args bOGUS_LVs
436 mk_app other_fun       args = StgApp other_fun args bOGUS_LVs
437 \end{code}