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"
19 -- and to make the interface self-sufficient...
22 import AnnCoreSyn -- intermediate form on which all work is done
23 import StgSyn -- output
26 import PrelInfo ( unpackCStringId, unpackCString2Id, stringTy,
27 integerTy, rationalTy, ratioDataCon,
28 PrimOp(..), -- For Int2IntegerOp etc
29 integerZeroId, integerPlusOneId,
30 integerPlusTwoId, integerMinusOneId
31 IF_ATTACK_PRAGMAS(COMMA mkListTy COMMA charTy)
32 IF_ATTACK_PRAGMAS(COMMA tagOf_PrimOp)
33 IF_ATTACK_PRAGMAS(COMMA pprPrimOp)
36 import Type ( isPrimType, isLeakFreeType, getAppDataTyCon )
37 import Bag -- Bag operations
38 import Literal ( mkMachInt, Literal(..) ) -- ToDo: its use is ugly...
39 import CostCentre ( noCostCentre, CostCentre )
40 import Id ( mkSysLocal, idType, isBottomingId
41 IF_ATTACK_PRAGMAS(COMMA bottomIsGuaranteed)
43 import Maybes ( Maybe(..), catMaybes )
44 import Outputable ( isExported )
45 import Pretty -- debugging only!
46 import SpecUtils ( mkSpecialisedCon )
47 import SrcLoc ( SrcLoc, mkUnknownSrcLoc )
52 *************** OVERVIEW *********************
55 The business of this pass is to convert Core to Stg. On the way:
57 * We discard type lambdas and applications. In so doing we discard
58 "trivial" bindings such as
60 where t1, t2 are types
62 * We make the representation of NoRep literals explicit, and
63 float their bindings to the top level
65 * We do *not* pin on the correct free/live var info; that's done later.
66 Instead we use bOGUS_LVS and _FVS as a placeholder.
68 * We convert case x of {...; x' -> ...x'...}
70 case x of {...; _ -> ...x... }
72 See notes in SimplCase.lhs, near simplDefault for the reasoning here.
75 %************************************************************************
77 \subsection[coreToStg-programs]{Converting a core program and core bindings}
79 %************************************************************************
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}
87 type StgEnv = IdEnv StgArg
90 No free/live variable information is pinned on in this pass; it's added
92 we use @bOGUS_LVs@ and @bOGUS_FVs@ as placeholders.
95 bOGUS_LVs :: StgLiveVars
96 bOGUS_LVs = panic "bOGUS_LVs" -- emptyUniqSet (used when pprTracing)
99 bOGUS_FVs = panic "bOGUS_FVs" -- [] (ditto)
103 topCoreBindsToStg :: UniqSupply -- name supply
104 -> [CoreBinding] -- input
105 -> [StgBinding] -- output
107 topCoreBindsToStg us core_binds
108 = case (initUs us (binds_to_stg nullIdEnv core_binds)) of
111 binds_to_stg :: StgEnv -> [CoreBinding] -> UniqSM [StgBinding]
113 binds_to_stg env [] = returnUs []
114 binds_to_stg env (b:bs)
115 = do_top_bind env b `thenUs` \ (new_b, new_env, float_binds) ->
116 binds_to_stg new_env bs `thenUs` \ new_bs ->
117 returnUs (bagToList float_binds ++ -- Literals
121 do_top_bind env bind@(Rec pairs)
122 = coreBindToStg env bind
124 do_top_bind env bind@(NonRec var rhs)
125 = coreBindToStg env bind `thenUs` \ (stg_binds, new_env, float_binds) ->
128 ppr_blah xs = ppInterleave ppComma (map pp_x xs)
129 pp_x (u,x) = ppBesides [pprUnique u, ppStr ": ", ppr PprDebug x]
131 pprTrace "do_top_bind:" (ppAbove (ppr PprDebug stg_binds) (ppr_blah (ufmToList new_env))) $
134 [StgNonRec var (StgRhsClosure cc bi fvs u [] rhs_body)] ->
135 -- Mega-special case; there's still a binding there
136 -- no fvs (of course), *no args*, "let" rhs
138 (extra_float_binds, rhs_body') = seek_liftable [] rhs_body
140 returnUs (extra_float_binds ++
141 [StgNonRec var (StgRhsClosure cc bi fvs u [] rhs_body')],
145 other -> returnUs (stg_binds, new_env, float_binds)
148 -- HACK: look for very simple, obviously-liftable bindings
149 -- that can come up to the top level; those that couldn't
150 -- 'cause they were big-lambda constrained in the Core world.
152 seek_liftable :: [StgBinding] -- accumulator...
153 -> StgExpr -- look for top-lev liftables
154 -> ([StgBinding], StgExpr) -- result
156 seek_liftable acc expr@(StgLet inner_bind body)
157 | is_liftable inner_bind
158 = seek_liftable (inner_bind : acc) body
160 seek_liftable acc other_expr = (reverse acc, other_expr) -- Finished
163 is_liftable (StgNonRec binder (StgRhsClosure _ _ _ _ args body))
164 = not (null args) -- it's manifestly a function...
165 || isLeakFreeType [] (idType binder)
167 -- ToDo: use a decent manifestlyWHNF function for STG?
169 is_whnf (StgCon _ _ _) = True
170 is_whnf (StgApp (StgVarArg v) _ _) = isBottomingId v
171 is_whnf other = False
173 is_liftable (StgRec [(_, StgRhsClosure _ _ _ _ args body)])
174 = not (null args) -- it's manifestly a (recursive) function...
176 is_liftable anything_else = False
179 %************************************************************************
181 \subsection[coreToStg-binds]{Converting bindings}
183 %************************************************************************
186 coreBindToStg :: StgEnv
188 -> UniqSM ([StgBinding], -- Empty or singleton
190 Bag StgBinding) -- Floats
192 coreBindToStg env (NonRec binder rhs)
193 = coreRhsToStg env rhs `thenUs` \ (stg_rhs, rhs_binds) ->
196 -- Binds to return if RHS is trivial
197 triv_binds = if isExported binder then
198 [StgNonRec binder stg_rhs] -- Retain it
203 StgRhsClosure cc bi fvs upd [] (StgApp atom [] lvs) ->
204 -- Trivial RHS, so augment envt, and ditch the binding
205 returnUs (triv_binds, new_env, rhs_binds)
207 new_env = addOneToIdEnv env binder atom
209 StgRhsCon cc con_id [] ->
210 -- Trivial RHS, so augment envt, and ditch the binding
211 returnUs (triv_binds, new_env, rhs_binds)
213 new_env = addOneToIdEnv env binder (StgVarArg con_id)
215 other -> -- Non-trivial RHS, so don't augment envt
216 returnUs ([StgNonRec binder stg_rhs], env, rhs_binds)
218 coreBindToStg env (Rec pairs)
219 = -- NB: *** WE DO NOT CHECK FOR TRIV_BINDS in REC BIND ****
222 (binders, rhss) = unzip pairs
224 mapAndUnzipUs (coreRhsToStg env) rhss `thenUs` \ (stg_rhss, rhs_binds) ->
225 returnUs ([StgRec (binders `zip` stg_rhss)], env, unionManyBags rhs_binds)
229 %************************************************************************
231 \subsection[coreToStg-rhss]{Converting right hand sides}
233 %************************************************************************
236 coreRhsToStg :: StgEnv -> CoreExpr -> UniqSM (StgRhs, Bag StgBinding)
238 coreRhsToStg env core_rhs
239 = coreExprToStg env core_rhs `thenUs` \ (stg_expr, stg_binds) ->
241 let stg_rhs = case stg_expr of
242 StgLet (StgNonRec var1 rhs) (StgApp (StgVarArg var2) [] _)
243 | var1 == var2 -> rhs
244 -- This curious stuff is to unravel what a lambda turns into
245 -- We have to do it this way, rather than spot a lambda in the
248 StgCon con args _ -> StgRhsCon noCostCentre con args
250 other -> StgRhsClosure noCostCentre -- No cost centre (ToDo?)
253 Updatable -- Be pessimistic
257 returnUs (stg_rhs, stg_binds)
261 %************************************************************************
263 \subsection[coreToStg-lits]{Converting literals}
265 %************************************************************************
267 Literals: the NoRep kind need to be de-no-rep'd.
268 We always replace them with a simple variable, and float a suitable
269 binding out to the top level.
271 If an Integer is small enough (Haskell implementations must support
272 Ints in the range $[-2^29+1, 2^29-1]$), wrap it up in @int2Integer@;
273 otherwise, wrap with @litString2Integer@.
276 tARGET_MIN_INT, tARGET_MAX_INT :: Integer
277 tARGET_MIN_INT = -536870912
278 tARGET_MAX_INT = 536870912
280 litToStgArg :: Literal -> UniqSM (StgArg, Bag StgBinding)
282 litToStgArg (NoRepStr s)
283 = newStgVar stringTy `thenUs` \ var ->
285 rhs = StgRhsClosure noCostCentre -- No cost centre (ToDo?)
288 Updatable -- WAS: ReEntrant (see note below)
292 -- We used not to update strings, so that they wouldn't clog up the heap,
293 -- but instead be unpacked each time. But on some programs that costs a lot
294 -- [eg hpg], so now we update them.
296 val = if (any is_NUL (_UNPK_ s)) then -- must cater for NULs in literal string
297 StgApp (StgVarArg unpackCString2Id)
298 [StgLitArg (MachStr s),
299 StgLitArg (mkMachInt (toInteger (_LENGTH_ s)))]
302 StgApp (StgVarArg unpackCStringId)
303 [StgLitArg (MachStr s)]
306 returnUs (StgVarArg var, unitBag (StgNonRec var rhs))
310 litToStgArg (NoRepInteger i)
311 -- extremely convenient to look out for a few very common
313 | i == 0 = returnUs (StgVarArg integerZeroId, emptyBag)
314 | i == 1 = returnUs (StgVarArg integerPlusOneId, emptyBag)
315 | i == 2 = returnUs (StgVarArg integerPlusTwoId, emptyBag)
316 | i == (-1) = returnUs (StgVarArg integerMinusOneId, emptyBag)
319 = newStgVar integerTy `thenUs` \ var ->
321 rhs = StgRhsClosure noCostCentre -- No cost centre (ToDo?)
324 Updatable -- Update an integer
329 | i > tARGET_MIN_INT && i < tARGET_MAX_INT
330 = -- Start from an Int
331 StgPrim Int2IntegerOp [StgLitArg (mkMachInt i)] bOGUS_LVs
334 = -- Start from a string
335 StgPrim Addr2IntegerOp [StgLitArg (MachStr (_PK_ (show i)))] bOGUS_LVs
337 returnUs (StgVarArg var, unitBag (StgNonRec var rhs))
339 litToStgArg (NoRepRational r)
340 = litToStgArg (NoRepInteger (numerator r)) `thenUs` \ (num_atom, binds1) ->
341 litToStgArg (NoRepInteger (denominator r)) `thenUs` \ (denom_atom, binds2) ->
342 newStgVar rationalTy `thenUs` \ var ->
344 rhs = StgRhsCon noCostCentre -- No cost centre (ToDo?)
345 ratioDataCon -- Constructor
346 [num_atom, denom_atom]
348 returnUs (StgVarArg var, binds1 `unionBags`
350 unitBag (StgNonRec var rhs))
352 litToStgArg other_lit = returnUs (StgLitArg other_lit, emptyBag)
356 %************************************************************************
358 \subsection[coreToStg-atoms{Converting atoms}
360 %************************************************************************
363 coreAtomToStg :: StgEnv -> CoreArg -> UniqSM (StgArg, Bag StgBinding)
365 coreAtomToStg env (VarArg var) = returnUs (stgLookup env var, emptyBag)
366 coreAtomToStg env (LitArg lit) = litToStgArg lit
369 There's not anything interesting we can ASSERT about \tr{var} if it
370 isn't in the StgEnv. (WDP 94/06)
372 stgLookup :: StgEnv -> Id -> StgArg
374 stgLookup env var = case (lookupIdEnv env var) of
375 Nothing -> StgVarArg var
379 %************************************************************************
381 \subsection[coreToStg-exprs]{Converting core expressions}
383 %************************************************************************
386 coreExprToStg :: StgEnv
388 -> UniqSM (StgExpr, -- Result
389 Bag StgBinding) -- Float these to top level
393 coreExprToStg env (Lit lit)
394 = litToStgArg lit `thenUs` \ (atom, binds) ->
395 returnUs (StgApp atom [] bOGUS_LVs, binds)
397 coreExprToStg env (Var var)
398 = returnUs (StgApp (stgLookup env var) [] bOGUS_LVs, emptyBag)
400 coreExprToStg env (Con con types args)
401 = mapAndUnzipUs (coreAtomToStg env) args `thenUs` \ (stg_atoms, stg_binds) ->
402 returnUs (StgCon spec_con stg_atoms bOGUS_LVs, unionManyBags stg_binds)
404 spec_con = mkSpecialisedCon con types
406 coreExprToStg env (Prim op tys args)
407 = mapAndUnzipUs (coreAtomToStg env) args `thenUs` \ (stg_atoms, stg_binds) ->
408 returnUs (StgPrim op stg_atoms bOGUS_LVs, unionManyBags stg_binds)
411 %************************************************************************
413 \subsubsection[coreToStg-type-stuff]{Type application and abstraction}
415 %************************************************************************
417 This type information dies in this Core-to-STG translation.
420 coreExprToStg env (CoTyLam tyvar expr) = coreExprToStg env expr
421 coreExprToStg env (CoTyApp expr ty) = coreExprToStg env expr
424 %************************************************************************
426 \subsubsection[coreToStg-lambdas]{Lambda abstractions}
428 %************************************************************************
431 coreExprToStg env expr@(Lam _ _)
432 = coreExprToStg env body `thenUs` \ (stg_body, binds) ->
433 newStgVar (coreExprType expr) `thenUs` \ var ->
435 (StgLet (StgNonRec var (StgRhsClosure noCostCentre
438 ReEntrant -- binders is non-empty
441 (StgApp (StgVarArg var) [] bOGUS_LVs),
444 (binders,body) = collect expr
446 -- Collect lambda-bindings, discarding type abstractions and applications
447 collect (Lam x e) = (x:binders, body) where (binders,body) = collect e
448 collect (CoTyLam _ e) = collect e
449 collect (CoTyApp e _) = collect e
450 collect body = ([], body)
453 %************************************************************************
455 \subsubsection[coreToStg-applications]{Applications}
457 %************************************************************************
460 coreExprToStg env expr@(App _ _)
461 = -- Deal with the arguments
462 mapAndUnzipUs (coreAtomToStg env) args `thenUs` \ (stg_args, arg_binds) ->
464 -- Now deal with the function
466 Var fun_id -> returnUs (StgApp (stgLookup env fun_id) stg_args bOGUS_LVs,
467 unionManyBags arg_binds)
469 other -> -- A non-variable applied to things; better let-bind it.
470 newStgVar (coreExprType fun) `thenUs` \ fun_id ->
471 coreExprToStg env fun `thenUs` \ (stg_fun, fun_binds) ->
473 fun_rhs = StgRhsClosure noCostCentre -- No cost centre (ToDo?)
476 SingleEntry -- Only entered once
480 returnUs (StgLet (StgNonRec fun_id fun_rhs)
481 (StgApp (StgVarArg fun_id) stg_args bOGUS_LVs),
482 unionManyBags arg_binds `unionBags`
485 (fun,args) = collect_args expr []
487 -- Collect arguments, discarding type abstractions and applications
488 collect_args (App fun arg) args = collect_args fun (arg:args)
489 collect_args (CoTyLam _ e) args = collect_args e args
490 collect_args (CoTyApp e _) args = collect_args e args
491 collect_args fun args = (fun, args)
494 %************************************************************************
496 \subsubsection[coreToStg-cases]{Case expressions}
498 %************************************************************************
500 At this point, we *mangle* cases involving fork# and par# in the
501 discriminant. The original templates for these primops (see
502 @PrelVals.lhs@) constructed case expressions with boolean results
503 solely to fool the strictness analyzer, the simplifier, and anyone
504 else who might want to fool with the evaluation order. Now, we
505 believe that once the translation to STG code is performed, our
506 evaluation order is safe. Therefore, we convert expressions of the
520 coreExprToStg env (Case discrim@(Prim op tys args) alts)
521 | funnyParallelOp op =
522 getUnique `thenUs` \ uniq ->
523 coreExprToStg env discrim `thenUs` \ (stg_discrim, discrim_binds) ->
524 alts_to_stg alts `thenUs` \ (stg_alts, alts_binds) ->
531 discrim_binds `unionBags` alts_binds
534 funnyParallelOp SeqOp = True
535 funnyParallelOp ParOp = True
536 funnyParallelOp ForkOp = True
537 funnyParallelOp _ = False
539 discrim_ty = coreExprType discrim
541 alts_to_stg (PrimAlts _ (BindDefault binder rhs))
542 = coreExprToStg env rhs `thenUs` \ (stg_rhs, rhs_binds) ->
544 stg_deflt = StgBindDefault binder False stg_rhs
546 returnUs (StgPrimAlts discrim_ty [] stg_deflt, rhs_binds)
548 -- OK, back to real life...
550 coreExprToStg env (Case discrim alts)
551 = coreExprToStg env discrim `thenUs` \ (stg_discrim, discrim_binds) ->
552 alts_to_stg discrim alts `thenUs` \ (stg_alts, alts_binds) ->
553 getUnique `thenUs` \ uniq ->
560 discrim_binds `unionBags` alts_binds
563 discrim_ty = coreExprType discrim
564 (_, discrim_ty_args, _) = getAppDataTyCon discrim_ty
566 alts_to_stg discrim (AlgAlts alts deflt)
567 = default_to_stg discrim deflt `thenUs` \ (stg_deflt, deflt_binds) ->
568 mapAndUnzipUs boxed_alt_to_stg alts `thenUs` \ (stg_alts, alts_binds) ->
569 returnUs (StgAlgAlts discrim_ty stg_alts stg_deflt,
570 deflt_binds `unionBags` unionManyBags alts_binds)
572 boxed_alt_to_stg (con, bs, rhs)
573 = coreExprToStg env rhs `thenUs` \ (stg_rhs, rhs_binds) ->
574 returnUs ((spec_con, bs, [ True | b <- bs ]{-bogus use mask-}, stg_rhs),
577 spec_con = mkSpecialisedCon con discrim_ty_args
579 alts_to_stg discrim (PrimAlts alts deflt)
580 = default_to_stg discrim deflt `thenUs` \ (stg_deflt,deflt_binds) ->
581 mapAndUnzipUs unboxed_alt_to_stg alts `thenUs` \ (stg_alts, alts_binds) ->
582 returnUs (StgPrimAlts discrim_ty stg_alts stg_deflt,
583 deflt_binds `unionBags` unionManyBags alts_binds)
585 unboxed_alt_to_stg (lit, rhs)
586 = coreExprToStg env rhs `thenUs` \ (stg_rhs, rhs_binds) ->
587 returnUs ((lit, stg_rhs), rhs_binds)
589 default_to_stg discrim NoDefault
590 = returnUs (StgNoDefault, emptyBag)
592 default_to_stg discrim (BindDefault binder rhs)
593 = coreExprToStg new_env rhs `thenUs` \ (stg_rhs, rhs_binds) ->
594 returnUs (StgBindDefault binder True{-used? no it is lying-} stg_rhs,
598 -- We convert case x of {...; x' -> ...x'...}
600 -- case x of {...; _ -> ...x... }
602 -- See notes in SimplCase.lhs, near simplDefault for the reasoning.
603 -- It's quite easily done: simply extend the environment to bind the
604 -- default binder to the scrutinee.
606 new_env = case discrim of
607 Var v -> addOneToIdEnv env binder (stgLookup env v)
611 %************************************************************************
613 \subsubsection[coreToStg-let(rec)]{Let and letrec expressions}
615 %************************************************************************
618 coreExprToStg env (Let bind body)
619 = coreBindToStg env bind `thenUs` \ (stg_binds, new_env, float_binds1) ->
620 coreExprToStg new_env body `thenUs` \ (stg_body, float_binds2) ->
621 returnUs (mkStgLets stg_binds stg_body, float_binds1 `unionBags` float_binds2)
625 %************************************************************************
627 \subsubsection[coreToStg-scc]{SCC expressions}
629 %************************************************************************
631 Covert core @scc@ expression directly to STG @scc@ expression.
633 coreExprToStg env (SCC cc expr)
634 = coreExprToStg env expr `thenUs` \ (stg_expr, binds) ->
635 returnUs (StgSCC (coreExprType expr) cc stg_expr, binds)
639 %************************************************************************
641 \subsection[coreToStg-misc]{Miscellaneous helping functions}
643 %************************************************************************
649 newStgVar :: Type -> UniqSM Id
651 = getUnique `thenUs` \ uniq ->
652 returnUs (mkSysLocal SLIT("stg") uniq ty mkUnknownSrcLoc)
656 mkStgLets :: [StgBinding]
657 -> StgExpr -- body of let
660 mkStgLets binds body = foldr StgLet body binds