2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
4 %************************************************************************
6 \section[CoreToStg]{Converting core syntax to STG syntax}
8 %************************************************************************
10 Convert a @CoreSyntax@ program to a @StgSyntax@ program.
13 module CoreToStg ( topCoreBindsToStg ) where
15 #include "HsVersions.h"
17 import CoreSyn -- input
18 import StgSyn -- output
20 import CoreUtils ( coreExprType )
21 import SimplUtils ( findDefault )
22 import CostCentre ( noCCS )
23 import Id ( Id, mkSysLocal, idType,
24 externallyVisibleId, setIdUnique, idName
26 import DataCon ( DataCon, dataConName, dataConId )
27 import Name ( Name, nameModule, isLocallyDefinedName )
28 import Module ( isDynamicModule )
29 import Const ( Con(..), Literal, isLitLitLit )
31 import Const ( Con(..), isWHNFCon, Literal(..) )
32 import PrimOp ( PrimOp(..) )
33 import Type ( isUnLiftedType, isUnboxedTupleType, Type )
34 import TysPrim ( intPrimTy )
35 import Unique ( Unique, Uniquable(..) )
36 import UniqSupply -- all of it, really
41 *************** OVERVIEW *********************
44 The business of this pass is to convert Core to Stg. On the way:
46 * We discard type lambdas and applications. In so doing we discard
47 "trivial" bindings such as
49 where t1, t2 are types
51 * We don't pin on correct arities any more, because they can be mucked up
52 by the lambda lifter. In particular, the lambda lifter can take a local
53 letrec-bound variable and make it a lambda argument, which shouldn't have
54 an arity. So SetStgVarInfo sets arities now.
56 * We do *not* pin on the correct free/live var info; that's done later.
57 Instead we use bOGUS_LVS and _FVS as a placeholder.
59 [Quite a bit of stuff that used to be here has moved
60 to tidyCorePgm (SimplCore.lhs) SLPJ Nov 96]
63 %************************************************************************
65 \subsection[coreToStg-programs]{Converting a core program and core bindings}
67 %************************************************************************
69 March 98: We keep a small environment to give all locally bound
70 Names new unique ids, since the code generator assumes that binders
71 are unique across a module. (Simplifier doesn't maintain this
72 invariant any longer.)
75 type StgEnv = IdEnv Id
82 No free/live variable information is pinned on in this pass; it's added
84 we use @bOGUS_LVs@ and @bOGUS_FVs@ as placeholders.
87 bOGUS_LVs :: StgLiveVars
88 bOGUS_LVs = panic "bOGUS_LVs" -- emptyUniqSet (used when pprTracing)
91 bOGUS_FVs = panic "bOGUS_FVs" -- [] (ditto)
95 topCoreBindsToStg :: UniqSupply -- name supply
96 -> [CoreBind] -- input
97 -> [StgBinding] -- output
99 topCoreBindsToStg us core_binds
100 = initUs us (coreBindsToStg emptyVarEnv core_binds)
102 coreBindsToStg :: StgEnv -> [CoreBind] -> UniqSM [StgBinding]
104 coreBindsToStg env [] = returnUs []
105 coreBindsToStg env (b:bs)
106 = coreBindToStg env b `thenUs` \ (new_b, new_env) ->
107 coreBindsToStg new_env bs `thenUs` \ new_bs ->
108 returnUs (new_b ++ new_bs)
111 %************************************************************************
113 \subsection[coreToStg-binds]{Converting bindings}
115 %************************************************************************
118 coreBindToStg :: StgEnv
120 -> UniqSM ([StgBinding], -- Empty or singleton
123 coreBindToStg env (NonRec binder rhs)
124 = coreRhsToStg env rhs `thenUs` \ stg_rhs ->
125 newLocalId env binder `thenUs` \ (new_env, new_binder) ->
126 returnUs ([StgNonRec new_binder stg_rhs], new_env)
128 coreBindToStg env (Rec pairs)
129 = newLocalIds env binders `thenUs` \ (env', binders') ->
130 mapUs (coreRhsToStg env') rhss `thenUs` \ stg_rhss ->
131 returnUs ([StgRec (binders' `zip` stg_rhss)], env')
133 (binders, rhss) = unzip pairs
137 %************************************************************************
139 \subsection[coreToStg-rhss]{Converting right hand sides}
141 %************************************************************************
144 coreRhsToStg :: StgEnv -> CoreExpr -> UniqSM StgRhs
146 coreRhsToStg env core_rhs
147 = coreExprToStg env core_rhs `thenUs` \ stg_expr ->
148 returnUs (exprToRhs stg_expr)
150 exprToRhs (StgLet (StgNonRec var1 rhs) (StgApp var2 []))
153 -- This curious stuff is to unravel what a lambda turns into
154 -- We have to do it this way, rather than spot a lambda in the
155 -- incoming rhs. Why? Because trivial bindings might conceal
156 -- what the rhs is actually like.
159 We reject the following candidates for 'static constructor'dom:
161 - any dcon that takes a lit-lit as an arg.
162 - [Win32 DLLs only]: any dcon that is (or takes as arg)
163 that's living in a DLL.
165 These constraints are necessary to ensure that the code
166 generated in the end for the static constructors, which
167 live in the data segment, remain valid - i.e., it has to
168 be constant. For obvious reasons, that's hard to guarantee
169 with lit-lits. The second case of a constructor referring
170 to static closures hiding out in some DLL is an artifact
171 of the way Win32 DLLs handle global DLL variables. A (data)
172 symbol exported from a DLL has to be accessed through a
173 level of indirection at the site of use, so whereas
175 extern StgClosure y_closure;
176 extern StgClosure z_closure;
177 x = { ..., &y_closure, &z_closure };
179 is legal when the symbols are in scope at link-time, it is
180 not when y_closure is in a DLL. So, any potential static
181 closures that refers to stuff that's residing in a DLL
182 will be put in an (updateable) thunk instead.
184 An alternative strategy is to support the generation of
185 constructors (ala C++ static class constructors) which will
186 then be run at load time to fix up static closures.
188 exprToRhs (StgCon (DataCon con) args _)
190 all (not.is_lit_lit) args = StgRhsCon noCCS con args
192 is_dynamic = isDynCon con || any (isDynArg) args
194 is_lit_lit (StgVarArg _) = False
195 is_lit_lit (StgConArg x) =
197 Literal l -> isLitLitLit l
201 = StgRhsClosure noCCS -- No cost centre (ToDo?)
203 noSRT -- figure out later
206 Updatable -- Be pessimistic
210 isDynCon :: DataCon -> Bool
211 isDynCon con = isDynName (dataConName con)
213 isDynArg :: StgArg -> Bool
214 isDynArg (StgVarArg v) = isDynName (idName v)
215 isDynArg (StgConArg con) =
217 DataCon dc -> isDynCon dc
218 Literal l -> isLitLitLit l
221 isDynName :: Name -> Bool
223 not (isLocallyDefinedName nm) &&
224 isDynamicModule (nameModule nm)
230 %************************************************************************
232 \subsection[coreToStg-atoms{Converting atoms}
234 %************************************************************************
237 coreArgsToStg :: StgEnv -> [CoreArg] -> UniqSM ([StgFloatBind], [StgArg])
242 coreArgsToStg env (Type ty : as) -- Discard type arguments
243 = coreArgsToStg env as
245 coreArgsToStg env (a:as)
246 = coreArgToStg env a `thenUs` \ (bs1, a') ->
247 coreArgsToStg env as `thenUs` \ (bs2, as') ->
248 returnUs (bs1 ++ bs2, a' : as')
250 -- This is where we arrange that a non-trivial argument is let-bound
252 coreArgToStg :: StgEnv -> CoreArg -> UniqSM ([StgFloatBind], StgArg)
255 = coreExprToStgFloat env arg `thenUs` \ (binds, arg') ->
256 case (binds, arg') of
257 ([], StgCon con [] _) | isWHNFCon con -> returnUs ([], StgConArg con)
258 ([], StgApp v []) -> returnUs ([], StgVarArg v)
260 -- A non-trivial argument: we must let (or case-bind)
261 -- We don't do the case part here... we leave that to mkStgBinds
263 -- Further complication: if we're converting this binding into
264 -- a case, then try to avoid generating any case-of-case
265 -- expressions by pulling out the floats.
267 newStgVar ty `thenUs` \ v ->
269 then returnUs (binds ++ [CaseBind v arg'], StgVarArg v)
270 else returnUs ([LetBind v (mkStgBinds binds arg')], StgVarArg v)
272 ty = coreExprType arg
277 %************************************************************************
279 \subsection[coreToStg-exprs]{Converting core expressions}
281 %************************************************************************
284 coreExprToStg :: StgEnv -> CoreExpr -> UniqSM StgExpr
286 coreExprToStg env (Var var)
287 = returnUs (StgApp (stgLookup env var) [])
291 %************************************************************************
293 \subsubsection[coreToStg-lambdas]{Lambda abstractions}
295 %************************************************************************
298 coreExprToStg env expr@(Lam _ _)
300 (binders, body) = collectBinders expr
301 id_binders = filter isId binders
303 newLocalIds env id_binders `thenUs` \ (env', binders') ->
304 coreExprToStg env' body `thenUs` \ stg_body ->
306 if null id_binders then -- it was all type/usage binders; tossed
311 -- if the body reduced to a lambda too...
312 (StgLet (StgNonRec var (StgRhsClosure cc bi srt fvs uf args body))
315 returnUs (StgLet (StgNonRec var
327 -- We must let-bind the lambda
328 newStgVar (coreExprType expr) `thenUs` \ var ->
330 (StgLet (StgNonRec var (StgRhsClosure noCCS
334 ReEntrant -- binders is non-empty
340 %************************************************************************
342 \subsubsection[coreToStg-let(rec)]{Let and letrec expressions}
344 %************************************************************************
347 coreExprToStg env (Let bind body)
348 = coreBindToStg env bind `thenUs` \ (stg_binds, new_env) ->
349 coreExprToStg new_env body `thenUs` \ stg_body ->
350 returnUs (foldr StgLet stg_body stg_binds)
354 %************************************************************************
356 \subsubsection[coreToStg-scc]{SCC expressions}
358 %************************************************************************
360 Covert core @scc@ expression directly to STG @scc@ expression.
362 coreExprToStg env (Note (SCC cc) expr)
363 = coreExprToStg env expr `thenUs` \ stg_expr ->
364 returnUs (StgSCC cc stg_expr)
368 coreExprToStg env (Note other_note expr) = coreExprToStg env expr
371 The rest are handled by coreExprStgFloat.
374 coreExprToStg env expr
375 = coreExprToStgFloat env expr `thenUs` \ (binds,stg_expr) ->
376 returnUs (mkStgBinds binds stg_expr)
379 %************************************************************************
381 \subsubsection[coreToStg-applications]{Applications}
383 %************************************************************************
386 coreExprToStgFloat env expr@(App _ _)
388 (fun,args) = collect_args expr []
390 coreArgsToStg env args `thenUs` \ (binds, stg_args) ->
392 -- Now deal with the function
393 case (fun, stg_args) of
394 (Var fun_id, _) -> -- A function Id, so do an StgApp; it's ok if
395 -- there are no arguments.
397 StgApp (stgLookup env fun_id) stg_args)
399 (non_var_fun, []) -> -- No value args, so recurse into the function
401 coreExprToStg env non_var_fun `thenUs` \e ->
404 other -> -- A non-variable applied to things; better let-bind it.
405 newStgVar (coreExprType fun) `thenUs` \ fun_id ->
406 coreExprToStg env fun `thenUs` \ (stg_fun) ->
408 fun_rhs = StgRhsClosure noCCS -- No cost centre (ToDo?)
412 SingleEntry -- Only entered once
417 StgLet (StgNonRec fun_id fun_rhs) $
418 StgApp fun_id stg_args)
421 collect_args (App fun arg) args = collect_args fun (arg:args)
422 collect_args (Note (Coerce _ _) expr) args = collect_args expr args
423 collect_args (Note InlineCall expr) args = collect_args expr args
424 collect_args fun args = (fun, args)
427 %************************************************************************
429 \subsubsection[coreToStg-con]{Constructors}
431 %************************************************************************
434 coreExprToStgFloat env expr@(Con (PrimOp (CCallOp (Right _) a b c)) args)
435 = getUniqueUs `thenUs` \ u ->
436 coreArgsToStg env args `thenUs` \ (binds, stg_atoms) ->
437 let con' = PrimOp (CCallOp (Right u) a b c) in
438 returnUs (binds, StgCon con' stg_atoms (coreExprType expr))
440 coreExprToStgFloat env expr@(Con con args)
441 = coreArgsToStg env args `thenUs` \ (binds, stg_atoms) ->
442 returnUs (binds, StgCon con stg_atoms (coreExprType expr))
445 %************************************************************************
447 \subsubsection[coreToStg-cases]{Case expressions}
449 %************************************************************************
452 coreExprToStgFloat env expr@(Case scrut bndr alts)
453 = coreExprToStgFloat env scrut `thenUs` \ (binds, scrut') ->
454 newLocalId env bndr `thenUs` \ (env', bndr') ->
455 alts_to_stg env' (findDefault alts) `thenUs` \ alts' ->
456 returnUs (binds, mkStgCase scrut' bndr' alts')
458 scrut_ty = idType bndr
459 prim_case = isUnLiftedType scrut_ty && not (isUnboxedTupleType scrut_ty)
461 alts_to_stg env (alts, deflt)
463 = default_to_stg env deflt `thenUs` \ deflt' ->
464 mapUs (prim_alt_to_stg env) alts `thenUs` \ alts' ->
465 returnUs (StgPrimAlts scrut_ty alts' deflt')
468 = default_to_stg env deflt `thenUs` \ deflt' ->
469 mapUs (alg_alt_to_stg env) alts `thenUs` \ alts' ->
470 returnUs (StgAlgAlts scrut_ty alts' deflt')
472 alg_alt_to_stg env (DataCon con, bs, rhs)
473 = coreExprToStg env rhs `thenUs` \ stg_rhs ->
474 returnUs (con, filter isId bs, [ True | b <- bs ]{-bogus use mask-}, stg_rhs)
475 -- NB the filter isId. Some of the binders may be
476 -- existential type variables, which STG doesn't care about
478 prim_alt_to_stg env (Literal lit, args, rhs)
479 = ASSERT( null args )
480 coreExprToStg env rhs `thenUs` \ stg_rhs ->
481 returnUs (lit, stg_rhs)
483 default_to_stg env Nothing
484 = returnUs StgNoDefault
486 default_to_stg env (Just rhs)
487 = coreExprToStg env rhs `thenUs` \ stg_rhs ->
488 returnUs (StgBindDefault stg_rhs)
489 -- The binder is used for prim cases and not otherwise
490 -- (hack for old code gen)
494 coreExprToStgFloat env expr
495 = coreExprToStg env expr `thenUs` \stg_expr ->
496 returnUs ([], stg_expr)
499 %************************************************************************
501 \subsection[coreToStg-misc]{Miscellaneous helping functions}
503 %************************************************************************
505 There's not anything interesting we can ASSERT about \tr{var} if it
506 isn't in the StgEnv. (WDP 94/06)
509 stgLookup :: StgEnv -> Id -> Id
510 stgLookup env var = case (lookupVarEnv env var) of
517 newStgVar :: Type -> UniqSM Id
519 = getUniqueUs `thenUs` \ uniq ->
520 returnUs (mkSysLocal SLIT("stg") uniq ty)
525 | externallyVisibleId id
529 = -- Local binder, give it a new unique Id.
530 getUniqueUs `thenUs` \ uniq ->
532 id' = setIdUnique id uniq
533 new_env = extendVarEnv env id id'
535 returnUs (new_env, id')
537 newLocalIds :: StgEnv -> [Id] -> UniqSM (StgEnv, [Id])
540 newLocalIds env (b:bs)
541 = newLocalId env b `thenUs` \ (env', b') ->
542 newLocalIds env' bs `thenUs` \ (env'', bs') ->
543 returnUs (env'', b':bs')
548 mkStgBinds :: [StgFloatBind] -> StgExpr -> StgExpr
549 mkStgBinds binds body = foldr mkStgBind body binds
551 mkStgBind (CaseBind bndr rhs) body
552 | isUnLiftedType bndr_ty
553 = mkStgCase rhs bndr (StgPrimAlts bndr_ty [] (StgBindDefault body))
555 = mkStgCase rhs bndr (StgAlgAlts bndr_ty [] (StgBindDefault body))
557 bndr_ty = idType bndr
559 mkStgBind (LetBind bndr rhs) body
560 | isUnboxedTupleType bndr_ty
561 = panic "mkStgBinds: unboxed tuple"
562 | isUnLiftedType bndr_ty
563 = mkStgCase rhs bndr (StgPrimAlts bndr_ty [] (StgBindDefault body))
566 = StgLet (StgNonRec bndr (exprToRhs rhs)) body
568 bndr_ty = idType bndr
570 mkStgCase (StgLet bind expr) bndr alts
571 = StgLet bind (mkStgCase expr bndr alts)
572 mkStgCase scrut bndr alts
573 = StgCase scrut bOGUS_LVs bOGUS_LVs bndr noSRT alts