root/compiler/stgSyn/StgSyn.lhs

Revision 155ce292c6a057b6338e9baa2affb93d1eebb465, 29.5 KB (checked in by David Terei <davidterei@…>, 5 months ago)

Fix haddock validate problem.

  • Property mode set to 100644
Line 
1%
2% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
3%
4\section[StgSyn]{Shared term graph (STG) syntax for spineless-tagless code generation}
5
6This data type represents programs just before code generation (conversion to
7@Cmm@): basically, what we have is a stylised form of @CoreSyntax@, the style
8being one that happens to be ideally suited to spineless tagless code
9generation.
10
11\begin{code}
12
13module StgSyn (
14        GenStgArg(..),
15        GenStgLiveVars,
16
17        GenStgBinding(..), GenStgExpr(..), GenStgRhs(..),
18        GenStgAlt, AltType(..),
19
20        UpdateFlag(..), isUpdatable,
21
22        StgBinderInfo,
23        noBinderInfo, stgSatOcc, stgUnsatOcc, satCallsOnly,
24        combineStgBinderInfo,
25
26        -- a set of synonyms for the most common (only :-) parameterisation
27        StgArg, StgLiveVars,
28        StgBinding, StgExpr, StgRhs, StgAlt,
29
30        -- StgOp
31        StgOp(..),
32
33        -- SRTs
34        SRT(..),
35
36        -- utils
37        stgBindHasCafRefs, stgArgHasCafRefs, stgRhsArity,
38        isDllConApp, isStgTypeArg,
39        stgArgType,
40
41        pprStgBinding, pprStgBindings, pprStgBindingsWithSRTs,
42        pprStgLVs
43    ) where
44
45#include "HsVersions.h"
46
47import Bitmap
48import CoreSyn     ( AltCon )
49import CostCentre  ( CostCentreStack, CostCentre )
50import DataCon
51import DynFlags
52import FastString
53import ForeignCall ( ForeignCall )
54import Id
55import IdInfo      ( mayHaveCafRefs )
56import Literal     ( Literal, literalType )
57import Module
58import Outputable
59import Packages    ( isDllName )
60import Platform
61import PprCore     ( {- instances -} )
62import PrimOp      ( PrimOp, PrimCall )
63import StaticFlags ( opt_SccProfilingOn )
64import TyCon       ( PrimRep(..) )
65import TyCon       ( TyCon )
66import Type        ( Type )
67import Type        ( typePrimRep )
68import UniqSet
69import Unique      ( Unique )
70import VarSet      ( IdSet, isEmptyVarSet )
71\end{code}
72
73%************************************************************************
74%*                                                                      *
75\subsection{@GenStgBinding@}
76%*                                                                      *
77%************************************************************************
78
79As usual, expressions are interesting; other things are boring. Here
80are the boring things [except note the @GenStgRhs@], parameterised
81with respect to binder and occurrence information (just as in
82@CoreSyn@):
83
84There is one SRT for each group of bindings.
85
86\begin{code}
87data GenStgBinding bndr occ
88  = StgNonRec bndr (GenStgRhs bndr occ)
89  | StgRec    [(bndr, GenStgRhs bndr occ)]
90\end{code}
91
92%************************************************************************
93%*                                                                      *
94\subsection{@GenStgArg@}
95%*                                                                      *
96%************************************************************************
97
98\begin{code}
99data GenStgArg occ
100  = StgVarArg  occ
101  | StgLitArg  Literal
102  | StgTypeArg Type     -- For when we want to preserve all type info
103
104isStgTypeArg :: StgArg -> Bool
105isStgTypeArg (StgTypeArg _) = True
106isStgTypeArg _              = False
107
108-- | Does this constructor application refer to
109-- anything in a different *Windows* DLL?
110-- If so, we can't allocate it statically
111isDllConApp :: DynFlags -> DataCon -> [StgArg] -> Bool
112isDllConApp dflags con args
113 | platformOS (targetPlatform dflags) == OSMinGW32
114    = isDllName this_pkg (dataConName con) || any is_dll_arg args
115 | otherwise = False
116  where
117    is_dll_arg :: StgArg -> Bool
118    is_dll_arg (StgVarArg v) =  isAddrRep (typePrimRep (idType v))
119                             && isDllName this_pkg (idName v)
120    is_dll_arg _             = False
121
122    this_pkg = thisPackage dflags
123
124-- True of machine adddresses; these are the things that don't
125-- work across DLLs. The key point here is that VoidRep comes
126-- out False, so that a top level nullary GADT construtor is
127-- False for isDllConApp
128--    data T a where
129--      T1 :: T Int
130-- gives
131--    T1 :: forall a. (a~Int) -> T a
132-- and hence the top-level binding
133--    $WT1 :: T Int
134--    $WT1 = T1 Int (Coercion (Refl Int))
135-- The coercion argument here gets VoidRep
136isAddrRep :: PrimRep -> Bool
137isAddrRep AddrRep = True
138isAddrRep PtrRep  = True
139isAddrRep _       = False
140
141-- | Type of an @StgArg@
142--
143-- Very half baked becase we have lost the type arguments.
144stgArgType :: StgArg -> Type
145stgArgType (StgVarArg v)   = idType v
146stgArgType (StgLitArg lit) = literalType lit
147stgArgType (StgTypeArg _)  = panic "stgArgType called on stgTypeArg"
148\end{code}
149
150%************************************************************************
151%*                                                                      *
152\subsection{STG expressions}
153%*                                                                      *
154%************************************************************************
155
156The @GenStgExpr@ data type is parameterised on binder and occurrence
157info, as before.
158
159%************************************************************************
160%*                                                                      *
161\subsubsection{@GenStgExpr@ application}
162%*                                                                      *
163%************************************************************************
164
165An application is of a function to a list of atoms [not expressions].
166Operationally, we want to push the arguments on the stack and call the
167function. (If the arguments were expressions, we would have to build
168their closures first.)
169
170There is no constructor for a lone variable; it would appear as
171@StgApp var [] _@.
172\begin{code}
173type GenStgLiveVars occ = UniqSet occ
174
175data GenStgExpr bndr occ
176  = StgApp
177        occ             -- function
178        [GenStgArg occ] -- arguments; may be empty
179\end{code}
180
181%************************************************************************
182%*                                                                      *
183\subsubsection{@StgConApp@ and @StgPrimApp@---saturated applications}
184%*                                                                      *
185%************************************************************************
186
187There are a specialised forms of application, for constructors,
188primitives, and literals.
189\begin{code}
190  | StgLit      Literal
191
192        -- StgConApp is vital for returning unboxed tuples
193        -- which can't be let-bound first
194  | StgConApp   DataCon
195                [GenStgArg occ] -- Saturated
196
197  | StgOpApp    StgOp           -- Primitive op or foreign call
198                [GenStgArg occ] -- Saturated
199                Type            -- Result type
200                                -- We need to know this so that we can
201                                -- assign result registers
202\end{code}
203
204%************************************************************************
205%*                                                                      *
206\subsubsection{@StgLam@}
207%*                                                                      *
208%************************************************************************
209
210StgLam is used *only* during CoreToStg's work. Before CoreToStg has
211finished it encodes (\x -> e) as (let f = \x -> e in f)
212
213\begin{code}
214  | StgLam
215        Type       -- Type of whole lambda (useful when
216                   -- making a binder for it)
217        [bndr]
218        StgExpr    -- Body of lambda
219\end{code}
220
221
222%************************************************************************
223%*                                                                      *
224\subsubsection{@GenStgExpr@: case-expressions}
225%*                                                                      *
226%************************************************************************
227
228This has the same boxed/unboxed business as Core case expressions.
229\begin{code}
230  | StgCase
231        (GenStgExpr bndr occ)
232                    -- the thing to examine
233
234        (GenStgLiveVars occ)
235                    -- Live vars of whole case expression,
236                    -- plus everything that happens after the case
237                    -- i.e., those which mustn't be overwritten
238
239        (GenStgLiveVars occ)
240                    -- Live vars of RHSs (plus what happens afterwards)
241                    -- i.e., those which must be saved before eval.
242                    --
243                    -- note that an alt's constructor's
244                    -- binder-variables are NOT counted in the
245                    -- free vars for the alt's RHS
246
247        bndr        -- binds the result of evaluating the scrutinee
248
249        SRT         -- The SRT for the continuation
250
251        AltType
252
253        [GenStgAlt bndr occ]
254                    -- The DEFAULT case is always *first*
255                    -- if it is there at all
256\end{code}
257
258%************************************************************************
259%*                                                                      *
260\subsubsection{@GenStgExpr@: @let(rec)@-expressions}
261%*                                                                      *
262%************************************************************************
263
264The various forms of let(rec)-expression encode most of the
265interesting things we want to do.
266\begin{enumerate}
267\item
268\begin{verbatim}
269let-closure x = [free-vars] [args] expr
270in e
271\end{verbatim}
272is equivalent to
273\begin{verbatim}
274let x = (\free-vars -> \args -> expr) free-vars
275\end{verbatim}
276\tr{args} may be empty (and is for most closures).  It isn't under
277circumstances like this:
278\begin{verbatim}
279let x = (\y -> y+z)
280\end{verbatim}
281This gets mangled to
282\begin{verbatim}
283let-closure x = [z] [y] (y+z)
284\end{verbatim}
285The idea is that we compile code for @(y+z)@ in an environment in which
286@z@ is bound to an offset from \tr{Node}, and @y@ is bound to an
287offset from the stack pointer.
288
289(A let-closure is an @StgLet@ with a @StgRhsClosure@ RHS.)
290
291\item
292\begin{verbatim}
293let-constructor x = Constructor [args]
294in e
295\end{verbatim}
296
297(A let-constructor is an @StgLet@ with a @StgRhsCon@ RHS.)
298
299\item
300Letrec-expressions are essentially the same deal as
301let-closure/let-constructor, so we use a common structure and
302distinguish between them with an @is_recursive@ boolean flag.
303
304\item
305\begin{verbatim}
306let-unboxed u = an arbitrary arithmetic expression in unboxed values
307in e
308\end{verbatim}
309All the stuff on the RHS must be fully evaluated.
310No function calls either!
311
312(We've backed away from this toward case-expressions with
313suitably-magical alts ...)
314
315\item
316~[Advanced stuff here! Not to start with, but makes pattern matching
317generate more efficient code.]
318
319\begin{verbatim}
320let-escapes-not fail = expr
321in e'
322\end{verbatim}
323Here the idea is that @e'@ guarantees not to put @fail@ in a data structure,
324or pass it to another function. All @e'@ will ever do is tail-call @fail@.
325Rather than build a closure for @fail@, all we need do is to record the stack
326level at the moment of the @let-escapes-not@; then entering @fail@ is just
327a matter of adjusting the stack pointer back down to that point and entering
328the code for it.
329
330Another example:
331\begin{verbatim}
332f x y = let z = huge-expression in
333        if y==1 then z else
334        if y==2 then z else
335        1
336\end{verbatim}
337
338(A let-escapes-not is an @StgLetNoEscape@.)
339
340\item
341We may eventually want:
342\begin{verbatim}
343let-literal x = Literal
344in e
345\end{verbatim}
346\end{enumerate}
347
348And so the code for let(rec)-things:
349\begin{code}
350  | StgLet
351        (GenStgBinding bndr occ)    -- right hand sides (see below)
352        (GenStgExpr bndr occ)       -- body
353
354  | StgLetNoEscape                  -- remember: ``advanced stuff''
355        (GenStgLiveVars occ)        -- Live in the whole let-expression
356                                    -- Mustn't overwrite these stack slots
357                                    -- _Doesn't_ include binders of the let(rec).
358
359        (GenStgLiveVars occ)        -- Live in the right hand sides (only)
360                                    -- These are the ones which must be saved on
361                                    -- the stack if they aren't there already
362                                    -- _Does_ include binders of the let(rec) if recursive.
363
364        (GenStgBinding bndr occ)    -- right hand sides (see below)
365        (GenStgExpr bndr occ)       -- body
366\end{code}
367
368%************************************************************************
369%*                                                                      *
370\subsubsection{@GenStgExpr@: @scc@ expressions}
371%*                                                                      *
372%************************************************************************
373
374For @scc@ expressions we introduce a new STG construct.
375
376\begin{code}
377  | StgSCC
378        CostCentre             -- label of SCC expression
379        !Bool                  -- bump the entry count?
380        !Bool                  -- push the cost centre?
381        (GenStgExpr bndr occ)  -- scc expression
382\end{code}
383
384%************************************************************************
385%*                                                                      *
386\subsubsection{@GenStgExpr@: @hpc@ expressions}
387%*                                                                      *
388%************************************************************************
389
390Finally for @scc@ expressions we introduce a new STG construct.
391
392\begin{code}
393  | StgTick
394        Module                 -- the module of the source of this tick
395        Int                    -- tick number
396        (GenStgExpr bndr occ)  -- sub expression
397
398-- END of GenStgExpr
399\end{code}
400
401%************************************************************************
402%*                                                                      *
403\subsection{STG right-hand sides}
404%*                                                                      *
405%************************************************************************
406
407Here's the rest of the interesting stuff for @StgLet@s; the first
408flavour is for closures:
409\begin{code}
410data GenStgRhs bndr occ
411  = StgRhsClosure
412        CostCentreStack         -- CCS to be attached (default is CurrentCCS)
413        StgBinderInfo           -- Info about how this binder is used (see below)
414        [occ]                   -- non-global free vars; a list, rather than
415                                -- a set, because order is important
416        !UpdateFlag             -- ReEntrant | Updatable | SingleEntry
417        SRT                     -- The SRT reference
418        [bndr]                  -- arguments; if empty, then not a function;
419                                -- as above, order is important.
420        (GenStgExpr bndr occ)   -- body
421\end{code}
422An example may be in order.  Consider:
423\begin{verbatim}
424let t = \x -> \y -> ... x ... y ... p ... q in e
425\end{verbatim}
426Pulling out the free vars and stylising somewhat, we get the equivalent:
427\begin{verbatim}
428let t = (\[p,q] -> \[x,y] -> ... x ... y ... p ...q) p q
429\end{verbatim}
430Stg-operationally, the @[x,y]@ are on the stack, the @[p,q]@ are
431offsets from @Node@ into the closure, and the code ptr for the closure
432will be exactly that in parentheses above.
433
434The second flavour of right-hand-side is for constructors (simple but important):
435\begin{code}
436  | StgRhsCon
437        CostCentreStack  -- CCS to be attached (default is CurrentCCS).
438                         -- Top-level (static) ones will end up with
439                         -- DontCareCCS, because we don't count static
440                         -- data in heap profiles, and we don't set CCCS
441                         -- from static closure.
442        DataCon          -- constructor
443        [GenStgArg occ]  -- args
444
445stgRhsArity :: StgRhs -> Int
446stgRhsArity (StgRhsClosure _ _ _ _ _ bndrs _)
447  = ASSERT( all isId bndrs ) length bndrs
448  -- The arity never includes type parameters, but they should have gone by now
449stgRhsArity (StgRhsCon _ _ _) = 0
450
451stgBindHasCafRefs :: GenStgBinding bndr Id -> Bool
452stgBindHasCafRefs (StgNonRec _ rhs) = rhsHasCafRefs rhs
453stgBindHasCafRefs (StgRec binds)    = any rhsHasCafRefs (map snd binds)
454
455rhsHasCafRefs :: GenStgRhs bndr Id -> Bool
456rhsHasCafRefs (StgRhsClosure _ _ _ upd srt _ _)
457  = isUpdatable upd || nonEmptySRT srt
458rhsHasCafRefs (StgRhsCon _ _ args)
459  = any stgArgHasCafRefs args
460
461stgArgHasCafRefs :: GenStgArg Id -> Bool
462stgArgHasCafRefs (StgVarArg id) = mayHaveCafRefs (idCafInfo id)
463stgArgHasCafRefs _ = False
464\end{code}
465
466Here's the @StgBinderInfo@ type, and its combining op:
467\begin{code}
468data StgBinderInfo
469  = NoStgBinderInfo
470  | SatCallsOnly        -- All occurrences are *saturated* *function* calls
471                        -- This means we don't need to build an info table and
472                        -- slow entry code for the thing
473                        -- Thunks never get this value
474
475noBinderInfo, stgUnsatOcc, stgSatOcc :: StgBinderInfo
476noBinderInfo = NoStgBinderInfo
477stgUnsatOcc  = NoStgBinderInfo
478stgSatOcc    = SatCallsOnly
479
480satCallsOnly :: StgBinderInfo -> Bool
481satCallsOnly SatCallsOnly    = True
482satCallsOnly NoStgBinderInfo = False
483
484combineStgBinderInfo :: StgBinderInfo -> StgBinderInfo -> StgBinderInfo
485combineStgBinderInfo SatCallsOnly SatCallsOnly = SatCallsOnly
486combineStgBinderInfo _            _            = NoStgBinderInfo
487
488--------------
489pp_binder_info :: StgBinderInfo -> SDoc
490pp_binder_info NoStgBinderInfo = empty
491pp_binder_info SatCallsOnly    = ptext (sLit "sat-only")
492\end{code}
493
494%************************************************************************
495%*                                                                      *
496\subsection[Stg-case-alternatives]{STG case alternatives}
497%*                                                                      *
498%************************************************************************
499
500Very like in @CoreSyntax@ (except no type-world stuff).
501
502The type constructor is guaranteed not to be abstract; that is, we can
503see its representation. This is important because the code generator
504uses it to determine return conventions etc. But it's not trivial
505where there's a moduule loop involved, because some versions of a type
506constructor might not have all the constructors visible. So
507mkStgAlgAlts (in CoreToStg) ensures that it gets the TyCon from the
508constructors or literals (which are guaranteed to have the Real McCoy)
509rather than from the scrutinee type.
510
511\begin{code}
512type GenStgAlt bndr occ
513  = (AltCon,            -- alts: data constructor,
514     [bndr],            -- constructor's parameters,
515     [Bool],            -- "use mask", same length as
516                        -- parameters; a True in a
517                        -- param's position if it is
518                        -- used in the ...
519     GenStgExpr bndr occ)       -- ...right-hand side.
520
521data AltType
522  = PolyAlt             -- Polymorphic (a type variable)
523  | UbxTupAlt TyCon     -- Unboxed tuple
524  | AlgAlt    TyCon     -- Algebraic data type; the AltCons will be DataAlts
525  | PrimAlt   TyCon     -- Primitive data type; the AltCons will be LitAlts
526\end{code}
527
528%************************************************************************
529%*                                                                      *
530\subsection[Stg]{The Plain STG parameterisation}
531%*                                                                      *
532%************************************************************************
533
534This happens to be the only one we use at the moment.
535
536\begin{code}
537type StgBinding  = GenStgBinding  Id Id
538type StgArg      = GenStgArg      Id
539type StgLiveVars = GenStgLiveVars Id
540type StgExpr     = GenStgExpr     Id Id
541type StgRhs      = GenStgRhs      Id Id
542type StgAlt      = GenStgAlt      Id Id
543\end{code}
544
545%************************************************************************
546%*                                                                      *
547\subsubsection[UpdateFlag-datatype]{@UpdateFlag@}
548%*                                                                      *
549%************************************************************************
550
551This is also used in @LambdaFormInfo@ in the @ClosureInfo@ module.
552
553A @ReEntrant@ closure may be entered multiple times, but should not be
554updated or blackholed. An @Updatable@ closure should be updated after
555evaluation (and may be blackholed during evaluation). A @SingleEntry@
556closure will only be entered once, and so need not be updated but may
557safely be blackholed.
558
559\begin{code}
560data UpdateFlag = ReEntrant | Updatable | SingleEntry
561
562instance Outputable UpdateFlag where
563    ppr u = char $ case u of
564                       ReEntrant   -> 'r'
565                       Updatable   -> 'u'
566                       SingleEntry -> 's'
567
568isUpdatable :: UpdateFlag -> Bool
569isUpdatable ReEntrant   = False
570isUpdatable SingleEntry = False
571isUpdatable Updatable   = True
572\end{code}
573
574%************************************************************************
575%*                                                                      *
576\subsubsection{StgOp}
577%*                                                                      *
578%************************************************************************
579
580An StgOp allows us to group together PrimOps and ForeignCalls.
581It's quite useful to move these around together, notably
582in StgOpApp and COpStmt.
583
584\begin{code}
585data StgOp
586  = StgPrimOp  PrimOp
587
588  | StgPrimCallOp PrimCall
589
590  | StgFCallOp ForeignCall Unique
591        -- The Unique is occasionally needed by the C pretty-printer
592        -- (which lacks a unique supply), notably when generating a
593        -- typedef for foreign-export-dynamic
594\end{code}
595
596
597%************************************************************************
598%*                                                                      *
599\subsubsection[Static Reference Tables]{@SRT@}
600%*                                                                      *
601%************************************************************************
602
603There is one SRT per top-level function group. Each local binding and
604case expression within this binding group has a subrange of the whole
605SRT, expressed as an offset and length.
606
607In CoreToStg we collect the list of CafRefs at each SRT site, which is later
608converted into the length and offset form by the SRT pass.
609
610\begin{code}
611data SRT
612  = NoSRT
613  | SRTEntries IdSet
614        -- generated by CoreToStg
615  | SRT !Int{-offset-} !Int{-length-} !Bitmap{-bitmap-}
616        -- generated by computeSRTs
617
618nonEmptySRT :: SRT -> Bool
619nonEmptySRT NoSRT           = False
620nonEmptySRT (SRTEntries vs) = not (isEmptyVarSet vs)
621nonEmptySRT _               = True
622
623pprSRT :: SRT -> SDoc
624pprSRT (NoSRT)          = ptext (sLit "_no_srt_")
625pprSRT (SRTEntries ids) = text "SRT:" <> ppr ids
626pprSRT (SRT off _ _)    = parens (ppr off <> comma <> text "*bitmap*")
627\end{code}
628
629%************************************************************************
630%*                                                                      *
631\subsection[Stg-pretty-printing]{Pretty-printing}
632%*                                                                      *
633%************************************************************************
634
635Robin Popplestone asked for semi-colon separators on STG binds; here's
636hoping he likes terminators instead...  Ditto for case alternatives.
637
638\begin{code}
639pprGenStgBinding :: (Outputable bndr, Outputable bdee, Ord bdee)
640                 => GenStgBinding bndr bdee -> SDoc
641
642pprGenStgBinding (StgNonRec bndr rhs)
643  = hang (hsep [ppr bndr, equals])
644        4 ((<>) (ppr rhs) semi)
645
646pprGenStgBinding (StgRec pairs)
647  = vcat $ ifPprDebug (ptext $ sLit "{- StgRec (begin) -}") :
648           map (ppr_bind) pairs ++ [ifPprDebug $ ptext $ sLit "{- StgRec (end) -}"]
649  where
650    ppr_bind (bndr, expr)
651      = hang (hsep [ppr bndr, equals])
652             4 ((<>) (ppr expr) semi)
653
654pprStgBinding :: StgBinding -> SDoc
655pprStgBinding  bind  = pprGenStgBinding bind
656
657pprStgBindings :: [StgBinding] -> SDoc
658pprStgBindings binds = vcat (map pprGenStgBinding binds)
659
660pprGenStgBindingWithSRT :: (Outputable bndr, Outputable bdee, Ord bdee)
661                        => (GenStgBinding bndr bdee,[(Id,[Id])]) -> SDoc
662pprGenStgBindingWithSRT (bind,srts)
663  = vcat $ pprGenStgBinding bind : map pprSRT srts
664  where pprSRT (id,srt) =
665           ptext (sLit "SRT") <> parens (ppr id) <> ptext (sLit ": ") <> ppr srt
666
667pprStgBindingsWithSRTs :: [(StgBinding,[(Id,[Id])])] -> SDoc
668pprStgBindingsWithSRTs binds = vcat (map pprGenStgBindingWithSRT binds)
669
670instance (Outputable bdee) => Outputable (GenStgArg bdee) where
671    ppr = pprStgArg
672
673instance (Outputable bndr, Outputable bdee, Ord bdee)
674                => Outputable (GenStgBinding bndr bdee) where
675    ppr = pprGenStgBinding
676
677instance (Outputable bndr, Outputable bdee, Ord bdee)
678                => Outputable (GenStgExpr bndr bdee) where
679    ppr = pprStgExpr
680
681instance (Outputable bndr, Outputable bdee, Ord bdee)
682                => Outputable (GenStgRhs bndr bdee) where
683    ppr rhs = pprStgRhs rhs
684
685pprStgArg :: (Outputable bdee) => GenStgArg bdee -> SDoc
686pprStgArg (StgVarArg var) = ppr var
687pprStgArg (StgLitArg con) = ppr con
688pprStgArg (StgTypeArg ty) = char '@' <+> ppr ty
689
690pprStgExpr :: (Outputable bndr, Outputable bdee, Ord bdee)
691           => GenStgExpr bndr bdee -> SDoc
692-- special case
693pprStgExpr (StgLit lit)     = ppr lit
694
695-- general case
696pprStgExpr (StgApp func args)
697  = hang (ppr func) 4 (sep (map (ppr) args))
698
699pprStgExpr (StgConApp con args)
700  = hsep [ ppr con, brackets (interppSP args)]
701
702pprStgExpr (StgOpApp op args _)
703  = hsep [ pprStgOp op, brackets (interppSP args)]
704
705pprStgExpr (StgLam _ bndrs body)
706  =sep [ char '\\' <+> ppr bndrs <+> ptext (sLit "->"),
707         pprStgExpr body ]
708
709-- special case: let v = <very specific thing>
710--               in
711--               let ...
712--               in
713--               ...
714--
715-- Very special!  Suspicious! (SLPJ)
716
717{-
718pprStgExpr (StgLet srt (StgNonRec bndr (StgRhsClosure cc bi free_vars upd_flag args rhs))
719                        expr@(StgLet _ _))
720  = ($$)
721      (hang (hcat [ptext (sLit "let { "), ppr bndr, ptext (sLit " = "),
722                          ppr cc,
723                          pp_binder_info bi,
724                          ptext (sLit " ["), ifPprDebug (interppSP free_vars), ptext (sLit "] \\"),
725                          ppr upd_flag, ptext (sLit " ["),
726                          interppSP args, char ']'])
727            8 (sep [hsep [ppr rhs, ptext (sLit "} in")]]))
728      (ppr expr)
729-}
730
731-- special case: let ... in let ...
732
733pprStgExpr (StgLet bind expr@(StgLet _ _))
734  = ($$)
735      (sep [hang (ptext (sLit "let {"))
736                2 (hsep [pprGenStgBinding bind, ptext (sLit "} in")])])
737      (ppr expr)
738
739-- general case
740pprStgExpr (StgLet bind expr)
741  = sep [hang (ptext (sLit "let {")) 2 (pprGenStgBinding bind),
742           hang (ptext (sLit "} in ")) 2 (ppr expr)]
743
744pprStgExpr (StgLetNoEscape lvs_whole lvs_rhss bind expr)
745  = sep [hang (ptext (sLit "let-no-escape {"))
746                2 (pprGenStgBinding bind),
747           hang ((<>) (ptext (sLit "} in "))
748                   (ifPprDebug (
749                    nest 4 (
750                      hcat [ptext  (sLit "-- lvs: ["), interppSP (uniqSetToList lvs_whole),
751                             ptext (sLit "]; rhs lvs: ["), interppSP (uniqSetToList lvs_rhss),
752                             char ']']))))
753                2 (ppr expr)]
754
755pprStgExpr (StgSCC cc tick push expr)
756  = sep [ hsep [scc, ppr cc], pprStgExpr expr ]
757  where
758    scc | tick && push = ptext (sLit "_scc_")
759        | tick         = ptext (sLit "_tick_")
760        | otherwise    = ptext (sLit "_push_")
761
762pprStgExpr (StgTick m n expr)
763  = sep [ hsep [ptext (sLit "_tick_"),  pprModule m,text (show n)],
764          pprStgExpr expr ]
765
766pprStgExpr (StgCase expr lvs_whole lvs_rhss bndr srt alt_type alts)
767  = sep [sep [ptext (sLit "case"),
768           nest 4 (hsep [pprStgExpr expr,
769             ifPprDebug (dcolon <+> ppr alt_type)]),
770           ptext (sLit "of"), ppr bndr, char '{'],
771           ifPprDebug (
772           nest 4 (
773             hcat [ptext  (sLit "-- lvs: ["), interppSP (uniqSetToList lvs_whole),
774                    ptext (sLit "]; rhs lvs: ["), interppSP (uniqSetToList lvs_rhss),
775                    ptext (sLit "]; "),
776                    pprMaybeSRT srt])),
777           nest 2 (vcat (map pprStgAlt alts)),
778           char '}']
779
780pprStgAlt :: (Outputable bndr, Outputable occ, Ord occ)
781          => GenStgAlt bndr occ -> SDoc
782pprStgAlt (con, params, _use_mask, expr)
783  = hang (hsep [ppr con, interppSP params, ptext (sLit "->")])
784         4 (ppr expr <> semi)
785
786pprStgOp :: StgOp -> SDoc
787pprStgOp (StgPrimOp  op)   = ppr op
788pprStgOp (StgPrimCallOp op)= ppr op
789pprStgOp (StgFCallOp op _) = ppr op
790
791instance Outputable AltType where
792  ppr PolyAlt        = ptext (sLit "Polymorphic")
793  ppr (UbxTupAlt tc) = ptext (sLit "UbxTup") <+> ppr tc
794  ppr (AlgAlt tc)    = ptext (sLit "Alg")    <+> ppr tc
795  ppr (PrimAlt tc)   = ptext (sLit "Prim")   <+> ppr tc
796
797pprStgLVs :: Outputable occ => GenStgLiveVars occ -> SDoc
798pprStgLVs lvs
799  = getPprStyle $ \ sty ->
800    if userStyle sty || isEmptyUniqSet lvs then
801        empty
802    else
803        hcat [text "{-lvs:", interpp'SP (uniqSetToList lvs), text "-}"]
804
805pprStgRhs :: (Outputable bndr, Outputable bdee, Ord bdee)
806          => GenStgRhs bndr bdee -> SDoc
807
808-- special case
809pprStgRhs (StgRhsClosure cc bi [free_var] upd_flag srt [{-no args-}] (StgApp func []))
810  = hcat [ ppr cc,
811           pp_binder_info bi,
812           brackets (ifPprDebug (ppr free_var)),
813           ptext (sLit " \\"), ppr upd_flag, pprMaybeSRT srt, ptext (sLit " [] "), ppr func ]
814
815-- general case
816pprStgRhs (StgRhsClosure cc bi free_vars upd_flag srt args body)
817  = hang (hsep [if opt_SccProfilingOn then ppr cc else empty,
818                pp_binder_info bi,
819                ifPprDebug (brackets (interppSP free_vars)),
820                char '\\' <> ppr upd_flag, pprMaybeSRT srt, brackets (interppSP args)])
821         4 (ppr body)
822
823pprStgRhs (StgRhsCon cc con args)
824  = hcat [ ppr cc,
825           space, ppr con, ptext (sLit "! "), brackets (interppSP args)]
826
827pprMaybeSRT :: SRT -> SDoc
828pprMaybeSRT (NoSRT) = empty
829pprMaybeSRT srt     = ptext (sLit "srt:") <> pprSRT srt
830\end{code}
Note: See TracBrowser for help on using the browser.