2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1996
4 \section[StgSyn]{Shared term graph (STG) syntax for spineless-tagless code generation}
6 This data type represents programs just before code generation
7 (conversion to @AbstractC@): basically, what we have is a stylised
8 form of @CoreSyntax@, the style being one that happens to be ideally
9 suited to spineless tagless code generation.
16 GenStgBinding(..), GenStgExpr(..), GenStgRhs(..),
17 GenStgCaseAlts(..), GenStgCaseDefault(..),
22 stgArgOcc, stgUnsatOcc, stgStdHeapOcc, stgNoUpdHeapOcc,
23 stgNormalOcc, stgFakeFunAppOcc,
26 -- a set of synonyms for the most common (only :-) parameterisation
28 StgBinding, StgExpr, StgRhs,
29 StgCaseAlts, StgCaseDefault,
31 pprStgBinding, pprStgBindings,
35 collectFinalStgBinders
38 #include "HsVersions.h"
40 import CostCentre ( showCostCentre, CostCentre )
41 import Id ( idPrimRep, DataCon,
42 GenId{-instance NamedThing-}, Id )
43 import Literal ( literalPrimRep, isLitLitLit, Literal{-instance Outputable-} )
45 import PrimOp ( PrimOp{-instance Outputable-} )
47 import Unique ( pprUnique, Unique )
48 import UniqSet ( isEmptyUniqSet, uniqSetToList, UniqSet )
52 %************************************************************************
54 \subsection{@GenStgBinding@}
56 %************************************************************************
58 As usual, expressions are interesting; other things are boring. Here
59 are the boring things [except note the @GenStgRhs@], parameterised
60 with respect to binder and occurrence information (just as in
64 data GenStgBinding bndr occ
65 = StgNonRec bndr (GenStgRhs bndr occ)
66 | StgRec [(bndr, GenStgRhs bndr occ)]
69 %************************************************************************
71 \subsection{@GenStgArg@}
73 %************************************************************************
79 | StgConArg DataCon -- A nullary data constructor
83 getArgPrimRep (StgVarArg local) = idPrimRep local
84 getArgPrimRep (StgConArg con) = idPrimRep con
85 getArgPrimRep (StgLitArg lit) = literalPrimRep lit
87 isLitLitArg (StgLitArg x) = isLitLitLit x
91 %************************************************************************
93 \subsection{STG expressions}
95 %************************************************************************
97 The @GenStgExpr@ data type is parameterised on binder and occurrence
100 %************************************************************************
102 \subsubsection{@GenStgExpr@ application}
104 %************************************************************************
106 An application is of a function to a list of atoms [not expressions].
107 Operationally, we want to push the arguments on the stack and call the
108 function. (If the arguments were expressions, we would have to build
109 their closures first.)
111 There is no constructor for a lone variable; it would appear as
114 type GenStgLiveVars occ = UniqSet occ
116 data GenStgExpr bndr occ
118 (GenStgArg occ) -- function
119 [GenStgArg occ] -- arguments
120 (GenStgLiveVars occ) -- Live vars in continuation; ie not
121 -- including the function and args
123 -- NB: a literal is: StgApp <lit-atom> [] ...
126 %************************************************************************
128 \subsubsection{@StgCon@ and @StgPrim@---saturated applications}
130 %************************************************************************
132 There are two specialised forms of application, for
133 constructors and primitives.
135 | StgCon -- always saturated
136 Id -- data constructor
138 (GenStgLiveVars occ) -- Live vars in continuation; ie not
139 -- including the constr and args
141 | StgPrim -- always saturated
144 (GenStgLiveVars occ) -- Live vars in continuation; ie not
145 -- including the op and args
147 These forms are to do ``inline versions,'' as it were.
148 An example might be: @f x = x:[]@.
150 %************************************************************************
152 \subsubsection{@GenStgExpr@: case-expressions}
154 %************************************************************************
156 This has the same boxed/unboxed business as Core case expressions.
159 (GenStgExpr bndr occ)
160 -- the thing to examine
162 (GenStgLiveVars occ) -- Live vars of whole case
163 -- expression; i.e., those which mustn't be
166 (GenStgLiveVars occ) -- Live vars of RHSs;
167 -- i.e., those which must be saved before eval.
169 -- note that an alt's constructor's
170 -- binder-variables are NOT counted in the
171 -- free vars for the alt's RHS
173 Unique -- Occasionally needed to compile case
174 -- statements, as the uniq for a local
175 -- variable to hold the tag of a primop with
178 (GenStgCaseAlts bndr occ)
181 %************************************************************************
183 \subsubsection{@GenStgExpr@: @let(rec)@-expressions}
185 %************************************************************************
187 The various forms of let(rec)-expression encode most of the
188 interesting things we want to do.
192 let-closure x = [free-vars] expr [args]
197 let x = (\free-vars -> \args -> expr) free-vars
199 \tr{args} may be empty (and is for most closures). It isn't under
200 circumstances like this:
206 let-closure x = [z] [y] (y+z)
208 The idea is that we compile code for @(y+z)@ in an environment in which
209 @z@ is bound to an offset from \tr{Node}, and @y@ is bound to an
210 offset from the stack pointer.
212 (A let-closure is an @StgLet@ with a @StgRhsClosure@ RHS.)
216 let-constructor x = Constructor [args]
220 (A let-constructor is an @StgLet@ with a @StgRhsCon@ RHS.)
223 Letrec-expressions are essentially the same deal as
224 let-closure/let-constructor, so we use a common structure and
225 distinguish between them with an @is_recursive@ boolean flag.
229 let-unboxed u = an arbitrary arithmetic expression in unboxed values
232 All the stuff on the RHS must be fully evaluated. No function calls either!
234 (We've backed away from this toward case-expressions with
235 suitably-magical alts ...)
238 ~[Advanced stuff here! Not to start with, but makes pattern matching
239 generate more efficient code.]
242 let-escapes-not fail = expr
245 Here the idea is that @e'@ guarantees not to put @fail@ in a data structure,
246 or pass it to another function. All @e'@ will ever do is tail-call @fail@.
247 Rather than build a closure for @fail@, all we need do is to record the stack
248 level at the moment of the @let-escapes-not@; then entering @fail@ is just
249 a matter of adjusting the stack pointer back down to that point and entering
254 f x y = let z = huge-expression in
260 (A let-escapes-not is an @StgLetNoEscape@.)
263 We may eventually want:
265 let-literal x = Literal
269 (ToDo: is this obsolete?)
272 And so the code for let(rec)-things:
275 (GenStgBinding bndr occ) -- right hand sides (see below)
276 (GenStgExpr bndr occ) -- body
278 | StgLetNoEscape -- remember: ``advanced stuff''
279 (GenStgLiveVars occ) -- Live in the whole let-expression
280 -- Mustn't overwrite these stack slots
281 -- *Doesn't* include binders of the let(rec).
283 (GenStgLiveVars occ) -- Live in the right hand sides (only)
284 -- These are the ones which must be saved on
285 -- the stack if they aren't there already
286 -- *Does* include binders of the let(rec) if recursive.
288 (GenStgBinding bndr occ) -- right hand sides (see below)
289 (GenStgExpr bndr occ) -- body
292 %************************************************************************
294 \subsubsection{@GenStgExpr@: @scc@ expressions}
296 %************************************************************************
298 Finally for @scc@ expressions we introduce a new STG construct.
302 Type -- the type of the body
303 CostCentre -- label of SCC expression
304 (GenStgExpr bndr occ) -- scc expression
308 %************************************************************************
310 \subsection{STG right-hand sides}
312 %************************************************************************
314 Here's the rest of the interesting stuff for @StgLet@s; the first
315 flavour is for closures:
317 data GenStgRhs bndr occ
319 CostCentre -- cost centre to be attached (default is CCC)
320 StgBinderInfo -- Info about how this binder is used (see below)
321 [occ] -- non-global free vars; a list, rather than
322 -- a set, because order is important
323 UpdateFlag -- ReEntrant | Updatable | SingleEntry
324 [bndr] -- arguments; if empty, then not a function;
325 -- as above, order is important
326 (GenStgExpr bndr occ) -- body
328 An example may be in order. Consider:
330 let t = \x -> \y -> ... x ... y ... p ... q in e
332 Pulling out the free vars and stylising somewhat, we get the equivalent:
334 let t = (\[p,q] -> \[x,y] -> ... x ... y ... p ...q) p q
336 Stg-operationally, the @[x,y]@ are on the stack, the @[p,q]@ are
337 offsets from @Node@ into the closure, and the code ptr for the closure
338 will be exactly that in parentheses above.
340 The second flavour of right-hand-side is for constructors (simple but important):
343 CostCentre -- Cost centre to be attached (default is CCC).
344 -- Top-level (static) ones will end up with
345 -- DontCareCC, because we don't count static
346 -- data in heap profiles, and we don't set CCC
347 -- from static closure.
349 [GenStgArg occ] -- args
352 Here's the @StgBinderInfo@ type, and its combining op:
357 Bool -- At least one occurrence as an argument
359 Bool -- At least one occurrence in an unsaturated application
361 Bool -- This thing (f) has at least occurrence of the form:
362 -- x = [..] \u [] -> f a b c
363 -- where the application is saturated
365 Bool -- Ditto for non-updatable x.
367 Bool -- At least one fake application occurrence, that is
368 -- an StgApp f args where args is an empty list
369 -- This is due to the fact that we do not have a
370 -- StgVar constructor.
371 -- Used by the lambda lifter.
372 -- True => "at least one unsat app" is True too
374 stgArgOcc = StgBinderInfo True False False False False
375 stgUnsatOcc = StgBinderInfo False True False False False
376 stgStdHeapOcc = StgBinderInfo False False True False False
377 stgNoUpdHeapOcc = StgBinderInfo False False False True False
378 stgNormalOcc = StgBinderInfo False False False False False
379 -- [Andre] can't think of a good name for the last one.
380 stgFakeFunAppOcc = StgBinderInfo False True False False True
382 combineStgBinderInfo :: StgBinderInfo -> StgBinderInfo -> StgBinderInfo
384 combineStgBinderInfo NoStgBinderInfo info2 = info2
385 combineStgBinderInfo info1 NoStgBinderInfo = info1
386 combineStgBinderInfo (StgBinderInfo arg1 unsat1 std_heap1 upd_heap1 fkap1)
387 (StgBinderInfo arg2 unsat2 std_heap2 upd_heap2 fkap2)
388 = StgBinderInfo (arg1 || arg2)
390 (std_heap1 || std_heap2)
391 (upd_heap1 || upd_heap2)
395 %************************************************************************
397 \subsection[Stg-case-alternatives]{STG case alternatives}
399 %************************************************************************
401 Just like in @CoreSyntax@ (except no type-world stuff).
404 data GenStgCaseAlts bndr occ
405 = StgAlgAlts Type -- so we can find out things about constructor family
406 [(Id, -- alts: data constructor,
407 [bndr], -- constructor's parameters,
408 [Bool], -- "use mask", same length as
409 -- parameters; a True in a
410 -- param's position if it is
412 GenStgExpr bndr occ)] -- ...right-hand side.
413 (GenStgCaseDefault bndr occ)
414 | StgPrimAlts Type -- so we can find out things about constructor family
415 [(Literal, -- alts: unboxed literal,
416 GenStgExpr bndr occ)] -- rhs.
417 (GenStgCaseDefault bndr occ)
419 data GenStgCaseDefault bndr occ
420 = StgNoDefault -- small con family: all
421 -- constructor accounted for
422 | StgBindDefault bndr -- form: var -> expr
423 Bool -- True <=> var is used in rhs
424 -- i.e., False <=> "_ -> expr"
425 (GenStgExpr bndr occ)
428 %************************************************************************
430 \subsection[Stg]{The Plain STG parameterisation}
432 %************************************************************************
434 This happens to be the only one we use at the moment.
437 type StgBinding = GenStgBinding Id Id
438 type StgArg = GenStgArg Id
439 type StgLiveVars = GenStgLiveVars Id
440 type StgExpr = GenStgExpr Id Id
441 type StgRhs = GenStgRhs Id Id
442 type StgCaseAlts = GenStgCaseAlts Id Id
443 type StgCaseDefault = GenStgCaseDefault Id Id
446 %************************************************************************
448 \subsubsection[UpdateFlag-datatype]{@UpdateFlag@}
450 %************************************************************************
452 This is also used in @LambdaFormInfo@ in the @ClosureInfo@ module.
455 data UpdateFlag = ReEntrant | Updatable | SingleEntry
457 instance Outputable UpdateFlag where
459 = char (case u of { ReEntrant -> 'r'; Updatable -> 'u'; SingleEntry -> 's' })
462 %************************************************************************
464 \subsection[Stg-utility-functions]{Utility functions}
466 %************************************************************************
469 For doing interfaces, we want the exported top-level Ids from the
470 final pre-codegen STG code, so as to be sure we have the
471 latest/greatest pragma info.
474 collectFinalStgBinders
475 :: [StgBinding] -- input program
478 collectFinalStgBinders [] = []
479 collectFinalStgBinders (StgNonRec b _ : binds) = b : collectFinalStgBinders binds
480 collectFinalStgBinders (StgRec bs : binds) = map fst bs ++ collectFinalStgBinders binds
483 %************************************************************************
485 \subsection[Stg-pretty-printing]{Pretty-printing}
487 %************************************************************************
489 Robin Popplestone asked for semi-colon separators on STG binds; here's
490 hoping he likes terminators instead... Ditto for case alternatives.
493 pprGenStgBinding :: (Outputable bndr, Outputable bdee, Ord bdee)
494 => GenStgBinding bndr bdee -> SDoc
496 pprGenStgBinding (StgNonRec bndr rhs)
497 = hang (hsep [ppr bndr, equals])
498 4 ((<>) (ppr rhs) semi)
500 pprGenStgBinding (StgRec pairs)
501 = vcat ((ifPprDebug (ptext SLIT("{- StgRec (begin) -}"))) :
502 (map (ppr_bind) pairs) ++ [(ifPprDebug (ptext SLIT("{- StgRec (end) -}")))])
504 ppr_bind (bndr, expr)
505 = hang (hsep [ppr bndr, equals])
506 4 ((<>) (ppr expr) semi)
508 pprStgBinding :: StgBinding -> SDoc
509 pprStgBinding bind = pprGenStgBinding bind
511 pprStgBindings :: [StgBinding] -> SDoc
512 pprStgBindings binds = vcat (map (pprGenStgBinding) binds)
516 instance (Outputable bdee) => Outputable (GenStgArg bdee) where
519 instance (Outputable bndr, Outputable bdee, Ord bdee)
520 => Outputable (GenStgBinding bndr bdee) where
521 ppr = pprGenStgBinding
523 instance (Outputable bndr, Outputable bdee, Ord bdee)
524 => Outputable (GenStgExpr bndr bdee) where
527 instance (Outputable bndr, Outputable bdee, Ord bdee)
528 => Outputable (GenStgRhs bndr bdee) where
529 ppr rhs = pprStgRhs rhs
533 pprStgArg :: (Outputable bdee) => GenStgArg bdee -> SDoc
535 pprStgArg (StgVarArg var) = ppr var
536 pprStgArg (StgConArg con) = ppr con
537 pprStgArg (StgLitArg lit) = ppr lit
541 pprStgExpr :: (Outputable bndr, Outputable bdee, Ord bdee)
542 => GenStgExpr bndr bdee -> SDoc
544 pprStgExpr (StgApp func [] lvs)
545 = (<>) (ppr func) (pprStgLVs lvs)
548 pprStgExpr (StgApp func args lvs)
549 = hang ((<>) (ppr func) (pprStgLVs lvs))
550 4 (sep (map (ppr) args))
554 pprStgExpr (StgCon con args lvs)
555 = hcat [ (<>) (ppr con) (pprStgLVs lvs),
556 ptext SLIT("! ["), interppSP args, char ']' ]
558 pprStgExpr (StgPrim op args lvs)
559 = hcat [ ppr op, char '#', pprStgLVs lvs,
560 ptext SLIT(" ["), interppSP args, char ']' ]
564 -- special case: let v = <very specific thing>
570 -- Very special! Suspicious! (SLPJ)
572 pprStgExpr (StgLet (StgNonRec bndr (StgRhsClosure cc bi free_vars upd_flag args rhs))
575 (hang (hcat [ptext SLIT("let { "), ppr bndr, ptext SLIT(" = "),
576 text (showCostCentre True{-as string-} cc),
578 ptext SLIT(" ["), ifPprDebug (interppSP free_vars), ptext SLIT("] \\"),
579 ppr upd_flag, ptext SLIT(" ["),
580 interppSP args, char ']'])
581 8 (sep [hsep [ppr rhs, ptext SLIT("} in")]]))
584 -- special case: let ... in let ...
586 pprStgExpr (StgLet bind expr@(StgLet _ _))
588 (sep [hang (ptext SLIT("let {")) 2 (hsep [pprGenStgBinding bind, ptext SLIT("} in")])])
592 pprStgExpr (StgLet bind expr)
593 = sep [hang (ptext SLIT("let {")) 2 (pprGenStgBinding bind),
594 hang (ptext SLIT("} in ")) 2 (ppr expr)]
596 pprStgExpr (StgLetNoEscape lvs_whole lvs_rhss bind expr)
597 = sep [hang (ptext SLIT("let-no-escape {"))
598 2 (pprGenStgBinding bind),
599 hang ((<>) (ptext SLIT("} in "))
602 hcat [ptext SLIT("-- lvs: ["), interppSP (uniqSetToList lvs_whole),
603 ptext SLIT("]; rhs lvs: ["), interppSP (uniqSetToList lvs_rhss),
609 pprStgExpr (StgSCC ty cc expr)
610 = sep [ hsep [ptext SLIT("_scc_"), text (showCostCentre True{-as string-} cc)],
615 pprStgExpr (StgCase expr lvs_whole lvs_rhss uniq alts)
616 = sep [sep [ptext SLIT("case"),
617 nest 4 (hsep [pprStgExpr expr,
618 ifPprDebug (ptext SLIT("::") <> pp_ty alts)]),
622 hcat [ptext SLIT("-- lvs: ["), interppSP (uniqSetToList lvs_whole),
623 ptext SLIT("]; rhs lvs: ["), interppSP (uniqSetToList lvs_rhss),
624 ptext SLIT("]; uniq: "), pprUnique uniq])),
625 nest 2 (ppr_alts alts),
628 ppr_default StgNoDefault = empty
629 ppr_default (StgBindDefault bndr used expr)
630 = hang (hsep [pp_binder, ptext SLIT("->")]) 4 (ppr expr)
632 pp_binder = if used then ppr bndr else char '_'
634 pp_ty (StgAlgAlts ty _ _) = ppr ty
635 pp_ty (StgPrimAlts ty _ _) = ppr ty
637 ppr_alts (StgAlgAlts ty alts deflt)
638 = vcat [ vcat (map (ppr_bxd_alt) alts),
641 ppr_bxd_alt (con, params, use_mask, expr)
642 = hang (hsep [ppr con, interppSP params, ptext SLIT("->")])
643 4 ((<>) (ppr expr) semi)
645 ppr_alts (StgPrimAlts ty alts deflt)
646 = vcat [ vcat (map (ppr_ubxd_alt) alts),
649 ppr_ubxd_alt (lit, expr)
650 = hang (hsep [ppr lit, ptext SLIT("->")])
651 4 ((<>) (ppr expr) semi)
655 pprStgLVs :: Outputable occ => GenStgLiveVars occ -> SDoc
657 = getPprStyle $ \ sty ->
658 if userStyle sty || isEmptyUniqSet lvs then
661 hcat [text "{-lvs:", interpp'SP (uniqSetToList lvs), text "-}"]
665 pprStgRhs :: (Outputable bndr, Outputable bdee, Ord bdee)
666 => GenStgRhs bndr bdee -> SDoc
669 pprStgRhs (StgRhsClosure cc bi [free_var] upd_flag [{-no args-}] (StgApp func [] lvs))
670 = hcat [ text (showCostCentre True{-as String-} cc),
672 brackets (ifPprDebug (ppr free_var)),
673 ptext SLIT(" \\"), ppr upd_flag, ptext SLIT(" [] "), ppr func ]
676 pprStgRhs (StgRhsClosure cc bi free_vars upd_flag args body)
677 = hang (hcat [text (showCostCentre True{-as String-} cc),
679 brackets (ifPprDebug (interppSP free_vars)),
680 ptext SLIT(" \\"), ppr upd_flag, brackets (interppSP args)])
683 pprStgRhs (StgRhsCon cc con args)
684 = hcat [ text (showCostCentre True{-as String-} cc),
685 space, ppr con, ptext SLIT("! "), brackets (interppSP args)]
689 pp_binder_info NoStgBinderInfo = empty
691 -- cases so boring that we print nothing
692 pp_binder_info (StgBinderInfo True b c d e) = empty
695 pp_binder_info (StgBinderInfo a b c d e)
696 = getPprStyle $ \ sty ->
697 if userStyle sty then
700 parens (hsep (punctuate comma (map ppr [a,b,c,d,e])))
703 Collect @IdInfo@ stuff that is most easily just snaffled straight
704 from the STG bindings.
707 stgArity :: StgRhs -> Int
709 stgArity (StgRhsCon _ _ _) = 0 -- it's a constructor, fully applied
710 stgArity (StgRhsClosure _ _ _ _ args _ ) = length args