2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 %************************************************************************
6 \section[CoreToStg]{Converting core syntax to STG syntax}
8 %************************************************************************
10 Convert a @CoreSyntax@ program to a @StgSyntax@ program.
14 #include "HsVersions.h"
16 module CoreToStg ( topCoreBindsToStg ) where
20 import CoreSyn -- input
21 import StgSyn -- output
23 import Bag ( emptyBag, unitBag, unionBags, unionManyBags, bagToList )
24 import CoreUtils ( coreExprType )
25 import CostCentre ( noCostCentre )
26 import Id ( mkSysLocal, idType, isBottomingId,
27 nullIdEnv, addOneToIdEnv, lookupIdEnv,
28 IdEnv(..), GenId{-instance NamedThing-}
30 import Literal ( mkMachInt, Literal(..) )
31 import Name ( isExported )
32 import PrelVals ( unpackCStringId, unpackCString2Id,
33 integerZeroId, integerPlusOneId,
34 integerPlusTwoId, integerMinusOneId
36 import PrimOp ( PrimOp(..) )
37 import SpecUtils ( mkSpecialisedCon )
38 import SrcLoc ( mkUnknownSrcLoc )
39 import TyCon ( TyCon{-instance Uniquable-} )
40 import Type ( maybeAppDataTyCon, getAppDataTyConExpandingDicts )
41 import TysWiredIn ( stringTy )
42 import Unique ( integerTyConKey, ratioTyConKey, Unique{-instance Eq-} )
43 import UniqSupply -- all of it, really
44 import Util ( panic, assertPanic, pprTrace{-ToDo:rm-} )
45 import Pretty--ToDo:rm
46 import PprStyle--ToDo:rm
47 import PprType --ToDo:rm
48 import Outputable--ToDo:rm
49 import PprEnv--ToDo:rm
51 isLeakFreeType x y = False -- safe option; ToDo
55 *************** OVERVIEW *********************
58 The business of this pass is to convert Core to Stg. On the way:
60 * We discard type lambdas and applications. In so doing we discard
61 "trivial" bindings such as
63 where t1, t2 are types
65 * We make the representation of NoRep literals explicit, and
66 float their bindings to the top level
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.
71 * We convert case x of {...; x' -> ...x'...}
73 case x of {...; _ -> ...x... }
75 See notes in SimplCase.lhs, near simplDefault for the reasoning here.
78 %************************************************************************
80 \subsection[coreToStg-programs]{Converting a core program and core bindings}
82 %************************************************************************
84 Because we're going to come across ``boring'' bindings like
85 \tr{let x = /\ tyvars -> y in ...}, we want to keep a small
86 environment, so we can just replace all occurrences of \tr{x}
90 type StgEnv = IdEnv StgArg
93 No free/live variable information is pinned on in this pass; it's added
95 we use @bOGUS_LVs@ and @bOGUS_FVs@ as placeholders.
98 bOGUS_LVs :: StgLiveVars
99 bOGUS_LVs = panic "bOGUS_LVs" -- emptyUniqSet (used when pprTracing)
102 bOGUS_FVs = panic "bOGUS_FVs" -- [] (ditto)
106 topCoreBindsToStg :: UniqSupply -- name supply
107 -> [CoreBinding] -- input
108 -> [StgBinding] -- output
110 topCoreBindsToStg us core_binds
111 = case (initUs us (binds_to_stg nullIdEnv core_binds)) of
114 binds_to_stg :: StgEnv -> [CoreBinding] -> UniqSM [StgBinding]
116 binds_to_stg env [] = returnUs []
117 binds_to_stg env (b:bs)
118 = do_top_bind env b `thenUs` \ (new_b, new_env, float_binds) ->
119 binds_to_stg new_env bs `thenUs` \ new_bs ->
120 returnUs (bagToList float_binds ++ -- Literals
124 do_top_bind env bind@(Rec pairs)
125 = coreBindToStg env bind
127 do_top_bind env bind@(NonRec var rhs)
128 = coreBindToStg env bind `thenUs` \ (stg_binds, new_env, float_binds) ->
131 ppr_blah xs = ppInterleave ppComma (map pp_x xs)
132 pp_x (u,x) = ppBesides [pprUnique u, ppStr ": ", ppr PprDebug x]
134 pprTrace "do_top_bind:" (ppAbove (ppr PprDebug stg_binds) (ppr_blah (ufmToList new_env))) $
137 [StgNonRec var (StgRhsClosure cc bi fvs u [] rhs_body)] ->
138 -- Mega-special case; there's still a binding there
139 -- no fvs (of course), *no args*, "let" rhs
141 (extra_float_binds, rhs_body') = seek_liftable [] rhs_body
143 returnUs (extra_float_binds ++
144 [StgNonRec var (StgRhsClosure cc bi fvs u [] rhs_body')],
148 other -> returnUs (stg_binds, new_env, float_binds)
151 -- HACK: look for very simple, obviously-liftable bindings
152 -- that can come up to the top level; those that couldn't
153 -- 'cause they were big-lambda constrained in the Core world.
155 seek_liftable :: [StgBinding] -- accumulator...
156 -> StgExpr -- look for top-lev liftables
157 -> ([StgBinding], StgExpr) -- result
159 seek_liftable acc expr@(StgLet inner_bind body)
160 | is_liftable inner_bind
161 = seek_liftable (inner_bind : acc) body
163 seek_liftable acc other_expr = (reverse acc, other_expr) -- Finished
166 is_liftable (StgNonRec binder (StgRhsClosure _ _ _ _ args body))
167 = not (null args) -- it's manifestly a function...
168 || isLeakFreeType [] (idType binder)
170 -- ToDo: use a decent manifestlyWHNF function for STG?
172 is_whnf (StgCon _ _ _) = True
173 is_whnf (StgApp (StgVarArg v) _ _) = isBottomingId v
174 is_whnf other = False
176 is_liftable (StgRec [(_, StgRhsClosure _ _ _ _ args body)])
177 = not (null args) -- it's manifestly a (recursive) function...
179 is_liftable anything_else = False
182 %************************************************************************
184 \subsection[coreToStg-binds]{Converting bindings}
186 %************************************************************************
189 coreBindToStg :: StgEnv
191 -> UniqSM ([StgBinding], -- Empty or singleton
193 Bag StgBinding) -- Floats
195 coreBindToStg env (NonRec binder rhs)
196 = coreRhsToStg env rhs `thenUs` \ (stg_rhs, rhs_binds) ->
199 -- Binds to return if RHS is trivial
200 triv_binds = if isExported binder then
201 [StgNonRec binder stg_rhs] -- Retain it
205 -- pprTrace "coreBindToStg:" (ppCat [ppr PprDebug binder, ppr PprDebug (isExported binder)]) $
207 StgRhsClosure cc bi fvs upd [] (StgApp atom [] lvs) ->
208 -- Trivial RHS, so augment envt, and ditch the binding
209 returnUs (triv_binds, new_env, rhs_binds)
211 new_env = addOneToIdEnv env binder atom
213 StgRhsCon cc con_id [] ->
214 -- Trivial RHS, so augment envt, and ditch the binding
215 returnUs (triv_binds, new_env, rhs_binds)
217 new_env = addOneToIdEnv env binder (StgVarArg con_id)
219 other -> -- Non-trivial RHS, so don't augment envt
220 returnUs ([StgNonRec binder stg_rhs], env, rhs_binds)
222 coreBindToStg env (Rec pairs)
223 = -- NB: *** WE DO NOT CHECK FOR TRIV_BINDS in REC BIND ****
226 (binders, rhss) = unzip pairs
228 mapAndUnzipUs (coreRhsToStg env) rhss `thenUs` \ (stg_rhss, rhs_binds) ->
229 returnUs ([StgRec (binders `zip` stg_rhss)], env, unionManyBags rhs_binds)
233 %************************************************************************
235 \subsection[coreToStg-rhss]{Converting right hand sides}
237 %************************************************************************
240 coreRhsToStg :: StgEnv -> CoreExpr -> UniqSM (StgRhs, Bag StgBinding)
242 coreRhsToStg env core_rhs
243 = coreExprToStg env core_rhs `thenUs` \ (stg_expr, stg_binds) ->
245 let stg_rhs = case stg_expr of
246 StgLet (StgNonRec var1 rhs) (StgApp (StgVarArg var2) [] _)
247 | var1 == var2 -> rhs
248 -- This curious stuff is to unravel what a lambda turns into
249 -- We have to do it this way, rather than spot a lambda in the
252 StgCon con args _ -> StgRhsCon noCostCentre con args
254 other -> StgRhsClosure noCostCentre -- No cost centre (ToDo?)
257 Updatable -- Be pessimistic
261 returnUs (stg_rhs, stg_binds)
265 %************************************************************************
267 \subsection[coreToStg-lits]{Converting literals}
269 %************************************************************************
271 Literals: the NoRep kind need to be de-no-rep'd.
272 We always replace them with a simple variable, and float a suitable
273 binding out to the top level.
275 If an Integer is small enough (Haskell implementations must support
276 Ints in the range $[-2^29+1, 2^29-1]$), wrap it up in @int2Integer@;
277 otherwise, wrap with @litString2Integer@.
280 tARGET_MIN_INT, tARGET_MAX_INT :: Integer
281 tARGET_MIN_INT = -536870912
282 tARGET_MAX_INT = 536870912
284 litToStgArg :: Literal -> UniqSM (StgArg, Bag StgBinding)
286 litToStgArg (NoRepStr s)
287 = newStgVar stringTy `thenUs` \ var ->
289 rhs = StgRhsClosure noCostCentre -- No cost centre (ToDo?)
292 Updatable -- WAS: ReEntrant (see note below)
296 -- We used not to update strings, so that they wouldn't clog up the heap,
297 -- but instead be unpacked each time. But on some programs that costs a lot
298 -- [eg hpg], so now we update them.
300 val = if (any is_NUL (_UNPK_ s)) then -- must cater for NULs in literal string
301 StgApp (StgVarArg unpackCString2Id)
302 [StgLitArg (MachStr s),
303 StgLitArg (mkMachInt (toInteger (_LENGTH_ s)))]
306 StgApp (StgVarArg unpackCStringId)
307 [StgLitArg (MachStr s)]
310 returnUs (StgVarArg var, unitBag (StgNonRec var rhs))
314 litToStgArg (NoRepInteger i integer_ty)
315 -- extremely convenient to look out for a few very common
317 | i == 0 = returnUs (StgVarArg integerZeroId, emptyBag)
318 | i == 1 = returnUs (StgVarArg integerPlusOneId, emptyBag)
319 | i == 2 = returnUs (StgVarArg integerPlusTwoId, emptyBag)
320 | i == (-1) = returnUs (StgVarArg integerMinusOneId, emptyBag)
323 = newStgVar integer_ty `thenUs` \ var ->
325 rhs = StgRhsClosure noCostCentre -- No cost centre (ToDo?)
328 Updatable -- Update an integer
333 | i > tARGET_MIN_INT && i < tARGET_MAX_INT
334 = -- Start from an Int
335 StgPrim Int2IntegerOp [StgLitArg (mkMachInt i)] bOGUS_LVs
338 = -- Start from a string
339 StgPrim Addr2IntegerOp [StgLitArg (MachStr (_PK_ (show i)))] bOGUS_LVs
341 returnUs (StgVarArg var, unitBag (StgNonRec var rhs))
343 litToStgArg (NoRepRational r rational_ty)
344 = --ASSERT(is_rational_ty)
345 (if is_rational_ty then \x->x else pprTrace "litToStgArg:not rational?" (pprType PprDebug rational_ty)) $
346 litToStgArg (NoRepInteger (numerator r) integer_ty) `thenUs` \ (num_atom, binds1) ->
347 litToStgArg (NoRepInteger (denominator r) integer_ty) `thenUs` \ (denom_atom, binds2) ->
348 newStgVar rational_ty `thenUs` \ var ->
350 rhs = StgRhsCon noCostCentre -- No cost centre (ToDo?)
351 ratio_data_con -- Constructor
352 [num_atom, denom_atom]
354 returnUs (StgVarArg var, binds1 `unionBags`
356 unitBag (StgNonRec var rhs))
358 (is_rational_ty, ratio_data_con, integer_ty)
359 = case (maybeAppDataTyCon rational_ty) of
360 Just (tycon, [i_ty], [con])
361 -> ASSERT(is_integer_ty i_ty)
362 (uniqueOf tycon == ratioTyConKey, con, i_ty)
364 _ -> (False, panic "ratio_data_con", panic "integer_ty")
367 = case (maybeAppDataTyCon ty) of
368 Just (tycon, [], _) -> uniqueOf tycon == integerTyConKey
371 litToStgArg other_lit = returnUs (StgLitArg other_lit, emptyBag)
375 %************************************************************************
377 \subsection[coreToStg-atoms{Converting atoms}
379 %************************************************************************
382 coreArgsToStg :: StgEnv -> [CoreArg] -> UniqSM ([Type], [StgArg], Bag StgBinding)
384 coreArgsToStg env [] = returnUs ([], [], emptyBag)
385 coreArgsToStg env (a:as)
386 = coreArgsToStg env as `thenUs` \ (tys, args, binds) ->
387 do_arg a tys args binds
389 do_arg a trest vrest binds
391 TyArg t -> returnUs (t:trest, vrest, binds)
392 UsageArg u -> returnUs (trest, vrest, binds)
393 VarArg v -> returnUs (trest, stgLookup env v : vrest, binds)
394 LitArg i -> litToStgArg i `thenUs` \ (v, bs) ->
395 returnUs (trest, v:vrest, bs `unionBags` binds)
398 There's not anything interesting we can ASSERT about \tr{var} if it
399 isn't in the StgEnv. (WDP 94/06)
401 stgLookup :: StgEnv -> Id -> StgArg
403 stgLookup env var = case (lookupIdEnv env var) of
404 Nothing -> StgVarArg var
408 %************************************************************************
410 \subsection[coreToStg-exprs]{Converting core expressions}
412 %************************************************************************
415 coreExprToStg :: StgEnv
417 -> UniqSM (StgExpr, -- Result
418 Bag StgBinding) -- Float these to top level
422 coreExprToStg env (Lit lit)
423 = litToStgArg lit `thenUs` \ (atom, binds) ->
424 returnUs (StgApp atom [] bOGUS_LVs, binds)
426 coreExprToStg env (Var var)
427 = returnUs (StgApp (stgLookup env var) [] bOGUS_LVs, emptyBag)
429 coreExprToStg env (Con con args)
430 = coreArgsToStg env args `thenUs` \ (types, stg_atoms, stg_binds) ->
432 spec_con = mkSpecialisedCon con types
434 returnUs (StgCon spec_con stg_atoms bOGUS_LVs, stg_binds)
436 coreExprToStg env (Prim op args)
437 = coreArgsToStg env args `thenUs` \ (_, stg_atoms, stg_binds) ->
438 returnUs (StgPrim op stg_atoms bOGUS_LVs, stg_binds)
441 %************************************************************************
443 \subsubsection[coreToStg-lambdas]{Lambda abstractions}
445 %************************************************************************
448 coreExprToStg env expr@(Lam _ _)
450 (_,_, binders, body) = collectBinders expr
452 coreExprToStg env body `thenUs` \ stuff@(stg_body, binds) ->
454 if null binders then -- it was all type/usage binders; tossed
457 newStgVar (coreExprType expr) `thenUs` \ var ->
459 (StgLet (StgNonRec var (StgRhsClosure noCostCentre
462 ReEntrant -- binders is non-empty
465 (StgApp (StgVarArg var) [] bOGUS_LVs),
469 %************************************************************************
471 \subsubsection[coreToStg-applications]{Applications}
473 %************************************************************************
476 coreExprToStg env expr@(App _ _)
478 (fun, _, _, args) = collectArgs expr
480 -- Deal with the arguments
481 coreArgsToStg env args `thenUs` \ (_, stg_args, arg_binds) ->
483 -- Now deal with the function
485 Var fun_id -> returnUs (StgApp (stgLookup env fun_id) stg_args bOGUS_LVs, arg_binds)
487 other -> -- A non-variable applied to things; better let-bind it.
488 newStgVar (coreExprType fun) `thenUs` \ fun_id ->
489 coreExprToStg env fun `thenUs` \ (stg_fun, fun_binds) ->
491 fun_rhs = StgRhsClosure noCostCentre -- No cost centre (ToDo?)
494 SingleEntry -- Only entered once
498 returnUs (StgLet (StgNonRec fun_id fun_rhs)
499 (StgApp (StgVarArg fun_id) stg_args bOGUS_LVs),
500 arg_binds `unionBags` fun_binds)
503 %************************************************************************
505 \subsubsection[coreToStg-cases]{Case expressions}
507 %************************************************************************
509 At this point, we *mangle* cases involving fork# and par# in the
510 discriminant. The original templates for these primops (see
511 @PrelVals.lhs@) constructed case expressions with boolean results
512 solely to fool the strictness analyzer, the simplifier, and anyone
513 else who might want to fool with the evaluation order. Now, we
514 believe that once the translation to STG code is performed, our
515 evaluation order is safe. Therefore, we convert expressions of the
529 coreExprToStg env (Case discrim@(Prim op _) alts)
531 = getUnique `thenUs` \ uniq ->
532 coreExprToStg env discrim `thenUs` \ (stg_discrim, discrim_binds) ->
533 alts_to_stg alts `thenUs` \ (stg_alts, alts_binds) ->
540 discrim_binds `unionBags` alts_binds
543 funnyParallelOp SeqOp = True
544 funnyParallelOp ParOp = True
545 funnyParallelOp ForkOp = True
546 funnyParallelOp _ = False
548 discrim_ty = coreExprType discrim
550 alts_to_stg (PrimAlts _ (BindDefault binder rhs))
551 = coreExprToStg env rhs `thenUs` \ (stg_rhs, rhs_binds) ->
553 stg_deflt = StgBindDefault binder False stg_rhs
555 returnUs (StgPrimAlts discrim_ty [] stg_deflt, rhs_binds)
557 -- OK, back to real life...
559 coreExprToStg env (Case discrim alts)
560 = coreExprToStg env discrim `thenUs` \ (stg_discrim, discrim_binds) ->
561 alts_to_stg discrim alts `thenUs` \ (stg_alts, alts_binds) ->
562 getUnique `thenUs` \ uniq ->
569 discrim_binds `unionBags` alts_binds
572 discrim_ty = coreExprType discrim
573 (_, discrim_ty_args, _) = getAppDataTyConExpandingDicts discrim_ty
575 alts_to_stg discrim (AlgAlts alts deflt)
576 = default_to_stg discrim deflt `thenUs` \ (stg_deflt, deflt_binds) ->
577 mapAndUnzipUs boxed_alt_to_stg alts `thenUs` \ (stg_alts, alts_binds) ->
578 returnUs (StgAlgAlts discrim_ty stg_alts stg_deflt,
579 deflt_binds `unionBags` unionManyBags alts_binds)
581 boxed_alt_to_stg (con, bs, rhs)
582 = coreExprToStg env rhs `thenUs` \ (stg_rhs, rhs_binds) ->
583 returnUs ((spec_con, bs, [ True | b <- bs ]{-bogus use mask-}, stg_rhs),
586 spec_con = mkSpecialisedCon con discrim_ty_args
588 alts_to_stg discrim (PrimAlts alts deflt)
589 = default_to_stg discrim deflt `thenUs` \ (stg_deflt,deflt_binds) ->
590 mapAndUnzipUs unboxed_alt_to_stg alts `thenUs` \ (stg_alts, alts_binds) ->
591 returnUs (StgPrimAlts discrim_ty stg_alts stg_deflt,
592 deflt_binds `unionBags` unionManyBags alts_binds)
594 unboxed_alt_to_stg (lit, rhs)
595 = coreExprToStg env rhs `thenUs` \ (stg_rhs, rhs_binds) ->
596 returnUs ((lit, stg_rhs), rhs_binds)
598 default_to_stg discrim NoDefault
599 = returnUs (StgNoDefault, emptyBag)
601 default_to_stg discrim (BindDefault binder rhs)
602 = coreExprToStg new_env rhs `thenUs` \ (stg_rhs, rhs_binds) ->
603 returnUs (StgBindDefault binder True{-used? no it is lying-} stg_rhs,
607 -- We convert case x of {...; x' -> ...x'...}
609 -- case x of {...; _ -> ...x... }
611 -- See notes in SimplCase.lhs, near simplDefault for the reasoning.
612 -- It's quite easily done: simply extend the environment to bind the
613 -- default binder to the scrutinee.
615 new_env = case discrim of
616 Var v -> addOneToIdEnv env binder (stgLookup env v)
620 %************************************************************************
622 \subsubsection[coreToStg-let(rec)]{Let and letrec expressions}
624 %************************************************************************
627 coreExprToStg env (Let bind body)
628 = coreBindToStg env bind `thenUs` \ (stg_binds, new_env, float_binds1) ->
629 coreExprToStg new_env body `thenUs` \ (stg_body, float_binds2) ->
630 returnUs (mkStgLets stg_binds stg_body, float_binds1 `unionBags` float_binds2)
634 %************************************************************************
636 \subsubsection[coreToStg-scc]{SCC expressions}
638 %************************************************************************
640 Covert core @scc@ expression directly to STG @scc@ expression.
642 coreExprToStg env (SCC cc expr)
643 = coreExprToStg env expr `thenUs` \ (stg_expr, binds) ->
644 returnUs (StgSCC (coreExprType expr) cc stg_expr, binds)
648 coreExprToStg env (Coerce c ty expr)
649 = coreExprToStg env expr -- `thenUs` \ (stg_expr, binds) ->
650 -- returnUs (StgSCC (coreExprType expr) cc stg_expr, binds)
654 %************************************************************************
656 \subsection[coreToStg-misc]{Miscellaneous helping functions}
658 %************************************************************************
664 newStgVar :: Type -> UniqSM Id
666 = getUnique `thenUs` \ uniq ->
667 returnUs (mkSysLocal SLIT("stg") uniq ty mkUnknownSrcLoc)
671 mkStgLets :: [StgBinding]
672 -> StgExpr -- body of let
675 mkStgLets binds body = foldr StgLet body binds